summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNoah Friedman <friedman@splode.com>2020-08-19 15:59:59 +0200
committerLars Ingebrigtsen <larsi@gnus.org>2020-08-19 15:59:59 +0200
commit90e65c826fab2092ad2099d7763538194c93e021 (patch)
tree2e5e49388d659926b5cd83ee959f6a114abed131
parent33a72465b53fd1dc71856ea4ad3376a05da35c73 (diff)
downloademacs-90e65c826fab2092ad2099d7763538194c93e021.tar.gz
Make shell-resync-dirs handle whitespace in directory names
* lisp/shell.el (shell-resync-dirs): Correctly handle whitespace in directory names (bug#23324).
-rw-r--r--lisp/shell.el54
1 files changed, 35 insertions, 19 deletions
diff --git a/lisp/shell.el b/lisp/shell.el
index 301a8cb0833..9667dab2afd 100644
--- a/lisp/shell.el
+++ b/lisp/shell.el
@@ -1035,25 +1035,41 @@ command again."
(accept-process-output proc)
(goto-char pt)))
(goto-char pmark) (delete-char 1) ; remove the extra newline
- ;; That's the dirlist. grab it & parse it.
- (let* ((dl (buffer-substring (match-beginning 2) (1- (match-end 2))))
- (dl-len (length dl))
- (ds '()) ; new dir stack
- (i 0))
- (while (< i dl-len)
- ;; regexp = optional whitespace, (non-whitespace), optional whitespace
- (string-match "\\s *\\(\\S +\\)\\s *" dl i) ; pick off next dir
- (setq ds (cons (concat comint-file-name-prefix
- (substring dl (match-beginning 1)
- (match-end 1)))
- ds))
- (setq i (match-end 0)))
- (let ((ds (nreverse ds)))
- (with-demoted-errors "Couldn't cd: %s"
- (shell-cd (car ds))
- (setq shell-dirstack (cdr ds)
- shell-last-dir (car shell-dirstack))
- (shell-dirstack-message)))))
+ ;; That's the dirlist. Grab it & parse it.
+ (let* ((dls (buffer-substring-no-properties
+ (match-beginning 0) (1- (match-end 0))))
+ (dlsl nil)
+ (pos 0)
+ (ds nil))
+ ;; Split the dirlist into whitespace and non-whitespace chunks.
+ ;; dlsl will be a reversed list of tokens.
+ (while (string-match "\\(\\S-+\\|\\s-+\\)" dls pos)
+ (push (match-string 1 dls) dlsl)
+ (setq pos (match-end 1)))
+
+ ;; Prepend trailing entries until they form an existing directory,
+ ;; whitespace and all. Discard the next whitespace and repeat.
+ (while dlsl
+ (let ((newelt "")
+ tem1 tem2)
+ (while newelt
+ ;; We need tem1 because we don't want to prepend
+ ;; `comint-file-name-prefix' repeatedly into newelt via tem2.
+ (setq tem1 (pop dlsl)
+ tem2 (concat comint-file-name-prefix tem1 newelt))
+ (cond ((file-directory-p tem2)
+ (push tem2 ds)
+ (when (string= " " (car dlsl))
+ (pop dlsl))
+ (setq newelt nil))
+ (t
+ (setq newelt (concat tem1 newelt)))))))
+
+ (with-demoted-errors "Couldn't cd: %s"
+ (shell-cd (car ds))
+ (setq shell-dirstack (cdr ds)
+ shell-last-dir (car shell-dirstack))
+ (shell-dirstack-message))))
(if started-at-pmark (goto-char (marker-position pmark)))))
;; For your typing convenience: