First
(shell)
opens a *shell*
buffer and starts a shell process in it. Then
(shell-command "cd C:/MyStartUp/ThisDirectory")
runs a non-interactive shell which executes the command cd C:/MyStartUp/ThisDirectory
and exits. Then
(setq default-directory "C:/MyStartUp/ThisDirectory")
sets the current directory of the buffer where the shell process is running. This does not affect the running process.
You need to either set the current directory of the *shell*
buffer before starting the shell process, or send the cd
command to the running shell. Setting the current directory of the *shell*
process is a little complicated because the way to do it depends on whether the *shell*
buffer already exists. You also need to decide whether you want to change the current directory if a shell is already running, which sending the cd
command will always do.
To set the current directory if a new *shell*
buffer is created:
(let ((default-directory "C:/MyStartUp/ThisDirectory"))
(shell))
To set the current directory of an existing *shell*
buffer if there is one:
(let ((buffer (get-buffer "*shell*")))
(if buffer
(with-current-buffer buffer
(shell-cd "C:/MyStartUp/ThisDirectory"))))
shell-cd
runs the cd
function, which is a bit fancier than directly setting default-directory
: it honors CDPATH
(which you may or may not care about). shell-cd
also takes care to update the directory shown in buffer lists. You can run this before the previous snippet to cover both the case where no *shell*
buffer exists and the case where a *shell*
buffer exists without a running shell process. Note that this does not cover the case of an existing *shell*
buffer with a running shell process.
To change the directory of the running shell, send a cd
command to it. (cd
works for all common shells including Unix-like *sh
, fish, Windows cmd
and Plan 9 rc, but if you use a more exotic shell you'll need to use its own syntax.) This doesn't work if you want to change to a remote directory using Tramp: for that, you have to decide on the host before running the shell.
(shell)
(with-current-buffer "*shell*"
(shell-cd "C:/MyStartUp/ThisDirectory")
(let ((cmd (concat "cd " (shell-quote-argument default-directory) "\n")))
(comint-send-string nil cmd))
Note that this snippet assumes that your shell accepts the same quoting mechanism as your platform's default shell. Otherwise you may need to replace shell-quote-argument
with a function that's suitable for your shell's syntax.
Sending input to the shell assumes that the shell is listening to input. If the shell is running an interactive application, that application will receive the input. There's no easy way to detect that and no reliable way to work around it.