Emacs is a powerful editor that can be a bit intimidating in the beginning, but it has many useful features. Normally I use it to program in C/C++, R and Python, and to write all sorts of documents (including presentation slides) in LaTeX.
I would like to share the configuration I use for Emacs, which might be useful for someone else or might get me some feedback to improve as well. This will not be a tutorial teaching how to install Emacs itself or its packages, and I also assume basic knowledge about how to use it.
I use Emacs 24 and complement it with the following packages:
- Auto-complete: Completes things I am typing
- ESS: Useful features when I use R
- Flycheck: Syntax checker
- Helm: I mainly use it to navigate between folders
- Undo Tree: Good for controlling undo/redo actions. It’s quite powerful and honestly I just use the basic features
- Writegood: Based on writing tips by Matt Might, this helps me avoid some bad habits when writing
- Yasnippet: Some code snippets that can speed up coding a bit. It mainly helps me when I am writing my presentation slides using Beamer
First, I use Dropbox to help me manage the plugins and configurations files, including the ones for Emacs. I also like to place my backup files there, as I don’t like them being at the directories I am working:
;Backup directory (add-to-list 'backup-directory-alist '("." . "~/Dropbox/.emacsBackups"))
When I am editing a LaTeX file, I have a number of modes and commands turned on:
;;Start Latex mode with flyspell and writegood minor modes (setq auto-mode-alist (cons '("\\.tex$" . latex-mode) auto-mode-alist)) (add-hook 'latex-mode-hook (lambda () (flyspell-mode 1))) (add-hook 'latex-mode-hook (lambda () (writegood-mode 1))) ; Compilation command for Latex mode (add-hook 'latex-mode-hook (lambda () (set (make-local-variable 'compile-command) (format "make -C %s" (get-closest-pathname)))))
The first one turns on Flyspell and Writegood modes when for when I am working with a LaTeX file. They are very helpful to catch some typos or bad habits when I am writing normal texts or presentation slides. The next one is related to the compilation and it runs the closest Makefile in relation to the directory of the currently open file, which is usually in the same directory or the parent directory. For this to work the following command is needed:
; Find the closest Makefile (require 'cl) ; If you don't have it already (defun* get-closest-pathname (&optional (file "Makefile")) "Determine the pathname of the first instance of FILE starting from the current directory towards root. This may not do the correct thing in presence of links. If it does not find FILE, then it shall return the name of FILE in the current directory, suitable for creation" (let ((root (expand-file-name "/"))) ; the win32 builds should translate this correctly (loop for d = default-directory then (expand-file-name ".." d) if (file-exists-p (expand-file-name file d)) return d if (equal d root) return nil)))
Also related to this, I use a command that closes the compilation screen if it is successful, so I don’t need to do it myself and just go back to focus on the file I am editing:
; If it is latex-mode, close compilation screen after it's done (add-hook 'compilation-finish-functions (lambda (buf strg) (if (string= "latex-mode" (buffer-mode (other-buffer (current-buffer) 1))) (let ((win (get-buffer-window buf 'visible))) (when win (delete-window win))) ) ) )
Regarding compilation, I have two more commands for the two other languages I usually use (C++ and Python):
; Compilation commands for different environments (require 'compile) (add-hook 'c++-mode-hook (lambda () (set (make-local-variable 'compile-command) (format "make -C %s run" (get-closest-pathname))))) (add-hook 'python-mode-hook (lambda () (set (make-local-variable 'compile-command) (format "python %s" (buffer-name)))))
They work in similarly to the way I explained in the case of a LaTex file, but in case of C++ it also runs the program after compiling, and in case of Python it just runs the script directly without looking for a Makefile.
I like to keep the key bindings the same across different modes, and the way I managed to do it was by overriding the global bindings with a minor mode (this idea was borrowed from an answer at StackExchange):
;; Initialize myMode to override other keybidings (load "~/Dropbox/SharedConf/myMode.el") (require 'my-mode)
Then, for example, to make the compile command run with “C-c C-k” in any mode, I define it as a key in the minor mode:
(define-key my-mode-map (kbd "C-c C-k") 'compile)
Finally, I found a command that is useful when I want to split my buffer just as I would open another tab in a web browser (“C-t”):
(defun other-window-or-split () (interactive) (when (one-window-p) (split-window-horizontally)) (other-window 1)) (global-set-key (kbd "C-t") 'other-window-or-split)
There are other configurations in the file at GitHub, and I would be happy to talk about them. Also, I am sure there are many other great ways to do things and tips when working with Emacs, so the comments are open for suggestions.