Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- (setq hfj/last-picked-tabs-max-length 10)
- (setq hfj/last-picked-tabs '())
- (defun hfj/tab-update-last-picked (name)
- (setq hfj/last-picked-tabs
- (-take hfj/last-picked-tabs-max-length
- (cons name (-remove-item name hfj/last-picked-tabs)))))
- (defface hfj/current-tab
- '((((background light)) :foreground "gray30")
- (((background dark)) :foreground "gray50"))
- "Current tab")
- (defun hfj/order-items-to-list (items match-to-items is-equal)
- "Sort ITEMS by matching them up with MATCH-TO-ITEMS using comparing function IS-EQUAL.
- Any items that weren't sorted will be appended to returned list in current order."
- (let ((culled-items (append items))
- (ordered-items '()))
- (loop for match-item in match-to-items
- for idx = (--find-index (funcall is-equal it match-item) culled-items)
- when idx do (progn (push (elt culled-items idx) ordered-items)
- (setf culled-items (-remove-at idx culled-items))))
- (append (nreverse ordered-items) culled-items)))
- (defun hfj/tab-pick-close-tab (candidate)
- (tab-bar-close-tab (1+ (cdr (assq 'pos candidate)))))
- (defun hfj/tab-pick-run-close-tab ()
- (interactive)
- (with-helm-alive-p (helm-exit-and-execute-action 'hfj/tab-pick-close-tab)))
- (defun hfj/tab-pick-rename-tab (candidate)
- (if-let ((new-name (read-string "New name: "
- (cdr (assq 'name candidate)))))
- (tab-bar-rename-tab new-name (1+ (cdr (assq 'pos candidate))))))
- (defun hfj/tab-pick-run-rename-tab ()
- (interactive)
- (with-helm-alive-p (helm-exit-and-execute-action 'hfj/tab-pick-rename-tab)))
- (defun hfj/tab-pick-by-name ()
- "Switch to a new or existing tab."
- (interactive)
- (let* ((tabs (funcall tab-bar-tabs-function))
- (tab-info-by-name (loop for pos from 0
- for tab in tabs
- collect (list (cdr (assq 'name tab))
- (cons 'name (cdr (assq 'name tab)))
- (cons 'pos pos)
- (cons 'current (eq 'current-tab (car tab))))))
- (current-tab (--first (cdr (assq 'current it)) tab-info-by-name))
- (current-tab-name (cdr (assq 'name current-tab)))
- (ordered-tab-info-by-name (hfj/order-items-to-list
- tab-info-by-name
- hfj/last-picked-tabs
- (lambda (tinfo name) (string= (car tinfo) name))))
- ;; Reorder with current at top
- (ordered-tab-info-by-name
- (cons (cons (propertize current-tab-name 'face 'hfj/current-tab)
- (cdr current-tab))
- (--remove (cdr (assq 'current it)) ordered-tab-info-by-name)))
- (tab-source
- (helm-build-sync-source "Tabs"
- :candidates ordered-tab-info-by-name
- :keymap (let ((map (make-sparse-keymap)))
- (set-keymap-parent map helm-map)
- (define-key map (kbd "C-d") 'hfj/tab-pick-run-close-tab)
- (define-key map (kbd "C-r") 'hfj/tab-pick-run-rename-tab)
- map)
- :action
- `(("Switch to tab" .
- (lambda (candidate)
- (let ((name (cdr (assq 'name candidate))))
- (hfj/tab-update-last-picked name)
- (tab-bar-select-tab (1+ (cdr (assq 'pos candidate)))))))
- ("Close tab (C-d)" . hfj/tab-pick-close-tab)
- ("Rename tab (C-r)" . hfj/tab-pick-rename-tab))))
- (new-tab-source
- (helm-build-dummy-source "New tab"
- :filtered-candidate-transformer
- (lambda (_candidates _source)
- (list (or (and (not (string= helm-pattern ""))
- helm-pattern)
- (propertize "Enter a new tab name"
- 'face 'helm-action))))
- :action '(("New tab" . (lambda (name)
- (message "Making a new tab with name %S" name)
- (tab-bar-new-tab)
- (tab-bar-rename-tab name)
- (hfj/tab-update-last-picked name)))))))
- (let ((helm-split-window-inside-p nil)
- (helm-split-window-default-side 'same))
- (helm :sources (list tab-source new-tab-source)
- :buffer "*helm tabs*"
- :preselect (cdr (assq 'name (cadr ordered-tab-info-by-name)))
- :prompt "Switch to: "))))
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement