Greetings everyone,

After I proposed a new customization interface for Emacs [1], I jumped on the 
occasion to rewrite my literate org configuration to replicate this interface 
idea there.

I saw many and various configurations files using org, (from where I took some 
inspiration when I first started), but I did not came across the approach I am 
presenting below.  I am sure it will interest many people already using org to 
configure emacs (and maybe others to jump into org and try it).



What I had before:
------------------

* package1
    #+begin_src emacs-lisp
       (use-package package1 ...)
    #+end_src
* package2
    #+begin_src emacs-lisp
       (use-package package2 ...)
    #+end_src




What I have after:
------------------

#+TAGS: [ group1 : tag1 tag2 tag3 tag4 tag5 ]
#+TAGS: [ group2 : tag6 tag7 tag8 tag9 ]

               filters
              ---------
group1 : tag1 tag2 tag3 tag4 tag5
group2 : tag6 tag7 tag8 tag9


* package1         :tag1:tag2:
   ** option1               :tag3:tag4:tag5:
      - [ ] choice1
      - [X] choice2
      - [ ] choice3
   ** option2               :tag4:tag5:tag6:
   ** option3               :tag5:tag6:tag7:
   ** install  
   ** load/enable feature
   ** keymap/keybinding
* package2
   same here.





So what I did, is that, I removed almost all (use-package) declarations.  Some 
of the main advantages are :

- allow tagging options individually, and easily find them later.

- allow adding org comments for each option separatly, (and even sometimes for 
a given choice).

- easily reference (via org links) other options individually, from within org 
comments.

- Also IMO, for new users for example, it is easier to read and understand this 
org configuration, than to see a (use-package) declaration.  It is true that 
org comments will help, but also new users won’t have an additional step to 
learn use-package.

- it introduces new users directly to Emacs Lisp functions, like hook 
functions, etc, which make it easier for them to learn Emacs Lisp, and also to 
easily hack things to their preferences.

- this also allows sharing more granular code snippets (as needed), instead of 
having to copy a whole (use-package) declaration, and sometimes without really 
understanding what the declaration (or a part of it) is supposed to do, and how 
someone is supposed to tweak it, without breaking anything (and without having 
to learn use-package, as a prerequisite).



This is not a with/against use-package discussion at all (please don’t divert 
from the main idea).  The main reason I removed use-package is to be able to 
_tag options individually, to easily find them later_ , (for this, I wanted 
each org code-block to be totally independent from all others code-blocks).  
This is the fundamental idea behind this new literate config approach (besides 
the other advantages it provides, which are numerous)





I will explain briefly each part :


Filters:
--------
These are org links (ex. [[mytagfilter:tag1][tag1]]).  Clicking on tag1 for 
example, will show only options tagged as “tag1” (and at the same time, will 
hide other irrelevant tags that makes no sense to select anymore).  It is a 
known filter mechanism, and is not specific to this approach. (I hope if org 
maintainers and/or contributors can implement this in org, because I find it 
useful in all my org files.  I think many would find it useful too.)




Install:
--------
Is how to install the package.  This is still work in progress, but this is how 
I imagine it :


** install
  - [ ] immediately
      call package functions directly.
  - [ ] at the end of the init
      append the package name in a variable and install the packages at the end.
  - [ ] etc
      other installation methods.

Maybe use-package or others can be (temporary) used here, if someone wants to 
(for its installation part).  Use-package can still be used, anywhere someone 
find it useful, it is not mandatory to completely remove use-package (but only 
for a single purpose).  Emacs is hackable after all, and everyone can use 
whatever they want.


       

Options:
--------

** option
   - [ ] choice1 (default)
         The default value should not be tangled into the init file.
          #+begin_src emacs-lisp
              (setopt option defaultvalue)
          #+end_src
   - [ ] choice2
          #+begin_src emacs-lisp
              (setopt option value2)
          #+end_src
   - [ ] choice3
          #+begin_src emacs-lisp
              Sometimes user needs to write complex regex.
          #+end_src
   - [X] choice4
          #+begin_src emacs-lisp
              Sometimes user needs to add/remove hooks.
              Sometimes user needs to do that for specific mode(s).
          #+end_src
   - [ ] choice5
          #+begin_src emacs-lisp
              Sometimes user needs to write a complex functions.
          #+end_src
   - [ ] etc


Some may say it is sometimes difficult to divide some options into more 
granular choices that can be checked/selected individually, (ex. when the 
option is a hook, list, etc.), but I managed to do so successfully for the 
moment.  (Maybe because my setup is not too complicated ?).  If someone can 
think of, or find in their config, an option that cannot be divided into 
comprehensive choices like above, we can maybe discuss it, but I think there 
should be a way to do that, even if sometimes there is little bit of 
overlapping (not mutually exclusive choices).




load/enable feature:
--------------------
This is to load/enable a package/feature.  Example :


* which-key
** load/enable feature
  - [ ] disable (default)
    [ ] enable immediately
         #+begin_src emacs-lisp
            (which-key-mode)
         #+end_src
  - [X] enabled after emacs idle delay
         #+begin_src emacs-lisp
            (run-with-idle-timer 2 nil #'which-key-mode t)
          #+end_src
  - [ ] enabled immediately after feature1 is loaded
         #+begin_src emacs-lisp
            (eval-after-load 'feature1
               '(which-key-mode))
         #+end_src
  - [ ] enable manually (autoload when which-key-mode is called)
         [ This is just an example. which-key-mode is already autoloaded ]
         #+begin_src emacs-lisp
            (unless
               (fboundp 'which-key-mode)
             (autoload #'which-key-mode "which-key" nil t))
         #+end_src
  - [ ] etc


These are also general choices examples, no need to add them all for every 
package, only when it make sense.  (I usually tend to defer loading features, 
in a way or other, so emacs starts faster).




I wish I could share my org config file, but it is still work in progress, and 
I also need to do a lot of cleanups before having something shareable, and I 
don’t really have time to do so.

So I preferred at least, to share the idea with you all, so you can explore it 
from now, and convert your config, if you find it useful.  Also for people who 
wants to jump into org literate config and haven’t done so yet, maybe they can 
consider this approach from the very start.




Also, if someone have time, and can start a project including an org file, and 
begin with few packages, then we can start sharing our code snippets (specially 
for complex configurations), so we can have a central configuration for 
everyone to use (new/non-new users), while being able to pick and choose the 
needed package(s), and how to install them, and also to easily tweak 
everything, with many choices to select from.

We can also add buttons/links (for new users) to select a given choice, and to 
save/tangle the modifications into the init file. (I am adding/removing 
“tangle” header arguments, and calling ‘org-babel-tangle’ manually for the 
moment.  Not complicated after all).  The org file can also be enhanced in many 
other ways.

If we want to also tag and/or reference individual option’s choices, (which I 
find very useful in many cases), we should use org headings instead of org 
lists.

There is not need to argue which archive, package or option to include/exclude, 
etc.  We can include literally everything.  Anyone can send his favorite 
package(s), option(s), and even individual choice(s), and also the favorite 
method to install a package, etc.

A problem I can see, is when we will have a lot of packages.  So maybe then we 
can separate each package into his own org file, while having a single main org 
file containing the tags/filters.  The tag filtering should be made to work 
just like it works today for org agenda files.  If org experts can give us some 
advice on if it is something reasonable to do, and what is the best approach.

Another thing, is how we can implement a way to keep someone’s local config org 
file(s) synced with the central config org file(s)’s modifications, without 
loosing local customizations.  (Maybe we can assign an org id to each choice).

There may be other things to take into account too.  But we should not consider 
anything as blocking.  Because having a central place where we can share all 
our config efficiently, is already a good thing in itself, and outweigh any 
other secondary inconvenience.



So if someone has time to do so, I think it is a very good idea, instead of 
every person struggling on his own through the exact same difficulties, and 
spending the same amount of time and energy in building their individual 
configuration file over the years, and without having a way to share them 
efficiently, so everyone can benefits from each other valuable work.

If an org file like this can exist, I think the “emacs is difficult to start 
with” will be from the past, and the same can be said for “maintaining one’s 
init file over time”.  If I could find an org file like this when I first 
started, it would have spared me an enormous amount of work and research, and I 
think this would be the same for others.

Although there are a lot of org literate config everywhere, (and non-literate 
too), they almost all use use-package declarations, which _as a new user_ , I 
found difficult to understand and tweak, unless I learn use-package and some 
Emacs Lisp before-hand.

With this approach, all you have to learn is org markup (not really after all, 
it is just a normal text file).  You open emacs, then you open this org file, 
then you read a 2min quick intro about how to use it, and you are ready to go :
- you can directly customize emacs (even with very advanced customizations)
- you gradually learn Emacs Lisp, by looking at the code-blocks from time to 
time.
- you can even change some customizations, by copying code-blocks and modifying 
them as needed, when you have enough Emacs Lisp knowledge.



I tried to keep the presentation as short as possible, while still being clear 
enough.  If there is something unclear or important but missing, let me know.


Thanks in advance,



[1] https://lists.gnu.org/archive/html/emacs-devel/2024-12/msg00344.html



[ I am not sure which mailing list is the appropriate one. ]


[ Maybe this can be a step before implementing option’s tagging and filtering 
natively into Emacs. ]


Reply via email to