Drag tabs to reorder buffers on the tab line.
authorJuri Linkov <juri@linkov.net>
Thu, 18 Apr 2024 17:28:16 +0000 (20:28 +0300)
committerJuri Linkov <juri@linkov.net>
Thu, 18 Apr 2024 17:28:16 +0000 (20:28 +0300)
* lisp/tab-line.el (tab-line-mouse-move-tab):
New command bound to [tab-line drag-mouse-1].

etc/NEWS
lisp/tab-line.el

index 78a1307b6a477dc74d6b6348638ae5119191b91a..8ad1e78ca600dead072dcf241557caa2162863de 100644 (file)
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -384,7 +384,8 @@ tabs function, is like the previous 'tab-line-tabs-window-buffers' where
 both of them show only buffers that were previously displayed in the
 window.  But the difference is that the new function always keeps the
 original order of buffers on the tab line, even after switching between
-these buffers.
+these buffers.  You can drag the tabs and release at a new position
+to manually reorder the buffers on the tab line.
 
 ---
 *** New user option 'tab-line-tabs-buffer-group-function'.
index 2eb970122622beb6ca7448dc0851f2143f32d9da..84dd20a6307ccbc2aedf1dffa2935c201d659c35 100644 (file)
@@ -959,6 +959,31 @@ is possible when `tab-line-switch-cycling' is non-nil."
             (let ((switch-to-buffer-obey-display-actions nil))
               (switch-to-buffer buffer))))))))
 
+(defun tab-line-mouse-move-tab (event)
+  "Move a tab to a different position on the tab line.
+This command should be bound to a drag event.  It moves the tab
+at the mouse-down event to the position at mouse-up event.
+It can be used only when `tab-line-tabs-function' is
+customized to `tab-line-tabs-fixed-window-buffers'."
+  (interactive "e")
+  (when (eq tab-line-tabs-function #'tab-line-tabs-fixed-window-buffers)
+    (let* ((posnp1 (tab-line-event-start event))
+           (posnp2 (event-end event))
+           (string1 (car (posn-string posnp1)))
+           (string2 (car (posn-string posnp2)))
+           (buffer1 (when string1 (tab-line--get-tab-property 'tab string1)))
+           (buffer2 (when string2 (tab-line--get-tab-property 'tab string2)))
+           (window1 (posn-window posnp1))
+           (window2 (posn-window posnp2))
+           (buffers (window-parameter window1 'tab-line-buffers))
+           (pos2 (when buffer2 (seq-position buffers buffer2))))
+      (when (and (eq window1 window2) buffer1 pos2)
+        (setq buffers (delq buffer1 buffers))
+        (cl-pushnew buffer1 (nthcdr pos2 buffers))
+        (set-window-parameter window1 'tab-line-buffers buffers)
+        (set-window-parameter window1 'tab-line-cache nil)
+        (with-selected-window window1 (force-mode-line-update))))))
+
 \f
 (defcustom tab-line-close-tab-function 'bury-buffer
   "What to do upon closing a tab on the tab line.
@@ -1120,6 +1145,7 @@ of `tab-line-exclude', are exempt from `tab-line-mode'."
 
 \f
 (global-set-key [tab-line down-mouse-3] 'tab-line-context-menu)
+(global-set-key [tab-line drag-mouse-1] 'tab-line-mouse-move-tab)
 
 (global-set-key [tab-line mouse-4]    'tab-line-hscroll-left)
 (global-set-key [tab-line mouse-5]    'tab-line-hscroll-right)