summaryrefslogtreecommitdiff
path: root/lisp
diff options
context:
space:
mode:
Diffstat (limited to 'lisp')
-rw-r--r--lisp/autoinsert.el2
-rw-r--r--lisp/emacs-lisp/seq.el1
-rw-r--r--lisp/frame.el17
-rw-r--r--lisp/gnus/gnus-cloud.el3
-rw-r--r--lisp/info.el18
-rw-r--r--lisp/menu-bar.el4
-rw-r--r--lisp/net/tramp-smb.el4
-rw-r--r--lisp/progmodes/cc-engine.el4
-rw-r--r--lisp/progmodes/cc-langs.el5
-rw-r--r--lisp/progmodes/pascal.el53
-rw-r--r--lisp/progmodes/project.el50
-rw-r--r--lisp/sort.el5
-rw-r--r--lisp/tab-bar.el6
-rw-r--r--lisp/term/tty-colors.el2
-rw-r--r--lisp/vc/vc-dir.el7
-rw-r--r--lisp/vc/vc-hooks.el5
-rw-r--r--lisp/vc/vc.el10
-rw-r--r--lisp/window.el55
18 files changed, 174 insertions, 77 deletions
diff --git a/lisp/autoinsert.el b/lisp/autoinsert.el
index 25961d41089..4af3d631a2c 100644
--- a/lisp/autoinsert.el
+++ b/lisp/autoinsert.el
@@ -396,7 +396,7 @@ Matches the visited file name against the elements of `auto-insert-alist'."
;; which might ask the user for something
(switch-to-buffer (current-buffer))
(if (and (consp action)
- (not (eq (car action) 'lambda)))
+ (not (functionp action)))
(skeleton-insert action)
(funcall action)))))
(if (vectorp action)
diff --git a/lisp/emacs-lisp/seq.el b/lisp/emacs-lisp/seq.el
index e3037a71901..4c1a1797adc 100644
--- a/lisp/emacs-lisp/seq.el
+++ b/lisp/emacs-lisp/seq.el
@@ -348,6 +348,7 @@ If SEQUENCE is empty, return INITIAL-VALUE and FUNCTION is not called."
(setq acc (funcall function acc elt)))
acc)))
+;;;###autoload
(cl-defgeneric seq-every-p (pred sequence)
"Return non-nil if (PRED element) is non-nil for all elements of SEQUENCE."
(catch 'seq--break
diff --git a/lisp/frame.el b/lisp/frame.el
index 6c2f774709e..77080b76e4f 100644
--- a/lisp/frame.el
+++ b/lisp/frame.el
@@ -1070,6 +1070,22 @@ that variable should be nil."
(setq arg (1+ arg)))
(select-frame-set-input-focus frame)))
+(defun other-frame-prefix ()
+ "Display the buffer of the next command in a new frame.
+The next buffer is the buffer displayed by the next command invoked
+immediately after this command (ignoring reading from the minibuffer).
+Creates a new frame before displaying the buffer.
+When `switch-to-buffer-obey-display-actions' is non-nil,
+`switch-to-buffer' commands are also supported."
+ (interactive)
+ (display-buffer-override-next-command
+ (lambda (buffer alist)
+ (cons (display-buffer-pop-up-frame
+ buffer (append '((inhibit-same-window . t))
+ alist))
+ 'frame)))
+ (message "Display next command buffer in a new frame..."))
+
(defun iconify-or-deiconify-frame ()
"Iconify the selected frame, or deiconify if it's currently an icon."
(interactive)
@@ -2697,6 +2713,7 @@ See also `toggle-frame-maximized'."
(define-key ctl-x-5-map "1" 'delete-other-frames)
(define-key ctl-x-5-map "0" 'delete-frame)
(define-key ctl-x-5-map "o" 'other-frame)
+(define-key ctl-x-5-map "5" 'other-frame-prefix)
(define-key global-map [f11] 'toggle-frame-fullscreen)
(define-key global-map [(meta f10)] 'toggle-frame-maximized)
(define-key esc-map [f10] 'toggle-frame-maximized)
diff --git a/lisp/gnus/gnus-cloud.el b/lisp/gnus/gnus-cloud.el
index 5028da5e8df..673a4d22988 100644
--- a/lisp/gnus/gnus-cloud.el
+++ b/lisp/gnus/gnus-cloud.el
@@ -478,8 +478,7 @@ Otherwise, returns the Gnus Cloud data chunks."
(push (gnus-cloud-parse-chunk) chunks)
(forward-line 1))))
(if update
- (progn
- (mapc #'gnus-cloud-update-all chunks)
+ (prog1 (mapcar #'gnus-cloud-update-all chunks)
(setq gnus-cloud-sequence highest-sequence-seen))
chunks)))
diff --git a/lisp/info.el b/lisp/info.el
index d579ecc5a3b..78f88947c79 100644
--- a/lisp/info.el
+++ b/lisp/info.el
@@ -2265,7 +2265,8 @@ End of submatch 0, 1, and 3 are the same, so you can safely concat."
(match-string-no-properties 1)))
(defun Info-next ()
- "Go to the next node of this node."
+ "Go to the \"next\" node, staying on the same hierarchical level.
+This command doesn't descend into sub-nodes, like \\<Info-mode-map>\\[Info-forward-node] does."
(interactive)
;; In case another window is currently selected
(save-window-excursion
@@ -2273,7 +2274,8 @@ End of submatch 0, 1, and 3 are the same, so you can safely concat."
(Info-goto-node (Info-extract-pointer "next"))))
(defun Info-prev ()
- "Go to the previous node of this node."
+ "Go to the \"previous\" node, staying on the same hierarchical level.
+This command doesn't go up to the parent node, like \\<Info-mode-map>\\[Info-backward-node] does."
(interactive)
;; In case another window is currently selected
(save-window-excursion
@@ -2887,7 +2889,13 @@ N is the digit argument used to invoke this command."
(Info-goto-node (Info-extract-menu-counting nil)))))
(defun Info-forward-node (&optional not-down not-up no-error)
- "Go forward one node, considering all nodes as forming one sequence."
+ "Go forward one node, considering all nodes as forming one sequence.
+Interactively, if the current node has sub-nodes, descend into the first
+sub-node; otherwise go to the \"next\" node, if it exists, else go \"up\"
+to the parent node.
+When called from Lisp, NOT-DOWN non-nil means don't descend into sub-nodes,
+NOT-UP non-nil means don't go to parent nodes, and NO-ERROR non-nil means
+don't signal a user-error if there's no node to go to."
(interactive)
(goto-char (point-min))
(forward-line 1)
@@ -2922,7 +2930,9 @@ N is the digit argument used to invoke this command."
(t (user-error "No pointer forward from this node")))))
(defun Info-backward-node ()
- "Go backward one node, considering all nodes as forming one sequence."
+ "Go backward one node, considering all nodes as forming one sequence.
+If the current node has a \"previous\" node, go to it, descending into its
+last sub-node, if any; otherwise go \"up\" to the parent node."
(interactive)
(let ((prevnode (Info-extract-pointer "prev[ious]*" t))
(upnode (Info-extract-pointer "up" t))
diff --git a/lisp/menu-bar.el b/lisp/menu-bar.el
index 9bc667acd61..bc094c9050d 100644
--- a/lisp/menu-bar.el
+++ b/lisp/menu-bar.el
@@ -1815,6 +1815,10 @@ mail status in mode line"))
(bindings--define-key menu [list-keybindings]
'(menu-item "List Key Bindings" describe-bindings
:help "Display all current key bindings (keyboard shortcuts)"))
+ (bindings--define-key menu [list-recent-keystrokes]
+ '(menu-item "Show Recent Inputs" view-lossage
+ :help "Display last few input events and the commands \
+they ran"))
(bindings--define-key menu [describe-current-display-table]
'(menu-item "Describe Display Table" describe-current-display-table
:help "Describe the current display table"))
diff --git a/lisp/net/tramp-smb.el b/lisp/net/tramp-smb.el
index 357e9a220ce..947e6a767c7 100644
--- a/lisp/net/tramp-smb.el
+++ b/lisp/net/tramp-smb.el
@@ -704,11 +704,11 @@ PRESERVE-UID-GID and PRESERVE-EXTENDED-ATTRIBUTES are completely ignored."
(delete nil
(mapcar (lambda (x) (when (string-match-p match x) x))
result))))
- ;; Append directory.
+ ;; Prepend directory.
(when full
(setq result
(mapcar
- (lambda (x) (format "%s/%s" directory x))
+ (lambda (x) (format "%s/%s" (directory-file-name directory) x))
result)))
;; Sort them if necessary.
(unless nosort (setq result (sort result #'string-lessp)))
diff --git a/lisp/progmodes/cc-engine.el b/lisp/progmodes/cc-engine.el
index 8c8296fd6da..888184d2b46 100644
--- a/lisp/progmodes/cc-engine.el
+++ b/lisp/progmodes/cc-engine.el
@@ -3137,7 +3137,7 @@ comment at the start of cc-engine.el for more info."
(not base) ; FIXME!!! Compare base and far-base??
; (2019-05-21)
(not end)
- (> here end))
+ (>= here end))
(progn
(setq far-base-and-state (c-parse-ps-state-below here)
far-base (car far-base-and-state)
@@ -3150,7 +3150,7 @@ comment at the start of cc-engine.el for more info."
(or
(and (> here base) (null end))
(null (nth 8 s))
- (and end (> here end))
+ (and end (>= here end))
(not
(or
(and (nth 3 s) ; string
diff --git a/lisp/progmodes/cc-langs.el b/lisp/progmodes/cc-langs.el
index 3ac4aad90b8..00babf95332 100644
--- a/lisp/progmodes/cc-langs.el
+++ b/lisp/progmodes/cc-langs.el
@@ -2787,7 +2787,7 @@ Keywords here should also be in `c-block-stmt-1-kwds'."
java '("for" "if" "switch" "while" "catch" "synchronized")
idl nil
pike '("for" "if" "switch" "while" "foreach")
- awk '("for" "if" "while"))
+ awk '("for" "if" "switch" "while"))
(c-lang-defconst c-block-stmt-2-key
;; Regexp matching the start of any statement followed by a paren sexp
@@ -2867,8 +2867,7 @@ nevertheless contains a list separated with `;' and not `,'."
(c-lang-defconst c-case-kwds
"The keyword(s) which introduce a \"case\" like construct.
This construct is \"<keyword> <expression> :\"."
- t '("case")
- awk nil)
+ t '("case"))
(c-lang-defconst c-case-kwds-regexp
;; Adorned regexp matching any "case"-like keyword.
diff --git a/lisp/progmodes/pascal.el b/lisp/progmodes/pascal.el
index 536a16dbb3c..fce059bafc7 100644
--- a/lisp/progmodes/pascal.el
+++ b/lisp/progmodes/pascal.el
@@ -589,7 +589,7 @@ See also `pascal-comment-area'."
(interactive)
(catch 'found
(if (not (looking-at (concat "\\s \\|\\s)\\|" pascal-defun-re)))
- (forward-sexp 1))
+ (ignore-errors (forward-sexp 1)))
(let ((nest 0) (max -1) (func 0)
(reg (concat pascal-beg-block-re "\\|"
pascal-end-block-re "\\|"
@@ -1170,26 +1170,27 @@ indent of the current line in parameterlist."
(defun pascal-type-completion (pascal-str)
"Calculate all possible completions for types."
- (let ((start (point))
- (pascal-all ())
- goon)
- ;; Search for all reachable type declarations
- (while (or (pascal-beg-of-defun)
- (setq goon (not goon)))
- (save-excursion
- (if (and (< start (prog1 (save-excursion (pascal-end-of-defun)
- (point))
- (forward-char 1)))
- (re-search-forward
- "\\<type\\>\\|\\<\\(begin\\|function\\|procedure\\)\\>"
- start t)
- (not (match-end 1)))
- ;; Check current type declaration
- (setq pascal-all
- (nconc (pascal-get-completion-decl pascal-str)
- pascal-all)))))
+ (save-excursion
+ (let ((start (point))
+ (pascal-all ())
+ goon)
+ ;; Search for all reachable type declarations
+ (while (or (pascal-beg-of-defun)
+ (setq goon (not goon)))
+ (save-excursion
+ (if (and (< start (prog1 (save-excursion (pascal-end-of-defun)
+ (point))
+ (forward-char 1)))
+ (re-search-forward
+ "\\<type\\>\\|\\<\\(begin\\|function\\|procedure\\)\\>"
+ start t)
+ (not (match-end 1)))
+ ;; Check current type declaration
+ (setq pascal-all
+ (nconc (pascal-get-completion-decl pascal-str)
+ pascal-all)))))
- pascal-all))
+ pascal-all)))
(defun pascal-var-completion (prefix)
"Calculate all possible completions for variables (or constants)."
@@ -1263,11 +1264,13 @@ indent of the current line in parameterlist."
(and (eq state 'defun)
(save-excursion
(re-search-backward ")[ \t]*:" (point-at-bol) t))))
- (if (or (eq state 'paramlist) (eq state 'defun))
- (pascal-beg-of-defun))
- (nconc
- (pascal-type-completion pascal-str)
- (pascal-keyword-completion pascal-type-keywords pascal-str)))
+ (save-excursion
+ (if (or (eq state 'paramlist) (eq state 'defun))
+ (pascal-beg-of-defun))
+ (nconc
+ (pascal-type-completion pascal-str)
+ (pascal-keyword-completion pascal-type-keywords
+ pascal-str))))
( ;--Starting a new statement
(and (not (eq state 'contexp))
(save-excursion
diff --git a/lisp/progmodes/project.el b/lisp/progmodes/project.el
index bfbe2362721..0a15939d243 100644
--- a/lisp/progmodes/project.el
+++ b/lisp/progmodes/project.el
@@ -449,7 +449,7 @@ backend implementation of `project-external-roots'.")
(cl-defmethod project-ignores ((project (head vc)) dir)
(let* ((root (cdr project))
- backend)
+ backend)
(append
(when (file-equal-p dir root)
(setq backend (vc-responsible-backend root))
@@ -674,8 +674,8 @@ PREDICATE, HIST, and DEFAULT have the same meaning as in
(let* ((all-files (project-files project dirs))
(completion-ignore-case read-file-name-completion-ignore-case)
(file (funcall project-read-file-name-function
- "Find file" all-files nil nil
- filename)))
+ "Find file" all-files nil nil
+ filename)))
(if (string= file "")
(user-error "You didn't specify the file")
(find-file file))))
@@ -719,7 +719,7 @@ PREDICATE, HIST, and DEFAULT have the same meaning as in
If a buffer already exists for running a shell in the project's root,
switch to it. Otherwise, create a new shell buffer.
With \\[universal-argument] prefix arg, create a new inferior shell buffer even
-if one already exist."
+if one already exists."
(interactive)
(let* ((default-directory (project-root (project-current t)))
(default-project-shell-name
@@ -738,14 +738,15 @@ if one already exist."
If a buffer already exists for running Eshell in the project's root,
switch to it. Otherwise, create a new Eshell buffer.
With \\[universal-argument] prefix arg, create a new Eshell buffer even
-if one already exist."
+if one already exists."
(interactive)
+ (defvar eshell-buffer-name)
(let* ((default-directory (project-root (project-current t)))
(eshell-buffer-name
- (concat "*" (file-name-nondirectory
- (directory-file-name
- (file-name-directory default-directory)))
- "-eshell*"))
+ (concat "*" (file-name-nondirectory
+ (directory-file-name
+ (file-name-directory default-directory)))
+ "-eshell*"))
(eshell-buffer (get-buffer eshell-buffer-name)))
(if (and eshell-buffer (not current-prefix-arg))
(pop-to-buffer eshell-buffer)
@@ -809,7 +810,8 @@ is inside the directory hierarchy of the project's root."
(predicate
(lambda (buffer)
;; BUFFER is an entry (BUF-NAME . BUF-OBJ) of Vbuffer_alist.
- (and (not (eq (cdr buffer) current-buffer))
+ (and (cdr buffer)
+ (not (eq (cdr buffer) current-buffer))
(when-let ((file (buffer-local-value 'default-directory
(cdr buffer))))
(file-in-directory-p file root))))))
@@ -818,10 +820,10 @@ is inside the directory hierarchy of the project's root."
"Switch to buffer: "
(when (funcall predicate (cons other-name other-buffer))
other-name)
- t
+ nil
predicate))))
-(defcustom project-kill-buffers-skip-conditions
+(defcustom project-kill-buffers-ignores
'("\\*Help\\*")
"Conditions for buffers `project-kill-buffers' should not kill.
Each condition is either a regular expression matching a buffer
@@ -829,7 +831,8 @@ name, or a predicate function that takes a buffer object as
argument and returns non-nil if it matches. Buffers that match
any of the conditions will not be killed."
:type '(repeat (choice regexp function))
- :version "28.1")
+ :version "28.1"
+ :package-version '(project . "0.5.0"))
(defun project--buffer-list (pr)
"Return the list of all buffers in project PR."
@@ -845,7 +848,7 @@ any of the conditions will not be killed."
;;;###autoload
(defun project-kill-buffers ()
"Kill all live buffers belonging to the current project.
-Certain buffers may be \"spared\", see `project-kill-buffers-skip-conditions'."
+Certain buffers may be \"spared\", see `project-kill-buffers-ignores'."
(interactive)
(let ((pr (project-current t)) bufs)
(dolist (buf (project--buffer-list pr))
@@ -855,7 +858,7 @@ Certain buffers may be \"spared\", see `project-kill-buffers-skip-conditions'."
(string-match-p c (buffer-name buf)))
((functionp c)
(funcall c buf))))
- project-kill-buffers-skip-conditions)
+ project-kill-buffers-ignores)
(push buf bufs)))
(when (yes-or-no-p (format "Kill %d buffers in %s? "
(length bufs) (project-root pr)))
@@ -871,7 +874,8 @@ Certain buffers may be \"spared\", see `project-kill-buffers-skip-conditions'."
:group 'project)
(defvar project--list 'unset
- "List of known project directories.")
+ "List structure containing root directories of known projects.
+With some possible metadata (to be decided).")
(defun project--read-project-list ()
"Initialize `project--list' using contents of `project-list-file'."
@@ -880,7 +884,13 @@ Certain buffers may be \"spared\", see `project-kill-buffers-skip-conditions'."
(when (file-exists-p filename)
(with-temp-buffer
(insert-file-contents filename)
- (read (current-buffer)))))))
+ (read (current-buffer)))))
+ (unless (seq-every-p
+ (lambda (elt) (stringp (car-safe elt)))
+ project--list)
+ (warn "Contents of %s are in wrong format, resetting"
+ project-list-file)
+ (setq project--list nil))))
(defun project--ensure-read-project-list ()
"Initialize `project--list' if it isn't already initialized."
@@ -933,6 +943,12 @@ It's also possible to enter an arbitrary directory not in the list."
(read-directory-name "Select directory: " default-directory nil t)
pr-dir)))
+;;;###autoload
+(defun project-known-project-roots ()
+ "Return the list of root directories of all known projects."
+ (project--ensure-read-project-list)
+ (mapcar #'car project--list))
+
;;; Project switching
diff --git a/lisp/sort.el b/lisp/sort.el
index de0e1b9519d..f878db24a3c 100644
--- a/lisp/sort.el
+++ b/lisp/sort.el
@@ -554,9 +554,6 @@ is the one that ends before END."
(if (> beg end)
(let (mid) (setq mid end end beg beg mid)))
(save-excursion
- (when (or (< (line-beginning-position) beg)
- (< end (line-end-position)))
- (user-error "There are no full lines in the region"))
;; Put beg at the start of a line and end and the end of one --
;; the largest possible region which fits this criteria.
(goto-char beg)
@@ -568,6 +565,8 @@ is the one that ends before END."
;; reversal; it isn't difficult to add it afterward.
(or (and (eolp) (not (bolp))) (progn (forward-line -1) (end-of-line)))
(setq end (point-marker))
+ (when (<= end beg)
+ (user-error "There are no full lines in the region"))
;; The real work. This thing cranks through memory on large regions.
(let (ll (do t))
(while do
diff --git a/lisp/tab-bar.el b/lisp/tab-bar.el
index b54258a4e4a..0a336e41658 100644
--- a/lisp/tab-bar.el
+++ b/lisp/tab-bar.el
@@ -1543,8 +1543,7 @@ Like \\[switch-to-buffer-other-frame] (which see), but creates a new tab."
(list (read-buffer-to-switch "Switch to buffer in other tab: ")))
(display-buffer (window-normalize-buffer-to-switch-to buffer-or-name)
'((display-buffer-in-tab)
- (inhibit-same-window . nil)
- (reusable-frames . t))
+ (inhibit-same-window . nil))
norecord))
(defun find-file-other-tab (filename &optional wildcards)
@@ -1575,8 +1574,7 @@ When `switch-to-buffer-obey-display-actions' is non-nil,
(lambda (buffer alist)
(cons (progn
(display-buffer-in-tab
- buffer (append alist '((inhibit-same-window . nil)
- (reusable-frames . t))))
+ buffer (append alist '((inhibit-same-window . nil))))
(selected-window))
'tab)))
(message "Display next command buffer in a new tab..."))
diff --git a/lisp/term/tty-colors.el b/lisp/term/tty-colors.el
index 73e2431822e..dda7fcc3691 100644
--- a/lisp/term/tty-colors.el
+++ b/lisp/term/tty-colors.el
@@ -923,7 +923,7 @@ The returned value reflects the standard Emacs definition of
COLOR (see the info node `(emacs) Colors'), regardless of whether
the terminal can display it, so the return value should be the
same regardless of what display is being used."
- (or (internal-color-values-from-color-spec color)
+ (or (color-values-from-color-spec color)
(cdr (assoc color color-name-rgb-alist))))
(defun tty-color-translate (color &optional frame)
diff --git a/lisp/vc/vc-dir.el b/lisp/vc/vc-dir.el
index a86c37c24ae..46be9b73801 100644
--- a/lisp/vc/vc-dir.el
+++ b/lisp/vc/vc-dir.el
@@ -1366,7 +1366,7 @@ These are the commands available for use in the file status buffer:
;; Otherwise if you do C-x v d -> C-x C-f -> C-x v d
;; you may get a new *vc-dir* buffer, different from the original
(file-truename (read-directory-name "VC status for directory: "
- (vc-root-dir) nil t
+ (vc-root-dir) (vc-known-roots) t
nil))
(if current-prefix-arg
(intern
@@ -1496,8 +1496,9 @@ This implements the `bookmark-make-record-function' type for
This implements the `handler' function interface for the record
type returned by `vc-dir-bookmark-make-record'."
(let* ((file (bookmark-prop-get bmk 'filename))
- (buf (save-window-excursion
- (vc-dir file) (current-buffer))))
+ (buf (progn ;; Don't use save-window-excursion (bug#39722)
+ (vc-dir file)
+ (current-buffer))))
(bookmark-default-handler
`("" (buffer . ,buf) . ,(bookmark-get-bookmark-record bmk)))))
diff --git a/lisp/vc/vc-hooks.el b/lisp/vc/vc-hooks.el
index ce72a49b955..46f55358de8 100644
--- a/lisp/vc/vc-hooks.el
+++ b/lisp/vc/vc-hooks.el
@@ -299,6 +299,11 @@ non-nil if FILE exists and its contents were successfully inserted."
(set-buffer-modified-p nil)
t))
+(declare-function project-try-vc "project")
+(defun vc-known-roots ()
+ "Return a list of known vc roots."
+ (seq-filter #'project-try-vc (project-known-project-roots)))
+
(defun vc-find-root (file witness)
"Find the root of a checked out project.
The function walks up the directory tree from FILE looking for WITNESS.
diff --git a/lisp/vc/vc.el b/lisp/vc/vc.el
index 9b12d449785..49323ef47d2 100644
--- a/lisp/vc/vc.el
+++ b/lisp/vc/vc.el
@@ -1074,11 +1074,9 @@ BEWARE: this function may change the current buffer."
(progn ;FIXME: Why not `with-current-buffer'? --Stef.
(set-buffer vc-parent-buffer)
(vc-deduce-fileset not-state-changing allow-unregistered state-model-only-files)))
- ((and (derived-mode-p 'log-view-mode)
+ ((and (not buffer-file-name)
(setq backend (vc-responsible-backend default-directory)))
(list backend nil))
- ((not buffer-file-name)
- (error "Buffer %s is not associated with a file" (buffer-name)))
((and allow-unregistered (not (vc-registered buffer-file-name)))
(if state-model-only-files
(list (vc-backend-for-registration (buffer-file-name))
@@ -2003,7 +2001,8 @@ saving the buffer."
rootdir working-revision)
(if backend
(setq rootdir (vc-call-backend backend 'root default-directory))
- (setq rootdir (read-directory-name "Directory for VC root-diff: "))
+ (setq rootdir (read-directory-name "Directory for VC root-diff: "
+ nil (vc-known-roots)))
(setq backend (vc-responsible-backend rootdir))
(if backend
(setq default-directory rootdir)
@@ -2547,7 +2546,8 @@ with its diffs (if the underlying VCS supports that)."
rootdir)
(if backend
(setq rootdir (vc-call-backend backend 'root default-directory))
- (setq rootdir (read-directory-name "Directory for VC revision log: "))
+ (setq rootdir (read-directory-name "Directory for VC revision log: "
+ nil (vc-known-roots)))
(setq backend (vc-responsible-backend rootdir))
(unless backend
(error "Directory is not version controlled")))
diff --git a/lisp/window.el b/lisp/window.el
index 998568e7b82..d499f9ab99a 100644
--- a/lisp/window.el
+++ b/lisp/window.el
@@ -4005,6 +4005,43 @@ always effectively nil."
;; Always return nil.
nil))))
+(defun other-window-prefix ()
+ "Display the buffer of the next command in a new window.
+The next buffer is the buffer displayed by the next command invoked
+immediately after this command (ignoring reading from the minibuffer).
+Creates a new window before displaying the buffer.
+When `switch-to-buffer-obey-display-actions' is non-nil,
+`switch-to-buffer' commands are also supported."
+ (interactive)
+ (display-buffer-override-next-command
+ (lambda (buffer alist)
+ (let ((alist (append '((inhibit-same-window . t)) alist))
+ window type)
+ (if (setq window (display-buffer-pop-up-window buffer alist))
+ (setq type 'window)
+ (setq window (display-buffer-use-some-window buffer alist)
+ type 'reuse))
+ (cons window type))))
+ (message "Display next command buffer in a new window..."))
+
+(defun same-window-prefix ()
+ "Display the buffer of the next command in the same window.
+The next buffer is the buffer displayed by the next command invoked
+immediately after this command (ignoring reading from the minibuffer).
+Even when the default rule should display the buffer in a new window,
+force its display in the already selected window.
+When `switch-to-buffer-obey-display-actions' is non-nil,
+`switch-to-buffer' commands are also supported."
+ (interactive)
+ (display-buffer-override-next-command
+ (lambda (buffer alist)
+ (setq alist (append '((inhibit-same-window . nil)) alist))
+ (cons (or
+ (display-buffer-same-window buffer alist)
+ (display-buffer-use-some-window buffer alist))
+ 'reuse)))
+ (message "Display next command buffer in the same window..."))
+
;; This should probably return non-nil when the selected window is part
;; of an atomic window whose root is the frame's root window.
(defun one-window-p (&optional nomini all-frames)
@@ -8590,19 +8627,24 @@ window; the function takes two arguments: an old and new window."
(let* ((old-window (or (minibuffer-selected-window) (selected-window)))
(new-window nil)
(minibuffer-depth (minibuffer-depth))
+ (clearfun (make-symbol "clear-display-buffer-overriding-action"))
(action (lambda (buffer alist)
(unless (> (minibuffer-depth) minibuffer-depth)
(let* ((ret (funcall pre-function buffer alist))
(window (car ret))
(type (cdr ret)))
(setq new-window (window--display-buffer buffer window
- type alist))))))
+ type alist))
+ ;; Reset display-buffer-overriding-action
+ ;; after the first buffer display action
+ (funcall clearfun)
+ (setq post-function nil)
+ new-window))))
(command this-command)
- (clearfun (make-symbol "clear-display-buffer-overriding-action"))
(exitfun
(lambda ()
- (setq display-buffer-overriding-action
- (delq action display-buffer-overriding-action))
+ (setcar display-buffer-overriding-action
+ (delq action (car display-buffer-overriding-action)))
(remove-hook 'post-command-hook clearfun)
(when (functionp post-function)
(funcall post-function old-window new-window)))))
@@ -8616,8 +8658,10 @@ window; the function takes two arguments: an old and new window."
;; adding the hook by the same command below.
(eq this-command command))
(funcall exitfun))))
+ ;; Reset display-buffer-overriding-action
+ ;; after the next command finishes
(add-hook 'post-command-hook clearfun)
- (push action display-buffer-overriding-action)))
+ (push action (car display-buffer-overriding-action))))
(defun set-window-text-height (window height)
@@ -10124,5 +10168,6 @@ displaying that processes's buffer."
(define-key ctl-x-map "-" 'shrink-window-if-larger-than-buffer)
(define-key ctl-x-map "+" 'balance-windows)
(define-key ctl-x-4-map "0" 'kill-buffer-and-window)
+(define-key ctl-x-4-map "4" 'other-window-prefix)
;;; window.el ends here