#+title: Emacs Configuration
#+setupfile: headers
#+OPTIONS: auto-id:t
#+HTML_HEAD_EXTRA: <meta name="description" content="Phundrak’s Spacemacs Configuration" />
#+HTML_HEAD_EXTRA: <meta property="og:title" content="Phundrak’s Spacemacs Configuration" />
#+HTML_HEAD_EXTRA: <meta property="og:description" content="Description of the Spacemacs configuration of Phundrak" />
#+PROPERTY: header-args: :mkdirp yes

* Introduction
  :PROPERTIES:
  :CUSTOM_ID: Introduction-f1cbb8bb
  :END:
  This file  is the main source  file for my Emacs  configuration which contains
  most of the user code. It is  exported thanks to Emacs’ code tangling from the
  original Org file  which you can find on my  dotfiles’ repository[fn:1] if you
  are  reading   the  web   version  of   it.  You  can   also  find   there  my
  ~.spacemacs~[fn:2] and its  code which isn’t part of the  present file. As you
  can  see in  my  ~.spacemacs~,  at init-time,  if  Emacs  detects the  tangled
  configuration  files are  older than  the Org  file, then  Emacs tangles  them
  again, and then loads them.

* Spacemacs layers and packages
  :PROPERTIES:
  :header-args:emacs-lisp: :mkdir yes :tangle ~/.config/emacs/private/spacemacs-layers.el :exports code :results silent
  :CUSTOM_ID: Spacemacs_layers_and_packages-6d318b87
  :END:
  Here  will be  our layer  configuration  set. Everything  here is  set with  a
  ~setq-default~ in the ~dotspacemacs/layers~ function like so:
  #+BEGIN_SRC emacs-lisp :tangle no
    (defun dotspacemacs/layers ()
      (setq-default
       ;; configuration goes here
       ))
  #+END_SRC

** General configuration
   :PROPERTIES:
   :CUSTOM_ID: Spacemacs_layers_and_packages-General_configuration-66b4311e
   :END:
   First, we need  to tell Spacemacs which base distribution  we are using. This
   is a  layer contained  in the directory  ~+distribution~. For  now, available
   distributions are ~spacemacs-base~ and ~spacemacs~ (the default one).
   #+BEGIN_SRC emacs-lisp
     (setq-default dotspacemacs-distribution 'spacemacs)
   #+END_SRC

   We can  seet a lazy  installation of layers  —i.e. layers are  installed only
   when a file with a supported type is opened. Possible values are:
   - ~all~ ::  will lazy install any  layer that support lazy  installation even
              the layers listed in ~dotspacemacs-configuration-layers~
   - ~unused~ :: will lazy install only unused layers (i.e. layers not listed in
                 the variable ~dotspacemacs-configuration-layers~)
   - ~nil~ :: disables the lazy installation  feature and you have to explicitly
              list a  layer in the  variable ~dotspacemacs-configuration-layers~
              to install it.
   The default value is ~unused~.
   #+BEGIN_SRC emacs-lisp
     (setq-default dotspacemacs-enable-lazy-installation 'unused)
   #+END_SRC

   If the  following variable  is non-nil, Spacemacs  will ask  for confirmation
   before installing a layer lazily. The default value is ~t~.
   #+BEGIN_SRC emacs-lisp
     (setq-default dotspacemacs-ask-for-lazy-installation t)
   #+END_SRC

** Package management
   :PROPERTIES:
   :CUSTOM_ID: Spacemacs_layers_and_packages-Package_management-0add1a62
   :END:
   It is possible to  indicate to Spacemacs a list of  additional paths where to
   look  for  configuration layers.  Paths  must  have  a trailing  slash,  i.e.
   =~/.mycontribs/=. As you can see, I added none:
   #+BEGIN_SRC emacs-lisp
   (setq-default dotspacemacs-configuration-layer-path '())
   #+END_SRC

   However, I  do have additional packages  I installed either from  the Elpa or
   the Melpa.  These are  set in  ~dotspacemacs-additional-packages~, a  list of
   additional packages that will be installed  without being wrapped in a layer.
   If you need  some configuration for these packages, then  consider creating a
   layer. You can also puth  the configuration in ~dotspacemacs/user-config~. To
   use a local version of a package, use the ~:location~ property, for instance:
   #+BEGIN_SRC emacs-lisp :tangle no
     '(your-package :location "~/path/to/your-package/")
   #+END_SRC

   With  the  variable  ~dotspacemacs-additional-packages~, it  is  possible  to
   install  extra  packages  which  are  not already  included  in  any  layers.
   Dependencies  should  be  explicitly  included  as  they  won’t  be  resolved
   automatically. Here is a table of all the extra packages I use:
   #+NAME: extra-packages
   | name of the package | why is it installed                                  |
   |---------------------+------------------------------------------------------|
   | caddyfile-mode      | Major mode for editing Caddyfiles                    |
   | dired-du            | alternative to ~ncdu~ with Dired                     |
   | doom-themes         | some cool themes                                     |
   | edit-indirect       | edit region in separate buffer                       |
   | elcord              | rich integration of Emacs in Discord                 |
   | helm-icons          | integration between helm and treemacs icons          |
   | kaolin-themes       | some cool themes                                     |
   | lsp-dart            | apparently, it isn’t included in the Dart layer      |
   | magit-gitflow       | integrate gitflow in Magit                           |
   | multiple-cursors    | I don’t like the layer, I prefer this package alone  |
   | org-sidebar         | display on the side the outline of an Org buffer     |
   | org-tree-slide      | presentation tool for org-mode                       |
   | outorg              | edit comments as Org-mode buffers                    |
   | pinentry            | enter a GPG password from Emacs                      |
   | s                   | The long lost Emacs string manipulation library.     |
   | visual-fill-column  | allow the use of ~fill-column~ in ~visual-line-mode~ |
   | wrap-region         | easily wrap region with delimiters                   |
   | wttrin              | weather in Emacs                                     |
   | yasnippet-snippets  | snippets for YaSnippet                               |

   #+NAME: make-extra-packages
   #+BEGIN_SRC emacs-lisp :tangle no :var packages=extra-packages[,0] :exports none
     (mapcar 'make-symbol packages)
   #+END_SRC

   #+BEGIN_SRC emacs-lisp :noweb yes :exports none
     (setq-default dotspacemacs-additional-packages (quote <<make-extra-packages()>>))
   #+END_SRC

   It is possible to also list packages that cannot be updated:
   #+BEGIN_SRC emacs-lisp
     (setq-default dotspacemacs-frozen-packages '(helm-icons))
   #+END_SRC

   And to list packages which won’t be installed nor loaded:
   #+BEGIN_SRC emacs-lisp
   (setq-default dotspacemacs-excluded-packages '(company-tern))
   #+END_SRC

   Finally, it is possible to define  the behaviour of Spacemacs when installing
   packages. Possible values are:
   - ~used-only~  :: installs  only  explicitly used  packages  and deletes  any
                    unused packages as well as their unused dependencies
   - ~used-but-keep-unused~ :: installs only the  used packages but won’t delete
        unused ones
   - ~all~  ::  installs  *all*  packages   supported  by  Spacemacs  and  never
              uninstalls them.
   The default value is ~used-only~.
   #+BEGIN_SRC emacs-lisp
   (setq-default dotspacemacs-install-packages 'used-only)
   #+END_SRC

** Layers
   :PROPERTIES:
   :CUSTOM_ID: Spacemacs_layers_and_packages-Layers-36e1c90c
   :END:
   All layers are set one variable: ~dotspacemacs-configuration-layers~. This
   variable is a list of layers, some of them will have some custom variables.
   Typically, the variable will be set like so:
   #+BEGIN_SRC emacs-lisp :tangle no
     (setq-default dotspacemacs-configuration-layers
                   '(emacs-lisp
                     helm
                     multiple-cursors
                     org
                     (shell :variables shell-default-height
                            30 shell-default-position 'bottom)
                     treemacs))
   #+END_SRC

# Don’t delete this code block, it wraps the layers
#+BEGIN_SRC emacs-lisp :exports none
(setq-default dotspacemacs-configuration-layers '(
#+END_SRC

*** Checkers
    :PROPERTIES:
    :CUSTOM_ID: Spacemacs_layers_and_packages-Layers-Checkers-aefeae26
    :END:
    The  two  first   checkers  I  use  are  for  spell   and  syntax  checking.
    ~spell-checking~ is disabled  by default, however it  should auto-detect the
    dictionary to use.
    #+BEGIN_SRC emacs-lisp
      (spell-checking :variables
                      spell-checking-enable-by-default nil
                      spell-checking-enable-auto-dictionary t)
      syntax-checking
    #+END_SRC

*** Completion
    :PROPERTIES:
    :CUSTOM_ID: Spacemacs_layers_and_packages-Layers-Completion-883e2b83
    :END:
    ~auto-completion~ is a layer enabled  in order to provide auto-completion to
    all  supported language  layers. It  is set  so that  the =RET=  key has  no
    behavior with  this layer, however  the =TAB= key cycles  between candidates
    displayed by the auto-completion toolbox.  I also want the autocompletion to
    include snippets  in the popup,  and the content of  the popup is  sorted by
    usage. It is also disabled for two modes: magit and Org.
    #+BEGIN_SRC emacs-lisp
      (auto-completion :variables
                    auto-completion-complete-with-key-sequence-delay 0.2
                    auto-completion-enable-help-tooltip 'manual
                    auto-completion-enable-sort-by-usage t
                    :disabled-for
                    org
                    git)
    #+END_SRC

    ~helm~ is also enabled, with its header disabled.
    #+BEGIN_SRC emacs-lisp
      (helm :variables helm-no-header t)
    #+END_SRC

*** Email
    :PROPERTIES:
    :CUSTOM_ID: Spacemacs_layers_and_packages-Layers-Email-67c16308
    :END:
    I use  as my daily Email  client ~mu4e~, so  let’s enable it and  tell Emacs
    where mu4e  is installed. I also  tell mu4e to use  maildirs extensions, use
    async operations, where to keep attachments, and enable the mu4e modeline.
    #+BEGIN_SRC emacs-lisp
      (mu4e :variables
            mu4e-installation-path "/usr/share/emacs/site-lisp"
            mu4e-use-maildirs-extension t
            mu4e-enable-mode-line t
            mu4e-attachment-dir "~/Documents")
    #+END_SRC

*** Emacs
    :PROPERTIES:
    :CUSTOM_ID: Spacemacs_layers_and_packages-Layers-Emacs-8e976e5c
    :END:
    The first layer  enabled in this category is ~better-defaults~.  I also made
    it so  that when  a command  equivalent to  ~C-a~ or  ~C-e~ is  pressed, the
    cursor will  respectively first move to  the beginning of code  first before
    going past the  indentation and to the  end of the code before  going to the
    end of the line before going over the end of the comments on the same line.
    #+BEGIN_SRC emacs-lisp
      (better-defaults :variables
                       better-defaults-move-to-beginning-of-code-first t
                       better-defaults-move-to-end-of-code-first t)
    #+END_SRC

    I also enabled ~ibuffer~ and made it so that buffers are sorted by projects.
    #+BEGIN_SRC emacs-lisp
      (ibuffer :variables
               ibuffer-group-buffers-by 'projects)
    #+END_SRC

    Most important  of all, the ~org~  layer is also enabled.  I enabled support
    for Epub  exports, Github,  Reveal.JS exports,  and sticky  headers. Project
    support is  also enabled  through files  named ~TODOs.org~.  I also  set the
    org-download folder for images in =~/Pictures/org/=, and I set the =RET= key
    to follow org links if the cursor is on one.
    #+BEGIN_SRC emacs-lisp
       (org :variables
            org-enable-epub-support t
            org-enable-github-support t
            org-enable-hugo-support t
            org-enable-reveal-js-support t
            org-enable-sticky-header t
            spaceline-org-clock-p t
            org-projectile-file "TODOs.org"
            org-download-image-dir "~/Pictures/org/"
            org-return-follows-link t)
    #+END_SRC

    The ~semantic~ layer is also enabled.
    #+BEGIN_SRC emacs-lisp
      semantic
    #+END_SRC

*** File trees
    :PROPERTIES:
    :CUSTOM_ID: Spacemacs_layers_and_packages-Layers-File_trees-5b6ed3e4
    :END:
    In this category, I only enabled one layer: ~treemacs~. In this layer, I set
    is  so that  treemacs syncs  with my  current buffer,  and it  automatically
    refreshes its buffer when  there is a change in the part  of the file system
    shown by treemacs.
    #+BEGIN_SRC emacs-lisp
      (treemacs :variables
                treemacs-use-follow-mode t
                treemacs-use-filewatch-mode t)
    #+END_SRC

*** Fonts
    :PROPERTIES:
    :CUSTOM_ID: Spacemacs_layers_and_packages-Layers-Fonts-11de8977
    :END:
    In this category,  again, one layer is enabled:  ~unicode-fonts~. This layer
    addssupport for the ~unicode-fonts~ package.
    #+BEGIN_SRC emacs-lisp
    unicode-fonts
    #+END_SRC

*** Fun
    :PROPERTIES:
    :CUSTOM_ID: Spacemacs_layers_and_packages-Layers-Fun-0728c04c
    :END:
    In this category, I only enabled two layers: ~selectric~ and ~xkcd~.
    #+BEGIN_SRC emacs-lisp
    selectric xkcd
    #+END_SRC

*** Internationalization
    :PROPERTIES:
    :CUSTOM_ID: Spacemacs_layers_and_packages-Layers-Internationalization-69601ff8
    :END:
    In  this  category,   I  enabled  the  ~keyboard-layout~   layer  to  enable
    compatibility with  the bépo  layout. This layer,  however, is  disabled for
    magit, Dired and eww.
    #+BEGIN_SRC emacs-lisp
      (keyboard-layout :variables
                       kl-layout 'bepo
                       kl-disabled-configurations '(magit dired eww))
    #+END_SRC

*** Programming languages
    :PROPERTIES:
    :CUSTOM_ID: Spacemacs_layers_and_packages-Layers-Programming_languages-4c318b81
    :END:
**** Domain-specific (DSLs)
     :PROPERTIES:
     :CUSTOM_ID: Spacemacs_layers_and_packages-Layers-Programming_languages-Domain-specific_(DSLs)-2c919937
     :END:
     In this  category, I enabled  support for  the R programming  language (the
     ~ess~ layer), the ~major-modes~ layer for the Arch Linux PKGBUILDs support,
     the ~prolog~, ~emacs-lisp~ and ~scheme~  layers, support for the CSV format
     with the  ~csv~ layer, the  ~yaml~ language, shell scripting  languages and
     support for the ~dot~ tool with the ~graphviz~ layer.
     #+BEGIN_SRC emacs-lisp
       ess major-modes prolog emacs-lisp scheme graphviz yaml shell-scripts
     #+END_SRC

     I also added support  for HTML and CSS with the ~html~  layer, with the web
     formatting  tool set  to ~web-beautify~,  and the  LSP layer  compatibility
     enabled for CSS, less, SCSS and HTML.
     #+BEGIN_SRC emacs-lisp
      (html :variables
            web-fmt-tool 'web-beautify
            css-enable-lsp t
            less-enable-lsp t
            scss-enable-lsp t
            html-enable-lsp t)
     #+END_SRC

     The  ~json~   layer  is  also  enabled,   with  the  format  tool   set  to
     ~web-beautify~.
     #+BEGIN_SRC emacs-lisp
      (json :variables
            json-fmt-tool 'web-beautify)
     #+END_SRC

     The LaTeX  layer has also  been enabled, with  its default compiler  set to
     XeLaTeX. I also enabled the auto-fill feature, the folding capacity and the
     “magic” symbols.
     #+BEGIN_SRC emacs-lisp
      (latex :variables
             latex-build-command "xelatex"
             latex-enable-auto-fill t
             latex-enable-folding t
             latex-enable-magic t)
     #+END_SRC

     The Markdown  layer has been  enabled, with  support for live  preview with
     ~vmd~, and and  automatic MMM-mode generation for C, C++,  Python, Rust and
     Emacs Lisp.
     #+BEGIN_SRC emacs-lisp
      (markdown :variables
                markdown-live-preview-engine 'vmd
                markdown-mmm-auto-modes '("c"
                                          "c++"
                                          "python"
                                          "rust"
                                          ("elisp" "emacs-lisp")))
     #+END_SRC

     #+BEGIN_SRC emacs-lisp
       (bibtex :variables
               org-ref-default-bibliography '("~/Documents/Papers/references.bib")
               org-ref-pdf-directory "~/Documents/Papers"
               org-ref-bibliography-notes "~/Documents/Papers/notes.org")
     #+END_SRC

     #+BEGIN_SRC emacs-lisp
       csv
     #+END_SRC

**** Frameworks
     :PROPERTIES:
     :CUSTOM_ID: Spacemacs_layers_and_packages-Layers-Programming_languages-Frameworks-f7c21585
     :END:
     Only one  framework support  has been  enabled so  far, and  is is  for the
     Django framework.
     #+BEGIN_SRC emacs-lisp
       django
     #+END_SRC

**** General-purpose
     :PROPERTIES:
     :CUSTOM_ID: Spacemacs_layers_and_packages-Layers-Programming_languages-General-purpose-1ed71a5b
     :END:
     Among  the  layers   I  activated,  the  only  one   without  any  specific
     configuration is the ~asm~ layer for the Assembly language.
     #+BEGIN_SRC emacs-lisp
       asm
     #+END_SRC

     Next, you can find the C/C++ layer for which I set the default language for
     ~.h~ files to be C. I also enabled support for subprojects and organization
     of  the  include  directives on  a  file  save.  I  also set  a  couple  of
     LSP-related variables,  such as the LSP  executable for C/C++ for  its CCLS
     backend and some highlight variables.
     #+BEGIN_SRC emacs-lisp
       (c-c++ :variables
              c-c++-default-mode-for-headers 'c-mode
              c-c++-adopt-subprojects t
              c-c++-enable-c++11 t
              c-c++-backend 'lsp-clangd
              c-c++-lsp-enable-semantic-highlight t
              c-c++-lsp-semantic-highlight-method 'overlay
              c-c++-lsp-semantic-highlight-rainbow t
              c++-enable-organize-includes-on-save t)
     #+END_SRC

     Dart has  also been  enabled, with  a custom path  to the  SDK of  the Dart
     server, and to the LSP server of Dart.
     #+BEGIN_SRC emacs-lisp
       (dart :variables
             lsp-dart-project-sdk-dir "/opt/dart-sdk/"
             lsp-dart-sdk-dir "/opt/dart-sdk/")
     #+END_SRC

     When it comes  to the Python layer,  I set its backend and  formatter to be
     bound to  the LSP layer.  Its fill columnn was  also set to  80 characters,
     imports are sorted on  save, and the tests can be  run using either nose.el
     or pytest.
     #+BEGIN_SRC emacs-lisp
       (python :variables
               python-backend 'lsp
               python-sort-imports-on-save t
               python-fill-column 80
               python-test-runner '(pytest nose)
               python-formatter 'lsp)
     #+END_SRC

     With the Rust layer, the only custom configuration set is the backend being
     bound to the LSP layer.
     #+BEGIN_SRC emacs-lisp
       (rust :variables rust-backend 'lsp)
     #+END_SRC

     As regards the  JavaScript layer, I set  its backend to the  LSP layer, and
     bound its  format tool to ~web-beautify~  and its REPL is  browser-based. I
     also want to  include ~node_modules/.bin~ to be automatically  added to the
     buffer local ~exec_path~.
     #+BEGIN_SRC emacs-lisp
       (javascript :variables
                   javascript-backend 'lsp
                   javascript-fmt-tool 'web-beautify
                   javascript-repl 'skewer
                   node-add-modules-path t)
     #+END_SRC

     Alternatively, I also  use Typescript which is a sort  of better Javascript
     as it should have been, with the LSP backend.
     #+BEGIN_SRC emacs-lisp
       (typescript :variables
                   typescript-backend 'lsp)
     #+END_SRC

     I am also currently using the Awesome window manager which requires the Lua
     programming language, so here it is.
     #+BEGIN_SRC emacs-lisp
       (lua :variables
            lua-backend 'lsp-emmy
            lua-lsp-emmy-jar-path "~/.config/awesome/EmmyLua-LS-all.jar"
            lua-lsp-emmy-java-path "java"
            lua-lsp-emmy-enable-file-watchers t)
     #+END_SRC

     But that won’t stop me trying to use other window managers. I am currently
     testing StumpWM, which requires the Common Lisp layer.
     #+BEGIN_SRC emacs-lisp
       common-lisp
     #+END_SRC

*** Readers
    :PROPERTIES:
    :CUSTOM_ID: Spacemacs_layers_and_packages-Layers-Readers-65e8e4ae
    :END:
**** Epub and Pdf readers
     :PROPERTIES:
     :CUSTOM_ID: Spacemacs_layers_and_packages-Layers-Readers-Epub_and_Pdf_readers-0ef6688f
     :END:
     In this category, only the ~epub~  and ~pdf~ layers are enabled without any
     special configuration, so I can read these files from Emacs directly.
     #+BEGIN_SRC emacs-lisp
     epub pdf
     #+END_SRC

**** Elfeed
     :PROPERTIES:
     :CUSTOM_ID: Spacemacs_layers_and_packages-Layers-Readers-Elfeed-78877179
     :END:
     Elfeed is an  Emacs feeed and RSS  reader which can be  managed through org
     files. Actually,  through only one file  in my case, located  in my =~/org=
     directory.
     #+BEGIN_SRC emacs-lisp
       (elfeed :variables
               rmh-elfeed-org-files '("~/org/elfeed.org"))
     #+END_SRC

*** Version control
    :PROPERTIES:
    :CUSTOM_ID: Spacemacs_layers_and_packages-Layers-Version_control-bc8e286a
    :END:
    Only the ~git~ layer is enabled in this category.
    #+BEGIN_SRC emacs-lisp
    git
    #+END_SRC

*** Themes
    :PROPERTIES:
    :CUSTOM_ID: Spacemacs_layers_and_packages-Layers-Themes-d88d1225
    :END:
    Here, the ~colors~  layer is the only one enabled.  It activates support for
    identifiers colorization, and strings representing colors.
    #+BEGIN_SRC emacs-lisp
      colors
    #+END_SRC

*** Tools
    :PROPERTIES:
    :CUSTOM_ID: Spacemacs_layers_and_packages-Layers-Tools-e57e405e
    :END:
    In this category, the first layer to be enabled is the CMake layer for which
    I enabled support for the ~cmake-ide~ package.
    #+BEGIN_SRC emacs-lisp
      (cmake :variables
             cmake-enable-cmake-ide-support t)
    #+END_SRC

    Next, we have the Docker, Nginx,  Pass (the standard Unix password manager),
    Prettier, Systemd,  Meson, Imenu-list,  Web-beautify, Dap, Helpful,  and LSP
    layers enabled.
    #+BEGIN_SRC emacs-lisp
      dap docker helpful imenu-list lsp meson nginx pass prettier systemd
      web-beautify
    #+END_SRC

    We  also have  the RestClient  layer  enabled for  which I  enabled the  Org
    compatibility support.
    #+BEGIN_SRC emacs-lisp
      (restclient :variables
                  restclient-use-org t)
    #+END_SRC

    And finally, we also have the Shell  layer for which I specified its default
    height when spawning  at the bottom of  the screen should be  40 lines high,
    and the default shell to invoke is Eshell.
    #+BEGIN_SRC emacs-lisp
      (shell :variables
             shell-default-height 40
             shell-default-position 'bottom
             shell-default-shell 'eshell)
    #+END_SRC

*** Web Services
    :PROPERTIES:
    :CUSTOM_ID: Spacemacs_layers_and_packages-Layers-Web_Services-c2888251
    :END:
    In this category, I have only enabled a layer for Twitter support.
    #+BEGIN_SRC emacs-lisp
    twitter
    #+END_SRC

*** Custom layers
    :PROPERTIES:
    :CUSTOM_ID: Spacemacs_layers_and_packages-Layers-Custom_layers-69473533
    :END:
    Lastly, three custom  layers have been enabled:  a w3m layer, and  two of my
    custom layers for Dired and for conlanging tools.
    #+BEGIN_SRC emacs-lisp
    conlanging dired-phundrak w3m
    #+END_SRC

# Don’t delete this code block, it wraps the layers
#+BEGIN_SRC emacs-lisp :exports none
))
#+END_SRC

* Init
  :PROPERTIES:
  :header-args:emacs-lisp: :mkdir yes :tangle ~/.config/emacs/private/spacemacs-init.el :exports code :results silent
  :CUSTOM_ID: Init-99a4b561
  :END:
  The ~dotspacemacs/init~ function is the one called at the very begining of the
  Spacemacs  startup, before  any  kind of  configuration,  including the  layer
  configuration. Only  the values of  the Spacemacs settings should  be modified
  here. By  default, every  values are  set in a  ~setq-default~ sexp,  and they
  represent all the supported Spacemacs settings. Hence, the function looks like
  this:
  #+BEGIN_SRC emacs-lisp :tangle no
    (defun dotspacemacs/init ()
      (setq-default
       ;; default Spacemacs configuration here
       ))
  #+END_SRC

** Emacs with pdumper
   :PROPERTIES:
   :CUSTOM_ID: Init-Emacs_with_pdumper-f24ab30b
   :END:
   It is possible to compile Emacs 27  from source with support for the portable
   dumper, as  shown in Spacemacs’  =EXPERIMENTAL.org= file.  I do not  use this
   feature  yet,  as  I  am  still  on  Emacs  26  provided  from  Arch  Linux’s
   repositories, so  I’ll disable  the Spacemacs support  for this  feature. The
   default value of this variable is =nil=.
   #+BEGIN_SRC emacs-lisp
     (setq-default dotspacemacs-enable-emacs-pdumper t)
   #+END_SRC

   In case the support for pdumper was enabled, Spacemacs needs to know the name
   of the Emacs executable which supports such a feature. The executable must be
   in the user’s =PATH=. By default, the value of the variable is ="emacs"=.
   #+BEGIN_SRC emacs-lisp
     (setq-default dotspacemacs-emacs-pdumper-executable-file "emacs")
   #+END_SRC

   And finally, we can name the Spacemacs  dump file. This is the file that will
   be created  by the portable dumper  in the cache directory  under the =dumps=
   sub-directory. To  load it when  starting Emacs, the  parameter =--dump-file=
   should be  added when invoking Emacs  27.1 executable from the  command line,
   for instance:
   #+BEGIN_SRC sh :tangle no :exports code
     ./emacs --dump-file=~/.config/emacs/.cache/dumps/spacemacs.pdmp
   #+END_SRC

   The default value of this variable is ="spacemacs.pdmp"=.
   #+BEGIN_SRC emacs-lisp
     (setq-default dotspacemacs-emacs-dumper-dump-file "spacemacs.pdmp")
   #+END_SRC

** Package managment and updates
   :PROPERTIES:
   :CUSTOM_ID: Init-Package_managment_and_updates-79363da3
   :END:
   Spacemacs’ core  configuration can be  updated via git commands  using Github
   services. If Spacemacs  is not set to  the =develop= branch, it  can check by
   itself if any update is available. However, I am using said branch, therefore
   I should set this variable to =nil=. The default value is =nil=.
   #+BEGIN_SRC emacs-lisp
     (setq-default dotspacemacs-check-for-update nil)
   #+END_SRC

   When  it comes  to package  management, Spacemacs  is able  to store  them in
   different directories  depending on  the version  of Emacs  used or  based on
   other variables. I  personally prefer to use the  value =emacs-version= since
   it makes  it easier to upgrade  or downgrade Emacs without  any conflict with
   the already installed packages. The default value is =emacs-version=.
   #+BEGIN_SRC emacs-lisp
     (setq-default dotspacemacs-elpa-subdirectory 'emacs-version)
   #+END_SRC

   Spacemacs has  a capacity of performing  rollbacks after updates. We  can set
   the maximum number of rollback slots to  keep in the cache. The default value
   is =5=.
   #+BEGIN_SRC emacs-lisp
     (setq-default dotspacemacs-max-rollback-slots 5)
   #+END_SRC

*** Elpa repository
    :PROPERTIES:
    :CUSTOM_ID: Init-Package_managment_and_updates-Elpa_repository-c07fb1c4
    :END:
    It is possible to  ask Emacs to use an HTTPS  connection when contacting the
    Elpa whenever possible. This value should be  set to =nil= when the user has
    no  way  to  contact  the  Elpa  though  HTTPS,  otherwise  it  is  strongly
    recommended to  let it set  to =t=. This variable  however has no  effect if
    Emacs is launched with the parameter  =--insecure= which forces the value of
    this variable to =nil=. The default value is =t=.
    #+BEGIN_SRC emacs-lisp
    (setq-default dotspacemacs-elpa-https t)
    #+END_SRC

    We can  set a  maximum amount  of seconds which  will represent  the maximum
    allowed time to contact the Elpa repository. By default, this setting is set
    on =5=.
    #+BEGIN_SRC emacs-lisp
      (setq-default dotspacemacs-elpa-timeout 5)
    #+END_SRC

*** Spacelpa repository
    :PROPERTIES:
    :CUSTOM_ID: Init-Package_managment_and_updates-Spacelpa_repository-a431b288
    :END:
    The Spacelpa  repository is a  Spacemacs-specific package repository.  It is
    possible to use  it as the primary  source to install a locked  version of a
    package. If the below value is set to =nil=, then Spacemacs will install the
    latest version of packages  from MELPA. I personally don’t use  it, so I let
    it set to =nil=. The default value is =nil=.
    #+BEGIN_SRC emacs-lisp
    (setq-default dotspacemacs-use-spacelpa nil)
    #+END_SRC

    If  the below  value is  not =nil=,  then the  signature for  the downloaded
    Spacelpa packages must be verified.
    #+BEGIN_SRC emacs-lisp
      (setq-default dotspacemacs-verify-spacelpa-archives t)
    #+END_SRC

** Editing style
   :PROPERTIES:
   :CUSTOM_ID: Init-Editing_style-56d58a4b
   :END:
   By  default, Spacemacs  encourages the  use  of evil-mode,  which brings  vim
   keybinding in Emacs. Still, it has three different styles available:
   - =vim=, which goes full evil-mode usage and most adapted to Emacs newcomers,
     especially if they were  used to vim before, with the use  of a normal mode
     and an insert mode.
   - =emacs=  which keeps  an Emacs-like  feel to  the keybindings,  without any
     difference between an insert or normal mode.
   - =hybrid= is a modification of the =vim= mode which brings the =emacs= style
     in insert mode, but otherwise behaves  like the =vim= style in normal mode.
     This is the style I personally use.
   The  value can  also be  a  list with  the =:variables=  keyword (similar  to
   layers). Check the editing styles section of the documentation for details on
   available variables. The default value is =vim=.
   #+BEGIN_SRC emacs-lisp
     (setq-default dotspacemacs-editing-style '(hybrid :variables
                                                       hybrid-mode-enable-evilified-state t
                                                       hybrid-mode-default-state 'normal))
   #+END_SRC

   If non-nil,  the paste transient-state  is enabled. While enabled,  after you
   paste something,  pressing ~C-j~ and  ~C-k~ several times cycles  through the
   elements in the ~kill-ring~. Default ~nil~.
   #+BEGIN_SRC emacs-lisp
     (setq-default dotspacemacs-enable-paste-transient-state t)
   #+END_SRC

** Spacemacs home configuration
   :PROPERTIES:
   :CUSTOM_ID: Init-Spacemacs_home_configuration-8375cdcc
   :END:
   The value below specifies the startup  banner of Spacemacs. The default value
   is =official=, it  displays the official Spacemacs logo. An  integer value is
   the  index of  text banner,  =random=  chooses a  random text  banner in  the
   =core/banners= directory.  A string value must  be a path to  an image format
   supported  by your  Emacs build.  If  the value  is  nil, then  no banner  is
   displayed. The default value is =official=.
   #+BEGIN_SRC emacs-lisp
   (setq-default dotspacemacs-startup-banner 'official)
   #+END_SRC

   On the Spacemacs homepage, a list of elements can also be shown, be it recent
   files, projects, agenda items,… Each of the elements making up the list value
   of the below variable are pairs in the form =(list-type . list-size)=. If the
   value is =nil=, then it is disabled. The possible values for =list-type= are:
   - =recents= :: displays recently opened files
   - =bookmarks= :: displays saved bookmarks
   - =projects= :: displays projectile projects recently opened
   - =agenda= :: displays upcoming events from Org-mode agendas
   - =todos= :: displays recent TODOs detected in projectile projects
   The order in which they are set in  the below list affects their order on the
   Spacemacs   startup  page.   List  sikes   may  be   =nil=,  in   which  case
   =spacemacs-buffer-startup-lists-length= takes effect.
   #+BEGIN_SRC emacs-lisp
     (setq-default dotspacemacs-startup-lists '((recents . 15)
                                                (projects . 15)
                                                (agenda . 10)))
   #+END_SRC

   The below variable  allows the startup page to respond  to resize events. Its
   default value is =t=.
   #+BEGIN_SRC emacs-lisp
     (setq-default dotspacemacs-startup-buffer-responsive t)
   #+END_SRC

   If non-nil show the version string in the Spacemacs buffer. It will appear as
   ~(spacemacs version)@(emacs version)~. Default ~t~.
   #+BEGIN_SRC emacs-lisp
     (setq-default dotspacemacs-startup-buffer-show-version t)
   #+END_SRC

** Default major modes
   :PROPERTIES:
   :CUSTOM_ID: Init-Default_major_modes-37f4a891
   :END:
   The below variable sets a default major mode for a new empty buffer. Possible
   values are mode names such as  =text-mode=, or =nil= to use Fundamental mode.
   The default value is =text-mode=, but I prefer to use =org-mode= by default.
   #+BEGIN_SRC emacs-lisp
   (setq-default dotspacemacs-new-empty-buffer-major-mode 'org-mode)
   #+END_SRC

   Similarly, the below  variable sets the default mode for  the scratch buffer.
   Its default  value is  =text-mode=, but I  also set it  to use  =org-mode= by
   default.
   #+BEGIN_SRC emacs-lisp
   (setq-default dotspacemacs-scratch-mode 'org-mode)
   #+END_SRC

   By the way, it  is possible to set a default message  for the scratch buffer,
   such as “Welcome to Spacemacs!”. I prefer to keep it clean. The default value
   is =nil=.
   #+BEGIN_SRC emacs-lisp
   (setq-default dotspacemacs-initial-scratch-message nil)
   #+END_SRC

** Visual configuration
   :PROPERTIES:
   :CUSTOM_ID: Init-Visual_configuration-c4116cc1
   :END:
*** Themes
    :PROPERTIES:
    :CUSTOM_ID: Init-Visual_configuration-Themes-315992bb
    :END:
    Spacemacs makes  it quite easy  to use themes  and organize them.  The below
    value is a  list of themes, the  first of the list is  loaded when Spacemacs
    starts. The user can press =SPC T n= to cycle to the next theme in the list.
    #+BEGIN_SRC emacs-lisp
      (setq-default dotspacemacs-themes '(doom-nord doom-vibrant spacemacs-dark doom-one
                                                    doom-opera doom-dracula doom-molokai doom-peacock
                                                    doom-sourcerer doom-spacegrey kaolin-dark
                                                    kaolin-aurora kaolin-bubblegum kaolin-galaxy
                                                    kaolin-mono-dark kaolin-temple kaolin-valley-dark))
    #+END_SRC

    Emacs also makes use  of themes for the Spaceline at  the bottom of buffers.
    Supported themes are:
    - =spacemacs=
    - =all-the-icons=
    - =custom=
    - =doom= (the one I use)
    - =vim-powerline=
    - =vanilla=
    The first  three are Spaceline  themes. =doom= is the  Doom-Emacs mode-line,
    and =vanilla=  is the default  Emacs mode-line.  =custom= is a  user defined
    theme, refer to Spacemacs’ =DOCUMENTATION.org= file  for more info on how to
    create  your  own Spaceline  theme.  Value  can be  a  symbol  or list  with
    additional  properties. The  default value  is ='(spacemacs  :separator wave
    :separator-scale 1.5))=.
    #+BEGIN_SRC emacs-lisp
      (setq-default dotspacemacs-mode-line-theme '(doom
                                                   :separator wave
                                                   :separator-scale 1.0))
    #+END_SRC

    It is also possible to color the cursor depending on which mode Spacemacs is
    in, in order to mach the state color in GUI Emacs. The default value is =t=.
    #+BEGIN_SRC emacs-lisp
      (setq-default dotspacemacs-colorize-cursor-according-to-state t)
    #+END_SRC

    The below  variable sets either  the default font  or a prioritized  list of
    fonts to be used by Emacs.
    #+BEGIN_SRC emacs-lisp
      (setq-default dotspacemacs-default-font '("DejaVu Sans Mono for Powerline"
                                                :size 9.0))
    #+END_SRC

    I also added the following code in order to define a fallback font for
    emojis, defined only on their unicode range:
    #+BEGIN_SRC emacs-lisp
      (set-fontset-font "fontset-default" '(#x1f600 . #x1f64f) "NotoEmoji Nerd Font")
    #+END_SRC

*** Other on-screen elements
    :PROPERTIES:
    :CUSTOM_ID: Init-Visual_configuration-Other_on-screen_elements-7d334e09
    :END:
    =which-key= is  a helper which  displays available keyboard  shortcuts. This
    variable sets in seconds the time  Spacemacs should wait between a key press
    and the moment =which-key= should be shown.
    #+BEGIN_SRC emacs-lisp
      (setq-default dotspacemacs-which-key-delay 3)
    #+END_SRC

    This variable sets =which-key='s frame position. Possible values are:
    - =right=
    - =bottom=
    - =right-then-bottom=
    =right-then-bottom= tries to display the frame to the right, but if there is
    insufficient  space it  displays  it at  the bottom.  The  default value  is
    =bottom=.
    #+BEGIN_SRC emacs-lisp
      (setq-default dotspacemacs-which-key-position 'bottom)
    #+END_SRC

    This controls where =switch-to-buffer= displays  the buffer. If the value is
    =nil=, =switch-to-buffer= displays the buffer  in the current window even if
    another  same-purpose window  is available.  If non-nil,  ~switch-to-buffer~
    displays  the buffer  in a  same-purpose window  even if  the buffer  can be
    displayed in the current window. The default value is =nil=.
    #+BEGIN_SRC emacs-lisp
      (setq-default dotspacemacs-switch-to-buffer-prefers-purpose nil)
    #+END_SRC

    If this variable  is non-nil, a progress bar is  displayed when Spacemacs is
    loading. This may  increase the boot time on some  systems and emacs builds,
    set it to =nil= to boost the loading time. The default value is =t=.
    #+BEGIN_SRC emacs-lisp
      (setq-default dotspacemacs-loading-progress-bar t)
    #+END_SRC

    If the value is non-nil, Emacs will  show the title of the transient states.
    The default value is ~t~.
    #+BEGIN_SRC emacs-lisp
      (setq-default dotspacemacs-show-transient-state-title t)
    #+END_SRC

    If non-nil,  this will show the  color guide hint for  transient state keys.
    The default value is ~t~.
    #+BEGIN_SRC emacs-lisp
      (setq-default dotspacemacs-show-transient-state-color-guide t)
    #+END_SRC

    If non-nil, unicode symbols are displayed in the mode line. If you use Emacs
    as a daemon and want unicode characters  only in GUI set the value to quoted
    ~display-graphic-p~. The default value is ~t~.
    #+BEGIN_SRC emacs-lisp
      (setq-default dotspacemacs-mode-line-unicode-symbols t)
    #+END_SRC

    If non-nil, smooth scrolling (native-scrolling) is enabled. Smooth scrolling
    overrides  the default  behavior  of  Emacs which  recenters  point when  it
    reaches the top or bottom of the screen. The default value is ~t~.
    #+BEGIN_SRC emacs-lisp
      (setq-default dotspacemacs-smooth-scrolling t)
    #+END_SRC

    The following  value controls  the line  number activation.  If set  to ~t~,
    ~relative~ or ~visual~ then line numbers  are enabled in all ~prog-mode~ and
    ~text-mode~ derivatives. If set to ~relative~, line numbers are relative. If
    set to ~visual~,  line numbers are also relative, but  only visual lines are
    counted. For example, folded lines will not be counted and wrapped lines are
    counted as multiple lines. This variable can  also be set to a property list
    for finer control:
    #+BEGIN_SRC emacs-lisp :tangle no
      '(:relative nil
        :visual nil
        :disabled-for-modes dired-mode
                            doc-view-mode
                            markdown-mode
                            org-mode
                            pdf-view-mode
                            text-mode
        :size-limit-kb 1000)
    #+END_SRC
    When used in a plist, ~visual~ takes precendence over ~relative~.
    #+BEGIN_SRC emacs-lisp
      (setq-default dotspacemacs-line-numbers '(:relative nil
                                                :enabled-for-modes prog-mode))
    #+END_SRC

    Select a scope to highlight delimiter. Possible values are:
    - ~any~
    - ~current~
    - ~all~
    - ~nil~
    The default  value is ~all~ (highlights  any scope and emphasis  the current
    one).
    #+BEGIN_SRC emacs-lisp
      (setq-default dotspacemacs-highlight-delimiters 'all)
    #+END_SRC

    After  a certain  amount of  time in  seconds, Spacemacs  can zone-out.  The
    default value is ~nil~. I set it so Spacemacs zones out after 15 minutes.
    #+BEGIN_SRC emacs-lisp
      (setq-default dotspacemacs-zone-out-when-idle 900)
    #+END_SRC

    Run ~spacemacs/prettify-org-buffer~ when visiting  the ~README.org~ files of
    Spacemacs. The default value is ~nil~.
    #+BEGIN_SRC emacs-lisp
      (setq-default dotspacemacs-pretty-docs nil)
    #+END_SRC

*** Appearance of Emacs frames
    :PROPERTIES:
    :CUSTOM_ID: Init-Visual_configuration-Appearance_of_Emacs_frames-59700bb7
    :END:
    Starting from Emacs 24.4, it is  possible to make the Emacs frame fullscreen
    when Emacs starts up if the variable  is set to a non-nil value. The default
    value is =nil=.
    #+BEGIN_SRC emacs-lisp
      (setq-default dotspacemacs-fullscreen-at-startup nil)
    #+END_SRC

    This  variable is  to  be used  if  the user  does not  want  to use  native
    fullscreen  with ~spacemacs/toggle-fullscreen~.  This disables  for instance
    the fullscreen animation under OSX. The default value is =nil=.
    #+BEGIN_SRC emacs-lisp
      (setq-default dotspacemacs-fullscreen-use-non-native nil)
    #+END_SRC

    If you do not start Emacs in fullscreen  at startup, you might want it to be
    maximized by  default. If  the value  for the  variable below  is set  to be
    non-nil,   the  frame   will   be   maximized.  This   can   only  work   if
    ~dotspacemacs-fullscreen-at-startup~  is  set  to  ~nil~,  and  it  is  only
    available from Emacs 24.4 onwards. The default value is ~nil~.
    #+BEGIN_SRC emacs-lisp
    (setq-default dotspacemacs-maximized-at-startup nil)
    #+END_SRC

    If non-nil, the frame is undecorated when Emacs starts up. Combine this with
    the variable ~dotspacemacs-maximized-at-startup~ in OSX to obtain borderless
    fullscreen. The default value is ~nil~.
    #+BEGIN_SRC emacs-lisp
      (setq-default dotspacemacs-undecorated-at-startup nil)
    #+END_SRC

    You  can  also set  a  transparency  level for  Emacs  when  you toggle  the
    transparency  of the  frame  with ~toggle-transparency~.  The  value of  the
    transparency,  going from  0 to  100  in increasing  opacity, describes  the
    transparency level  of a  frame when  it’s active  or selected.  The default
    value is ~90~.
    #+BEGIN_SRC emacs-lisp
      (setq-default dotspacemacs-active-transparency 75)
    #+END_SRC

    Similarly, you  can set a  value from 0 to  100 in increasing  opacity which
    describes  the  transparency  level  of   a  frame  when  it’s  inactive  or
    deselected. The default value is ~90~.
    #+BEGIN_SRC emacs-lisp
      (setq-default dotspacemacs-inactive-transparency 80)
    #+END_SRC

    The variable below sets the format of frame title. You can use:
    - ~%a~ :: the ~abbreviated-file-name~ or ~buffer-name~
    - ~%t~ :: ~projectile-project-name~
    - ~%I~ :: ~invocation-name~
    - ~%S~ :: ~system-name~
    - ~%U~ :: contents of ~$USER~
    - ~%b~ :: buffer name
    - ~%f~ :: visited file name
    - ~%F~ :: frame name
    - ~%s~ :: process status
    - ~%p~ :: percent of buffer above top of window, or Top, Bot, or All
    - ~%P~ ::  percent of buffer  above bottom of  window, perhaps plus  Top, or
              Bot, or All
    - ~%m~ :: mode name
    - ~%n~ :: Narrow if appropriate
    - ~%z~ :: mnemonics of buffer, terminal, and keyboard coding systems
    - ~%Z~ :: like ~%z~, but including the end-of-line format
    The default value is ~"%I@%S"~.
    #+BEGIN_SRC emacs-lisp
      (setq-default dotspacemacs-frame-title-format "%b (%m)")
    #+END_SRC

    Format specification for setting the icon title format. The default value is
    ~nil~, same as ~frame-title-format~.
    #+BEGIN_SRC emacs-lisp
      (setq-default dotspacemacs-icon-title-format nil)
    #+END_SRC

** Spacemacs leader keys and shortcuts
   :PROPERTIES:
   :CUSTOM_ID: Init-Spacemacs_leader_keys_and_shortcuts-ebf21abe
   :END:
   The below  setting sets  the Spacemacs  leader key. By  default, this  is the
   =SPC= key.
   #+BEGIN_SRC emacs-lisp
     (setq-default dotspacemacs-leader-key "SPC")
   #+END_SRC

   Once the leader  key has been pressed,  it is possible to set  another key in
   order to call Emacs’ command =M-x=. By default, it is again the =SPC= key.
   #+BEGIN_SRC emacs-lisp
     (setq-default dotspacemacs-emacs-command-key "SPC")
   #+END_SRC

   It is also possible to invoke Vim Ex commands with the press of a key, and by
   default it is the =:= key.
   #+BEGIN_SRC emacs-lisp
     (setq-default dotspacemacs-ex-command-key ":")
   #+END_SRC

   The  below variable  sets  the  leader key  accessible  in =emacs-state=  and
   =insert-state=:
   #+BEGIN_SRC emacs-lisp
     (setq-default dotspacemacs-emacs-leader-key "M-m")
   #+END_SRC

   The  major mode  leader key  is a  shortcut key  which is  the equivalent  of
   pressing =<leader> m=.  Set it to =nil=  to disable it. Its  default value is
   =,=.
   #+BEGIN_SRC emacs-lisp
     (setq-default dotspacemacs-major-mode-leader-key ",")
   #+END_SRC

   In =emacs-state=  and =insert-state=, the same  major mode leader key  can be
   accessible from another shortcut, which by default is =C-M-m=.
   #+BEGIN_SRC emacs-lisp
     (setq-default dotspacemacs-major-mode-emacs-leader-key "C-M-m")
   #+END_SRC

   These variables control whether separate commands are bound in the GUI to the
   key pairs =C-i= and =TAB=, and =C-m= and =RET=. Setting it to a non-nil value
   allows for separate  commands under =C-i= and =TAB=, and  =C-m= and =RET=. In
   the terminal, these pairs are generally indistinguishable, so this only works
   in the GUI. The default value is =nil=.
   #+BEGIN_SRC emacs-lisp
     (setq-default dotspacemacs-distinguish-gui-tab nil)
   #+END_SRC

** Layouts
   :PROPERTIES:
   :CUSTOM_ID: Init-Layouts-61c0374d
   :END:
   The variable belows sets the name of the default layout. Its default value is
   ="Default"=.
   #+BEGIN_SRC emacs-lisp
     (setq-default dotspacemacs-default-layout-name "Default")
   #+END_SRC

   If  non-nil, the  default  layout name  is displayed  in  the mode-line.  The
   default value is =nil=.
   #+BEGIN_SRC emacs-lisp
     (setq-default dotspacemacs-display-default-layout nil)
   #+END_SRC

   If non-nil, then the last auto saved layouts are resumed automatically upon
   start. The default value is =nil=.
   #+BEGIN_SRC emacs-lisp
     (setq-default dotspacemacs-auto-resume-layouts nil)
   #+END_SRC

   If non-nil, the layout name will be auto-generated when creating new layouts.
   It only has an effect when using  the “jump to layout by number” command. The
   default value is =nil=.
   #+BEGIN_SRC emacs-lisp
     (setq-default dotspacemacs-auto-generate-layout-names nil)
   #+END_SRC

** Files-related settings
   :PROPERTIES:
   :CUSTOM_ID: Init-Files-related_settings-67fba383
   :END:
   The below value sets the size in MB above which Spacemacs will prompt to open
   the  file literally  in order  to avoid  preformance issues.  Opening a  file
   literally means that no  major or minor mode is active.  The default value is
   =1=.
   #+BEGIN_SRC emacs-lisp
   (setq-default dotspacemacs-large-file-size 5)
   #+END_SRC

   This variable  sets the  location where to  auto-save files.  Possible values
   are:
   - =original= :: auto-saves files in-place
   - =cache= :: auto-saves files in another file stored in the cache directory
   - =nil= :: disables auto-saving.
   The default value is =cache=.
   #+BEGIN_SRC emacs-lisp
   (setq-default dotspacemacs-auto-save-file-location 'original)
   #+END_SRC

** Emacs server
   :PROPERTIES:
   :CUSTOM_ID: Init-Emacs_server-d3947c28
   :END:
   Emacs can be  launched as a server  if the following value is  set to non-nil
   and if one isn’t already running. The default value is ~nil~.
   #+BEGIN_SRC emacs-lisp
     (setq-default dotspacemacs-enable-server nil)
   #+END_SRC

   You can  also set  a custom  emacs server  socket location.  If the  value is
   ~nil~, Emacs  will use whatever the  Emacs default is, otherwise  a directory
   path   like    ="$HOME/.config/emacs/server"=.   It   has   no    effect   if
   ~dotspacemacs-enable-server~ is ~nil~.
   #+BEGIN_SRC emacs-lisp
     (setq-default dotspacemacs-server-socket-dir nil)
   #+END_SRC

   It is  also possible  to tell Emacs  that the quit  function should  keep the
   server open when quitting. The default value is ~nil~.
   #+BEGIN_SRC emacs-lisp
     (setq-default dotspacemacs-persistent-server t)
   #+END_SRC

** Miscellaneous
   :PROPERTIES:
   :CUSTOM_ID: Init-Miscellaneous-6b4f0b76
   :END:
   This value changes the folding method of code blocks. The possible values are
   either ~evil~, the default value, or ~origami~.
   #+BEGIN_SRC emacs-lisp
     (setq-default dotspacemacs-folding-method 'evil)
   #+END_SRC

   If non-nil,  ~smartparens-strict-mode~ will be enabled  in programming modes.
   The default value is ~nil~.
   #+BEGIN_SRC emacs-lisp
     (setq-default dotspacemacs-smartparens-strict-mode nil)
   #+END_SRC

   If non-nil,  pressing the closing parenthesis  ~)~ key in insert  mode passes
   over any automatically  added closing parenthesis, bracket,  quote, etc… This
   can temporarily disabled  by pressing ~C-q~ before ~)~. The  default value is
   ~nil~.
   #+BEGIN_SRC emacs-lisp
     (setq-default dotspacemacs-smart-closing-parenthesis nil)
   #+END_SRC

   List of search tool executable names. Spacemacs uses the first installed tool
   of the list. Supported tools are:
   - ~rg~
   - ~ag~
   - ~pt~
   - ~ack~
   - ~grep~
   The default value is ~'("rg" "ag" "pt" "ack" "grep")~.
   #+BEGIN_SRC emacs-lisp
     (setq-default dotspacemacs-search-tools '("rg" "grep"))
   #+END_SRC

   Delete whitespace while saving buffer. Possible values are:
   - ~all~ :: aggresively delete empty lines and long sequences of whitespace
   - ~trailing~ :: only detele the whitespace at end of lines
   - ~changed~ :: to delete only whitespace for changed lines
   - ~nil~ :: disable cleanup
   The default value is ~nil~.
   #+BEGIN_SRC emacs-lisp
     (setq-default dotspacemacs-whitespace-cleanup nil)
   #+END_SRC

  Set ~gc-cons-threshold~  and ~gc-cons-percentage~ when startup  finishes. This
  is an advanced option and should not be changed unless you suspect performance
  issues due to garbage collection operations. The default is ~'(100000000 0.1)~
  #+BEGIN_SRC emacs-lisp
    (setq-default dotspacemacs-gc-cons '(100000000 0.1))
  #+END_SRC

  If  non  nil activate  ~clean-aindent-mode~  which  tries to  correct  virtual
  indentation  of simple  modes. This  can  interfer with  mode specific  indent
  handling like has been reported for  ~go-mode~. If it does deactivate it here.
  Default ~t~.
  #+BEGIN_SRC emacs-lisp
    (setq-default dotspacemacs-use-clean-aindent-mode t)
  #+END_SRC

  Text   of  shifted   values   from  your   keyboard's   number  row.   Default
  ~'!@#$%^&*()'~. I adapted it to the bépo layout.
  #+BEGIN_SRC emacs-lisp
    (setq-default dotspacemacs-snoopy-keyrow "\"«»()@+-/*")
  #+END_SRC

  If non-nil  activate ~snoopy-mode~ which shifts  your number row to  match the
  set  of  signs  given  in ~dotspacemacs-snoopy-keyrow~  in  programming  modes
  (~insert-mode~ only). Default ~nil~.
  #+BEGIN_SRC emacs-lisp
    (setq-default dotspacemacs-use-snoopy-mode nil)
  #+END_SRC

  Set  ~read-process-output-max~ when  startup finishes.  This defines  how much
  data is  read from  a foreign process.  Setting this >=  1 MB  should increase
  performance for lsp servers in emacs 27.
  #+BEGIN_SRC emacs-lisp
    (setq-default dotspacemacs-read-process-output-max (* 1024 1024 8))
  #+END_SRC

* User Initialization
  :PROPERTIES:
  :header-args:emacs-lisp: :mkdir yes :tangle ~/.config/emacs/private/user-init.el :exports code :results silent
  :CUSTOM_ID: User_Initialization-e0d21089
  :END:

  While  Emacs and  especially Spacemacs  loads, I  want it  to initialize  some
  elements and load  some packages. First of  all, I want it to  load my private
  Emacs config file:
  #+BEGIN_SRC emacs-lisp
    (load "~/.config/emacs/private/private_emacs")
  #+END_SRC

  Let’s also load  the file defining ~odf-mode~, a mode  for viewing the content
  of ODF files  generated by OpenOffice and LibreOffice (if  you use one, please
  use the latter).
  #+BEGIN_SRC emacs-lisp
    (load "~/.config/emacs/private/odf-mode")
  #+END_SRC

  Then, I want a couple of requires:
  #+BEGIN_SRC emacs-lisp
    (require 'org-id)
    (require 'org-protocol)
    (require 'package)
    (require 'ox-latex)
    (require 'ox-publish)
    (require 'tramp)
  #+END_SRC

  I would also like to enable the setup of flycheck for Rust when Flycheck is
  loaded:
  #+BEGIN_SRC emacs-lisp
    (add-hook 'flycheck-mode-hook #'flycheck-rust-setup)
  #+END_SRC

  By default, Flyspell should be disabled and only enabled manually.
  #+BEGIN_SRC emacs-lisp
    (flyspell-mode 0)
  #+END_SRC

  Finally, here is a quick workaround for Tramp, sometimes it cannot connect to
  my hosts if I don’t have this code snippet.
  #+BEGIN_SRC emacs-lisp
    (setq tramp-ssh-controlmaster-options
          "-o ControlMaster=auto -o ControlPath='tramp.%%C' -o ControlPersist=no")
  #+END_SRC

* User Configuration
  :PROPERTIES:
  :header-args:emacs-lisp: :mkdir yes :tangle ~/.config/emacs/private/user-config.el :exports code :results silent
  :CUSTOM_ID: User_Configuration-4a937fe5
  :END:
** Custom functions
   :PROPERTIES:
   :CUSTOM_ID: User_Configuration-Custom_functions-ceb4bc42
   :END:
   In this section,  I will put my  various custom functions that do  not fit in
   other sections and  which are more oriented towards  general usage throughout
   Emacs and in Elisp code.

   Almost all of my code snippets will be prefixed by either my name or the name
   of  the package  or layer  they  are part  of,  unless they  are an  explicit
   overwrite of a function that already exists.
*** ~phundrak/yas-rust-new-assignments~
    :PROPERTIES:
    :CUSTOM_ID: User_Configuration-Custom_functions-phundrakyas-rust-new-assignments-10f73456
    :END:
    The following  function is a  function that will  allow me to  easily create
    ~new~    functions    for    Rust     structs.    Inspired    from    [[https://github.com/jorgenschaefer/elpy][elpy]]’s
    ~elpy-snippet-init-assignments~  function,   it  will   automatically  write
    assignments  to  my new  struct  as  I write  new  parameters  in the  ~new~
    function. It  also comes with  a helper  function that parses  the arguments
    given to the ~new~ function.
    #+BEGIN_SRC emacs-lisp
      (defun phundrak//yas-snippet-split-rust-args ($arg-string)
        "Split a Rust argument string into ((name, default)...) tuples"
        (mapcar (lambda ($elem)
                  (split-string $elem "[[:blank:]]*:[[:blank:]]*" t))
                (split-string $arg-string "[[:blank:]]*,[[:blank:]]*" t)))

      (defun phundrak/yas-rust-new-assignments ($arg-string)
        "Return a typical new assignment for arguments.

      Inspired from elpy’s functions https://github.com/jorgenschaefer/elpy"
        (let ((indentation (make-string (save-excursion
                                         (goto-char start-point)
                                         (current-indentation))
                                       ?\s)))
          (mapconcat (lambda ($elem)
                       (if (string-match "^\\*" (car $elem))
                           ""
                         (format "%s,\n%s" (car $elem) indentation)))
                     (phundrak//yas-snippet-split-rust-args $arg-string)
                     "")))
    #+END_SRC

*** ~phundrak/add-all-to-list~
    :PROPERTIES:
    :CUSTOM_ID: User_Configuration-Custom_functions-phundrakadd-all-to-list-7e34472b
    :END:
    #+BEGIN_SRC emacs-lisp
      (defun phundrak/add-all-to-list ($list &rest $elements)
        "Add all $elements from `$elements' to the $list `$list'. If an
      element from `$elements' is already part of `$list', it will be
      ignored."
        (dolist ($e $elements)
          (if (not (member $e $list))
              (add-to-list '$list $e)))
        $list)
    #+END_SRC

*** ~phundrak/fill-paragraph~
    :PROPERTIES:
    :CUSTOM_ID: User_Configuration-Custom_functions-~phundrak-fill-paragraph~-ab4ef600
    :END:
    This function was created in order  to bind to another keyboard shortcut the
    already existing ~C-u M-q~ which I  cannot type with evil-mode unless I’m in
    insert mode.
    #+BEGIN_SRC emacs-lisp
    (defun phundrak/fill-paragraph ()
      (interactive)
      (let* ((current-prefix-arg 4))
        (call-interactively 'fill-paragraph)))
    #+END_SRC

*** ~terminal-here-default-terminal-command~
    :PROPERTIES:
    :CUSTOM_ID: User_Configuration-Custom_functions-~terminal-here-default-terminal-command~-1916a912
    :END:
    This function is  actually an overwrite of the default  one which apparently
    does   not   work   on   my    machine.   This   function   is   called   by
    ~terminal-here-launch~  and  spawns an  external  terminal  emulator in  the
    directory emacs was in when the terminal  was invoked. I simply point out to
    this function the name of my terminal emulator. Here is the code:
    #+BEGIN_SRC emacs-lisp
      (defun terminal-here-default-terminal-command (_dir)
        '("st"))
    #+END_SRC

** Emacs builtins
   :PROPERTIES:
   :CUSTOM_ID: User_Configuration-Emacs_builtins-7822b8dd
   :END:
*** Dired
    :PROPERTIES:
    :CUSTOM_ID: User_Configuration-Dired-ef8a7cac
    :END:
    When it  comes to dired, I  chose do modify  some elements on how  things are
    sorted and shown, but there isn’t much configuration. First, I want to always
    copy folders in a recursive way, no questions asked.
    #+BEGIN_SRC emacs-lisp
      (setq dired-recursive-copies 'always)
    #+END_SRC

    Also, when  I have two  Dired buffers opened side  by side, I  generally want
    them to interact, for  example if I want to move  something around. So, let’s
    tell Emacs that:
    #+BEGIN_SRC emacs-lisp
      (setq dired-dwim-target t)
    #+END_SRC

    Finally,  let’s  tell  Dired  how  to sort  the  elements  to  be  displayed:
    directories first, non-hidden first.
    #+BEGIN_SRC emacs-lisp
      (setq dired-listing-switches "-ahl --group-directories-first")
    #+END_SRC

    By the way, let’s enable ~org-download~ when we are in a Dired buffer:
    #+BEGIN_SRC emacs-lisp
      (add-hook 'dired-mode-hook 'org-download-enable)
    #+END_SRC

*** Eshell
    :PROPERTIES:
    :CUSTOM_ID: User_Configuration-Eshell-3012e67e
    :END:
    Eshell is a built-in  shell available from Emacs which I  use almost as often
    as Fish. Some adjustments are necessary for making this shell usable for me.

**** Environment variables
     :PROPERTIES:
     :CUSTOM_ID: User_Configuration-Eshell-Environment_variables-8dac73e0
     :END:
     Some environment variables need to be  correctly set so Eshell can correctly
     work. The first  environment variable to be  set is the ~PATH~, as  I have a
     couple of directories  where executables are located. Let’s add  them to our
     path.
     #+BEGIN_SRC emacs-lisp
       (setenv "PATH"
               (concat
                (getenv "HOME") "/.pub-cache/bin"
                ":" (getenv "HOME") "/.local/bin"
                ":" (getenv "HOME") "/go/bin"
                ":" (getenv "HOME") "/.cargo/bin"
                ":" (getenv "HOME") "/.gem/ruby/2.6.0/bin"
                ":" (getenv "PATH")))
     #+END_SRC

     I  would  also  like  to  set two  environment  variables  related  to  Dart
     development: the ~DART_SDK~ and ~ANDROID_HOME~ variables.
     #+BEGIN_SRC emacs-lisp
       (setenv "DART_SDK" "/opt/dart-sdk/bin")
       (setenv "ANDROID_HOME" (concat (getenv "HOME") "/Android/Sdk/"))
     #+END_SRC

     Finally, I’d like to add a custom directory to the ~PKG_CONFIG_PATH~:
     #+BEGIN_SRC emacs-lisp
       (setenv "PKG_CONFIG_PATH" (concat
                                  "/usr/local/lib/pkgconfig/" ":"
                                  (getenv "PKG_CONFIG_PATH")))
     #+END_SRC

     The ~EDITOR~ variable also needs to  be set for git commands, especially the
     ~yadm~ commands.
     #+BEGIN_SRC emacs-lisp
       (setenv "EDITOR" "emacsclient -c")
     #+END_SRC

**** Custom functions
     :PROPERTIES:
     :CUSTOM_ID: User_Configuration-Eshell-Custom_functions-79d98245
     :END:
     When I’m  in Eshell,  sometimes I  wish to  open multiple  files at  once in
     Emacs. For this, when I have several arguments for ~find-file~, I want to be
     able to open them all at once. Let’s modify ~find-file~ like so:
     #+BEGIN_SRC emacs-lisp
       (defadvice find-file (around find-files activate)
         "Also find all files within a list of files. This even works recursively."
         (if (listp filename)
             (loop for f in filename do (find-file f wildcards))
           ad-do-it))
     #+END_SRC

     I also want to be able to  have multiple instances of Eshell opened at once.
     For that, I declared the function ~eshell-new~ that does exactly that.
     #+BEGIN_SRC emacs-lisp
       (defun eshell-new()
         "Open a new instance of eshell."
         (interactive)
         (eshell 'N))
     #+END_SRC

***** Redirect text editors to Emacs
      :PROPERTIES:
      :CUSTOM_ID: User_Configuration-Eshell-Custom_functions-Redirect_text_editors_to_Emacs-dff362c6
      :END:
      I still have  some muscle memory telling  me to open nano, ed,  or vim, and
      sometimes I even try to type ~emacs~  in the terminal, which is stupid with
      Eshell since I’m already inside Emacs.  So, for each of these text editors,
      let’s make the command open the files in Emacs.
      #+BEGIN_SRC emacs-lisp
        (defun eshell/emacs (&rest $files)
          "Open a file in a new buffer. Old habits die hard"
          (if (null $files)
              (bury-buffer)
            (mapc #'find-file
                  (mapcar #'expand-file-name
                          (eshell-flatten-list (reverse $files))))))
        (defalias 'eshell/vi 'eshell/emacs)
        (defalias 'eshell/vim 'eshell/emacs)
        (defalias 'eshell/ed 'eshell/emacs)
        (defalias 'eshell/nano 'eshell/emacs)
      #+END_SRC

**** Aliases
     :PROPERTIES:
     :CUSTOM_ID: User_Configuration-Eshell-Aliases-ef06615f
     :END:
     This  function  is a  function  that  will come  in  very  handy for  Eshell
     functions  that call  shell processes.  It concatenates  the initial  string
     ~command~ with all the arguments ~args~, each separated with a space.
     #+BEGIN_SRC emacs-lisp
       (defun phundrak/concatenate-shell-command ($command &rest $args)
         (string-join (cons $command $args) " "))
     #+END_SRC

     Just like most shells, it is possible to declare in Eshell aliases. First, I
     would like to be able to use ~open~ to open files in Emacs:
     #+BEGIN_SRC emacs-lisp
       (defalias 'open 'find-file)
     #+END_SRC

     I also  have ~openo~  which allows  me to  perform the  same action,  but in
     another window:
     #+BEGIN_SRC emacs-lisp
       (defalias 'openo 'find-file-other-window)
     #+END_SRC

     The function ~yes-or-no-p~  is also aliased to ~y-or-n-p~ so  I only have to
     answer by ~y~ or ~n~ instead of typing ~yes~ or ~no~.
     #+BEGIN_SRC emacs-lisp
       (defalias 'yes-or-no-p 'y-or-n-p)
     #+END_SRC

     For  some ease  of use,  I’ll  also declare  ~list-buffers~ as  an alias  of
     ~ibuffer~.
     #+BEGIN_SRC emacs-lisp
       (defalias 'list-buffers 'ibuffer)
     #+END_SRC

     #+BEGIN_SRC emacs-lisp
       (defun eshell/mkdir ($directory)
         (make-directory $directory t))
     #+END_SRC

     #+BEGIN_SRC emacs-lisp
       (defun eshell/ls (&optional $directory)
         (shell-command (format "exa -halg@ --group-directories-first --git%s"
                                (if (string= "" $directory)
                                    ""
                                  (concat " " $directory)))))
     #+END_SRC

***** System monitoring
      :PROPERTIES:
      :CUSTOM_ID: User_Configuration-Eshell-Aliases-System_monitoring-ee01b070
      :END:
      Similar to ~meminfo~, we also have ~gpumeminfo~  so we can get a quick look
      at the memory-related logs of our X session.
      #+BEGIN_SRC emacs-lisp
        (defun eshell/gpumeminfo (&rest $args)
          (eshell/grep "-i" "--color" "memory" "/var/log/Xorg.0.log"))
        (defun eshell/diskspace ()
          (shell-command "sudo df -h | grep -E \"sd|lv|Size\" | sort"))
      #+END_SRC

      I also declared  ~cpuinfo~ an alias of ~lscpu~ in  order to keep consistent
      with ~meminfo~.
      #+BEGIN_SRC emacs-lisp
        (defun eshell/meminfo ()
          (shell-command "free -m -l -t"))
      #+END_SRC

      ~pscpu~ gives  us information  on what  the CPU is  running right  now, and
      I also declared  ~cpuinfo~ an alias of ~lscpu~ in  order to keep consistent
      with ~meminfo~.
      #+BEGIN_SRC emacs-lisp
        (defun eshell/cpuinfo ()
          (shell-command "lscpu"))
      #+END_SRC

      ~pscpu10~ limits that to the top 10 threads.
      #+BEGIN_SRC emacs-lisp
        (defun eshell/pscpu ()
          (shell-command "ps auxf | sort -nr -k 3"))
        (defun eshell/pscpu10 ()
          (shell-command "ps auxf | sort -nr -k 3 | head -10"))
      #+END_SRC

      Similarly, ~psmem~ gives us information on  the memory usage of the current
      threads, and  ~psmem10~ only  the ten  most important  threads in  terms of
      memory usage.
      #+BEGIN_SRC emacs-lisp
        (defun eshell/pscpu ()
          (shell-command "ps auxf | sort -nr -k 4"))
        (defun eshell/pscpu10 ()
          (shell-command "ps auxf | sort -nr -k 4 | head -10"))
      #+END_SRC

***** System management (packages and services)
      :PROPERTIES:
      :CUSTOM_ID: User_Configuration-Eshell-Aliases-System_management_(packages_and_services)-afb6d9d3
      :END:
      The first command is ~remove~ which removes a package and its dependencies
      from the system.
      #+BEGIN_SRC emacs-lisp
        (defun eshell/remove (&rest $args)
          (phundrak/concatenate-shell-command "sudo pacman -Rscnd"
                                              $args))
      #+END_SRC

      But if I just  want to run ~pacman~ as sudo, then I  could always just type
      ~p~.
      #+BEGIN_SRC emacs-lisp
        (defun eshell/p (&rest $args)
          (phundrak/concatenate-shell-command "sudo pacman" $args))
      #+END_SRC

      Sometimes,  I  just  want  to  purge my  package  manager’s  cache,  be  it
      ~pacman~'s or ~yay~'s. This is why I simply type ~purge~.
      #+BEGIN_SRC emacs-lisp
        (defun eshell/purge ()
          (shell-command "yay -Sc"))
      #+END_SRC

***** Other
      :PROPERTIES:
      :CUSTOM_ID: User_Configuration-Eshell-Aliases-Other-bd88ca97
      :END:
      ~mkcd~ is a function that allows me to create a directory and ~cd~ into it
      at the same time.
      #+begin_src emacs-lisp
        (defun eshell/mkcd ($directory)
          (eshell/mkdir "-p" $directory)
          (cd $directory))
      #+end_src

      #+BEGIN_SRC emacs-lisp
        (defun eshell/lsl (&rest $args)
          (eshell/ls "-aHl" $args))
      #+END_SRC

      #+BEGIN_SRC emacs-lisp
        (defun eshell/ll (&rest $args)
          (eshell/ls "-ahl" $args))
      #+END_SRC

      #+BEGIN_SRC emacs-lisp
        (defun eshell/la (&rest $args)
          (eshell/ls "-A" $args))
      #+END_SRC

***** Typos
      :PROPERTIES:
      :CUSTOM_ID: User_Configuration-Eshell-Aliases-Typos-c7bfe6eb
      :END:
      ~q~ is a shorthand for ~exit~. ~exti~ and ~exi~ are for typos when I type ~exit~.
      #+BEGIN_SRC emacs-lisp
        (defun eshell/q (&rest $args)
          (eshell/exit $args))
        (defun eshell/exti (&rest $args)
          (eshell/exit $args))
        (defun eshell/exi (&rest $args)
          (eshell/exit $args))
      #+END_SRC

      ~clean~ is also a typo of ~clear~ I often make. Let’s fix this:
      #+BEGIN_SRC emacs-lisp
        (defun eshell/clean (&rest $args)
          (eshell/clear $args))
      #+END_SRC

**** Visual commands
     :PROPERTIES:
     :CUSTOM_ID: User_Configuration-Eshell-Visual_commands-2b15e0dc
     :END:
     With Eshell,  some commands don’t  work very well, especially  commands that
     create a TUI. So, let’s declare them as visual commands or subcommands:
     #+BEGIN_SRC emacs-lisp
       (setq eshell-visual-commands
             '("fish" "zsh" "bash" "tmux" "htop" "top" "vim" "bat" "nano")
             eshell-visual-subcommands
             '("git" "log" "l" "diff" "show"))
     #+END_SRC

**** Eshell theme
     :PROPERTIES:
     :CUSTOM_ID: User_Configuration-Eshell-Eshell_theme-a06715a9
     :END:
     As with  most shells, again, it  is possible to customize  the appearance of
     the Eshell prompt.  First, we need to declare  a macro so we can  set a face
     with properties:
     #+BEGIN_SRC emacs-lisp
       (defmacro with-face (str &rest properties)
         `(propertize ,str 'face (list ,@properties)))
     #+END_SRC

     Now,  let’s  declare a  function  that  will  abbreviate the  current  ~pwd~
     fish-shell style.
     #+BEGIN_SRC emacs-lisp
       (defun eshell/abbr-pwd ()
         (let (($home (getenv "HOME"))
               ($path (eshell/pwd)))
           (cond
            ((string-equal $home $path) "~")
            ((f-ancestor-of? $home $path) (concat "~/" (f-relative $path $home)))
            ($path))))
     #+END_SRC

     Now, let’s declare our prompt:
     #+BEGIN_SRC emacs-lisp
       (defun eshell/my-prompt ()
         (let ((header-bg "#161616"))
           (concat
            (with-face (eshell/abbr-pwd) :foreground "#008700")
            "\n"
            (if (= (user-uid) 0)
                (with-face "➜" :foreground "red")
              (with-face "➜" :foreground "#2345ba"))
            " ")))
     #+END_SRC

     Now, let’s declare our prompt regexp and our prompt functions:
     #+BEGIN_SRC emacs-lisp
       (setq eshell-prompt-regexp "^[^#$\n]*[#$] "
             eshell-prompt-function 'eshell/my-prompt)
     #+END_SRC

*** Org-mode
    :PROPERTIES:
    :CUSTOM_ID: User_Configuration-Org-mode-04ab8ad3
    :END:
    Org-mode is  probably one of the  best if not  the best Emacs feature  I have
    ever  discovered. It  is awesome  for  writing documents,  regardless of  the
    format you need it to be exported to, for agenda management, and for literary
    programming, such as with this document.
    #+BEGIN_SRC emacs-lisp :tangle no
      (with-eval-after-load 'org
        ;; configuration goes here
        )
    #+END_SRC

 # Don’t delete this, this code block is here to wrap the org configuration
 #+BEGIN_SRC emacs-lisp :exports none
   (with-eval-after-load 'org
 #+END_SRC

**** Custom org-mode functions
     :PROPERTIES:
     :CUSTOM_ID: User_Configuration-Org-mode-Custom_org-mode_functions-f1726995
     :END:
     We begin with a couple of custom functions that I use in my org-mode files.

***** Custom and unique headings ID
      :PROPERTIES:
      :CUSTOM_ID: User_Configuration-Org-mode-Custom_org-mode_functions-Custom_and_unique_headings_ID-44d2beaf
      :END:
      The  first ones  are dedicated  to provide  org-mode headings  a fixed  and
      unique  ID  that  won’t  change  over   time.  This  code  was  taken  from
      [[https://writequit.org/articles/emacs-org-mode-generate-ids.html][https://writequit.org/articles/emacs-org-mode-generate-ids.html]].  The first
      function’s job is to create these unique IDs
      #+BEGIN_SRC emacs-lisp
        (defun eos/org-id-new (&optional prefix)
          "Create a new globally unique ID.

        An ID consists of two parts separated by a colon:
        - a prefix
        - a   unique   part   that   will   be   created   according   to
          `org-id-method'.

        PREFIX  can specify  the  prefix,  the default  is  given by  the
        variable  `org-id-prefix'.  However,  if  PREFIX  is  the  symbol
        `none', don't  use any  prefix even if  `org-id-prefix' specifies
        one.

        So a typical ID could look like \"Org-4nd91V40HI\"."
          (let* ((prefix (if (eq prefix 'none)
                             ""
                           (concat (or prefix org-id-prefix)
                                   "-"))) unique)
            (if (equal prefix "-")
                (setq prefix ""))
            (cond
             ((memq org-id-method
                    '(uuidgen uuid))
              (setq unique (org-trim (shell-command-to-string org-id-uuid-program)))
              (unless (org-uuidgen-p unique)
                (setq unique (org-id-uuid))))
             ((eq org-id-method 'org)
              (let* ((etime (org-reverse-string (org-id-time-to-b36)))
                     (postfix (if org-id-include-domain
                                  (progn
                                    (require 'message)
                                    (concat "@"
                                            (message-make-fqdn))))))
                (setq unique (concat etime postfix))))
             (t (error "Invalid `org-id-method'")))
            (concat prefix (car (split-string unique "-")))))
      #+END_SRC

      Now, let’s  see the function that  will be used to  get the custom id  of a
      heading at point. If  the function does not detect any  custom ID, then one
      should be created and inserted.
      #+BEGIN_SRC emacs-lisp
        (defun eos/org-custom-id-get (&optional pom create prefix)
          "Get the CUSTOM_ID property of the entry at point-or-marker POM.

        If POM is nil, refer to the entry at point. If the entry does not
        have an CUSTOM_ID, the function returns nil. However, when CREATE
        is non nil, create a CUSTOM_ID if none is present already. PREFIX
        will  be passed  through to  `eos/org-id-new'. In  any case,  the
        CUSTOM_ID of the entry is returned."
          (interactive)
          (org-with-point-at pom
            (let* ((orgpath (mapconcat #'identity (org-get-outline-path) "-"))
                   (heading (replace-regexp-in-string
                             "/\\|~" ""
                             (replace-regexp-in-string
                              " " "_" (if (string= orgpath "")
                                          (org-get-heading t t t t)
                                        (concat orgpath "-" (org-get-heading t t t t))))))
                   (id (org-entry-get nil "CUSTOM_ID")))
              (cond
               ((and id
                     (stringp id)
                     (string-match "\\S-" id)) id)
               (create (setq id (eos/org-id-new (concat prefix heading)))
                       (org-entry-put pom "CUSTOM_ID" id)
                       (org-id-add-location id
                                            (buffer-file-name (buffer-base-buffer)))
                       id)))))
      #+END_SRC

      Finally,  this is  the function  that  gets called  on file  saves. If  the
      function  detects ~auto-id:t~  among the  org options  in the  ~#+OPTIONS:~
      header, then the above function is called.
      #+BEGIN_SRC emacs-lisp
        (defun eos/org-add-ids-to-headlines-in-file ()
          "Add CUSTOM_ID properties to all headlines in the current file
        which do not already have one.

        Only adds ids if the `auto-id' option is set to `t' in the file
        somewhere. ie, #+OPTIONS: auto-id:t"
          (interactive)
          (save-excursion
            (widen)
            (goto-char (point-min))
            (when (re-search-forward "^#\\+OPTIONS:.*auto-id:t"
                                     (point-max)
                                     t)
              (org-map-entries (lambda ()
                                 (eos/org-custom-id-get (point)
                                                        'create))))))
      #+END_SRC

      Let’s add  a hook to  the above function so  it is called  automatically on
      save, and only in read-write functions.
      #+BEGIN_SRC emacs-lisp
        (add-hook 'org-mode-hook
                  (lambda ()
                    (add-hook 'before-save-hook
                              (lambda ()
                                (when (and (eq major-mode 'org-mode)
                                           (eq buffer-read-only nil))
                                  (eos/org-add-ids-to-headlines-in-file))))))
      #+END_SRC

**** Org babel languages
     :PROPERTIES:
     :CUSTOM_ID: User_Configuration-Org-mode-Org_babel_languages-c062fc16
     :END:
     One  of  the  amazing  features  of org-mode  is  its  literary  programming
     capacities by running code blocks from within Org-mode itself. But for that,
     only a  couple of languages are  supported directly by Org-mode  itself, and
     they need to be activated. Here are the languages I activated in my Org-mode
     configuration:
     #+BEGIN_SRC emacs-lisp
       (org-babel-do-load-languages
        'org-babel-load-languages
        '((C          . t)
          (dot        . t)
          (emacs-lisp . t)
          (gnuplot    . t)
          (latex      . t)
          (makefile   . t)
          (python     . t)
          (R          . t)
          (sass       . t)
          (scheme     . t)
          (shell      . t)))
     #+END_SRC

     Scheme requires a default implementation for geiser:
     #+BEGIN_SRC emacs-lisp
       (setq geiser-default-implementation 'racket)
     #+END_SRC

     By the  way, I wish  to see source  code behave the  same way in  the source
     blocks as in their own major mode. Let’s tell Emacs so:
     #+BEGIN_SRC emacs-lisp
       (setq org-src-tab-acts-natively t)
     #+END_SRC

**** Org variables
     :PROPERTIES:
     :CUSTOM_ID: User_Configuration-Org-mode-Org_variables-97587637
     :END:
***** User information
      :PROPERTIES:
      :CUSTOM_ID: User_Configuration-Org-mode-Org_variables-User_information-6c7d5e3f
      :END:
      Some  variables  about  myself  need  to be  set  so  Org-mode  knows  what
      information to include in exported files.
      #+BEGIN_SRC emacs-lisp
        (setq user-full-name "Lucien Cartier-Tilet"
              user-real-login-name "Lucien Cartier-Tilet"
              user-login-name "phundrak"
              user-mail-address "lucien@phundrak.com")
      #+END_SRC

***** Visual settings
      :PROPERTIES:
      :CUSTOM_ID: User_Configuration-Org-mode-Org_variables-Visual_settings-5d02f4c0
      :END:
      Visually, I prefer to hide the markers of macros, so let’s do that:
      #+BEGIN_SRC emacs-lisp
        (setq org-hide-macro-markers t)
      #+END_SRC

      I also have an issue where small dots precede my org headers. Let’s fix that:
      #+BEGIN_SRC emacs-lisp
        (setq org-hide-leading-stars nil
              org-superstar-leading-bullet ?\s)
      #+END_SRC

***** Org behavior
      :PROPERTIES:
      :CUSTOM_ID: User_Configuration-Org-mode-Org_variables-Org_behavior-0319db38
      :END:
      Here is one behavior that I really want to see modified: the ability to use
      ~M-RET~ without slicing the text the marker is on.
      #+BEGIN_SRC emacs-lisp
        (setq org-M-RET-may-split-line nil)
      #+END_SRC

      I also have added  a couple of custom structure templates  for Org mode (>=
      9.3), mainly for source code blocks.
      #+begin_src emacs-lisp
        (add-to-list 'org-structure-template-alist '("L" . "src emacs-lisp"))
      #+end_src

      Since Org 9.3,  Org no longer attempts to restore  the window configuration
      in the frame  to which the user  returns after editing a  source block with
      ~org-edit-src-code~.   This    means   with    the   original    value   of
      ~org-src-window-setup~  (~reorganize-frame~),  the  current frame  will  be
      split in  two between the  original org window  and the source  window, and
      once we quit the source window only the org window will remain. This is not
      a  desired  behavior   for  me,  so  I  chose  to   set  this  variable  to
      ~split-window-right~ in  order to keep  my windows organization and  have a
      similar behavior to the old one.
      #+BEGIN_SRC emacs-lisp
        (setq org-src-window-setup 'split-window-right)
        ;; (setq org-src-window-setup 'split-window-below)
      #+END_SRC

      However, it is not rare that I want to change that for an horizontal split,
      which can  be achieved  with the value  ~split-window-below~. Thus,  I have
      made this function that allows me  to switch between the (default) vertical
      split and the horizontal split.
      #+BEGIN_SRC emacs-lisp
        (defun phundrak/toggle-org-src-window-split ()
          "This function allows the user to toggle the behavior of
        `org-edit-src-code'. If the variable `org-src-window-setup' has
        the value `split-window-right', then it will be changed to
        `split-window-below'. Otherwise, it will be set back to
        `split-window-right'"
          (interactive)
          (if (equal org-src-window-setup 'split-window-right)
              (setq org-src-window-setup 'split-window-below)
            (setq org-src-window-setup 'split-window-right))
          (message "Org-src buffers will now split %s"
                   (if (equal org-src-window-setup 'split-window-right)
                       "vertically"
                     "horizontally")))
      #+END_SRC

      Lastly, I  know this  can be  a terrible idea,  but I  want Emacs  to just
      evaluate  Org  code  blocks  without  asking me.  Of  course,  this  could
      represent some  big security issue if  not careful enough, but  I generaly
      just open my own org files.
      #+BEGIN_SRC emacs-lisp
        (setq org-confirm-babel-evaluate nil)
      #+END_SRC

***** Miscellaneous
      :PROPERTIES:
      :CUSTOM_ID: User_Configuration-Org-mode-Org_variables-Miscellaneous-ddcb568a
      :END:
      When creating  a link to an  Org flie, I want  to create an ID  only if the
      link is  created interactively, and only  if there is no  custom ID already
      created.
      #+BEGIN_SRC emacs-lisp
        (setq org-id-link-to-org-use-id 'create-if-interactive-and-no-custom-id)
      #+END_SRC

**** Org files exports
     :PROPERTIES:
     :CUSTOM_ID: User_Configuration-Org-mode-Org_files_exports-1e194169
     :END:
     When it comes to  exports, I want the LaTeX and PDF exports  to be done with
     XeLaTeX only. This implies the modification of the following variable:
     #+BEGIN_SRC emacs-lisp
       (setq org-latex-compiler "xelatex")
     #+END_SRC

     I also  want to get  by default  ~minted~ for LaTeX  listings so I  can have
     syntax highlights:
     #+BEGIN_SRC emacs-lisp
       (setq org-latex-listings 'minted)
     #+END_SRC

     The default  packages break my LaTeX  exports: for some reasons,  images are
     not  loaded and  exported  in PDFs,  so  I needed  to  redifine the  default
     packages excluding the  one that broke my exports. I  also added two default
     packages, ~minted~  and ~xeCJK~  for syntax  highlighting and  Japanese (and
     additionally Chinese and Korean) support.
     #+BEGIN_SRC emacs-lisp
       (setq org-latex-default-packages-alist '((""         "graphicx"  t)
                                                ("T1"       "fontspec"  t ("pdflatex"))
                                                (""         "longtable" nil)
                                                (""         "wrapfig"   nil)
                                                (""         "rotating"  nil)
                                                ("normalem" "ulem"      t)
                                                (""         "amsmath"   t)
                                                (""         "textcomp"  t)
                                                (""         "amssymb"   t)
                                                (""         "capt-of"   nil)
                                                (""         "minted"    nil)
                                                (""         "xeCJK"     nil)
                                                (""         "hyperref"  nil)))
     #+END_SRC

     By the way, reference links in LaTeX should be written in this format:
     #+BEGIN_SRC emacs-lisp
       (setq org-export-latex-hyperref-format "\\ref{%s}")
     #+END_SRC

     When it  comes to the  export itself, the latex  file needs to  be processed
     several times through XeLaTeX.
     #+BEGIN_SRC emacs-lisp
       (setq org-latex-pdf-process
             '("xelatex -shell-escape -interaction nonstopmode -output-directory %o %f"
               "xelatex -shell-escape -interaction nonstopmode -output-directory %o %f"
               "xelatex -shell-escape -interaction nonstopmode -output-directory %o %f"))
     #+END_SRC

     For Reveal.JS exports, I need to set where to find the framework by default:
     #+BEGIN_SRC emacs-lisp
       (setq org-reveal-root "file:///home/phundrak/fromGIT/reveal.js")
     #+END_SRC

     I also  want to  disable by  default behavior of  ~^~ and  ~_~ for  only one
     character, making it compulsory to use instead ~^{}~ and ~_{}~ respectively.
     This is  due to my  frequent usage of  the underscore in  my org files  as a
     regular character and not a markup one. So, let’s disable it:
     #+BEGIN_SRC emacs-lisp
       (setq org-use-sub-superscripts (quote {}))
     #+END_SRC

     On  HTML exports,  Org-mode  tries  to include  a  validation  link for  the
     exported HTML. Let’s disable that since I never use it.
     #+BEGIN_SRC emacs-lisp
       (setq org-html-validation-link nil)
     #+END_SRC

**** Custom LaTeX formats
     :PROPERTIES:
     :CUSTOM_ID: User_Configuration-Org-mode-Custom_LaTeX_formats-8e8dca1c
     :END:
     I currently have two custom formats for my Org-mode exports: one for general
     use (initialy for my conlanging files, hence its ~conlang~ name), and one
     for beamer exports.

     Below is the declaration of the ~conlang~ LaTeX class:
     #+NAME: org-latex-class-conlang
     #+BEGIN_SRC emacs-lisp :tangle no
       '("conlang"
         "\\documentclass{book}"
         ("\\chapter{%s}" . "\\chapter*{%s}")
         ("\\section{%s}" . "\\section*{%s}")
         ("\\subsection{%s}" . "\\subsection*{%s}")
         ("\\subsubsection{%s}" . "\\subsubsection*{%s}"))
     #+END_SRC

     And here is the declaration of the ~beamer~ class:
     #+NAME: org-latex-class-beamer
     #+BEGIN_SRC emacs-lisp :tangle no
       `("beamer"
         ,(concat "\\documentclass[presentation]{beamer}\n"
                  "[DEFAULT-PACKAGES]"
                  "[PACKAGES]"
                  "[EXTRA]\n")
         ("\\section{%s}" . "\\section*{%s}")
         ("\\subsection{%s}" . "\\subsection*{%s}")
         ("\\subsubsection{%s}" . "\\subsubsection*{%s}"))
     #+END_SRC

     Both these classes have to be added to ~org-latex-classes~ like so:
     #+BEGIN_SRC emacs-lisp :noweb yes
       (eval-after-load "ox-latex"
         '(progn
            (add-to-list 'org-latex-classes
                         <<org-latex-class-conlang>>
                         )
            (add-to-list 'org-latex-classes
                         <<org-latex-class-beamer>>
                         )))
     #+END_SRC

**** Org agenda
     :PROPERTIES:
     :CUSTOM_ID: User_Configuration-Org-mode-Org_agenda-53f9d319
     :END:
     One awesome feature  of Org mode is  the agenda. By default,  my agendas are
     stored in =~/org/agenda=.
     #+BEGIN_SRC emacs-lisp
       (setq org-agenda-files (list "~/org/agenda" "~/org/notes.org"))
     #+END_SRC

     I also  have a  custom command  in Org agenda  to mark  some tasks  as daily
     tasks with the =:DAILY:= tag,:
     #+BEGIN_SRC emacs-lisp
       (setq org-agenda-custom-commands
             '(("h" "Daily habits"
                ((agenda ""))
                ((org-agenda-show-log t)
                 (org-agenda-ndays 7)
                 (org-agenda-log-mode-items '(state))
                 (org-agenda-skip-function
                  '(org-agenda-skip-entry-if 'notregexp
                                             ":DAILY:"))))
               ("Y" "Yearly events"
                ((agenda ""))
                ((org-agenda-show-log t)
                 (org-agenda-ndays 365)
                 (org-agenda-log-mode-items '(state))
                 (org-agenda-skip-entry-if 'notregexp
                                           ":YEARLY:")))))
     #+END_SRC

**** Org capture
     :PROPERTIES:
     :CUSTOM_ID: User_Configuration-Org-mode-Org_capture-f58979cf
     :END:
     Org-capture is  an amazing feature  of Org-mode  which allows me  to quickly
     save links, resources,  reminders, and notes in neatly  organized org files.
     Here they are described:
     #+BEGIN_SRC emacs-lisp
       (setq
        org-conlanging-file "~/org/conlanging.org"
        org-default-notes-file "~/org/notes.org"
        org-journal-file "~/org/journal.org"
        org-linguistics-notes-file "~/org/linguistics-notes.org"
        org-novel-notes-file "~/org/novel-notes.org"
        org-private-agenda-file "~/org/agenda/private.org"
        org-school-agenda-file "~/org/agenda/school.org"
        org-wordbuilding-file "~/org/worldbuilding.org")
     #+END_SRC

     With Spacemacs, an Org capture can be invoked with the shortcut ~SPC a o c~.
     It  will then  ask which  template I  wish to  use. In  the table  below are
     described the shortcuts that are available after ~SPC a o c~ is invoked. The
     /name/ will be the one displayed  in Org capture’s interface, the /title/ is
     the headline  where to  save the  capture (if  it does  not differ  from the
     capture’s name,  the cell will be  blank). The /insertion mode/  tells Emacs
     how to add the capture to the /file/, using which /template/. A line with no
     insertion mode, file,  or template is just a category.  All of the following
     insert entries to  their org files, that  is a new org node  with a headline
     and some content.
     #+NAME: org-capture-shortcuts-table
     | Shortcut | Name          | Title    | Insertion mode | file                    | template                 |
     |----------+---------------+----------+----------------+-------------------------+--------------------------|
     | e        | Email         |          |                |                         |                          |
     | ew       | Write Email   | Emails   | file+headline  | org-default-notes-file  | emails.orgcaptmpl        |
     | j        | Journal       |          | file+datetree  | org-journal-file        | journal.orgcaptmpl       |
     | l        | Link          |          |                |                         |                          |
     | ll       | General       |          | file+headline  | org-default-notes-file  |                          |
     | ly       | YouTube       |          | file+headline  | org-default-notes-file  | youtube.orgcaptmpl       |
     | L        | Protocol Link | Link     | file+headline  | org-default-notes-file  | protocol-link.orgcaptmpl |
     | n        | Notes         |          |                |                         |                          |
     | nc       | Conlanging    | Note     | file+headline  | org-conlanging-file     | notes.orgcaptmpl         |
     | nn       | General       |          | file+headline  | org-default-notes-file  | notes.orgcaptmpl         |
     | nN       | Novel         | Note     | file+headline  | org-novel-notes-file    | notes.orgcaptmpl         |
     | nq       | Quote         |          | file+headline  | org-default-notes-file  | notes-quote.orgcaptmpl   |
     | nw       | Worldbuilding | Note     | file+headline  | org-wordbuilding-file   | notes.orgcaptmpl         |
     | N        | Novel         |          |                |                         |                          |
     | Ni       | Ideas         |          | file+headline  | org-novel-notes-file    | notes.orgcaptmpl         |
     | p        | Protocol      | Link     | file+headline  | org-default-notes-file  | protocol.orgcaptmpl      |
     | r        | Resources     |          |                |                         |                          |
     | rc       | Conlanging    | Resource | file+headline  | org-conlanging-file     | resource.orgcaptmpl      |
     | re       | Emacs         |          | file+headline  | org-default-notes-file  | resource.orgcaptmpl      |
     | ri       | Informatique  |          | file+headline  | org-default-notes-file  | resource.orgcaptmpl      |
     | rl       | Linguistics   |          | file+headline  | org-default-notes-file  | resource.orgcaptmpl      |
     | rw       | Worldbuilding | Resource | file+headline  | org-wordbuilding-file   | resource.orgcaptmpl      |
     | t        | Tasks         |          |                |                         |                          |
     | tb       | Birthday      |          | file+headline  | org-private-agenda-file | birthday.orgcaptmpl      |
     | te       | Event         |          | file+headline  | org-private-agenda-file | event.orgcaptmpl         |
     | th       | Health        |          | file+headline  | org-private-agenda-file | health.orgcaptmpl        |
     | ti       | Informatique  |          | file+headline  | org-private-agenda-file | informatique.orgcaptmpl  |

     The following  code snipped is not  tangled into my configuration  file, but
     instead creates the equivalent to the  table above into EmacsLisp code found
     in the next code snippet.
     #+NAME: org-capture-shortcut-gen
     #+BEGIN_SRC emacs-lisp :tangle no :noweb yes :var table=org-capture-shortcuts-table :exports code :cache yes :results replace
       (mapconcat (lambda (entry)
                    (let* ((shortcut   (nth 0 entry))
                           (name       (nth 1 entry))
                           (title      (nth 2 entry))
                           (insertmode (nth 3 entry))
                           (fileinsert (nth 4 entry))
                           (sourceorg  (nth 5 entry)))
                      (if (string= "" insertmode)
                          (format "(\"%s\" \"%s\")" shortcut name)
                        (concat (format "(\"%s\" \"%s\" entry\n" shortcut name)
                                (format "  (%s %s%s)\n" insertmode fileinsert
                                        (if (string= "file+datetree" insertmode) ""
                                          (format " \"%s\"" (if (string= "" title) name title))))
                                (format "  (file \"~/org/capture/%s\"))" sourceorg)))) )
                  table "\n")
     #+END_SRC

     #+RESULTS[5826faa0521c58664ddeedcf44b88910dbd344b6]: org-capture-shortcut-gen
     #+begin_example
     ("e" "Email")
     ("ew" "Write Email" entry
       (file+headline org-default-notes-file "Emails")
       (file "~/org/capture/emails.orgcaptmpl"))
     ("j" "Journal" entry
       (file+datetree org-journal-file)
       (file "~/org/capture/journal.orgcaptmpl"))
     ("l" "Link")
     ("ll" "General" entry
       (file+headline org-default-notes-file "General")
       (file "~/org/capture/"))
     ("ly" "YouTube" entry
       (file+headline org-default-notes-file "YouTube")
       (file "~/org/capture/youtube.orgcaptmpl"))
     ("L" "Protocol Link" entry
       (file+headline org-default-notes-file "Link")
       (file "~/org/capture/protocol-link.orgcaptmpl"))
     ("n" "Notes")
     ("nc" "Conlanging" entry
       (file+headline org-conlanging-file "Note")
       (file "~/org/capture/notes.orgcaptmpl"))
     ("nn" "General" entry
       (file+headline org-default-notes-file "General")
       (file "~/org/capture/notes.orgcaptmpl"))
     ("nN" "Novel" entry
       (file+headline org-novel-notes-file "Note")
       (file "~/org/capture/notes.orgcaptmpl"))
     ("nq" "Quote" entry
       (file+headline org-default-notes-file "Quote")
       (file "~/org/capture/notes-quote.orgcaptmpl"))
     ("nw" "Worldbuilding" entry
       (file+headline org-wordbuilding-file "Note")
       (file "~/org/capture/notes.orgcaptmpl"))
     ("N" "Novel")
     ("Ni" "Ideas" entry
       (file+headline org-novel-notes-file "Ideas")
       (file "~/org/capture/notes.orgcaptmpl"))
     ("p" "Protocol" entry
       (file+headline org-default-notes-file "Link")
       (file "~/org/capture/protocol.orgcaptmpl"))
     ("r" "Resources")
     ("rc" "Conlanging" entry
       (file+headline org-conlanging-file "Resource")
       (file "~/org/capture/resource.orgcaptmpl"))
     ("re" "Emacs" entry
       (file+headline org-default-notes-file "Emacs")
       (file "~/org/capture/resource.orgcaptmpl"))
     ("ri" "Informatique" entry
       (file+headline org-default-notes-file "Informatique")
       (file "~/org/capture/resource.orgcaptmpl"))
     ("rl" "Linguistics" entry
       (file+headline org-default-notes-file "Linguistics")
       (file "~/org/capture/resource.orgcaptmpl"))
     ("rw" "Worldbuilding" entry
       (file+headline org-wordbuilding-file "Resource")
       (file "~/org/capture/resource.orgcaptmpl"))
     ("t" "Tasks")
     ("tb" "Birthday" entry
       (file+headline org-private-agenda-file "Birthday")
       (file "~/org/capture/birthday.orgcaptmpl"))
     ("te" "Event" entry
       (file+headline org-private-agenda-file "Event")
       (file "~/org/capture/event.orgcaptmpl"))
     ("th" "Health" entry
       (file+headline org-private-agenda-file "Health")
       (file "~/org/capture/health.orgcaptmpl"))
     ("ti" "Informatique" entry
       (file+headline org-private-agenda-file "Informatique")
       (file "~/org/capture/informatique.orgcaptmpl"))
     #+end_example

     Below you can find the equivalent code as described above.
     #+BEGIN_SRC emacs-lisp :noweb yes
       (setq
        org-capture-templates
        '(
          <<org-capture-shortcut-gen()>>
          ))
     #+END_SRC

     You may notice a capture entry for my journal, and this is due to the fact I
     do  not use  ~org-journal~ anymore:  it was  too overpowered  for me,  and I
     prefer to keep it simple with a single  file. And as you can see, and unlike
     a lot of other Emacs configurations, the  content of the template is not set
     in  the variable,  but in  external files  which can  be modified  freely as
     actual Org buffers instead of trying to  get a proper one with loads of ~\n~
     characters and such. All these templates are declared below.

     In the next  sub-sections will be described my org  capture templates. These
     are  not  tangled into  my  Emacs  configuration  files, but  into  separate
     ~.orgcaptmpl~ files stored into =~/org/capture/=.

***** Emails
      :PROPERTIES:
      :CUSTOM_ID: User_Configuration-Org-mode-Org_capture-Emails-d87336fe
      :END:
      This is my template for a new Email:
      #+BEGIN_SRC org :mkdir yes :tangle ~/org/capture/email.orgcaptmpl
        ,** TODO [#A] Write Email
           SCHEDULED: %^t
           :PROPERTIES:
           :CAPTURED: %U
           :END:
        From: Lucien Cartier-Tilet <lucien@phundrak.com>
        To: %^{Recipient}
        Subject: %^{Object}
        --text follows this line--
        %?
        --
        Lucien “Phundrak” Cartier-Tilet
        https://phundrak.com (Français)
        https://en.phundrak.com (English)

        Sent from a Free and Open-Source Linux operating system with GNU/Emacs
      #+END_SRC

      I use  it in case my  computer is not yet  connected to the internet  and I
      need to already write the email so I  can send it later. All I will need to
      to afterwards will be to copy and  paste my capture in a new message buffer
      and   send   it   once   I   am  back   online.   This   is   exported   to
      =~/org/capture/email.orgcaptmpl=.

***** Journal
      :PROPERTIES:
      :CUSTOM_ID: User_Configuration-Org-mode-Org_capture-Journal-9916f9bf
      :END:
      This template  is quite  simple: it  creates a new  entry with  the current
      timestamp as its title, a brief title  of my choosing, and then I can write
      whatever     I     wish    to     write.     This     is    exported     to
      =~/org/capture/journal.orgcaptmpl=.
      #+BEGIN_SRC org :mkdir yes :tangle ~/org/capture/journal.orgcaptmpl
        ,* %U %^{Title}
          %?
      #+END_SRC

***** Notes
      :PROPERTIES:
      :CUSTOM_ID: User_Configuration-Org-mode-Org_capture-Notes-4b4c10aa
      :END:
      This template  is used for taking  note about various subjects  that can go
      from conlanging to  development. I wrote it  so I can know  from where this
      capture was made  and when, and it even supports  text that was highlighted
      in  Emacs that  will be  inserted in  a quote  block. This  is exported  to
      =~/org/capture/notes.orgcaptmpl=.
      #+BEGIN_SRC org :mkdir yes :tangle ~/org/capture/notes.orgcaptmpl
        ,* %^{Title}
          :PROPERTIES:
          :CAPTURED: %U
          :END:
          %?
      #+END_SRC


      #+BEGIN_SRC org :mkdir yes :tangle ~/org/capture/notes-quote.orgcaptmpl
        ,* %^{Title}
          :PROPERTIES:
          :CAPTURED: %U
          :END:
          Possible inspiration:
          ,#+begin_quote
          %i
          ,#+end_quote

          %?
      #+END_SRC

***** Protocol
      :PROPERTIES:
      :CUSTOM_ID: User_Configuration-Org-mode-Org_capture-Protocol-ec45ec49
      :END:
      This  capture  is  used  when   received  through  org-protocol,  with  the
      Org-protocol Extension for  Firefox. It allows me to save  in a quote block
      what I’ve highlighted, as well as the link of the webpage on which my saved
      content     was    highlighted.     This     file     is    exported     to
      =~/org/capture/protocol.orgcaptmpl=.
      #+BEGIN_SRC org :mkdir yes :tangle ~/org/capture/protocol.orgcaptmpl
        ,* TODO [#C] %^{Title}
          :PROPERTIES:
          :CAPTURED: %U
          :LINK:     %:link
          :TITLE:    %:description
          :END:
          ,#+begin_quote
          %i
          ,#+end_quote

          %?
      #+END_SRC

      This next capture template is used only when a link is sent to Emacs and no
      content was highlighted.
      #+BEGIN_SRC org :mkdir yes :tangle ~/org/capture/protocol-link.orgcaptmpl
        ,* TODO [#C] Link: %^{Title}
          :PROPERTIES:
          :CAPTURED: %U
          :LINK:     %:link
          :TITLE:    %:description
          :END:
          %?
      #+END_SRC

***** Resources
      :PROPERTIES:
      :CUSTOM_ID: User_Configuration-Org-mode-Org_capture-Resources-b23bfbd0
      :END:
      This is the default template for  resources, which generally are located on
      the Internet. By default, I give them the lowest priority, because although
      this is something for me to remember later, it is not by default important.
      You can see in the properties I  record when the capture happened, and what
      the link is. The  title of the capture is a summary of  what this is, while
      the body of the  capture is a more detailed explanation  of what I capture,
      why, and how it could be useful to me.
      #+BEGIN_SRC org :mkdir yes :tangle ~/org/capture/resource.orgcaptmpl
        ,* TODO [#C] %^{Title}
          :PROPERTIES:
          :CAPTURED: %U
          :LINK:     %^{Link}
          :END:
          %?
      #+END_SRC

***** Tasks
      :PROPERTIES:
      :CUSTOM_ID: User_Configuration-Org-mode-Org_capture-Tasks-3fcf382a
      :END:

****** Computers and stuff
       :PROPERTIES:
       :CUSTOM_ID: User_Configuration-Org-mode-Org_capture-Tasks-Computers_and_stuff-a4eef8e3
       :END:
       One type of task  I often capture is related to my  servers or thing about
       computers in  general. With this,  I can capture a  task for which  I will
       either set a schedule or a deadline.
       #+BEGIN_SRC org :mkdir yes :tangle ~/org/capture/informatique.orgcaptmpl
         ,* TODO %^{Title}
           %^{Scheduled or Deadline?||SCHEDULED||DEADLINE}: %^t
           :PROPERTIES:
           :CATEGORY: %^{Category}
           :END:
           %?
       #+END_SRC

****** Health
       :PROPERTIES:
       :CUSTOM_ID: User_Configuration-Org-mode-Org_capture-Tasks-Health-74f8f338
       :END:
       This capture is rarely used (I’m lucky to have a good health), but it can
       be useful.
       #+BEGIN_SRC org :mkdir yes :tangle ~/org/capture/health.orgcaptmpl
         ,* %^{Title}
           SCHEDULED: %^t

           %?
       #+END_SRC

****** Birthdays
       :PROPERTIES:
       :CUSTOM_ID: User_Configuration-Org-mode-Org_capture-Tasks-Birthdays-ec3b27be
       :END:
       This capture is used  to store new birthdays I have  to remember. They are
       set to be repeated yearly.
       #+BEGIN_SRC org :mkdir yes :tangle ~/org/capture/birthday.orgcaptmpl
         ,* %^{Name}
           SCHEDULED: %^t
       #+END_SRC

****** Events
       :PROPERTIES:
       :CUSTOM_ID: User_Configuration-Org-mode-Org_capture-Tasks-Events-7f0f8dee
       :END:
       #+BEGIN_SRC org :mkdir yes :tangle ~/org/capture/event.orgcaptmpl
         ,* %^{Title}
           %^{Scheduled or deadline?||SCHEDULED||DEADLINE}: %^t
           %?
       #+END_SRC

***** Links
      :PROPERTIES:
      :CUSTOM_ID: User_Configuration-Org-mode-Org_capture-Links-586a6b2a
      :END:
****** General
       :PROPERTIES:
       :CUSTOM_ID: User_Configuration-Org-mode-Org_capture-Links-General-1f0732db
       :END:
       #+BEGIN_SRC org :mkdir yes :tangle ~/org/capture/link.orgcaptmpl
         ,* TODO [#C] %^{Title}
           :PROPERTIES:
           :CAPTURED: %U
           :LINK:     %^{Link}
           :END:
           %?
       #+END_SRC

****** YouTube
       :PROPERTIES:
       :CUSTOM_ID: User_Configuration-Org-mode-Org_capture-Links-YouTube-b89fe20e
       :END:
       #+BEGIN_SRC org :mkdir yes :tangle ~/org/capture/youtube.orgcaptmpl
         ,* TODO [#C] %^{Title}
           :PROPERTIES:
           :CAPTURED: %U
           :AUTHOR:   %^{Author}
           :LINK:     %^{Link}
           :END:
           %?
       #+END_SRC

**** Org projects
     :PROPERTIES:
     :CUSTOM_ID: User_Configuration-Org-mode-Org_projects-5be088cd
     :END:
     Another great features  of Org-mode is the Org projects  that allow the user
     to easily  publish a bunch of  org files to  a remote location. Here  is the
     current declaration of my projects, which will be detailed later:
     #+BEGIN_SRC emacs-lisp :noweb yes
       (setq org-publish-project-alist
             '(
               <<org-proj-config-html>>
               <<org-proj-config-static>>
               <<org-proj-config>>
               <<org-proj-lang-html>>
               <<org-proj-lang-pdf>>
               <<org-proj-lang-static>>
               <<org-proj-lang>>))
     #+END_SRC

***** Configuration website
      :PROPERTIES:
      :CUSTOM_ID: User_Configuration-Org-mode-Org_projects-Configuration_website-79bd0468
      :END:
      #+NAME: org-proj-config-html
      #+BEGIN_SRC emacs-lisp :tangle no
        ("config-website-org"
         :base-directory "~/org/config/"
         :base-extension "org"
         :exclude "\\./\\(CONTRIB\\|head\\|temp\\|svg-ink\\).*"
         :publishing-directory "/ssh:Tilo:~/www/phundrak.com/config"
         :recursive t
         :language "en"
         :publishing-function org-html-publish-to-html
         :headline-levels 5
         :auto-sitemap t
         :auto-preamble t)
      #+END_SRC

      And lastly, we  have the component for  all the static files  needed to run
      the website:
      #+NAME: org-proj-config-static
      #+BEGIN_SRC emacs-lisp :tangle no
        ("config-website-static"
         :base-directory "~/org/config/"
         :base-extension "png\\|jpg\\|gif\\|webp\\|svg\\|jpeg\\|ttf\\|woff\\|txt\\|epub\\|md"
         :publishing-directory "/ssh:Tilo:~/www/phundrak.com/config"
         :recursive t
         :language "en"
         :publishing-function org-publish-attachment)
      #+END_SRC

      The project is then defined like so:
      #+NAME: org-proj-config
      #+BEGIN_SRC emacs-lisp :tangle no
        ("config-website"
         :components ("config-website-org"
                      "config-website-static"))
      #+END_SRC

***** Linguistics website
      :PROPERTIES:
      :CUSTOM_ID: User_Configuration-Org-mode-Org_projects-Linguistics_website-34b8d4e7
      :END:
      In my case, I only have my linguistics website, made out of three projects.
      The  first component  is the  one generating  the HTML  files from  the org
      files.
      #+NAME: org-proj-lang-html
      #+BEGIN_SRC emacs-lisp :tangle no
        ("langue-phundrak-com-org"
         :base-directory "~/Documents/conlanging/content/"
         :base-extension "org"
         :exclude "\\./\\(CONTRIB\\|README\\|head\\|temp\\|svg-ink\\).*"
         :publishing-directory "/ssh:Tilo:~/www/phundrak.com/langue/"
         :recursive t
         :language "fr"
         :publishing-function org-html-publish-to-html
         :headline-levels 5
         :auto-sitemap t
         :auto-preamble t)
      #+END_SRC

      We also have the component for the LaTeX and PDF part of the website:
      #+NAME: org-proj-lang-pdf
      #+BEGIN_SRC emacs-lisp :tangle no
        ("langue-phundrak-com-pdf"
         :base-directory "~/Documents/conlanging/content/"
         :base-extension "org"
         :exclude "\\./\\(CONTRIB\\|README\\|index\\|head\\|temp\\|svg-ink\\).*"
         :publishing-directory "/ssh:Tilo:~/www/phundrak.com/langue/"
         :recursive t
         :language "fr"
         :publishing-function org-latex-publish-to-pdf
         :headline-levels 5
         :auto-preamble t)
      #+END_SRC

      And lastly, we  have the component for  all the static files  needed to run
      the website:
      #+NAME: org-proj-lang-static
      #+BEGIN_SRC emacs-lisp :tangle no
        ("langue-phundrak-com-static"
         :base-directory "~/Documents/conlanging/content/"
         :base-extension "png\\|jpg\\|gif\\|webp\\|svg\\|jpeg\\|ttf\\|woff\\|txt\\|epub"
         :publishing-directory "/ssh:Tilo:~/www/phundrak.com/langue/"
         :recursive t
         :language "fr"
         :publishing-function org-publish-attachment)
      #+END_SRC

      The project is then defined like so:
      #+NAME: org-proj-lang
      #+BEGIN_SRC emacs-lisp :tangle no
        ("langue-phundrak-com"
         :components ("langue-phundrak-com-org"
                      "langue-phundrak-com-static"
                      "langue-phundrak-com-pdf"))
      #+END_SRC

  # Don’t delete this, this code block is here to wrap the org configuration
  #+BEGIN_SRC emacs-lisp :exports none
      )
  #+END_SRC

** Editing and modes
   :PROPERTIES:
   :CUSTOM_ID: User_Configuration-Editing_and_modes-7dbaf258
   :END:
*** Default modes
    :PROPERTIES:
    :CUSTOM_ID: User_Configuration-Editing_and_modes-Default_modes-50d4e086
    :END:
    :CUSTOM_ID: User_Configuration-Miscellaneous-Default_modes-b9e1522c
    :END:
    Some  buffers sometimes  won’t  have a  default  mode at  all,  such as  the
    ~*scratch*~ buffer. In any vanilla  configuration, they will then default to
    ~text-mode~. I personally prefer ~org-mode~ to  be my default mode, so let’s
    set it so!
    #+BEGIN_SRC emacs-lisp
      (setq edit-server-default-major-mode 'org-mode)
    #+END_SRC

*** Evil
    :PROPERTIES:
    :CUSTOM_ID: User_Configuration-Editing_and_modes-Evil-3cedaaee
    :END:
    :CUSTOM_ID: User_Configuration-Miscellaneous-Evil-ab8a36e3
    :END:
    As a user of Evil, I’m sometimes  pissed when I accidentally press ~C-u~ and
    it gets me to the top of the document. So, let’s disable it:
    #+BEGIN_SRC emacs-lisp
      (setq evil-want-C-u-scroll nil)
    #+END_SRC

*** File extensions
    :PROPERTIES:
    :CUSTOM_ID: User_Configuration-File_extensions-f76fe752
    :END:
    Sometimes,  Emacs   doesn’t  recognize  or  misrecognizes   some  extensions,
    resulting in a  wrong mode set for  said file. Let’s fix  that by associating
    the extension with the desired mode:
    #+BEGIN_SRC emacs-lisp
      (dolist (e '(("xml" . web-mode)
                   ("xinp" . web-mode)
                   ("aiml" . web-mode)
                   ("C" . c++-mode)
                   ("dconf" . conf-mode)
                   ("yy" . bison-mode)
                   ("ll" . flex-mode)
                   ("s" . asm-mode)
                   ("pl" . prolog-mode)
                   ("l" . scheme-mode)
                   ("vs" . glsl-mode)
                   ("fs" . glsl-mode)))
        (push (cons (concat "\\."
                            (car e)
                            "\\'") (cdr e))
              auto-mode-alist))
    #+END_SRC

    We also have a couple of  extensions which should all be in ~conf-unix-mode~,
    let’s indicate that to Emacs:
    #+BEGIN_SRC emacs-lisp
      (dolist (e '("service" "timer" "target" "mount" "automount"
                   "slice" "socket" "path" "netdev" "network"
                   "link"))
        (push (cons (concat "\\." e "\\'") 'conf-unix-mode)
              auto-mode-alist))
    #+END_SRC

*** Hooks
    :PROPERTIES:
    :CUSTOM_ID: User_Configuration-Miscellaneous-Hooks-86da2da0
    :END:
    I also have  some hooks I use  for enabling some major and  minor modes. The
    first one here  allows the execution of the deletion  of trailing space each
    time I save a file.
    #+BEGIN_SRC emacs-lisp
      (add-hook 'before-save-hook 'delete-trailing-whitespace)
    #+END_SRC

    I also  want to always  be in  ~visual-line-mode~ so Emacs  soft-wraps lines
    that are too  long for the buffer  they are displayed in. This  will also be
    enabled for Elfeed.
    #+BEGIN_SRC emacs-lisp
      (add-hook 'prog-mode-hook 'visual-line-mode)
      (add-hook 'elfeed-read-mode-hook 'visual-line-mode)
    #+END_SRC

    I also want  for some non-programming modes to enable  a hard-limit in terms
    of how many characters can fit on one line. The modes that benefit from that
    are ~message-mode~, ~org-mode~, ~text-mode~ and ~markdown-mode~.
    #+BEGIN_SRC emacs-lisp
      (mapc (lambda (x)
           (add-hook x 'auto-fill-mode)
           (add-hook x 'visual-line-mode))
         '(message-mode-hook
           org-mode-hook
           text-mode-hook
           markdown-mode-hook))
    #+END_SRC

*** Twittering mode
    :PROPERTIES:
    :CUSTOM_ID: User_Configuration-Miscellaneous-Twittering_mode-b97d9327
    :END:
    For ~twittering-mode~, a Twitter major mode  for Emacs, I want to encrypt my
    data using a master password, which I do thanks to this option:
    #+BEGIN_SRC emacs-lisp
      (setq twittering-use-master-password t)
    #+END_SRC

*** Wrapping regions
    :PROPERTIES:
    :CUSTOM_ID: User_Configuration-Editing_and_modes-Wrapping_regions-2250281e
    :END:
    I really  like the ~M-(~ keybinding  for wrapping a selected  region between
    parenthesis.  However,   parenthesis  are  not  everything   (even  in  Lisp
    dialects), and other wrappers could be nice. And they are! Here is how they
    are declared:
    #+BEGIN_SRC emacs-lisp
      (global-set-key (kbd "M-[") 'insert-pair)
      (global-set-key (kbd "M-{") 'insert-pair)
      (global-set-key (kbd "M-<") 'insert-pair)
      (global-set-key (kbd "M-'") 'insert-pair)
      (global-set-key (kbd "M-`") 'insert-pair)
      (global-set-key (kbd "M-\"") 'insert-pair)
    #+END_SRC

    For the record, this is from [[http://www.howardism.org/][Howard Abram]]’s [[https://github.com/howardabrams/dot-files][dotfiles]].

** Keybindings
   :PROPERTIES:
   :CUSTOM_ID: User_Configuration-Shortcuts-aef3f7a7
   :END:
   As you  will see,  I defined  a LOT of  custom keybindings.  All of  them are
   Spacemacs keybindings,  defined in  a way  they can  be used  seamlessly with
   Evil.  They  almost all  begin  with  ~o~, which  is  a  prefix reserved  for
   user-defined  keybindings so  they  won’t conflict  with  any package.  Let’s
   declare it like so.
   #+BEGIN_SRC emacs-lisp
     (spacemacs/declare-prefix "o" "custom")
   #+END_SRC

   Now, all keybindings that will be  defined can be invoked in Normal-mode with
   the ~SPC~ key followed by the sequence assigned to each keybinding.

   Before some more specialized categories, I  have two commands which don’t fit
   into any other category  that I sometime use. The first one is  a fix for the
   Bépo keybindings which left out a keybind: ~winum-select-window-by-number~ is
   still bound  to ~SPC ²~,  which is not  a key that  is available on  the bépo
   layout (instead, we use the dead key  ~^~ followed by ~2~, or any digits). So
   instead, let’s use the key that is physically in the same place: ~$~.
   #+BEGIN_SRC emacs-lisp
     (spacemacs/declare-prefix "$" "select window by number")
     (spacemacs/set-leader-keys "$"  'winum-select-window-by-number)
   #+END_SRC

   The following, I use it rarely, it  can launch an external command from Emacs
   to launch, for instance, my web browser  or any other software not related to
   Emacs. It offers a similar interface to [[https://wiki.archlinux.org/index.php/Dmenu][dmenu]] through helm.
   #+BEGIN_SRC emacs-lisp
     (spacemacs/declare-prefix "or" "external command")
     (spacemacs/set-leader-keys "or" 'helm-run-external-command)
   #+END_SRC

*** Applications
    :PROPERTIES:
    :CUSTOM_ID: User_Configuration-Shortcuts-Applications-af8730b1
    :END:
    As this is a new category, let’s declare its prefix:
    #+BEGIN_SRC emacs-lisp
      (spacemacs/declare-prefix "oa" "applications")
    #+END_SRC

    Now, let’s also declare the keybindings  in this category. ~oac~ will invoke
    Emacs’ calculator, while  ~oac~ invokes the calendar, ~oae~  invokes the Eww
    navigator and ~oaw~ invokes the weather forecast.
    #+BEGIN_SRC emacs-lisp
      (spacemacs/set-leader-keys
        "oac" 'calc
        "oaC" 'calendar
        "oae" 'eww
        "oaw" 'wttrin)
    #+END_SRC

**** Org tree slide
     :PROPERTIES:
     :CUSTOM_ID: User_Configuration-Keybindings-Applications-Org_tree_slide-29545c5e
     :END:
     Finally, here we have the  keybindings for ~org-tree-slide~, a presentation
     mode with orgmode. Since I want  the keys to be directly accessible without
     any prefix from Spacemacs, I’ll have to declare them the vanilla way. First
     we have keybindings that will launch the presentation:
     #+BEGIN_SRC emacs-lisp
       (define-key org-mode-map (kbd "<f8>") 'org-tree-slide-mode)
       (define-key org-mode-map (kbd "s-<f8>") 'org-tree-slide-skip-done-toggle)
     #+END_SRC

     Next, we have some additional keybindings  that will only be active when in
     ~org-tree-slide-mode~. The first one will allow us to exit this mode, while
     the second one  will toggle the display of headers  marked as ~DONE~. Next,
     we have  ~F9~ and  ~F10~ which are  bound to movement  in the  slide, while
     ~F11~   changes  the   way  the   content   is  displayed.   We  also   set
     ~org-tree-slide-skip-outline-level~  to  set  the  maximum  depth  we  will
     display as an individual heading during the presentation.
     #+BEGIN_SRC emacs-lisp
       (when (require 'org-tree-slide nil t)
         (global-set-key (kbd "<f8>") 'org-tree-slide-mode)
         (global-set-key (kbd "S-<f8>") 'org-tree-slide-skip-done-toggle)
         (define-key org-tree-slide-mode-map (kbd "<f9>")
           'org-tree-slide-move-previous-tree)
         (define-key org-tree-slide-mode-map (kbd "<f10>")
           'org-tree-slide-move-next-tree)
         (define-key org-tree-slide-mode-map (kbd "<f11>")
           'org-tree-slide-content)
         (setq org-tree-slide-skip-outline-level 4)
         (org-tree-slide-narrowing-control-profile)
         (setq org-tree-slide-skip-done nil))
     #+END_SRC

*** Comments
    :PROPERTIES:
    :CUSTOM_ID: User_Configuration-Shortcuts-Comments-508db33d
    :END:
    Some  keybindings are  also related  to comment  editing, in  particular using
    outorg. Let’s first declare the dedicated prefix:
    #+BEGIN_SRC emacs-lisp
      (spacemacs/declare-prefix "oc" "comments")
    #+END_SRC

    Now, let’s declare the following keybindings:
    #+BEGIN_SRC emacs-lisp
      (spacemacs/set-leader-keys
        "occ" 'outorg-copy-edits-and-exit
        "oce" 'outorg-edit-as-org
        "oco" 'outline-minor-mode)
    #+END_SRC

    ~oco~ enables the  outline minor mode, which then allows  for the edition of
    comments in  org buffers with ~oce~  and saving them to  the original source
    file with ~occ~.

*** Files
    :PROPERTIES:
    :CUSTOM_ID: User_Configuration-Shortcuts-Files-206c2126
    :END:
    There are lots of  files which I want to be able to  quickly open. I used to
    have one shortcut for  each one of these files, but as  their number grew, I
    decided to switch to helm for my  file selector which will be called by only
    one common shortcut. Most of my files will be located in =~/org=, but I have
    some conlanging files which are located in =~/Documents/conlanging=, and all
    my  university notes  are in  =~/Documents/university=. Let’s  declare these
    directories in a variable:
    #+BEGIN_SRC emacs-lisp
      (setq phundrak/org-directories '("~/org"
                                       "~/Documents/university"
                                       "~/Documents/conlanging"))
    #+END_SRC

    With this established, let’s write some emacs-lisp that will allow me to get
    a list of all these files and select them through helm. Be aware that I will
    be using some functions from third party packages, such as [[https://github.com/rejeep/f.el][f.el]] and [[https://github.com/magnars/dash.el][dash]].
    #+BEGIN_SRC emacs-lisp
      (spacemacs/declare-prefix "of" "open org file")
      (spacemacs/set-leader-keys
        "of"
        (lambda ()
          (interactive)
          (find-file
           (helm
            :sources (helm-build-sync-source "org files"
                       :candidates (-mapcat
                                    (lambda (path)
                                      (f-files path
                                               (lambda (file) (equal (f-ext file) "org"))
                                               t))
                                    phundrak/org-directories)
                       :fuzzy-match t)
            :buffer "*org files*"))))
    #+END_SRC

    And that’s it! This should list all my org files under these directories and
    give me  fuzzy finding for  these files. I just  need to partially  type the
    name of the file I want to open and it should open without any issue.

*** Multiple cursors
    :PROPERTIES:
    :CUSTOM_ID: User_Configuration-Shortcuts-Multiple_cursors-83db7c9c
    :END:
    I don’t  really like Spacemacs’  layer for  MultipleCursors, so I  prefer to
    simply install the  package and create shortcuts for it  myself. Let’s first
    declare category:
    #+BEGIN_SRC emacs-lisp
     (spacemacs/declare-prefix "om" "multiple-cursors")
    #+END_SRC

    Now, let’s declare the shortcuts related to multiple-cursors:
    #+BEGIN_SRC emacs-lisp
      (spacemacs/set-leader-keys
        "ome" 'mc/edit-lines
        "omn" 'mc/mark-next-like-this
        "omp" 'mc/mark-previous-like-this
        "oma" 'mc/mark-all-like-this)
    #+END_SRC

*** Org-mode
    :PROPERTIES:
    :CUSTOM_ID: User_Configuration-Shortcuts-Org-mode-a8938199
    :END:
    Now, onto some shortcuts related to org-mode. Let’s first declare the
    category:
    #+BEGIN_SRC emacs-lisp
      (spacemacs/declare-prefix-for-mode 'org-mode "mo" "custom" "User-defined keybindings")
      (spacemacs/declare-prefix-for-mode 'org-mode "mot" "toggle" "Toggle org elements")
      (spacemacs/declare-prefix-for-mode 'org-mode "moT" "tables")
    #+END_SRC

    Now, I have a couple of shortcuts I use regularly:
    #+BEGIN_SRC emacs-lisp
      (spacemacs/set-leader-keys-for-major-mode 'org-mode
        "os" 'org-insert-structure-template
        "ots" 'phundrak/toggle-org-src-window-split
        "ott" 'org-sidebar-tree)
      (spacemacs/declare-prefix-for-mode 'org-mode "moS" "insert template")
      (spacemacs/declare-prefix-for-mode 'org-mode "mots" "toggle src split")
    #+END_SRC

    ~os~   allows  me   to  insert   an  org   structure  template   defined  in
    ~org-structure-template-alist~ (see [[#User_Configuration-Org-mode-Org_variables-Org_behavior-0319db38][Org behavior]]),  while ~ott~ displays the
    outline of the current org file.

    ~oT~ is the prefix for tree-related operations:
    #+BEGIN_SRC emacs-lisp
      (spacemacs/declare-prefix-for-mode 'org-mode "moT" "tables")
    #+END_SRC

    These shortcuts  allow to manipulate the  width of the column  the cursor is
    currently in,  by either shrinking it,  expanding it, or toggling  its state
    between shrunk or expanded. A prefix for all of these commands has been also
    added in order to make the purpose of the shortcuts clearer.
    #+BEGIN_SRC emacs-lisp
      (spacemacs/set-leader-keys-for-major-mode 'org-mode
        "oTt" 'org-table-toggle-column-width
        "oTe" 'org-table-expand
        "oTs" 'org-table-shrink)
      (spacemacs/declare-prefix-for-mode 'org-mode "moTt" "toggle width")
      (spacemacs/declare-prefix-for-mode 'org-mode "moTe" "expand")
      (spacemacs/declare-prefix-for-mode 'org-mode "moTs" "shrink")
    #+END_SRC

    Finaly, I  set the following  shortcut in  order to easily  remove ~RESULTS~
    blocks from org source code blocks:
    #+BEGIN_SRC emacs-lisp
      (spacemacs/set-leader-keys-for-major-mode 'org-mode
        "or" 'org-babel-remove-result-one-or-many)
      (spacemacs/declare-prefix-for-mode 'org-mode "mor" "remove org result")
    #+END_SRC

*** Toggle
    :PROPERTIES:
    :CUSTOM_ID: User_Configuration-Shortcuts-Toggle-d53c27ef
    :END:
    This category allows to toggle some modes and options.
    #+BEGIN_SRC emacs-lisp
     (spacemacs/declare-prefix "ot" "toggle")
    #+END_SRC

    As you can see, I have here four shortcuts for toggling various elements in
    Emacs:
    - ~otb~ :: toggles ~fancy-battery-mode~. This comes  in very handy when I am
      on a laptop that is not pluged in or which is charging.
    - ~otd~ :: toggles ~elcord-mode~. This mode  is used to create an Emacs rich
      integration in Discord.
    - ~otf~ :: toggles  the activation of FlyCheck, Emacs’ spell  checker. It is
      by default  disabled, and I  can turn it on  with this shortcut  only when
      needed.
    - ~ots~  :: toggles  ~prettify-symbols-mode~. This  allows Emacs  to replace
      some symbols  by some others,  like for  example by replacing  ~lambda~ in
      Emacs Lisp buffers with an actual λ.
    #+BEGIN_SRC emacs-lisp
      (spacemacs/set-leader-keys
        "otb" 'fancy-battery-mode
        "otd" 'elcord-mode
        "otf" 'flycheck-mode
        "ots" 'prettify-symbols-mode)
    #+END_SRC

    We also have some input  methods-related shortcuts in a sub-category: ~oti~.
    The first shortcuts below are used  to either toggle between no input method
    or the last one  used (~otit~), or choose an input  method among the various
    available ones from Emacs (~otis~).
    #+BEGIN_SRC emacs-lisp
      (spacemacs/declare-prefix "oti" "input methods")
      (spacemacs/set-leader-keys
        "otit"  'toggle-input-method
        "otis"  'set-input-method)
    #+END_SRC

    The shortcuts below though allow me to directly switch to one of these three
    known input methods  I sometimes or often use, namely  Japanese, Tibetan and
    IPA (by typing in X-SAMPA).
    #+BEGIN_SRC emacs-lisp
      (spacemacs/declare-prefix "otij" "Japanese")
      (spacemacs/declare-prefix "otix" "IPA (X-SAMPA)")
      (spacemacs/declare-prefix "otiT" "Tibetan")
      (spacemacs/set-leader-keys
        "otij" (lambda () (interactive) (set-input-method 'japanese))
        "otix" (lambda () (interactive) (set-input-method 'ipa-x-sampa))
        "otiT" (lambda () (interactive) (set-input-method 'tibetan-wylie)))
    #+END_SRC

*** Text
    :PROPERTIES:
    :CUSTOM_ID: User_Configuration-Shortcuts-Text-8d877c4b
    :END:
    The last category is a text-related category. Let’s declare it:
    #+BEGIN_SRC emacs-lisp
     (spacemacs/declare-prefix "ox" "text")
    #+END_SRC

    The only command for now is a command  that allows the use of ~C-u M-q~ with
    the simple shortcut ~oxf~:
    #+BEGIN_SRC emacs-lisp
      (spacemacs/set-leader-keys "oxf" 'phundrak/fill-paragraph)
    #+END_SRC

** Mu4e
   :PROPERTIES:
   :CUSTOM_ID: User_Configuration-Mu4e-f3df8e9e
   :END:
   Mu4e is a frontend  for mu, an email analyzer which sits on  top of a Maildir
   which gets updated  with the ~mbsync~ command  from ~isync~. It has  a lot of
   neat features, but I guess my favorite ones are:
   1. the search query feature
   2. being able to send an HTML email either to the browser

   Due to mu sitting on top of a Maildir, I need to tell mu4e where said maildir
   is, and point it the trash, archive,  and sent folders as well as the refresh
   command and how frequently I want my emails to be refreshed.
   #+BEGIN_SRC emacs-lisp
     (setq mu4e-maildir "~/.mail"
           mu4e-trash-folder "/Trash"
           mu4e-refile-folder "/Archive"
           mu4e-sent-folder "/Sent"
           mu4e-drafts-folder "/Drafts"
           mu4e-get-mail-command "mbsync -a"
           mu4e-update-interval 60)
   #+END_SRC

   The following  also allows  me to  automatically include  my signature  in my
   Emails, to view images  in my Emacs buffers and to show me  the address of my
   contacts and not just their names.
   #+BEGIN_SRC emacs-lisp
     (setq mu4e-compose-signature-auto-include t
           mu4e-view-show-images t
           mu4e-view-prefer-html t
           mu4e-view-show-addresses t)
   #+END_SRC

   This source block  is an example of  the search queries in mu4e,  and part of
   the reason why I very much like mu4e: these bookmarks are actually defined by
   search queries, but act as if they were just yet another type of custom inbox
   you get  with modern Email  client (and often you  don’t even get  them). All
   these bookmarks can  be accessed through a shortcut on  the main mu4e buffer,
   prefixed by  ~b~. So, for instance,  my unread messages are  accessed through
   ~bU~.
   #+BEGIN_SRC emacs-lisp
     (setq mu4e-bookmarks
           `(("maildir:/Inbox AND NOT flag:trashed" "Inbox" ?i)
             (,(s-join " "
                       '("maildir:/Inbox"
                         "AND NOT flag:trashed"
                         "AND f:/.*up8\.edu|.*univ-paris8.*/"))
              "University" ?u)
             (,(s-join " "
                       '("maildir:/Inbox"
                         "AND (list:ateliers-emacs.framalistes.org"
                         "OR list:ateliers-paris.emacs-doctor.com)"))
              "Emacs" ?e)
             ("maildir:/Sent" "Sent messages" ?s)
             ("flag:unread AND NOT flag:trashed" "Unread messages" ?U)
             ("date:today..now" "Today's messages" ?t)
             ("date:7d..now" "Last 7 days" ?w)
             ("date:1m..now" "Last month" ?m)
             ("date:1y..now" "Last year" ?y)
             ("flag:trashed" "Trash" ?T)
             ("mime:image/*" "Messages with images" ?p)))
   #+END_SRC

   On new email arrival, Emacs can send  the system a notification which will be
   handled as any other notification received by the system and will display the
   number of unread emails to the user; in my case, notifications are handled by
   AwesomeWM.
   #+BEGIN_SRC emacs-lisp
     (setq mu4e-enable-notifications t
           mu4e-alert-email-notification-types '(count))
     (with-eval-after-load 'mu4e-alert
       (mu4e-alert-set-default-style 'notifications))
     (add-hook 'mu4e-view-mode-hook 'visual-line-mode)
   #+END_SRC

   Now this  hook is  added so  I can  get a maximal  width for  the text  of my
   emails, I really don’t  like it when lines are kilometers  long. I would like
   instead to hook ~visual-line-mode~ and ~auto-fill-mode~, but for some reasons
   Emacs throws an error when I add them, So I go with ~visual-fill-column-mode~
   instead.
   #+BEGIN_SRC emacs-lisp
     (add-hook 'mu4e-view-mode-hook 'visual-fill-column-mode)
   #+END_SRC

   On modern-day  computers, with  wide screens almost  everywhere, there  is no
   reason for the email buffer to open  below the email directory and not on its
   right,  which  is  why I  set  the  split  view  to be  vertical  instead  of
   horizontal. And to make it more  readable, the header window will only occupy
   40% of Emacs’  frame, the rest will be  given to emails. As you  can see, the
   width of the mu4e headers is evaluated each time we enter it, so it can react
   to the frame being potentially not the  same width than earlier or the window
   not taking the entire frame. It has to have a minimal size though, I’d say 80
   characters is enough for that.
   #+BEGIN_SRC emacs-lisp
     (setq mu4e-split-view 'vertical)
     (add-hook 'mu4e-headers-mode-hook
               (lambda ()
                 (setq mu4e-headers-visible-columns (max 80
                                                         (round (* (window-width)
                                                                   0.4))))))
   #+END_SRC

   This  is the  setup I  have for  my  SMTP mail  server: I  point Emacs’  SMTP
   services to  my private mail  server on its SMTP  port, which should  be used
   with a STARTTLS stream.  And I tell Emacs this is the default  way to send an
   email.
   #+BEGIN_SRC emacs-lisp
     (setq smtpmail-smtp-server "mail.phundrak.com"
           smtpmail-smtp-service 587
           smtpmail-stream-type 'starttls
           message-send-mail-function 'smtpmail-send-it)
   #+END_SRC

   I am  unsure yet if  this has  any effect on  mu4e, but this  variable should
   discourage mu4e from reading rich text  emails and instead open them as plain
   text. However, I  do not wish to  discourage opening HTML emails  since I can
   compile them to PDF or open them in the browser.
   #+BEGIN_SRC emacs-lisp
     (setq mm-discouraged-alternatives '("text/richtext"))
   #+END_SRC

   I am still unsure about this variable and  if it has an effect on mu4e, but I
   wish to  set a default  web viewer for  my HTML emails:  w3m. This is  not as
   effective as sending the email in the  browser or rendering it as a PDF file,
   but it can be effective enough for some emails.
   #+BEGIN_SRC emacs-lisp
     (setq mm-text-html-renderer 'w3m)
   #+END_SRC

** Miscellaneous
   :PROPERTIES:
   :CUSTOM_ID: User_Configuration-Miscellaneous-d230bc2f
   :END:
   I have  a lot of variables  that need to be  set but don’t fall  in any other
   category, so I’ll collect them here.

   I have this regexp for detecting paragraphs.
   #+BEGIN_SRC emacs-lisp
     (setq paragraph-start "\f\\|[ \t]*$\\|[ \t]*[-+*] ")
   #+END_SRC

*** Pinentry
    :PROPERTIES:
    :CUSTOM_ID: User_Configuration-Miscellaneous-Pinentry-95004d5a
    :END:
    Pinentry should use the ~loopback~ mode when communicating with GnuPG. Let’s
    set it so:
    #+BEGIN_SRC emacs-lisp
    (setq epa-pinentry-mode 'loopback)
    #+END_SRC

*** Wttr.in cities
    :PROPERTIES:
    :CUSTOM_ID: User_Configuration-Miscellaneous-Wttr.in_cities-dd24f8c5
    :END:
    Thanks to the wttrin package, I can  get the weather forecast in Emacs for a
    couple of cities. I just need to specify them to Emacs like so:
    #+BEGIN_SRC emacs-lisp
      (setq wttrin-default-cities '("Aubervilliers" "Paris" "Lyon" "Nonières"
                                    "Saint Agrève"))
    #+END_SRC

    :PROPERTIES:
    :PROPERTIES:
** Visual configuration
   :PROPERTIES:
   :CUSTOM_ID: User_Configuration-Visual_configuration-78e6cafc
   :END:
*** Battery mode line
    :PROPERTIES:
    :CUSTOM_ID: User_Configuration-Editing_and_modes-Battery_mode_line-895e5e52
    :END:
    I want to see  by default how much battery my computer  has, so let’s enable
    it:
    #+BEGIN_SRC emacs-lisp
      (spacemacs/toggle-mode-line-battery-on)
    #+END_SRC

*** Helm icons
    :PROPERTIES:
    :CUSTOM_ID: User_Configuration-Visual_configuration-Helm_icons-6475fb5f
    :END:
    With the package ~helm-icons~, it is possible to bring ~all-the-icons~ to
    helm when going through files and buffers. Let’s enable it.
    #+BEGIN_SRC emacs-lisp
      (helm-icons-enable)
    #+END_SRC

*** Prettified symbols
    :PROPERTIES:
    :CUSTOM_ID: User_Configuration-Miscellaneous-Prettified_symbols-da50f4a6
    :END:
    Just because  it is  pleasing to the  eye, some symbols  in source  code get
    prettified into simpler symbols. Here is the  list of symbols that are to be
    prettified. You  can see in  the corresponding  comment what symbol  will be
    displayed.
    #+BEGIN_SRC emacs-lisp
      (setq prettify-symbols-alist '(("lambda" . 955) ; λ
                                     ("->" . 8594)    ; →
                                     ("<->" . 8596)   ; ↔
                                     ("<-" . 8592)    ; ←
                                     ("=>" . 8658)    ; ⇒
                                     ("<=>" . 8860)   ; ⇔
                                     ("<=" . 8656)    ; ⇐
                                     ("mapc" . 8614)  ; ↦
                                     ("map" . 8614)   ; ↦
                                     (">>" . 187)     ; »
                                     ("<<" . 171)     ; «
                                     ))
    #+END_SRC

    Let’s enable this mode globally.
    #+BEGIN_SRC emacs-lisp
      (global-prettify-symbols-mode 1)
    #+END_SRC

*** Time in modeline
    :PROPERTIES:
    :CUSTOM_ID: User_Configuration-Visual_configuration-Time_in_modeline-61b40ef2
    :END:
    I like to see what time it is in Emacs. It may be sometimes redundant with
    my window manager’s clock, but the latter is not always visible; I might
    have, for instance, Emacs in fullscreen. First, I need to tell Emacs a few
    things: I want a 24h format, as well as the current date.
    #+BEGIN_SRC emacs-lisp
      (setq display-time-24hr-format t
            display-time-day-and-date t)
    #+END_SRC

    Now that Emacs knows how to display time, let’s ask it to.
    #+BEGIN_SRC emacs-lisp
      (display-time-mode 1)
    #+END_SRC

*** ~which-key~ replacements
    :PROPERTIES:
    :CUSTOM_ID: User_Configuration-Visual_configuration-which-key_replacements-cccc5202
    :END:
    It is possible to customize a bit what the ~which-key~ package shows us when
    invoked.  For the  record, most  of this  either comes  from [[http://www.howardism.org/][Howard  Abram]]’s
    [[https://github.com/howardabrams/dot-files][config]] on  Github. First  of all,  I’d like to  have some  elements replaced
    alltogether, such  as ~left~ or  ~right~ being  replaced with a  more visual
    indicator, while some keys are replaced with a more understandable name.
    #+BEGIN_SRC emacs-lisp
      (setq which-key-key-replacement-alist
            '(("<\\([[:alnum:]-]+\\)>" . "\\1")
              ("left"                  . "◀")
              ("right"                 . "▶")
              ("up"                    . "▲")
              ("down"                  . "▼")
              ("delete"                . "DEL") ; delete key
              ("\\`DEL\\'"             . "BS") ; backspace key
              ("next"                  . "PgDn")
              ("prior"                 . "PgUp")))
    #+END_SRC

    Let’s also write some replacements for the function names.
    #+BEGIN_SRC emacs-lisp
      (setq which-key-description-replacement-alist
            '(("Prefix Command" . "prefix")
              ("\\`calc-" . "")
              ("\\`projectile-" . "𝓟/")
              ("\\`org-babel-" . "ob/")
              ("\\`phundrak/" . "")))
    #+END_SRC

** Nov-mode
   :PROPERTIES:
   :CUSTOM_ID: User_Configuration-Nov-mode-6f10765d
   :END:
   ~nov-mode~ is the  mode used in the  Epub reader. Here I will  write a little
   function that  I will call through  a hook each  time I’m opening a  new EPUB
   file.
   #+BEGIN_SRC emacs-lisp
     (defun my-nov-font-setup ()
       (face-remap-add-relative 'variable-pitch :family "Charis SIL"
                                :size 16
                                :height 1.0))
   #+END_SRC

   Let’s  bind this  function to  the ~nov-mode~  hook. By  the way,  we’ll also
   enable the ~visual-line-mode~ here, just in case.
   #+BEGIN_SRC emacs-lisp
     (mapc (lambda (mode)
             (add-hook 'nov-mode-hook mode))
           '('my-nov-font-setup 'visual-line-mode))
   #+END_SRC

   Let’s also set the maximum length of the lines in ~nov-mode~:
   #+BEGIN_SRC emacs-lisp
     (setq nov-text-width 80)
   #+END_SRC

** Programming
   :PROPERTIES:
   :CUSTOM_ID: User_Configuration-Programming-b4b565ae
   :END:
*** LSP
    :PROPERTIES:
    :CUSTOM_ID: User_Configuration-LSP-4f8aa691
    :END:
    When it comes to the LSP layer,  there are some options which are not enabled
    by default that I want to use, especially some modes I want to take advantage
    of. This  is why I enable  first the ~lsp-treemacs-sync-mode~ so  treemacs is
    LSP aware:
    #+BEGIN_SRC emacs-lisp
      (lsp-treemacs-sync-mode 1)
    #+END_SRC

    I also enable some layers related to ~dap~, the Debug Adapter Protocol, which
    works really nicely with LSP. Let’s enable Dap’s modes:
    #+BEGIN_SRC emacs-lisp
      (dap-mode 1)
      (dap-ui-mode 1)
      (dap-tooltip-mode 1)
    #+END_SRC

    Finally, I also want the documentation tooltip  to show up when the cursor is
    above a documented piece of code or symbol. Let’s enable that too:
    #+BEGIN_SRC emacs-lisp
      (tooltip-mode 1)
    #+END_SRC

*** ASM configuration
    :PROPERTIES:
    :CUSTOM_ID: User_Configuration-ASM_configuration-f6dc7674
    :END:
    The first thing I  will set with my ASM configuration  is where the reference
    PDF is located.
    #+BEGIN_SRC emacs-lisp
      (setq x86-lookup-pdf "~/Documents/code/asm/Intelx86/325383-sdm-vol-2abcd.pdf")
    #+END_SRC
    I will also modify what the comment character is, from a ~;~ to a ~#~:
    #+BEGIN_SRC emacs-lisp
      (setq asm-comment-char ?\#)
    #+END_SRC

*** C/C++
    :PROPERTIES:
    :CUSTOM_ID: User_Configuration-C-C++-76c3f997
    :END:
    As the C/C++ syntax is checked by  flycheck, let’s make sure we are using the
    latest standard available, that is C++17 and C17, from Clang.
    #+BEGIN_SRC emacs-lisp
      (add-hook 'c-mode-hook
                (lambda ()
                  (setq flycheck-clang-language-standard "c17")))
      (add-hook 'c++-mode-hook
                (lambda ()
                  (setq flycheck-clang-language-standard "c++17")))
    #+END_SRC

*** Dart configuration
    :PROPERTIES:
    :CUSTOM_ID: User_Configuration-Dart_configuration-ecf24ebf
    :END:
    For  Dart, I  mainly  declared  some custom  shortcuts  bound to  ~dart-mode~
    related to flutter, so nothing too exciting here. Some prefix are declared in
    order to avoid the shortcuts in helm to show up as just ~custom~.
    #+begin_src emacs-lisp
      (spacemacs/declare-prefix-for-mode 'dart-mode "mo" "user-defined")
      (spacemacs/declare-prefix-for-mode 'dart-mode "mof" "flutter")
      (spacemacs/declare-prefix-for-mode 'dart-mode "mofr" "flutter-run")
    #+end_src

    Now, for the shortcuts themselves:
    #+BEGIN_SRC emacs-lisp
      (spacemacs/set-leader-keys-for-major-mode 'dart-mode
        "ofH" 'flutter-hot-restart
        "ofh" 'flutter-hot-reload
        "ofq" 'flutter-quit
        "ofr" (lambda () (interactive) (flutter-run "-v"))
        "ofs" 'flutter-screenshot)
    #+END_SRC

*** Emacs Lisp
    :PROPERTIES:
    :CUSTOM_ID: User_Configuration-Emacs_Lisp-59230f3c
    :END:
    Here  will  be  stored  my  configuration directly  related  to  Emacs  Lisp,
    including some functions or default modes.

**** Enable ~eldoc-mode~ by default
     :PROPERTIES:
     :CUSTOM_ID: User_Configuration-Emacs_Lisp-Enable_~eldoc-mode~_by_default-f131abde
     :END:
     By default, if some Elisp code is opened, I want to enable ~eldoc-mode~ so I
     can easily get some documentation on the symbols in the source code. This is
     done via the use of hooks.
     #+BEGIN_SRC emacs-lisp
       (add-hook 'prog-mode-hook 'eldoc-mode)
     #+END_SRC

**** ~phundrak/write-to-buffer~
     :PROPERTIES:
     :CUSTOM_ID: User_Configuration-Emacs_Lisp-~phundrak-write-to-buffer~-2f192dd3
     :END:
     I was  very surprised when  I discovered no  such function exists  in Elisp.
     This  function basically  writes  a  string into  a  buffer, and  optionally
     switches the user to the buffer. Here is the code for that function:
     #+BEGIN_SRC elisp :results silent
       (defun write-to-buffer ($input-string $outputbuf &optional $switchbuf)
         "Writes `$input-string' to the specified `output-buffer'. If
       `switch-buffer' is non-nil, the active buffer will switch to the
       output buffer; otherwise, it will take the user back to their
       initial buffer. Works with `$input-string' as a string or a list
       of strings."
         (let ((oldbuf (current-buffer)))
           (switch-to-buffer $outputbuf)
           (cond ((char-or-string-p $input-string) (insert $input-string))
                 ((listp $input-string) (dolist (elem $input-string)
                                         (insert (format "%s\n" elem)))))
           (if (not $switchbuf)
               (switch-to-buffer oldbuf))))
     #+END_SRC

*** Python
    :PROPERTIES:
    :CUSTOM_ID: User_Configuration-Python-9cdd1b06
    :END:
    Emacs throws me an error about the python interpreter, let’s silence it:
    #+BEGIN_SRC emacs-lisp
      (setq python-shell-completion-native-disabled-interpreters '("python"))
    #+END_SRC

*** Rust
    :PROPERTIES:
    :CUSTOM_ID: User_Configuration-Rust-ba633575
    :END:
    I need to  point to racer where the  source code of Rust is located  so I can
    get some documentation.  This is installed with the  ~rust-src~ component you
    can get through ~rustup~. To install it, simply run
    #+BEGIN_SRC shell :tangle no :exports code
      $ rustup component add rust-src
    #+END_SRC

    Now, the  source code  for Rust  should be included  in your  installation. I
    personally prefer to develop with Rust  stable, so let’s indicate to Emacs to
    search for documentation in the stable sources:
    #+BEGIN_SRC emacs-lisp
      (setq racer-rust-src-path
            "~/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/src")
    #+END_SRC

    Rust’s default  ~cargo check~ command  is already  very good, however  I also
    enjoy getting  some more hints  while developping,  and ~clippy~ does  a very
    good job at it. To get clippy, I need to run the following to install it:
    #+BEGIN_SRC shell
      $ rustup compontent add clippy
    #+END_SRC

    And this will get it installed with all  of my Rust toolchain, and it will be
    updated with it. Now,  let’s indicate LSP that I want to  use that instead of
    ~check~:
    #+BEGIN_SRC emacs-lisp
      (setq lsp-rust-analyzer-cargo-watch-command "clippy")
    #+END_SRC

    Finally, I  wish to  enable ~electric-pair-mode~ and  ~indent-guide-mode~ for
    Rust files, so let’s enable that through the use of a hook:
    #+BEGIN_SRC emacs-lisp
      (add-hook 'rust-mode-hook
                '(lambda ()
                   (local-set-key (kbd "TAB") #'company-indent-or-complete-common)
                   (electric-pair-mode 1)
                   (indent-guide-mode 1)))
    #+END_SRC

*** Scheme
    :PROPERTIES:
    :CUSTOM_ID: User_Configuration-Scheme-e35aa50a
    :END:
    The Scheme configuration  will be very short,  I just need to  tell Emacs the
    name of the interpreter since it is not the default one:
    #+BEGIN_SRC emacs-lisp
      (setq geiser-chicken-binary "chicken-csi")
    #+END_SRC

** Projectile
   :PROPERTIES:
   :CUSTOM_ID: User_Configuration-Projectile-06e580f0
   :END:
   Projectile is an awesome utility  which helps managing projects within Emacs.
   It  will automatically  detect version  controlled directories,  and will  by
   default assume this is a project I can be working on. However, there are some
   directories that are version controlled that I  do not want to see in my list
   of projects,  namely all the cached  AUR packages from my  AUR helper, ~yay~.
   They are  all stored in  the same parent directory,  so let’s ignore  that. I
   will  also  make  Emacs  ignore   all  ~node_modules~  directories  it  could
   encounter. And  for some reason,  =~/.config/emacs= is always in  my projects
   list (I now use XDG-compliant directories), so let’s also ignore that.
   #+BEGIN_SRC emacs-lisp
     (phundrak/add-all-to-list projectile-globally-ignored-directories
                               "~/.cache/yay/*" "node_modules" "~/.config/emacs")
   #+END_SRC

** Security
   :PROPERTIES:
   :CUSTOM_ID: User_Configuration-Security-21d88555
   :END:
   This paragraph  is about  making Emacs  and GPG  as a  whole (since  Emacs is
   /always/ open on my computer) more secure.  The first thing I want to make is
   a function that  will close any buffer  that contains an open  ~.gpg~ file –I
   certainly do not want anyone to be able  to read such files on my computer if
   I leave it even for a couple of minutes.
   #+BEGIN_SRC emacs-lisp
     (defun phundrak/kill-gpg-buffers ()
       "Kill GPG buffers."
       (interactive)
       (let ((buffers-killed 0))
         (dolist (buffer (buffer-list))
           (with-current-buffer buffer
             (when (string-match ".*\.gpg$" (buffer-name buffer))
               (message "Auto killing .gpg buffer '%s'" (buffer-name buffer))
               (when (buffer-modified-p buffer)
                 (save-buffer))
               (kill-buffer buffer)
               (setq buffers-killed (+ buffers-killed 1)))))
         (unless (zerop buffers-killed)
           ;; Kill gpg-agent.
           (shell-command "gpgconf --kill gpg-agent")
           (message "%s .gpg buffers have been autosaved and killed" buffers-killed))))
   #+END_SRC

   Notice  the ~(shell-command  "gpgconf --kill  gpg-agent")~ command  there: it
   kills ~gpg-agent~ which  will always respawn each time GPG2  is invoked. That
   way, I know anyone trying to open a  GPG file will have to insert my password
   when trying  to do so instead  of just hoping I  entered it not long  ago and
   they won’t have to.

   But surely, if  I only define this function  and hope to call it  each time I
   leav my  computer, surely  at one point  I will forget  to execute  it before
   leaving. I can’t trust  myself to always call it manually.  Which is why I’ll
   ask Emacs  itself to  call it  after it detects  a minute  of idling.  It may
   become from times to times a bit of a pain, but at least I’m now sure I won’t
   ever have to worry about someone reading my GPG files open in Emacs while I’m
   out for a quick break.
   #+BEGIN_SRC emacs-lisp
     (run-with-idle-timer 60 t 'phundrak/kill-gpg-buffers)
   #+END_SRC

** Snippets
   :PROPERTIES:
   :CUSTOM_ID: User_Configuration-Snippets-67a32065
   :HEADER-ARGS:snippet: :padline no :mkdir yes
   :END:
   Yasnippet’s snippets tool  is extremely powerful and allows me  to write very
   quickly code. For now,  we have snippets for two modes.  The files you’ll see
   below are  exported to  ~$HOME/.config/emacs/private/snippets/~ and  to their
   respective mode  directory. For instance,  my ~caption~ snippet  for org-mode
   will be exported to ~$HOME/.config/emacs/private/snippets/org-mode/caption~.

   Be  aware that  on top  of  these custom  snippets,  I also  use the  package
   [[file:awesome.org::#Autostart-f2cf42fe][yasnippet-snippets]] which provide plenty of already made snippets.
*** Rust snippets
    :PROPERTIES:
    :CUSTOM_ID: User_Configuration-Snippets-Rust_snippets-b106fad4
    :END:
    I have so far two snippets, the  first one is actually just a convenience to
    make it easier to type a ~println!~ macro than the default snippet.
    #+BEGIN_SRC snippet :tangle ~/.config/emacs/private/snippets/rust-mode/println
      # -*- mode: snippet -*-
      # name: println
      # key: pln
      # --
      println!("${1:{}}", $2);
    #+END_SRC

    The second one is more interesting: it is used to create a ~new~ method for
    a struct, and it will try to create a function that will assign each
    argument passed to the method to members of the struct. It relies on the
    custom function [[#User_Configuration-Custom_functions-phundrakyas-rust-new-assignments-10f73456][I wrote here]].
    #+BEGIN_SRC snippet :tangle ~/.config/emacs/private/snippets/rust-mode/new
      # -*- mode: snippet -*-
      # name: new
      # key: _new
      # --
      fn new(${1:args}) -> Self {
        $0
        Self {
          ${1:$(phundrak/yas-rust-new-assignments yas-text)}
        }
      }
    #+END_SRC


*** Org headers
    :PROPERTIES:
    :CUSTOM_ID: User_Configuration-Snippets-org-mode_snippets-Org_headers-ed14fbac
    :END:
    The first two snippets are used to  add HTML or LaTeX attributes to elements
    in org-mode.  The third also  has a  similar usage, inserting  a ~#+CAPTION~
    header before  an element, as  well as the  fourth which inserts  a ~#+NAME~
    header.
    #+BEGIN_SRC snippet :tangle ~/.config/emacs/private/snippets/org-mode/attr_html
      # -*- mode: snippet -*-
      # name: ATTR HTML
      # key: <ah
      # --
      ,#+ATTR_HTML: $0
    #+END_SRC

    #+BEGIN_SRC snippet :tangle ~/.config/emacs/private/snippets/org-mode/attr_latex
      # -*- mode: snippet -*-
      # name: ATTR LATEX
      # key: <al
      # --
      ,#+ATTR_LATEX: $0
    #+END_SRC

    #+BEGIN_SRC snippet :tangle ~/.config/emacs/private/snippets/org-mode/caption
      # -*- mode: snippet -*-
      # name: caption
      # key: <ca
      # --
      ,#+CAPTION: $0
    #+END_SRC

    #+BEGIN_SRC snippet :tangle ~/.config/emacs/private/snippets/org-mode/name
      # -*- mode: snippet -*-
      # name: name
      # key: <na
      # --
      ,#+NAME: $0
    #+END_SRC

    Now, the following  is a bit more complex:  it is meant to be used  as a new
    org buffer  is created. It  will insert an org  header for the  title, which
    will  default  to  the  buffer’s   name  capitalized  minus  the  dashes  or
    underscores replaced with spaces, it will  insert a default author and email
    based on the user’s  parameters, and the date at the  moment of the creation
    of these headers. The user can also add some tags if they wish to.
    #+BEGIN_SRC snippet :tangle ~/.config/emacs/private/snippets/org-mode/header
      # -*- mode: snippet -*-
      # name: header
      # key: header
      # --
      ,#+TITLE:  ${1:`(replace-regexp-in-string "-" " " (capitalize (file-name-nondirectory (file-name-sans-extension (buffer-file-name)))))`}
      ,#+AUTHOR: `(user-full-name)`
      ,#+EMAIL:  `user-mail-address`
      ,#+DATE:   `(format-time-string "%Y-%m-%d")`
      ,#+TAGS:   $2

      $0
    #+END_SRC

*** Org blocks
    :PROPERTIES:
    :CUSTOM_ID: User_Configuration-Snippets-org-mode_snippets-Org_blocks-e4dfc448
    :END:
    Now,  Let’s write  some snippets  for org  blocks. The  first one  is for  a
    comment block,  then two snippets  for an unnamed  and a named  Elisp source
    block, and two others for an unnamed  and a named Python source block. There
    are  also two  block for  generic unnamed  source blocks  and generic  named
    source blocks.
    #+BEGIN_SRC snippet :tangle ~/.config/emacs/private/snippets/org-mode/comment_block
      # -*- mode: snippet -*-
      # name: comment block
      # key: <co
      # --
      ,#+BEGIN_COMMENT
      $0
      ,#+END_COMMENT
    #+END_SRC

    #+BEGIN_SRC snippet :tangle ~/.config/emacs/private/snippets/org-mode/emacs-lisp
      # -*- mode: snippet -*-
      # name: emacs-lisp block
      # key: <el
      # --
      ,#+BEGIN_SRC emacs-lisp
      $0
      ,#+END_SRC
    #+END_SRC

    #+BEGIN_SRC snippet :tangle ~/.config/emacs/private/snippets/org-mode/emacs-lisp-named
            # -*- mode: snippet -*-
            # name: named emacs-lisp block
            # key: <eln
            # --
            ,#+NAME: $1
            ,#+BEGIN_SRC emacs-lisp
            $0
            ,#+END_SRC
    #+END_SRC

    #+BEGIN_SRC snippet :tangle ~/.config/emacs/private/snippets/org-mode/python
      # -*- mode: snippet -*-
      # name: python block
      # key: <py
      # --
      ,#+BEGIN_SRC python
      $0
      ,#+END_SRC
    #+END_SRC

    #+BEGIN_SRC snippet :tangle ~/.config/emacs/private/snippets/org-mode/python-named
      # -*- mode: snippet -*-
      # name: named python block
      # key: <pyn
      # --
      ,#+NAME: $1
      ,#+BEGIN_SRC python
      $0
      ,#+END_SRC
    #+END_SRC

    #+BEGIN_SRC snippet :tangle ~/.config/emacs/private/snippets/org-mode/src
      # -*- mode: snippet -*-
      # name: source block
      # key: <s
      # --
      ,#+BEGIN_SRC $1
      $0
      ,#+END_SRC
    #+END_SRC

    #+BEGIN_SRC snippet :tangle ~/.config/emacs/private/snippets/org-mode/src-named
      # -*- mode: snippet -*-
      # name: named source block
      # key: <sn
      # --
      ,#+NAME: $1
      ,#+BEGIN_SRC $2
      $0
      ,#+END_SRC
    #+END_SRC

*** Org misc
    :PROPERTIES:
    :CUSTOM_ID: User_Configuration-Snippets-Org_misc-82223a44
    :END:
    Finally, there are a couple of miscellaneous org snippets that insert macros
    I often  use in my conlanging  documents. The first one  inserts a phonetics
    macro, while the second one inserts a macro used for my Proto-Ñyqy language.
    #+BEGIN_SRC snippet :tangle ~/.config/emacs/private/snippets/org-mode/phon
      # -*- mode: snippet -*-
      # name: phon
      # key: <ph
      # --
      \{\{\{phon($1)\}\}\} $0
    #+END_SRC

    #+BEGIN_SRC snippet :tangle ~/.config/emacs/private/snippets/org-mode/phon
      # -*- mode: snippet -*-
      # name: nyqy
      # key: <ny
      # --
      \{\{\{nyqy($1)\}\}\} $0
    #+END_SRC

** Yadm
   :PROPERTIES:
   :CUSTOM_ID: User_Configuration-Yadm-4344fec3
   :END:
   yadm is  the utility  I use  for managing my  dotfiles, and  it is  a wrapper
   In order to manage my dotfiles, I use the following shortcut to launch Magit
   Status for yadm:
   #+BEGIN_SRC emacs-lisp
     (spacemacs/declare-prefix "oy" "yadm status")
     (spacemacs/set-leader-keys "oy" (lambda () (interactive) (magit-status "/yadm::")))
   #+END_SRC

   around ~git~.  Logically, it means  Magit could theoretically manage  my yadm
   repo. And it is  indeed possible, according to [[https://github.com/TheLocehiliosan/yadm/blob/master/yadm.md][this page]]  using TRAMP. I just
   need to add the following code snippet:
   #+BEGIN_SRC emacs-lisp
     (add-to-list 'tramp-methods
                  '("yadm"
                    (tramp-login-program "yadm")
                    (tramp-login-args (("enter")))
                    (tramp-login-env (("SHELL")
                                      ("/bin/sh")))
                    (tramp-remote-shell "/bin/sh")
                    (tramp-remote-shell-args ("-c"))))
   #+END_SRC

* Footnotes
  :PROPERTIES:
  :CUSTOM_ID: Footnotes-5ffd05ee
  :END:

[fn:2] [[https://labs.phundrak.com/phundrak/dotfiles/src/branch/master/.spacemacs][labs.phundrak.com/phundrak/dotfiles/src/branch/master/.spacemacs]]

[fn:1] [[https://labs.phundrak.com/phundrak/dotfiles/src/branch/master/org/config/emacs.org][labs.phundrak.com/phundrak/dotfiles/src/branch/master/org/config/emacs.org]]
