Lucien Cartier-Tilet
87b128d0dd
`visual-line-mode` is now enabled by default when opening a message, which will be preferably opened as HTML Org src block editions will now open to the right of the active buffer
3363 lines
131 KiB
Org Mode
3363 lines
131 KiB
Org Mode
# -*- org-confirm-babel-evaluate: nil -*-
|
||
#+title: Phundrak’s Spacemacs Configuration
|
||
#+INCLUDE: headers.org
|
||
#+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
|
||
#+STARTUP: content
|
||
|
||
* Table of Contents :TOC:noexport:
|
||
:PROPERTIES:
|
||
:CUSTOM_ID: h-f61204c4-beb8-4008-b02e-55eae4e8f163
|
||
:END:
|
||
- [[#introduction][Introduction]]
|
||
- [[#spacemacs-layers-and-packages][Spacemacs layers and packages]]
|
||
- [[#general-configuration][General configuration]]
|
||
- [[#package-management][Package management]]
|
||
- [[#layers][Layers]]
|
||
- [[#checkers][Checkers]]
|
||
- [[#completion][Completion]]
|
||
- [[#email][Email]]
|
||
- [[#emacs][Emacs]]
|
||
- [[#file-trees][File trees]]
|
||
- [[#fonts][Fonts]]
|
||
- [[#fun][Fun]]
|
||
- [[#internationalization][Internationalization]]
|
||
- [[#programming-languages][Programming languages]]
|
||
- [[#domain-specific-dsls][Domain-specific (DSLs)]]
|
||
- [[#frameworks][Frameworks]]
|
||
- [[#general-purpose][General-purpose]]
|
||
- [[#readers][Readers]]
|
||
- [[#version-control][Version control]]
|
||
- [[#themes][Themes]]
|
||
- [[#tools][Tools]]
|
||
- [[#web-services][Web Services]]
|
||
- [[#custom-layers][Custom layers]]
|
||
- [[#init][Init]]
|
||
- [[#emacs-with-pdumper][Emacs with pdumper]]
|
||
- [[#package-managment-and-updates][Package managment and updates]]
|
||
- [[#elpa-repository][Elpa repository]]
|
||
- [[#spacelpa-repository][Spacelpa repository]]
|
||
- [[#editing-style][Editing style]]
|
||
- [[#spacemacs-home-configuration][Spacemacs home configuration]]
|
||
- [[#default-major-modes][Default major modes]]
|
||
- [[#visual-configuration][Visual configuration]]
|
||
- [[#themes-1][Themes]]
|
||
- [[#other-on-screen-elements][Other on-screen elements]]
|
||
- [[#appearance-of-emacs-frames][Appearance of Emacs frames]]
|
||
- [[#spacemacs-leader-keys-and-shortcuts][Spacemacs leader keys and shortcuts]]
|
||
- [[#layouts][Layouts]]
|
||
- [[#files-related-settings][Files-related settings]]
|
||
- [[#emacs-server][Emacs server]]
|
||
- [[#miscellaneous][Miscellaneous]]
|
||
- [[#user-initialization][User Initialization]]
|
||
- [[#user-configuration][User Configuration]]
|
||
- [[#asm-configuration][ASM configuration]]
|
||
- [[#cc][C/C++]]
|
||
- [[#custom-functions][Custom functions]]
|
||
- [[#phundrakfill-paragraph][~phundrak/fill-paragraph~]]
|
||
- [[#terminal-here-default-terminal-command][~terminal-here-default-terminal-command~]]
|
||
- [[#dart-configuration][Dart configuration]]
|
||
- [[#dired][Dired]]
|
||
- [[#emacs-lisp][Emacs Lisp]]
|
||
- [[#enable-eldoc-mode-by-default][Enable ~eldoc-mode~ by default]]
|
||
- [[#phundrakwrite-to-buffer][~phundrak/write-to-buffer~]]
|
||
- [[#eshell][Eshell]]
|
||
- [[#environment-variables][Environment variables]]
|
||
- [[#custom-functions-1][Custom functions]]
|
||
- [[#redirect-text-editors-to-emacs][Redirect text editors to Emacs]]
|
||
- [[#aliases][Aliases]]
|
||
- [[#system-monitoring][System monitoring]]
|
||
- [[#system-management-packages-and-services][System management (packages and services)]]
|
||
- [[#other][Other]]
|
||
- [[#typos][Typos]]
|
||
- [[#visual-commands][Visual commands]]
|
||
- [[#eshell-theme][Eshell theme]]
|
||
- [[#file-extensions][File extensions]]
|
||
- [[#lsp][LSP]]
|
||
- [[#mu4e][Mu4e]]
|
||
- [[#miscellaneous-1][Miscellaneous]]
|
||
- [[#evil][Evil]]
|
||
- [[#default-modes][Default modes]]
|
||
- [[#hooks][Hooks]]
|
||
- [[#pinentry][Pinentry]]
|
||
- [[#prettified-symbols][Prettified symbols]]
|
||
- [[#twittering-mode][Twittering mode]]
|
||
- [[#wttrin-cities][Wttr.in cities]]
|
||
- [[#nov-mode][Nov-mode]]
|
||
- [[#python][Python]]
|
||
- [[#org-mode][Org-mode]]
|
||
- [[#custom-org-mode-functions][Custom org-mode functions]]
|
||
- [[#custom-and-unique-headings-id][Custom and unique headings ID]]
|
||
- [[#org-babel-languages][Org babel languages]]
|
||
- [[#org-variables][Org variables]]
|
||
- [[#user-information][User information]]
|
||
- [[#visual-settings][Visual settings]]
|
||
- [[#org-behavior][Org behavior]]
|
||
- [[#miscellaneous-2][Miscellaneous]]
|
||
- [[#org-files-exports][Org files exports]]
|
||
- [[#custom-latex-formats][Custom LaTeX formats]]
|
||
- [[#org-agenda][Org agenda]]
|
||
- [[#org-capture][Org capture]]
|
||
- [[#emails][Emails]]
|
||
- [[#journal][Journal]]
|
||
- [[#notes][Notes]]
|
||
- [[#protocol][Protocol]]
|
||
- [[#resources][Resources]]
|
||
- [[#tasks][Tasks]]
|
||
- [[#computers-and-stuff][Computers and stuff]]
|
||
- [[#health][Health]]
|
||
- [[#birthdays][Birthdays]]
|
||
- [[#youtube][YouTube]]
|
||
- [[#org-projects][Org projects]]
|
||
- [[#configuration-website][Configuration website]]
|
||
- [[#linguistics-website][Linguistics website]]
|
||
- [[#rust][Rust]]
|
||
- [[#scheme][Scheme]]
|
||
- [[#shortcuts][Shortcuts]]
|
||
- [[#applications][Applications]]
|
||
- [[#comments][Comments]]
|
||
- [[#files][Files]]
|
||
- [[#multiple-cursors][Multiple cursors]]
|
||
- [[#org-mode-1][Org-mode]]
|
||
- [[#toggle][Toggle]]
|
||
- [[#text][Text]]
|
||
- [[#yadm][Yadm]]
|
||
- [[#footnotes][Footnotes]]
|
||
|
||
* Introduction
|
||
:PROPERTIES:
|
||
:CUSTOM_ID: h-ff1cbbaa-6ab0-49ab-8945-7e25706ead8e
|
||
: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: :comments link :tangle ~/.config/emacs/private/spacemacs-layers.el :exports code :results silent
|
||
:CUSTOM_ID: h-9d9869e0-4672-419c-bf37-3d3ae1b7c0aa
|
||
: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: h-ecfe1909-18af-451d-b78f-0d7e5a1d45c0
|
||
: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: h-587fd3fb-5a99-4c19-af02-b1553c6acfae
|
||
: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 |
|
||
|---------------------+------------------------------------------------------|
|
||
| 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 |
|
||
| kaolin-themes | some cool themes |
|
||
| magit-gitflow | integrate gitflow in Magit |
|
||
| meson-mode | major mode for Meson build files |
|
||
| 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 |
|
||
| outorg | edit comments as Org-mode buffers |
|
||
| pinentry | enter a GPG password from Emacs |
|
||
| visual-fill-column | allow the use of ~fill-column~ in ~visual-line-mode~ |
|
||
| 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 '())
|
||
#+END_SRC
|
||
|
||
And to list packages which won’t be installed nor loaded:
|
||
#+BEGIN_SRC emacs-lisp
|
||
(setq-default dotspacemacs-excluded-packages '())
|
||
#+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: h-313bf79e-c24c-40a6-8bc0-eb608fda05d9
|
||
: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: h-04664b1a-8138-4566-8b63-8050437351a7
|
||
: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: h-fc18dd98-1411-4516-a87c-6c1047d2a13c
|
||
: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-snippets-in-popup t
|
||
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: h-0db2333c-86bf-4b41-8226-da66885fce36
|
||
: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: h-ad6174a6-4056-420e-9620-3da5f00bd3fc
|
||
: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-reveal-js-support t
|
||
org-enable-trello-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: h-35f135ac-45cd-4e91-a23d-41700dc7495f
|
||
: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: h-7a0a7d6d-6caa-4504-acf6-f97c25436ef1
|
||
: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: h-3aec0cda-50d5-4c31-a57e-4244a254a57f
|
||
:END:
|
||
In this category, I only enabled two layers: ~selectric~ and ~xkcd~.
|
||
#+BEGIN_SRC emacs-lisp
|
||
selectric xkcd
|
||
#+END_SRC
|
||
|
||
*** Internationalization
|
||
:PROPERTIES:
|
||
:CUSTOM_ID: h-0edb1ff3-15a1-46cd-b980-7fdd124020b6
|
||
: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: h-9dd88370-a959-4266-a01e-2231f9008a1f
|
||
:END:
|
||
**** Domain-specific (DSLs)
|
||
:PROPERTIES:
|
||
:CUSTOM_ID: h-c212d89f-6854-48f3-84a5-8195811bfc4d
|
||
: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
|
||
|
||
**** Frameworks
|
||
:PROPERTIES:
|
||
:CUSTOM_ID: h-ac43dd9a-5a2f-4a80-bb35-535ec6e31e72
|
||
: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: h-9d41427d-ec93-40c6-8c24-113c5b174fc3
|
||
: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 the C++11 standard, the
|
||
Google coding style for C++, 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-google-style t
|
||
c-c++-enable-c++11 t
|
||
c-c++-backend 'lsp-ccls
|
||
c-c++-lsp-executable "/usr/bin/ccls"
|
||
c-c++-lsp-sem-highlight-method 'overlay
|
||
c-c++-lsp-sem-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
|
||
dart-server-sdk-path "/opt/flutter/bin/cache/dart-sdk/"
|
||
lsp-dart-sdk-dir "/opt/flutter/bin/cache/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
|
||
|
||
I am also currently testing 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
|
||
|
||
*** Readers
|
||
:PROPERTIES:
|
||
:CUSTOM_ID: h-02099754-7102-4251-9e2e-a3ee33f4b469
|
||
:END:
|
||
In this category, only the ~epub~ and ~pdf~ layers are enabled so I can read
|
||
these files from Emacs directly.
|
||
#+BEGIN_SRC emacs-lisp
|
||
epub pdf
|
||
#+END_SRC
|
||
|
||
*** Version control
|
||
:PROPERTIES:
|
||
:CUSTOM_ID: h-53ebecc5-53da-4a0c-88f4-b031ff3b1952
|
||
:END:
|
||
Only the ~git~ layer is enabled in this category.
|
||
#+BEGIN_SRC emacs-lisp
|
||
git
|
||
#+END_SRC
|
||
|
||
*** Themes
|
||
:PROPERTIES:
|
||
:CUSTOM_ID: h-e593bbe4-d778-4b11-a450-4e6e418109fe
|
||
: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: h-51f1d8a6-5f52-486a-a16b-301429cf8313
|
||
: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, Imenu-list, Web-beautify, Dap, Helpful, and LSP layers
|
||
enabled.
|
||
#+BEGIN_SRC emacs-lisp
|
||
docker imenu-list nginx pass prettier systemd web-beautify helpful dap lsp
|
||
#+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: h-6ec58708-518c-44f4-8ad0-3fa3b58117d5
|
||
: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: h-f9c6b261-f06b-4fd5-bf4e-161cb8744aeb
|
||
: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:
|
||
:CUSTOM_ID: h-3f3c8a0b-56cd-4be6-b019-3ba6f1e24f96
|
||
:header-args:emacs-lisp: :comments link :tangle ~/.config/emacs/private/spacemacs-init.el :exports code :results silent
|
||
: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: h-bb7c391e-3d0c-4c3c-99d4-09a1cb20be43
|
||
: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 nil)
|
||
#+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: h-8573bacc-4372-49e3-a0ff-4520fe999c97
|
||
: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: h-ac64233a-5c7a-41f4-98b5-ce838b33ba44
|
||
: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: h-1f432881-39b2-4d60-862f-a1a95ebe4a58
|
||
: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: h-8a6bfe01-3e45-4189-9bde-70efbe9739ee
|
||
: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
|
||
|
||
** Spacemacs home configuration
|
||
:PROPERTIES:
|
||
:CUSTOM_ID: h-6a78794e-9c0b-4390-99d5-55c5b13c8c5a
|
||
: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
|
||
|
||
** Default major modes
|
||
:PROPERTIES:
|
||
:CUSTOM_ID: h-8318ee22-ffaf-419a-a76b-41f327c23970
|
||
: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: h-d7fe8e66-bfcd-43c4-81e5-fba433300b7b
|
||
:END:
|
||
*** Themes
|
||
:PROPERTIES:
|
||
:CUSTOM_ID: h-013f84c3-92c6-453f-9229-98f0ad6ba884
|
||
: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-vibrant doom-nord 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 '("FiraCode Nerd Font Mono" :size 8.0
|
||
:weight normal
|
||
:width normal))
|
||
#+END_SRC
|
||
|
||
*** Other on-screen elements
|
||
:PROPERTIES:
|
||
:CUSTOM_ID: h-fabead22-a4d0-4826-9ed1-37297810c30b
|
||
: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: h-deae54d7-5790-4c11-8640-573cd3824dbd
|
||
: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 95)
|
||
#+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: h-0bf00e10-d577-4133-91c6-39bdc96d847d
|
||
: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: h-7b84a553-6c54-431e-ad23-dfa26c8a334f
|
||
: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: h-c3aa3e27-4c42-4607-98fa-6e4647247ed3
|
||
: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: h-ca601390-7851-4c05-8021-18ca3eb48ac7
|
||
: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 ="~/.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: h-69b80cd3-dc0c-405b-bd02-315821105922
|
||
: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" "ag" "pt" "ack" "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
|
||
|
||
* User Initialization
|
||
:PROPERTIES:
|
||
:CUSTOM_ID: h-e297b9be-9b0d-4c2d-bb6e-402f0d00be0d
|
||
:header-args:emacs-lisp: :comments link :tangle ~/.config/emacs/private/user-init.el :exports code :results silent
|
||
: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 also want to load what’s in ~icons-in-terminal~ so I can use them in various
|
||
packages in Emacs:
|
||
#+BEGIN_SRC emacs-lisp
|
||
(add-to-list 'load-path "~/.local/share/icons-in-terminal/")
|
||
#+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:
|
||
:CUSTOM_ID: h-7a36d3a0-8bb6-4d9d-9402-eadbc49fef32
|
||
:header-args:emacs-lisp: :comments link :tangle ~/.config/emacs/private/user-config.el :exports code :results silent
|
||
:END:
|
||
** ASM configuration
|
||
:PROPERTIES:
|
||
:CUSTOM_ID: h-73c92790-872d-404d-b3b7-7a94fba4ef34
|
||
: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: h-c0ee6b96-db28-408e-872a-4c4347f807d8
|
||
: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
|
||
|
||
** Custom functions
|
||
:PROPERTIES:
|
||
:CUSTOM_ID: h-e3766e6a-3b77-488d-8dfc-8489411b1c4f
|
||
: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/fill-paragraph~
|
||
:PROPERTIES:
|
||
:CUSTOM_ID: h-e87c6c3f-728d-4065-a886-70eb2c3cc579
|
||
: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: h-4e7c3229-4baa-47d5-8897-545a8b85800a
|
||
: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
|
||
|
||
** Dart configuration
|
||
:PROPERTIES:
|
||
:CUSTOM_ID: h-00537655-3c5f-4cc0-af90-4f357ba9350f
|
||
: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 "o" "user-defined")
|
||
(spacemacs/declare-prefix-for-mode 'dart-mode "of" "flutter")
|
||
(spacemacs/declare-prefix-for-mode 'dart-mode "ofr" "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
|
||
|
||
** Dired
|
||
:PROPERTIES:
|
||
:CUSTOM_ID: h-1214442f-4dc7-4855-90ba-bb23d59af2c9
|
||
: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
|
||
|
||
** Emacs Lisp
|
||
:PROPERTIES:
|
||
:CUSTOM_ID: h-f087976e-3350-46c7-a269-f90c83f60d64
|
||
: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: h-ef91e851-f0f2-4fe6-a1ee-b1556a17761c
|
||
: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: h-3f3b771e-a4dd-42fd-bf97-8930d20c0a86
|
||
: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 switchbuf
|
||
(switch-to-buffer oldbuf))))
|
||
#+END_SRC
|
||
|
||
** Eshell
|
||
:PROPERTIES:
|
||
:CUSTOM_ID: h-846478af-19e5-4e06-a97b-0886062d32c7
|
||
: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: h-f88fac3c-5bf1-452b-93f2-1f68436f2302
|
||
: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: h-8c921fc7-6b55-4829-92cd-133131f1e5f8
|
||
: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: h-a003cd6c-8e80-43a0-ac64-d21774c334b1
|
||
: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: h-7e11a04b-4387-4a62-af00-5d402814acac
|
||
: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
|
||
|
||
**** System monitoring
|
||
:PROPERTIES:
|
||
:CUSTOM_ID: h-a2873e6b-2b71-499e-a113-341df334e4bd
|
||
: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: h-b46ba273-f212-45bb-8500-f82c168232f0
|
||
: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
|
||
|
||
#+RESULTS:
|
||
: eshell/purge
|
||
|
||
**** Other
|
||
:PROPERTIES:
|
||
:CUSTOM_ID: h-4c235c5b-e61b-4a0e-8046-7e957e9dac13
|
||
: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: h-4da87dd0-18b3-46ae-8251-8a829288210f
|
||
: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: h-b276c491-58ba-43a2-898f-1d65aad0df89
|
||
: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: h-83cff5d6-d77c-40af-ba49-80e5c84ff581
|
||
: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
|
||
|
||
** File extensions
|
||
:PROPERTIES:
|
||
:CUSTOM_ID: h-beb67a88-d7d3-4d58-bbc7-7a7be67f64aa
|
||
: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
|
||
|
||
** LSP
|
||
:PROPERTIES:
|
||
:CUSTOM_ID: h-4d0272c3-df5e-4f6b-a6e6-f769add4e603
|
||
: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
|
||
|
||
** Mu4e
|
||
:PROPERTIES:
|
||
:CUSTOM_ID: h-ba4a69ff-38a6-498a-b076-a514bbf0701f
|
||
:END:
|
||
Mu4e is a frontend for mu, an email analyzer which sits on top of a Maildir
|
||
which gets updated with ~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 or
|
||
3. to compile it to a PDF for a better output
|
||
This last feature can only be enabled manually with Arch Linux. We need ~webkitgtk~ installed, and unfortunately, it is by default only available
|
||
through the AUR and has to be compiled. Thing is, ~webkitgtk~ is a *BIG*
|
||
piece of software, and compiling it can be very time consuming. So, I decided
|
||
to add ArchLinuxCN’s servers to my pacman config (instructions on how to do
|
||
so [[https://github.com/archlinuxcn/repo][here]]) so I could install a compiled version from their repos. Next, when I
|
||
installed ~mu~ from the AUR, I modified the PKGBUILD like so:
|
||
#+BEGIN_SRC text :tangle no
|
||
# Maintainer: Marcel Röthke <marcel@roethke.info>
|
||
# Contributor: Pierre Neidhardt <ambrevar@gmail.com>
|
||
# Contributor: csllbr; Popsch <popsch@gmx.net>
|
||
|
||
pkgname=mu
|
||
pkgver=1.2
|
||
pkgrel=3
|
||
pkgdesc="Maildir indexer/searcher and Emacs client (mu4e)"
|
||
arch=("x86_64")
|
||
url="http://www.djcbsoftware.nl/code/mu"
|
||
license=("GPL")
|
||
depends=("gmime3" "xapian-core" "guile2.0")
|
||
makedepends=("emacs")
|
||
optdepends=("guile: guile support"
|
||
"emacs: mu4e support")
|
||
source=("mu-$pkgver.tar.gz::https://github.com/djcb/mu/archive/$pkgver.tar.gz")
|
||
md5sums=('5e7d7c3549b9428ec0b5ea7d374b6d0d')
|
||
|
||
prepare() {
|
||
cd "$pkgname-$pkgver"
|
||
autoreconf -i
|
||
}
|
||
|
||
|
||
build() {
|
||
cd "$pkgname-$pkgver"
|
||
./configure --prefix=/usr --enable-mu4e --enable-guile
|
||
make
|
||
}
|
||
|
||
package() {
|
||
cd "$pkgname-$pkgver"
|
||
make DESTDIR="$pkgdir" install
|
||
# if msg2pdf and mug were built, install them
|
||
# if not, remove the unneeded mug manpage
|
||
if [ -f toys/msg2pdf/msg2pdf ]; then
|
||
install -m755 toys/msg2pdf/msg2pdf "${pkgdir}"/usr/bin/msg2pdf
|
||
fi
|
||
if [ -f toys/mug/mug ]; then
|
||
install -m755 toys/mug/mug "${pkgdir}"/usr/bin/mug
|
||
install -Dm644 toys/mug/mug.svg "${pkgdir}"/usr/share/pixmaps/mug.svg
|
||
else
|
||
rm "${pkgdir}"/usr/share/man/man1/mug.1
|
||
fi
|
||
}
|
||
#+END_SRC
|
||
|
||
This enables the installation of ~msg2pdf~, which in turn enables the email
|
||
compilation to PDF with the shortcut ~a v~ when an email is opened, and this
|
||
opens the PDF in a new Emacs buffer.
|
||
|
||
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
|
||
`(("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)
|
||
("mime:image/*" "Messages with images" ?p)
|
||
(,(mapconcat 'identity
|
||
(mapcar
|
||
(lambda (maildir)
|
||
(concat "maildir:" (car maildir)))
|
||
mu4e-maildir-shortcuts) " OR ")
|
||
"All inboxes" ?i)))
|
||
#+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
|
||
[[https://dunst-project.org/][dunst]].
|
||
#+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 'libnotify))
|
||
(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. I also set the width the email directory should keep to 80
|
||
characters (and I could go to 120, but that’s only good for my
|
||
ultra-widescreen), because 30 characters is way too f-ing low.
|
||
#+BEGIN_SRC emacs-lisp
|
||
(setq mu4e-split-view 'vertical
|
||
mu4e-headers-visible-columns 140)
|
||
#+END_SRC
|
||
|
||
I want to add myself as a hidden recipient to all of my messages so I can get
|
||
them in the email thread in my inbox and not just get a thread of messages
|
||
not sent by me –the thread could kinda lack some context if the other people
|
||
do not insert my email in their answer. But unfortunately, for some obscure
|
||
reason, mu4e does not use the following variable for its email templates, so
|
||
I am keeping this as a reminder I should find how to fix that. It does work
|
||
when I’m exporting an org file to and HTML buffer to be sent by email through ~, e m~.
|
||
#+BEGIN_SRC emacs-lisp
|
||
(setq message-default-headers "Bcc: Lucien Cartier-Tilet <lucien@phundrak.com>\n")
|
||
#+END_SRC
|
||
|
||
Finally but very importantly, 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: h-cee08965-745a-4a6f-b04e-bf1638342698
|
||
: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
|
||
|
||
*** Evil
|
||
:PROPERTIES:
|
||
:CUSTOM_ID: h-1d889318-8b93-4e78-9fe4-9e751b0b1cbe
|
||
: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
|
||
|
||
*** Default modes
|
||
:PROPERTIES:
|
||
:CUSTOM_ID: h-3ac59b6b-4ea3-4270-bdf2-07a68b867ebc
|
||
: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
|
||
|
||
I also want to have by default some aggressive indentation in my source
|
||
files. Let’s enable that:
|
||
#+BEGIN_SRC emacs-lisp
|
||
(global-aggressive-indent-mode 1)
|
||
#+END_SRC
|
||
However, I do not wish to see it activated for Dart mode, so let’s exclude
|
||
it:
|
||
#+BEGIN_SRC emacs-lisp
|
||
(add-to-list 'aggressive-indent-excluded-modes 'dart-mode)
|
||
#+END_SRC
|
||
|
||
*** Hooks
|
||
:PROPERTIES:
|
||
:CUSTOM_ID: h-a895c541-505f-4dc2-8eac-d1fbc45e2512
|
||
: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.
|
||
#+BEGIN_SRC emacs-lisp
|
||
(add-hook 'prog-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
|
||
|
||
*** Pinentry
|
||
:PROPERTIES:
|
||
:CUSTOM_ID: h-c69ca384-fb5b-49e9-9b0d-987da0df1d61
|
||
: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
|
||
|
||
*** Prettified symbols
|
||
:PROPERTIES:
|
||
:CUSTOM_ID: h-3b37d76b-8da4-4c06-adfc-0ccd04bbef18
|
||
: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
|
||
|
||
*** Twittering mode
|
||
:PROPERTIES:
|
||
:CUSTOM_ID: h-fb99695a-99f9-4c30-a286-a9accbb8410f
|
||
: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
|
||
|
||
*** Wttr.in cities
|
||
:PROPERTIES:
|
||
:CUSTOM_ID: h-9d0208e7-f88f-4bba-a48a-e306d3f00939
|
||
: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
|
||
|
||
** Nov-mode
|
||
:PROPERTIES:
|
||
:CUSTOM_ID: h-fea5c178-425f-4e1d-a491-591a3dbb4f93
|
||
: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
|
||
|
||
** Python
|
||
:PROPERTIES:
|
||
:CUSTOM_ID: h-d26ce2ad-94b6-4e50-9803-d53e567f1206
|
||
: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
|
||
|
||
** Org-mode
|
||
:PROPERTIES:
|
||
:CUSTOM_ID: h-5534acb1-963d-4aec-874d-f1f66b02a597
|
||
: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: h-e87fcf0c-2e3e-48e1-80aa-1d8f1a39842b
|
||
: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: h-c6950fac-82a2-49cd-86bb-8f72c0fe9f22
|
||
: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 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 ((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 "h")))
|
||
(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: h-e60e0cf5-55ec-401a-82ed-256baff90f0c
|
||
: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: h-8e86e8dc-5889-44ff-9d10-766fb3e8b873
|
||
:END:
|
||
**** User information
|
||
:PROPERTIES:
|
||
:CUSTOM_ID: h-73307234-da02-4e61-8443-616213d5b004
|
||
: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: h-a88bf63a-5200-46a6-be6e-2e455c347e4a
|
||
: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
|
||
|
||
**** Org behavior
|
||
:PROPERTIES:
|
||
:CUSTOM_ID: h-81bcc367-4b2a-4a10-b42c-7b3cb7fd2d60
|
||
: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
|
||
|
||
**** Miscellaneous
|
||
:PROPERTIES:
|
||
:CUSTOM_ID: h-42ccf90a-f507-4fab-ae42-3fd815a34ef0
|
||
: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: h-65bba789-e7d5-4f60-9280-5c7d11d7f657
|
||
: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: h-783545b6-04b8-4d16-8ab5-12a74c34cfba
|
||
: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"
|
||
;; update the list of LaTeX classes and associated header (encoding, etc.)
|
||
;; and structure
|
||
'(add-to-list 'org-latex-classes
|
||
<<org-latex-class-conlang>>
|
||
<<org-latex-class-beamer>>
|
||
))
|
||
#+END_SRC
|
||
|
||
*** Org agenda
|
||
:PROPERTIES:
|
||
:CUSTOM_ID: h-1c4fb1d5-dfc9-4b1e-be8c-375e6d61f886
|
||
: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
|
||
|
||
By the way, let’s also add all TODO.org files in Org-agenda with
|
||
Org-projectile:
|
||
#+BEGIN_SRC emacs-lisp
|
||
(with-eval-after-load 'org-agenda
|
||
(require 'org-projectile)
|
||
(mapcar #'(lambda (file)
|
||
(when (file-exists-p file)
|
||
(push file org-agenda-files)))
|
||
(org-projectile-todo-files)))
|
||
#+END_SRC
|
||
|
||
*** Org capture
|
||
:PROPERTIES:
|
||
:CUSTOM_ID: h-9a070bbb-5b57-4abd-9d61-51f2070eb47b
|
||
:END:
|
||
Org-capture is an amazing feature of Org-mode which allows me to quickly
|
||
save links, resources, reminders and notes in a neatly organized org file.
|
||
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. Said templates are described
|
||
below:
|
||
#+BEGIN_SRC emacs-lisp
|
||
(setq
|
||
org-default-notes-file "~/org/notes.org"
|
||
org-capture-templates
|
||
'(("e" "Emails")
|
||
("ew" "Write Email" entry
|
||
(file+headline org-default-notes-file "Emails")
|
||
(file "~/org/capture/emails.orgcaptmpl"))
|
||
("j" "Journal" entry
|
||
(file+datetree "~/org/journal.org")
|
||
(file "~/org/capture/journal.orgcaptmpl"))
|
||
("l" "Links")
|
||
("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" "Note")
|
||
("nq" "Quote"
|
||
entry (file+headline org-default-notes-file "Note")
|
||
(file "~/org/capture/notes-quote.orgcaptmpl"))
|
||
("nn" "Note"
|
||
entry (file+headline org-default-notes-file "Note")
|
||
(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-default-notes-file "Conlanging")
|
||
(file "~/org/capture/resource.orgcaptmpl"))
|
||
("re" "Emacs" entry
|
||
(file+headline org-default-notes-file "Emacs")
|
||
(file "~/org/capture/resource.orgcaptmpl"))
|
||
("ri" "Informatique général" 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-default-notes-file "Worldbuilding")
|
||
(file "~/org/capture/resource.orgcaptmpl"))
|
||
("t" "Tasks")
|
||
("ti" "Informatique" entry
|
||
(file+headline "~/org/agenda/private.org" "Informatique")
|
||
(file "~/org/capture/informatique.orgcaptmpl"))
|
||
("th" "Health" entry
|
||
(file+headline "~/org/agenda/private.org" "Health")
|
||
(file "~/org/capture/health.orgcaptmpl"))
|
||
("tb" "Birthday" entry
|
||
(file+headline "~/org/agenda/private.org" "Birthdays")
|
||
(file "~/org/capture/birthday.orgcaptmpl"))
|
||
("te" "Birthday event" entry
|
||
(file+headline "~/org/agenda/private.org" "Burthdays")
|
||
(file "~/org/capture/birthday-event.orgcaptmpl"))))
|
||
#+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.
|
||
|
||
**** Emails
|
||
:PROPERTIES:
|
||
:CUSTOM_ID: h-9012599e-c143-4df0-b63c-7c60ddb4a081
|
||
:END:
|
||
This is my template for a new Email:
|
||
#+BEGIN_SRC org :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: h-ab1b21af-e887-41a7-be7a-c08825d16339
|
||
: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 :tangle ~/org/capture/journal.orgcaptmpl
|
||
,* %U %^{Title}
|
||
%?
|
||
#+END_SRC
|
||
|
||
**** Notes
|
||
:PROPERTIES:
|
||
:CUSTOM_ID: h-2b5e7efc-4a9d-4a92-b75f-4ec75e2fb48d
|
||
: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 :tangle ~/org/capture/notes.orgcaptmpl
|
||
,* %^{Title}
|
||
:PROPERTIES:
|
||
:CAPTURED: %U
|
||
:FROM: %f
|
||
:END:
|
||
%?
|
||
#+END_SRC
|
||
|
||
|
||
#+BEGIN_SRC org :tangle ~/org/capture/notes-quote.orgcaptmpl
|
||
,* %^{Title}
|
||
:PROPERTIES:
|
||
:CAPTURED: %U
|
||
:FROM: %f
|
||
:END:
|
||
Possible inspiration:
|
||
,#+begin_quote
|
||
%i
|
||
,#+end_quote
|
||
|
||
%?
|
||
#+END_SRC
|
||
|
||
**** Protocol
|
||
:PROPERTIES:
|
||
:CUSTOM_ID: h-6fa10246-26bf-4ab3-a3b0-1f58bc79350e
|
||
: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 :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 :tangle ~/org/capture/protocol-link.orgcaptmpl
|
||
,* TODO [#C] Link: %^{Title}
|
||
:PROPERTIES:
|
||
:CAPTURED: %U
|
||
:LINK: %:link
|
||
:TITLE: %:description
|
||
:END:
|
||
%?
|
||
#+END_SRC
|
||
|
||
**** Resources
|
||
:PROPERTIES:
|
||
:CUSTOM_ID: h-001eb681-1725-442d-91ef-b6a46c1784dc
|
||
: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 :tangle ~/org/capture/resource.orgcaptmpl
|
||
,* TODO [#C] %^{Title}
|
||
:PROPERTIES:
|
||
:CAPTURED: %U
|
||
:LINK: %^{Link}
|
||
:END:
|
||
%?
|
||
#+END_SRC
|
||
|
||
**** Tasks
|
||
:PROPERTIES:
|
||
:CUSTOM_ID: h-e8190e80-e2d5-4f68-84df-a760b00727e7
|
||
:END:
|
||
|
||
***** Computers and stuff
|
||
:PROPERTIES:
|
||
:CUSTOM_ID: h-96f1bf32-ff88-498f-920b-0a583f5782eb
|
||
: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 :tangle ~/org/capture/informatique.orgcaptmpl
|
||
,* TODO %^{Title}
|
||
%^{Scheduled or Deadline?||SCHEDULED||DEADLINE}: %^t
|
||
:PROPERTIES:
|
||
:CATEGORY: %^{Category}
|
||
:END:
|
||
%?
|
||
#+END_SRC
|
||
|
||
***** Health
|
||
:PROPERTIES:
|
||
:CUSTOM_ID: h-99c15553-4298-4d15-a0a1-1335ebc83cc2
|
||
:END:
|
||
This capture is rarely used (I’m lucky to have a good health), but it can
|
||
be useful.
|
||
#+BEGIN_SRC org :tangle ~/org/capture/health.orgcaptmpl
|
||
,* %^{Title}
|
||
SCHEDULED: %^t
|
||
|
||
%?
|
||
#+END_SRC
|
||
|
||
***** Birthdays
|
||
:PROPERTIES:
|
||
:CUSTOM_ID: h-e0d32ee1-cdf8-4d9e-aac6-55de262bb45e
|
||
:END:
|
||
This capture is used to store new birthdays I have to remember. They are
|
||
set to be repeated yearly.
|
||
#+BEGIN_SRC org :tangle ~/org/capture/birthday.orgcaptmpl
|
||
,* %^{Name}
|
||
SCHEDULED: %^t
|
||
#+END_SRC
|
||
|
||
Sometimes I will have a special event for one birthday, and I need to
|
||
store it in the same header as birthdays in general, they don’t need
|
||
to be repeated but they might need some more information.
|
||
#+BEGIN_SRC org :tangle ~/org/capture/birthday-event.orgcaptmpl
|
||
,* %^{Title}
|
||
%^{Scheduled or deadline?||SCHEDULED||DEADLINE}: %^t
|
||
:PROPERTIES:
|
||
:WHOM: %^{Whom’s birthday?}
|
||
:END:
|
||
%?
|
||
#+END_SRC
|
||
|
||
**** YouTube
|
||
:PROPERTIES:
|
||
:CUSTOM_ID: h-4b962a95-47d9-4410-8365-7d09e19530eb
|
||
:END:
|
||
#+BEGIN_SRC org :tangle ~/org/capture/youtube.orgcaptmpl
|
||
,* TODO [#C] %^{Title}
|
||
:PROPERTIES:
|
||
:CAPTURED: %U
|
||
:AUTHOR: %^{Author}
|
||
:LINK: %^{Link}
|
||
:END:
|
||
%?
|
||
#+END_SRC
|
||
|
||
*** Org projects
|
||
:PROPERTIES:
|
||
:CUSTOM_ID: h-a1d5b79e-a053-46b0-a5ea-d5457acd1f7e
|
||
: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: h-7559d45e-a1e8-4755-8c34-a95c80a592c7
|
||
: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:Naro:~/www/phundrak.com/www/config"
|
||
:recursive t
|
||
:language "en"
|
||
:publishing-function org-html-publish-to-html
|
||
: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-config-static
|
||
#+BEGIN_SRC emacs-lisp :tangle no
|
||
("config-website-static"
|
||
:base-directory "~/org/config/"
|
||
:base-extension "css\\|scss\\|dart\\|js\\|png\\|jpg\\|gif\\|svg\\|jpeg\\|ttf\\|woff\\|txt\\|epub\\|md"
|
||
:publishing-directory "/ssh:Naro:~/www/phundrak.com/www/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: h-a54bbe09-960f-428e-9cbd-5dabb4bb8daa
|
||
: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/web/"
|
||
:base-extension "org"
|
||
:exclude "\\./\\(CONTRIB\\|README\\|head\\|temp\\|svg-ink\\).*"
|
||
:publishing-directory "/ssh:Naro:~/www/phundrak.com/langue-phundrak-com/web"
|
||
: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/web/"
|
||
:base-extension "org"
|
||
:exclude "\\./\\(CONTRIB\\|README\\|index\\|head\\|temp\\|svg-ink\\).*"
|
||
:publishing-directory "/ssh:Naro:~/www/phundrak.com/langue-phundrak-com/web"
|
||
: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/web/"
|
||
:base-extension "css\\|scss\\|dart\\|js\\|png\\|jpg\\|gif\\|svg\\|jpeg\\|ttf\\|woff\\|txt\\|epub"
|
||
:publishing-directory "/ssh:Naro:~/www/phundrak.com/langue-phundrak-com/web"
|
||
: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
|
||
|
||
** Rust
|
||
:PROPERTIES:
|
||
:CUSTOM_ID: h-4f572b65-92eb-4ecd-beb3-75aa5c260e37
|
||
:END:
|
||
The first thing I need to set for my Rust setup is the path to ~racer~.
|
||
#+BEGIN_SRC emacs-lisp
|
||
(setq racer-cmd "~/.cargo/bin/racer")
|
||
#+END_SRC
|
||
|
||
Now, I also need to point to racer where the source code of Rust is located
|
||
so I can get some documentation.
|
||
#+BEGIN_SRC emacs-lisp
|
||
(setq racer-rust-src-path "~/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/src")
|
||
#+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: h-6b392c4b-9014-4dfa-802d-2bc0c85273b3
|
||
: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
|
||
|
||
** Shortcuts
|
||
:PROPERTIES:
|
||
:CUSTOM_ID: h-f193126f-abc1-4287-aa70-4f2080d2ef8f
|
||
:END:
|
||
As you will see, I defined a LOT of custom shortcuts. Most of them are
|
||
Spacemacs shortcuts, defined in a way they can be used seamlessly with Evil.
|
||
Only two shortcuts are defined the vanilla way for Emacs:
|
||
#+BEGIN_SRC emacs-lisp
|
||
(global-set-key (kbd "M-»") 'end-of-buffer)
|
||
(global-set-key (kbd "M-«") 'beginning-of-buffer)
|
||
#+END_SRC
|
||
|
||
Spacemacs shortcuts all begin with ~o~, which is a prefix reserved for
|
||
user-defined shortcuts 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 shortcuts that will be defined can be invoked in Normal-mode with
|
||
the src_emacs-lisp[:exports results]{(princ dotspacemacs-leader-key)} key
|
||
followed by the sequence assigned to each shortcut.
|
||
|
||
Before some more specialized categories, I have two commands which don’t fit
|
||
into any other category that I sometime use:
|
||
#+BEGIN_SRC emacs-lisp
|
||
(spacemacs/declare-prefix "oB" "byte-compile ~/.config/emacs")
|
||
(spacemacs/declare-prefix "or" "external command")
|
||
(spacemacs/set-leader-keys
|
||
"oB" (lambda () (byte-recompile-directory (expand-file-name "~/.config/emacs") 0))
|
||
"or" 'helm-run-external-command)
|
||
#+END_SRC ~oB~ byte-compiles every ~.el~ file located in the =~/.config/emacs/=
|
||
directory — it can be useful in case of package upgrade and an old ~.elc~
|
||
file still loads instead of an uncompiled but newer ~.el~ file. ~or~ on the other hand invokes an external comand the same way [[https://wiki.archlinux.org/index.php/Dmenu][dmenu]] would.
|
||
|
||
*** Applications
|
||
:PROPERTIES:
|
||
:CUSTOM_ID: h-928236e4-66e6-4d15-acd9-2748b90fdc70
|
||
: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 shortcuts in this category:
|
||
#+BEGIN_SRC emacs-lisp
|
||
(spacemacs/set-leader-keys
|
||
"oac" 'calc
|
||
"oaC" 'calendar
|
||
"oae" 'eww
|
||
"oaw" 'wttrin)
|
||
#+END_SRC ~oac~ will invoke Emacs’ calculator, while ~oac~ invokes the calendar, ~oae~
|
||
invokes the Eww navigator and ~oaw~ invokes the weather forecast.
|
||
|
||
*** Comments
|
||
:PROPERTIES:
|
||
:CUSTOM_ID: h-f91ff790-3511-471a-83ce-4071a6e33420
|
||
:END:
|
||
Some shortcuts 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 shortcuts:
|
||
#+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: h-37877887-e6d0-4e05-a2eb-566f349b76f6
|
||
:END:
|
||
This category is mainly used for opening configuration files, but it is also
|
||
more generally for files-related commands. Let’s declare the category:
|
||
#+BEGIN_SRC emacs-lisp
|
||
(spacemacs/declare-prefix "of" "files")
|
||
#+END_SRC
|
||
|
||
If a file is designated in a buffer, it is possible to open it with the
|
||
following shortcut:
|
||
#+BEGIN_SRC emacs-lisp
|
||
(spacemacs/set-leader-keys "ofo" 'find-file-at-point)
|
||
#+END_SRC
|
||
|
||
Now, Let’s declare shortcuts related to my configuration files. Here is the
|
||
list of them:
|
||
- [[file:bin.org][bin.org]] :: contains the source code of my custom scripts in my ~$PATH~
|
||
- [[file:spacemacs.org][spacemacs.org]] :: this file, configuration of Emacs
|
||
- [[file:fish.org][fish.org]] :: configuration of my fish shell
|
||
- [[file:i3.org][i3.org]] :: configuration of my i3 installation
|
||
- [[file:index.org][index.org]] :: some various configuration files and index of this website
|
||
- [[file:polybar.org][polybar.org]] :: configuration polybar
|
||
- [[https://labs.phundrak.com/phundrak/dotfiles][README.org]] :: README of the yadm repo
|
||
Each of these files are accessible through a simple shortcut, and each one
|
||
of them has a description so the shortcut doesn’t show up as ~lambda~ with ~which-keys~.
|
||
#+BEGIN_SRC emacs-lisp
|
||
(spacemacs/declare-prefix "ofb" "bin.org")
|
||
(spacemacs/declare-prefix "ofe" "spacemacs.org")
|
||
(spacemacs/declare-prefix "off" "fish.org")
|
||
(spacemacs/declare-prefix "ofi" "i3.org")
|
||
(spacemacs/declare-prefix "ofI" "index.org")
|
||
(spacemacs/declare-prefix "ofp" "polybar.org")
|
||
(spacemacs/declare-prefix "ofP" "picom.org")
|
||
(spacemacs/declare-prefix "ofr" "yadm README")
|
||
(spacemacs/set-leader-keys
|
||
"ofb" (lambda () (interactive) (find-file "~/org/config/bin.org"))
|
||
"ofe" (lambda () (interactive) (find-file "~/org/config/spacemacs.org"))
|
||
"off" (lambda () (interactive) (find-file "~/org/config/fish.org"))
|
||
"ofi" (lambda () (interactive) (find-file "~/org/config/i3.org"))
|
||
"ofI" (lambda () (interactive) (find-file "~/org/config/index.org"))
|
||
"ofp" (lambda () (interactive) (find-file "~/org/config/polybar.org"))
|
||
"ofP" (lambda () (interactive) (find-file "~/org/config/picom.org"))
|
||
"ofr" (lambda () (interactive) (find-file "~/README.org")))
|
||
#+END_SRC
|
||
|
||
I also want a quick access to my notes and my journal.
|
||
#+BEGIN_SRC emacs-lisp
|
||
(spacemacs/declare-prefix "ofj" "journal.org")
|
||
(spacemacs/declare-prefix "ofn" "notes.org")
|
||
(spacemacs/set-leader-keys
|
||
"ofj" (lambda () (interactive) (find-file "~/org/journal.org"))
|
||
"ofn" (lambda () (interactive) (find-file "~/org/notes.org")))
|
||
#+END_SRC
|
||
|
||
*** Multiple cursors
|
||
:PROPERTIES:
|
||
:CUSTOM_ID: h-de40bea1-4301-4ad3-b3f1-c4c8ed029feb
|
||
: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: h-beb15231-9718-4581-95dd-444c57190ee8
|
||
:END:
|
||
Now, onto some shortcuts related to org-mode. Let’s first declare the
|
||
category:
|
||
#+BEGIN_SRC emacs-lisp
|
||
(spacemacs/declare-prefix "oo" "org-mode")
|
||
(spacemacs/declare-prefix-for-mode 'org-mode "o" "custom" "User-defined keybindings")
|
||
#+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
|
||
"op" 'org-pomodoro
|
||
"os" 'org-insert-structure-template
|
||
"oT" 'org-sidebar-tree)
|
||
#+END_SRC ~oss~ allows me to insert an org structure template defined in ~org-structure-template-alist~ (see [[#h-81bcc367-4b2a-4a10-b42c-7b3cb7fd2d60][User Configuration/Org-mode/Org
|
||
Variables/Org behavior]]), while ~ooT~ displays the outline of the current org
|
||
file. ~oot~ is the prefix for tree-related operations:
|
||
#+BEGIN_SRC emacs-lisp
|
||
(spacemacs/declare-prefix "oot" "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 "oott" "toggle width")
|
||
(spacemacs/declare-prefix-for-mode 'org-mode "oote" "expand")
|
||
(spacemacs/declare-prefix-for-mode 'org-mode "oots" "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)
|
||
#+END_SRC
|
||
|
||
*** Toggle
|
||
:PROPERTIES:
|
||
:CUSTOM_ID: h-25a07df0-02b5-4e6e-a8a3-94a00dbbc54f
|
||
: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: h-1852f9ec-e2ca-495b-a72e-c3258add8033
|
||
: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
|
||
|
||
#+RESULTS:
|
||
|
||
** Yadm
|
||
:PROPERTIES:
|
||
:CUSTOM_ID: h-fb5284ed-9862-4ba5-9d92-78b466ab65f8
|
||
: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: h-a471c99d-e731-4196-9e69-beb0359962bd
|
||
: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/spacemacs.org][labs.phundrak.com/phundrak/dotfiles/src/branch/master/org/config/spacemacs.org]]
|