New functions to set and use context of window points (bug#33871)
* lisp/dired.el (dired-mode): Set buffer-local 'window-point-context-set-function' to remember 'dired-filename' or 'position' in the window with the Dired buffer. Set buffer-local 'window-point-context-use-function' to restore the remembered position of the window point. * lisp/tab-bar.el (tab-bar--tab): Use window-point-context-set. (tab-bar-select-restore-context): New user option. (tab-bar-select-tab): Use window-point-context-use. * lisp/window.el: Add '(context . writable)' to 'window-persistent-parameters'. (window-point-context-set, window-point-context-use): New functions. (window-point-context-set-default-function) (window-point-context-use-default-function): New functions. (window-point-context-set-function) (window-point-context-use-function): New variables.
This commit is contained in:
parent
617debf673
commit
c3781bf59e
4 changed files with 124 additions and 0 deletions
16
etc/NEWS
16
etc/NEWS
|
@ -309,8 +309,24 @@ It specifies how 'set-window-configuration' and 'window-state-put'
|
|||
should proceed with windows whose buffer was killed after the
|
||||
corresponding configuration or state was recorded.
|
||||
|
||||
*** New variable 'window-point-context-set-function'.
|
||||
It can be used to set a context for window point in all windows by
|
||||
'window-point-context-set' before calling 'current-window-configuration'
|
||||
and 'window-state-get'. Then later another new variable
|
||||
'window-point-context-use-function' can be used by
|
||||
'window-point-context-use' after 'set-window-configuration' and
|
||||
'window-state-put' to restore positions of window points
|
||||
according to the context stored in a window parameter.
|
||||
|
||||
** Tab Bars and Tab Lines
|
||||
|
||||
---
|
||||
*** New user option 'tab-bar-select-restore-context'.
|
||||
It uses 'window-point-context-set' to save contexts where
|
||||
window points were located before switching away from the tab,
|
||||
and 'window-point-context-use' to restore positions of window
|
||||
points after switching back to that tab.
|
||||
|
||||
---
|
||||
*** New user option 'tab-bar-select-restore-windows'.
|
||||
It defines what to do with windows whose buffer was killed
|
||||
|
|
|
@ -2743,6 +2743,26 @@ Keybindings:
|
|||
'(dired-font-lock-keywords t nil nil beginning-of-line))
|
||||
(setq-local desktop-save-buffer 'dired-desktop-buffer-misc-data)
|
||||
(setq-local grep-read-files-function #'dired-grep-read-files)
|
||||
(setq-local window-point-context-set-function
|
||||
(lambda (w)
|
||||
(with-current-buffer (window-buffer w)
|
||||
(let ((point (window-point w)))
|
||||
(save-excursion
|
||||
(goto-char point)
|
||||
(if-let ((f (dired-get-filename nil t)))
|
||||
`((dired-filename . ,f))
|
||||
`((position . ,(point)))))))))
|
||||
(setq-local window-point-context-use-function
|
||||
(lambda (w context)
|
||||
(with-current-buffer (window-buffer w)
|
||||
(let ((point (window-point w)))
|
||||
(save-excursion
|
||||
(if-let ((f (alist-get 'dired-filename context)))
|
||||
(dired-goto-file f)
|
||||
(when-let ((p (alist-get 'position context)))
|
||||
(goto-char p)))
|
||||
(setq point (point)))
|
||||
(set-window-point w point)))))
|
||||
(setq dired-switches-alist nil)
|
||||
(hack-dir-local-variables-non-file-buffer) ; before sorting
|
||||
(dired-sort-other dired-actual-switches t)
|
||||
|
|
|
@ -1292,6 +1292,9 @@ tab bar might wrap to the second line when it shouldn't.")
|
|||
frame 'buffer-list)))
|
||||
(bbl (seq-filter #'buffer-live-p (frame-parameter
|
||||
frame 'buried-buffer-list))))
|
||||
(when tab-bar-select-restore-context
|
||||
(window-point-context-set))
|
||||
|
||||
`(tab
|
||||
(name . ,(if tab-explicit-name
|
||||
(alist-get 'name tab)
|
||||
|
@ -1442,6 +1445,16 @@ if it was visiting a file."
|
|||
(setq buffer-read-only t)
|
||||
(set-window-buffer window new-buffer))))))
|
||||
|
||||
(defcustom tab-bar-select-restore-context t
|
||||
"If this is non-nil, try to restore window points from their contexts.
|
||||
This will try to find the same position in every window where point was
|
||||
before switching away from this tab. After selecting this tab,
|
||||
point in every window will be moved to its previous position
|
||||
in the buffer even when the buffer was modified."
|
||||
:type 'boolean
|
||||
:group 'tab-bar
|
||||
:version "30.1")
|
||||
|
||||
(defvar tab-bar-minibuffer-restore-tab nil
|
||||
"Tab number for `tab-bar-minibuffer-restore-tab'.")
|
||||
|
||||
|
@ -1539,6 +1552,9 @@ Negative TAB-NUMBER counts tabs from the end of the tab bar."
|
|||
(select-window (get-mru-window)))
|
||||
(window-state-put ws nil 'safe)))
|
||||
|
||||
(when tab-bar-select-restore-context
|
||||
(window-point-context-use))
|
||||
|
||||
;; Select the minibuffer when it was active before switching tabs
|
||||
(when (and minibuffer-was-active (active-minibuffer-window))
|
||||
(select-window (active-minibuffer-window)))
|
||||
|
|
|
@ -10838,6 +10838,78 @@ displaying that processes's buffer."
|
|||
(set-process-window-size process (cdr size) (car size))))))))))
|
||||
|
||||
(add-hook 'window-configuration-change-hook 'window--adjust-process-windows)
|
||||
|
||||
|
||||
;;; Window point context
|
||||
|
||||
(defun window-point-context-set ()
|
||||
"Set context near the window point.
|
||||
Call function specified by `window-point-context-set-function' for every
|
||||
live window on the selected frame with that window as sole argument.
|
||||
The function called is supposed to return a context of the window's point
|
||||
that can be later used as argument for `window-point-context-use-function'.
|
||||
Remember the returned context in the window parameter `context'."
|
||||
(walk-windows
|
||||
(lambda (w)
|
||||
(when-let ((fn (buffer-local-value 'window-point-context-set-function
|
||||
(window-buffer w)))
|
||||
((functionp fn))
|
||||
(context (funcall fn w)))
|
||||
(set-window-parameter w 'context (cons (buffer-name) context))))
|
||||
'nomini))
|
||||
|
||||
(defun window-point-context-use ()
|
||||
"Use context to relocate the window point.
|
||||
Call function specified by `window-point-context-use-function' to move the
|
||||
window point according to the previously saved context. For every live
|
||||
window on the selected frame this function is called with two arguments:
|
||||
the window and the context data structure saved by
|
||||
`window-point-context-set-function' in the window parameter `context'.
|
||||
The function called is supposed to set the window point to the location
|
||||
found by the provided context."
|
||||
(walk-windows
|
||||
(lambda (w)
|
||||
(when-let ((fn (buffer-local-value 'window-point-context-use-function
|
||||
(window-buffer w)))
|
||||
((functionp fn))
|
||||
(context (window-parameter w 'context))
|
||||
((equal (buffer-name) (car context))))
|
||||
(funcall fn w (cdr context))
|
||||
(set-window-parameter w 'context nil)))
|
||||
'nomini))
|
||||
|
||||
(add-to-list 'window-persistent-parameters '(context . writable))
|
||||
|
||||
(defun window-point-context-set-default-function (w)
|
||||
"Set context of file buffers to the front and rear strings."
|
||||
(with-current-buffer (window-buffer w)
|
||||
(when buffer-file-name
|
||||
(let ((point (window-point w)))
|
||||
`((front-context-string
|
||||
. ,(buffer-substring-no-properties
|
||||
point (min (+ point 16) (point-max))))
|
||||
(rear-context-string
|
||||
. ,(buffer-substring-no-properties
|
||||
point (max (- point 16) (point-min)))))))))
|
||||
|
||||
(defun window-point-context-use-default-function (w context)
|
||||
"Restore context of file buffers by the front and rear strings."
|
||||
(with-current-buffer (window-buffer w)
|
||||
(let ((point (window-point w)))
|
||||
(save-excursion
|
||||
(goto-char point)
|
||||
(when-let ((f (alist-get 'front-context-string context))
|
||||
((search-forward f (point-max) t)))
|
||||
(goto-char (match-beginning 0))
|
||||
(when-let ((r (alist-get 'rear-context-string context))
|
||||
((search-backward r (point-min) t)))
|
||||
(goto-char (match-end 0))
|
||||
(setq point (point)))))
|
||||
(set-window-point w point))))
|
||||
|
||||
(defvar window-point-context-set-function 'window-point-context-set-default-function)
|
||||
(defvar window-point-context-use-function 'window-point-context-use-default-function)
|
||||
|
||||
|
||||
;; Some of these are in tutorial--default-keys, so update that if you
|
||||
;; change these.
|
||||
|
|
Loading…
Add table
Reference in a new issue