reddit / emacs

Advice on config hacking / yak shaving / bikeshedding

skyler544 · 2022-12-23 18:14
This post may end up rambling a little but I'll try to keep it short. I decided to try doing a vanilla Emacs config again; I usually use Doom. I've tried this before with moderate success, but I felt like starting from scratch would be refreshing and allow me to craft things more carefully. I made a concerted effort *not* to add things I don't understand fully or that I will never actually use. I also decided not to use `evil` or try to ape all the Doom keybindings [like I did with my previous attempt](https://github.com/skyler544/rune-emacs-config/blob/main/modules/keybinds.el). Fast forward to today; the result is [this](https://github.com/skyler544/rex). I'm actually quite satisfied with it; the code meets my goals of consisting of fully self-contained `use-package` statements, which in my inexpert opinion is a nice way of making the code as stable and idiot-proof (me) as possible. There's one problem though: I won't be able to use it with plain Emacs keybindings in the long-term. Constantly holding down Control is very fatiguing, and while I'm glad that I made the attempt, my muscle memory just won't let me stick with it. This means that I somehow need to be able to integrate `evil` into this setup *without* breaking the way it works right now and turning it into the exact same thing as my previous config. To be clear: I don't want to introduce a bunch of dependencies to the existing `use-package` blocks, but I will need to rewrite a lot of bindings to play nicely with `evil`. This conflicts with the current approach: Everything related to `corfu` should be in the completion file, and not strewn around (which makes it harder to debug and understand). How would you approach this? Is there a way to maintain the way it works right now, where I can just comment out a `load` line in `init.el` without breaking the config? I'm going to have to define keybindings for the commands from various packages *somehow*, so how do I do that without ending up with a super fragile load-order snafu like in my original vanilla config? I can't decide if it would be better to have evil and friends as a self-contained single file loaded after everything else the way all of the other functionality works currently, and having that be loaded first and having a section in each of the existing files that adds evil compatibility. I hope this makes sense; thanks for your time! EDIT: I bit the bullet and decided to implement `evil` after all. The key was patience and reading the manual (which we all know should be the standard way, but it's difficult sometimes). I made a pull request just to document what it was like; it actually simplified the configuration in a couple of places, which I found surprising. Furthermore, I was able to conform to my intended goal of not introducing dependencies between the `use-package` blocks. https://github.com/skyler544/rex/pull/1/files
PlatypusOrthoganus · 2022-12-23 20:19
I haven't looked at your whole config, yet, but I like the way you have organized it. One thing I saw is that you're using `linum-mode`. That's deprecated, now. You will have a better experience with `display-line-numbers-mode`, which replaces `linum-mode`. Give it a try and see what you think. Happy hacking!
skyler544 · 2022-12-23 20:54
Thank you! I was wondering why the line numbers seemed off. Fixed.
McBobrow · 2022-12-23 21:05
did you try god-mode for modal editing? it integrate almost seamlessly with the vanilla key bindings.
CulturMultur · 2022-12-23 21:11
I was in a similar boat and bringing evil makes things a lot harder to understand, A LOT. I needed to use general.el to configure keybindings that evil sees, the package changes so many things that it doesn't look like Emacs anymore. So, I was looking for alternatives. Luckily, there are many. I stick with meow, it is a modal editing mode inspired by kakoune editor, the difference with vim is "visual" mode is always on, so all movement commands create visual selection, also object and verb switched in places comparing to vim "language", so instead 2cw it is 2wc in meow (actually I found that I completely disabled functionality with numbered commands as I almost never use it). The beauty of meow is that you configure keybindings yourself, if needed it can look almost exactly like vim keybindings. &#x200B; Below is my meow config for reference, nothing apart this in my config deals with meow: ``` (with-package 'meow (meow-thing-register 'angle '(regexp "<" ">") '(regexp "<" ">")) (add-to-list 'meow-char-thing-table '(?a . angle)) (add-to-list 'meow-mode-state-list '(recentf-dialog-mode . insert)) (setq meow-expand-hint-remove-delay 4.0 meow-goto-line-function 'goto-line meow-cheatsheet-layout meow-cheatsheet-layout-qwerty meow-expand-exclude-mode-list '(markdown-mode org-mode go-mode nov-mode text-mode)) (global-set-key (kbd "C-c M") 'meow-normal-mode) (defun meow--maybe-highlight-num-positions (&optional nav-functions) "Disable highlighting to use digit argument." nil) (meow-leader-define-key '("7" . meow-digit-argument) '("8" . meow-digit-argument) '("9" . meow-digit-argument) '("4" . meow-digit-argument) '("5" . meow-digit-argument) '("6" . meow-digit-argument) '("1" . meow-digit-argument) '("2" . meow-digit-argument) '("3" . meow-digit-argument) '("0" . meow-digit-argument) '("/" . meow-keypad-describe-key) '("?" . meow-cheatsheet)) (setq meow-keypad-leader-dispatch "C-x") (meow-define-keys 'normal '("0" . meow-expand-0) '("9" . meow-expand-9) '("8" . meow-expand-8) '("7" . meow-expand-7) '("6" . meow-expand-6) '("5" . meow-expand-5) '("4" . meow-expand-4) '("3" . meow-expand-3) '("2" . meow-expand-2) '("1" . meow-expand-1) '("-" . negative-argument) '("," . er/contract-region) '("." . er/expand-region) '("{" . meow-inner-of-thing) '("}" . meow-bounds-of-thing) '("[" . meow-beginning-of-thing) '("]" . meow-end-of-thing) '("a" . meow-append) '("A" . meow-open-below) '("b" . meow-back-word) '("B" . meow-back-symbol) '("c" . meow-change) '("C" . (lambda () (interactive) (kill-line) (meow-insert))) '("d" . meow-delete) '("D" . meow-backward-delete) '("e" . meow-next-word) '("E" . meow-next-symbol) '("f" . meow-find) '("F" . forward-sexp) '("g" . meow-cancel-selection) '("G" . meow-grab) '("h" . meow-left) '("H" . meow-left-expand) '("i" . meow-insert) '("I" . meow-open-above) '("j" . meow-next) '("J" . meow-next-expand) '("k" . meow-prev) '("K" . meow-prev-expand) '("l" . meow-right) '("L" . meow-right-expand) '("m" . meow-join) '("M" . join-line) '("n" . meow-search) '("N" . execute-extended-command) '("o" . meow-block) '("O" . meow-to-block) '("p" . meow-yank) '("P" . (lambda () (interactive) (beginning-of-line) (meow-yank))) '("q" . lispy-ace-paren) '("Q" . meow-goto-line) '("r" . meow-replace) '("R" . meow-swap-grab) '("s" . meow-kill) '("S" . query-replace) '("t" . meow-till) '("T" . transpose-sexps) '("u" . meow-undo) '("U" . meow-undo-in-selection) '("v" . meow-visit) '("w" . meow-mark-word) '("W" . meow-mark-symbol) '("x" . meow-line) '("X" . meow-goto-line) '("y" . meow-save) '("Y" . meow-sync-grab) '("z" . meow-pop-selection) '("Z" . repeat) '("/" . meow-reverse) '("'" . repeat) '("%" . lispy-different) '(";" . avy-goto-char-timer)) (meow-global-mode +1)) ```
skyler544 · 2022-12-23 21:28
I haven't gotten further than reading a blog post about it from the creator; I'll take a look!
skyler544 · 2022-12-23 21:28
Interesting. This is the second time I've heard of this package and it does seem pretty promising. I'll take a closer look!
-vz8- · 2022-12-23 22:18
Reading your post, I thought I was having some kind of stroke. Or I'd fallen asleep listening to a review of the latest Pokemon release. ... Or both.
CorysInTheHouse69 · 2022-12-23 23:27
God-mode and meow are utterly fantastic. They integrate directly with vanilla emacs. Not to mention they’re both small packages compared to the large heft that is evil.
nv-elisp · 2022-12-23 23:39
I don't see how breaking up a few lines of use-package declarations is better than just having them inline in init.el, but to each their own.
skyler544 · 2022-12-23 23:59
It makes less sense for some of the sections than for others; when there's only one or two blocks and it amounts to ~10 lines having an entire file feels a little overkill. However, it's more of a conceptual thing than a functional thing, at least the way I look at it. It's like going into a bookstore and finding all the mystery novels in a section ( and not finding cookbooks mixed in among them). To Emacs, it makes no difference when loading the code (except the strict need to have the package system be initialized before trying to use it). While writing and reading the code as a human however, the organization makes a big difference.
nv-elisp · 2022-12-24 01:07
There is a performance penalty for loading each file. If you're an Org user, I suggest looking into tangling an init.org to init.el (ahead of time, avoiding the cost of tangling on each init). This gives you the flexibility of organizing the presentation however you like, having an easy way of toggling sections on/off, and makes organizing things very simple.
IcyTransition586 · 2022-12-24 01:47
I use emacs on windows, and remapped ctrl to space (when pressed together with other keys), which saves me from the emacs pinky issue.
eternal-hobbyist · 2022-12-24 02:15
u/skyler544 I was literally about to go on this subreddit and make the same post that you just did. Could you keep me in the loop about your experience with meow? I tried to use it, and it looks very promising. The only issue I had is that the default keybindings were just different enough from Vim to throw me off. I know I can change them but I'm afraid I will constantly be making mistakes due to little differences. For my day job I basically have to use VSCode (long story) but opt to use the Spacemacs plugin. Right now I am considering god-mode instead since my emacs config is becoming a less bulky but still problematic version of Spacemacs.
thetemp_ · 2022-12-24 06:22
I break mine up into sections using pagebreak characters ("\^L"). There's a fairly simple bit of config that makes them look like horizontal lines. And Emacs already has built-in pagebreak navigation ("C-x \]" and "C-x \["), which helps when moving across long sections. You can also set the `imenu` regexp to recognize whatever syntax you use for blocks of configuration and jump directly to them that way.
[deleted] · 2022-12-24 09:30
[removed]
skyler544 · 2022-12-24 09:44
That's a neat idea! I'll take a look
skyler544 · 2022-12-24 09:45
Noted; I do use a tangled config with Doom but it lacks certain things like code completion in src blocks. That's probably just a configuration detail that I would need to look into.
skyler544 · 2022-12-24 09:46
I have caps lock remapped to ctrl; it's definitely better than if I had to use the ctrl key on the lower left all the time, but it's just not ideal. Remapping it to space is a nice idea though.
skyler544 · 2022-12-24 10:00
I'll let you know what I think after trying it out; for now I expect that I'll probably be unable to use it much. One of the issues that I can see stemming from using it is that if I got used to it I would be even more crippled using other software than I already am... The vim keybindings are like a mental virus
skyler544 · 2022-12-24 10:12
Does this only affect the init time, or does it also affect performance of packages that have been loaded in this daisy-chain way?
nv-elisp · 2022-12-24 11:01
Init time. With such a small number of files, it's likely a negligible cost, but it's hard to say without profiling.
Illiamen · 2022-12-24 13:32
If you're not aware, you could also just open the SRC block in the major mode via `C-c '`.
eternal-hobbyist · 2022-12-24 16:22
I agree with you. My other issue with Vim is that I feel like it is a complete system, which gives it both pros and cons. You can always be learning different ways of accomplishing the same task, but it is not flexible for remapping. As a result I am basically using 5% of Vim's functionality, but don't feel comfortable reassigning keys. In contrast emacs whole philosophy is that you get to customize it, which has a much clearer advantage when you are primarily working with downloaded packages.
your_sweetpea · 2022-12-24 20:06
This is a bit out of left wing, but have you considered switching to a new keyboard layout? It would help break your Vim muscle memory and also improve your ergonomics when typing in general. You'd be killing two birds with one stone. The downside of course being that you'd have to take some time to get used to it, but the holiday season (assuming you're somewhere that loosely follows the same holidays as me) isn't the worst time for that. I kind of did the opposite of this a couple of years ago, which is that I switched to Dvorak and it meant that Evil was no longer viable so I started using Emacs-style bindings (and just recently have begun moving to Meow), but it essentially let me "start from scratch" with regards to my editor muscle memory. Meow has [example layouts for both Dvorak](https://github.com/meow-edit/meow/blob/master/KEYBINDING_DVORAK.org) and [Colemak](https://github.com/meow-edit/meow/blob/master/KEYBINDING_COLEMAK.org) as well.
your_sweetpea · 2022-12-24 20:10
It may also be worth taking a look at [outli](https://github.com/jdtsmith/outli) which provides `org-mode`-like navigation and structure editing via your comments. Kind of like an "inverted" org mode, where the comments are your text and the uncommented bits are your code blocks. It means you wouldn't have to tangle your file before loading it.
skyler544 · 2022-12-24 21:30
It would be worth looking into if I had an external keyboard; as it is I have two laptops, one is a Mac and the other runs Linux; the different key shapes alone (let alone the weird key-feel on the Mac) cause me lots of friction when I switch between them and so switching layouts entirely isn't really in the cards right now. Thanks for the suggestion though; I'll keep it in mind if I do finally get around to getting a nice keyboard.
Face_Motor_Cut · 2022-12-25 00:25
+1 for meow. Please check jt out as well, not just god mode
skyler544 · 2022-12-25 14:40
Not to leave you hanging on this; I only used meow for a few minutes, so I can't give you any real advice on whether it's great or not. I'm sure that it's fine and all, but the vim keybindings are so ingrained in my brain that I ended up not having any motivation to pursue meow. It's a shame, but it is what it is. That said, I found that setting up `evil` wasn't as bad as I thought it would be. If you want to see how simple it can be, you can take a look at the pull request I linked in the original post. I can also recommend taking a look at this config for another example of how setting it up can actually be very simple: https://github.com/ianyepan/yay-evil-emacs
wunderspud7575 · 2022-12-25 18:10
Am curious to know why you used `(load 'foo)` rather than `(require 'foo)` (with foo.el having a `(provides 'foo)`)? Speed?
skyler544 · 2022-12-25 18:43
I didn't really put any thought into it other than "hey, interesting that I can use `load` without needing `(provides '...)`." It would be interesting to find out if there's any other difference; whether that's for "safety" or just because it's a convention, or whatever else
wunderspud7575 · 2022-12-25 20:06
Makes sense - keep it simple.
ieoa · 2022-12-25 22:58
> jt What's this? I tried googling and searching on Melpa and couldn't find anything.
aisamu · 2022-12-26 12:59
I suspect that was a just typo: > Please check **it** out as well
ieoa · 2022-12-26 14:06
That makes *much* more sense. Thank you