Advertisement
6clk4mW8KYjKb5Af

Emacs 27 tabs helm select

Nov 29th, 2019
389
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lisp 4.63 KB | None | 0 0
  1. (setq hfj/last-picked-tabs-max-length 10)
  2. (setq hfj/last-picked-tabs '())
  3.  
  4. (defun hfj/tab-update-last-picked (name)
  5.   (setq hfj/last-picked-tabs
  6.         (-take hfj/last-picked-tabs-max-length
  7.                (cons name (-remove-item name hfj/last-picked-tabs)))))
  8.  
  9. (defface hfj/current-tab
  10.   '((((background light)) :foreground "gray30")
  11.     (((background dark))  :foreground "gray50"))
  12.   "Current tab")
  13.  
  14. (defun hfj/order-items-to-list (items match-to-items is-equal)
  15.   "Sort ITEMS by matching them up with MATCH-TO-ITEMS using comparing function IS-EQUAL.
  16.  
  17. Any items that weren't sorted will be appended to returned list in current order."
  18.   (let ((culled-items (append items))
  19.         (ordered-items '()))
  20.     (loop for match-item in match-to-items
  21.           for idx = (--find-index (funcall is-equal it match-item) culled-items)
  22.           when idx do (progn (push (elt culled-items idx) ordered-items)
  23.                              (setf culled-items (-remove-at idx culled-items))))
  24.     (append (nreverse ordered-items) culled-items)))
  25.  
  26. (defun hfj/tab-pick-close-tab (candidate)
  27.   (tab-bar-close-tab (1+ (cdr (assq 'pos candidate)))))
  28.  
  29. (defun hfj/tab-pick-run-close-tab ()
  30.   (interactive)
  31.   (with-helm-alive-p (helm-exit-and-execute-action 'hfj/tab-pick-close-tab)))
  32.  
  33. (defun hfj/tab-pick-rename-tab (candidate)
  34.   (if-let ((new-name (read-string "New name: "
  35.                                   (cdr (assq 'name candidate)))))
  36.       (tab-bar-rename-tab new-name (1+ (cdr (assq 'pos candidate))))))
  37.  
  38. (defun hfj/tab-pick-run-rename-tab ()
  39.   (interactive)
  40.   (with-helm-alive-p (helm-exit-and-execute-action 'hfj/tab-pick-rename-tab)))
  41.  
  42. (defun hfj/tab-pick-by-name ()
  43.   "Switch to a new or existing tab."
  44.   (interactive)
  45.   (let* ((tabs (funcall tab-bar-tabs-function))
  46.          (tab-info-by-name (loop for pos from 0
  47.                                  for tab in tabs
  48.                                  collect (list (cdr (assq 'name tab))
  49.                                                (cons 'name (cdr (assq 'name tab)))
  50.                                                (cons 'pos pos)
  51.                                                (cons 'current (eq 'current-tab (car tab))))))
  52.          (current-tab (--first (cdr (assq 'current it)) tab-info-by-name))
  53.          (current-tab-name (cdr (assq 'name current-tab)))
  54.          (ordered-tab-info-by-name (hfj/order-items-to-list
  55.                                     tab-info-by-name
  56.                                     hfj/last-picked-tabs
  57.                                     (lambda (tinfo name) (string= (car tinfo) name))))
  58.          ;; Reorder with current at top
  59.          (ordered-tab-info-by-name
  60.           (cons (cons (propertize current-tab-name 'face 'hfj/current-tab)
  61.                       (cdr current-tab))
  62.                 (--remove (cdr (assq 'current it)) ordered-tab-info-by-name)))
  63.          (tab-source
  64.           (helm-build-sync-source "Tabs"
  65.             :candidates ordered-tab-info-by-name
  66.             :keymap (let ((map (make-sparse-keymap)))
  67.                       (set-keymap-parent map helm-map)
  68.                       (define-key map (kbd "C-d") 'hfj/tab-pick-run-close-tab)
  69.                       (define-key map (kbd "C-r") 'hfj/tab-pick-run-rename-tab)
  70.                       map)
  71.             :action
  72.             `(("Switch to tab" .
  73.                (lambda (candidate)
  74.                  (let ((name (cdr (assq 'name candidate))))
  75.                    (hfj/tab-update-last-picked name)
  76.                    (tab-bar-select-tab (1+ (cdr (assq 'pos candidate)))))))
  77.               ("Close tab (C-d)" . hfj/tab-pick-close-tab)
  78.               ("Rename tab (C-r)" . hfj/tab-pick-rename-tab))))
  79.          (new-tab-source
  80.           (helm-build-dummy-source "New tab"
  81.             :filtered-candidate-transformer
  82.             (lambda (_candidates _source)
  83.               (list (or (and (not (string= helm-pattern ""))
  84.                              helm-pattern)
  85.                         (propertize "Enter a new tab name"
  86.                                     'face 'helm-action))))
  87.             :action '(("New tab" . (lambda (name)
  88.                                      (message "Making a new tab with name %S" name)
  89.                                      (tab-bar-new-tab)
  90.                                      (tab-bar-rename-tab name)
  91.                                      (hfj/tab-update-last-picked name)))))))
  92.     (let ((helm-split-window-inside-p nil)
  93.           (helm-split-window-default-side 'same))
  94.       (helm :sources (list tab-source new-tab-source)
  95.             :buffer "*helm tabs*"
  96.             :preselect (cdr (assq 'name (cadr ordered-tab-info-by-name)))
  97.             :prompt "Switch to: "))))
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement