Bowmansarrow

Another month has passed. I've tried to get as much done as I can think of in order to move to a “beta” release (if you want to call it that). So, as I'm running out of things I think are critical to get done, I'm now announcing the move to a “beta” release!

To get here the following updates have been made:

  • Module consolidation for several similar modules.
  • Archival (soon to be deleted) of several modules replaced by the above effort.
  • Support built in package.el as the primary package management solution. Before, we included code to support both package.el and straight.el, that code has been removed, but there are some general instructions on using packagers other than package.el with Crafted Emacs.
  • Separate package lists from package configuration.
    • Using modules with the suffix packages simply adds “bundles” of packages to the list of selected packages. Doing so allow use of the built-in package-install-selected-packages function to install everything needed at once. Packages already installed are skipped without additional checks and is generally faster and easier to use. N.B. these are not required if the user installs their Emacs packages from external tools, for example guix or nix or other operating system package managers.
    • Using modules with the suffix config assumes packages have been installed and provides configuration for them. There are checks to make sure those packages are installed and enabled by the package system before configuring them.
  • Rewrite the README.org file, consolidate some parts to make it more concise. The intention is people will actually read the README file rather than skip it due to how long it is.
  • Provide a “Getting Started” guide and link to it from the README.org as well as in the generated info file included with Crafted Emacs.
  • Change the approach to configuration to push customized values to the default Emacs custom-set-variables section of the custom-file. This enables the user to decouple from Crafted Emacs and (mostly) not lose any configuration.
  • Simplified both early-init.el and init.el. Now these files are in the users control and we only provide examples of their use rather than providing the implementation.
  • Crafted Emacs no longer stores configuration in it's own folder. This was problematic for several reasons, as different packages dropped files or folders in the user-emacs-directory and we had to detect those and move them to the CRAFTED_EMACS_HOME. That effort was incomplete so files were scattered across the two directories leaving a confusing mess. Everything now is in the user-emacs-directory and the user has control over moving them to XDG locations if they choose, or possibly using something like a no-littering approach.

This is a very divergent approach compared to what Crafted Emacs has been so far. I'll be writing a transition guide for existing Crafted Emacs users. Those who wish to try it are encouraged to send feedback via issues on the project GitHub site.

Tags: #emacs

Sometimes, real life gets in the way of progress. That has happened to me, unfortunately, so I'm late on posting progress on the Crafted Emacs rewrite. I have made a bit of progress to get the project more polished and ready for a “beta” release, and I think I'm almost there.

Since the last update, I have been working more on the documentation side of things. I have rewritten the project README file, I have added a “Getting Started” guide (which is still incomplete), I have updated the Info manual, I have removed a lot of “old” stuff that won't be making it into the next “version” of Crafted Emacs.

I had moved to a Guix virtual machine for development purposes, I thought that might be an interesting experience as well as give me an opportunity to test integration using guix-home to install Emacs packages and configure them with Crafted Emacs. That turned out to be more frustrating for me and I have since abandonded that virtual machine. I went back to my trusty Vagrant configuration. On the way I found out the compat library isn't built-in enough to Emacs, so I had to add code to make sure it gets installed before I start using it. The crafted-init-config.el handles that now. Another odd behavior I ran into, it seemed like the list of selected packages was not being saved in the custom-file. I added a hook to handle that after Emacs finishes initialization. That might be a little fragile as I'm using an internal package.el function, however that function, when called, will put itself in the after-init-hook, so I feel less bad about it. Another tweak, setting the load-prefer-newer was added to crafted-default-config.el; still baffled why this needs to be set to t at all, I feel like it should be the default. I'm sure the Emacs maintainers have a good reason though. And I started work on some examples as well. Over time, I'm sure I'll think of other examples to include there as well. For the moment, there is just one, and it matches what is in the startup guide.

If you are feeling adventurous, or are running Emacs 29 and want to use the new --init-directory command line to test Crafted Emacs V2, your feedback would be welcome. Please read through the documentation as a lot has changed. Also, I'm still making changes, so no guarantees I won't break something – it is still alpha level code at the moment.

I feel like I keep saying this, but more to follow next month. And, I do feel like I'm getting closer to something I could turn into a beta, just not yet.

Happy Crafting!

#emacs

