diff options
| -rw-r--r-- | etc/NEWS | 16 | ||||
| -rw-r--r-- | lisp/dired.el | 20 | ||||
| -rw-r--r-- | lisp/tab-bar.el | 16 | ||||
| -rw-r--r-- | lisp/window.el | 72 |
4 files changed, 124 insertions, 0 deletions
| @@ -309,9 +309,25 @@ It specifies how 'set-window-configuration' and 'window-state-put' | |||
| 309 | should proceed with windows whose buffer was killed after the | 309 | should proceed with windows whose buffer was killed after the |
| 310 | corresponding configuration or state was recorded. | 310 | corresponding configuration or state was recorded. |
| 311 | 311 | ||
| 312 | *** New variable 'window-point-context-set-function'. | ||
| 313 | It can be used to set a context for window point in all windows by | ||
| 314 | 'window-point-context-set' before calling 'current-window-configuration' | ||
| 315 | and 'window-state-get'. Then later another new variable | ||
| 316 | 'window-point-context-use-function' can be used by | ||
| 317 | 'window-point-context-use' after 'set-window-configuration' and | ||
| 318 | 'window-state-put' to restore positions of window points | ||
| 319 | according to the context stored in a window parameter. | ||
| 320 | |||
| 312 | ** Tab Bars and Tab Lines | 321 | ** Tab Bars and Tab Lines |
| 313 | 322 | ||
| 314 | --- | 323 | --- |
| 324 | *** New user option 'tab-bar-select-restore-context'. | ||
| 325 | It uses 'window-point-context-set' to save contexts where | ||
| 326 | window points were located before switching away from the tab, | ||
| 327 | and 'window-point-context-use' to restore positions of window | ||
| 328 | points after switching back to that tab. | ||
| 329 | |||
| 330 | --- | ||
| 315 | *** New user option 'tab-bar-select-restore-windows'. | 331 | *** New user option 'tab-bar-select-restore-windows'. |
| 316 | It defines what to do with windows whose buffer was killed | 332 | It defines what to do with windows whose buffer was killed |
| 317 | since the tab was last selected. By default it displays | 333 | since the tab was last selected. By default it displays |
diff --git a/lisp/dired.el b/lisp/dired.el index 9e3b888df14..f0113c002a4 100644 --- a/lisp/dired.el +++ b/lisp/dired.el | |||
| @@ -2743,6 +2743,26 @@ Keybindings: | |||
| 2743 | '(dired-font-lock-keywords t nil nil beginning-of-line)) | 2743 | '(dired-font-lock-keywords t nil nil beginning-of-line)) |
| 2744 | (setq-local desktop-save-buffer 'dired-desktop-buffer-misc-data) | 2744 | (setq-local desktop-save-buffer 'dired-desktop-buffer-misc-data) |
| 2745 | (setq-local grep-read-files-function #'dired-grep-read-files) | 2745 | (setq-local grep-read-files-function #'dired-grep-read-files) |
| 2746 | (setq-local window-point-context-set-function | ||
| 2747 | (lambda (w) | ||
| 2748 | (with-current-buffer (window-buffer w) | ||
| 2749 | (let ((point (window-point w))) | ||
| 2750 | (save-excursion | ||
| 2751 | (goto-char point) | ||
| 2752 | (if-let ((f (dired-get-filename nil t))) | ||
| 2753 | `((dired-filename . ,f)) | ||
| 2754 | `((position . ,(point))))))))) | ||
| 2755 | (setq-local window-point-context-use-function | ||
| 2756 | (lambda (w context) | ||
| 2757 | (with-current-buffer (window-buffer w) | ||
| 2758 | (let ((point (window-point w))) | ||
| 2759 | (save-excursion | ||
| 2760 | (if-let ((f (alist-get 'dired-filename context))) | ||
| 2761 | (dired-goto-file f) | ||
| 2762 | (when-let ((p (alist-get 'position context))) | ||
| 2763 | (goto-char p))) | ||
| 2764 | (setq point (point))) | ||
| 2765 | (set-window-point w point))))) | ||
| 2746 | (setq dired-switches-alist nil) | 2766 | (setq dired-switches-alist nil) |
| 2747 | (hack-dir-local-variables-non-file-buffer) ; before sorting | 2767 | (hack-dir-local-variables-non-file-buffer) ; before sorting |
| 2748 | (dired-sort-other dired-actual-switches t) | 2768 | (dired-sort-other dired-actual-switches t) |
diff --git a/lisp/tab-bar.el b/lisp/tab-bar.el index fa22500a04e..05631c3c8f3 100644 --- a/lisp/tab-bar.el +++ b/lisp/tab-bar.el | |||
| @@ -1292,6 +1292,9 @@ tab bar might wrap to the second line when it shouldn't.") | |||
| 1292 | frame 'buffer-list))) | 1292 | frame 'buffer-list))) |
| 1293 | (bbl (seq-filter #'buffer-live-p (frame-parameter | 1293 | (bbl (seq-filter #'buffer-live-p (frame-parameter |
| 1294 | frame 'buried-buffer-list)))) | 1294 | frame 'buried-buffer-list)))) |
| 1295 | (when tab-bar-select-restore-context | ||
| 1296 | (window-point-context-set)) | ||
| 1297 | |||
| 1295 | `(tab | 1298 | `(tab |
| 1296 | (name . ,(if tab-explicit-name | 1299 | (name . ,(if tab-explicit-name |
| 1297 | (alist-get 'name tab) | 1300 | (alist-get 'name tab) |
| @@ -1442,6 +1445,16 @@ if it was visiting a file." | |||
| 1442 | (setq buffer-read-only t) | 1445 | (setq buffer-read-only t) |
| 1443 | (set-window-buffer window new-buffer)))))) | 1446 | (set-window-buffer window new-buffer)))))) |
| 1444 | 1447 | ||
| 1448 | (defcustom tab-bar-select-restore-context t | ||
| 1449 | "If this is non-nil, try to restore window points from their contexts. | ||
| 1450 | This will try to find the same position in every window where point was | ||
| 1451 | before switching away from this tab. After selecting this tab, | ||
| 1452 | point in every window will be moved to its previous position | ||
| 1453 | in the buffer even when the buffer was modified." | ||
| 1454 | :type 'boolean | ||
| 1455 | :group 'tab-bar | ||
| 1456 | :version "30.1") | ||
| 1457 | |||
| 1445 | (defvar tab-bar-minibuffer-restore-tab nil | 1458 | (defvar tab-bar-minibuffer-restore-tab nil |
| 1446 | "Tab number for `tab-bar-minibuffer-restore-tab'.") | 1459 | "Tab number for `tab-bar-minibuffer-restore-tab'.") |
| 1447 | 1460 | ||
| @@ -1539,6 +1552,9 @@ Negative TAB-NUMBER counts tabs from the end of the tab bar." | |||
| 1539 | (select-window (get-mru-window))) | 1552 | (select-window (get-mru-window))) |
| 1540 | (window-state-put ws nil 'safe))) | 1553 | (window-state-put ws nil 'safe))) |
| 1541 | 1554 | ||
| 1555 | (when tab-bar-select-restore-context | ||
| 1556 | (window-point-context-use)) | ||
| 1557 | |||
| 1542 | ;; Select the minibuffer when it was active before switching tabs | 1558 | ;; Select the minibuffer when it was active before switching tabs |
| 1543 | (when (and minibuffer-was-active (active-minibuffer-window)) | 1559 | (when (and minibuffer-was-active (active-minibuffer-window)) |
| 1544 | (select-window (active-minibuffer-window))) | 1560 | (select-window (active-minibuffer-window))) |
diff --git a/lisp/window.el b/lisp/window.el index 46de1819c69..3867f6fa6ef 100644 --- a/lisp/window.el +++ b/lisp/window.el | |||
| @@ -10838,6 +10838,78 @@ displaying that processes's buffer." | |||
| 10838 | (set-process-window-size process (cdr size) (car size)))))))))) | 10838 | (set-process-window-size process (cdr size) (car size)))))))))) |
| 10839 | 10839 | ||
| 10840 | (add-hook 'window-configuration-change-hook 'window--adjust-process-windows) | 10840 | (add-hook 'window-configuration-change-hook 'window--adjust-process-windows) |
| 10841 | |||
| 10842 | |||
| 10843 | ;;; Window point context | ||
| 10844 | |||
| 10845 | (defun window-point-context-set () | ||
| 10846 | "Set context near the window point. | ||
| 10847 | Call function specified by `window-point-context-set-function' for every | ||
| 10848 | live window on the selected frame with that window as sole argument. | ||
| 10849 | The function called is supposed to return a context of the window's point | ||
| 10850 | that can be later used as argument for `window-point-context-use-function'. | ||
| 10851 | Remember the returned context in the window parameter `context'." | ||
| 10852 | (walk-windows | ||
| 10853 | (lambda (w) | ||
| 10854 | (when-let ((fn (buffer-local-value 'window-point-context-set-function | ||
| 10855 | (window-buffer w))) | ||
| 10856 | ((functionp fn)) | ||
| 10857 | (context (funcall fn w))) | ||
| 10858 | (set-window-parameter w 'context (cons (buffer-name) context)))) | ||
| 10859 | 'nomini)) | ||
| 10860 | |||
| 10861 | (defun window-point-context-use () | ||
| 10862 | "Use context to relocate the window point. | ||
| 10863 | Call function specified by `window-point-context-use-function' to move the | ||
| 10864 | window point according to the previously saved context. For every live | ||
| 10865 | window on the selected frame this function is called with two arguments: | ||
| 10866 | the window and the context data structure saved by | ||
| 10867 | `window-point-context-set-function' in the window parameter `context'. | ||
| 10868 | The function called is supposed to set the window point to the location | ||
| 10869 | found by the provided context." | ||
| 10870 | (walk-windows | ||
| 10871 | (lambda (w) | ||
| 10872 | (when-let ((fn (buffer-local-value 'window-point-context-use-function | ||
| 10873 | (window-buffer w))) | ||
| 10874 | ((functionp fn)) | ||
| 10875 | (context (window-parameter w 'context)) | ||
| 10876 | ((equal (buffer-name) (car context)))) | ||
| 10877 | (funcall fn w (cdr context)) | ||
| 10878 | (set-window-parameter w 'context nil))) | ||
| 10879 | 'nomini)) | ||
| 10880 | |||
| 10881 | (add-to-list 'window-persistent-parameters '(context . writable)) | ||
| 10882 | |||
| 10883 | (defun window-point-context-set-default-function (w) | ||
| 10884 | "Set context of file buffers to the front and rear strings." | ||
| 10885 | (with-current-buffer (window-buffer w) | ||
| 10886 | (when buffer-file-name | ||
| 10887 | (let ((point (window-point w))) | ||
| 10888 | `((front-context-string | ||
| 10889 | . ,(buffer-substring-no-properties | ||
| 10890 | point (min (+ point 16) (point-max)))) | ||
| 10891 | (rear-context-string | ||
| 10892 | . ,(buffer-substring-no-properties | ||
| 10893 | point (max (- point 16) (point-min))))))))) | ||
| 10894 | |||
| 10895 | (defun window-point-context-use-default-function (w context) | ||
| 10896 | "Restore context of file buffers by the front and rear strings." | ||
| 10897 | (with-current-buffer (window-buffer w) | ||
| 10898 | (let ((point (window-point w))) | ||
| 10899 | (save-excursion | ||
| 10900 | (goto-char point) | ||
| 10901 | (when-let ((f (alist-get 'front-context-string context)) | ||
| 10902 | ((search-forward f (point-max) t))) | ||
| 10903 | (goto-char (match-beginning 0)) | ||
| 10904 | (when-let ((r (alist-get 'rear-context-string context)) | ||
| 10905 | ((search-backward r (point-min) t))) | ||
| 10906 | (goto-char (match-end 0)) | ||
| 10907 | (setq point (point))))) | ||
| 10908 | (set-window-point w point)))) | ||
| 10909 | |||
| 10910 | (defvar window-point-context-set-function 'window-point-context-set-default-function) | ||
| 10911 | (defvar window-point-context-use-function 'window-point-context-use-default-function) | ||
| 10912 | |||
| 10841 | 10913 | ||
| 10842 | ;; Some of these are in tutorial--default-keys, so update that if you | 10914 | ;; Some of these are in tutorial--default-keys, so update that if you |
| 10843 | ;; change these. | 10915 | ;; change these. |