reddit / emacs

Make Emacs start-up different when opening file

andyjda · 2022-11-23 00:07
When I'm opening Emacs, I normally want it to display my [dashboard](https://github.com/emacs-dashboard/emacs-dashboard). But if I'm opening a file, I just want it to jump straight to the file and not waste time showing the dashboard. It seems that there is a [pretty trivial](https://emacs.stackexchange.com/questions/32892/is-it-possible-to-disable-the-startup-screen-only-when-emacs-opens-a-file) solution in cases when Emacs is invoked from the command line: just check if there are command-line arguments that look like files, and make Emacs behave accordingly. However, I want Emacs to behave this way even when I invoke it from the GUI: when I double-click on a file, or select 'Open with Emacs'. I've done some snooping around the startup code, and it looks like in the latter case, the file that we're about to open does not show up as a command-line argument, so the above solution doesn't work. Yet there must be a way for Emacs to know that it needs to open a file (otherwise it'd just open normally and not immediately display the file in a buffer). So what can I check to know if Emacs was called in this way?
sickofthisshit · 2022-11-23 00:13
Everyone has their own style, but I think opening a new Emacs instance is something you do roughly once per reboot. Do you know about Emacs server mode and emacsclient? I suspect this is not really an Emacs question but a question about what this "right click on file" is doing.
andyjda · 2022-11-23 00:16
I do know about it and I'd rather not use it. I just want my Emacs to open in different ways depending on the situation
sickofthisshit · 2022-11-23 00:18
The question is what "situation" your right click menu is: that's probably a feature of your graphics environment, not Emacs itself.
andyjda · 2022-11-23 00:21
opening a file is the situation. Emacs is aware that I called it to open a file, because that's what it does. I don't see why the graphics environment is important
sickofthisshit · 2022-11-23 00:25
The question is "how is the graphics environment asking for Emacs to open the file". Emacs does not have "awareness", some process is being launched by something and I am asking you to figure out where that is configured and what it does on the command arguments or environment that you can change to do something that you can script Emacs to respond to. Emacs isn't haunted by file spirits.
andyjda · 2022-11-23 00:38
I don't know the internals of how MacOS launches applications, do you know where I'd find that information? The command-line arguments are nil. My point is that there is something within Emacs' state that corresponds to the fact that it was invoked to open a file. That's what I meant by "awareness", though file spirits would be nice 😂
sickofthisshit · 2022-11-23 01:56
Oh, ok, Mac OS X is kind of wonky, and I'm not completely sure how it works, I thought you were doing something in Linux, my bad. I suspect, based on a couple minutes playing with Aquamacs and `M-x dribble-file`, what that "Open File With..." menu is doing is sending an "event" such as `<ns-open-file-line>`. https://www.gnu.org/software/emacs/manual/html_node/emacs/Mac-_002f-GNUstep-Events.html discusses what these do. It is probably executing `(ns-open-file-select-line)` and that goes down into a maze of code in [ns-win.el](https://github.com/emacs-mirror/emacs/blob/master/lisp/term/ns-win.el) which is finding the file path from `ns-input-file` and possibly invoking `dnd-open-local-file` (`dnd` is for "Drag-and-drop" support). I don't know if this applies to your particular flavor of Emacs, but either you can change these functions or find customization hooks of some kind. For example, in that file there is a default binding for the event in the global keymap (define-key global-map [ns-open-file-line] 'ns-open-file-select-line) and you could replace that with your own function.
andyjda · 2022-11-23 05:00
Thank you! This pointed me in the right direction. Seems like a good option is to just check the `ns-input-file` variable, and set the startup behavior depending on whether it is `nil`. The one tricky thing is that I'm not sure when exactly this variable is set: its value seems to `nil` when the init file is being loaded, but then it has a value when the `after-init-hook`s are being run. And none of the functions that run in between seem to have anything to do with it. I'll keep tinkering with it. I might have to come up with somewhat of a hacky solution, but I'll definitely be able to accomplish it now, which is great! Thanks again!
sickofthisshit · 2022-11-23 14:12
I suspect that variable is set by the Cocoa event handling somewhere in Objective C: events look like keystrokes so they can't carry parameters. The incoming event has to stick all the other incoming information from the OS into these other variables when it sticks the fake keystroke into the event queue.