#+title: Yuchen Pei's GNU Emacs Configuration #+author: Yuchen Pei #+language: en #+email: id@ypei.org * Intro :PROPERTIES: :UPDATED: [2023-06-26 Mon 16:02] :END: I started using Emacs and ditched Vim in 2020, and the content of this repo is the result of the config over the years. This config has several characteristics. It tries to stay close to the Emacs core. If a feature is needed, the quest to realise it always favours the Emacs core, followed by the GNU ELPA, then the NonGNU ELPA. In the same spirit, the keybindings follow the convention of Emacs core. * Organisation :PROPERTIES: :UPDATED: [2023-06-26 Mon 15:49] :END: Here's how the files are organised: - The =early-init.el= file :: The first file loaded by emacs, it does the following - Set the ~my-profile~ variable from the ~EMACS_PROFILE~ environment variable. This variable controls which packages to allow or ignore. Examples include ~emms~ and ~erc~ which causes a dedicated emacs instance to run ~emms~ or ~erc~, in which case most packages are disabled. The default profile, by contrast, disables these two packages. - Add a hook to report the time taken at the end of initialisation - Some optimizations - The =init.el= file :: The init file, it adds the ~load-path~, and ~requires~'s ~'my-package~, ~'ycp-package~ and the remaining configurations. Apart from ~my-package~ and ~ycp-package~, the remaining ~require~'s may be needed to be in a loose order. - The =lisp/my/my-package.el= file :: This file defines macros needed by the rest of the initialisation. After comparing [[https://protesilaos.com/emacs/dotemacs][Protesilaos Stavrou's]] and [[https://github.com/jwiegley/dot-emacs][John Wiegley's]] approaches, I decided to adopt the former, with the simple ~my-package~ macro, given that the delay and installation directives are sufficient for the use of this config, and it is closer to the emacs core. Another design decision is to not use org literate configuration. This file also defines functions and macros related to local config. The local config is a mechanism for separating out variables concerning machine-specific and/or personal information from the emacs config files in this repository. Values of these variables are set with the macro ~my-setq-from-local~ after running ~my-read-from-local-config~ to read the local config in ~my-local-config~. To generate a local config file from all the variables used in ~my-setq-from-local~ with their current values, invoke the function ~my-collect-my-setqd-vars~ which will print out an alist that you can put in a local config file. Finally, this file defines some other convenience macros for overriding functions and setting timers. - The =init/ycp-package.el= file :: This file determines what packages to allow or omit depending on the profile, calls ~my-read-from-local-config~ as mentioned above, starts the server, and sets the package archives to use. It also configure package related options, like the rest of the files in the =init= directory. - The =init= directory :: Files under this directory are customisations to various parts and they use the =ycp-= prefix. Each file is mainly organised into blocks of =my-package= and =my-configure= defined in =lisp/my/my-package.el=. They follow some principles: - The delay depends on the importance and the size of the package. - Packages are either installed from GNU or NonGNU ELPA or loaded from packages under the =lisp= directory. - The files are organised by functionalities, rather than specific packages, even if some of them are named after specific packages. For example =ycp-editing= is customisations about editing, and =ycp-grep= is concerned with grep, occur, isearch and so on. Some packages may belong to multiple files, in which case a certain precedence is used to resolve this. For example, =magit= provides vc features (=ycp-vc.el=) and is itself mostly a git client (=ycp-client.el=). Because =ycp-client= is for things that do not belong to other files, we place =magit= customisation in =ycp-vc=. - Avoid lambdas in hooks and keybinding, and name all functions instead. - The =lisp/my= directory :: Files under this directory are my extensions to other packages, as well as features that I have worked on but have not grown into a standalone package yet. Most features here have =my-= prefix. They are organised in a more refined manner than files under the =init= directory: - There are certainly files named after functionalities like under =init=, examples including =my-buffer.el= and =my-complete.el=, but they are strictly extensions to features that come with the Emacs core. For packages outside of the Emacs core, individual =my-foo.el= files are used, however small they may be. Examples include =my-consult.el= and =my-corfu.el=. Despite the customisation of both are inside =init/ycp-complete.el= - There are also files that are like libraries, like =my-utils.el= (defining common utility functions) and =my-algos.el= (algorithms and data structure implementation) - There are a few features without the =my-= prefix. They are more like standalone features, but have not graduated to their own packages or been merged into obvious packages they belong to, like =generic-search.el= and =emms-info-ytdl.el=. - The =lisp= directory :: Files under this directory are packages that cannot be installed from [Non]GNU ELPA. All but =lisp/my= and =lisp/mis= are git submodules. Apart from =lisp/my=, packages here belong to one of the follow cases. - My own packages that have not been submitted to GNU ELPA yet, for instance =hmm.el= and =buildbot.el=. - Third party packages not in either ELPA, like =directionary-el= and =nov.el=. - Individual packages that are a small part of a bigger non elisp project. They are placed under =lisp/misc=. Examples include =cmake-mode.el=. - The =tempel-templates= file :: tempel templates. There's also a gitignored =local-tempel-templates= for machine-specific and/or personal templates.