Another month has passed, more development for the next version of Crafted Emacs! Picking up from last month, I've been working on the plans for the modules I outlined before.

  • crafted-defaults-config is now a more complete starting point, and is the combination of the crafted-mastering-emacs and crafted-windows modules. Those have both been marked for deletion.
  • crafted-ide-config and crafted-ide-packages have both been updated. The latter includes packages like Mickey Petersen's Combobulate package, aggressive-indent, editorconfig, and ibuffer-project. Additionally, there is code to handle both Emacs prior to and post Emacs 29 for tree-sitter and eglot inclusion. crafted-ide-config now configures those packages with the same attention to pre-/post-Emacs 29. Language specific modules were deleted.
  • crafted-writing (thanks to the suggestion from the #systemcrafters IRC channel for the name) now combines the former crafted-editing, crafted-latex, and crafted-pdf-tools modules, as well as additional settings for writing… well… things!
  • I leveraged the compat package to smooth the path toward adoption of Emacs 29. I use keymap-set and keymap-set-global for any key bindings in modules, including references in comments. However, as that package is meant for package authors and not configuration authors, there is no provision for moving to use setopt in place of customize-set-variable.
  • I removed the configuration for use-short-answers as its use is discouraged in documentation.
  • Customizations are now saved to the custom-file after the Emacs finishes initialization.
  • I found a way to set the crafted-emacs-home variable in case it isn't set by the user. I'm not checking for an environment variable value yet, that is still on the todo list. But now, just loading the crafted-init-config module is sufficient to set the load-path so the other modules can be simply required.

On that last point, an example init.el file might look like this structurally:

(when (file-exists-p custom-file)
  (load custom-file :noerror :nomessage))

(load "/path/to/crafted-emacs/modules/crafted-init-config" :noerror :nomessage)

;; -- below not needed when using Guix to manage packages --
;; add any packages to the `package-selected-packages' list
;; for example:
(require 'crafted-ide-packages)

;; install packages as necessary
(package-install-selected-packages :noconfirm)
;; -- above not needed when using Guix to manage packages --

;; add any crafted configure modules
(require 'crafted-defaults-config)
(require 'crafted-ide-config)

;; any personal configuration, for example:
(keymap-set "C-c '" #'imenu)

When using GNU Guix to manage your Emacs packages, the bits related to adding packages to the package-selected-packages list and then installing them is not needed. The same might be true if you use some other tool like straight.el to install packages. I continue to eschew using use-package, this does not prevent the user from doing so in the “personal configuration” section in the example above. In fact it may be possible to use use-package everywhere once the crafted-init-config file is loaded.

While I feel like I'm making progress, there is still much to do. From my list last month, I haven't begun to touch the documentation or examples. I have a few articles to read and test ideas for a more usable completion experience out-of-the-box using built-in facilities. This work will be in the crafted-defaults-config module. The intention is to be able to load just that one module and have a nicely working Emacs configuration. Enhancements come from adding any additional modules, like crafted-writing-config, crafted-completion-config, etc.

More to follow next month, but I feel like I'm getting closer to something I could turn into a beta. I'll probably start to focus more on the documentation and examples so I can do just that sooner rather than later.

Tags: #emacs

Recently, I saw this article from Mickey Peteresen on his combobulate package. It looked interesting, so I thought I'd give it a go. I got together with a friend from the Austin TX based ATX Emacs group and we tried it out. Well, I did anyway, he was busy trying to compile Emacs with Tree-Sitter support on his Mac and not having much success.

I finally did get it working, but it took a moment to get things to setup. Since this was for Emacs 29, I compiled a version and made sure to include --with-tree-sitter. Then I thought to try out using package-vc-install to install combobulate, but alas, that didn't work. I was getting this error:

(file-error "https://melpa.org/packages/elpa-packages.eld" "Not found")

And it turns out, package-vc needs the elpa-packages.eld file, which neither MELPA nor MELPA Stable provide. Removing both from the package-archives resolved the error and installed the combobulate package.

UPDATE: 2023-02-13

The above has been fixed! I received an email from Philip Kaludercic, who let me know he had fixed this. I built a new version of Emacs29 and package-vc worked like a champ! Thanks Philip!!

… now back to the rest of the article previously posted …

Since package-vc was giving me difficulties at the time, I used quelpa to install the package (the debugging to resolve the error above came later). I used this recipe to get combobulate installed:

(quelpa '(combobulate :fetcher github :repo mickeynp/combobulate))

If you read the GitHub page, he provides a detailed configuration for getting tree-sitter language sources and compiling them. However, there is the tree-sitter-langs package which already does this. Some deep diving into the treesit package built-in to Emacs 29 led me to the tree-sitter folder in the user-emacs-directory. I used dired to copy the files from the tree-sitter-langs package, and then used wdired mode to rename them in bulk to be prefixed with tree-sitter- and presto! Everything just worked! Here is the final configuration which worked for me:

;; if neither MELPA nor MELPA Stable are in package-archives this
;; should work:
;; (package-vc-install '(combobulate :url "https://github.com/mickeynp/combobulate"))

;; Works even if MELPA or MELPA Stable (or both) are in the
;; package-archives
(quelpa '(combobulate :fetcher github :repo mickeynp/combobulate))

;; manual step: copy .so files from tree-sitter-langs to
;; tree-sitter/tree-sitter-*.so in the user-emacs-directory

;; add more languages as necessary
(add-to-list 'major-mode-remap-alist '(python-mode . python-ts-mode))

;; add more language hooks as necessary
(add-hook 'python-ts-mode 'combobulate-mode)

Combobulate was fun to use. The navigation works exactly was I had hoped. Coming from writing a lot of Emacs Lisp, the movement matched my existing habits. I am looking forward to more features than just movement, though. Things like smartparens slurp or barf concepts, refactoring (like extract method, wrap with conditional, rename, etc), perhaps indentation linting. For the moment, movement is good enough and LSPs (although, the refactoring support is dismal – but that's another topic) or intelligent snippets provide some of the other features .

Tags: #emacs

This will be a bit of a shorter update on the Crafted Emacs project. Nothing changed from last month on the current version, but a lot has changed on the major changes discussed in my last post.

Updates to modules

Crafted Emacs v2 Alpha. That's what I'm calling it. It's very alpha at the moment. I have worked through all of the modules at this point. The first pass was to accomplish several goals:

  • Get rid of the defcustom variables as much as possible. There are still a handful left to figure out, but most of them are gone.
  • Split the modules into packages and config modules. The former just updates a list of packages to install which the user will need to make happen, the latter is for configuring those packages, assuming they were installed.
  • Don't make assumptions about the packages installed. I use featurep to check if packages are enabled before configuring them. I also make use of with-eval-after-load in several places to control when configuration takes place. I need to be a lot more consistent with this approach, so will need to review this work going forward.
  • Things controlled by customizable variables are now (mostly) functions to call. The idea, if it was an optional thing, then not calling the function serves the same purpose as setting the customization option to nil.

Removed early-init.el and init.el

With our focus changing from being a “starter kit” to being a set of configurations to quickly craft your own configuration, we don't need startup files. Those are provided by the user. That said, there is a little structure that we assume, so I have both of these files as examples and have commented them heavily to illustrate how someone might approach writing their own.

Expectations

There are some expectations, like the custom-file is loaded first so we can have the package-selected-packages value initialized before using any of the crafted-*-packages modules.

We also need to know where the user cloned the crafted-emacs project, so these two lines are needed very early in the init.el file, before using any other crafted modules:

(load "~/crafted-emacs/modules/crafted-emacs-home-config")
(load "~/crafted-emacs/modules/crafted-init-config")

The first defines a variable, then the second is able to use that fact to find the file where it is defined and set the crafted-emacs-home value to the project-root of that file. Or the user can just set it manually, either way, that variable needs a value before we do anything with the modules. The crafted-init-config also takes a moment to update the load-path so the modules can be found later.

Once all of the appropriate crafted-*-packages modules are loaded, then the packages listed in the package-selected-packages need to be installed. I assume use of package.el so that is just a call to package-install-selected-packages. I have a crafted-package-config module with helper functions for this as well. If the user chooses a different package manager, there are a couple of variables which can be set before using the helpers I provide. Otherwise, just iterate over the list and install the packages. For example, this might work (maybe…):

(mapc #'straight-use-package package-selected-packages)

Once the packages are installed, then they need to be configured, which is where the user would then load any of the crafted-*-config modules needed. So the order might look something like this:

(when (and custom-file (file-exists-p custom-file)) (load custom-file))

(load "~/crafted-emacs/modules/crafted-emacs-home-config")
(load "~/crafted-emacs/modules/crafted-init-config")

(require 'crafted-completion-packages)

;; ...

(package-install-selected-packages)

;; ...

(require 'crafted-completion-config)

Plans of more things to come

There is still much to do:

  • Ensure there are copious code comments describing how to use *everything*.
  • Conflate several of the modules into more general versions. For example, I'm planning to get rid of the language specific modules (Python and Erlang in this case, although I'll keep this Lisp module because, well Emacs… it's a Lisp Machine) in favor of a more rich crafted-ide-config module. Similarly, the LaTeX and PDF modules will be conflated with the editing module. There are others and I'll have to carefully consider how to best move forward with fewer, but richer modules.
  • Rewrite the README.org file
  • Rewrite the info documentation
  • Develop more startup file examples and put them all in the examples folder and then document them in the info file and possibly in org files to be loaded from README.org.
  • Document how steps to disconnect from using Crafted Emacs when your configuration grows beyond needing it. Some of that will happen naturally without needing any documentation. Obviously, if the user is rewriting, copying or whatever chunks of Crafted Emacs, eventually there isn't anything left for them to load in their init.el file. However, just in case, I'll mention some of the things one should look for when its time to move on from Crafted Emacs.

While I say things are probably not working, I do have a working configuration I'm using to do the development. It still loads pretty fast, but I don't have my full configuration there (yet). Once I get through more of these changes and the dust settles a bit, I'll move to a “beta” level and start looking for help getting across the finish line so it can be “released”. Which in this case really just means renaming a couple branches since this work will likely not merge to master without significant effort. That is still some time in the future.

Tags: #emacs

Welcome to 2023 and another update of the Crafted Emacs project! Today's post is going to be different than prior posts; today I discuss what is coming in the, hopefully, near future for Crafted Emacs.

Major changes are coming. After a year of working on this project we have learned a lot of things, not just about working on an Emacs configuration, but about our own goals for the project. Many of the original principles and goals will remain, but with a different focus. The change then… we are moving from the concept of being a starter kit and really getting back to the one of the original concepts with the System Crafters mentality – that of “you own your own configuration”.

To that end, here is a short list of things we are going to change. This is not an all inclusive list at this time, but just because this will be a disruptive change (or many of them!) we are trying to communicate them early.

  • No intention for the user to clone the crafted-emacs repository as ~/.config/emacs or ~/.emacs.d. We intend to be agnostic enough for the user to clone the repository as a sub-module for their own dot files, or in a completely separate location and then added to the load path through their own configuration. What we would prefer is the user to *not* use this as a starter kit, but rather a we prefer the user own their own configuration and use Crafted Emacs as a faster way to get started.
  • No more built-in support for Chemacs2. Especially with the updates to Emacs 29 which provide that kind of feature out of the box.
  • The default package manager will be package.el, but we will provide a “hook” to allow you to provide your own package manager, be it straight.el, elget, borg, package-vc, whatever.
  • No more crafted-emacs folder, at least not by default. We may optionally install the nolittering package and provide a minimal configuration there. TBD.
  • No more early-init.el or init.el. Well, sorta. We will largely clean out those files and provide only a minimal configuration which a user might use to jump start their configuration. Essentially, those will be considered obsolete in favor of having the user provide their own. This means we won't be turning on a default theme, no default font list, no GUI customization, etc.
  • Reduce or (ideally) completely eliminate all Crafted Emacs Customizable variables.
  • Possibly split the modules into a package list and a configuration for each type. So, if the user only wants the list of packages for something (like completion for example), they can use the appropriate package module to get that list. If they only need the configuration, they can use the appropriate configuration module. Or use both if they prefer. Ultimate flexibility for the user.

So lots of changes coming. I'll still be doing what I can to fix issues as they appear for the existing project codebase, but this will be my focus for a while. When I have something stable enough to test, I'll share the branch where I'm making the changes. With this effort, I'll close a lot (maybe all) of the outstanding issues so we can start with a clean slate.

Shameless Plug

If you enjoy configuring Emacs and tweak yours often, you might consider giving Crafted Emacs a try. I'm sure you'll find some rough edges, and when you do, I invite you to open an issue, or submit a pull request. Or, maybe you won't find any rough edges and this will be just the thing you need. I'm not holding my breath on that just yet.

If you enjoy crafting your computing experience, from hacking on Emacs, your Linux/Mac/Windows configuration, maybe your Guix or NixOS home configuration, or whatever it is… consider joining the SystemCrafters community!

Tags: #emacs

Another month gone by and a few more updates to the Crafted Emacs project!

But first, I hope everyone had a happy holiday season. This time of year is fun for me as I usually take off quite a bit of time from work and tinker with pet projects. This year, I worked on the Advent of Code for a while. I didn't finish the challenge, but I had fun doing the parts I did finish. Gavin Freeborn did one day in Emacs! See the video here.

Pull Requests

For Crafted Emacs, we saw some interesting pull requests come in, here is a list:

  • Show eldoc after a corfu selection. This puts the eldoc information in the minibuffer when a completion selection is made.
  • Add corfu extension directory to the load-path. This has to do with those who use straight.el for their package management. straight.el does not install packages in the same way package.el does, so additional directories for packages with extensions get lost, unless you add them to the load path. This PR does that for the corfu package.
  • Add corfu-terminal to when non-graphical display in use fixes an old complaint related to corfu when Emacs is running in a terminal.
  • Add documentation for using Eglot with Python. Eglot replaces all entries in flymake-diagnostic-functions, this PR puts python-flymake back in the list.
  • And finally, a lot of minor fixes to the documentation to improve the quality there.

Issues

On the issues front, there has been a few with some good discussion:

  • One suggests to make the modules completely independent of the project. I discuss one way this can be approached with the current project as is. The author of the issue is considering a PR to make things a bit less tightly coupled.
  • One user had issues when starting Emacs at work. The network and proxy configuration would stall the package archive updates and slow down or stall the startup process. So, I updated Crafted Emacs to allow the user to configure the number of days before an archive is considered stale, and completely turn off the stale check thus disabling the updates on startup.
  • There was a request for the rational for not using use-package. That issue was answered, and a PR was submitted which copies most of the text into the README.org file, but I haven't pulled that PR in yet.
  • The most recent issue is a notification of a change to the keycast package which changes the name of a variable from keycast-mode to keycast-mode-line-mode. This applies to those who use straight.el to pull from the “master” branch or those who prefer to use the “MELPA” archive.

For those who are interested in participating in the project, there are still several modules which need documentation, that would be a great place to start!

Shameless Plug

If you enjoy configuring Emacs and tweak yours often, you might consider giving Crafted Emacs a try. I'm sure you'll find some rough edges, and when you do, I invite you to open an issue, or submit a pull request. Or, maybe you won't find any rough edges and this will be just the thing you need. I'm not holding my breath on that just yet.

If you enjoy crafting your computing experience, from hacking on Emacs, your Linux/Mac/Windows configuration, maybe your Guix or NixOS home configuration, or whatever it is… consider joining the SystemCrafters community!

Tags: #emacs

It's been another month, time for an update! This post will be a bit longer than others, I have a few different things to talk about:

  1. Crafted Emacs Update – a few PRs were merged, a few issues closed.
  2. Tracking development rather than using stable versions
  3. An interesting post on namespaces and shorthands and my thoughts on those.

Crafted Emacs

  • A pull request was submitted to use the tabspaces package for managing buffers for a project. It's a neat idea, I haven't tried it out, but the concept and demo from the GitHub page look pretty neat. I have used tabs to do approximately the same thing, so I might try this new configuration and see which I like better. Check out the GitHub page though (see link above) and read about it to see if it makes sense in your workflow.
  • There have been several issues with doom-modeline, mostly related to the package found on MELPA and people who use Helm. This broke a few configurations, but the solution was the same in those cases, stop using doom-modeline. I pushed a change to do just that. There is a variable to customize to enable it again.
  • Another pull request added showing the eldoc for a completion when it was selected when using Corfu.
  • corfu-doc as a package has been deprecated. The authors of Corfu and Corfu-Doc worked together to pull that package in as an extension to Corfu itself. The new extension name is corfu-popupinfo. There was an old pull request to remove corfu-doc once the merge had occurred, however, it was from before the name change from Rational Emacs to Crafted Emacs. I pulled that request in, fixed the conflicts and name change for global-corfu-mode and now everything is back up-to-date and working well. The author of that pull request even mentioned the new corfu-popupinfo was working very well indeed!

Versions: development vs released aka stable

I've commented on this topic before, but as it has come up again a few times recently, it seemed to be a ripe topic to talk about again.

Crafted Emacs, if you use package.el prefers to install “stable” packages rather than development versions. Stable, in this context should really read “released” though. The name of the repository has the word “stable” in it though. The reason we prefer the stable packages is they are more likely to not break on update, and updates come (usually) a bit slower. There is no guarantee the package authors have completely tested every integration point with other packages, or that any testing at all has occurred. That statement is true of the development versions as well, they just change more frequently.

So, why bring this up again? Well, if you prefer to use straight.el with your Crafted Emacs configuration, you risk pulling development versions which might break your configuration. This is because we don't prioritize released versions, so you get the most recent commit. Sometimes, that breaks things. This happened a couple of times with doom-modeline this month. One suggestion I had was to install a released version. In at least one case, that solved the problem. In another case, turning off doom-modeline worked just as well. This came up enough times, I chose to just disable doom-modeline by default.

Thus, if you choose to use the development versions (i.e. pull directly from a source repository on the main development branch), then understand things may break in surprising ways. Possible options when this happens:

  • Ensure dependencies are also up-to-date, sometimes just updating the dependencies will resolve the issue.
  • Revert to a previous commit that was working for you.
  • File a bug report, ideally with a patch or pull request to fix it.
  • Install a released version (pull from a tag in version control).

In a bit of irony, sometimes a released version will break on update because it depends on a development version of another package that doesn't have releases. This is an unfortunate situation. If you happen to be using straight.el you can lock that development version to a specific commit.

Namespaces and the shorthand feature in Emacs 28+

There is a very interesting post on the use of the shorthand feature in Emacs. Andrey does a great job of describing shorthands, how they compare to other systems and the “namespace” topic in general. In my case, didn't even know shorthands were a thing, so I learned something. If you haven't read the topic in the Emacs Lisp manual (online here), take a read on it.

Emacs lisp does not have namespaces. At least not in the sense that other lisps do. It's a manual process to prefix the name of the file before all the symbols in that file to “namespace” things. For example, in the file crafted-package.el symbols all have the prefix crafted-package- and we get names like crafted-package-install-package. The first bit is the “namespace”, if you will. What a shorthand does is tell the reader to substitute a shorter version (a shorthand) for the “namespace”. In this example, we could have a shorthand description of: (("cp-" . "crafted-package-")) and then I could write cp-install-package. Nothing changes under the hood, as a matter of fact if I place the point on the cp- portion, the eldoc says the full name in the echo area.

I'm not sure I will be using this feature in any Crafted Emacs modules. I think it's a little clearer to just spell things out, even if that makes the name of a symbol fairly long. It's also a bit inconvenient to scroll to the bottom of the file to find the shorthand definition in the local variables comment. Imagine having several shorthands described, you'd have to jump to the bottom to see which shorthand applied to which “namespace” just to read the code. Here is the example from the manual, but consider if this were from a larger work and how confusing it could end up being if there were a few more shorthands or the file was fairly long.

(defun t-reverse-lines (s) (string-join (reverse (sns-lines s)) "\n")

;; Local Variables:
;; read-symbol-shorthands: (("t-" . "my-tricks-")
;;                          ("sns-" . "some-nice-string-utils-"))
;; End:

Shameless Plug

If you enjoy configuring Emacs and tweak yours often, you might consider giving Crafted Emacs a try. I'm sure you'll find some rough edges, and when you do, I invite you to open an issue, or submit a pull request. Or, maybe you won't find any rough edges and this will be just the thing you need. I'm not holding my breath on that just yet.

If you enjoy crafting your computing experience, from hacking on Emacs, your Linux/Mac/Windows configuration, maybe your Guix or NixOS home configuration, or whatever it is… consider joining the SystemCrafters community!

Tags: #emacs

Two posts in one month! That's new! After my last post, I thought I'd catch up with an update about the issues and pull requests that have happened since the rename. I also made a really long post on Discord which I will cover later in this post as well.

Issues

There have been a few issues raised, the current outstanding ones haven't seen much movement in quite a while.

  • Add guix as a possible package manager from inside Emacs. The idea here is the call to crafted-package-install-package would actually shell out to guix to install the package from the Guix Store. An interesting idea and there is a good discussion there.
  • Use Git sub-modules. This one is about adding some text to the README.org file to describe how a user might use Git sub-modules when cloning crafted-emacs and their own config in the same directory. It's a bit out of scope for Crafted Emacs, but not a bad idea. I'll leave it open for a bit longer in case someone decides to step up and push a PR for it.
  • Use the XDG specification. This one is about re-homing the users config to fit the XDG specification, ie using .local for packages, .config for config files, .cache for temporary files (like history, projects, recentf, etc). We already re-home things to the crafted-config-path which has its own issues, especially since I haven't found every single place where Emacs drops a file or folder in the user-emacs-directory so that I move it to the crafted-config-var-directory (for example). Someone thought they would put together a PR, but it hasn't come about yet, which is why I'm leaving this one open.
  • Add bookmarks to the startup page. This is a good idea. One of the things on my todo list is to rework the crafted-startup-screen code to make a more generic API and allow additional modules like bookmarks (ie common files) to be added to the startup screen. This would allow others to customize the startup screen more easily. Leaving it open for the moment until I can get some spare time to rework the code.
  • Use tabspaces to implement crafted-workspaces. An interesting idea, one I've started to try out, but without using the tabspaces package itself. The idea is to use Emacs built-in tabs for grouping project related buffers and (possibly) window layout. I don't know that we need a package to handle this, but I've found the concept useful as I now use it at work. One tab holds my org file with my tasks, meetings, notes, etc, and another tab holds my project files with its own window layout. I open another tab if I need to shift to another project, so I keep everything organized. All that is working well enough I'll probably take a serious look at implementing the requested solution. The author of the tabspaces project graciously replied to the thread and provided an example configuration. More to come on this I think.
  • And the real head-scratcher, symbol's definition is void crafted-package-install-package when using native compile. No idea on this one. Anyone out there who knows how native compile works and can jump in are welcome to assist. In the meanwhile, I'll figure out how to get that turned on (its not hard, just need to make sure my Emacs was built with the feature turned on and then enable it in my config), and then debug, debug, debug. This issue has an example configuration to use as well.

Pull Requests

There were a lot of these, most of them bug fixes, and an update to the straight package manager configuration to move to the most recent version. I won't mention all 23 of them, but here are some of them:

  • Initial config for LaTeX and PDF files
  • Fix early-init.el typo “crafted-bootstrap-directory”
  • Add error handling around crafted-updates
  • Fix typo in cljr-add-keybindings-with-prefix
  • Fix README.org typos
  • Fix compile issue when cache is not found
  • Add fallback completion style
  • Update straight.el bootstrap code

And a few other typos, fixes, removals after the Rational to Crafted rename.

Recap from Discord

I recently made a long post on the #crafted-emacs channel on the System Crafters Discord server. Here is a recap.

Compared to other starter kits

As far as comparison to other kits like Prelude (a personal favorite), Doom, Spacemacs et. al., Crafted Emacs is not a complete solution in the same sense as those are. You are expected to “fill in the gaps”. So, its like a quick start from scratch kinda thing. Imagine starting your config from scratch, but using some pre-built pieces for some common things (and, in some cases, not so common – erlang anyone?) to jump start your config.

Emacs 29 compatibility

On whether Crafted Emacs is ready for Emacs 29… well, YMMV. We (and by “We”, I mean “Me”) aren't trying to make sure it works with 29. Keeping it going and killing bugs as they appear for 27 and 28 is the priority. When the 29 release cycle starts, I'll probably get a fresh copy and start making updates on a branch to merge after Emacs 29 comes out. That said, if you are using 29 as your daily driver, just know there are breaking changes there which affect more than just Crafted Emacs. There are packages which have not (yet) updated to the Emacs 29 API differences, so things can break. Other features, like eglot being merged to mainline (!!) may cause a change in the crafted-ide module since we prefer to use eglot at the moment.

Crafted TODOs

Other things on my TODO list are items like:

  • The crafted-completion may also get an update to prefer built-in completers like fido-vertical-mode (available since 28) over the consult/corfu/vertico stack.
  • The crafted-evil module will probably stay around, but a crafted-viper module might appear as viper is built in and provides a reasonable vi-like style of keyboarding, so those who prefer built-in options will have that available as well.
  • I would also like to expand on the examples a bit and provide at least one using only built-in configuration, thus the crafted-defaults, crafted-mastering-emacs modules at least.

Shameless Plug

If you enjoy configuring Emacs and tweak yours often, you might consider giving Crafted Emacs a try. I'm sure you'll find some rough edges, and when you do, I invite you to open an issue, or submit a pull request. Or, maybe you won't find any rough edges and this will be just the thing you need. I'm not holding my breath on that just yet.

If you enjoy crafting your computing experience, from hacking on Emacs, your Linux/Mac/Windows configuration, maybe your Guix or NixOS home configuration, or whatever it is… consider joining the SystemCrafters community!

Tags: #emacs

Its been a while since I mentioned Crafted Emacs. The last update was back in July! There have been a few updates, a PR was submitted to update the straight.el configuration to use the newer version. There were a few other updates as well, mostly around some fixes needed in different places, and some additional documentation updates. I won't go into all of these on this post, instead I'd like to focus on the new module based on the book “Mastering Emacs”1 by Mickey Petersen.

I bought this book way back in 2015 mostly to support the author and because, well, who doesn't need another book about Emacs, right!? The cool thing, this is more like a subscription because Mickey Petersen keeps updating the book with each new release of Emacs. Which is pretty cool, if you ask me. He also writes an article here and there to demystify common areas of Emacs and provide some example configuration as well. Between the book and the articles, there is a lot to learn and benefit from on the Mastering Emacs site.

A few months back, David Wilson and Mickey Petersen got together and worked out a cool deal that helps support the System Crafters YouTube channel. Basically, if you buy the book using this link, a portion of the proceeds go to the channel. And Mickey sells a book. And you get to benefit from a ton of really good information. Everybody wins!

It had been a while since I read the book. After the news just mentioned, I got inspired to read it again and put together a module for Crafted Emacs based on the book. The really cool thing the book highlights is the amount of built-in stuff immediately available for use. He goes over a number of configuration elements and covers the absolute basics every user needs to understand when using Emacs. Its like the built-in tutorial only better! The built-in tutorial does get you up to speed quickly in terms of basic operations, but the book expands on that information (repeating it in some ways) and does a great job of explaining how to go about configuring Emacs with very little actual Emacs Lisp knowledge and usage.

Of course, as this is a Crafted Emacs module, I will pretty much only use Emacs Lisp. I'm sure you aren't surprised. Not only did I use the book as inspiration, I also reviewed a few articles, notably the following:

Some highlights:

(customize-set-variable 'completion-cycle-threshold 3)
(customize-set-variable 'tab-always-indent 'complete)
(customize-set-variable 'completion-category-overrides
                        '((file (styles . (partial-completion)))))
(customize-set-variable 'completions-detailed t)
(if (version< emacs-version "28")
    (icomplete-mode 1)
  (fido-vertical-mode 1))

(when (version< emacs-version "28")
  (defun crafted-mastering-emacs-use-icomplete-vertical ()
    "Install and enable icomplete-vertical-mode for Emacs versions
less than 28."
    (interactive)
    (crafted-package-install-package 'icomplete-vertical)
    (icomplete-mode 1)
    (icomplete-vertical-mode 1)))

This bit uses the built-in completion settings. With Emacs 28, uses fido-vertical-mode which is in contrast to vertico as defined in the crafted-completion module. For users with Emacs versions before 28, provide a form to possibly install icomplete-vertical-mode if desired, otherwise just continue with icomplete-mode.

The completion-cycle-threshold value is set low. If there are 3 or fewer completions, hitting the TAB key will cycle through them, more than that and a *Completions* buffer pops up.

(add-to-list 'display-buffer-alist
             '("\\*Help\\*"
               (display-buffer-reuse-window display-buffer-pop-up-window)
               (inhibit-same-window . t)))

(add-to-list 'display-buffer-alist
             '("\\*Completions\\*"
               (display-buffer-reuse-window display-buffer-pop-up-window)
               (inhibit-same-window . t)
               (window-height . 10)))

(add-to-list 'display-buffer-alist
             '("^\\*Dictionary\\*"
               (display-buffer-in-side-window)
               (side . left)
               (window-width . 70)))

This bit configures some windows. For *Help* windows, keep using the same buffer, for *Completions* windows, make the max height 10 lines tall. This last one is to avoid having a lot of completions take over the entire screen. The former is to avoid the buffer proliferation that occurs when using the helpful package installed when using the crafted-ui module. The last bit of window configuration moves the definitions window to the left side of the frame.

(define-key global-map (kbd "M-#") #'dictionary-lookup-definition)

There is a keyboard binding provided to call the dictionary to get the definition of the word a the point as well.

I turn on winner-mode, also provided in the crafted-windows, but unlike that module, no additional keybindings are provided. The default keybindings are CTRL-LEFT or CTRL-RIGHT to undo or redo layout.

(with-eval-after-load 'ispell
  (when (executable-find ispell-program-name)
    (add-hook 'text-mode-hook #'flyspell-mode)
    (add-hook 'prog-mode-hook #'flyspell-prog-mode)))

Spell checking is turned on in different modes if there is a suitable spell check program, either ispell or, better, aspell. No keybindings are provided, but the default of CTRL-PERIOD might conflict with Embark if you have that installed and configured.

Finally, there are a couple of functions available to install dumb-jump and hydra. The dumb-jump package is useful for jump-to-definition situations, and hydra allows for creating a “menu” of keys to use so you don't have to remember every keybinding. Just use a single “leader” key and the menu will pop up. This is similar in concept to how the transient package works, which is used by the magit (and others) package.

A nice feature of this particular module is you can really simplify your Emacs configuration to nearly this:

(require 'crafted-defaults)
(require 'crafted-mastering-emacs)

and have a very reasonably complete Emacs configuration. Notable missing features are configurations for Org mode and any specific configurations for the various programming languages. Crafted Emacs has other modules which provide some of those features, but you'll need to fill in the blanks where functionality is missing.

Shameless Plug

If you enjoy configuring Emacs and tweak yours often, you might consider giving Crafted Emacs a try. I'm sure you'll find some rough edges, and when you do, I invite you to open an issue, or submit a pull request. Or, maybe you won't find any rough edges and this will be just the thing you need. I'm not holding my breath on that just yet.

If you enjoy crafting your computing experience, from hacking on Emacs, your Linux/Mac/Windows configuration, maybe your Guix or NixOS home configuration, or whatever it is… consider joining the SystemCrafters community!

Tags: #emacs

Footnotes

1 See the Mastering Emacs website for more information.