reddit / emacs
How to call functions only when on GUI, even when using the daemon
graduale · 2022-09-08 13:01
I've had luck binding `ESC` to `keyboard-quit` everywhere except in terminal sessions with the following line:
(when (display-graphic-p)
(define-key key-translation-map (kbd "ESC") (kbd "C-g"))
But recently I've started making more regular use of the daemon and this hasn't worked really anymore. (From what I understand, upon first starting the server, `display-graphic-p` returns `nil`.)
The workaround that seems to be doing the trick is to add the above to `server-after-make-frame-hook`. (I tried adding the above to `after-init-hook` but it doesn't seem to work, and some poking around suggests that when the functions in `after-init-hook` are run when the server starts, `display-graphic-p` also returns `nil`.)
Now, there are other things I want to run only when starting a new GUI session, so I've kept on adding things to `server-after-make-frame-hook`.
Not knowing very much about the way all of this works, I keep thinking this is inefficient. For it seems that `server-after-make-frame-hook` gets called more often than just when I start what, on my end, looks like a new session: calling `magit-commit`, for example, will run all of the functions in that hook.
So, what I'm looking for is some tips on how to activate some bits of my config in all and only the following circumstances: when a new GUI frame is opened but no other GUI frames are.
One solution I would be happy with, but which I cannot figure out how to create, is to have a GUI dedicated daemon and another daemon, if needed, for terminal sessions. I'd then need to have a way of triggering some bits of my config only when the dedicated GUI daemon starts.
Sorry if this a bit muddled. As I write this I suspect I'm confused about something, I just don't quite know what it is!
[deleted] · 2022-09-08 14:34
[deleted]
flexibeast · 2022-09-08 14:34
>when a new GUI frame is opened but no other GUI frames are
Do you mean, when a new GUI frame is opened without there being existing GUI frames? If so, here's some of the function i add to `server-after-make-frame-hook`:
(defun frame-setup ()
"Set up frame depending on frame type."
(message "Running frame-setup ....")
(let ((len (length (frame-list))))
(message (concat
(number-to-string len)
" frame(s) found."))
(if (>= len 1)
(progn
(let ((frame-type (framep (selected-frame))))
(menu-bar-mode 1) ; enable menu bar
(cond
((eq 'x frame-type)
(unless graphical-frame-created
(progn
(message "Setting up X frame ....")
... ;; Setup code
(setq graphical-frame-created t))))
((eq 't frame-type)
t)))))))
lebensterben · 2022-09-08 15:39
thanks. TIL server-after-make-frame-hook
graduale · 2022-09-09 00:59
Thanks! Interesting approach.
c256 · 2022-09-10 04:46
If you use the desktop package/feature to save state between sessions, you can see a daemon startup with multiple frames and no gui windows, which might break this pattern.
Roughly speaking, when the emacs daemon starts, it creates a dummy/placeholder frame for parts of emacs’ initial startup process, and AFAIK this cannot be avoided or reused. This dummy gets silently pruned from the various built-in frame-switching machinery, so most people don’t notice it, but you can see it in code like this.
flexibeast · 2022-09-10 04:54
Yeah, i learned of the presence of the dummy frame as i was putting this code together, resulting in the `(if (>= len 1)` line. That's a good point about the desktop feature saving state; i don't use that functionality myself, so thanks for noting it!
deaddyfreddy · 2022-09-10 13:50
are you using `if` + `progn` for a single-branch condition?
flexibeast · 2022-09-10 14:49
\*checks\* Oh huh, that `progn` is an artifact of when the `if` *didn't* involve a single-branch condition. Removed, thanks!
deaddyfreddy · 2022-09-10 14:55
I believe there should be `when` :)
flexibeast · 2022-09-11 00:12
Heh, okay - i actually tend to prefer `if` to `when` for some reason, and since i'm the one maintaining the code, that's what i go with. :-)
deaddyfreddy · 2022-09-11 09:34
> i actually tend to prefer if to when for some reason
okay, just be aware it's an antipattern
flexibeast · 2022-09-11 09:47
Oh? How so?
i ask because people's ideas of what does and doesn't constitute an 'antipattern' can be more subjective than objective, in the same way that tabs vs spaces can be subjective, i.e. that there can be good reasons to use one or the other in some contexts, and in other contexts it doesn't really matter as long as one is consistent.
deaddyfreddy · 2022-09-11 11:54
related
https://www.emacswiki.org/emacs/WhenToUseIf#h5o-4
https://github.com/bbatsov/emacs-lisp-style-guide#syntax
https://github.com/metacontent/The-One-True-Lisp-Style-Guide#17-conditional-expressions
https://www.cs.cmu.edu/Groups/AI/html/cltl/clm/node84.html
https://www.cs.cmu.edu/Groups/AI/html/faqs/lang/lisp/part1/faq-doc-4.html
flexibeast · 2022-09-11 12:48
Of all those, none explicitly refer to use of `if` rather than `when` in this context as an 'anti-pattern'. The EmacsWiki link even says: "This is an informal convention, and it is not followed by everyone." A couple of times no justification is even given; where it is, only the last link speaks strongly enough to suggest that to do otherwise is an anti-pattern. Overall, the idea seems to be to use `when` rather than `if` in certain situations in order to try to convey certain information, not because it's actually *wrong* to do so.
As per my previous comment, my belief is that when i'm overwhelmingly the person maintaining the code, it's what works for me that matters. i see no benefit to methodically changing all the code in my config and packages to use `when` rather than `if` in the relevant places - because i wouldn't want to start using `when` such that the project had a *mix* of the two styles, which i would argue is *more* problematic - and i very much doubt that my preference in this regard is preventing people from contributing. Certainly when i'm contributing to other projects, i make an effort to respect the style preferred by the people who are actually putting in the work, even if i personally have issues with it.
More generally, i wish people were willing to devote as much effort to fixing bugs or adding functionality as they are to bikeshedding stylistic issues that don't actually have any significant impact on how the code works.
This will be my last comment on this matter in this thread.
deaddyfreddy · 2022-09-11 14:42
> Of all those, none explicitly refer to use of if rather than when in this context as an 'anti-pattern'.
ok, probably the "antipattern" word was too harsh, but at least the Emacs Lisp Style Guide clearly marks it as `bad`.
> that don't actually have any significant impact on how the code works
They have a significant impact on how the code is maintainable by other people - programmers learned this the hard way.
When I see a pattern with `if` I expect two branches there, and when else one isn't there, it definitely adds some wtfs to understanding what's going on.
One of the biggest problems with Emacs code floating around is people tend to avoid good coding practices (code style, linting, tests, CI) - "Who cares if it works for me". Even MELPA only checks if packages can be built without errors.
> This will be my last comment on this matter in this thread.
Thanks for the discussion
No_oneMinax002 · 2022-09-11 19:19
Ooh okay! I’d kill for one