350 lines
12 KiB
Org Mode
350 lines
12 KiB
Org Mode
#+title: Gists by bram85
|
|
#+PROPERTY: header-args :mkdirp yes
|
|
|
|
#+begin_src org :tangle README.org
|
|
Gists referred from [[https://emacs.ch/@bram85][@bram85@emacs.ch]].
|
|
|
|
Unfortunately gitea has no gist support and there's no mature yet lightweight gist solution suitable for self-hosting, so resorting to this poor-man's setup of sharing gists with an audience.
|
|
#+end_src
|
|
|
|
* Termux keys :termux:emacs:
|
|
:PROPERTIES:
|
|
:URL: https://emacs.ch/@bram85/109393570150138285
|
|
:END:
|
|
|
|
Put this in ~/.termux/termux.properties for a better Emacs experience inside Termux.
|
|
|
|
#+begin_src conf :tangle gists/termux-emacs-keys.conf
|
|
extra-keys = [[ \
|
|
{key: ESC, popup: {macro: "CTRL g", display: "C-g"}}, \
|
|
{key: CTRL, popup: {macro: "CTRL x", display: "C-x"}}, \
|
|
{key: ALT, popup: {macro: "ALT x", display: "M-x"}}, \
|
|
{key: TAB}, \
|
|
{key: DEL, popup: {macro: "CTRL k", display: C-k}}, \
|
|
{key: LEFT, popup: HOME}, \
|
|
{key: DOWN, popup: PGDN}, \
|
|
{key: UP, popup: PGUP}, \
|
|
{key: RIGHT, popup: END} \
|
|
]]
|
|
#+end_src
|
|
|
|
* Nesting with use-package :emacs:usepackage:
|
|
:PROPERTIES:
|
|
:URL: https://emacs.ch/@bram85/109393551314878399
|
|
:END:
|
|
|
|
#+begin_src elisp :tangle gists/use-package-nesting.el
|
|
;; Demonstrate that use-package allows for nesting configurations,
|
|
;; although it is done semantically rather than syntactically. The
|
|
;; :after keyword makes sure that the 'bar' package is only evaluated
|
|
;; after the 'foo' package was loaded.
|
|
|
|
(use-package foo)
|
|
|
|
;; only loads after foo has been loaded
|
|
(use-package bar
|
|
:after foo)
|
|
#+end_src
|
|
|
|
* Track usage of Emacs packages over time :emacs:org:orgbabel:
|
|
:PROPERTIES:
|
|
:URL: https://emacs.ch/@bram85/109403483724552863
|
|
:END:
|
|
|
|
Using the idea of evaluating code on state changes [[id:3be8333e-7a47-4251-8ee4-2cba0ec4614b][below]].
|
|
|
|
#+begin_src org :tangle gists/track-use-package-over-time.org
|
|
,* TODO Update Emacs package count
|
|
DEADLINE: <2023-01-04 Wed .+1m>
|
|
:PROPERTIES:
|
|
:LAST_REPEAT: [2022-12-04 Sun 10:56]
|
|
:ON_DONE: (org-babel-execute-subtree)
|
|
:END:
|
|
:LOGBOOK:
|
|
- State "DONE" from "TODO" [2022-11-26 Sat 07:57]
|
|
:END:
|
|
|
|
A small org file to keep track of some metric in a table, see [[https://orgmode.org/manual/Results-of-Evaluation.html][Results of Evaluation]] in the Org mode manual for more information. It's important that the function is supposed to return a list in order to record the result as a table row.
|
|
|
|
In this case, count the number of packages in my Emacs init file. It is executed automatically when the task is marked as done, using [[https://apps.bram85.nl/gitea/bram/gists/src/branch/main/gists/evaluate-code-on-task-state-change.org][this function]].
|
|
|
|
Press =C-c C-c= inside the code block to add a new entry to the table below.
|
|
|
|
,#+begin_src elisp :results table append
|
|
(with-temp-buffer
|
|
(insert-file-contents user-init-file)
|
|
(list (format-time-string "%F")
|
|
(count-matches (rx (seq "(" (? "elpaca-") "use-package" space)))))
|
|
,#+end_src
|
|
|
|
,#+RESULTS:
|
|
| 2022-11-25 | 140 |
|
|
| 2022-11-26 | 140 |
|
|
#+end_src
|
|
|
|
* vertico-repeat setup :emacs:vertico:
|
|
:PROPERTIES:
|
|
:URL: https://emacs.ch/@bram85/109408577100294769
|
|
:END:
|
|
|
|
My vertico-repeat setup.
|
|
|
|
#+begin_src elisp :tangle gists/vertico-repeat.el
|
|
(use-package vertico-repeat
|
|
:straight (vertico-repeat :host github :repo "emacs-straight/vertico" :files ("extensions/vertico-repeat.el"))
|
|
:after (vertico savehist)
|
|
:bind
|
|
("M-g r" . vertico-repeat-select)
|
|
:config
|
|
(add-to-list 'savehist-additional-variables 'vertico-repeat-history)
|
|
:hook
|
|
(minibuffer-setup . vertico-repeat-save))
|
|
#+end_src
|
|
|
|
* Evaluate code on task state changes :emacs:org:
|
|
:PROPERTIES:
|
|
:ID: 3be8333e-7a47-4251-8ee4-2cba0ec4614b
|
|
:END:
|
|
|
|
#+begin_src org :tangle gists/evaluate-code-on-task-state-change.org
|
|
The function below evaluates Lisp forms stored in properties of a task, when it changes to a certain state. The function is supposed to be added to the =org-after-todo-state-change-hook=.
|
|
|
|
The property should be named =ON_<STATE>= where =STATE= is a state defined in =org-todo-keywords=. See also the example task below (open this file in [[https://apps.bram85.nl/gitea/bram/gists/raw/branch/main/gists/evaluate-code-on-task-state-change.org][raw mode]] to see the properties).
|
|
|
|
,#+begin_src elisp
|
|
(defun my/task-state-event-handler ()
|
|
"Evaluate a Lisp form attached to the task whose state is being changed.
|
|
|
|
When this function is added to org-after-todo-state-change-hook,
|
|
it looks for a Lisp form stored in the property called ON_<STATE>
|
|
where STATE is the new state of the todo item. When the state is
|
|
cleared, ON_CLEAR will be used.
|
|
|
|
Example:
|
|
|
|
,,* TODO Example task
|
|
:PROPERTIES:
|
|
:ON_PROGRESS: (message \"Busy!\")
|
|
:ON_DONE: (message \"Done!\")
|
|
:ON_CLEAR: (message \"No state.\")
|
|
:END:"
|
|
|
|
(when-let* ((state (or org-state "CLEAR"))
|
|
(event-property-name (concat "ON_" state))
|
|
(code-string (cdr (assoc event-property-name
|
|
(org-entry-properties))))
|
|
(code (car (read-from-string code-string))))
|
|
(org-eval code)))
|
|
|
|
(add-hook 'org-after-todo-state-change-hook 'my/task-state-event-handler)
|
|
,#+end_src
|
|
|
|
,* TODO Example task
|
|
:PROPERTIES:
|
|
:ON_PROGRESS: (message "Busy!")
|
|
:ON_DONE: (message "Done!")
|
|
:ON_CLEAR: (message "No state.")
|
|
:END:
|
|
#+end_src
|
|
|
|
* Emacs commenting: do what I actually mean :emacs:
|
|
|
|
#+begin_src elisp :tangle gists/emacs-comments-do-what-i-actually-mean.el
|
|
;; Replace comment-dwim (M-;) with a modified version of
|
|
;; comment-or-uncomment-region. The modification is done by the crux
|
|
;; [1] package, which acts on a region if active otherwise on the
|
|
;; current line.
|
|
;;
|
|
;; My personal preference goes to using straight.el-powered
|
|
;; use-package forms, even for built-in modules.
|
|
;;
|
|
;; [1] https://github.com/bbatsov/crux
|
|
|
|
(use-package newcomment
|
|
:straight (:type built-in)
|
|
:bind
|
|
([remap comment-dwim] . #'comment-or-uncomment-region))
|
|
|
|
(use-package crux
|
|
:config
|
|
(crux-with-region-or-line comment-or-uncomment-region))
|
|
#+end_src
|
|
|
|
* Use xr for more readable regular expressions :emacs:
|
|
|
|
#+begin_src org :tangle gists/xr-for-readable-regular-expressions.org
|
|
If you look for the value of =org-link-any-re=, you'll see this beauty:
|
|
|
|
,#+begin_example
|
|
"\\(\\[\\[\\(\\(?:[^][\\]\\|\\\\\\(?:\\\\\\\\\\)*[][]\\|\\\\+[^][]\\)+\\)]\\(?:\\[\\([^z-a]+?\\)]\\)?]\\)\\|\\(<\\(bibtex\\|elisp\\|f\\(?:ile\\(?:\\+\\(?:\\(?:emac\\|sy\\)s\\)\\)?\\|tp\\)\\|h\\(?:elp\\|ttps?\\)\\|id\\|mai\\(?:lto\\|rix\\)\\|news\\|org-ql-search\\|shell\\):\\([^>
|
|
]*\\(?:
|
|
[ ]*[^>
|
|
][^>
|
|
]*\\)*\\)>\\)\\|\\(\\(?:\\<\\(?:\\(bibtex\\|elisp\\|f\\(?:ile\\(?:\\+\\(?:\\(?:emac\\|sy\\)s\\)\\)?\\|tp\\)\\|h\\(?:elp\\|ttps?\\)\\|id\\|mai\\(?:lto\\|rix\\)\\|news\\|org-ql-search\\|shell\\)\\):\\(\\(?:[^][
|
|
()<>]\\|(\\(?:[^][
|
|
()<>]\\|([^][
|
|
()<>]*)\\)*)\\)+\\(?:[^[:punct:]
|
|
]\\|/\\|(\\(?:[^][
|
|
()<>]\\|([^][
|
|
()<>]*)\\)*)\\)\\)\\)\\)"
|
|
,#+end_example
|
|
|
|
[[https://github.com/mattiase/xr][xr]] to the rescue:
|
|
|
|
,#+begin_src elisp
|
|
(pp-to-string (xr org-link-any-re))
|
|
,#+end_src
|
|
|
|
,#+RESULTS:
|
|
,#+begin_example
|
|
(or
|
|
(group "[["
|
|
(group
|
|
(one-or-more
|
|
(or
|
|
(not
|
|
(any "[\\]"))
|
|
(seq "\\"
|
|
(zero-or-more "\\\\")
|
|
(any "[]"))
|
|
(seq
|
|
(one-or-more "\\")
|
|
(not
|
|
(any "[]"))))))
|
|
"]"
|
|
(opt "["
|
|
(group
|
|
(+\? anything))
|
|
"]")
|
|
"]")
|
|
(group "<"
|
|
(group
|
|
(or "bibtex" "elisp"
|
|
(seq "f"
|
|
(or
|
|
(seq "ile"
|
|
(opt "+"
|
|
(or "emac" "sy")
|
|
"s"))
|
|
"tp"))
|
|
(seq "h"
|
|
(or "elp"
|
|
(seq "ttp"
|
|
(opt "s"))))
|
|
"id"
|
|
(seq "mai"
|
|
(or "lto" "rix"))
|
|
"news" "org-ql-search" "shell"))
|
|
":"
|
|
(group
|
|
(zero-or-more
|
|
(not
|
|
(any "\n>")))
|
|
(zero-or-more "\n"
|
|
(zero-or-more
|
|
(any " "))
|
|
(not
|
|
(any " \n >"))
|
|
(zero-or-more
|
|
(not
|
|
(any "\n>")))))
|
|
">")
|
|
(group bow
|
|
(group
|
|
(or "bibtex" "elisp"
|
|
(seq "f"
|
|
(or
|
|
(seq "ile"
|
|
(opt "+"
|
|
(or "emac" "sy")
|
|
"s"))
|
|
"tp"))
|
|
(seq "h"
|
|
(or "elp"
|
|
(seq "ttp"
|
|
(opt "s"))))
|
|
"id"
|
|
(seq "mai"
|
|
(or "lto" "rix"))
|
|
"news" "org-ql-search" "shell"))
|
|
":"
|
|
(group
|
|
(one-or-more
|
|
(or
|
|
(not
|
|
(any " \n ()<>[]"))
|
|
(seq "("
|
|
(zero-or-more
|
|
(or
|
|
(not
|
|
(any " \n ()<>[]"))
|
|
(seq "("
|
|
(zero-or-more
|
|
(not
|
|
(any " \n ()<>[]")))
|
|
")")))
|
|
")")))
|
|
(or
|
|
(not
|
|
(any " \n " punct))
|
|
"/"
|
|
(seq "("
|
|
(zero-or-more
|
|
(or
|
|
(not
|
|
(any " \n ()<>[]"))
|
|
(seq "("
|
|
(zero-or-more
|
|
(not
|
|
(any " \n ()<>[]")))
|
|
")")))
|
|
")")))))
|
|
,#+end_example
|
|
|
|
* Define a lambda in a let expression
|
|
|
|
#+begin_src elisp :tangle gists/let-lambda.el
|
|
;; https://stackoverflow.com/questions/36039840/elisp-bind-a-lambda-in-a-let-and-execute-it
|
|
|
|
(let ((f (lambda (s) (message s))))
|
|
;; f is a variable so should be treated as such.
|
|
(funcall f "This works.")
|
|
|
|
;; f is not a function so cannot be found if called like this.
|
|
(f "This does not work."))
|
|
#+end_src
|
|
|
|
* Meta
|
|
** License
|
|
|
|
#+begin_src org :tangle LICENSE.txt
|
|
MIT License
|
|
|
|
Copyright (c) 2022 Bram Schoenmakers
|
|
|
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
of this software and associated documentation files (the "Software"), to deal
|
|
in the Software without restriction, including without limitation the rights
|
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
copies of the Software, and to permit persons to whom the Software is
|
|
furnished to do so, subject to the following conditions:
|
|
|
|
The above copyright notice and this permission notice shall be included in all
|
|
copies or substantial portions of the Software.
|
|
|
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
SOFTWARE.
|
|
#+end_src
|
|
|
|
** COMMENT Local variables
|
|
|
|
Auto tangle this file on save.
|
|
|
|
Local variables:
|
|
eval: (add-hook 'after-save-hook #'org-babel-tangle 0 t)
|
|
End:
|