ShellDirtrackByProcfs

This has the same goal as ShellDirtrackByPrompt but uses a different approach. It doesn’t require you to change your shell’s rc-file.

  (defun track-shell-directory/procfs ()
    (shell-dirtrack-mode 0)
    (add-hook 'comint-preoutput-filter-functions
              (lambda (str)
                (prog1 str
                  (when (string-match comint-prompt-regexp str)
                    (cd (file-symlink-p
                         (format "/proc/%s/cwd" (process-id
                                                 (get-buffer-process
                                                  (current-buffer)))))))))
              nil t))
  (add-hook 'shell-mode-hook 'track-shell-directory/procfs)

This is a problem that disturbed me for a long long time. A very neat solution without making changes to shell script.

That’s much better. I wrapped it nicely in a minor mode.

  (defun shell-procfs-dirtrack (str)
    (prog1 str
      (when (string-match comint-prompt-regexp str)
        (let ((directory (file-symlink-p
                          (format "/proc/%s/cwd"
                                  (process-id
                                   (get-buffer-process
                                    (current-buffer)))))))
          (when (file-directory-p directory)
            (cd directory))))))
  
  (define-minor-mode shell-procfs-dirtrack-mode
    "Track shell directory by inspecting procfs."
    nil nil nil
    (cond (shell-procfs-dirtrack-mode
           (when (bound-and-true-p shell-dirtrack-mode)
             (shell-dirtrack-mode 0))
           (when (bound-and-true-p dirtrack-mode)
             (dirtrack-mode 0))
           (add-hook 'comint-preoutput-filter-functions
                     'shell-procfs-dirtrack nil t))
          (t
           (remove-hook 'comint-preoutput-filter-functions
                        'shell-procfs-dirtrack t))))