I have this simple function that opens an external shell (st) in the same directory of the current buffer:

(defun external-shell-in-dir ()
  (start-process "st" nil "st"))

However, if I type in the terminal emacsclient -e "(external-shell-in-dir)" it opens a terminal in my home directory and not in the directory of the current window of emacs.

By the way, I am using spacemacs and I need this for a script to use inside i3wm.

1 Answer 1


Your shell command will be picking up on whatever the default-directory is for the current buffer, and emacsclient sets the server buffer as the current buffer by default. The current buffer needn't be displayed in a window at all, so although there will still be a "selected window" for the frame, you will need to select that window explicitly (which will make its buffer the current buffer for the duration).

Try this:

emacsclient -e "(with-selected-window (selected-window) (external-shell-in-dir))"

Of course that may or may not have selected the frame you intended, so you might want to wrap with-selected-frame around that, assuming you have a reliable way to choose it.

You may find it helpful to test the likes of:

emacsclient -e "(current-buffer)"
emacsclient -e "(selected-window)"
emacsclient -e "(selected-frame)"
emacsclient -e "(frame-list)"

If it's feasible for your use-case, I think using with-current-buffer and an explicit buffer to act on would be a more robust approach.

  • emacsclient -e "(current-buffer)" gives me the *server* buffer, while with (selected-window) I obtain the desired behaviour, thanks.
    – Marco Ieni
    Jun 29, 2018 at 11:18

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.