8

In my .emacs file, I have:

(setq-default major-mode
          (lambda ()
            (let ((buffer-file-name
                   (replace-regexp-in-string
                    "\\.tmp$" ""
                    (or buffer-file-name (buffer-name)))))
              (set-auto-mode)
              )))

This ended up causing files such as 'foo.el.tmp' to open in emacs-lisp-mode.

Once I upgraded Emacs, this started breaking; when I open a buffer that doesn't exist that should be open in fundamental-mode, such as 'asdfg', I get an error:

image-type-from-buffer: Variable binding depth exceeds max-specpdl-size

This seems to be due to (set-auto-mode) in major-mode calling now being recursive.

What's the best way to do this?

Malabarba
  • 22,878
  • 6
  • 78
  • 163
Nathaniel Flath
  • 627
  • 6
  • 13
  • 2
    Why are you setting the value of variable `major-mode` to a lambda form? See the doc for it - the value is expected to be a **symbol**. Dunno whether that is relevant to your issue, however. – Drew Oct 26 '14 at 16:55

1 Answers1

14

The auto-mode-alist variable does what you need. Never bind anything to the major-mode variable.

The documentation explains how you can set major-modes per file extension and, most importantly, it explains how to treat multiple extensions.

Alist of filename patterns vs corresponding major mode functions. Each element looks like (REGEXP . FUNCTION) or (REGEXP FUNCTION NON-NIL). (NON-NIL stands for anything that is not nil; the value does not matter.) Visiting a file whose name matches REGEXP specifies FUNCTION as the mode function to use. FUNCTION will be called, unless it is nil.

If the element has the form (REGEXP FUNCTION NON-NIL), then after calling FUNCTION (if it's not nil), we delete the suffix that matched REGEXP and search the list again for another match.

So you just need to tell Emacs to ignore the "tmp" extension and to look at the next extension.

(add-to-list 'auto-mode-alist '("\\.tmp\\'" ignore t))

If you also want to apply major-modes to buffers not associated to any file, see this question.

Malabarba
  • 22,878
  • 6
  • 78
  • 163
  • This doesn't solve the full problem, which is that it doesn't take effect on new buffers not associated with a file. – Nathaniel Flath Oct 26 '14 at 19:50
  • 2
    @NathanielFlath The question was how to "cause **files** such as 'foo.el.tmp' to open in emacs-lisp-mode" without triggering the error you quoted on non-file buffers. This does answer that question. You never mentioned you wanted the major-mode to apply to non-file buffers. – Malabarba Oct 26 '14 at 19:59
  • 1
    @NathanielFlath If you'd like to know how to make non-file buffers activate the major-mode too, there are great answers in [this question](http://emacs.stackexchange.com/q/2497/50). If you're still not satisfied with this answer, could you edit the question clarifying what more you need? – Malabarba Jan 10 '15 at 23:44