For the most part, I'm really liking shell-mode. I've configured it to read my .history file and if I spawn a dired or open a file it uses the current directory.

I'm using tcsh with the set implicitcd flag set. This allows me to type a directory and cd to it automatically, e.g.

% cd
<home directory>
% /tmp
% pwd

There are two problems with the default shell-mode configuration from my perspective (although they're fine for the default sh or csh settings).

1) I can't tab-complete directories in the first position, only executables. I'd like to be able to tab-complete directories here.

2) If I change directory without using cd emacs does not know to change the buffer's directory. I'd like to stat the first argument if there's only one argument and see if it's a directory and cd to it.

As for (2), the documentation mentions something about comint-input-filter-functions.

(defun comint-send-input (&optional no-newline artificial)
  "Send input to process.
After the process output mark, sends all text from the process mark to
point as input to the process.  Before the process output mark, calls
value of variable `comint-get-old-input' to retrieve old input, copies
it to the process mark, and sends it.

This command also sends and inserts a final newline, unless
NO-NEWLINE is non-nil.

Any history reference may be expanded depending on the value of the variable
`comint-input-autoexpand'.  The list of function names contained in the value
of `comint-input-filter-functions' is called on the input before sending it.
The input is entered into the input history ring, if the value of variable
`comint-input-filter' returns non-nil when called on the input.

But I'm a little concerned that comint-input-filter-functions may not be the appropriate place to parse input and determine if it constitutes changing directory because it's nil by default and emacs does parse the command if it starts with cd (but not chdir oddly enough).

(defvar comint-input-filter-functions '()
  "Abnormal hook run before input is sent to the process.
These functions get one argument, a string containing the text to send.")

1 Answer 1


For tab completion, I use company-mode:

(defun my-shell-mode-hook ()
 (define-key shell-mode-map (kbd "TAB") #'company-manual-begin))

(add-hook 'shell-mode-hook #'my-shell-mode-hook)

see wikemacs.

(source: wikemacs.org)

For 2) I think we could advice the input method to transform its input beforehand.

I myself don't write "cd" a lot any more, I mainly use shell-pop (see wiki) and if I must, I use my integration with the fasd tool, so I don't have to write full paths, but just something like d foo and it takes me to ~/projects/bla/foo, if I visited it already after installing fasd.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.