Emacs tip exchange

It seems we have a decent contingent of Emacs users in this group, so let’s pool together our knowledge! Use this thread to post customizations/elisp snippets/packages that you find useful. This thread can also be a place to ask questions and troubleshoot issues you encounter with Emacs generally, fortran-mode, f90-mode, or any Fortran-adjacent packages.


I’ll kick it off with a handful of things that I use every day.

  • emacs -q to launch emacs in text mode (non-GUI)
    I do most of my development on remote machines. Emacs has TRAMP to work with remote files, but I prefer the experience of running Emacs in text mode on the remote machine directly. It is lightning fast, and it avoids some configuration headaches when it comes to remote paths and environment variables. I find there are very few GUI-specific features that I miss.
  • f90-mark-subprogram (C-M-h in f90-mode)
    When the cursor is in a function/subroutine body, this marks the whole subprogram. When it’s in a module body, it marks the whole module. Useful follow-ups include indent-region (C-M-\), query-replace (C-%), narrow-to-region (C-x n n), and kill-region (C-w).
  • back-to-indentation (M-m) is like C-a except it puts your cursor at the first non-whitespace character on the current line.
  • Essential packages: undo-tree (super-powered undo history), magit (super-powered git integration), counsel/ivy/swiper (super-powered isearch).

— '(electric-pair-mode t)
closes parenthesis, brackets, quotes, etc, as soon as the opening is written

— (setq frame-title-format `("%b " ,(user-login-name) “@” ,(system-name)))
writes the name of the file on the window title bar.

Just add the commands to your .emacs.


I don’t personally use EMACS but this is how you configure it with the fortls Language Server. Some supplementary configuration can be found in this GitHub Discussion


electric-pair-mode is one of those things I know I should be using, but I haven’t yet been able to overwrite the muscle memory to make it work for me. Fortunately, for Fortran, we mostly need parens only, for which (setq parens-require-spaces nil) and M-( have gotten me pretty far.

Hi folks, I just announced Doom Emacs’s new Fortran module here: Fully-featured Fortran setup for Linux/Mac in Emacs (Intel Fortran support included!)


It took me a couple of days to get used to, but now I think it worth the effort…

I find default indentation in F90 mode unnecessarily large, and indenting the whole subroutine/function body (a la C-style) completely useless. Therefore:

(setq f90-program-indent 0)
(setq f90-do-indent 2)
(setq f90-if-indent 2)
(setq f90-type-indent 2)
(setq f90-continuation-indent 2)

Also, not exclusively related to Fortran programming, but I use it all the time there: popup-kill-ring (available at MELPA) makes yanking text from kill ring much better than its default state, with a pop-up menu that shows every entry in kill ring, and you can easily pick the part you need:

(require 'popup-kill-ring)
(global-set-key (kbd "C-c C-y") 'popup-kill-ring)

(there are many other packages that help editing programs but since they are generic and not Fortran-only related, I only mentioned the one I consider more or less mandatory.)

Finally, when compiling you probably want the compilation buffer to remain visible in split window only if errors were reported by the compiler. At least for gfortran, this does the job (also added a quick shortcut for make):

(setq compile-command "make -j rebuild")
(global-set-key [f12] 'compile)
(defun notify-compilation-result(buffer compilation)
  (if (string-match "^finished" compilation)
      (progn (if (string-match "^Warning" compilation)
                 (tooltip-show " Compilation Successful, warnings issued ")
               (tooltip-show " Compilation Successful "))
             (delete-windows-on buffer))
    (tooltip-show " Compilation Failed "))
  (setq current-frame (car (car (cdr (current-frame-configuration)))))
  (select-frame-set-input-focus current-frame))
(add-to-list 'compilation-finish-functions

PS: electric-pair-mode never worked for me, since the many-years hardened “muscle memory” @nshaffer mentioned proved to be extremely powerful.

I think I tried electric-pair-mode once upon a time, and it didn’t work for me either. Here is some code that works for me:

(defun vi-type-paren-match (arg)
“Go to the matching parenthesis if on parenthesis.”
(interactive “p”)
(cond ((looking-at “[([{]”) (forward-sexp 1) (backward-char))
((looking-at “[])}]”) (forward-char) (backward-sexp 1))))
(global-set-key “\C-F(” 'vi-type-paren-match)
(global-set-key “\C-F)” 'vi-type-paren-match)