This is more or less my vanilla-ish Emacs playground. I start from nano-emacs. It’s pretty and pretty useful. But expect it to veer pretty far from that base over time.
There’s bound to be a lot of things that make you, the Emacs veteran, wonder “why didn’t he just do X?” The likeliest options:
- I didn’t know X was an option
- I saw X but wanted to wait until I understood it
That last is particularly likely. I keep getting reminded that outsmarting yourself is a major hazard of Emacs configuration.
org-pymacs-nodejs-todoist-roam-lsp-mode later. Maybe. I
may not even need it.
Give Emacs some breathing room
max-specpdl-size sets the upper limit for how many variable bindings and
unwind-protect Emacs allows.
max-lisp-eval-depth says how deep we can get into a recursive function call.
I got the RAM so let’s go past the respective defaults of 1600 and 800.
And of course I’m sure to screw something up so let’s make sure the debugger is enabled for when I do.
Enable local lisp
Simplify reloading my config
I putter with this config marginally less than I did initially - progress! - but enough that restarting Emacs for every config tweak gets tedious.
One of the ideas I grabbed from Vianney Lebouteiller’s Emacs config.
Use straight.el to install packages
straight.el is my new friend.
But if I’m using
straight.el I better disable
package.el during the early init
Boilerplate from the
I tried to avoid use-package here for a more “minimal” setup. That did not work.
straight.el plays nice with
use-package, let’s let it do that.
General guidelines for text handling
Where to put the fill column marker for line wraps, how many pixels to put between lines, stuff like that.
I read Steve Yegge’s effective-emacs a long time ago — back when it was an internal Amazon blog. Applied his suggestion to invoke
C-x C-m and that’s been part of my Emacs muscle memory ever since.
Make a few adjustments for running on macOS
Make sure the macOS Emacs GUI app picks up environment variables.
macOS doesn’t use GNU Coreutils and of course its
ls isn’t what
dired expects. Adjust for that.
visual-fill-column for a nice soft wrap
The Roboto Mono font that NANO wants is not part of any
*roboto* package I
found in Pop! OS repositories. Ended up going to Font Library for a direct
With that note out of the way - I still lean towards Fantasque Sans Mono.
nano and its dependencies
Load the Nano layout
Define my colors
Because I’m the kind of person I am: setting the nano theme colors to match my own tacky tastes. Maybe not tacky but certainly not as refined as the author of nano.
This particular set of colors comes from the Spaceduck theme.
Set up font faces
I feel comfortable loading
nano-faces for font rules now that I’ve defined my colors.
Will need to fuss a bit more in a second though.
Want to overload some of the defaults, though. nano-emacs does not like to show bold text when using Fantasque Sans Mono.
Let nano theme everything
nano-theme maps those custom faces to pretty much everything everywhere.
Except for this little thing where it disables bold for graphical displays? I think? I’m still learning how all this works.
I know I like bold, though. And italics, now that you mention it.
Once I have my base established, I should be able to load the nano theme.
Load nano defaults
Enable nano session handling
Enable the nano modeline
One of my favorite bits really.
Enable nano key bindings
- kill current buffer without asking
- open a new frame
- switch to other frame
- delete the current frame; exit if no frames remain
- interactive select from recent files
- toggle maximization of current frame
- not sure if I like this one; it confuses org muscle memory, and if I want “maximized” I usually toggle tiling in the window manager
nano Counsel integration
nano-counsel.el is small. I’ll just map its logic directly to some
I need to give myself a little context here.
Ivy, Counsel, and Swiper
flexible, simple tools for minibuffer completion in Emacs
These are technically separate packages developed together in the swiper repo.
- an alternative completion framework for Emacs
- Ivy-enhanced alternatives to common Emacs commands
- Ivy-enhanced alternative to Isearch
nano-counsel failed with complaints about missing
Smex provides enhancements to
M-x behavior, such as an interface to recent and commonly used commands.
Since I want my foundation to be a clean Nano experience, I install smex as well.
Life management with Org
Okay here we go. Building up my
org-roam experience while keeping Deft handy for the longer, more intentional notes.
I work this out piecemeal, as some of the files and folders build on what’s been defined before.
First: what’s the top level of everything? That depends on whether I’m in a UNIX-like system or playing with the native Windows version of Emacs.
Trying an experiment where first we look for a local
~org/ folder and
use that if found, otherwise going with my actual default of
~/Dropbox/org. Trying to shift over to git-synchronized Org files
instead of Dropbox-synchronized, but that change will take a bit to
percolate through all my systems.
That’s enough to define most of the files I need.
Oh, one more thing. I want to include
org-roam files in my Org
agenda. I found helpful instructions, but I’m not adding that code to
my config until I understand it. Maybe if I follow the link to the
beginning of the post series and start there.
What a novel idea.
But today? With my small collection of
org-roam notes, I can get away
with directly including them in my agenda searches.
Tumblelogging with ox-hugo
I started an experiment with using Org to drive a tumblelog at Random Geekery Life. Tumblelog is an older term for a blog that mainly consists of dumping whatever thoughts, links, or just whatever. Sort of like Twitter or Tumblr, but on my own site and less constrained than a tweet-length microblog. Someday I may put more words elsewhere and replace this all this explanatory text with a link.
For now I build the visible tumblelog as a static site with Hugo. It’s quick and it’s familiar.
Org enters the scene with a single file within my Hugo site.
That file contains all the content for the tumblelog, but the important part here is a function to dynamically generate a filename for ox-hugo based on the current time.
Hugo configuration determines permalinks from post dates, which ox-hugo derives from task completion timestamps. If I want to keep all the times for an entry in sync I manually edit, but it’s not a big deal yet.
C-t d muscle memory so far is quicker than figuring out how to automate that process.
The actual filename gets ignored, but the epoch timestamp keeps each output file unique at my normal human rate of adding entries.
This also squeaks me past the fact that I came up with this version of the template after I already had a few entries.
Then when I’m building
org-capture-templates I create a
datetree entry for tumblelogging.
A process vagiuely similar to GTD but my brain insists on its own task classifications.
- I need to do it, but it can wait (or it’s waiting on something)
- I got everything I need to do this
- An idea, suggestion, or action that I may or may not want to to
- A multi-part task with notable dependencies
- I did it!
- Never mind
CUSTOM_ID generation via writequit
Grabbing directly from this post.
More to keep my
org-roam-ui graph in order than for publishing, but
hopefully it’ll come in handy there too.
Putting it all together
Additional Org tools
The perfect solution for knowledge management varies by context. But the core thing really needed: someplace to drop my notes where I can find them when I need them.
Deft provides exactly that. And since Org mode is the main reason I load Emacs, my
~/org folder is where Deft will look for notes.
I don’t want
org-roam notes obscuring the more persistent notes in my Org folder. Better ignore them. Also the
org-brain stuff until I have a good handle on that.
Helpful hint when enabling
deft-recursive: =../ is one of the entries in your directory listing, and Deft will do its darndest to follow it if you forget to include it in
deft-recursive-ignore-dir-regexp (set to
"\\(?:\\.\\|\\.\\.\\)" by default).
This can lead to all sorts of recursive headaches, so don’t forget!
Of course I’ll end up tweaking it. But to get me started?
“Ask deft about my notes” is more than sufficient.
Taking advantage of
org-roam-dailies for journaling. I started by
copying from OrgMode-ExoCortex and System Crafters.
I like to always see backlinks as a side-window of my current view.
Something is off with my
:bind-keymap settings for
Until I learn enough to fix that, I’ll make a global binding for the
one I care about: going to today’s daily note.
For the pretty. Sometimes I enable
org-roam-ui-mode on load.
Although ox-hugo isn’t required to use Hugo with Emacs, it sure does simplify things.
Project management with Projectile and friends
Projectile plus a
.dir-locals.el file seems like the right way to
handle development projects without bumping into everything else.
lsp-mode and related for an IDE experience
lsp-mode adds support for Microsoft’s Language Server
Protocol. Hypothetically that means easier setup of commonly desired
features like linting and autocompletion.
lsp-mode uses YASnippet for abbreviation and expansion.
lsp-mode’s breadcrumb trail wrestle with each other
for space on that top line. Maybe someday I can figure out how to
stack them. Until then, I like the modeline and its placement more
than I like the breadcrumb.
Pyenv for Python versions.
I manage my projects with Poetry. poetry.el offers a nice Magit-like interface to managing and maintaining Poetry projects.
In particular, it might simplify venv handling when I get to linting tools and language server providers.
which-key adds a completion panel for commands. That helps me learn
the many Emacs key maps.
Treemacs is a file explorer sidebar. That part is kind of “meh” for
me. The outliner provided by
lsp-treemacs interests me much more.
To get Treemacs and nano playing nice I had to comment out line 515 of
nano-modeline.el in my local copy of nano.
Watching issue #75 for updates on this problem.
dired icons, and I want them consistent with my Spaceduck colors.