[Misc] switching to new repo for org files
This commit is contained in:
1703
docs/emacs/packages/applications.org
Normal file
1703
docs/emacs/packages/applications.org
Normal file
File diff suppressed because it is too large
Load Diff
310
docs/emacs/packages/autocompletion.org
Normal file
310
docs/emacs/packages/autocompletion.org
Normal file
@@ -0,0 +1,310 @@
|
||||
#+title: Emacs — Packages — Autocompletion
|
||||
#+setupfile: ../../headers
|
||||
#+property: header-args:emacs-lisp :mkdirp yes :lexical t :exports code
|
||||
#+property: header-args:emacs-lisp+ :tangle ~/.config/emacs/lisp/autocompletion.el
|
||||
#+property: header-args:emacs-lisp+ :mkdirp yes :noweb no-export
|
||||
|
||||
* Autocompletion
|
||||
** Code Autocompletion
|
||||
Company is, in my opinion, the best autocompleting engine for Emacs,
|
||||
and it is one of the most popular if not /the/ most popular.
|
||||
#+begin_src emacs-lisp
|
||||
(use-package company
|
||||
:straight (:build t)
|
||||
:defer t
|
||||
:hook (company-mode . evil-normalize-keymaps)
|
||||
:init (global-company-mode)
|
||||
:config
|
||||
(setq company-minimum-prefix-length 2
|
||||
company-toolsip-limit 14
|
||||
company-tooltip-align-annotations t
|
||||
company-require-match 'never
|
||||
company-global-modes '(not erc-mode message-mode help-mode gud-mode)
|
||||
company-frontends
|
||||
'(company-pseudo-tooltip-frontend ; always show candidates in overlay tooltip
|
||||
company-echo-metadata-frontend) ; show selected candidate docs in echo area
|
||||
company-backends '(company-capf)
|
||||
company-auto-commit nil
|
||||
company-auto-complete-chars nil
|
||||
company-dabbrev-other-buffers nil
|
||||
company-dabbrev-ignore-case nil
|
||||
company-dabbrev-downcase nil))
|
||||
#+end_src
|
||||
|
||||
This package is a backend for company. It emulates
|
||||
~ac-source-dictionary~ by proposing text related to the current
|
||||
major-mode.
|
||||
#+begin_src emacs-lisp
|
||||
(use-package company-dict
|
||||
:after company
|
||||
:straight (:build t)
|
||||
:config
|
||||
(setq company-dict-dir (expand-file-name "dicts" user-emacs-directory)))
|
||||
#+end_src
|
||||
|
||||
On the other hand, ~company-box~ is a Company front-end which offers
|
||||
colors, icons, documentation and so on. Very nice.
|
||||
|
||||
Declaring all the icons for the variable
|
||||
~company-box-icons-all-the-icons~ is quite verbose in Elisp, so I do it
|
||||
with an org-table.
|
||||
#+name: company-box-icons
|
||||
| Type | Icon | Color |
|
||||
|---------------+--------------------------+--------|
|
||||
| Unknown | find_in_page | purple |
|
||||
| Text | text_fields | green |
|
||||
| Method | functions | red |
|
||||
| Function | functions | red |
|
||||
| Constructor | functions | red |
|
||||
| Field | functions | red |
|
||||
| Variable | adjust | blue |
|
||||
| Class | class | red |
|
||||
| Interface | settings_input_component | red |
|
||||
| Module | view_module | red |
|
||||
| Property | settings | red |
|
||||
| Unit | straighten | red |
|
||||
| Value | filter_1 | red |
|
||||
| Enum | plus_one | red |
|
||||
| Keyword | filter_center_focus | red |
|
||||
| Snippet | short_text | red |
|
||||
| Color | color_lens | red |
|
||||
| File | insert_drive_file | red |
|
||||
| Reference | collections_bookmark | red |
|
||||
| Folder | folder | red |
|
||||
| EnumMember | people | red |
|
||||
| Constant | pause_circle_filled | red |
|
||||
| Struct | streetview | red |
|
||||
| Event | event | red |
|
||||
| Operator | control_point | red |
|
||||
| TypeParameter | class | red |
|
||||
| Template | short_text | green |
|
||||
| ElispFunction | functions | red |
|
||||
| ElispVariable | check_circle | blue |
|
||||
| ElispFeature | stars | orange |
|
||||
| ElispFace | format_paint | pink |
|
||||
|
||||
#+name: gen-company-box-icons
|
||||
#+headers: :tangle no :noweb yes :exports none :cache yes
|
||||
#+header: :wrap "src emacs-lisp :exports none :tangle no"
|
||||
#+begin_src emacs-lisp :var table=company-box-icons
|
||||
(mapconcat (lambda (row)
|
||||
(format "(%s . ,(all-the-icons-material \"%s\" :face 'all-the-icons-%s))"
|
||||
(car row)
|
||||
(cadr row)
|
||||
(caddr row)))
|
||||
table
|
||||
"\n")
|
||||
#+end_src
|
||||
|
||||
#+RESULTS[8ebf4bb3f7f354571a5d42cf58f8b9ba847ba028]: gen-company-box-icons
|
||||
#+begin_src emacs-lisp :exports none :tangle no
|
||||
(Unknown . ,(all-the-icons-material "find_in_page" :face 'all-the-icons-purple))
|
||||
(Text . ,(all-the-icons-material "text_fields" :face 'all-the-icons-green))
|
||||
(Method . ,(all-the-icons-material "functions" :face 'all-the-icons-red))
|
||||
(Function . ,(all-the-icons-material "functions" :face 'all-the-icons-red))
|
||||
(Constructor . ,(all-the-icons-material "functions" :face 'all-the-icons-red))
|
||||
(Field . ,(all-the-icons-material "functions" :face 'all-the-icons-red))
|
||||
(Variable . ,(all-the-icons-material "adjust" :face 'all-the-icons-blue))
|
||||
(Class . ,(all-the-icons-material "class" :face 'all-the-icons-red))
|
||||
(Interface . ,(all-the-icons-material "settings_input_component" :face 'all-the-icons-red))
|
||||
(Module . ,(all-the-icons-material "view_module" :face 'all-the-icons-red))
|
||||
(Property . ,(all-the-icons-material "settings" :face 'all-the-icons-red))
|
||||
(Unit . ,(all-the-icons-material "straighten" :face 'all-the-icons-red))
|
||||
(Value . ,(all-the-icons-material "filter_1" :face 'all-the-icons-red))
|
||||
(Enum . ,(all-the-icons-material "plus_one" :face 'all-the-icons-red))
|
||||
(Keyword . ,(all-the-icons-material "filter_center_focus" :face 'all-the-icons-red))
|
||||
(Snippet . ,(all-the-icons-material "short_text" :face 'all-the-icons-red))
|
||||
(Color . ,(all-the-icons-material "color_lens" :face 'all-the-icons-red))
|
||||
(File . ,(all-the-icons-material "insert_drive_file" :face 'all-the-icons-red))
|
||||
(Reference . ,(all-the-icons-material "collections_bookmark" :face 'all-the-icons-red))
|
||||
(Folder . ,(all-the-icons-material "folder" :face 'all-the-icons-red))
|
||||
(EnumMember . ,(all-the-icons-material "people" :face 'all-the-icons-red))
|
||||
(Constant . ,(all-the-icons-material "pause_circle_filled" :face 'all-the-icons-red))
|
||||
(Struct . ,(all-the-icons-material "streetview" :face 'all-the-icons-red))
|
||||
(Event . ,(all-the-icons-material "event" :face 'all-the-icons-red))
|
||||
(Operator . ,(all-the-icons-material "control_point" :face 'all-the-icons-red))
|
||||
(TypeParameter . ,(all-the-icons-material "class" :face 'all-the-icons-red))
|
||||
(Template . ,(all-the-icons-material "short_text" :face 'all-the-icons-green))
|
||||
(ElispFunction . ,(all-the-icons-material "functions" :face 'all-the-icons-red))
|
||||
(ElispVariable . ,(all-the-icons-material "check_circle" :face 'all-the-icons-blue))
|
||||
(ElispFeature . ,(all-the-icons-material "stars" :face 'all-the-icons-orange))
|
||||
(ElispFace . ,(all-the-icons-material "format_paint" :face 'all-the-icons-pink))
|
||||
#+end_src
|
||||
|
||||
#+begin_src emacs-lisp
|
||||
(use-package company-box
|
||||
:straight (:build t)
|
||||
:after (company all-the-icons)
|
||||
:config
|
||||
(setq company-box-show-single-candidate t
|
||||
company-box-backends-colors nil
|
||||
company-box-max-candidates 50
|
||||
company-box-icons-alist 'company-box-icons-all-the-icons
|
||||
company-box-icons-all-the-icons
|
||||
(let ((all-the-icons-scale-factor 0.8))
|
||||
`(
|
||||
<<gen-company-box-icons()>>))))
|
||||
#+end_src
|
||||
|
||||
** Ivy
|
||||
My main menu package is =ivy= which I use as much as possible –I’ve
|
||||
noticed =helm= can be slow, very slow in comparison to =ivy=, so I’ll use
|
||||
the latter as much as possible. Actually, only =ivy= is installed for
|
||||
now. I could have used =ido= too, but I find it to be a bit too
|
||||
restricted in terms of features compared to =ivy=.
|
||||
#+begin_src emacs-lisp
|
||||
(use-package ivy
|
||||
:straight t
|
||||
:defer t
|
||||
:diminish
|
||||
:bind (("C-s" . swiper)
|
||||
:map ivy-minibuffer-map
|
||||
("TAB" . ivy-alt-done)
|
||||
("C-l" . ivy-alt-done)
|
||||
("C-t" . ivy-next-line)
|
||||
("C-s" . ivy-previous-line)
|
||||
("C-u" . ivy-scroll-up-command)
|
||||
("C-d" . ivy-scroll-down-command)
|
||||
:map ivy-switch-buffer-map
|
||||
("C-t" . ivy-next-line)
|
||||
("C-s" . ivy-previous-line)
|
||||
("C-l" . ivy-done)
|
||||
("C-d" . ivy-switch-buffer-kill)
|
||||
:map ivy-reverse-i-search-map
|
||||
("C-t" . ivy-next-line)
|
||||
("C-s" . ivy-previous-line)
|
||||
("C-d" . ivy-reverse-i-search-kill))
|
||||
:config
|
||||
(ivy-mode 1)
|
||||
(setq ivy-wrap t
|
||||
ivy-height 17
|
||||
ivy-sort-max-size 50000
|
||||
ivy-fixed-height-minibuffer t
|
||||
ivy-read-action-functions #'ivy-hydra-read-action
|
||||
ivy-read-action-format-function #'ivy-read-action-format-columns
|
||||
projectile-completion-system 'ivy
|
||||
ivy-on-del-error-function #'ignore
|
||||
ivy-use-selectable-prompt t))
|
||||
#+end_src
|
||||
|
||||
There is also [[https://github.com/raxod502/prescient.el][~prescient.el~]] that offers some nice features when
|
||||
coupled with ~ivy~, guess what was born out of it? ~ivy-prescient~, of
|
||||
course!
|
||||
#+begin_src emacs-lisp
|
||||
(use-package ivy-prescient
|
||||
:after ivy
|
||||
:straight (:build t))
|
||||
#+end_src
|
||||
|
||||
I warned you I’d use too much ~all-the-icons~, I did!
|
||||
#+begin_src emacs-lisp
|
||||
(use-package all-the-icons-ivy
|
||||
:straight (:build t)
|
||||
:after (ivy all-the-icons)
|
||||
:init (all-the-icons-ivy-setup)
|
||||
:hook (after-init . all-the-icons-ivy-setup))
|
||||
(all-the-icons-ivy-setup)
|
||||
#+end_src
|
||||
|
||||
A buffer popping at the bottom of the screen is nice and all, but have
|
||||
you considered a floating buffer in the center of your frame?
|
||||
#+begin_src emacs-lisp
|
||||
(use-package ivy-posframe
|
||||
:defer t
|
||||
:after (:any ivy helpful)
|
||||
:hook (ivy-mode . ivy-posframe-mode)
|
||||
:straight (:build t)
|
||||
:init
|
||||
(ivy-posframe-mode 1)
|
||||
:config
|
||||
(setq ivy-fixed-height-minibuffer nil
|
||||
ivy-posframe-border-width 10
|
||||
ivy-posframe-parameters
|
||||
`((min-width . 90)
|
||||
(min-height . ,ivy-height))))
|
||||
#+end_src
|
||||
|
||||
Something that can be missing sometimes in Ivy is the ability to
|
||||
select multiple entries at once. For instance, when programming in
|
||||
Java, LPS can offer you to automatically generate the methods ~equals~
|
||||
and ~hashCode~ based on selected members, but with vanilla Ivy, you can
|
||||
only select one. Not really useful. ~ivy-hydra~ is a package that offers
|
||||
a Hydra interface when in Ivy which allows you to select multiple
|
||||
choices among other things.
|
||||
#+begin_src emacs-lisp
|
||||
(use-package ivy-hydra
|
||||
:requires (ivy hydra)
|
||||
:after ivy
|
||||
:straight (:build t))
|
||||
#+end_src
|
||||
|
||||
Finally, let’s make ~ivy~ richer:
|
||||
#+begin_src emacs-lisp
|
||||
(use-package ivy-rich
|
||||
:straight (:build t)
|
||||
:after ivy
|
||||
:init
|
||||
(ivy-rich-mode 1))
|
||||
#+end_src
|
||||
|
||||
** Counsel
|
||||
I could almost merge this chapter with the previous one since counsel
|
||||
is a package that provides loads of completion functions for ivy. The
|
||||
ones I find most useful are ~counsel-M-x~ and ~counsel-find-file~.
|
||||
#+begin_src emacs-lisp
|
||||
(use-package counsel
|
||||
:straight t
|
||||
:after recentf
|
||||
:after ivy
|
||||
:bind (("M-x" . counsel-M-x)
|
||||
("C-x b" . counsel-ibuffer)
|
||||
("C-x C-f" . counsel-find-file)
|
||||
:map minibuffer-local-map
|
||||
("C-r" . 'counsel-minibuffer-history)))
|
||||
#+end_src
|
||||
|
||||
** Yasnippet
|
||||
Yasnippet allows you to insert some pre-made code by just typing a few
|
||||
characters. It can even generate some string with Elisp expressions
|
||||
and ask the user for some input in some precise places.
|
||||
#+begin_src emacs-lisp
|
||||
(use-package yasnippet
|
||||
:defer t
|
||||
:straight (:build t)
|
||||
:init
|
||||
(yas-global-mode)
|
||||
:hook ((prog-mode . yas-minor-mode)
|
||||
(text-mode . yas-minor-mode)))
|
||||
#+end_src
|
||||
|
||||
Of course, yasnippet wouldn’t be as awesome as it is without pre-made
|
||||
snippets.
|
||||
#+begin_src emacs-lisp
|
||||
(use-package yasnippet-snippets
|
||||
:defer t
|
||||
:after yasnippet
|
||||
:straight (:build t))
|
||||
#+end_src
|
||||
|
||||
Similarly, yatemplate offers pre-made files rather than just strings.
|
||||
That’s still yasnippet by the way.
|
||||
#+begin_src emacs-lisp
|
||||
(use-package yatemplate
|
||||
:defer t
|
||||
:after yasnippet
|
||||
:straight (:build t))
|
||||
#+end_src
|
||||
|
||||
And finally, with ivy you can choose your snippets from a menu if
|
||||
you’re not sure or if you don’t remember what your snippet is.
|
||||
#+begin_src emacs-lisp
|
||||
(use-package ivy-yasnippet
|
||||
:defer t
|
||||
:after (ivy yasnippet)
|
||||
:straight (:build t)
|
||||
:general
|
||||
(phundrak/leader-key
|
||||
:infix "i"
|
||||
:packages 'ivy-yasnippet
|
||||
"y" #'ivy-yasnippet))
|
||||
#+end_src
|
||||
174
docs/emacs/packages/editing.org
Normal file
174
docs/emacs/packages/editing.org
Normal file
@@ -0,0 +1,174 @@
|
||||
#+title: Emacs — Packages — Editing
|
||||
#+setupfile: ../../headers
|
||||
#+property: header-args:emacs-lisp :mkdirp yes :lexical t :exports code
|
||||
#+property: header-args:emacs-lisp+ :tangle ~/.config/emacs/lisp/editing.el
|
||||
#+property: header-args:emacs-lisp+ :mkdirp yes :noweb no-export
|
||||
|
||||
|
||||
* Editing
|
||||
First, I’ll define some keybindings for easily inserting pairs when
|
||||
editing text.
|
||||
#+begin_src emacs-lisp
|
||||
(general-define-key
|
||||
:states 'visual
|
||||
"M-[" #'insert-pair
|
||||
"M-{" #'insert-pair
|
||||
"M-<" #'insert-pair
|
||||
"M-'" #'insert-pair
|
||||
"M-`" #'insert-pair
|
||||
"M-\"" #'insert-pair)
|
||||
#+end_src
|
||||
|
||||
** Atomic Chrome
|
||||
Why write in your browser when you could write with Emacs? Despite its
|
||||
name, this package isn’t only geared towards Chrome/Chromium-based
|
||||
browsers but also towards Firefox since its 2.0 version. I find it a
|
||||
bit unfortunate Chrome’s name stuck in the package’s name though.
|
||||
#+begin_src emacs-lisp
|
||||
(use-package atomic-chrome
|
||||
:straight (:build t)
|
||||
:init
|
||||
(atomic-chrome-start-server)
|
||||
:config
|
||||
(setq atomic-chrome-default-major-mode 'markdown-mode
|
||||
atomic-chrome-url-major-mode-alist `(("github\\.com" . gfm-mode)
|
||||
("gitlab\\.com" . gfm-mode)
|
||||
("labs\\.phundrak\\.com" . markdown-mode)
|
||||
("reddit\\.com" . markdown-mode))))
|
||||
#+end_src
|
||||
|
||||
** Editorconfig
|
||||
Editorconfig is a unified way of passing to your text editor settings
|
||||
everyone working in a repo need to follow. ~.editorconfig~ files work
|
||||
for VSCode users, vim users, Atom users, Sublime users, and of course
|
||||
Emacs users.
|
||||
#+begin_src emacs-lisp
|
||||
(use-package editorconfig
|
||||
:defer t
|
||||
:straight (:build t)
|
||||
:diminish editorconfig-mode
|
||||
:init
|
||||
(editorconfig-mode t))
|
||||
#+end_src
|
||||
|
||||
** Evil Nerd Commenter
|
||||
Emacs’ default commenting system is nice, but I don’t find it smart
|
||||
enough for me.
|
||||
#+begin_src emacs-lisp
|
||||
(use-package evil-nerd-commenter
|
||||
:after evil
|
||||
:straight (:build t))
|
||||
#+end_src
|
||||
|
||||
** Iedit
|
||||
Iedit is a powerful text editing tool that can be used to refactor
|
||||
code through the edition of multiple regions at once, be it in a
|
||||
region or in a whole buffer. Since I’m using evil, I’ll also use a
|
||||
compatibility package that adds states for iedit.
|
||||
#+begin_src emacs-lisp
|
||||
(use-package evil-iedit-state
|
||||
:defer t
|
||||
:straight (:build t)
|
||||
:commands (evil-iedit-state evil-iedit-state/iedit-mode)
|
||||
:init
|
||||
(setq iedit-curent-symbol-default t
|
||||
iedit-only-at-symbol-boundaries t
|
||||
iedit-toggle-key-default nil)
|
||||
:general
|
||||
(phundrak/leader-key
|
||||
:infix "r"
|
||||
:packages '(iedit evil-iedit-state)
|
||||
"" '(:ignore t :which-key "refactor")
|
||||
"i" #'evil-iedit-state/iedit-mode)
|
||||
(general-define-key
|
||||
:keymaps 'evil-iedit-state-map
|
||||
"c" nil
|
||||
"s" nil
|
||||
"J" nil
|
||||
"S" #'iedit-expand-down-a-line
|
||||
"T" #'iedit-expand-up-a-line
|
||||
"h" #'evil-iedit-state/evil-change
|
||||
"k" #'evil-iedit-state/evil-substitute
|
||||
"K" #'evil-iedit-state/substitute
|
||||
"q" #'evil-iedit-state/quit-iedit-mode))
|
||||
#+end_src
|
||||
|
||||
** Smartparens
|
||||
#+begin_src emacs-lisp
|
||||
(use-package smartparens
|
||||
:straight (:build t)
|
||||
:defer t)
|
||||
#+end_src
|
||||
|
||||
** Parinfer
|
||||
Don’t let the name of the package fool you! ~parinfer-rust-mode~ is not
|
||||
a ~parinfer~ mode for ~rust-mode~, but a mode for ~parinfer-rust~. ~parinfer~
|
||||
was a project for handling parenthesis and other double markers in a
|
||||
much more intuitive way when writing Lisp code. However, it is now out
|
||||
of date (last commit was on January 2nd, 2019) and the repository has
|
||||
since been archived. New implementations then appeared, one of them is
|
||||
[[https://github.com/eraserhd/parinfer-rust][~parinfer-rust~]], obviously written in Rust, around which
|
||||
~parinfer-rust-mode~ is built. Enabling ~parinfer-rust-mode~ should also
|
||||
automatically disable ~smartparens-mode~ in order to avoid conflicting
|
||||
behavior.
|
||||
#+begin_src emacs-lisp
|
||||
(use-package parinfer-rust-mode
|
||||
:defer t
|
||||
:straight (:build t)
|
||||
:diminish parinfer-rust-mode
|
||||
:hook emacs-lisp-mode common-lisp-mode scheme-mode
|
||||
:init
|
||||
(setq parinfer-rust-auto-download t
|
||||
parinfer-rust-library-directory (concat user-emacs-directory
|
||||
"parinfer-rust/"))
|
||||
(add-hook 'parinfer-rust-mode-hook
|
||||
(lambda () (smartparens-mode -1)))
|
||||
:general
|
||||
(phundrak/major-leader-key
|
||||
:keymaps 'parinfer-rust-mode-map
|
||||
"m" #'parinfer-rust-switch-mode
|
||||
"M" #'parinfer-rust-toggle-disable))
|
||||
#+end_src
|
||||
|
||||
** Smartparens
|
||||
~smartparens~ is a package similar to ~parinfer~, but while the latter is
|
||||
more specialized for Lisp dialects, ~smartparens~ works better with
|
||||
other programming languages that still uses parenthesis, but not as
|
||||
much as Lisp dialects; think for example C, C++, Rust, Javascript, and
|
||||
so on.
|
||||
#+begin_src emacs-lisp
|
||||
(use-package smartparens
|
||||
:defer t
|
||||
:straight (smartparens :build t
|
||||
:type git
|
||||
:host github
|
||||
:repo "Fuco1/smartparens")
|
||||
:hook (prog-mode . smartparens-mode))
|
||||
#+end_src
|
||||
|
||||
** ~string-edit~
|
||||
~string-edit~ is a cool package that allows the user to write naturally
|
||||
a string and get it automatically escaped for you. No more manually
|
||||
escaping your strings!
|
||||
#+begin_src emacs-lisp
|
||||
(use-package string-edit-at-point
|
||||
:defer t
|
||||
:straight (:build t))
|
||||
#+end_src
|
||||
|
||||
** Writeroom
|
||||
On the other hand, ~writeroom~ allows the user to enter a
|
||||
distraction-free mode of Emacs, and I like that! But the default width
|
||||
is a bit too small for me, and I prefer not to go fullscren.
|
||||
#+begin_src emacs-lisp
|
||||
(use-package writeroom-mode
|
||||
:defer t
|
||||
:straight (:build t)
|
||||
:init (global-writeroom-mode 1)
|
||||
:config
|
||||
(setq writeroom-width 100
|
||||
writeroom-fullscreen-effect nil
|
||||
writeroom-maximize-window nil
|
||||
writeroom-mode-line t
|
||||
writeroom-major-modes '(text-mode org-mode markdown-mode nov-mode Info-mode)))
|
||||
#+end_src
|
||||
496
docs/emacs/packages/emacs-builtin.org
Normal file
496
docs/emacs/packages/emacs-builtin.org
Normal file
@@ -0,0 +1,496 @@
|
||||
#+title: Emacs — Packages — Emacs Built-ins
|
||||
#+setupfile: ../../headers
|
||||
#+property: header-args:emacs-lisp :mkdirp yes :lexical t :exports code
|
||||
#+property: header-args:emacs-lisp+ :tangle ~/.config/emacs/lisp/emacs-builtin.el
|
||||
#+property: header-args:emacs-lisp+ :mkdirp yes :noweb no-export
|
||||
|
||||
|
||||
* Emacs built-ins
|
||||
** Dired
|
||||
Dired is Emacs’ built-in file manager. It’s really great, and replaces
|
||||
any graphical file manager for me most of the time because:
|
||||
- I am not limited to /x/ tabs or panes
|
||||
- All actions can be done with keybindings
|
||||
- I get a consistent behavior between Dired and Emacs, since it’s the
|
||||
same thing.
|
||||
I used to have an extensive configuration for Dired with a couple of
|
||||
additional packages to make it more usable. Dirvish rendered that
|
||||
obsolete!
|
||||
#+begin_src emacs-lisp
|
||||
(use-package dirvish
|
||||
:straight (:build t)
|
||||
:defer t
|
||||
:init (dirvish-override-dired-mode)
|
||||
:custom
|
||||
(dirvish-quick-access-entries
|
||||
'(("h" "~/" "Home")
|
||||
("d" "~/Downloads/" "Downloads")
|
||||
("c" "~/org/config" "Config")
|
||||
("C" "~/Documents/conlanging/content" "Conlanging")))
|
||||
(dirvish-mode-line-format
|
||||
'(:left (sort file-time "" file-size symlink) :right (omit yank index)))
|
||||
(dirvish-attributes '(all-the-icons file-size collapse subtree-state vc-state git-msg))
|
||||
:config
|
||||
(dirvish-peek-mode)
|
||||
<<dired-drag-and-drop>>
|
||||
<<dired-listing-flags>>
|
||||
<<dired-files-and-dirs>>
|
||||
<<dirvish-exa-offload>>
|
||||
(setq dired-dwim-target t
|
||||
dired-recursive-copies 'always
|
||||
dired-recursive-deletes 'top
|
||||
delete-by-moving-to-trash t
|
||||
dirvish-preview-dispatchers (cl-substitute 'pdf-preface 'pdf dirvish-preview-dispatchers))
|
||||
:general
|
||||
(phundrak/evil
|
||||
:keymaps 'dirvish-mode-map
|
||||
:packages '(dired dirvish)
|
||||
"q" #'dirvish-quit
|
||||
"TAB" #'dirvish-subtree-toggle)
|
||||
(phundrak/major-leader-key
|
||||
:keymaps 'dirvish-mode-map
|
||||
:packages '(dired dirvish)
|
||||
"A" #'gnus-dired-attach
|
||||
"a" #'dirvish-quick-access
|
||||
"d" #'dirvish-dispatch
|
||||
"e" #'dirvish-emerge-menu
|
||||
"f" #'dirvish-fd-jump
|
||||
"F" #'dirvish-file-info-menu
|
||||
"h" '(:ignore t :which-key "history")
|
||||
"hp" #'dirvish-history-go-backward
|
||||
"hn" #'dirvish-history-go-forward
|
||||
"hj" #'dirvish-history-jump
|
||||
"hl" #'dirvish-history-last
|
||||
"l" '(:ignore t :which-key "layout")
|
||||
"ls" #'dirvish-layout-switch
|
||||
"lt" #'dirvish-layout-toggle
|
||||
"m" #'dirvish-mark-menu
|
||||
"s" #'dirvish-quicksort
|
||||
"S" #'dirvish-setup-menu
|
||||
"y" #'dirvish-yank-menu
|
||||
"n" #'dirvish-narrow))
|
||||
#+end_src
|
||||
|
||||
It requires some programs which can be installed like so:
|
||||
#+begin_src sh :dir /sudo::~/ :exports code :tangle no :results verbatim
|
||||
pacman -S --needed --noprogressbar --noconfirm --color=never \
|
||||
fd poppler ffmpegthumbnailer mediainfo imagemagick tar unzip
|
||||
#+end_src
|
||||
|
||||
Since Emacs 29, it is possible to enable drag-and-drop between Emacs
|
||||
and other applications.
|
||||
#+name: dired-drag-and-drop
|
||||
#+begin_src emacs-lisp :tangle no
|
||||
(csetq dired-mouse-drag-files t
|
||||
mouse-drag-and-drop-region-cross-program t)
|
||||
#+end_src
|
||||
|
||||
In Dirvish, it’s best to use the long name of flags whenever possible,
|
||||
otherwise some commands won’t work.
|
||||
#+name: dired-listing-flags
|
||||
#+begin_src emacs-lisp :tangle no
|
||||
(csetq dired-listing-switches (string-join '("--all"
|
||||
"--human-readable"
|
||||
"--time-style=long-iso"
|
||||
"--group-directories-first"
|
||||
"-lv1")
|
||||
" "))
|
||||
#+end_src
|
||||
|
||||
However, it is possible to instead use ~exa~ when it is available.
|
||||
Instead of making Emacs’ main thread to the file listing in a
|
||||
directory, we offload it to an external thread.
|
||||
#+name: dirvish-exa-offload
|
||||
#+begin_src emacs-lisp :tangle no
|
||||
(dirvish-define-preview exa (file)
|
||||
"Use `exa' to generate directory preview."
|
||||
:require ("exa")
|
||||
(when (file-directory-p file)
|
||||
`(shell . ("exa" "--color=always" "-al" ,file))))
|
||||
|
||||
(add-to-list 'dirvish-preview-dispatchers 'exa)
|
||||
#+end_src
|
||||
|
||||
Finally, some directories need to be set for Dired to store various
|
||||
files and images.
|
||||
#+name: dired-files-and-dirs
|
||||
#+begin_src emacs-lisp :tangle no
|
||||
(let ((my/file (lambda (path &optional dir)
|
||||
(expand-file-name path (or dir user-emacs-directory))))
|
||||
(my/dir (lambda (path &optional dir)
|
||||
(expand-file-name (file-name-as-directory path)
|
||||
(or dir user-emacs-directory)))))
|
||||
(csetq image-dired-thumb-size 150
|
||||
image-dired-dir (funcall my/dir "dired-img")
|
||||
image-dired-db-file (funcall my/file "dired-db.el")
|
||||
image-dired-gallery-dir (funcall my/dir "gallery")
|
||||
image-dired-temp-image-file (funcall my/file "temp-image" image-dired-dir)
|
||||
image-dired-temp-rotate-image-file (funcall my/file "temp-rotate-image" image-dired-dir)))
|
||||
#+end_src
|
||||
|
||||
Copying files with Dired is a blocking process. It’s usually fine when
|
||||
there’s not a lot to copy, but it becomes annoying when moving larger
|
||||
files. The package ~dired-rsync~ allows copying files with ~rsync~ in the
|
||||
background; we can then carry on with our tasks while the copy is
|
||||
happening.
|
||||
#+begin_src emacs-lisp
|
||||
(use-package dired-rsync
|
||||
:if (executable-find "rsync")
|
||||
:defer t
|
||||
:straight (:build t)
|
||||
:general
|
||||
(phundrak/evil
|
||||
:keymaps 'dired-mode-map
|
||||
:packages 'dired-rsync
|
||||
"C-r" #'dired-rsync))
|
||||
#+end_src
|
||||
|
||||
** Compilation mode
|
||||
After reading about a blog article, I found out it is possible to run
|
||||
quite a few things through ~compilation-mode~, so why not? First, let’s
|
||||
redefine some keybinds for this mode. I’ll also define a general
|
||||
keybind in order to re-run my programs from other buffers than the
|
||||
~compilation-mode~ buffer. I also want to follow the output of the
|
||||
compilation buffer, as well as enable some syntax highlighting.
|
||||
#+begin_src emacs-lisp
|
||||
(use-package compile
|
||||
:defer t
|
||||
:straight (compile :type built-in)
|
||||
:hook (compilation-filter . colorize-compilation-buffer)
|
||||
:init
|
||||
(require 'ansi-color)
|
||||
(defun colorize-compilation-buffer ()
|
||||
(let ((inhibit-read-only t))
|
||||
(ansi-color-apply-on-region (point-min) (point-max))))
|
||||
:general
|
||||
(phundrak/evil
|
||||
:keymaps 'compilation-mode-map
|
||||
"g" nil
|
||||
"r" nil
|
||||
"R" #'recompile
|
||||
"h" nil)
|
||||
(phundrak/leader-key
|
||||
"R" #'recompile)
|
||||
:config
|
||||
(setq compilation-scroll-output t))
|
||||
#+end_src
|
||||
|
||||
** Eshell
|
||||
[[file:../img/emacs-eshell.svg]]
|
||||
|
||||
Eshell is a built-in shell available from Emacs which I use almost as
|
||||
often as fish. Some adjustments are necessary to make it fit my taste
|
||||
though.
|
||||
#+begin_src emacs-lisp
|
||||
(use-package eshell
|
||||
:defer t
|
||||
:straight (:type built-in :build t)
|
||||
:config
|
||||
(setq eshell-prompt-function
|
||||
(lambda ()
|
||||
(concat (abbreviate-file-name (eshell/pwd))
|
||||
(if (= (user-uid) 0) " # " " λ ")))
|
||||
eshell-prompt-regexp "^[^#λ\n]* [#λ] ")
|
||||
<<eshell-alias-file>>
|
||||
<<eshell-concat-shell-command>>
|
||||
<<eshell-alias-open>>
|
||||
<<eshell-alias-clear>>
|
||||
<<eshell-alias-buffers>>
|
||||
<<eshell-alias-emacs>>
|
||||
<<eshell-alias-mkcd>>
|
||||
:general
|
||||
(phundrak/evil
|
||||
:keymaps 'eshell-mode-map
|
||||
[remap evil-collection-eshell-evil-change] #'evil-backward-char
|
||||
"c" #'evil-backward-char
|
||||
"t" #'evil-next-visual-line
|
||||
"s" #'evil-previous-visual-line
|
||||
"r" #'evil-forward-char
|
||||
"h" #'evil-collection-eshell-evil-change)
|
||||
(general-define-key
|
||||
:keymaps 'eshell-mode-map
|
||||
:states 'insert
|
||||
"C-a" #'eshell-bol
|
||||
"C-e" #'end-of-line))
|
||||
#+end_src
|
||||
|
||||
*** Aliases
|
||||
First, let’s declare our list of “dumb” aliases we’ll use in
|
||||
Eshell. You can find them here.
|
||||
#+name: eshell-alias-file
|
||||
#+begin_src emacs-lisp :tangle no
|
||||
(setq eshell-aliases-file (expand-file-name "eshell-alias" user-emacs-directory))
|
||||
#+end_src
|
||||
|
||||
A couple of other aliases will be defined through custom Elisp
|
||||
functions, but first I’ll need a function for concatenating a shell
|
||||
command into a single string:
|
||||
#+name: eshell-concat-shell-command
|
||||
#+begin_src emacs-lisp :tangle no
|
||||
(defun phundrak/concatenate-shell-command (&rest command)
|
||||
"Concatenate an eshell COMMAND into a single string.
|
||||
All elements of COMMAND will be joined in a single
|
||||
space-separated string."
|
||||
(mapconcat #'identity command " "))
|
||||
#+end_src
|
||||
|
||||
I’ll also declare some aliases here, such as ~open~ and ~openo~ that
|
||||
respectively allow me to open a file in Emacs, and same but in another
|
||||
window.
|
||||
#+name: eshell-alias-open
|
||||
#+begin_src emacs-lisp :tangle no
|
||||
(defalias 'open #'find-file)
|
||||
(defalias 'openo #'find-file-other-window)
|
||||
#+end_src
|
||||
|
||||
The default behavior of ~eshell/clear~ is not great at all, although it
|
||||
clears the screen it also scrolls all the way down. Therefore, let’s
|
||||
alias it to ~eshell/clear-scrollback~ which has the correct behavior.
|
||||
#+name: eshell-alias-clear
|
||||
#+begin_src emacs-lisp :tangle no
|
||||
(defalias 'eshell/clear #'eshell/clear-scrollback)
|
||||
#+end_src
|
||||
|
||||
As you see, these were not declared in my dedicated aliases file but
|
||||
rather were declared programmatically. This is because I like to keep
|
||||
my aliases file for stuff that could work too with other shells were
|
||||
the syntax a bit different, and aliases related to Elisp are kept
|
||||
programmatically. I’ll also declare ~list-buffers~ an alias of ~ibuffer~
|
||||
because naming it that way kind of makes more sense to me.
|
||||
#+name: eshell-alias-buffers
|
||||
#+begin_src emacs-lisp :tangle no
|
||||
(defalias 'list-buffers 'ibuffer)
|
||||
#+end_src
|
||||
|
||||
I still have some stupid muscle memory telling me to open ~emacs~, ~vim~
|
||||
or ~nano~ in Eshell, which is stupid: I’m already inside Emacs and I
|
||||
have all its power available instantly. So, let’s open each file
|
||||
passed to these commands.
|
||||
#+name: eshell-alias-emacs
|
||||
#+begin_src emacs-lisp :tangle no
|
||||
(defun eshell/emacs (&rest file)
|
||||
"Open each FILE and kill eshell.
|
||||
Old habits die hard."
|
||||
(when file
|
||||
(dolist (f (reverse file))
|
||||
(find-file f t))))
|
||||
#+end_src
|
||||
|
||||
Finally, I’ll declare ~mkcd~ which allows the simultaneous creation of a
|
||||
directory and moving into this newly created directory. And of course,
|
||||
it will also work if the directory also exists or if parent
|
||||
directories don’t, similarly to the ~-p~ option passed to ~mkdir~.
|
||||
#+name: eshell-alias-mkcd
|
||||
#+begin_src emacs-lisp :tangle no
|
||||
(defun eshell/mkcd (dir)
|
||||
"Create the directory DIR and move there.
|
||||
If the directory DIR doesn’t exist, create it and its parents
|
||||
if needed, then move there."
|
||||
(mkdir dir t)
|
||||
(cd dir))
|
||||
#+end_src
|
||||
|
||||
*** Commands
|
||||
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)
|
||||
(cl-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
|
||||
|
||||
A very useful command I often use in fish is ~z~, a port from bash’s and
|
||||
zsh’s command that allows to jump around directories based on how
|
||||
often we go in various directories.
|
||||
#+begin_src emacs-lisp
|
||||
(use-package eshell-z
|
||||
:defer t
|
||||
:after eshell
|
||||
:straight (:build t)
|
||||
:hook (eshell-mode . (lambda () (require 'eshell-z))))
|
||||
#+end_src
|
||||
|
||||
*** Environment Variables
|
||||
Some environment variables need to be correctly set so Eshell can
|
||||
correctly work. I would 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
|
||||
|
||||
The ~EDITOR~ variable also needs to be set for git commands, especially the
|
||||
~yadm~ commands.
|
||||
#+BEGIN_SRC emacs-lisp
|
||||
(setenv "EDITOR" "emacsclient -c -a emacs")
|
||||
#+END_SRC
|
||||
|
||||
Finally, for some specific situations I need ~SHELL~ to be set to
|
||||
something more standard than fish:
|
||||
#+begin_src emacs-lisp
|
||||
(setenv "SHELL" "/bin/sh")
|
||||
#+end_src
|
||||
|
||||
*** Visual configuration
|
||||
I like to have at quick glance some information about my machine when
|
||||
I fire up a terminal. I haven’t found anything that does that the way
|
||||
I like it, so [[https://github.com/Phundrak/eshell-info-banner.el][I’ve written a package]]! It’s actually available on
|
||||
MELPA, but since I’m the main dev of this package, I’ll keep track of
|
||||
the git repository.
|
||||
#+begin_src emacs-lisp
|
||||
(use-package eshell-info-banner
|
||||
:after (eshell)
|
||||
:defer t
|
||||
:straight (eshell-info-banner :build t
|
||||
:type git
|
||||
:host github
|
||||
:protocol ssh
|
||||
:repo "phundrak/eshell-info-banner.el")
|
||||
:hook (eshell-banner-load . eshell-info-banner-update-banner)
|
||||
:custom-face
|
||||
(eshell-info-banner-normal-face ((t :foreground "#A3BE8C")))
|
||||
(eshell-info-banner-background-face ((t :foreground "#E5E9F0")))
|
||||
(eshell-info-banner-warning-face ((t :foreround "#D08770")))
|
||||
(eshell-info-banner-critical-face ((t :foreground "#BF616A")))
|
||||
:custom
|
||||
(eshell-info-banner-partition-prefixes (list "/dev" "zroot" "tank")))
|
||||
#+end_src
|
||||
|
||||
Another feature I like is fish-like syntax highlight, which brings
|
||||
some more colors to Eshell.
|
||||
#+begin_src emacs-lisp
|
||||
(use-package eshell-syntax-highlighting
|
||||
:after (esh-mode eshell)
|
||||
:defer t
|
||||
:straight (:build t)
|
||||
:config
|
||||
(eshell-syntax-highlighting-global-mode +1))
|
||||
#+end_src
|
||||
|
||||
Powerline prompts are nice, git-aware prompts are even better!
|
||||
~eshell-git-prompt~ is nice, but I prefer to write my own package for
|
||||
that.
|
||||
#+begin_src emacs-lisp
|
||||
(use-package powerline-eshell
|
||||
:if (string= (string-trim (shell-command-to-string "uname -n")) "leon")
|
||||
:load-path "~/fromGIT/emacs-packages/powerline-eshell.el/"
|
||||
:after eshell)
|
||||
#+end_src
|
||||
|
||||
** Eww
|
||||
Since Emacs 29, it is possible to automatically rename ~eww~ buffers to
|
||||
a more human-readable name, see [[https://protesilaos.com/codelog/2021-10-15-emacs-29-eww-rename-buffers/][Prot’s blog]] post on the matter.
|
||||
#+begin_src emacs-lisp
|
||||
(use-package eww
|
||||
:defer t
|
||||
:straight (:type built-in)
|
||||
:config
|
||||
(setq eww-auto-rename-buffer 'title))
|
||||
#+end_src
|
||||
|
||||
** Image-mode
|
||||
I won’t modify much for ~image-mode~ (the mode used to display images)
|
||||
aside from Emacs’ ability to use external converters to display some
|
||||
images it wouldn’t be able to handle otherwise.
|
||||
#+begin_src emacs-lisp
|
||||
(setq image-use-external-converter t)
|
||||
#+end_src
|
||||
|
||||
** Info
|
||||
Let’s define some more intuitive keybinds for ~info-mode~.
|
||||
#+begin_src emacs-lisp
|
||||
(use-package info
|
||||
:defer t
|
||||
:straight (info :type built-in :build t)
|
||||
:general
|
||||
(phundrak/evil
|
||||
:keymaps 'Info-mode-map
|
||||
"c" #'Info-prev
|
||||
"t" #'evil-scroll-down
|
||||
"s" #'evil-scroll-up
|
||||
"r" #'Info-next)
|
||||
(phundrak/major-leader-key
|
||||
:keymaps 'Info-mode-map
|
||||
"?" #'Info-toc
|
||||
"b" #'Info-history-back
|
||||
"f" #'Info-history-forward
|
||||
"m" #'Info-menu
|
||||
"t" #'Info-top-node
|
||||
"u" #'Info-up))
|
||||
#+end_src
|
||||
|
||||
** Tab Bar
|
||||
#+begin_src emacs-lisp
|
||||
(use-package tab-bar
|
||||
:defer t
|
||||
:straight (:type built-in)
|
||||
:custom
|
||||
(tab-bar-close-button-show nil)
|
||||
(tab-bar-new-button-show nil)
|
||||
(tab-bar-new-tab-choice "*dashboard*")
|
||||
:custom-face
|
||||
(tab-bar ((t (:background "#272C36"
|
||||
:foreground "#272C36"
|
||||
:box (:line-width (8 . 5) :style flat-button)))))
|
||||
:init
|
||||
(advice-add #'tab-new
|
||||
:after
|
||||
(lambda (&rest _) (when (y-or-n-p "Rename tab? ")
|
||||
(call-interactively #'tab-rename)))))
|
||||
#+end_src
|
||||
|
||||
** Tramp
|
||||
Tramp is an Emacs built-in package that allows the user to connect to
|
||||
various hosts using various protocols, such as ~ssh~ and
|
||||
~rsync~. However, I have some use-case for Tramp which are not
|
||||
supported natively. I will describe them here.
|
||||
#+begin_src emacs-lisp
|
||||
(use-package tramp
|
||||
:straight (tramp :type built-in :build t)
|
||||
:config
|
||||
<<tramp-add-yadm>>
|
||||
(csetq tramp-ssh-controlmaster-options nil
|
||||
tramp-verbose 0
|
||||
tramp-auto-save-directory (locate-user-emacs-file "tramp/")
|
||||
tramp-chunksize 2000)
|
||||
(add-to-list 'backup-directory-alist ; deactivate auto-save with TRAMP
|
||||
(cons tramp-file-name-regexp nil)))
|
||||
#+end_src
|
||||
|
||||
*** Yadm
|
||||
[[https://yadm.io/][~yadm~]] is a git wrapper made to easily manage your dotfiles. It has
|
||||
loads of features I don’t use (the main one I like but don’t use is
|
||||
its [[https://yadm.io/docs/templates][Jinja-like host and OS-aware syntax]]), but unfortunately Magit
|
||||
doesn’t play nice with it. Tramp to the rescue, and this page explains
|
||||
how! Let’s just insert in my config this code snippet:
|
||||
#+name: tramp-add-yadm
|
||||
#+begin_src emacs-lisp :tangle no
|
||||
(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
|
||||
|
||||
I’ll also create a fuction for connecting to this new Tramp protocol:
|
||||
#+begin_src emacs-lisp
|
||||
(defun my/yadm ()
|
||||
"Manage my dotfiles through TRAMP."
|
||||
(interactive)
|
||||
(magit-status "/yadm::"))
|
||||
#+end_src
|
||||
401
docs/emacs/packages/exwm.org
Normal file
401
docs/emacs/packages/exwm.org
Normal file
@@ -0,0 +1,401 @@
|
||||
#+title: Emacs — Packages — EXWM
|
||||
#+setupfile: ../../headers
|
||||
#+property: header-args:emacs-lisp :mkdirp yes :lexical t :exports code
|
||||
#+property: header-args:emacs-lisp+ :tangle ~/.config/emacs/lisp/exwm.el
|
||||
#+property: header-args:emacs-lisp+ :mkdirp yes :noweb no-export
|
||||
|
||||
* EXWM
|
||||
So, I’m finally slowly getting back to EXWM. I tried it a couple of
|
||||
years ago, but that was with the SpacemacsOS layer on Spacemacs, on a
|
||||
laptop which got accidentaly formatted before I could save my config
|
||||
and all… So it got me some time to come back. I’m still a bit worried
|
||||
about Emacs being single threaded, so if I get one blocking function
|
||||
blocking Emacs, my whole desktop will hang, but for now I haven’t had
|
||||
this issue.
|
||||
|
||||
All my EXWM config is enabled only if I launch Emacs with the argument
|
||||
~--with-exwm~, otherwise none of the related packages get installed, let
|
||||
alone activated and made available.
|
||||
|
||||
First, I need to install the /X protocol Emacs Lisp Bindings/. It
|
||||
doesn’t seem to be available in any repo, so I’ll install it directly
|
||||
from Git.
|
||||
#+begin_src emacs-lisp
|
||||
(use-package xelb
|
||||
:if (seq-contains-p command-line-args "--with-exwm")
|
||||
:straight (xelb :build t
|
||||
:type git
|
||||
:host github
|
||||
:repo "emacs-straight/xelb"
|
||||
:fork "ch11ng/xelb"))
|
||||
#+end_src
|
||||
|
||||
Next is a function I’ve +stolen+ copied from Daviwil’s [[https://config.daviwil.com/desktop][desktop
|
||||
configuration]]. This allows to launch software in the background
|
||||
easily.
|
||||
#+begin_src emacs-lisp
|
||||
(defun exwm/run-in-background (command &optional once)
|
||||
(let ((command-parts (split-string command " +")))
|
||||
(apply #'call-process `(,(car command-parts) nil 0 nil ,@(cdr command-parts)))))
|
||||
#+end_src
|
||||
|
||||
In order to launch Emacs with EXWM with ~startx~, I need a ~xinit~ file.
|
||||
This one is exported to ~$HOME/.xinitrc.emacs~.
|
||||
#+begin_src sh :tangle ~/.xinitrc.emacs :shebang "#!/bin/sh"
|
||||
xhost +SI:localuser:$USER
|
||||
|
||||
# Set fallback cursor
|
||||
xsetroot -cursor_name left_ptr
|
||||
|
||||
# If Emacs is started in server mode, `emacsclient` is a convenient
|
||||
# way to edit files in place (used by e.g. `git commit`)
|
||||
export VISUAL=emacsclient
|
||||
export EDITOR="$VISUAL"
|
||||
|
||||
# in case Java applications display /nothing/
|
||||
# wmname LG3D
|
||||
# export _JAVA_AWT_WM_NONREPARENTING=1
|
||||
|
||||
autorandr -l home
|
||||
|
||||
exec emacs --with-exwm
|
||||
#+end_src
|
||||
|
||||
** EXWM itself
|
||||
Now we come to the plat de résistance. Like with ~xelb~, I’m using its
|
||||
Git source to install it to make sure I get the right version --- the
|
||||
version available on the GNU ELPA is from the same source, true, but I
|
||||
don’t know at which rate it is updated. And more packages down the
|
||||
line will depend on this Git repository, so I might as well just clone
|
||||
it right now.
|
||||
|
||||
As you can see, I added in the ~:config~ secion to two hooks functions
|
||||
that rename buffers accurately. While the average X window will simply
|
||||
get the name of the current X window, I want Firefox and Qutebrowser
|
||||
to be prefixed with the name of the browser. Actually, all these will
|
||||
be renamed this way:
|
||||
#+name: exwm-renamed-buffers-list
|
||||
- Kitty
|
||||
- Qutebrowser
|
||||
|
||||
#+name: exwm-gen-buffers-rename
|
||||
#+header: :exports none :tangle no
|
||||
#+begin_src emacs-lisp :var buffers=exwm-renamed-buffers-list :cache yes
|
||||
(format "%s\n%S"
|
||||
(mapconcat (lambda (buffer)
|
||||
(let ((buffer-name (if (stringp buffer)
|
||||
buffer
|
||||
(car buffer))))
|
||||
(format "(\"%s\" %S)"
|
||||
(downcase buffer-name)
|
||||
`(exwm-workspace-rename-buffer
|
||||
(concat ,(concat "EXWM: " buffer-name " - ")
|
||||
exwm-title)))))
|
||||
buffers
|
||||
"\n")
|
||||
'(_otherwise (exwm-workspace-rename-buffer exwm-title)))
|
||||
#+end_src
|
||||
|
||||
#+RESULTS[64fdbf1e8957b82aad801ec57f2155a0a8f5be54]: exwm-gen-buffers-rename
|
||||
: ("kitty" (exwm-workspace-rename-buffer (concat "EXWM: Kitty - " exwm-title)))
|
||||
: ("qutebrowser" (exwm-workspace-rename-buffer (concat "EXWM: Qutebrowser - " exwm-title)))
|
||||
: (_otherwise (exwm-workspace-rename-buffer exwm-title))
|
||||
|
||||
#+name: exwm-buffers-name
|
||||
#+begin_src emacs-lisp :tangle no
|
||||
(add-hook 'exwm-update-class-hook
|
||||
(lambda () (exwm-workspace-rename-buffer exwm-class-name)))
|
||||
|
||||
(add-hook 'exwm-update-title-hook
|
||||
(lambda ()
|
||||
(pcase exwm-class-name
|
||||
<<exwm-gen-buffers-rename()>>)))
|
||||
#+end_src
|
||||
|
||||
As you can see below, in the ~:config~ section I added two advices and
|
||||
one hook in order to correctly integrate evil with EXWM. When I’m in
|
||||
an X window, I want to be in insert-mode in order to type however I
|
||||
want. However, when I exit one, I want to default back to normal-mode.
|
||||
#+name: exwm-advices-evil
|
||||
#+begin_src emacs-lisp :tangle no
|
||||
(add-hook 'exwm-manage-finish-hook (lambda () (call-interactively #'exwm-input-release-keyboard)))
|
||||
(advice-add #'exwm-input-grab-keyboard :after (lambda (&optional id) (evil-normal-state)))
|
||||
(advice-add #'exwm-input-release-keyboard :after (lambda (&optional id) (evil-insert-state)))
|
||||
#+end_src
|
||||
|
||||
Secondly, I add ~i~, ~C-SPC~, and ~M-m~ as exwm prefix keys so they aren’t
|
||||
sent directly to the X windows but caught by Emacs (and EXWM). I’ll
|
||||
use the ~i~ key in normal-mode to enter ~insert-mode~ and have Emacs
|
||||
release the keyboard so the X window can grab it. Initially, I had
|
||||
~s-<escape>~ as a keybind for grabbing back the keyboard from an X
|
||||
window, as if I were in insert mode and wanted to go back to normal
|
||||
mode, and I had ~s-I~ to toggle keyboard grabbing. But I found myself
|
||||
more than once trying to use ~s-<escape>~ to toggle this state, ~s-I~
|
||||
completely forgotten. So I removed ~s-I~ and made ~s-<escape>~ behave like
|
||||
~s-I~ once did.
|
||||
#+name: exwm-prefix-keys
|
||||
#+begin_src emacs-lisp :tangle no
|
||||
(general-define-key
|
||||
:keymaps 'exwm-mode-map
|
||||
:states 'normal
|
||||
"i" #'exwm-input-release-keyboard)
|
||||
|
||||
(exwm-input-set-key (kbd "s-<escape>") #'exwm-input-toggle-keyboard)
|
||||
|
||||
(push ?\i exwm-input-prefix-keys)
|
||||
(push (kbd "C-SPC") exwm-input-prefix-keys)
|
||||
(push (kbd "M-m") exwm-input-prefix-keys)
|
||||
#+end_src
|
||||
|
||||
As stated a couple of times in my different configuration files, I’m
|
||||
using the bépo layout, which means the default keys in the number row
|
||||
are laid as follows:
|
||||
#+name: exwm-bepo-number-row
|
||||
#+begin_src emacs-lisp :tangle no
|
||||
(defconst exwm-workspace-keys '("\"" "«" "»" "(" ")" "@" "+" "-" "/" "*"))
|
||||
#+end_src
|
||||
|
||||
With this, we can create keybinds for going or sending X windows to
|
||||
workspaces 0 to 9.
|
||||
#+name: exwm-workspace-keybinds
|
||||
#+begin_src emacs-lisp :tangle no
|
||||
(setq exwm-input-global-keys
|
||||
`(,@exwm-input-global-keys
|
||||
,@(mapcar (lambda (i)
|
||||
`(,(kbd (format "s-%s" (nth i exwm-workspace-keys))) .
|
||||
(lambda ()
|
||||
(interactive)
|
||||
(exwm-workspace-switch-create ,i))))
|
||||
(number-sequence 0 9))
|
||||
,@(mapcar (lambda (i)
|
||||
`(,(kbd (format "s-%d" i)) .
|
||||
(lambda ()
|
||||
(interactive)
|
||||
(exwm-workspace-move-window ,(let ((index (1- i)))
|
||||
(if (< index 0)
|
||||
(- 10 index)
|
||||
;; FIXME: does not work with s-0
|
||||
index))))))
|
||||
(number-sequence 0 9))))
|
||||
#+end_src
|
||||
|
||||
You can then see the list of the keybinds I have set for EXWM, which
|
||||
are all prefixed with ~SPC x~ in normal mode (and ~C-SPC x~ in insert
|
||||
mode), except for ~s-RET~ which opens an eshell terminal.
|
||||
#+name: exwm-keybinds
|
||||
#+begin_src emacs-lisp :tangle no
|
||||
(exwm-input-set-key (kbd "s-<return>") (lambda ()
|
||||
(interactive)
|
||||
(eshell)))
|
||||
|
||||
(phundrak/leader-key
|
||||
:infix "x"
|
||||
"" '(:ignore t :which-key "EXWM")
|
||||
"d" #'exwm-debug
|
||||
"k" #'exwm-input-send-next-key
|
||||
"l" '((lambda ()
|
||||
(interactive)
|
||||
(start-process "" nil "plock"))
|
||||
:which-key "lock")
|
||||
"r" '(:ignore t :wk "rofi")
|
||||
"rr" '((lambda () (interactive)
|
||||
(shell-command "rofi -show drun" (current-buffer) (current-buffer)))
|
||||
:wk "drun")
|
||||
"rw" '((lambda () (interactive)
|
||||
(shell-command "rofi -show window" (current-buffer) (current-buffer)))
|
||||
:wk "windows")
|
||||
"R" '(:ignore t :wk "restart")
|
||||
"Rr" #'exwm-reset
|
||||
"RR" #'exwm-restart
|
||||
"t" '(:ignore t :which-key "toggle")
|
||||
"tf" #'exwm-layout-toggle-fullscreen
|
||||
"tF" #'exwm-floating-toggle-floating
|
||||
"tm" #'exwm-layout-toggle-mode-line
|
||||
"w" '(:ignore t :which-key "workspaces")
|
||||
"wa" #'exwm-workspace-add
|
||||
"wd" #'exwm-workspace-delete
|
||||
"ws" #'exwm-workspace-switch
|
||||
"x" '((lambda ()
|
||||
(interactive)
|
||||
(let ((command (string-trim (read-shell-command "RUN: "))))
|
||||
(start-process command nil command)))
|
||||
:which-key "run")
|
||||
"RET" #'eshell-new)
|
||||
#+end_src
|
||||
|
||||
A couple of commands are also automatically executed through my
|
||||
~autostart~ script written [[file:bin.org::#Autostart-a99e99e7][here]].
|
||||
#+name: exwm-autostart
|
||||
#+begin_src emacs-lisp :tangle no
|
||||
(exwm/run-in-background "autostart")
|
||||
#+end_src
|
||||
|
||||
Finally, let’s only initialize and start EXWM once functions from
|
||||
exwm-randr ran, because otherwise having multiple monitors don’t work.
|
||||
#+name: exwm-init
|
||||
#+begin_src emacs-lisp :tangle no
|
||||
(with-eval-after-load 'exwm-randr
|
||||
(exwm-init))
|
||||
#+end_src
|
||||
|
||||
The complete configuration for the ~exwm~ package can be found below.
|
||||
#+begin_src emacs-lisp :noweb yes
|
||||
(use-package exwm
|
||||
:if (seq-contains-p command-line-args "--with-exwm")
|
||||
:straight (exwm :build t
|
||||
:type git
|
||||
:host github
|
||||
:repo "ch11ng/exwm")
|
||||
:custom
|
||||
(use-dialog-box nil "Disable dialog boxes since they are unusable in EXWM")
|
||||
(exwm-input-line-mode-passthrough t "Pass all keypresses to emacs in line mode.")
|
||||
:init
|
||||
(require 'exwm-config)
|
||||
(setq exwm-workspace-number 6)
|
||||
:config
|
||||
(set-frame-parameter (selected-frame) 'alpha-background 0.7)
|
||||
<<exwm-randr>>
|
||||
|
||||
<<exwm-buffers-name>>
|
||||
|
||||
<<exwm-advices-evil>>
|
||||
<<exwm-prefix-keys>>
|
||||
|
||||
<<exwm-bepo-number-row>>
|
||||
<<exwm-workspace-keybinds>>
|
||||
|
||||
<<exwm-keybinds>>
|
||||
|
||||
<<exwm-autostart>>
|
||||
|
||||
<<exwm-init>>)
|
||||
#+end_src
|
||||
|
||||
** EXWM-Evil integration
|
||||
#+begin_src emacs-lisp
|
||||
(use-package evil-exwm-state
|
||||
:if (seq-contains-p command-line-args "--with-exwm")
|
||||
:defer t
|
||||
:after exwm
|
||||
:straight (evil-exwm-state :build t
|
||||
:type git
|
||||
:host github
|
||||
:repo "domenzain/evil-exwm-state"))
|
||||
#+end_src
|
||||
|
||||
** Multimonitor support
|
||||
#+name: exwm-randr
|
||||
#+begin_src emacs-lisp :tangle no
|
||||
(require 'exwm-randr)
|
||||
(exwm/run-in-background "xwallpaper --zoom \"${cat $HOME/.cache/wallpaper}\"")
|
||||
(start-process-shell-command
|
||||
"xrandr" nil "xrandr --output eDP1 --mode 1920x1080 --pos 2560x0 --rotate normal --output HDMI1 --primary --mode 2560x1080 --pos 0x0 --rotate normal --output VIRTUAL1 --off --output DP-1-0 --off --output DP-1-1 --off")
|
||||
(exwm-randr-enable)
|
||||
(setq exwm-randr-workspace-monitor-plist '(3 "eDP1"))
|
||||
#+end_src
|
||||
|
||||
** Keybinds for a desktop environment
|
||||
#+begin_src emacs-lisp
|
||||
(use-package desktop-environment
|
||||
:defer t
|
||||
:straight (desktop-environment :build t
|
||||
:type git
|
||||
:host github
|
||||
:repo "DamienCassou/desktop-environment")
|
||||
:after exwm
|
||||
:diminish t
|
||||
:config
|
||||
(add-hook 'exwm-init-hook #'desktop-environment-mode)
|
||||
(setq desktop-environment-update-exwm-global-keys :prefix
|
||||
exwm-layout-show-al-buffers t)
|
||||
|
||||
(setq desktop-environment-bluetooth-command "bluetoothctl"
|
||||
|
||||
desktop-environment-brightness-get-command "xbacklight -get"
|
||||
desktop-environment-brightness-get-regexp (rx line-start (group (+ digit)))
|
||||
desktop-environment-brightness-set-command "xbacklight %s"
|
||||
desktop-environment-brightness-normal-increment "-inc 5"
|
||||
desktop-environment-brightness-normal-decrement "-dec 5"
|
||||
desktop-environment-brightness-small-increment "-inc 2"
|
||||
desktop-environment-brightness-small-decrement "-dec 2"
|
||||
|
||||
desktop-environment-volume-normal-decrement "-d 5"
|
||||
desktop-environment-volume-normal-increment "-i 5"
|
||||
desktop-environment-volume-small-decrement "-d 2"
|
||||
desktop-environment-volume-small-increment "-i 2"
|
||||
desktop-environment-volume-set-command "pamixer -u %s"
|
||||
|
||||
desktop-environment-screenshot-directory "~/Pictures/Screenshots"
|
||||
desktop-environment-screenlock-command "plock"
|
||||
|
||||
desktop-environment-music-toggle-command "mpc toggle"
|
||||
desktop-environment-music-previous-command "mpc prev"
|
||||
desktop-environment-music-next-command "mpc next"
|
||||
desktop-environment-music-stop-command "mpc stop")
|
||||
|
||||
(general-define-key
|
||||
"<XF86AudioPause>" (lambda () (interactive)
|
||||
(with-temp-buffer
|
||||
(shell-command "mpc pause" (current-buffer) (current-buffer)))))
|
||||
|
||||
(desktop-environment-mode))
|
||||
#+end_src
|
||||
|
||||
** Bluetooth
|
||||
#+begin_src emacs-lisp
|
||||
(defvar bluetooth-command "bluetoothctl")
|
||||
#+end_src
|
||||
|
||||
#+begin_src emacs-lisp
|
||||
(defun bluetooth-turn-on ()
|
||||
(interactive)
|
||||
(let ((process-connection-type nil))
|
||||
(start-process "" nil bluetooth-command "power" "on")))
|
||||
#+end_src
|
||||
|
||||
#+begin_src emacs-lisp
|
||||
(defun bluetooth-turn-off ()
|
||||
(interactive)
|
||||
(let ((process-connection-type nil))
|
||||
(start-process "" nil bluetooth-command "power" "off")))
|
||||
#+end_src
|
||||
|
||||
#+begin_src emacs-lisp
|
||||
(defun create-bluetooth-device (raw-name)
|
||||
"Create a bluetooth device cons from RAW NAME.
|
||||
The cons will hold first the MAC address of the device, then its
|
||||
human-friendly name."
|
||||
(let ((split-name (split-string raw-name " " t)))
|
||||
`(,(mapconcat #'identity (cddr split-name) " ") . ,(cadr split-name))))
|
||||
#+end_src
|
||||
|
||||
#+begin_src emacs-lisp
|
||||
(require 'dbus)
|
||||
(defun bluetooth-get-devices ()
|
||||
(let ((bus-list (dbus-introspect-get-node-names :system "org.bluez" "/org/bluez/hci0")))
|
||||
(mapcar (lambda (device)
|
||||
`(,(dbus-get-property :system
|
||||
"org.bluez"
|
||||
(concat "/org/bluez/hci0/" device)
|
||||
"org.bluez.Device1"
|
||||
"Alias")
|
||||
. ,device))
|
||||
bus-list)))
|
||||
#+end_src
|
||||
|
||||
#+begin_src emacs-lisp
|
||||
(defun bluetooth-connect-device ()
|
||||
(interactive)
|
||||
(progn
|
||||
(bluetooth-turn-on)
|
||||
(let* ((devices (bluetooth-get-devices))
|
||||
(device (alist-get (completing-read "Device: " devices)
|
||||
devices nil nil #'string=)))
|
||||
(dbus-call-method-asynchronously
|
||||
:system "org.bluez"
|
||||
(concat "/org/bluez/hci0" device)
|
||||
"org.bluez.Device1"
|
||||
"Connect"
|
||||
(lambda (&optional msg)
|
||||
(when msg (message "%s" msg)))))))
|
||||
#+end_src
|
||||
59
docs/emacs/packages/helpful.org
Normal file
59
docs/emacs/packages/helpful.org
Normal file
@@ -0,0 +1,59 @@
|
||||
#+title: Emacs — Packages — Making My Life Easier
|
||||
#+setupfile: ../../headers
|
||||
#+property: header-args:emacs-lisp :mkdirp yes :lexical t :exports code
|
||||
#+property: header-args:emacs-lisp+ :tangle ~/.config/emacs/lisp/helpful.el
|
||||
#+property: header-args:emacs-lisp+ :mkdirp yes :noweb no-export
|
||||
|
||||
* Making my life easier
|
||||
** Bufler
|
||||
Bufler is a package that organises and lists buffers in a much better
|
||||
way than how they are usually sorted. You can easily and quickly find
|
||||
buffers by their group, not only by their name, and THIS is great
|
||||
news! Also, no ~helm~ please! And for some reasons the keybindings are
|
||||
borked by default, so let’s redefine them, and let’s also rebind ~SPC~
|
||||
to ~p~ since it would conflict with my main ~general~ prefix.
|
||||
#+begin_src emacs-lisp
|
||||
(use-package bufler
|
||||
:straight (bufler :build t
|
||||
:files (:defaults (:exclude "helm-bufler.el")))
|
||||
:defer t
|
||||
:general
|
||||
(phundrak/evil
|
||||
:keymaps 'bufler-list-mode-map
|
||||
:packages 'bufler
|
||||
"?" #'hydra:bufler/body
|
||||
"g" #'bufler
|
||||
"f" #'bufler-list-group-frame
|
||||
"F" #'bufler-list-group-make-frame
|
||||
"N" #'bufler-list-buffer-name-workspace
|
||||
"k" #'bufler-list-buffer-kill
|
||||
"p" #'bufler-list-buffer-peek
|
||||
"s" #'bufler-list-buffer-save
|
||||
"RET" #'bufler-list-buffer-switch))
|
||||
#+end_src
|
||||
|
||||
** Helpful
|
||||
As the name tells, ~helpful~ is a really helpful package which greatly
|
||||
enhances a couple of built-in functions from Emacs, namely:
|
||||
| Vanilla Emacs Function | Helpful Function | Comment |
|
||||
|------------------------+------------------+-----------------------------------------------|
|
||||
| ~describe-function~ | ~helpful-callable~ | Only interactive functions |
|
||||
| ~describe-function~ | ~helpful-function~ | Only actual functions (including interactive) |
|
||||
| ~describe-function~ | ~helpful-macro~ | |
|
||||
| ~describe-command~ | ~helpful-command~ | |
|
||||
| ~describe-key~ | ~helpful-key~ | |
|
||||
| ~describe-variable~ | ~helpful-variable~ | |
|
||||
|
||||
#+begin_src emacs-lisp
|
||||
(use-package helpful
|
||||
:straight (:build t)
|
||||
:after (counsel ivy)
|
||||
:custom
|
||||
(counsel-describe-function-function #'helpful-callable)
|
||||
(counsel-describe-variable-function #'helpful-variable)
|
||||
:bind
|
||||
([remap describe-function] . counsel-describe-function)
|
||||
([remap describe-command] . helpful-command)
|
||||
([remap describe-variable] . counsel-describe-variable)
|
||||
([remap describe-key] . helpful-key))
|
||||
#+end_src
|
||||
207
docs/emacs/packages/latex.org
Normal file
207
docs/emacs/packages/latex.org
Normal file
@@ -0,0 +1,207 @@
|
||||
#+title: Emacs — Packages — LaTeX
|
||||
#+setupfile: ../../headers
|
||||
#+property: header-args:emacs-lisp :mkdirp yes :lexical t :exports code
|
||||
#+property: header-args:emacs-lisp+ :tangle ~/.config/emacs/lisp/latex.el
|
||||
#+property: header-args:emacs-lisp+ :mkdirp yes :noweb no-export
|
||||
|
||||
* LaTeX
|
||||
#+begin_src emacs-lisp :noweb yes
|
||||
(use-package auctex
|
||||
:defer t
|
||||
:straight (:build t)
|
||||
:hook (tex-mode . lsp-deferred)
|
||||
:hook (latex-mode . lsp-deferred)
|
||||
:init
|
||||
(setq TeX-command-default (if (executable-find "latexmk") "LatexMk" "LaTeX")
|
||||
TeX-engine (if (executable-find "xetex") 'xetex 'default)
|
||||
TeX-auto-save t
|
||||
TeX-parse-self t
|
||||
TeX-syntactic-comment t
|
||||
TeX-auto-local ".auctex-auto"
|
||||
TeX-style-local ".auctex-style"
|
||||
TeX-source-correlate-mode t
|
||||
TeX-source-correlate-method 'synctex
|
||||
TeX-source-correlate-start-server nil
|
||||
TeX-electric-sub-and-superscript t
|
||||
TeX-fill-break-at-separators nil
|
||||
TeX-save-query t)
|
||||
:config
|
||||
<<latex-fontification>>
|
||||
(setq TeX-master t)
|
||||
(setcar (cdr (assoc "Check" TeX-command-list)) "chktex -v6 -H %s")
|
||||
(add-hook 'TeX-mode-hook (lambda ()
|
||||
(setq ispell-parser 'tex
|
||||
fill-nobreak-predicate (cons #'texmathp fill-nobreak-predicate))))
|
||||
(add-hook 'TeX-mode-hook #'visual-line-mode)
|
||||
(add-hook 'TeX-update-style-hook #'rainbow-delimiters-mode)
|
||||
:general
|
||||
(phundrak/major-leader-key
|
||||
:packages 'lsp-mode
|
||||
:keymaps '(latex-mode-map LaTeX-mode-map)
|
||||
"l" '(:keymap lsp-command-map :which-key "lsp"))
|
||||
(phundrak/major-leader-key
|
||||
:packages 'auctex
|
||||
:keymaps '(latex-mode-map LaTeX-mode-map)
|
||||
"v" '(TeX-view :which-key "View")
|
||||
"c" '(TeX-command-run-all :which-key "Compile")
|
||||
"m" '(TeX-command-master :which-key "Run a command")))
|
||||
#+end_src
|
||||
|
||||
From Doom Emacs’ configuration:
|
||||
#+name: latex-fontification
|
||||
#+begin_src emacs-lisp :tangle no
|
||||
(setq font-latex-match-reference-keywords
|
||||
'(;; BibLaTeX.
|
||||
("printbibliography" "[{") ("addbibresource" "[{")
|
||||
;; Standard commands.
|
||||
("cite" "[{") ("citep" "[{")
|
||||
("citet" "[{") ("Cite" "[{")
|
||||
("parencite" "[{") ("Parencite" "[{")
|
||||
("footcite" "[{") ("footcitetext" "[{")
|
||||
;; Style-specific commands.
|
||||
("textcite" "[{") ("Textcite" "[{")
|
||||
("smartcite" "[{") ("Smartcite" "[{")
|
||||
("cite*" "[{") ("parencite*" "[{")
|
||||
("supercite" "[{")
|
||||
;; Qualified citation lists.
|
||||
("cites" "[{") ("Cites" "[{")
|
||||
("parencites" "[{") ("Parencites" "[{")
|
||||
("footcites" "[{") ("footcitetexts" "[{")
|
||||
("smartcites" "[{") ("Smartcites" "[{")
|
||||
("textcites" "[{") ("Textcites" "[{")
|
||||
("supercites" "[{")
|
||||
;; Style-independent commands.
|
||||
("autocite" "[{") ("Autocite" "[{")
|
||||
("autocite*" "[{") ("Autocite*" "[{")
|
||||
("autocites" "[{") ("Autocites" "[{")
|
||||
;; Text commands.
|
||||
("citeauthor" "[{") ("Citeauthor" "[{")
|
||||
("citetitle" "[{") ("citetitle*" "[{")
|
||||
("citeyear" "[{") ("citedate" "[{")
|
||||
("citeurl" "[{")
|
||||
;; Special commands.
|
||||
("fullcite" "[{")
|
||||
;; Cleveref.
|
||||
("cref" "{") ("Cref" "{")
|
||||
("cpageref" "{") ("Cpageref" "{")
|
||||
("cpagerefrange" "{") ("Cpagerefrange" "{")
|
||||
("crefrange" "{") ("Crefrange" "{")
|
||||
("labelcref" "{")))
|
||||
|
||||
(setq font-latex-match-textual-keywords
|
||||
'(;; BibLaTeX brackets.
|
||||
("parentext" "{") ("brackettext" "{")
|
||||
("hybridblockquote" "[{")
|
||||
;; Auxiliary commands.
|
||||
("textelp" "{") ("textelp*" "{")
|
||||
("textins" "{") ("textins*" "{")
|
||||
;; Subcaption.
|
||||
("subcaption" "[{")))
|
||||
|
||||
(setq font-latex-match-variable-keywords
|
||||
'(;; Amsmath.
|
||||
("numberwithin" "{")
|
||||
;; Enumitem.
|
||||
("setlist" "[{") ("setlist*" "[{")
|
||||
("newlist" "{") ("renewlist" "{")
|
||||
("setlistdepth" "{") ("restartlist" "{")
|
||||
("crefname" "{")))
|
||||
#+end_src
|
||||
|
||||
#+begin_src emacs-lisp
|
||||
(use-package tex-mode
|
||||
:defer t
|
||||
:straight (:type built-in)
|
||||
:config
|
||||
(setq LaTeX-section-hook '(LaTeX-section-heading
|
||||
LaTeX-section-title
|
||||
LaTeX-section-toc
|
||||
LaTeX-section-section
|
||||
LaTeX-section-label)
|
||||
LaTeX-fill-break-at-separators nil
|
||||
LaTeX-item-indent 0))
|
||||
#+end_src
|
||||
|
||||
#+begin_src emacs-lisp
|
||||
(use-package preview
|
||||
:defer t
|
||||
:straight (:type built-in)
|
||||
:config
|
||||
(add-hook 'LaTeX-mode-hook #'LaTeX-preview-setup)
|
||||
(setq-default preview-scale 1.4
|
||||
preview-scale-function
|
||||
(lambda () (* (/ 10.0 (preview-document-pt)) preview-scale)))
|
||||
(setq preview-auto-cache-preamble nil)
|
||||
(phundrak/major-leader-key
|
||||
:packages 'auctex
|
||||
:keymaps '(latex-mode-map LaTeX-mode-map)
|
||||
"p" #'preview-at-point
|
||||
"P" #'preview-clearout-at-point))
|
||||
#+end_src
|
||||
|
||||
#+begin_src emacs-lisp
|
||||
(use-package cdlatex
|
||||
:defer t
|
||||
:after auctex
|
||||
:straight (:build t)
|
||||
:hook (LaTeX-mode . cdlatex-mode)
|
||||
:hook (org-mode . org-cdlatex-mode)
|
||||
:config
|
||||
(setq cdlatex-use-dollar-to-ensure-math nil)
|
||||
:general
|
||||
(phundrak/major-leader-key
|
||||
:packages 'cdlatex
|
||||
:keymaps 'cdlatex-mode-map
|
||||
"$" nil
|
||||
"(" nil
|
||||
"{" nil
|
||||
"[" nil
|
||||
"|" nil
|
||||
"<" nil
|
||||
"^" nil
|
||||
"_" nil
|
||||
[(control return)] nil))
|
||||
#+end_src
|
||||
|
||||
#+begin_src emacs-lisp
|
||||
(use-package adaptive-wrap
|
||||
:defer t
|
||||
:after auctex
|
||||
:straight (:build t)
|
||||
:hook (LaTeX-mode . adaptative-wrap-prefix-mode)
|
||||
:init (setq-default adaptative-wrap-extra-indent 0))
|
||||
#+end_src
|
||||
|
||||
#+begin_src emacs-lisp
|
||||
(use-package auctex-latexmk
|
||||
:after auctex
|
||||
:defer t
|
||||
:straight (:build t)
|
||||
:init
|
||||
(setq auctex-latexmk-inherit-TeX-PDF-mode t)
|
||||
(add-hook 'LaTeX-mode (lambda () (setq TeX-command-default "LatexMk")))
|
||||
:config
|
||||
(auctex-latexmk-setup))
|
||||
#+end_src
|
||||
|
||||
#+begin_src emacs-lisp
|
||||
(use-package company-auctex
|
||||
:defer t
|
||||
:after (company auctex)
|
||||
:straight (:build t)
|
||||
:config
|
||||
(company-auctex-init))
|
||||
#+end_src
|
||||
|
||||
#+begin_src emacs-lisp
|
||||
(use-package company-math
|
||||
:defer t
|
||||
:straight (:build t)
|
||||
:after (company auctex)
|
||||
:config
|
||||
(defun my-latex-mode-setup ()
|
||||
(setq-local company-backends
|
||||
(append '((company-math-symbols-latex company-latex-commands))
|
||||
company-backends)))
|
||||
(add-hook 'TeX-mode-hook #'my-latex-mode-setup))
|
||||
#+end_src
|
||||
276
docs/emacs/packages/misc.org
Normal file
276
docs/emacs/packages/misc.org
Normal file
@@ -0,0 +1,276 @@
|
||||
#+title: Emacs — Packages — Misc
|
||||
#+setupfile: ../../headers
|
||||
#+property: header-args:emacs-lisp :mkdirp yes :lexical t :exports code
|
||||
#+property: header-args:emacs-lisp+ :tangle ~/.config/emacs/lisp/misc.el
|
||||
#+property: header-args:emacs-lisp+ :mkdirp yes :noweb no-export
|
||||
|
||||
* Misc
|
||||
** ArchWiki pages
|
||||
A small package I’ve written allows the user to view ArchLinux pages
|
||||
either in Emacs or in an external web browser. I prefer the defaults.
|
||||
#+begin_src emacs-lisp
|
||||
(use-package archwiki
|
||||
:defer t
|
||||
:straight (archwiki :build t
|
||||
:type git
|
||||
:repo "https://labs.phundrak.com/phundrak/archwiki.el"))
|
||||
#+end_src
|
||||
|
||||
** ~avy~
|
||||
~avy~ is a really convenient way of jumping around and performing
|
||||
actions on these selections, but I’ll need some configuration to make
|
||||
it bépo-compatible.
|
||||
#+begin_src emacs-lisp
|
||||
(use-package avy
|
||||
:defer t
|
||||
:straight t
|
||||
:config
|
||||
(csetq avy-keys '(?a ?u ?i ?e ?c ?t ?s ?r ?n)
|
||||
avy-dispatch-alist '((?x . avy-action-kill-move)
|
||||
(?X . avy-action-kill-stay)
|
||||
(?T . avy-action-teleport)
|
||||
(?m . avy-action-mark)
|
||||
(?C . avy-action-copy)
|
||||
(?y . avy-action-yank)
|
||||
(?Y . avy-action-yank-line)
|
||||
(?I . avy-action-ispell)
|
||||
(?z . avy-action-zap-to-char)))
|
||||
(defun my/avy-goto-url ()
|
||||
"Jump to url with avy."
|
||||
(interactive)
|
||||
(avy-jump "https?://"))
|
||||
(defun my/avy-open-url ()
|
||||
"Open url selected with avy."
|
||||
(interactive)
|
||||
(my/avy-goto-url)
|
||||
(browse-url-at-point))
|
||||
:general
|
||||
(phundrak/evil
|
||||
:pakages 'avy
|
||||
"gc" #'evil-avy-goto-char-timer
|
||||
"gl" #'evil-avy-goto-line)
|
||||
(phundrak/leader-key
|
||||
:packages 'avy
|
||||
:infix "j"
|
||||
"b" #'avy-pop-mark
|
||||
"c" #'evil-avy-goto-char-timer
|
||||
"l" #'avy-goto-line)
|
||||
(phundrak/leader-key
|
||||
:packages 'avy
|
||||
:infix "A"
|
||||
"c" '(:ignore t :which-key "copy")
|
||||
"cl" #'avy-copy-line
|
||||
"cr" #'avy-copy-region
|
||||
"k" '(:ignore t :which-key "kill")
|
||||
"kl" #'avy-kill-whole-line
|
||||
"kL" #'avy-kill-ring-save-whole-line
|
||||
"kr" #'avy-kill-region
|
||||
"kR" #'avy-kill-ring-save-region
|
||||
"m" '(:ignore t :which-key "move")
|
||||
"ml" #'avy-move-line
|
||||
"mr" #'avy-move-region
|
||||
"mt" #'avy-transpose-lines-in-region
|
||||
"n" #'avy-next
|
||||
"p" #'avy-prev
|
||||
"u" #'my/avy-goto-url
|
||||
"U" #'my/avy-open-url)
|
||||
(phundrak/major-leader-key
|
||||
:packages '(avy org)
|
||||
:keymaps 'org-mode-map
|
||||
"A" '(:ignore t :which-key "avy")
|
||||
"Ar" #'avy-org-refile-as-child
|
||||
"Ah" #'avy-org-goto-heading-timer))
|
||||
#+end_src
|
||||
|
||||
** Calc
|
||||
Let’s give ~calc-mode~ some better defaults.
|
||||
#+begin_src emacs-lisp
|
||||
(setq calc-angle-mode 'rad
|
||||
calc-symbolic-mode t)
|
||||
#+end_src
|
||||
|
||||
** Elcord
|
||||
What’s the point of using Emacs if you can’t tell everyone?
|
||||
#+begin_src emacs-lisp
|
||||
(use-package elcord
|
||||
:straight (:built t)
|
||||
:defer t
|
||||
:config
|
||||
(csetq elcord-use-major-mode-as-main-icon t
|
||||
elcord-refresh-rate 5
|
||||
elcord-boring-buffers-regexp-list `("^ "
|
||||
,(rx "*" (+ any) "*")
|
||||
,(rx bol (or "Re: "
|
||||
"Fwd: ")))))
|
||||
#+end_src
|
||||
|
||||
** ~ivy-quick-find-files.el~
|
||||
This package is a small utility package I’ve written in order to
|
||||
quickly find files across my filesystem.
|
||||
#+begin_src emacs-lisp
|
||||
(use-package ivy-quick-find-files
|
||||
:defer t
|
||||
:straight (ivy-quick-find-files :type git
|
||||
:host github
|
||||
:repo "phundrak/ivy-quick-find-files.el"
|
||||
:build t)
|
||||
:config
|
||||
(setq ivy-quick-find-files-program 'fd
|
||||
ivy-quick-find-files-dirs-and-exts '(("~/org" . "org")
|
||||
("~/Documents/university" . "org"))
|
||||
ivy-quick-find-files-fd-additional-options "-L"))
|
||||
#+end_src
|
||||
|
||||
** Keycast
|
||||
In case I am sharing my screen with people and I want to show which
|
||||
functions are called on my keystrokes since I don’t exactly use
|
||||
standard keybindings.
|
||||
#+begin_src emacs-lisp
|
||||
(use-package keycast
|
||||
:defer t
|
||||
:straight (:build t)
|
||||
:config
|
||||
(define-minor-mode keycast-mode
|
||||
"Show current command and its key binding in the mode line."
|
||||
:global t
|
||||
(if keycast-mode
|
||||
(add-hook 'pre-command-hook 'keycast--update t)
|
||||
(remove-hook 'pre-command-hook 'keycast--update)))
|
||||
(add-to-list 'global-mode-string '("" mode-line-keycast " ")))
|
||||
#+end_src
|
||||
|
||||
** Keyfreq
|
||||
Keyfreq is a package that records all the commands I call from Emacs
|
||||
and builds a heatmap out of it.
|
||||
#+begin_src emacs-lisp
|
||||
(use-package keyfreq
|
||||
:straight (:build t)
|
||||
:init
|
||||
(keyfreq-mode 1)
|
||||
(keyfreq-autosave-mode 1)
|
||||
:config
|
||||
(setq keyfreq-excluded-commands '(self-insert-command org-self-insert-command
|
||||
evil-previous-visual-line evil-next-visual-line
|
||||
ivy-next-line evil-backward-char evil-forward-char
|
||||
evil-next-line evil-previous-line evil-normal-state
|
||||
text-scale-pinch)))
|
||||
#+end_src
|
||||
|
||||
** Mastodon
|
||||
#+begin_src emacs-lisp
|
||||
(use-package mastodon
|
||||
:defer t
|
||||
:ensure t
|
||||
:straight (mastodon :type git
|
||||
:host codeberg
|
||||
:repo "martianh/mastodon.el")
|
||||
:config
|
||||
(setq mastodon-instance-url "https://emacs.ch"
|
||||
mastodon-active-user "phundrak")
|
||||
|
||||
(defun me/mastodon-toot--send-language-if-none ()
|
||||
(unless mastodon-toot--language
|
||||
(mastodon-toot--set-toot-language)))
|
||||
(advice-add #'me/mastodon-toot--send-language-if-none :before #'mastodon-toot--send)
|
||||
:general
|
||||
(phundrak/evil
|
||||
:packages '(mastodon)
|
||||
:keymaps 'mastodon-mode-map
|
||||
"]]" '(mastodon-tl--goto-next-toot :wk "Next status")
|
||||
"[[" '(mastodon-tl--goto-prev-toot :wk "Previous status")
|
||||
"gt" '(mastodon-tl--next-tab-item :wk "Next tab item")
|
||||
"gs" '(mastodon-tl--previous-tab-item :wk "Previous tab item")
|
||||
"»" '(mastodon-tl--goto-next-toot :wk "Next status")
|
||||
"«" '(mastodon-tl--goto-prev-toot :wk "Previous status")
|
||||
"q" #'kill-current-buffer)
|
||||
(phundrak/major-leader-key
|
||||
:package 'mastodon
|
||||
:keymaps 'mastodon-mode-map
|
||||
"#" '(mastodon-tl--get-tag-timeline :wk "Tag timeline")
|
||||
"f" '(mastodon-tl--get-federated-timeline :wk "Federated timeline")
|
||||
"F" '(mastoton-tl--view-filters :wk "Filters")
|
||||
"H" '(mastodon-tl--get-local-timeline :wk "Home timeline")
|
||||
"L" '(mastodon-tl--get-local-timeline :wk "Local timeline")
|
||||
"N" '(mastodon-notifications-get :wk "Notifications")
|
||||
"T" '(mastodon-tl--thread :wk "Thread")
|
||||
"O" '(mastodon-profile--my-profile :wk "My profile")
|
||||
"S" '(mastodon-tl--get-follow-suggestions :wk "Follow suggestions")
|
||||
"a" '(mastodon-profile--get-toot-author :wk "Toot author")
|
||||
"b" '(mastodon-profile--view-bookmarks :wk "Bookmarks")
|
||||
"s" '(mastodon-search--search-query :wk "Search query")
|
||||
"U" '(mastodon-tl--update :wk "Update")
|
||||
|
||||
"t" '(nil :wk "Toots")
|
||||
"tt" '(mastodon-toot :wk "Toot")
|
||||
"tb" '(mastodon-toot--toggle-boost :wk "Boost")
|
||||
"tB" '(mastodon-toot--bookmark-toot-toggle :wk "Bookmark")
|
||||
"td" '(mastodon-toot--delete-toot :wk "Delete")
|
||||
"tD" '(mastodon-toot--delete-and-redraft-toot :wk "Redraft")
|
||||
"tf" '(mastodon-toot--toggle-favourite :wk "Favourite")
|
||||
"tF" '(mastodon-profile--view-favourites :wk "View favourites")
|
||||
"tr" '(mastodon-toot--reply :wk "Reply")
|
||||
"tp" '(mastodon-toot--pin-toot-toggle :wk "Pin")
|
||||
"ts" '(mastodon-tl--toggle-spoiler-text-in-toot :wk "Spoiler")
|
||||
"tu" '(mastodon-toot--copy-toot-url :wk "Copy url")
|
||||
"tv" '(mastodon-tl--poll-vote :wk "Vote on poll")
|
||||
|
||||
"f" '(nil :wk "Follow requests")
|
||||
"fa" '(mastodon-notifications--follow-request-accept :wk "Accept")
|
||||
"fr" '(mastodon-notifications--follow-request-reject :wk "Reject")
|
||||
"fv" '(mastodon-profile--view-follow-requests :wk "View follow requests")
|
||||
|
||||
"u" '(nil :wk "User")
|
||||
"uf" '(mastodon-tl--follow-user :wk "Follow")
|
||||
"uF" '(mastodon-tl--unfollow-user :wk "Unfollow")
|
||||
"ub" '(mastodon-tl--block-user :wk "Block")
|
||||
"uB" '(mastodon-tl--unblock-user :wk "Unblock")
|
||||
"um" '(mastodon-tl--mute-user :wk "Mute")
|
||||
"uM" '(mastodon-tl--unmute-user :wk "Unmute")
|
||||
"un" '(mastodon-profile--update-user-profile-note :wk "Update user profile note")
|
||||
"uu" '(mastodon-profile--show-user :wk "Show user")))
|
||||
#+end_src
|
||||
|
||||
** Mediawiki
|
||||
#+begin_src emacs-lisp
|
||||
(use-package mediawiki
|
||||
:defer t
|
||||
:straight (:build t)
|
||||
:custom
|
||||
(mediawiki-site-alist '(("PhundrakWiki" ; Title
|
||||
"https://wiki.phundrak.com/" ; URL
|
||||
"phundrak" ; username
|
||||
nil ; password
|
||||
nil ; LDAP
|
||||
"Main Page")))) ; Default page
|
||||
#+end_src
|
||||
|
||||
** SICP
|
||||
Who would get interested in Emacs and not want to read the SICP?
|
||||
Moreover, inside Emacs?
|
||||
#+begin_src emacs-lisp
|
||||
(use-package sicp
|
||||
:straight (:build t)
|
||||
:defer t)
|
||||
#+end_src
|
||||
|
||||
** Winum
|
||||
Winum allows Emacs to associate windows with a specific number and
|
||||
navigate through these windows by directly refering to their
|
||||
associated number! This allows for faster window configuration than
|
||||
just going to the frame above, then left, left, and up.
|
||||
#+begin_src emacs-lisp
|
||||
(use-package winum
|
||||
:straight (:build t)
|
||||
:init (winum-mode))
|
||||
#+end_src
|
||||
|
||||
** Ytplay
|
||||
~ytplay~ is a small package I’ve written with which you can choose at
|
||||
which resolution to play a YouTube video in an external video player.
|
||||
#+begin_src emacs-lisp
|
||||
(use-package ytplay
|
||||
:defer t
|
||||
:straight (ytplay :build t
|
||||
:type git
|
||||
:repo "https://labs.phundrak.com/phundrak/ytplay.el"))
|
||||
#+end_src
|
||||
1399
docs/emacs/packages/org.org
Normal file
1399
docs/emacs/packages/org.org
Normal file
File diff suppressed because it is too large
Load Diff
1782
docs/emacs/packages/programming.org
Normal file
1782
docs/emacs/packages/programming.org
Normal file
File diff suppressed because it is too large
Load Diff
260
docs/emacs/packages/visual-config.org
Normal file
260
docs/emacs/packages/visual-config.org
Normal file
@@ -0,0 +1,260 @@
|
||||
#+title: Emacs — Packages — Visual Configuration
|
||||
#+setupfile: ../../headers
|
||||
#+property: header-args:emacs-lisp :mkdirp yes :lexical t :exports code
|
||||
#+property: header-args:emacs-lisp+ :tangle ~/.config/emacs/lisp/visual-config.el
|
||||
#+property: header-args:emacs-lisp+ :mkdirp yes :noweb no-export
|
||||
|
||||
* Visual Configuration
|
||||
** Dashboard
|
||||
#+begin_src emacs-lisp
|
||||
(use-package dashboard
|
||||
:straight (:build t)
|
||||
:ensure t
|
||||
:after all-the-icons
|
||||
:config
|
||||
(setq dashboard-banner-logo-title "Phundrak’s Vanilla Emacs"
|
||||
dashboard-startup-banner 'logo
|
||||
dashboard-center-content t
|
||||
dashboard-show-shortcuts t
|
||||
dashboard-set-navigator t
|
||||
dashboard-set-heading-icons t
|
||||
dashboard-set-file-icons t
|
||||
initial-buffer-choice (lambda () (get-buffer "*dashboard*"))
|
||||
dashboard-projects-switch-function 'counsel-projectile-switch-project-by-name)
|
||||
(setq dashboard-navigator-buttons
|
||||
`(((,(all-the-icons-faicon "language" :height 1.1 :v-adjust 0.0)
|
||||
"Linguistics Website"
|
||||
""
|
||||
(lambda (&rest _) (browse-url "https://langue.phundrak.com")))
|
||||
|
||||
(,(all-the-icons-faicon "firefox" :height 1.1 :v-adjust 0.0)
|
||||
"Config Website"
|
||||
""
|
||||
(lambda (&rest _) (browse-url "https://config.phundrak.com"))))
|
||||
|
||||
((,(all-the-icons-octicon "git-branch" :height 1.1 :v-adjust 0.0)
|
||||
"Dotfiles Sources"
|
||||
""
|
||||
(lambda (&rest _) (browse-url "https://labs.phundrak.com/phundrak/dotfiles")))
|
||||
("!" "Issues" "Show issues" (lambda (&rest _)
|
||||
(browse-url "https://labs.phundrak.com/phundrak/dotfiles/issues"))
|
||||
warning))
|
||||
((,(all-the-icons-faicon "level-up" :height 1.1 :v-adjust 0.0)
|
||||
"Update Packages"
|
||||
""
|
||||
(lambda (&rest _) (progn
|
||||
(require 'straight)
|
||||
(straight-pull-all)
|
||||
(straight-rebuild-all)))))))
|
||||
|
||||
(setq dashboard-items '((recents . 15)
|
||||
(agenda . 10)
|
||||
(projects . 10)))
|
||||
(dashboard-setup-startup-hook)
|
||||
:init
|
||||
(add-hook 'after-init-hook 'dashboard-refresh-buffer))
|
||||
#+end_src
|
||||
|
||||
** Fringe
|
||||
It’s nice to know which lines were modified since the last commit in a
|
||||
file.
|
||||
#+begin_src emacs-lisp
|
||||
(use-package git-gutter-fringe
|
||||
:straight (:build t)
|
||||
:hook ((prog-mode . git-gutter-mode)
|
||||
(org-mode . git-gutter-mode)
|
||||
(markdown-mode . git-gutter-mode)
|
||||
(latex-mode . git-gutter-mode)))
|
||||
#+end_src
|
||||
|
||||
** Icons? Did someone say icons?
|
||||
/*YES! ALL OF THEM!*/
|
||||
|
||||
Ahem…
|
||||
|
||||
The package ~all-the-icons~ allows us to use a wide variety of icons in
|
||||
Emacs for various purposes, wherever we want, and /THAT/ is *GREAT*! I’ll
|
||||
(ab)use this feature in my config, be warned! *NOTE*: The first time a
|
||||
configuration with ~all-the-icons~ loads on a machine, the needed fonts
|
||||
might not be available, so you’ll need to install them with the
|
||||
command ~M-x all-the-icons-install-fonts~.
|
||||
#+begin_src emacs-lisp
|
||||
(use-package all-the-icons
|
||||
:defer t
|
||||
:straight t)
|
||||
#+end_src
|
||||
|
||||
~prettify-symbols-mode~ is also a nifty feature of Emacs, and it is
|
||||
built-in! With that, I can replace strings of my choice by another
|
||||
character of my choice! First, let’s declare the general symbols that
|
||||
will be used everywhere.
|
||||
#+begin_src emacs-lisp
|
||||
(defun prog-mode-set-symbols-alist ()
|
||||
(setq prettify-symbols-alist '(("lambda" . ?λ)))
|
||||
(prettify-symbols-mode 1))
|
||||
|
||||
(add-hook 'prog-mode-hook #'prog-mode-set-symbols-alist)
|
||||
#+end_src
|
||||
|
||||
We can now take care of the language-specific symbols. First, let’s
|
||||
declare some symbols for the Lisp languages.
|
||||
#+begin_src emacs-lisp
|
||||
(setq-default lisp-prettify-symbols-alist '(("lambda" . ?λ)
|
||||
("defun" . ?𝑓)
|
||||
("defvar" . ?𝑣)
|
||||
("defcustom" . ?𝑐)
|
||||
("defconst" . ?𝐶)))
|
||||
|
||||
(defun lisp-mode-prettify ()
|
||||
(setq prettify-symbols-alist lisp-prettify-symbols-alist)
|
||||
(prettify-symbols-mode -1)
|
||||
(prettify-symbols-mode 1))
|
||||
|
||||
(dolist (lang '(emacs-lisp lisp common-lisp scheme))
|
||||
(add-hook (intern (format "%S-mode-hook" lang))
|
||||
#'lisp-mode-prettify))
|
||||
#+end_src
|
||||
|
||||
Finally, similar to how ~org-appear~ behaves, let’s show the real string
|
||||
of our symbols when the cursor is on it.
|
||||
#+begin_src emacs-lisp
|
||||
(setq prettify-symbols-unprettify-at-point t)
|
||||
#+end_src
|
||||
|
||||
** Ligatures
|
||||
The font I’m using (see *here*) supports ligatures, but Emacs in GUI
|
||||
mode does not. And of course, there’s a package for that.
|
||||
|
||||
# Insert equivalent of #Basic-configuration-Visual-Configuration-Fontsxfkjel6184j0 in *here*
|
||||
|
||||
#+begin_src emacs-lisp
|
||||
(use-package ligature
|
||||
:straight (ligature :type git
|
||||
:host github
|
||||
:repo "mickeynp/ligature.el"
|
||||
:build t)
|
||||
:config
|
||||
(ligature-set-ligatures 't
|
||||
'("www"))
|
||||
;; Enable traditional ligature support in eww-mode, if the
|
||||
;; `variable-pitch' face supports it
|
||||
(ligature-set-ligatures '(eww-mode org-mode elfeed-show-mode)
|
||||
'("ff" "fi" "ffi"))
|
||||
;; Enable all Cascadia Code ligatures in programming modes
|
||||
(ligature-set-ligatures 'prog-mode
|
||||
'("|||>" "<|||" "<==>" "<!--" "####" "~~>" "***" "||=" "||>"
|
||||
":::" "::=" "=:=" "===" "==>" "=!=" "=>>" "=<<" "=/=" "!=="
|
||||
"!!." ">=>" ">>=" ">>>" ">>-" ">->" "->>" "-->" "---" "-<<"
|
||||
"<~~" "<~>" "<*>" "<||" "<|>" "<$>" "<==" "<=>" "<=<" "<->"
|
||||
"<--" "<-<" "<<=" "<<-" "<<<" "<+>" "</>" "###" "#_(" "..<"
|
||||
"..." "+++" "/==" "///" "_|_" "www" "&&" "^=" "~~" "~@" "~="
|
||||
"~>" "~-" "**" "*>" "*/" "||" "|}" "|]" "|=" "|>" "|-" "{|"
|
||||
"[|" "]#" "::" ":=" ":>" ":<" "$>" "==" "=>" "!=" "!!" ">:"
|
||||
">=" ">>" ">-" "-~" "-|" "->" "--" "-<" "<~" "<*" "<|" "<:"
|
||||
"<$" "<=" "<>" "<-" "<<" "<+" "</" "#{" "#[" "#:" "#=" "#!"
|
||||
"##" "#(" "#?" "#_" "%%" ".=" ".-" ".." ".?" "+>" "++" "?:"
|
||||
"?=" "?." "??" ";;" "/*" "/=" "/>" "//" "__" "~~" "(*" "*)"
|
||||
"\\\\" "://"))
|
||||
(global-ligature-mode t))
|
||||
#+end_src
|
||||
|
||||
** Modeline
|
||||
The DoomEmacs modeline looks nice in my opinion, let’s use it.
|
||||
#+begin_src emacs-lisp
|
||||
(use-package doom-modeline
|
||||
:straight (:build t)
|
||||
:defer t
|
||||
:init (doom-modeline-mode 1)
|
||||
:config
|
||||
(csetq doom-modeline-height 15
|
||||
doom-modeline-enable-word-count t
|
||||
doom-modeline-continuous-word-count-modes '(markdown-mode gfm-mode org-mode)
|
||||
doom-modeline-mu4e t
|
||||
doom-modeline-env-version t)
|
||||
(mu4e-alert-enable-mode-line-display))
|
||||
#+end_src
|
||||
|
||||
** Pixel-perfect alignment of Markdown and org-mode tables
|
||||
:END:
|
||||
Usually, I have no issue with the alignment of the tables I write in
|
||||
org-mode and (more rarely) Markdown. However, there are occurences
|
||||
where I’ll use a character that does not exactly respect my monospace
|
||||
font, which messes with the alignment of the table (often when I do
|
||||
linguistics stuff). A solution to this is the package ~valign~. A little
|
||||
caveat though, as its name implies ~valign~ helps with vertical
|
||||
alignment. If some lines are too high, they won’t exactly fit. Unless?
|
||||
Unless ~valign-fancy-bar~ is set to ~t~.
|
||||
|
||||
For now, I disabled the hook with org-mode and markdown-mode because
|
||||
it slows down opening these files quite a lot. I’ll re-enable the hook
|
||||
once it is fixed.
|
||||
#+begin_src emacs-lisp
|
||||
(use-package valign
|
||||
:defer t
|
||||
:straight (:build t)
|
||||
:after (org markdown-mode)
|
||||
;; :hook ((org-mode markdown-mode) . valign-mode)
|
||||
:custom ((valign-fancy-bar t)))
|
||||
#+end_src
|
||||
|
||||
** Secret mode
|
||||
Sometimes, I want to hide the text displayed by Emacs but not lock
|
||||
altogether my computer. In this case, ~secret-mode~ comes in handy.
|
||||
#+begin_src emacs-lisp
|
||||
(use-package secret-mode
|
||||
:defer t
|
||||
:straight (secret-mode :build t
|
||||
:type git
|
||||
:host github
|
||||
:repo "bkaestner/secret-mode.el"))
|
||||
#+end_src
|
||||
|
||||
** Solaire: Incandescent Emacs
|
||||
A common issue when you have a lot of windows opened in Emacs is
|
||||
sometimes there’s just too much. Is the first window source code? Is
|
||||
the other one just an open email? Oh, let’s not forget the ~*Messages*~
|
||||
buffer open next to another source buffer.
|
||||
|
||||
Solaire-mode applies a subtle but useful tweak to your current color
|
||||
scheme: the background of programming buffers is slightly lighter than
|
||||
the background of other buffers. (Or is it other buffers that have a
|
||||
slightly darker background? I’m not sure.)
|
||||
#+begin_src emacs-lisp
|
||||
(use-package solaire-mode
|
||||
:defer t
|
||||
:straight (:build t)
|
||||
:init (solaire-global-mode +1))
|
||||
#+end_src
|
||||
|
||||
** Theme
|
||||
You may have noticed I use the Nord theme pretty much everywhere on my
|
||||
computer, why not Emacs? In my opinion, its aurora variant is nicer
|
||||
than the default Nord theme since it is richer in colors --- just a
|
||||
personal preference.
|
||||
#+begin_src emacs-lisp
|
||||
(use-package doom-themes
|
||||
:straight (:build t)
|
||||
:defer t
|
||||
:init (load-theme 'doom-nord-aurora t))
|
||||
#+end_src
|
||||
|
||||
** Rainbow Delimiters
|
||||
This makes Lisp especially more readable, but it’s also nice to have
|
||||
for any language that has delimiters like brackets too.
|
||||
#+begin_src emacs-lisp
|
||||
(use-package rainbow-delimiters
|
||||
:straight (:build t)
|
||||
:defer t
|
||||
:hook (prog-mode . rainbow-delimiters-mode))
|
||||
#+end_src
|
||||
|
||||
** Y’all want some more /COLORS/?
|
||||
It is possible to make info buffers much more colorful (and imo easier
|
||||
to read) with this simple package:
|
||||
#+begin_src emacs-lisp
|
||||
(use-package info-colors
|
||||
:straight (:build t)
|
||||
:commands info-colors-fnontify-node
|
||||
:hook (Info-selection . info-colors-fontify-node)
|
||||
:hook (Info-mode . mixed-pitch-mode))
|
||||
#+end_src
|
||||
Reference in New Issue
Block a user