reddit / emacs

Is it possible to set major mode from buffer name, not filename?

arensb · 2022-09-29 18:36
If I visit file `foo.py`, Emacs opens it in python-mode because the extension ".py" appears in `auto-mode-alist` This is true even if the file doesn't yet exist. However, if I simply create a new buffer called `foo.py`, using `M-x switch-to-buffer`, without tying it to a file, the new buffer is opened in fundamental-mode. Is there a way to set a new buffer's major mode based on its buffer name, rather than (or in addition to) its filename? I haven't found any hooks that would do the trick. Conversely, is there any reason why I *don't* want to do this? Thanks, (ETAA: this is slightly different from [this question](https://emacs.stackexchange.com/questions/14013/change-the-default-mode-used-when-opening-a-new-buffer). That one is about setting the one mode to use in a new buffer. Mine is about calling a function to choose a mode dynamically. But that question seems to imply that there's no hook to do what I want.)
nv-elisp · 2022-09-29 20:33
https://www.gnu.org/software/emacs/manual/html_node/elisp/Auto-Major-Mode.html https://www.gnu.org/software/emacs/manual/html_node/emacs/Choosing-Modes.html#Choosing-Modes
arensb · 2022-09-29 20:56
Can you please be more specific? I know how to choose a mode based on the filename or on the contents of the buffer, but I don't see anything above on how to set the mode of a new, empty buffer.
nv-elisp · 2022-09-29 21:09
You can use the knowledge above in combination with `buffer-list-update-hook` to achieve what you're after. There will probably be corner cases that need to be considered, though. The easier solution is just to use `find-file` and not save the file.
nv-elisp · 2022-09-29 21:25
This should get you started. Haven't tested; not interested in supporting. (defun +set-new-buffer-mode () "Set new buffer's major-mode." (when-let ((buffer (car (buffer-list))) (name (buffer-name buffer)) (mode (cdr (cl-find-if (lambda (regexp) (string-match regexp name)) auto-mode-alist :key #'car)))) (with-current-buffer buffer (unless (eq mode major-mode) (funcall mode)))))
arensb · 2022-09-29 22:13
Thanks. After a little bit of digging, it looks as though `buffer-list-update-hook`'s functions aren't told which buffer just got created. Yes, I could try to keep track of what `(buffer-list)` returns, and try to guess which buffer just appeared, but that seems difficult and prone to error. Maybe a better approach would be to write a wrapper around `switch-to-buffer`, that sets the mode in the buffer, if it was created.