summaryrefslogtreecommitdiff
path: root/lisp/native-tabs.el
diff options
context:
space:
mode:
Diffstat (limited to 'lisp/native-tabs.el')
-rw-r--r--lisp/native-tabs.el134
1 files changed, 83 insertions, 51 deletions
diff --git a/lisp/native-tabs.el b/lisp/native-tabs.el
index afd46a9124b..283c7a640dd 100644
--- a/lisp/native-tabs.el
+++ b/lisp/native-tabs.el
@@ -33,7 +33,7 @@
(define-key map "\C-x70" 'tab-delete)
(define-key map "\C-x71" 'tab-delete-other)
(define-key map "\C-x72" 'tab-new)
- (define-key map "\C-x73" 'switch-to-buffer-tab)
+ (define-key map "\C-x73" 'switch-to-buffer-in-tab)
(define-key map "\C-x7b" 'switch-to-buffer-other-tab)
(define-key map "\C-x7f" 'find-file-new-tab)
(define-key map "\C-x7o" 'tab-next)
@@ -58,16 +58,34 @@ Keyboard commands for tabs are:
:keymap tab-mode-map
(modify-all-frames-parameters (list (cons 'disable-tabs (not tab-mode)))))
-(declare-function tab-new "xfns.c" ())
-(declare-function tab-delete "xfns.c" ())
-(declare-function tab-delete-other "xfns.c" ())
-(declare-function tab-next "xfns.c" ())
-(declare-function tab-previous "xfns.c" ())
-(declare-function tab-nr-of-tabs "xfns.c" ())
-(declare-function tab-configuration "xfns.c" ())
-(declare-function tab-current "xfns.c" ())
-(declare-function tab-show "xfns.c" ())
-(declare-function tab-enable "xfns.c" ())
+(declare-function tab-new "xfns.c" (&optional label frame))
+(declare-function tab-delete "xfns.c" (&optional label frame))
+(declare-function tab-delete-other "xfns.c" (&optional frame))
+(declare-function tab-next "xfns.c" (&optional frame))
+(declare-function tab-previous "xfns.c" (&optional frame))
+(declare-function tab-nr-of-tabs "xfns.c" (&optional frame))
+(declare-function tab-current "xfns.c" (&optional frame))
+(declare-function tab-show "xfns.c" (key &optional frame))
+(declare-function tab-enable "xfns.c" (enable &optional frame))
+
+(defun current-tab-window-config ()
+ (list (current-window-configuration) (point-marker)))
+
+(defun window-tab-config-frame (config)
+ (if (and (consp config) (window-configuration-p (car config)))
+ (window-configuration-frame (car config))
+ nil))
+
+(defun set-tab-window-config (config)
+ (and (consp config) (window-configuration-p (car config))
+ (set-window-configuration (car config))
+ (goto-char (cadr config))))
+
+(defun change-tab-window-config-frame (config frame)
+ (if (and (consp config) (window-configuration-p (car config)))
+ (list (change-window-configuration-frame (car config) frame)
+ (cadr config))
+ config))
(defun find-file-new-tab (filename &optional wildcards)
"Edit file FILENAME, in a new tab.
@@ -83,16 +101,20 @@ expand wildcards (if any) and visit multiple files."
(interactive
(find-file-read-args "Find file in new tab: "
(confirm-nonexistent-file-or-buffer)))
- (let ((value (find-file-noselect filename nil nil wildcards)))
- (if (not (null (tab-new)))
- (progn
- (delete-other-windows)
- (if (listp value)
- (progn
- (setq value (nreverse value))
- (cons (switch-to-buffer (car value))
- (mapcar 'switch-to-buffer (cdr value))))
- (switch-to-buffer value))))))
+ (save-window-excursion
+ (let* ((value (find-file-noselect filename nil nil wildcards))
+ (newtab (tab-new)))
+ (if newtab
+ (progn
+ (delete-other-windows)
+ (if (listp value)
+ (progn
+ (setq value (nreverse value))
+ (cons (switch-to-buffer (car value))
+ (dolist 'switch-to-buffer (cdr value))))
+ (switch-to-buffer value))
+ (put newtab 'winconfig (current-tab-window-config)))))))
+
(defun switch-to-buffer-other-tab (buffer-or-name &optional norecord)
"Switch to buffer BUFFER-OR-NAME in another tab.
@@ -123,8 +145,8 @@ documentation for additional customization information."
(delete-other-windows)))))
-(defun display-existing-buffer-in-tab (buffer-or-name &optional frame)
- "Switch to a tab that shows BUFFER-OR-NAME on FRAME.
+(defun find-tab-for-existing-buffer (buffer-or-name &optional frame)
+ "Find a tab that shows BUFFER-OR-NAME on FRAME.
FRAME nil means selected frame.
Returns the key for the tab switch to, or nil if no tab displays
@@ -136,21 +158,19 @@ BUFFER-OR-NAME."
(tab-key))
(while (and tabs (null tab-key))
(let* ((elt (car tabs))
- (winconf (cadr elt))
+ (winconf (get elt 'winconfig))
(buffers (buffers-in-window-configuration winconf)))
(if (memq buffer buffers)
- (setq tab-key (car elt))
+ (setq tab-key elt)
(setq tabs (cdr tabs)))))
- (if (and tab-key (not (equal tab-key (tab-current frame))))
- (progn
- (tab-show tab-key frame)
- tab-key)
- nil)))
+ tab-key))
-(defun switch-to-buffer-tab (buffer-or-name &optional frame)
+(defun switch-to-buffer-in-tab (buffer-or-name &optional frame)
(interactive "BSwitch to buffer:\nP")
- (if (not (display-existing-buffer-in-tab buffer-or-name frame))
- (switch-to-buffer buffer-or-name)))
+ (let ((tab (find-tab-for-existing-buffer buffer-or-name frame)))
+ (if tab
+ (tab-show tab frame)
+ (switch-to-buffer buffer-or-name))))
(defun handle-tab-event (event)
"Handle tab-event to change tabs on the frame in EVENT."
@@ -161,23 +181,35 @@ BUFFER-OR-NAME."
(frame (car n1))
(x (car (cdr n1)))
(y (cdr (cdr n1))))
- (if (eq type 2) ;; // A tab is dropped from another frame.
- (let ((top y)
- (left x)
- (width (frame-pixel-width frame))
- (height (frame-pixel-height frame))
- (dw (x-display-pixel-width frame))
- (dh (x-display-pixel-height frame)))
- (if (< dw (+ left width))
- (setq left (- dw width)))
- (if (< dh (+ top height))
- (setq top (- dh height)))
- (make-frame
- (list (cons 'width (frame-parameter frame 'width))
- (cons 'height(frame-parameter frame 'height))
- (cons 'top top)
- (cons 'left left)))))))
-
-(define-key special-event-map [tab-event] 'handle-tab-event)
+ (cond ((eq type 'tab-new-frame) ;; // A tab is dropped to the background.
+ (let ((tab (car (cdr n2)))
+ (top y)
+ (left x)
+ (width (frame-pixel-width frame))
+ (height (frame-pixel-height frame))
+ (dw (x-display-pixel-width frame))
+ (dh (x-display-pixel-height frame)))
+ (if (< dw (+ left width))
+ (setq left (- dw width)))
+ (if (< dh (+ top height))
+ (setq top (- dh height)))
+ (make-frame
+ (list (cons 'width (frame-parameter frame 'width))
+ (cons 'height(frame-parameter frame 'height))
+ (cons 'top top)
+ (cons 'left left)))))
+
+ ((eq type 'tab-changed)
+ (let* ((newtab (car (cdr n2)))
+ (newcfg (get newtab 'winconfig))
+ (oldtab (cdr (cdr n2))))
+ (if oldtab (put oldtab 'winconfig (current-tab-window-config)))
+ (if newcfg (set-tab-window-config
+ (if (eq (window-tab-config-frame newcfg) frame)
+ newcfg
+ (put newtab 'winconfig
+ (change-tab-window-config-frame newcfg frame))))
+ (delete-other-windows)))))))
+(define-key special-event-map [tab-event] 'handle-tab-event)