Org: Improve inline src block fontification

This fixes the significant issue where a unpaired bracket would cause
the rest of the buffer to be parsed, ignoring `limit'. Not nice.

I also now use inline src blocks a lot more in my config.
This commit is contained in:
TEC 2021-03-28 18:29:18 +08:00
parent f2c4765065
commit 27b937e97f
Signed by: tec
GPG Key ID: 779591AFDB81F06C
1 changed files with 88 additions and 62 deletions

View File

@ -5,9 +5,10 @@
#+macro: timezone (eval (substring (shell-command-to-string "date +%Z") 0 -1))
#+macro: git-rev (eval (format "@@html:<a href=\"https://github.com/tecosaur/emacs-config/commit/%1$s\" style=\"text-decoration: none\"><code style=\"padding: 0; color: var(--text-light); font-size: inherit; opacity: 0.7\">%1$s</code></a>@@@@latex:\\href{https://github.com/tecosaur/emacs-config/commit/%1$s}{\\normalsize\\texttt{%1$s}}@@" (substring (shell-command-to-string "git rev-parse --short HEAD") 0 -1)))
#+html_head: <link rel='shortcut icon' type='image/png' href='https://www.gnu.org/software/emacs/favicon.png'>
#+property: header-args:emacs-lisp :tangle yes :cache yes :results silent :comments link
#+property: header-args:emacs-lisp :tangle yes :comments link
#+property: header-args:elisp :exports code
#+property: header-args:shell :tangle "setup.sh"
#+property: header-args :tangle no :results silent
#+property: header-args :tangle no :results silent :eval no-export
#+options: coverpage:yes
#+startup: fold
@ -136,7 +137,7 @@ digraph {
#+caption: Some sample workflow integrations that can be used within Emacs
#+attr_html: :class invertible :alt Graph of possible Emacs task integrations :style max-width:min(24em,100%)
#+attr_latex: :width 0.5\linewidth
#+attr_latex: :width 0.55\linewidth
[[file:misc/emacs-platform.svg]]
*** Some notably unique features
@ -243,10 +244,11 @@ wonder why things aren't working), here's a list of sections which rely on
external setup (i.e. outside of this config).
+ dictionary :: I've downloaded a custom [[http://app.aspell.com/create][SCOWL]] dictionary, which I use in [[*Ispell][ispell]].
If this causes issues, just delete the ~(setq ispell-dictionary ...)~ bit.
If this causes issues, just delete the src_elisp{(setq ispell-dictionary ...)}
bit.
+ uni-units file :: I've got a file in =~/.org/.uni-units= which I use in ~org-capture~
If this causes issues, just remove the reference to that file in [[*Capture][Capture]] and
instances of ~unit-prompt~ used in ~(doct ...)~
instances of ~unit-prompt~ used in src_elisp{(doct ...)}.
Oh, did I mention that I started this config when I didn't know any =elisp=, and
this whole thing is a hack job? If you can suggest any improvements, please do
@ -260,7 +262,8 @@ few extras.
+ A [[https://www.tug.org/texlive/][LaTeX Compiler]] is required for the mathematics rendering performed in [[#org][Org]],
and by [[*CalcTeX][CalcTeX]].
+ I use the [[https://overpassfont.org/][Overpass]] font as a go-to sans serif.
It's used as my ~doom-variable-pitch-font~ and in the graph generated by [[*Roam][Roam]].
It's used as my ~doom-variable-pitch-font~ and in the graph generated
by [[*Roam][Roam]].
I have chosen it because it possesses a few characteristics I consider
desirable, namely:
- A clean, and legible style. Highway-style fonts tend to be designed to be
@ -321,8 +324,8 @@ Apparently this is used by ~GPG~, and all sorts of other things.
Speaking of ~GPG~, I want to use =~/.authsource.gpg= instead of the default in
=~/.emacs.d=. Why? Because my home directory is already cluttered, so this won't
make a difference, and I don't want to accidentaly purge this file (I have done
~rm -rf~/.emac.d~ before). I also want to cache as much as possible, as my home
machine is pretty safe, and my laptop is shutdown a lot.
src_shell{rm -rf~/.emac.d~ before}. I also want to cache as much as possible, as
my home machine is pretty safe, and my laptop is shutdown a lot.
#+begin_src emacs-lisp
(setq auth-sources '("~/.authinfo.gpg")
auth-source-cache-expiry nil) ; default is 7200 (2h)
@ -330,7 +333,9 @@ machine is pretty safe, and my laptop is shutdown a lot.
** Better defaults
*** Simple settings
Browsing the web and seeing [[https://github.com/angrybacon/dotemacs/blob/master/dotemacs.org#use-better-defaults][angrybacon/dotemacs]] and comparing with the values
shown by =SPC h v= and selecting what I thought looks good, I've ended up adding the following:
shown by =SPC h v= and selecting what I thought looks good, I've ended up adding
the following:
#+begin_src emacs-lisp
(setq-default
delete-by-moving-to-trash t ; Delete files to trash
@ -353,8 +358,8 @@ shown by =SPC h v= and selecting what I thought looks good, I've ended up adding
#+end_src
*** Frame sizing
It's nice to control the size of new frames, when launching Emacs that can be
done with ~emacs -geometry 160x48~. After the font size adjustment during
initialisation this works out to be ~102x31~.
done with src_shell{emacs -geometry 160x48}. After the font size adjustment
during initialisation this works out to be ~102x31~.
Thanks to hotkeys, it's easy for me to expand a frame to half/full-screen, so it
makes sense to be conservative with the sizing of new frames.
@ -378,17 +383,20 @@ setting, and load it if it exists.
*** Windows
I find it rather handy to be asked which buffer I want to see after splitting
the window. Let's make that happen.
First, we'll enter the new window
#+begin_src emacs-lisp
(setq evil-vsplit-window-right t
evil-split-window-below t)
#+end_src
Then, we'll pull up ~ivy~
#+begin_src emacs-lisp
(defadvice! prompt-for-buffer (&rest _)
:after '(evil-window-split evil-window-vsplit)
(+ivy/switch-buffer))
#+end_src
Oh, and previews are nice
#+begin_src emacs-lisp
(setq +ivy-buffer-preview t)
@ -481,8 +489,9 @@ have flags applied to tweak their behaviour.
As you may have noticed by this point, this is a [[https://en.wikipedia.org/wiki/Literate_programming][literate]] configuration. Doom
has good support for this which we access though the ~literate~ module.
While we're in the ~:config~ section, we'll use Dooms nicer defaults, along with
the bindings and smartparens behaviour (the flags aren't documented, but they exist).
While we're in the src_elisp{:config} section, we'll use Dooms nicer defaults,
along with the bindings and smartparens behaviour (the flags aren't documented,
but they exist).
#+name: doom-config
#+begin_src emacs-lisp
literate
@ -829,8 +838,8 @@ that Org doesn't try to confirm that I want to allow evaluation (I do!).
Thankfully Doom supports =$DOOMDIR/cli.el= file which is sourced every time a CLI
command is run, so we can just enable evaluation by setting
~org-confirm-babel-evaluate~ to ~nil~ there.
While we're at it, we should silence ~org-babel-execute-src-block~ to avoid
polluting the output.
While we're at it, we should silence ~org-babel-execute-src-block~ to
avoid polluting the output.
#+begin_src emacs-lisp :tangle cli.el :comments none
;;; cli.el -*- lexical-binding: t; -*-
@ -1267,7 +1276,7 @@ This is where you install packages, by declaring them with the ~package!~
macro, then running ~doom refresh~ on the command line. You'll need to
restart Emacs for your changes to take effect! Or at least, run =M-x doom/reload=.
WARNING: Don't disable core packages listed in ~~/.emacs.d/core/packages.el~.
*Warning*: Don't disable core packages listed in =~/.emacs.d/core/packages.el=.
Doom requires these, and disabling them may have terrible side effects.
*** Packages in MELPA/ELPA/emacsmirror
@ -1874,7 +1883,7 @@ let's just switch to an ~o~, which still looks decent but doesn't cause any
issues.
A 'active-bar' is nice, so let's have one of those. If we have it ~under~ needs us to
turn on ~x-underline-at-decent~ though. For some reason this didn't seem to work
inside the ~(after! ... )~ block ¯\_(ツ)_/¯.
inside the src_elisp{(after! ... )} block ¯\_(ツ)_/¯.
Then let's change the font to a sans serif, but the default one doesn't fit too
well somehow, so let's switch to 'P22 Underground Book'; it looks much nicer.
#+begin_src emacs-lisp
@ -2100,8 +2109,8 @@ nearby (also means that if I change the 'main' dictionary I keep my addition).
#+end_src
** Ivy
While in an ivy mini-buffer =C-o= shows a list of all possible actions one may take.
By default this is ~#'ivy-read-action-by-key~ however a better interface to this
is using Hydra.
By default this is src_elisp{#'ivy-read-action-by-key} however a better
interface to this is using Hydra.
#+begin_src emacs-lisp
(setq ivy-read-action-function #'ivy-hydra-read-action)
#+end_src
@ -2287,7 +2296,8 @@ Let's make this popup a bit faster
#+begin_src emacs-lisp
(setq which-key-idle-delay 0.5) ;; I need the help, I really do
#+end_src
I also think that having =evil-= appear in so many popups is a bit too verbose, let's change that, and do a few other similar tweaks while we're at it.
I also think that having =evil-= appear in so many popups is a bit too verbose,
let's change that, and do a few other similar tweaks while we're at it.
#+begin_src emacs-lisp
(setq which-key-allow-multiple-replacements t)
(after! which-key
@ -2867,7 +2877,8 @@ omitting the =#= in channel names we can have a list of channels comma-separated
accounts))))
#+end_src
We'll just call ~(register-irc-auths)~ on a hook when we start Circe up.
We'll just call src_elisp{(register-irc-auths)} on a hook when we start Circe
up.
Now we're ready to go, let's actually wire-up Circe, with one or two
configuration tweaks.
@ -2907,7 +2918,7 @@ configuration tweaks.
#+end_src
*** Org-style emphasis
Let's do our *bold*, /italic/, and _underline_ in org-syntax, using IRC control characters
Let's do our *bold*, /italic/, and _underline_ in org-syntax, using IRC control characters.
#+name: org-emph-to-irc
#+begin_src emacs-lisp
(defun lui-org-to-irc ()
@ -3469,8 +3480,8 @@ When run without flags this will perform the following actions
- ~Patterns~
+ Call ~mbsync --list ACCOUNT~, and filter results according to ~Patterns~
+ Construct a imapnotify config for each account, with the following hooks
- onNewMail :: ~mbsync --pull ACCOUNT:MAILBOX~
- onNewMailPost :: ~if mu index --lazy-check; then test -f /tmp/mu_reindex_now && rm /tmp/mu_reindex_now; else touch /tmp/mu_reindex_now; fi~
- onNewMail :: src_shell{mbsync --pull ACCOUNT:MAILBOX}
- onNewMailPost :: src_shell{if mu index --lazy-check; then test -f /tmp/mu_reindex_now && rm /tmp/mu_reindex_now; else touch /tmp/mu_reindex_now; fi}
+ Compare accounts list to previous accounts, enable/disable the relevant
systemd services, called with the ~--now~ flag (start/stop services as well)
@ -4214,7 +4225,7 @@ figure.png╶─╧─▶ PROJECT.ORG ▶───╴filters╶───╧─
:end:
Finally, because this section is fairly expensive to initialise, we'll wrap it
in an ~(after! ...)~ block.
in an src_elisp{(after! ...)} block.
#+begin_src emacs-lisp :noweb no-export :tangle yes :noweb-ref nil
(after! org
<<org-conf>>
@ -4340,7 +4351,8 @@ Entries of the form (subject . id)."
org-export-with-sub-superscripts '{} ; don't treat lone _ / ^ as sub/superscripts, require _{} / ^{}
org-re-reveal-root "https://cdn.jsdelivr.net/npm/reveal.js")
#+end_src
I also like the ~:comments~ header-argument, so let's make that a default.
I also like the src_elisp{:comments} header-argument, so let's make that a
default.
#+begin_src emacs-lisp
(setq org-babel-default-header-args
'((:session . "none")
@ -5895,11 +5907,19 @@ we can apply language-appropriate syntax highlighting. Then, continuing on to
the value-surrounding constructs hidden by mimicking the behaviour of
~prettify-symbols-mode~.
#+begin_warning
This currently only highlights a single inline src block per line.
I have no idea why it stops, but I'd rather it didn't.
If you have any idea what's going on or how to fix this /please/ get in touch.
#+end_warning
#+begin_src emacs-lisp
(defvar org-prettify-inline-results t
"Whether to use (ab)use prettify-symbols-mode on {{{results(...)}}}.")
(defvar org-fontify-inline-src-blocks-max-length 200
"Maximum content length of an inline src block that will be fontified.")
(defun org-fontify-inline-src-blocks (limit)
"Try to apply `org-fontify-inline-src-blocks-1'."
(condition-case nil
@ -5909,7 +5929,7 @@ the value-surrounding constructs hidden by mimicking the behaviour of
(line-number-at-pos)))))
(defun org-fontify-inline-src-blocks-1 (limit)
"Fontify inline src_LANG blocks, from `point' up to LIMIT."
"Fontify inline src_LANG blocks, from `point' up to LIMIT."
(let ((case-fold-search t))
(when (re-search-forward "\\_<src_\\([^ \t\n[{]+\\)[{[]?" limit t) ; stolen from `org-element-inline-src-block-parser'
(let ((beg (match-beginning 0))
@ -5921,19 +5941,24 @@ the value-surrounding constructs hidden by mimicking the behaviour of
(font-lock-append-text-property beg lang-beg 'face 'shadow)
(font-lock-append-text-property beg lang-end 'face 'org-block)
(setq pt (goto-char lang-end))
(when (org-element--parse-paired-brackets ?\[)
(remove-text-properties pt (point) '(face nil))
(font-lock-append-text-property pt (point) 'face 'org-block)
(setq pt (point)))
(when (org-element--parse-paired-brackets ?\{)
(remove-text-properties pt (point) '(face nil))
(font-lock-append-text-property pt (1+ pt) 'face '(org-block shadow))
(unless (= (1+ pt) (1- (point)))
(if org-src-fontify-natively
(org-src-font-lock-fontify-block (buffer-substring-no-properties lang-beg lang-end) (1+ pt) (1- (point)))
(font-lock-append-text-property (1+ pt) (1- (point)) 'face 'org-block)))
(font-lock-append-text-property (1- (point)) (point) 'face '(org-block shadow))
(setq pt (point)))
;; `org-element--parse-paired-brackets' doesn't take a limit, so to
;; prevent it searching the entire rest of the buffer we temporarily
;; narrow the active region.
(save-restriction
(narrow-to-region beg (min (point-max) limit (+ lang-end org-fontify-inline-src-blocks-max-length)))
(when (ignore-errors (org-element--parse-paired-brackets ?\[))
(remove-text-properties pt (point) '(face nil))
(font-lock-append-text-property pt (point) 'face 'org-block)
(setq pt (point)))
(when (ignore-errors (org-element--parse-paired-brackets ?\{))
(remove-text-properties pt (point) '(face nil))
(font-lock-append-text-property pt (1+ pt) 'face '(org-block shadow))
(unless (= (1+ pt) (1- (point)))
(if org-src-fontify-natively
(org-src-font-lock-fontify-block (buffer-substring-no-properties lang-beg lang-end) (1+ pt) (1- (point)))
(font-lock-append-text-property (1+ pt) (1- (point)) 'face 'org-block)))
(font-lock-append-text-property (1- (point)) (point) 'face '(org-block shadow))
(setq pt (point))))
(when (and org-prettify-inline-results (re-search-forward "\\= {{{results(" limit t))
(font-lock-append-text-property pt (1+ pt) 'face 'org-block)
(goto-char pt))))
@ -6488,8 +6513,8 @@ the vast majority of the change in behaviour comes from switch statements in:
#+end_src
There are quite a few instances where I want to modify variables defined in
=ox-html=, so we'll wrap the contents of this section in an ~(after! ox-html ...)~
block.
=ox-html=, so we'll wrap the contents of this section in a
src_elisp{(after! ox-html ...)} block.
#+begin_src emacs-lisp :noweb no-export :noweb-ref org-conf
(after! ox-html
<<ox-html-conf>>
@ -6959,8 +6984,8 @@ org provides.
**** Make verbatim different to code
Since we have =verbatim= and ~code~, let's make use of the difference.
We can use ~code~ exclusively for code snippets and commands like: "calling ~(message
"Hello")~ in batch-mode Emacs prints to stdout like ~echo~".
We can use ~code~ exclusively for code snippets and commands like: "calling
src_elisp{(message "Hello")} in batch-mode Emacs prints to stdout like ~echo~".
Then we can use =verbatim= for miscellaneous 'other monospace' like keyboard
shortcuts: "either =C-c C-c= or =C-g= is likely the most useful keybinding in Emacs",
or file names: "I keep my configuration in =~/.config/doom/=", among other things.
@ -7552,12 +7577,12 @@ First we want to process our fancy keywords in ~org-latex-feature-implementation
to produce an /expanded/ list of features. We'll do that by performing the
following steps.
+ The dependencies for each listed feature are added to feature list
(=:requires=).
+ The =:when= conditions of each feature, and available features with =:eager t=,
are evaluated, and added/removed accordingly
+ Any features present in a =:prevents= value are removed
(src_elisp{:requires}).
+ The src_elisp{:when} conditions of each feature, and available features with
src_elisp{:eager t}, are evaluated, and added/removed accordingly
+ Any features present in a src_elisp{:prevents} value are removed
+ The feature list is scrubbed of duplicates
+ The feature list is sorted by =:order= (ascending)
+ The feature list is sorted by src_elisp{:order} (ascending)
#+begin_src emacs-lisp
(defun org-latex-expand-features (features)
@ -7665,10 +7690,11 @@ If \"nil\" no custom fonts will ever be used.")
Then a function is needed to generate a LaTeX snippet which applies the fontset. It
would be nice if this could be done for individual styles and use different
styles as the main document font. If the individual typefaces for a fontset are
defined individually as (=:serif=, =:sans=, =:mono=, and =:maths=). I can use those to
generate LaTeX for subsets of the full fontset. Then, if I don't let any fontset
names have =-= in them, I can use =-sans= and =-mono= as suffixes that specify the
document font to use.
defined individually as
src_elisp{:serif}, src_elisp{:sans}, src_elisp{:mono}, and src_elisp{:maths}.
I can use those to generate LaTeX for subsets of the full fontset. Then, if I
don't let any fontset names have =-= in them, I can use =-sans= and =-mono= as
suffixes that specify the document font to use.
#+begin_src emacs-lisp
(defun org-latex-fontset-entry ()
@ -8113,13 +8139,13 @@ better) we add bit to the preamble:
At some point it would be nice to make the box colours easily customisable. At
the moment it's fairly easy to change the syntax highlighting colours with
src_emacs-lisp[:eval no :exports code]{(setq engrave-faces-preset-styles
(engrave-faces-generate-preset))}, but perhaps a toggle which specifies whether
to use the default values, the current theme, or any named theme could be a good
idea. It should also possible to set the box background dynamically to match.
The named theme could work by looking for a style definition with a certain name
in a cache dir, and then switching to that theme and producing (and saving) the
style definition if it doesn't exist.
src_elisp{(setq engrave-faces-preset-styles (engrave-faces-generate-preset))},
but perhaps a toggle which specifies whether to use the default values, the
current theme, or any named theme could be a good idea. It should also possible
to set the box background dynamically to match. The named theme could work by
looking for a style definition with a certain name in a cache dir, and then
switching to that theme and producing (and saving) the style definition if it
doesn't exist.
Now let's have the example block be styled similarly.
#+begin_src emacs-lisp
@ -8253,10 +8279,10 @@ fairly easily.
Now we just need to hook this handy function into Org's export.
We can't use standard string-replacement as we rely on the buffer modifications
enacted by =(emojify-mode)=.
enacted by src_elisp{(emojify-mode)}.
As I have not yet implemented a nice way of sharing feature detection
information outside of =(org-latex-generate-features-preamble)=, we'll
information outside of src_elisp{(org-latex-generate-features-preamble)}, we'll
use the same check before attempting to LaTeXify emojis and hope that nothing
strange happens.