New way to display line-numbers. I set mine to =relative= so that I can jump up and down by that value. Set this to =nil= to turn off, or =t= to be absolute.
I like the rendering to curved quotes using [[help:text-quoting-style][text-quoting-style]], because it improves the readability of documentation strings in the =∗Help∗= buffer and whatnot.
As [[https://tecosaur.github.io/emacs-config/config.html][tec wrote]], I want to use =~/.authsource.gpg= as I don’t want to accidentaly purge this file cleaning =~/.emacs.d=, and let's cache as much as possible, as my home machine is pretty safe, and my laptop is shutdown a lot. Also, as [[https://www.bytedude.com/gpg-in-emacs/][bytedude]] mentions, I need to se the =epa-pineentry-mode= to =loopback= to actually get a prompt for the password, instead of an error.
Since I have troubles installing Doom’s [[https://github.com/hlissner/doom-snippets][collection of snippets]], lets use the [[http://github.com/AndreaCrotti/yasnippet-snippets][yasnippet-snippets]] package:
The [[https://www.emacswiki.org/emacs/AutoInsertMode][auto-insert]] feature is a wee bit complicated. All I want is to associate a filename regular expression with a YASnippet template. I'm stealing some ideas from Henrik Lissner's [[https://github.com/hlissner/doom-emacs/blob/develop/modules/editor/file-templates/autoload.el][set-file-template!]] macro, but simpler?
Always spaces and never tabs. Note that we use =setq-default= since [[elisp:(describe-variable 'indent-tabs-mode)][indent-tabs-mode]] is a /buffer-local/ variable, meaning using =setq=, sets it for /that buffer file/. We want this globally the default:
When I push changes to my files to Gerrit and other code review, I don’t want trailing spaces or any tabs to appear, so let’s fix all files when I [[elisp:(describe-variable 'before-save-hook)][save them]]:
The [[https://www.emacswiki.org/emacs/RecentFiles][recentf]] feature has been in Emacs for a long time, but it has a problem with Tramp, as we need to turn off the cleanup feature that attempts to =stat= all the files and remove them from the =recent= accessed list if they are readable. The requires recentf to open up a remote files which blocks Emacs at the most inopportune times… like when trying to reboot the machine.
#+begin_src emacs-lisp
(use-package recentf
:straight (:type built-in)
:config
(setq recentf-auto-cleanup 'never) ;; disable before we start recentf!
(recentf-mode 1))
#+end_src
*** File Backups
While I use git as much as I can, sometimes Emacs’ built-in file backup and versioning feature has saved me for files that aren’t.
As [[https://philjackson.github.io//emacs/backups/2022/01/31/keeping-backups-of-every-edited-file/][Phil Jackson]] mentioned, Emacs has a lot of variations to its file backup strategy, and either change the [[help:backup-directory-alist][backup-directory-alist]] to put individual file backups elsewhere, e.g.
After using Ivy, I am going the route of a =completing-read= interface that extends the original Emacs API, as opposed to implementing backend-engines or complete replacements.
The [[https://github.com/minad/vertico][vertico]] package puts the completing read in a vertical format, and like [[https://github.com/raxod502/selectrum#vertico][Selectrum]], it extends Emacs’ built-in functionality, instead of adding a new process. This means all these projects work together.
My issue with Vertico is when calling =find-file=, the Return key opens =dired=, instead of inserting the directory at point. This package addresses this:
This fuzzy completion style is like the built-in =flex= style, but has a better scoring algorithm, non-greedy and ranks completions that match at word; path component; or camelCase boundaries higher.
While flexible at matching, you have to get the /order/ correct. For instance, ~alireg~ matches with [[help:align-regexp][align-regexp]], but ~regali~ does not, so we will use =hotfuzz= for scoring, and not use this as a completion-project (see the =fussy= project below).
While the space can be use to separate words (acting a bit like a =.*= regular expression), the [[https://github.com/oantolin/orderless][orderless]] project allows those words to be in any order.
The [[https://github.com/jojojames/fussy][fussy]] project is a fuzzy pattern matching extension for the normal [[help:completing-read][completing-read]] interface. By default, it uses [[https://github.com/lewang/flx][flx]], but we can specify other sorting and filtering algorithms.
How does it compare? Once upon a time, I enjoyed typing ~plp~ for =package-list-packages=, and when I switched to [[https://github.com/oantolin/orderless][orderless]], I would need to put a space between the words. While I will continue to play with the different mechanism, I’ll combine =hotfuzz= and =orderless=.
Persist history over Emacs restarts using the built-in [[https://www.emacswiki.org/emacs/SaveHist][savehist]] project. Since both Vertico and Selectrum sorts by history position, this should make the choice /smarter/ with time.
The [[https://github.com/minad/marginalia][marginalia]] package gives a preview of =M-x= functions with a one line description, extra information when selecting files, etc. Nice enhancement without learning any new keybindings.
Why use [[https://gitlab.com/ideasman42/emacs-undo-fu][undo-fu]] instead of the built-in undo functionality? Well, there isn’t much to the project (that’s a good thing), but It basically doesn’t /cycle/ around the redo, which annoying.
- [[https://stackoverflow.com/questions/25542097/emacs-evil-mode-how-to-change-insert-state-to-emacs-state-automatically][Evil insert state is really Emacs?]] Real answer to that is to set [[help:evil-disable-insert-state-bindings][evil-disable-insert-state-bindings]]
While I’m pretty good with the VIM keybindings, I would like to play around with the [[https://evil.readthedocs.io/en/latest/extension.html#text-objects][text objects]] and how it compares to others (including the surround), for instance:
- ~g~ :: within a brace, paren, etc., with the [[Better Parenthesis with Text Object][my extensions below]], see ~b~ and ~f~ for similar functionality.
- ~a~ :: function arguments (probably a lot like symbol, ~o~) with the [[https://github.com/wcsmith/evil-args][evil-args]] extension (that I’m not bothering with)
Delete a line, ~d d~ is in basic VI. Since some commands use text objects, and the basic text object doesn’t include lines, the [[https://github.com/emacsorphanage/evil-textobj-line][evil-textobj-line]] project adds that:
The [[https://github.com/TheBB/evil-indent-plus][evil-indent-plus]] project creates text objects based on the indentation level, similar to how the ~b~ works with “blocks” of code.
This can be handy for Python, YAML, and lists in org files. Note that ~i~ works for the current indent, but ~k~ includes one line above and ~j~ includes one line above and below.
*** Arguments as Text Objects
The [[https://github.com/wcsmith/evil-args][evil-args]] projects creates text objects for symbols, but with trailing ~,~ or other syntax.
#+begin_src emacs-lisp
(use-package evil-args
:config
;; bind evil-args text objects
(define-key evil-inner-text-objects-map "a" 'evil-inner-arg)
(define-key evil-outer-text-objects-map "a" 'evil-outer-arg)
I took the following clever idea and code from [[http://blog.binchen.org/posts/code-faster-by-extending-emacs-evil-text-object/][this essay]] from Chen Bin for creating a ~xig~ to grab code within any grouping characters, like parens, braces and brackets. For instance, ~dig~ cuts the content inside brackets, etc. First, we need a function to do the work (I changed the original from =my-= to =ha-= so that it is easier for me to distinguish functions from my configuration):
#+begin_src emacs-lisp
(defun ha-evil-paren-range (count beg end type inclusive)
"Get minimum range of paren text object.
COUNT, BEG, END, TYPE is used. If INCLUSIVE is t, the text object is inclusive."
(let* ((parens '("()" "[]" "{}" "<>"))
range
found-range)
(dolist (p parens)
(condition-case nil
(setq range (evil-select-paren (aref p 0) (aref p 1) beg end type count inclusive))
(error nil))
(when range
(cond
(found-range
(when (< (- (nth 1 range) (nth 0 range))
(- (nth 1 found-range) (nth 0 found-range)))
(setf (nth 0 found-range) (nth 0 range))
(setf (nth 1 found-range) (nth 1 range))))
(t
(setq found-range range)))))
found-range))
#+end_src
Extend the text object to call this function for both /inner/ and /outer/:
#+begin_src emacs-lisp
(evil-define-text-object ha-evil-a-paren (count &optional beg end type)
"Select a paren."
:extend-selection t
(ha-evil-paren-range count beg end type t))
(evil-define-text-object ha-evil-inner-paren (count &optional beg end type)
The [[https://github.com/PythonNut/evil-easymotion][evil-easymotion]] project combines [[Jump with Avy][avy]] and evil keybindings, where ~SPC j~ shows labels for all the lines below the cursor, so that you can jump right there. This doesn’t work well with a leader, but what about using Key Chords?
#+begin_src emacs-lisp
(use-package evil-easymotion
:config (evilem-default-keybindings "<f19>"))
#+end_src
My ~F19~ key is within easy reach of my [[https://configure.zsa.io/moonlander/layouts/L4laD/latest/0][Moonlander configuration]], so this might be a good, if somewhat distracting, feature. Perhaps a better solution is to use [[Jump with Avy][avy]] (see below).
The [[https://github.com/edkolev/evil-lion][evil-lion]] package is a wrapper around Emacs’ [[help:align][align]] function. Just a little easier to use. Primary sequence is ~g a i p =~ to align along all the equal characters in the paragraph (block), or ~g a i b RET~ to use a built in rule to align (see below), or ~g a i b /~ to specify a regular expression, similar to [[help:align-regexp][align-regexp]].
Where I like to align, is on variable assignments, e.g.
#+begin_src emacs-lisp :tangle no
(let ((foobar "Something something")
(a 42)
(very-long-var "odd string"))
;;
)
#+end_src
If you press ~RETURN~ for the /character/ to align, =evil-lion= package simply calls the built-in [[help:align][align]] function. This function chooses a regular expression based on a list of /rules/, and aligning Lisp variables requires a complicated regular expression. Extend [[elisp:(describe-variable 'align-rules-list)][align-rules-list]]:
The one thing that both Spacemacs and Doom taught me, is how much I like the /key sequences/ that begin with a leader key. In both of those systems, the key sequences begin in the /normal state/ with a space key. This means, while typing in /insert state/, I have to escape to /normal state/ and then hit the space.
I'm not trying an experiment where specially-placed function keys on my fancy ergodox keyboard can kick these off using [[https://github.com/noctuid/general.el][General Leader]] project. Essentially, I want a set of leader keys for Evil's /normal state/ as well as a global leader in all modes.
Let's try this general "space" prefix by defining some top-level operations, including hitting ~space~ twice to bring up the =M-x= collection of functions:
This is nice since the window numbers are always present on a Doom modeline, but they order the window numbers /differently/ than =ace-window=. Let's see which I end up liking better.
Ways to search for information goes under the ~s~ key. The venerable sage has always been =grep=, but we now have new-comers, like [[https://github.com/BurntSushi/ripgrep][ripgrep]], which are really fast.
**** ripgrep
Install the [[https://github.com/dajva/rg.el][rg]] package, which builds on the internal =grep= system, and creates a =*rg*= window with =compilation= mode, so ~C-j~ and ~C-k~ will move and show the results by loading those files.
I don’t understand the bug associated with the =:general= extension to =use-package=, but it /works/, but stops everything else from working, so pulling it out into its own =use-package= section addresses that issue:
The [[https://github.com/mhayashi1120/Emacs-wgrep][wgrep package]] integrates with =ripgrep=. Typically, you hit ~i~ to automatically go into =wgrep-mode= and edit away, but since I typically want to edit everything at the same time, I have a toggle that should work as well:
Unfilling a paragraph joins all the lines in a paragraph into a single line. Taken [[http://www.emacswiki.org/UnfillParagraph][from here]] … I use this all the time:
The [[https://github.com/minad/consult][consult project]] aims to use libraries like [[*Vertico][Vertico]] to enhance specific, built-in, Emacs functions. I appreciate this project that when selecting an element in the minibuffer, it displays what you are looking at… for instance, it previews a buffer before choosing it. Unlike /Vertico/ and /Orderless/, you need to bind keys to its special functions (or rebind existing keys that do something similar).
One of the reasons that Consult hasn’t been too important to me, is that I often narrow my searching based on projectile. The [[https://gitlab.com/OlMon/consult-projectile][consult-projectile]] can help with this.
The [[https://github.com/oantolin/embark/][embark]] project offers /actions/ on /targets/. I'm primarily thinking of acting on selected items in the minibuffer, but these commands act anywhere. I need an easy-to-use keybinding that doesn't conflict. Hey, that is what the Super key is for, right?
According to [[https://elpa.gnu.org/packages/embark-consult.html#orgc76b5de][this essay]], Embark cooperates well with the [[https://github.com/minad/marginalia][Marginalia]] and [[https://github.com/minad/consult][Consult]] packages. Neither of those packages is a dependency of Embark, but Embark supplies a hook for Consult where Consult previews can be done from Embark Collect buffers:
According to the [[https://elpa.gnu.org/packages/embark-consult.html][Embark-Consult page]]:
#+begin_quote
Users of the popular [[https://github.com/justbur/emacs-which-key][which-key]] package may prefer to use the =embark-which-key-indicator= from the [[https://github.com/oantolin/embark/wiki/Additional-Configuration#use-which-key-like-a-key-menu-prompt][Embark wiki]]. Just copy its definition from the wiki into your configuration and customize the =embark-indicators= user option to exclude the mixed and verbose indicators and to include =embark-which-key-indicator=.
#+end_quote
In other words, typing ~s-;~ to call Embark, specifies the options in a buffer, but the following code puts them in a smaller configuration directly above the selections.
I often use the Emacs commands, ~M-t~ and whatnot to exchange words and whatnot, but this requires a drop out of normal state mode. The [[https://github.com/Dewdrops/evil-exchange][evil-exchange]] project attempts to do something similar, but in a VI-way, and the /objects/ do not need to be adjacent.
Move the point to the word, /red/, and type ~g x i w~ (anywhere since we are using the inner text object). Next, jump to the word /blue/, and type the sequence, ~g x i w~ again, and you have:
The ball was blue and the boy was red.
The idea is that you can exchange anything. The ~g x~ marks something (like what we would normally do in /visual mode/), and then by marking something else with a ~g x~ sequence, it swaps them.
The [[https://github.com/linktohack/evil-commentary][evil-commentary]] is a VI-like way of commenting text. Yeah, I typically type ~M-;~ to call Emacs’ originally functionality, but in this case, ~g c c~ comments out a line(s), and ~g c~ takes text objects and whatnot. For instance, ~g c $~ comments to the end of the line.
Dropping into Emacs state is better than pure Evil state for applications, however, [[https://github.com/emacs-evil/evil-collection][the evil-collection package]] creates a hybrid between the two, that I like.
Doom introduced me to [[https://github.com/hlissner/evil-snipe][evil-snipe]], like =f= and =t=, but with two characters, and can, when configured, search more than the current line. My issue is that [[Evil Surround]] uses the same keybindings. Since surround doesn’t work in /normal/ and /visual/ states, we’ll bind snipe only for those:
I like both [[https://github.com/emacs-evil/evil-surround][evil-surround]] and Henrik's [[https://github.com/hlissner/evil-snipe][evil-snipe]], but they both start with ~s~, and conflict, and getting them to work together means I have to remember when does ~s~ call sniper and when it calls surround. As an original Emacs person, I am not bound by that key history, but I do need them consistent, so I’m choosing the ~s~ to be /surround/.
The next interface is [[help:completion-at-point][completion-at-point]] (which I set to ~M-TAB~). This code (from mini-buffer) doubles with the other [[Vertico][completing processes]] (like [[help:completing-read][completing-read]]) and presents choices based on a series of functions (see [[https://with-emacs.com/posts/tutorials/customize-completion-at-point/][this essay]] for details).
What would be nice is that if =complete= doesn't have a match, =completion-at-point= would be called. Until then, we need to bind a key … or automatically display choices after a certain time (see below):
The [[file:ha-org.org::*Spell Checking][Flyspell package]] takes over ~M-TAB~, so let’s add another keybinding (or [[Corfu][use time-based menu option]]):
The idea of cycling through candidates sounds like a good idea, but let’s start with a number before setting this to =t=:
#+begin_src emacs-lisp
(setq completion-cycle-threshold 3)
#+end_src
In Emacs version 28, we can hide commands in ~M-x~ which do not apply to the current mode.
#+begin_src emacs-lisp
(setq read-extended-command-predicate
#'command-completion-default-include-p)
#+end_src
**** Hippie Expand
The venerable [[help:hippie-expand][hippie-expand]] function does a better job than the default, [[help:dabbrev-expand][dabbrev-expand]], so let’s swap it out (see this [[https://www.masteringemacs.org/article/text-expansion-hippie-expand][essay]] by Mickey Petersen) with its default key of ~M-/~:
Details on its job? We need to update its [[help:hippie-expand-try-functions-list][list of expanders]]. I don’t care much for [[help:try-expand-line][try-expand-line]], so that is not on the list.
#+begin_src emacs-lisp
(setq hippie-expand-try-functions-list
'(try-complete-file-name-partially ; complete filenames, start with /
try-complete-file-name
try-expand-all-abbrevs
try-expand-list ; help when function args repeated another func's args
try-expand-dabbrev
try-expand-dabbrev-all-buffers
try-expand-whole-kill ; grab text from the kill ring
try-expand-dabbrev-from-kill ; similar to above
try-complete-lisp-symbol-partially
try-complete-lisp-symbol))
#+end_src
In the shell, IDEs and other systems, the key binding is typically ~TAB~. In modes other than =org-mode=, ~TAB~ re-indents the line with [[help:indent-for-tab-command][indent-for-tab-command]], but I find that I want that feature when I’m in Evil’s =normal state= and hit the ~=~ key, so changing this sounds good. But why not /have both/?
In =org-mode=, ~TAB~ calls [[help:org-cycle][org-cycle]], a complicated function, and attaching the hippie creates more complications. So, I can’t use ~TAB~ to expand long words. Keep to ~M-/~ or something else on the Meta key?
Then I converted to [[http://company-mode.github.io/][company]], and didn’t really need to use Hippie’s built-in functionality. Now, I’m wanting to try out [[https://github.com/minad/corfu][corfu]] (see [[https://takeonrules.com/2022/01/17/switching-from-company-to-corfu-for-emacs-completion/][this essay]] for more details). This package focuses on the UI, relying on other completion facilities. Seems like a good idea, as long as it works with the [[https://github.com/joaotavora/eglot][eglot]] package.
I personally find a menu that constantly pops up as I’m typing quite annoying, and if =corfu-auto= is on, then I need a delay before it shows:
#+begin_src emacs-lisp
(use-package corfu
:straight (:files (:defaults "extensions/*.el"))
:custom
(corfu-cycle t) ; Enable cycling for `corfu-next/previous'
(corfu-auto t) ; Enable auto completion
(corfu-auto-delay 1) ; Wait a second. Good idea if corfu-auto is t
(corfu-auto-prefix 3) ; Start if we have typed four letters
(corfu-quit-no-match t) ; quit if there is no match
(corfu-echo-documentation t) ; Show documentation in the echo area
(corfu-scroll-margin 5) ; Use scroll margin
(corfu-preview-current t) ; Disable current candidate preview
(corfu-preselect-first t) ; Showing us the goods? Take it with TAB/RET
(corfu-on-exact-match 'insert) ; Configure handling of exact matches
;; The Escape key, when the Corfu menu shows, goes into some sort of
;; normal movement without removing the menu. Odd behavior.
;; Let's _try_ to make it cancel:
:general
(:keymaps 'corfu-map
:states 'insert
"s-SPC" #'corfu-insert-separator
"C-n" #'corfu-next
"C-p" #'corfu-previous
"<escape>" #'corfu-quit
"<return>" #'corfu-insert
"M-d" #'corfu-show-documentation
"M-l" #'corfu-show-location)
:init
(global-corfu-mode))
#+end_src
*Note:* The [[elisp:(describe-variable 'corfu-separator)][corfu-separator]] variable, defaults to the ~M-SPC~, can be used to limit the choices with two different sections of selection.
What about the locatio
With the [[https://github.com/minad/corfu/blob/main/extensions/corfu-quick.el][corfu-quick]] package, you can apply /labels/ to every section, making it easier to select something on the Corfu menu without either typing more of the section, or hitting the down arrow keys. The issue is actually loading the file that is embedded in the =extensions= directory. One approach is to call =load-file= on it:
With the [[https://github.com/minad/corfu/blob/main/extensions/corfu-history.el][corfu-history]] extension, we can sort candidates by their history position:
#+begin_src emacs-lisp
(use-package corfu-history
:after corfu
:straight (:type built-in)
:config
(corfu-history-mode))
#+end_src
For =eshell=, I don’t want completion until I ask for it, so then I need to set these variables:
#+begin_src emacs-lisp
(use-package eshell
:after corfu
:config
(defun corfu-send-shell (&rest _)
"Send completion candidate when inside comint/eshell."
More Capf backends and =completion-in-region= commands are provided by the [[https://github.com/minad/cape][Cape]] package. Among others, the package supplies a file path and a Dabbrev completion backend. Cape provides the =cape-company-to-capf= adapter to reuse Company backends in Corfu. Furthermore the function =cape-super-capf= can merge multiple Capfs, such that the candidates of multiple Capfs are displayed together at the same time.
The customization is to add =completion-at-point-functions=, used by =completion-at-point=:
The =pcomplete= system (that =eshell= uses) has some technical issues. Cape provides wrappers, which sanitize the [[help:pcomplete][pcomplete]] function. Until these bugs are fixed upstream, these two advices addresses the problem.
#+begin_src emacs-lisp
;; Silence the pcomplete capf, no errors or messages!
While I grew up on =Control S=, I am liking the /mental model/ associated with the [[https://github.com/abo-abo/avy][avy project]] that allows a /jump/ among matches across all visible windows. I use the ~F18~ key on my keyboard that should be easy to use, but ~g o~ seems obvious.
I originally appreciated [[https://github.com/abo-abo/ace-link][ace-link]] to work with hyperlinks on Org, EWW and Info pages, but the [[https://github.com/noctuid/link-hint.el][link-hint]] project works with more types of links:
Magnar Sveen's [[https://github.com/magnars/expand-region.el][expand-region]] project allows me to hit ~v~ in =visual= mode, and have the selection grow by syntactical units.
While editing any file on disk is easy enough, I like the mental context switch associated with a full-screen window frame showing all the buffers of a /project task/ (often a direct link to a repository project, but not always).
While I don't /need/ all the features that [[https://github.com/bbatsov/projectile][projectile]] provides, it has all the features I do need, and is easy enough to install. I am referring to the fact that I /could/ use the built-in =project.el= system (see [[https://cestlaz.github.io/post/using-emacs-79-project/][this essay]] for details on what I mean as an alternative).
A /workspace/ (at least to me) requires a quick jump to a collection of buffer windows organized around a project or task. For this, I'm basing my work on the [[https://github.com/nex3/perspective-el][perspective.el]] project.
I build a Hydra to dynamically list the current projects as well as select the project.
To do this, we need a way to generate a string of the perspectives in alphabetical order:
Let's describe a list of startup project workspaces. This way, I don't need the clutter of the recent state, but also get back to a state of mental normality.
Granted, this list is essentially a list of projects that I'm currently developing, so I expect this to change often.
Often, but not always, I want a perspective based on an actual Git repository, e.g. a project. Projectile keeps state of a "project" based on the current file loaded, so we /combine/ the two projects by first choosing from a list of /known projects/ and then creating a perspective based on the name. To pin the perspective to a project, we load a file from it, e.g. Like a README or something.
The [[https://scripter.co/using-git-delta-with-magit][magit-delta]] project uses [[https://github.com/dandavison/delta][git-delta]] for colorized diffs.
#+begin_src emacs-lisp
(use-package magit-delta
:ensure t
:hook (magit-mode . magit-delta-mode))
#+end_src
I also need to append the following to my [[file:~/.gitconfig][~/.gitconfig]] file:
I’m stealing the code for this section from [[https://tsdh.org/posts/2022-08-01-difftastic-diffing-with-magit.html][this essay]] by Tassilo Horn, and in fact, I’m going to lift a lot of his explanation too, as I may need to remind myself how this works. The idea is based on using Wilfred’s excellent [[https://github.com/Wilfred/difftastic][difftastic]] tool to do a structural/syntax comparison of code changes in git. To begin, install the binary:
#+begin_src sh
brew install difftastic # and the equivalent on Linux
#+end_src
Next, we can do this, to use this as a diff tool for everything.
#+begin_src emacs-lisp
(setenv "GIT_EXTERNAL_DIFF" "difft")
#+end_src
But perhaps integrating it into Magit and selectively calling it (as it is slow). Tassilo suggests making the call to =difft= optional by first creating a helper function to set the =GIT_EXTERNAL_DIFF= to =difft=:
The crucial parts of this helper function are that we "wash" the result using =ansi-color-apply-on-region= so that the function can transform the difftastic highlighting using shell escape codes to Emacs faces. Also, note the need to possibly change the width, as difftastic makes a side-by-side comparison.
The functions below depend on [[help:magit-thing-at-point][magit-thing-at-point]], and this depends on the [[https://sr.ht/~pkal/compat/][compat]] library, so let’s grab that stuff:
Next, let's define our first command basically doing a =git show= for some revision which defaults to the commit or branch at point or queries the user if there's none.
And here the second command which basically does a =git diff=. It tries to guess what one wants to diff, e.g., when point is on the Staged changes section in a magit buffer, it will run =git diff --cached= to show a diff of all staged changes. If it can not guess the context, it'll query the user for a range or commit for diffing.
What's left is integrating the new show and diff commands in Magit. For that purpose, Tasillo created a new transient prefix for all personal commands. Intriguing, but I have a hack that I can use on a leader:
Using the [[https://github.com/emacsmirror/gist][gist package]] to write code snippets on [[https://gist.github.com/][Github]] seems like it can be useful, but I'm not sure how often.
Every /so often/, pop over to the following URLs and generate a new token where the *Note* is =forge=, and then copy that into the [[file:~/.authinfo.gpg][~/.authinfo.gpg]]:
Pushing directly to the upstream branch is /bad form/, as one should create a pull request, etc. To prevent an accidental push, we /double-check/ first:
Browsing on a work laptop is a bit different. According to [[http://ergoemacs.org/emacs/emacs_set_default_browser.html][this page]], I can set a /default browser/ for different URLs, which is great, as I can launch my browser for personal browsing, or another browser for work access, or even EWW. To make this clear, I'm using the abstraction associated with [[https://github.com/rolandwalker/osx-browse][osx-browse]]:
I primarily use [[https://github.com/jaypei/emacs-neotree][Neotree]] when I am screen-sharing my Emacs session with collegues as it shows a /project/ like an IDE.
Let's try [[https://github.com/bastibe/annotate.el][annotate-mode]], which allows you to drop "notes" and then move to them (yes, serious overlap with bookmarks, which we will return to).
Making demonstrations /within/ Emacs with my [[https://github.com/howardabrams/demo-it][demo-it]] project. While on MELPA, I want to use my own cloned version to make sure I can keep debugging it.