This is one of those nice bits about Emacs. You can tweak it almost endlessly. Keybindings can be remapped, or even supplanted. If you wanted to take any binding that mapped to undo, and instead pass it to your own custom function. You can do that. You don’t even need to know what those bindings are ahead of time. Any package that comes along and also adds a map to undo, will instead have it pointed correctly.
I tend to break my keybindings down into two general categories: Personal and package. My personal bindings are for things I make myself (functions) and changing around the default bindings to my liking. This tends to be a smaller list, since I’m focusing on just what is available. Packages, since I use use-package, are bound with the package. The reason for this is to ensure that if I add or delete a package from my Emacs configuration, the whole thing is contained in a block of configuration, instead of spread out across multiple files.
:bind (:map dired-mode-map
;; Reuse the same dired window ("RET" . dired-find-alternate-file)
("^" . (lambda()
;; Use 'open' to open the file with the user's choice ("E" . ndegruchy/open-in-external-app)
;; Get the file size(s) ("; d" . dired-get-size)
;; Toggle omit ("; o" . dired-omit-mode)
;; Close the frame, useful when using dired by itself ("; q" . delete-frame))
:config (setq dired-listing-switches "--group-directories-first -alh" dired-dwim-target t)
(setq-default dired-omit-files-p t)
(put 'dired-find-alternate-file 'disabled nil)
:hook (dired-mode . dired-hide-details-mode))
Keeping things organized is awesome, especially if you end up endlessly tweaking, like I do.
Emacs is what you make of it. While the defaults are great and are somewhat useful as-is, you’re going to run into situations where the defined bindings are less than optimal. I actually unbound a couple of keys because the way I type, when I hit M-x, I end up hitting M-z accidentally (my keyboard has a very shallow key travel).
To that end, it feels like the built in libraries are somewhat magical in how well they handle things. I’m comparing to C, whose idea of standard libraries feels unbelievably spartan in comparison. Different tools for different jobs, I suppose. There are really weird, simple pleasures in programming in Python. Consider:
from pathlib import Path
scoreboard = Path(os.environ.get("XDG_DATA_HOME") + "/guessing-game/scores.txt")
with scoreboard.open("a+") as scores:
// Game code here
This is delightful. I don’t have to do stuff like count to see if the return from Path is greater than 1 to indicate existence of a file, like I have to in JS when selecting elements, Path comes with a ready-made exists method that does exactly what it says on the tin. Oh, and the whole thing figures out the path on POSIX vs Windows path styles. Scrumptious!
I know my little honeymoon phase with my incredibly basic script will probably come crashing down when I want to do stuff more complicated, like have a high-scores list, but I’m enjoying it while it lasts.