Some adjustments to text

This commit is contained in:
2025-11-26 19:34:22 +00:00
parent 12da1e3dbb
commit fdd92a07fe

View File

@@ -142,6 +142,18 @@ reverting wherever possible.
revert-without-query '(".")) revert-without-query '("."))
(global-auto-revert-mode) (global-auto-revert-mode)
#+end_src #+end_src
I'd like ~duplicate-line~ to put the cursor at the newly created line,
rather than at the original line.
#+begin_src emacs-lisp
(setopt duplicate-line-final-position -1)
#+end_src
I'd also like ~async-shell-command~ to make a new buffer every time,
no need to check with me first!
#+begin_src emacs-lisp
(setopt async-shell-command-buffer 'new-buffer)
#+end_src
* Custom functionality and libraries * Custom functionality and libraries
This is custom Lisp that I or someone else has written which I really This is custom Lisp that I or someone else has written which I really
need to setup ASAP due to how necessary it is throughout the rest of need to setup ASAP due to how necessary it is throughout the rest of
@@ -160,6 +172,12 @@ An anonymous function (~lambda~) which takes no arguments is a
the macro being the body of the procedure. The function is returned the macro being the body of the procedure. The function is returned
quoted (as data rather than code), as that is the most common use of quoted (as data rather than code), as that is the most common use of
this macro. this macro.
We also have another helper macro which returns an interactive form -
this allows the procedure to be called "interactively" i.e. as a
command instead. There's a clear distinction between commands and
functions in emacs, which you can read about further
[[info:elisp#Using Interactive][here]].
#+begin_src emacs-lisp #+begin_src emacs-lisp
(defmacro proc (&rest BODY) (defmacro proc (&rest BODY)
"For a given list of forms BODY, return a quoted 0 argument "For a given list of forms BODY, return a quoted 0 argument
@@ -180,11 +198,10 @@ which allows you to do so - ~clean-buffers~.
By default, it will kill all buffers associated with the directory of By default, it will kill all buffers associated with the directory of
your current buffer. Using ~C-u~ will provide a list of directories your current buffer. Using ~C-u~ will provide a list of directories
for buffers available, which you can select from. ~C-u C-u~ will kill for buffers available, which you can select from. ~C-u C-u~ will kill
all buffers period. all buffers.
Please note ~clean-buffers-keep~, which defines a list of buffers that Please note ~clean-buffers-keep~, which defines a list of buffers that
must be preserved in any form of the operation above. must be preserved for any operation suggested by the above.
#+begin_src emacs-lisp #+begin_src emacs-lisp
(defconst +cfg/clean-buffers-keep (defconst +cfg/clean-buffers-keep
(list "*scratch*" "*dashboard*" (list "*scratch*" "*dashboard*"
@@ -234,10 +251,9 @@ must be preserved in any form of the operation above.
(setq items (buffer-list)))) (setq items (buffer-list))))
(message "[clean-buffers]: Cleaning %d buffers" (length items)) (message "[clean-buffers]: Cleaning %d buffers" (length items))
(if items
(thread-last items (thread-last items
(cl-remove-if should-not-kill) (cl-remove-if should-not-kill)
(mapc #'kill-buffer))))) (mapc #'kill-buffer))))
#+end_src #+end_src
** Custom window management ** Custom window management
Emacs has a window management system unlike any other piece of Emacs has a window management system unlike any other piece of
@@ -259,13 +275,19 @@ Here's an example record:
#+end_src #+end_src
This states that for any buffer named =config.org=, display the buffer This states that for any buffer named =config.org=, display the buffer
in a side window (the bottom to be precise). And there are a *lot* in a side window (the bottom, based on the later property record).
more ways to display buffers. We'd just need to ~add-to-list~ this to
~display-buffer-alist~ and that record will take first precedence. Emacs scans the ~display-buffer-alist~ for matches - the first one
that matches will be used for displaying the buffer. Therefore,
~cons~'ing your record to the alist will ensure your configuration
takes precedence.
*** ~:display~ keyword for use-package *** ~:display~ keyword for use-package
What I want to do is make the process of adding records to What I want to do is make the process of adding records to
~display-buffer-alist~ a bit smooter by integrating it into Emacs' ~display-buffer-alist~ a bit smoother by integrating it into Emacs'
use-package. use-package. ~use-package~ comes with an API to do so. Please don't
ask me how this works; I hacked it when I was much younger by copying
someone's configuration for it. It works and it seems to make sense,
so who cares?
2024-04-23: Found this option ~switch-to-buffer-obey-display-actions~ 2024-04-23: Found this option ~switch-to-buffer-obey-display-actions~
which makes manual buffer switches obey the same constraints via which makes manual buffer switches obey the same constraints via
@@ -330,16 +352,18 @@ never used before, 3 seems to be a reasonable default.
#+begin_src emacs-lisp #+begin_src emacs-lisp
(use-package comp (use-package comp
:init :init
(setq native-comp-async-jobs-number (thread-last
(pcase (system-name) (if (member (system-name) '("rhmaiden" "newboy"))
("ravenmaiden" 6) 6
(_ 3)))) 3)
(setq native-comp-async-jobs-number)))
#+end_src #+end_src
** Proper paths in Emacs ** Proper paths in Emacs
Imagine you adjust your path in ZSH. This change won't necessarily Imagine you adjust your path in ZSH. This change won't necessarily
affect the results of ~(getenv "PATH")~ - you'd need to ensure Emacs affect the results of ~(getenv "PATH")~ - you'd need to ensure Emacs
was loaded from a recent ZSH instance. This allows you to synchronise was loaded from a recent ZSH instance. This package allows you to
the PATH variable with the shell to avoid any silly issues. synchronise the PATH variable with the shell to avoid any silly
issues.
#+begin_src emacs-lisp #+begin_src emacs-lisp
(use-package exec-path-from-shell (use-package exec-path-from-shell
@@ -350,11 +374,11 @@ the PATH variable with the shell to avoid any silly issues.
(exec-path-from-shell-initialize))) (exec-path-from-shell-initialize)))
#+end_src #+end_src
** Reset font size ** Reset font size
Font size is best left unfixed: depending on the display size and the Font size is best left unfixed by the theme: depending on the display
machine, I will usually need to adjust it so it looks just right. size, I will usually need to adjust it so it looks just right. This
This function sets the font size using both those variables. It is function sets the font size using exactly that. It is also added to
also added to `enable-theme-functions` such that loading a theme will `enable-theme-functions` such that loading a theme will forcefully
forcefully adjust the font size. adjust the font size.
#+begin_src emacs-lisp #+begin_src emacs-lisp
(defvar +cfg/font-size-alist (defvar +cfg/font-size-alist
@@ -373,7 +397,7 @@ forcefully adjust the font size.
* Essential packages * Essential packages
External and internal packages absolutely necessary for the rest of External and internal packages absolutely necessary for the rest of
this configuration. this configuration.
** General - Bindings package ** TODO General - Bindings package
What's the point of an editor with no keybindings? Vanilla Emacs has What's the point of an editor with no keybindings? Vanilla Emacs has
the ~bind-key~ function (and the ~bind-key*~ macro) for this, but the ~bind-key~ function (and the ~bind-key*~ macro) for this, but
[[*Evil - Vim Emulation][Evil]] has it's own ~evil-define-key~. I'd [[*Evil - Vim Emulation][Evil]] has it's own ~evil-define-key~. I'd
@@ -386,11 +410,11 @@ over some pre-defined configuration, all through one interface.
Here I setup the rough outline of how bindings should be made in the Here I setup the rough outline of how bindings should be made in the
global scope, namely: global scope, namely:
+ Use "SPC" as a "leader", the root of all general bindings - Use "SPC" as a "leader", the root of all general bindings
+ Use "\" as a local-leader, the root of all major mode specific - Use "\" as a local-leader, the root of all major mode (read "mode
bindings specific") bindings
+ A few "definers" for the different sub bindings for the leader key - A few "definers" for the different sub bindings for the leader key
+ ~nmmap~ macro, for defining keys under both normal and motion - ~nmmap~ macro, for defining keys under both normal and motion
states. states.
#+begin_src emacs-lisp #+begin_src emacs-lisp
@@ -402,18 +426,7 @@ global scope, namely:
(general-def (general-def
:states '(normal motion) :states '(normal motion)
"SPC" nil "SPC" nil
"\\" nil "\\" nil)
"SPC a" nil
"SPC b" nil
"SPC c" nil
"SPC d" nil
"SPC f" nil
"SPC i" nil
"SPC m" nil
"SPC r" nil
"SPC s" nil
"SPC t" nil
"SPC q" nil)
(general-create-definer leader (general-create-definer leader
:states '(normal motion) :states '(normal motion)
@@ -479,11 +492,6 @@ global scope, namely:
:keymaps 'override :keymaps 'override
:prefix "SPC d") :prefix "SPC d")
(general-create-definer org-leader
:states '(normal motion)
:keymaps 'override
:prefix "SPC o")
(general-create-definer general-nmmap (general-create-definer general-nmmap
:states '(normal motion)) :states '(normal motion))
@@ -499,19 +507,21 @@ set of examples on how to use general.
#+begin_src emacs-lisp #+begin_src emacs-lisp
(use-package emacs (use-package emacs
:init
(setq duplicate-line-final-position -1
async-shell-command-buffer 'new-buffer)
:config
(defmacro +cfg/--then-recenter-top (&rest actions)
`(proc-int ,@actions (recenter 0)))
:general :general
;; Binding anywhere, without the use of a keyword or definer
(:keymaps 'override
"M-ESC" #'keyboard-quit)
(:keymaps 'help-map
"l" #'find-library)
;; Our basic leader bindings
(leader (leader
"SPC" #'execute-extended-command "SPC" #'execute-extended-command
"R" #'revert-buffer
":" (proc-int (switch-to-buffer "*scratch*"))
"!" #'async-shell-command "!" #'async-shell-command
"h" #'help-command) "h" #'help-command
"R" #'revert-buffer
":" (proc-int (switch-to-buffer "*scratch*")))
(mode-leader (mode-leader
"t" (proc-int (+cfg/load-theme)) "t" (proc-int (+cfg/load-theme))
@@ -525,12 +535,12 @@ set of examples on how to use general.
(file-leader (file-leader
"f" #'find-file "f" #'find-file
"P" (proc-int
(find-file (concat user-emacs-directory "config.org")))
"F" #'find-file-other-window "F" #'find-file-other-window
"t" #'find-file-other-tab "t" #'find-file-other-tab
"s" #'save-buffer
"v" #'add-file-local-variable "v" #'add-file-local-variable
"s" #'save-buffer) "P" (proc-int (find-file (concat user-emacs-directory "config.org")))
"S" (proc-int (find-file (concat user-emacs-directory "straight/"))))
(insert-leader (insert-leader
"c" #'insert-char) "c" #'insert-char)
@@ -555,9 +565,9 @@ set of examples on how to use general.
"q" #'save-buffers-kill-terminal "q" #'save-buffers-kill-terminal
"c" #'+literate/compile-config "c" #'+literate/compile-config
"C" #'+literate/clean-config "C" #'+literate/clean-config
"l" #'+literate/load-config "l" #'+literate/load-config)
"s" (proc-int (find-file (concat user-emacs-directory "straight/"))))
;; Narrowing binds
(leader (leader
:prefix "SPC n" :prefix "SPC n"
"p" #'narrow-to-page "p" #'narrow-to-page
@@ -569,7 +579,6 @@ set of examples on how to use general.
(nmmap (nmmap
:keymaps 'override :keymaps 'override
"M-'" #'replace-regexp-as-diff "M-'" #'replace-regexp-as-diff
"M-%" #'query-replace-regexp
"M-o" #'duplicate-dwim "M-o" #'duplicate-dwim
"M-;" #'comment-dwim "M-;" #'comment-dwim
"gC" #'comment-dwim "gC" #'comment-dwim
@@ -577,26 +586,18 @@ set of examples on how to use general.
"C--" #'text-scale-decrease "C--" #'text-scale-decrease
"C-=" #'text-scale-increase "C-=" #'text-scale-increase
"C-+" #'text-scale-adjust "C-+" #'text-scale-adjust
"M-[" (+cfg/--then-recenter-top (backward-paragraph))
"M-]" (+cfg/--then-recenter-top (forward-paragraph))
"M-Y" (proc-int (let ((current (point))) "M-Y" (proc-int (let ((current (point)))
(mark-whole-buffer) (mark-whole-buffer)
(call-interactively #'copy-region-as-kill) (call-interactively #'copy-region-as-kill)
(goto-char current))) (goto-char current)))
"M-D" (proc-int (mark-whole-buffer) "M-D" (proc-int (mark-whole-buffer)
(call-interactively #'delete-region))) (call-interactively #'delete-region))))
(:keymaps 'override
"M-ESC" #'keyboard-quit)
(:keymaps 'help-map
"l" #'find-library))
#+end_src #+end_src
** Evil - Vim emulation ** Evil - Vim emulation
My editor journey started off with Vim rather than Emacs, so my brain My editor journey started off with Vim rather than Emacs, so my brain
has imprinted on its style. Emacs is super extensible so there exists has imprinted on its style. Emacs is super extensible, so of course
a package for porting Vim's modal editing style to Emacs, called Evil there exists a package for porting Vim's modal editing style to Emacs,
(Extensible Vi Layer). called Evil (Extensible Vi Layer).
There are a lot of plugins in Vim that provide greater functionality, There are a lot of plugins in Vim that provide greater functionality,
for example tpope's "vim-surround". Emacs has some of these for example tpope's "vim-surround". Emacs has some of these
@@ -604,17 +605,9 @@ capabilities out of the box, but there are further packages which
integrate them into Evil. These are setup later in [[*Evil integrate them into Evil. These are setup later in [[*Evil
additions][Evil additions]]. additions][Evil additions]].
Setup the evil package, with some opinionated settings: Here I setup the evil package, with some opinionated settings. It
+ Switch ~evil-upcase~ and ~evil-downcase~ because I use ~evil-upcase~ may be best to read up on the various variables I set via Emacs' help
more system directly, rather than me explain every setting.
+ Use 'gt' prefix as an action for "transposing objects"
+ Swapping any two textual "objects" seems like a natural thing in
Vim considering the "verb-object" model most motions follow, but
by default Vim doesn't have the ability to do so. But Emacs can,
hence I can set these up.
+ Allow the Evil cursor to traverse EOLs like the Emacs cursor.
+ Do not move the cursor when exiting insert mode.
+ Respect visual lines, allowing movement through them.
#+begin_src emacs-lisp #+begin_src emacs-lisp
(use-package evil (use-package evil
:straight t :straight t
@@ -630,14 +623,9 @@ Setup the evil package, with some opinionated settings:
evil-want-keybinding nil evil-want-keybinding nil
evil-want-Y-yank-to-eol t evil-want-Y-yank-to-eol t
evil-want-change-word-to-end t evil-want-change-word-to-end t
evil-respect-visual-line-mode nil) evil-respect-visual-line-mode t)
:config :config
(evil-mode) (evil-mode)
(defun +evil/select-pasted ()
(interactive)
(evil-goto-mark 91)
(evil-visual-char)
(evil-goto-mark 93))
:general :general
(leader (leader
@@ -662,7 +650,6 @@ Setup the evil package, with some opinionated settings:
:keymaps 'override :keymaps 'override
"gu" #'evil-upcase "gu" #'evil-upcase
"gU" #'evil-downcase "gU" #'evil-downcase
"g C-v" #'+evil/select-pasted
"M-y" #'yank-pop "M-y" #'yank-pop
"T" 'nil) "T" 'nil)
@@ -683,10 +670,10 @@ command is ~execute-extended-command~, which takes a command name as
input then executes it. Input is taken from the /minibuffer/. input then executes it. Input is taken from the /minibuffer/.
A critical component of this interaction is text completion: given a A critical component of this interaction is text completion: given a
list of options and some user input, try to find an option that best list of options and some user input, help the user find an option that
fits it. Out of the box, Emacs provides the ~completions-list~ to best fits it. Out of the box, Emacs provides the ~completions-list~
help with selecting an option given some initial input, which can be to help with selecting an option given some initial input, which can
activated in the minibuffer using ~TAB~. This is quite a handy be activated in the minibuffer using ~TAB~. This is quite a handy
interface on its own, but we can do much better. interface on its own, but we can do much better.
So called "text completion frameworks" remodel the interaction with So called "text completion frameworks" remodel the interaction with
@@ -711,13 +698,18 @@ that.
*** Minibuffer *** Minibuffer
As described before, the minibuffer is the default text input/output As described before, the minibuffer is the default text input/output
mechanism. Here are some basic binds that I need to work effectively mechanism. Here are some basic binds that I need to work effectively
in it. in it:
+ By default, the minibuffer is in insert state, with Escape going to - By default, the minibuffer is in insert state, with Escape going to
normal state. M-escape allows quick exits from the minibuffer while normal state. M-escape allows quick exits from the minibuffer while
in insert state in insert state
+ In normal state, escape exits the minibuffer - In normal state, escape exits the minibuffer
+ ~M-{j, k}~ for selecting elements - ~M-{j, k}~ for selecting elements
+ ~<backtab>~ (shift + TAB) to switch to the completions list - ~<backtab>~ (shift + TAB) to switch to the completions list
I also setup our basic ~completion-styles~, which are the ways Emacs
will use the input we provide to filter the possible candidates. This
is a particularly critical component and I'd recommend taking a look
at [[*Orderless][Orderless]] for the state of the art here.
#+begin_src emacs-lisp #+begin_src emacs-lisp
(use-package minibuffer (use-package minibuffer
:defer t :defer t
@@ -757,9 +749,10 @@ replicate previous inputs.
#+end_src #+end_src
*** Completions list *** Completions list
The list of completions that comes by default with the minibuffer when The list of completions that comes by default with the minibuffer when
forcing it to complete some input is the completions list. Here I forcing it to complete some input is the completions list. We should
just make some binds to make selection easier, if and when I need to never really need to drop down to this level, as our completion
use it. framework should do a good job of allowing me to work through my
candidates.
#+begin_src emacs-lisp #+begin_src emacs-lisp
(use-package simple (use-package simple
@@ -831,18 +824,24 @@ point in this. However, after seeing that [[*empv][empv]] had some
embark bindings for cool behaviours (such as moving tracks around on embark bindings for cool behaviours (such as moving tracks around on
the live playlist) I had to try it out - and I was not disappointed. the live playlist) I had to try it out - and I was not disappointed.
~embark-act~ is the entry point to using embark, and you can use it It's somewhat difficult to explain exactly what Embark does in a
basically anywhere to great effect. Searching a buffer via simple manner. Consider it a way of extending your capabilities of
~consult-line~? ~execute-extended-command~? Looking for files? performing actions /while/ performing some kind of completion. You
~embark-act~ will pop up a little buffer full of keybindings specific activate Embark when completing something through ~embark-act~.
to that context that lower the time it takes to get what you want
done. Notice how general "performing some kind of completion" is. Searching
a buffer via ~consult-line~? ~execute-extended-command~? Looking for
files? ~embark-act~ will pop up a little buffer full of keybindings
specific to that context that lower the time it takes to get what you
want done.
A major reason for why this works so well is the actions buffer A major reason for why this works so well is the actions buffer
generated by ~embark-act~. You can actually use this buffer generated by ~embark-act~. You can actually use this buffer
generation when asking for help after a prefix-key, which I've set generation when asking for help after a prefix-key, which I've set
here. There are also many other little options you can tweak to make here (so anytime you've typed some prefix, =?= will generate an embark
embark act more like how you wish, which I've barely touch on here. buffer for you to peruse). There are also many other little options
you can tweak to make embark act more like how you wish, which I've
barely touched on here.
#+begin_src emacs-lisp #+begin_src emacs-lisp
(use-package embark (use-package embark
:after vertico :after vertico
@@ -996,10 +995,9 @@ should try to use Emacs defaults, so when setting up on a new computer
it takes a bit less time. it takes a bit less time.
Here I: Here I:
+ Bind ~project-prefix-map~ to "<leader>p" - Bind ~project-prefix-map~ to "<leader>p"
+ Bind a tags generation command to "<leader>pr" - Bind a tags generation command to "<leader>pr" which mimics
+ mimics projectile's one, so I can quickly generate them. projectile's one
+ mimicking
#+begin_src emacs-lisp #+begin_src emacs-lisp
(use-package project (use-package project
@@ -1309,7 +1307,7 @@ side by side.
:defer t :defer t
:hook (after-init-hook . zoom-mode) :hook (after-init-hook . zoom-mode)
:init :init
(setq zoom-size '(90 . 20))) (setq zoom-size '(80 . 40)))
#+end_src #+end_src
** Hide mode line ** Hide mode line
Custom minor mode to toggle the mode line. Check it out at Custom minor mode to toggle the mode line. Check it out at
@@ -1631,13 +1629,13 @@ software which deeply integrates with Emacs as a whole. I can't think
of a better file management tool than this. of a better file management tool than this.
*** Dired Core *** Dired Core
Here I setup dired with a few niceties Here I setup dired with a few niceties
+ Hide details by default (no extra stuff from ~ls~) - Hide details by default (no extra stuff from ~ls~)
+ Omit dot files by default (using ~dired-omit-mode~) - Omit dot files by default (using ~dired-omit-mode~)
+ If I have two dired windows open, moving or copying files in one - If I have two dired windows open, moving or copying files in one
dired instance will automatically target the other dired window dired instance will automatically target the other dired window
(~dired-dwim~) (~dired-dwim~)
+ If opening an application on a PDF file, suggest ~zathura~ - If opening an application on a PDF file, suggest ~zathura~
+ Examine all the subdirectories within the same buffer - Examine all the subdirectories within the same buffer
(~+dired/insert-all-subdirectories~) (~+dired/insert-all-subdirectories~)
#+begin_src emacs-lisp #+begin_src emacs-lisp
@@ -2021,9 +2019,9 @@ thankfully.
:END: :END:
2025-02-17: I haven't used this in at least 1.5 years. Why would I 2025-02-17: I haven't used this in at least 1.5 years. Why would I
use this when I can: use this when I can:
+ Use [[*EShell][EShell]] - Use [[*EShell][EShell]]
+ Use ~async-shell-command~ - Use ~async-shell-command~
+ Just spawn a terminal like a normie - Just spawn a terminal like a normie
There are a few times when EShell doesn't cut it, particularly in the There are a few times when EShell doesn't cut it, particularly in the
domain of TUI applications like ~cfdisk~. Emacs comes by default with domain of TUI applications like ~cfdisk~. Emacs comes by default with
@@ -2226,9 +2224,9 @@ IBuffer is the dired of buffers. Nothing much else to be said.
#+end_src #+end_src
** Proced ** Proced
Emacs has two systems for process management: Emacs has two systems for process management:
+ proced: a general 'top' like interface which allows general - proced: a general 'top' like interface which allows general
management of linux processes management of linux processes
+ list-processes: a specific Emacs based system that lists processes - list-processes: a specific Emacs based system that lists processes
spawned by Emacs (similar to a top for Emacs specifically) spawned by Emacs (similar to a top for Emacs specifically)
Core Proced config, just a few bindings and evil collection setup. Core Proced config, just a few bindings and evil collection setup.
@@ -2258,9 +2256,9 @@ diverse array of mathematical operations. It uses reverse polish
notation, but there is a standard infix algebraic notation mode so notation, but there is a standard infix algebraic notation mode so
don't be too shocked. It can do a surprising amount of stuff, such don't be too shocked. It can do a surprising amount of stuff, such
as: as:
+ finding derivatives/integrals of generic equations - finding derivatives/integrals of generic equations
+ matrix operations - matrix operations
+ finding solutions for equations, such as for finite degree multi - finding solutions for equations, such as for finite degree multi
variable polynomials variable polynomials
Perhaps most powerful is ~embedded-mode~. This allows one to perform Perhaps most powerful is ~embedded-mode~. This allows one to perform
@@ -3087,14 +3085,14 @@ write the code.
[remap imenu] #'consult-outline)) [remap imenu] #'consult-outline))
:general :general
(leader (leader
";" #'org-agenda) "ol" #'org-store-link
"od" #'org-babel-detangle
"oi" #'org-insert-last-stored-link
"oo" #'org-open-at-point-global)
(org-leader (leader
"l" #'org-store-link :keymaps 'org-mode-map
"a" #'org-agenda "ns" #'org-narrow-to-subtree)
"d" #'org-babel-detangle
"i" #'org-insert-last-stored-link
"o" #'org-open-at-point-global)
(nmmap (nmmap
:keymaps 'org-mode-map :keymaps 'org-mode-map
@@ -3165,11 +3163,15 @@ a very tidy way to manage your time.
:config :config
(evil-set-initial-state 'org-agenda-mode 'normal) (evil-set-initial-state 'org-agenda-mode 'normal)
:general :general
(leader
";" #'org-agenda)
(file-leader (file-leader
"a" (proc-int "a" (proc-int
(--> org-agenda-files (--> org-agenda-files
(completing-read "Enter file: " it nil t) (completing-read "Enter file: " it nil t)
(find-file it)))) (find-file it))))
(nmmap (nmmap
:keymaps 'org-agenda-mode-map :keymaps 'org-agenda-mode-map
"," #'org-agenda-goto-date "," #'org-agenda-goto-date
@@ -3192,9 +3194,9 @@ a very tidy way to manage your time.
Org capture provides a system for quickly "capturing" some information Org capture provides a system for quickly "capturing" some information
into an org file. A classic example is creating a new TODO in a into an org file. A classic example is creating a new TODO in a
todo file, where the bare minimum to record one is: todo file, where the bare minimum to record one is:
+ where was it recorded? - where was it recorded?
+ when was it recorded? - when was it recorded?
+ what is it? - what is it?
Org capture provides a way to do that seamlessly without opening the Org capture provides a way to do that seamlessly without opening the
todo file directly. todo file directly.
@@ -3217,8 +3219,8 @@ todo file directly.
%? %?
,#+end_quote"))) ,#+end_quote")))
:general :general
(org-leader (leader
"c" #'org-capture) "oc" #'org-capture)
(nmmap (nmmap
:keymaps 'org-capture-mode-map :keymaps 'org-capture-mode-map
"ZZ" #'org-capture-finalize "ZZ" #'org-capture-finalize
@@ -3415,10 +3417,10 @@ the [[https://elpa.gnu.org/packages/nhexl-mode.html][page]] yourself.
Setup for C and C++ modes, using Emacs' default package: cc-mode. Setup for C and C++ modes, using Emacs' default package: cc-mode.
*** cc-mode *** cc-mode
Tons of stuff, namely: Tons of stuff, namely:
+ ~auto-fill-mode~ for 80 char limit - ~auto-fill-mode~ for 80 char limit
+ Some keybindings to make evil statement movement easy - Some keybindings to make evil statement movement easy
+ Lots of pretty symbols - Lots of pretty symbols
+ Indenting options and a nice (for me) code style for C - Indenting options and a nice (for me) code style for C
#+begin_src emacs-lisp #+begin_src emacs-lisp
(use-package cc-mode (use-package cc-mode
@@ -3513,7 +3515,7 @@ This is a generic auto-insert template for C/C++ files.
" * Commentary:\n" " * Commentary:\n"
" */\n" " */\n"
"\n\n" "\n\n"
"#ifndef " str n "#define " str "\n\n" "\n\n#endif\n" "#ifndef " str n "#define " str "\n\n" "\n\n#endif\n\n"
"/" (+cc/copyright-notice) "\n\n*/")) "/" (+cc/copyright-notice) "\n\n*/"))
#+end_src #+end_src
*** Clang format *** Clang format
@@ -4226,81 +4228,9 @@ appropriately.
(setq-default lisp-indent-function #'+cfg/lisp-indent-function)) (setq-default lisp-indent-function #'+cfg/lisp-indent-function))
#+end_src #+end_src
* Miscellaneous * Miscellaneous
** gptel
LLMs in my Emacs?? What kind of developer have I become!
I came kinda late to the party with AI and LLM usage for development -
I did try them out much earlier near 2022-2023 but found them
obtrusive to use. They didn't integrate into my workflow well and
providing the context necessary for some of the problems I was facing
was, in and of itself, a gargantuan task.
~gptel~ changes that in quite a dramatic way: incredibly smooth
integration of LLMs into my Emacs instance. Some things this package
does:
- Call an LLM from any buffer in Emacs: from code buffers, to a
dedicated chat buffer, even [[*EShell][EShell]]!
- Maintain large persistent conversations just by saving the
conversation to disc
- Use ~org-mode~ for conversations, so generated code is actually in
clean source code blocks
- Allows one to slickly use all options available via one transient
interface ~gptel-menu~
#+begin_src emacs-lisp
(use-package gptel
:straight t
:general
(app-leader
"g" #'gptel-menu)
(local-leader
:keymaps 'gptel-mode-map
"RET" #'gptel-send)
:init
(setq gptel-default-mode 'org-mode
gptel-prompt-prefix-alist '((markdown-mode . "# Prompt:")
(org-mode . "* Prompt:")
(text-mode . "# Prompt:"))
gptel-response-prefix-alist '((markdown-mode . "# Response:\n")
(org-mode . "* Response:\n")
(text-mode . "# Response:\n"))
gptel-directives
'((default . "You are a large language model living in Emacs and a helpful assistant. Respond concisely and with justification.")
(programming . "You are a large language model and a careful programmer. Provide code and only code as output without any additional text, prompt or note.")
(writing . "You are a large language model and a writing assistant. Respond concisely.")
(chat . "You are a large language model and a conversation partner. Respond concisely.")
(networking . "You are a large language model and an experienced networking technician talking to a colleague. You have the CCNA qualification. Respond concisely and with justification.")))
:config
(defun gptel-auto-fill-response (beg end)
"Auto-fill the text response inserted between BEG and END, skipping Org
source code blocks."
(save-excursion
(goto-char beg)
(let ((current-point beg))
(while (re-search-forward "^\s*#\\+begin_src\\|^\s*#\\+end_src" end t)
;; we've found a block indicator - what kind of block is it?
(let ((block-start (match-beginning 0))
(block-end (match-end 0)))
(cond
((and (string-match-p "^\s*#\\+begin_src" (match-string 0))
(< current-point block-start))
;; We should fill everything we can up to the source block
(fill-region current-point block-start)
;; make sure we move current-point to look for the "end of block"
(setq current-point block-end))
(t
;; we're at an end block indicator, so we should bump our
;; current-point just past it.
(setq current-point (1+ block-end)))))
(goto-char current-point))
(when (< current-point end)
;; Any stragglers, get them filled as well
(fill-region current-point end)))))
(add-hook 'gptel-post-response-functions #'gptel-auto-fill-response))
#+end_src
** Evil additions ** Evil additions
Additional packages that add the functionality of plugins in Vim I Additional packages that add the functionality of plugins in Vim I
really liked, as well as some new stuff. really liked, as well as some new stuff. Also some stuff from me.
*** Evil surround *** Evil surround
A port for vim-surround, providing the ability to mutate delimiters A port for vim-surround, providing the ability to mutate delimiters
around some text. around some text.
@@ -4381,6 +4311,94 @@ Make it easier to notice edits and changes using Vim motions!
(evil-goggles-mode) (evil-goggles-mode)
(evil-goggles-use-diff-faces)) (evil-goggles-use-diff-faces))
#+end_src #+end_src
*** Evil copying what I pasted
A little helper function to instantly mark anything I paste.
#+begin_src emacs-lisp
(use-package evil
:straight t
:defer t
:config
(defun +evil/select-pasted ()
(interactive)
(evil-goto-mark 91)
(evil-visual-char)
(evil-goto-mark 93))
:general
(nmmap
"g C-v" #'+evil/select-pasted))
#+end_src
** gptel
LLMs in my Emacs?? What kind of developer have I become!
I came kinda late to the party with AI and LLM usage for development -
I did try them out much earlier near 2022-2023 but found them
obtrusive to use. They didn't integrate into my workflow well and
providing the context necessary for some of the problems I was facing
was, in and of itself, a gargantuan task.
~gptel~ changes that in quite a dramatic way: incredibly smooth
integration of LLMs into my Emacs instance. Some things this package
does:
- Call an LLM from any buffer in Emacs: from code buffers, to a
dedicated chat buffer, even [[*EShell][EShell]]!
- Maintain large persistent conversations just by saving the
conversation to disc
- Use ~org-mode~ for conversations, so generated code is actually in
clean source code blocks
- Allows one to slickly use all options available via one transient
interface ~gptel-menu~
#+begin_src emacs-lisp
(use-package gptel
:straight t
:general
(app-leader
"g" #'gptel-menu)
(local-leader
:keymaps 'gptel-mode-map
"RET" #'gptel-send)
:init
(setq gptel-default-mode 'org-mode
gptel-prompt-prefix-alist '((markdown-mode . "# Prompt:")
(org-mode . "* Prompt:")
(text-mode . "# Prompt:"))
gptel-response-prefix-alist '((markdown-mode . "# Response:\n")
(org-mode . "* Response:\n")
(text-mode . "# Response:\n"))
gptel-directives
'((default . "You are a large language model living in Emacs and a helpful assistant. Respond concisely and with justification.")
(programming . "You are a large language model and a careful programmer. Provide code and only code as output without any additional text, prompt or note.")
(writing . "You are a large language model and a writing assistant. Respond concisely.")
(chat . "You are a large language model and a conversation partner. Respond concisely.")
(networking . "You are a large language model and an experienced networking technician talking to a colleague. You have the CCNA qualification. Respond concisely and with justification.")))
:config
(defun gptel-auto-fill-response (beg end)
"Auto-fill the text response inserted between BEG and END, skipping Org
source code blocks."
(save-excursion
(goto-char beg)
(let ((current-point beg))
(while (re-search-forward "^\s*#\\+begin_src\\|^\s*#\\+end_src" end t)
;; we've found a block indicator - what kind of block is it?
(let ((block-start (match-beginning 0))
(block-end (match-end 0)))
(cond
((and (string-match-p "^\s*#\\+begin_src" (match-string 0))
(< current-point block-start))
;; We should fill everything we can up to the source block
(fill-region current-point block-start)
;; make sure we move current-point to look for the "end of block"
(setq current-point block-end))
(t
;; we're at an end block indicator, so we should bump our
;; current-point just past it.
(setq current-point (1+ block-end)))))
(goto-char current-point))
(when (< current-point end)
;; Any stragglers, get them filled as well
(fill-region current-point end)))))
(add-hook 'gptel-post-response-functions #'gptel-auto-fill-response))
#+end_src
** Save place ** Save place
Saves current place in a buffer permanently, so on revisiting the file Saves current place in a buffer permanently, so on revisiting the file
(even in a different Emacs instance) you go back to the place you were (even in a different Emacs instance) you go back to the place you were
@@ -4462,11 +4480,11 @@ effectively.
Registers are essentially an alist of symbols mapped to some Lisp Registers are essentially an alist of symbols mapped to some Lisp
object, which can be easily accessed and manipulated. Some common use object, which can be easily accessed and manipulated. Some common use
cases of registers are: cases of registers are:
+ Marking locations in a file to quickly go to (using Emacs' in-built - Marking locations in a file to quickly go to (using Emacs' in-built
notion of marks) notion of marks)
+ Copying and pasting text without the clipboard (essentially even - Copying and pasting text without the clipboard (essentially even
more clipboards) more clipboards)
+ Creating number counters (usually for macros) - Creating number counters (usually for macros)
Of course, Vim has its own notion of registers which are way less Of course, Vim has its own notion of registers which are way less
capable than Emacs. Evil emulates this limited notion of registers, capable than Emacs. Evil emulates this limited notion of registers,
@@ -4554,7 +4572,7 @@ Avy is a package that provides "jump" functions. Given some input,
the current buffer is scanned and any matching candidates are given a the current buffer is scanned and any matching candidates are given a
tag which the user can input to perform some action (usually moving tag which the user can input to perform some action (usually moving
the cursor to that point). the cursor to that point).
*** Avy core *** Avy
Setup avy with leader. As I use ~avy-goto-char-timer~ a lot, use the Setup avy with leader. As I use ~avy-goto-char-timer~ a lot, use the
~C-s~ bind which replaces isearch. Switch isearch to M-s in case I ~C-s~ bind which replaces isearch. Switch isearch to M-s in case I
need to use it. need to use it.
@@ -4568,6 +4586,7 @@ need to use it.
:keymaps 'override :keymaps 'override
"C-s" #'avy-goto-char-timer "C-s" #'avy-goto-char-timer
"M-s" #'isearch-forward "M-s" #'isearch-forward
"g/" #'avy-isearch
"gp" #'avy-copy-region "gp" #'avy-copy-region
"gP" #'avy-move-region "gP" #'avy-move-region
"gl" #'avy-goto-line "gl" #'avy-goto-line
@@ -4624,7 +4643,9 @@ symbols around as I wanted.
:general :general
(nmmap (nmmap
"C-M-h" #'jagger-move-sexp-backward "C-M-h" #'jagger-move-sexp-backward
"C-M-l" #'jagger-move-sexp-forward)) "C-M-l" #'jagger-move-sexp-forward
"C-M-j" #'jagger-move-line-down
"C-M-k" #'jagger-move-line-up))
#+end_src #+end_src
** Separedit ** Separedit
Edit anything anywhere all at once! Edit anything anywhere all at once!
@@ -4725,7 +4746,8 @@ such as presenting the key bind when looking for a command.
:straight t :straight t
:demand t :demand t
:init :init
(setq amx-backend 'auto) (setq amx-backend 'auto
read-extended-command-predicate #'command-completion-default-include-p)
:config :config
(amx-mode)) (amx-mode))
#+end_src #+end_src
@@ -4747,3 +4769,21 @@ for all snippets I've got.
(yas-load-directory (no-littering-expand-etc-file-name (yas-load-directory (no-littering-expand-etc-file-name
"yasnippet/snippets"))) "yasnippet/snippets")))
#+end_src #+end_src
** Movement with re-centring
When reading text at leisure, I like to move paragraph by paragraph.
My cursor designates the paragraph I'm reading currently. With
particularly long pieces of text, my cursor can be moving all across
the screen, so I like to recenter the buffer around the cursor. Here
are some movements to package that movement in one go.
#+begin_src emacs-lisp
(use-package emacs
:config
(defmacro +cfg/--then-recenter-top (&rest actions)
`(proc-int ,@actions (recenter 0)))
:general
(nmmap
:keymaps 'override
"M-[" (+cfg/--then-recenter-top (backward-paragraph))
"M-]" (+cfg/--then-recenter-top (forward-paragraph))))
#+end_src