20

how to change the current working directory of emacs?

set default-directory doesn't not affect the emacs process's current working directory, which can be verified via lsof -p pid.

FunkyBaby
  • 767
  • 1
  • 4
  • 10
  • 1
    Emacs, being "a kind of OS" doesn't really have a single current working directory. So what you see as the process's cwd is largely accidental and not really documented. Looking at Emacs's C code, I get the impression that there is currently no way to do what you want. You might hence `M-x report-emacs-bug` and request it as a new feature. – Stefan Nov 21 '17 at 18:47
  • 2
    Assuming you are on Linux, you could force the cwd to change by working at OS level, see https://unix.stackexchange.com/questions/281994/changing-the-current-working-directory-of-a-certain-process for details. – TTimo Sep 25 '18 at 14:54

4 Answers4

36

M-x cd

This should solve your problem.

Stefan
  • 26,154
  • 3
  • 46
  • 84
ksinkar
  • 526
  • 5
  • 9
  • 3
    According to the docs, `cd` will "Make DIR become the current buffer's default directory." I would presume that it's a per-buffer value and wouldn't apply to other existing buffers or to newly created ones. – mojo Feb 14 '19 at 14:52
  • @mojo perhaps, but if you do that with the default buffer when all your other buffers are closed that's all you're left with anyway. So it's still quite practical – Keldon Alleyne Mar 04 '20 at 01:33
9

C-h f cd:

cd is an interactive compiled Lisp function in files.el.

(cd DIR)

Make DIR become the current buffer’s default directory.

If your environment includes a CDPATH variable, try each one of that list of directories (separated by occurrences of path-separator) when resolving a relative directory name. The path separator is colon in GNU and GNU-like systems.

And please explain why changing default-directory does not also change the "current directory" for you: (setq default-directory "/my/favorite/dir").

Drew
  • 75,699
  • 9
  • 109
  • 225
  • 1
    I mean the cwd of the emacs process, which is an entry in the process control block, and it can be easily checked via =lsof -p pid=. The =default-directory= is an internal thing to emacs. Why I need to change cwd is because tmux uses the cwd of a foreground process as the start directory of a new window/pane. – FunkyBaby Nov 21 '17 at 03:05
  • I see. Then your question was (and still is, to me) unclear. What does it mean to change the current working directory of the Emacs process? You want to change it after the process exists? More than once? – Drew Nov 21 '17 at 03:09
  • 1
    it is literally changing the =cwd= of emacs. "More than once"? what do you mean by that. =cwd= is not designed to be a fixed thing. In c, man 2 chdir. In python, os.chdir. I want to know how to do that in elisp (for emacs). – FunkyBaby Nov 21 '17 at 14:57
  • See @Stefan's answer. – Drew Nov 21 '17 at 19:33
7

I think the only way Emacs offers to control the cwd of the process is the --chdir command line argument. Once the process is started, there is currently no way to modify it.

Stefan
  • 26,154
  • 3
  • 46
  • 84
  • This is wrong. `M-x cd` command does change the current working directory. It even makes `find-file` to iniially suggest the given directory to look for files in. – Sventimir Dec 20 '21 at 21:48
  • 2
    `M-x cd` does not change the working directory of the Emacs *process* (which can be seen in `/proc//cwd` under Linux, for example), it only changes the directory used by ELisp code (and subprocesses it may spawn). – Stefan Dec 22 '21 at 00:18
1

Maybe not an answer to the question but I had a similar issue. The setup was emacsclient over tmux session and had to split the window horizontally and open a new tmux tab with the current Emacs' working directory. Here is a workaround:

init.el:

;;; Tmux integration (See tmux.conf for details).

(defun id/tmux-split-horisontal ()
  "Split tmux pane horisontally."
  (interactive)
  (ignore-errors (call-process "tmux" nil nil nil "split-window" "-h" "-c"
                               default-directory)))

(global-set-key (kbd "C-q %") #'id/tmux-split-horisontal)

(defun id/tmux-new-tab ()
  "Create new tmux tab."
  (interactive)
  (ignore-errors (call-process "tmux" nil nil nil "new-window" "-c"
                               default-directory)))

(global-set-key (kbd "C-q c") #'id/tmux-new-tab)

tmux.conf:

## Use C-q as a prefix key.
unbind C-b
set -g prefix C-q
bind C-q send-prefix

## Handle [C-q %] and [C-q c].
is_emacs='echo "#{pane_current_command}" | grep -iqE "emacs"'

# Let Emacs handle [C-q %] if active.
bind-key -T prefix % if-shell "$is_emacs" "send-prefix ; send-keys %" "split-window -h -c \"#{pane_current_path}\""
# Let Emacs handle [C-q c] if active.
bind-key -T prefix c if-shell "$is_emacs" "send-prefix ; send-keys c" "new-window -c \"#{pane_current_path}\""

In this way, if you're under emacs or emacsclient the control is passing to Emacs, thus Emacs sends tmux command with default-directory argument. Otherwise, tmux handles it directly, so the user doesn't see the difference.

Illia Danko
  • 123
  • 6