Here are a few things I’ve had to figure out in the process of setting up Emacs on a Mac, in particular with getting shell-mode
to work as I’d like. Maybe this will save someone else some time if they want to do the same.
I’ve used a Mac occasionally since the days of the beige toasters, but I never owned one until recently. I’ve said for years that I’d buy a Mac as soon as I have a justification, and I recently started a project that needs a Mac.
I’d heard that Emacs was hard to set up on Mac, but that has not been my experience. I’m running Emacs 25.1 on macOS 10.12.1. Maybe there were problems with earlier versions of Emacs or OS X that I skipped. Or maybe there are quirks I haven’t run into yet. So far my only difficulties have been related to running a shell inside Emacs.
Path differences
The first problem I ran into is that my path is not the same inside shell-mode
as in a terminal window. A little searching showed a lot of discussion of this problem but no good solutions. My current solution is to run source .bash_profile
from my bash shell inside Emacs to manually force it to read the configuration file. There’s probably a way to avoid this, and if you know how please tell me, but this works OK for now.
Manually sourcing the .bash_profile
file works for bash but doesn’t work for Eshell. I doubt I’ll have much use for Eshell, however. It’s more useful on Windows when you want a Unix-like shell inside Emacs.
Update: Dan Schmidt pointed out in the comments that Emacs reads .bashrc
rather than .bash_profile
. It seems that Mac doesn’t read .bashrc
at all, at least not if it can find a .bash_profile
file. I created a .bashrc
file that sources .bash_profile
and that fixed my problem, though it did not fix the problem with Eshell or the path problem below.
Scrolling command history
The second problem I had was that Control-up arrow does not scroll through shell history because that key combination has special meaning to the operating system, bringing up Mission Control. Quite a surprise when you expect to scroll through previous commands but instead your entire screen changes.
I got around this by putting the following code in my Emacs config file and using Alt-up and Alt-down instead of Control-up and Control-down to scroll shell history. (I’m using my beloved Microsoft Natural keyboard, so I have an Alt key.)
(add-hook 'shell-mode-hook (lambda () (define-key shell-mode-map (kbd "<M-up>") 'comint-previous-input) (define-key shell-mode-map (kbd "<M-down>") 'comint-next-input) ) )
Another path problem
The last problem I had was running the Clojure REPL inside Emacs. When I ran lein repl
from bash inside Emacs I got an error saying command not found. Apparently running source .bash_profile
didn’t give me entirely the same path in Emacs as in a terminal. I was able to fix the following to my Emacs config file.
(add-to-list 'exec-path "/usr/local/bin")
This works, though there are a couple things I don’t understand. First, I don’t understand why /usr/local/bin
was missing from my path inside Emacs. Second, I don’t understand why adding the path customizations from my .bash_profile
to exec-path
doesn’t work. Until I need to understand this, I’m willing to let it remain a mystery.
Update: LaTeX path problem
After fixing the problems mentioned in the original post, I ran into another problem. Trying to run LaTeX on a file failed saying that pdflatex
couldn’t be found. Adding the path to pdflatex
to the exec-path
didn’t work. But the following code from the TeX Stack Exchange did work:
(getenv "PATH") (setenv "PATH" (concat "/Library/TeX/texbin" ":" (getenv "PATH")))
This is the path for El Capitan and Sierra. The path is different in earlier versions of the OS.
Portable Emacs config file
By the way, you can use one configuration file across operating systems by putting code like this in your file.
(cond ((string-equal system-type "windows-nt") (progn ; Windows-specific configurations ... ) ) ((string-equal system-type "gnu/linux") (progn ; Linux-specific configurations ... ) ) ((string-equal system-type "darwin") (progn ; Mac-specific configurations ... ) ) )
If you need machine-specific configuration for two machines running the same OS, you can test system-name
rather than system-type
.