How to use the same file extension with different modes? - emacs

I have files with a .new extension that contain LaTeX code (they are the output of a program that does things on the original .tex source).
In order to check them I need that they have the LaTeX syntax highlighted and that they can be opened in read-only mode to avoid introducing errors. So I put these lines in my .emacs:
(setq auto-mode-alist
(append '(("\\.new\\'" . read-only-mode)
("\\.new\\'" . latex-mode))
auto-mode-alist))
But it does not work as expected because only the first mode is applied. How can I force emacs to apply both read-only-mode and latex-mode to the same file extension?

An easy solution is to associate your file extension with a custom derived major mode:
(define-derived-mode read-only-latex-mode latex-mode "LaTeX"
"Major mode for viewing files of input for LaTeX."
(read-only-mode 1))
(add-to-list 'auto-mode-alist '("\\.new\\'" . read-only-latex-mode))
The new read-only-latex-mode does everything that latex-mode does (including running latex-mode-hook if you're already using that), but it additionally enables read-only-mode after all of the parent mode's actions have taken place.
Any other code which cares about the major mode being latex-mode should already be testing that using the standard approach of (derived-mode-p 'latex-mode) which is still true for this new mode; so in principle this approach should Just Work.

Not sure I can really provide an answer, but here's some things to consider:
read-only-mode is a minor mode, while
auto-mode-alist is meant to turn on major modes. For major modes, it makes sense that you can have only one.
You can put something like -*- buffer-read-only: t; -*- on your first line in the file (possibly behind some comments or shebangs, depending on the file type) which would turn on read-only-mode. Maybe automate this using auto-insert-alist and match the .new filename pattern.
There's some good suggestions over at https://www.reddit.com/r/emacs/comments/jqxgiz/how_can_i_make_some_files_automatically_readonly/ , namely try file local variables and use find-file-hook
Hope some of that helps.

Related

How does the "pdf-tools" package overrides "dired-find-file" method?

After installing pdf-tools the dired mode opens the pdf file with PDFView mode as major mode.
(use-package pdf-tools
:ensure t
:config
(pdf-tools-install t))
How does the pdf-tools package be able to accomplish this?
The Help for RET key in dried buffer says it is bound to dired-find-file
RET (translated from ) runs the command dired-find-file (found
in dired-mode-map), which is an interactive compiled Lisp function.
I searched for dired-find-file in pdf-tools installed elisp files and could not find any advice-add's?
Also please explain how can one go about finding arbitrary key bindings like this one?
What it modified is not directly related to dired, but to how Emacs decides to open files in general. The part of the code that is responsible for that is in pdf-tools-install-noverify, itself called by pdf-tools-install. The first two lines of the function are:
(add-to-list 'auto-mode-alist pdf-tools-auto-mode-alist-entry)
(add-to-list 'magic-mode-alist pdf-tools-magic-mode-alist-entry)
the relevant variables pdf-tools-<auto/magic>-mode-alist-entry being constants defined earlier in the file pdf-tools.el.
You can check the relevant documentation for auto-mode-alist and magic-mode-alist, but to sum up, the former is a mapping from "filenames" (or more precisely, file patterns -- typically, regexps matching file extensions) to major modes, and the latter is a mapping from "beginning of a buffer" to a major mode (see also this wikipedia page on magic numbers/file signatures).
As to how one can determine that: because it is not directly related to key bindings/advices/redefinition of functions, the only "general" option is to explore the "call stack" ! The package tells you to put (pdf-tools-install) somewhere in your init file to activate the package, so you can try to see what this function actually does -- and going a bit further, you see that it is essentially a wrapper around pdf-tools-install-noverify, which does the real job of setting everything up.

Set emacs comment style based on file extension

There are multiple questions along these lines but I haven't been able to find what I need from start to finish. I have been using emacs for a few years but am not used to its customization.
I have a unique file type, identified by its extension, which emacs is not configured for. Its comment style is
<!-- text -->
and I would like to set the variables comment-start and comment-end to the relevant values (which I am assuming will allow me to use comment-region). I don't know the correct way to do this so that it will always be configured when I open this file type but won't affect the default behavior of emacs.
Do I need to make a new major mode for this file type, and then set the variables, or is there an easier way of doing it? An example of the complete requirements for my .emacs file would be much appreciated!
See here. I think this will work:
(add-to-list 'auto-mode-alist
'("\\.extension\\'" . (lambda ()
(setq-local comment-start "<!--")
(setq-local comment-end "-->"))))
Alternatively, if this file extension is well known (or if these files are close enough to a well known syntax), you may be able to just find a major-mode online that does what you want. For example, NXML Mode may just give you the comment syntax you want along with some other useful features.

Collapse/expand parts of .emacs file with org-mode

I recently learned the basics of emacs' org-mode and couldn't help but imagine applying the collapse/expand concept to parts of a source file. I would like to be able to divide my .emacs file in subparts and only display headers on load, somewhat like the following:
; ERC config...
; DIRED config...
; MISC config...
Each of these would of course be headers to many lines of codes once expanded, like this:
; ERC config
(defun start-irc ()
(interactive)
(erc-tls :server "irc.freenode.net" :port 6697 :nick "foo"))
; DIRED config...
; MISC config...
So is this possible? How could I accomplish something like this with emacs 24.2?
Thanks!
As nice as org-mode is, it does require some structure, which I don't believe can be maintained the way you want in your .emacs file.
What does work well is folding-mode. Check out the information for it on the wiki page, but basically what you do is set up comments around the chunks of code you want to put in a fold, like so:
;;{{{ some folder of some kind
(a few lines)
(of lisp)
(this "code" is just filler)
;;}}}
;;{{{ a different folder
(some more elisp code)
;;}}}
And when it is folded, it will look like:
;;{{{ some folder of some kind...
;;{{{ a different folder...
Babel enables you to achieve exactly this (i.e. managing your init file in org-mode). Specifically, see: http://orgmode.org/worg/org-contrib/babel/intro.html#emacs-initialization
Myself, I make use of outline-minor-mode in my init file for vaguely similar purposes. Various things are treated as outline headings, but you can set outline-regexp as a file local variable to restrict that behaviour, and then you toggle things open and closed with outline-toggle-children (which you would bind to some convenient key). The toggle command works from anywhere in the section, not just on the heading.
I start the headings I want to be collapsed by default with ;;;; * and end my init file with:
;;; Local Variables:
;;; outline-regexp: ";;;; "
;;; eval:(progn (outline-minor-mode 1) (while (re-search-forward "^;;;; \\* " nil t) (outline-toggle-children)))
;;; End:
In your instance you could use:
;;; Local Variables:
;;; outline-regexp: "; "
;;; eval:(progn (outline-minor-mode 1) (hide-body))
;;; End:
Pretty similar in effect to Trey's suggestion, although I expect with folding you can trivially nest sections which I'm not accounting for (having no need to do so). I feel the outline approach leaves the file looking slightly cleaner, if that matters to you.
You can also take a look at the new Outshine package which works together with outline-minor-mode to make it feel more like org-mode. In (e)lisp files outshine interprets sequences of semicolons as headers so all existing code which follows standard conventions for comments becomes foldable without any changes. Many org-mode-like key bindings (like TAB to fold/unfold heading, etc) work too.

how to change variables for specific fundamental-mode buffers

Goal: I want to have show-trailing-whitespace enabled for all buffers save a few. Exceptions posing a problem are *Shell Command Output* and its cousin *Async Shell Command*.
I usually have show-trailing-whitespace customized to t. Therefore it is active in all new buffers.
I would also like to have it turned off for certain buffers, foremost amongst them *Shell Command Output*. This poses a problem for me:
The output buffer doesn't use a special mode; it is still in fundamental-mode. There is no fundamental-mode-hook that I could hook this setting into.
There is the after-major-mode-change-hook which is run when the major mode is changed to fundamental-mode, but the buffer starts out in that mode and therefore this hook is not run.
There doesn't seem to be a way to hook into get-buffer-create.
I know I can always advise the function get-buffer-create for this particular example, but I try to avoid that as much as possible.
Any hints?
You might be better off looking at the problem from the other side, and only set the var in those modes where you want to see trailing whitespace.
But I think you have a good point: these shell output buffers should not use fundamental-mode. It's probably time for M-x report-emacs-bug
In accordance with the accepted answer, here's a code snippet that enables trailing whitespaces highlighting for specific modes only:
(setq-default show-trailing-whitespace nil)
(defun namespace/show-trailing-whitespace ()
"Highlight trailing whitespaces in this buffer."
(setq-local show-trailing-whitespace t))
(dolist (hook '(prog-mode-hook text-mode-hook))
(add-hook hook 'namespace/show-trailing-whitespace))
This snippet is essentially taken from Steve Purcell's configuration.

In Emacs, how to automatically enable a minor mode based on buffer name?

I have a Emacs extension that creates a buffer named *erl-output*. This buffer gets created with only fundamental-mode by default. Is there any way to automatically enable compilation-minor-mode on that buffer?
To automatically change major modes you can add the following to your .emacs file:
(add-to-list 'auto-mode-alist '("^\\*erl-output\\*$" . my-major-mode))
This won't work for you; it's for major mode selection and you're after minor mode selection.
Instead you could try a Hook. The manual says:
A hook is a Lisp variable which holds a list of functions, to be called on some well-defined occasion.
So you should be able to write a function which sets the minor mode when required. Looking at the List of Standard Hooks I think you should be trying temp-buffer-setup-hook or temp-buffer-show-hook.
You'll have to write a function which checks the buffer name and sets the mode if required, and add it to the hook using something like the following in your .emacs:
(add-hook 'temp-buffer-setup-hook 'my-func-to-set-mode)
Since your extension is creating the buffer, why not just add:
(compilation-mode)
(or (compilation-minor-mode) if you're really set on the minor mode idea) in the code that's creating the *erl-output* buffer. You can edit the source for the mode, or use advice around the creation routine...