Function: shell-resync-dirs

shell-resync-dirs is an interactive and byte-compiled function defined in shell.el.gz.

Signature

(shell-resync-dirs)

Documentation

Resync the buffer's idea of the current directory stack.

This command queries the shell with the command bound to shell-dirstack-query (default "dirs"), reads the next line output and parses it to form the new directory stack. DON'T issue this command unless the buffer is at a shell prompt. Also, note that if some other subprocess decides to do output immediately after the query, its output will be taken as the new directory stack -- you lose. If this happens, just do the command again.

Key Bindings

Aliases

dirs

Source Code

;; Defined in /usr/src/emacs/lisp/shell.el.gz
(defun shell-resync-dirs ()
  "Resync the buffer's idea of the current directory stack.
This command queries the shell with the command bound to
`shell-dirstack-query' (default \"dirs\"), reads the next
line output and parses it to form the new directory stack.
DON'T issue this command unless the buffer is at a shell prompt.
Also, note that if some other subprocess decides to do output
immediately after the query, its output will be taken as the
new directory stack -- you lose.  If this happens, just do the
command again."
  (interactive)
  (let* ((proc (get-buffer-process (current-buffer)))
	 (pmark (process-mark proc))
	 (started-at-pmark (= (point) (marker-position pmark))))
    (save-excursion
      (goto-char pmark)
      ;; If the process echoes commands, don't insert a fake command in
      ;; the buffer or it will appear twice.
      (unless comint-process-echoes
	(insert shell-dirstack-query) (insert "\n"))
      (sit-for 0)			; force redisplay
      (comint-send-string proc shell-dirstack-query)
      (comint-send-string proc "\n")
      (set-marker pmark (point))
      (let ((pt (point))
	    (regexp
	     (concat
	      (if comint-process-echoes
		  ;; Skip command echo if the process echoes
		  (concat "\\(" (regexp-quote shell-dirstack-query) "\n\\)")
		"\\(\\)")
	      "\\(.+\n\\)")))
	;; This extra newline prevents the user's pending input from spoofing us.
	(insert "\n") (backward-char 1)
	;; Wait for one line.
	(while (not (looking-at regexp))
	  (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)))))
    (if started-at-pmark (goto-char (marker-position pmark)))))