Revert "Clean out the repository" - bring back emacs-lisp

This reverts commit b673fb12c1.
This commit is contained in:
Magic_RB 2023-09-16 19:54:12 +02:00
parent 6a36890077
commit 640de3fb86
43 changed files with 2848 additions and 0 deletions

1
emacs-lisp/.gitignore vendored Normal file
View file

@ -0,0 +1 @@
*.el

18
emacs-lisp/avy.org Normal file
View file

@ -0,0 +1,18 @@
:PROPERTIES:
:ID: e93571d6-ae50-4aca-8b2f-6ada70655be3
:END:
#+title: Avy
#+filetags: emacs-load
# SPDX-FileCopyrightText: 2022 Richard Brežák <richard@brezak.sk>
#
# SPDX-License-Identifier: LGPL-3.0-or-later
#+BEGIN_QUOTE
~avy~ is a GNU Emacs package for jumping to visible text using a char-based decision tree. See also ~ace-jump-mode~ and ~vim-easymotion~ - ~avy~ uses the same idea.
#+END_QUOTE
#+BEGIN_SRC emacs-lisp
(use-package avy
:straight t)
#+END_SRC

View file

@ -0,0 +1,12 @@
:PROPERTIES:
:header-args:emacs-lisp: :comments link :results none
:ID: d4ebe1b8-db78-42af-a1d8-70060fee6c89
:END:
#+title: C++ Language Support
#+filetags: emacs-load
#+begin_src elisp
(use-package clang-format
:straight t)
#+end_src

101
emacs-lisp/corfu.org Normal file
View file

@ -0,0 +1,101 @@
:PROPERTIES:
:ID: a4eab1d7-8928-438e-9ccc-1e3a65765534
:END:
#+title: Corfu
#+filetags: emacs-load
# SPDX-FileCopyrightText: 2022 Richard Brežák <richard@brezak.sk>
#
# SPDX-License-Identifier: LGPL-3.0-or-later
#+begin_quote
Corfu enhances completion at point with a small completion popup. The current candidates are shown in a popup below or above the point. Corfu is the minimalistic completion-in-region counterpart of the Vertico minibuffer UI.
#+end_quote
#+begin_src emacs-lisp
(use-package corfu
:straight t
:custom
(corfu-separator ?\s) ;; M-SPC
:general
("C-c c" 'completion-at-point)
:init
(global-corfu-mode))
#+end_src
* Company
#+begin_src emacs-lisp :noweb yes :exports none
(use-package company
:defer t
:init
<<company-global-modes>>)
#+end_src
Disable ~company~ globally, because company enables itself...
#+name: company-init
#+begin_src emacs-lisp
(setq company-global-modes nil)
#+end_src
* LSP Mode
#+begin_src emacs-lisp :noweb yes :exports none
(use-package corfu-lsp-mode
:no-require t
:after (lsp-mode corfu)
:init
<<lsp-completion-provider>>)
#+end_src
Make ~lsp-mode~ not turn on ~company~ first thing after start, so annoying.
#+name: lsp-completion-provider
#+begin_src emacs-lisp :tangle no
(setq lsp-completion-provider :none)
#+end_src
* Cape
~cape~ provides useful ~capfs~, such as file and ispell completion, stuff that ~company~ has built-in.
#+begin_src emacs-lisp :noweb yes :exports none
(use-package cape
:straight t
:after (corfu)
:init
<<cape-hooks>>)
#+end_src
Hook ~cape~ onto both ~text-mode~ and ~prog-mode~.
#+name: cape-hooks
#+begin_src emacs-lisp :tangle no
(defun cape-setup-capf-prog ()
"Setup cape completions for prog-mode"
(cape-setup-capf))
(defun cape-setup-capf-text ()
"Setup cape completions for text-mode"
(add-hook 'completion-at-point-functions #'cape-ispell)
(cape-setup-capf))
(defun cape-setup-capf ()
"Setup cape completions"
(add-hook 'completion-at-point-functions #'cape-file)
(add-hook 'completion-at-point-functions #'cape-tex))
:hook
((prog-mode . cape-setup-capf-prog)
(text-mode . cape-setup-capf-text))
#+end_src
~lsp-mode~ completely wipes ~completion-at-point-functions~, so we need re-add ~cape~ after it removes everything.
#+begin_src emacs-lisp
(use-package cape-lsp-mode
:no-require t
:after (cape lsp-mode)
:hook
((lsp-mode . #'cape-setup-capf)))
#+end_src

63
emacs-lisp/cosult.org Normal file
View file

@ -0,0 +1,63 @@
:PROPERTIES:
:ID: db1d0122-58d6-4dec-84f6-afcb52937fc7
:END:
#+title: Consult
#+filetags: emacs-load
# SPDX-FileCopyrightText: 2022 Richard Brežák <richard@brezak.sk>
#
# SPDX-License-Identifier: LGPL-3.0-or-later
#+BEGIN_QUOTE
Consult provides practical commands based on the Emacs completion function completing-read. Completion allows you to quickly select an item from a list of candidates.
#+END_QUOTE
#+BEGIN_SRC emacs-lisp :results none
(use-package consult
:straight t
:bind (("C-x b" . consult-buffer)
("C-x 4 b" . consult-buffer-other-window)
("C-x 5 b" . consult-buffer-other-frame)
;; M-s bindings (search-map)
("M-s r" . consult-ripgrep)
("M-s f" . consult-find))
:init
(defun compat-string-width (&rest args)
(apply #'string-width args))
(setq
consult-project-root-function #'projectile-project-root
consult-ripgrep-args "rg --null --line-buffered --color=never --max-columns=1000 --path-separator / --smart-case --no-heading --line-number --hidden ."
consult-find-args "find ."))
#+END_SRC
Also enable ~fd~ support, as that ignores paths listed in .gitignore unlike ~find~..
#+begin_src emacs-lisp
(use-package consult-fd
:no-require t
:after (consult)
:init
(defvar consult--fd-command "fd")
(defun consult--fd-builder (input)
(unless consult--fd-command
(setq consult--fd-command
(if (eq 0 (call-process-shell-command "fdfind"))
"fdfind"
"fd")))
(pcase-let* ((`(,arg . ,opts) (consult--command-split input))
(`(,re . ,hl) (funcall consult--regexp-compiler
arg 'extended t)))
(when re
(list :command (append
(list consult--fd-command
"--color=never" "--full-path"
(consult--join-regexps re 'extended))
opts)
:highlight hl))))
(defun consult-fd (&optional dir initial)
(interactive "P")
(let* ((prompt-dir (consult--directory-prompt "Fd" dir))
(default-directory (cdr prompt-dir)))
(find-file (consult--find (car prompt-dir) #'consult--fd-builder initial)))))
#+end_src

25
emacs-lisp/daylies.org Normal file
View file

@ -0,0 +1,25 @@
:PROPERTIES:
:ID: f4a10ea3-a1df-42cc-b436-08d859272679
:END:
#+title: Daylies
#+filetags: emacs-load
# SPDX-FileCopyrightText: 2022 Richard Brežák <richard@brezak.sk>
#
# SPDX-License-Identifier: LGPL-3.0-or-later
Daylies, are like scratch buffers, but they are saved. So I can shove stuff in them and they are nicely kept for later reference. Kind of INBOX.
#+begin_src emacs-lisp
(defun point-scratch-to-daylies ()
(save-excursion
(with-current-buffer "*scratch*"
(org-mode)
(set-visited-file-name
(format "~/roam/daylies/%s.org"
(format-time-string "%Y-%m-%d")))
(rename-buffer "*scratch*"))))
(add-hook 'emacs-startup-hook 'point-scratch-to-daylies)
#+end_src

14
emacs-lisp/dired.org Normal file
View file

@ -0,0 +1,14 @@
:PROPERTIES:
:ID: 484fd154-6f7c-4313-8f79-7b502b7a1c56
:END:
#+title: Dired
#+filetags: emacs-load
# SPDX-FileCopyrightText: 2022 Richard Brežák <richard@brezak.sk>
#
# SPDX-License-Identifier: LGPL-3.0-or-later
Dired is inclueded with Emacs since forever, I use a wrapper called [[id:67919dd9-2aa0-4b89-8c96-0441a54e7b03][dirvish]].
#+begin_src emacs-lisp
#+end_src

15
emacs-lisp/dirvish.org Normal file
View file

@ -0,0 +1,15 @@
:PROPERTIES:
:ID: 67919dd9-2aa0-4b89-8c96-0441a54e7b03
:END:
#+title: Dirvish
#+filetags: emacs-load
# SPDX-FileCopyrightText: 2022 Richard Brežák <richard@brezak.sk>
#
# SPDX-License-Identifier: LGPL-3.0-or-later
#+begin_src emacs-lisp
(use-package dirvish
:straight t)
#+end_src

View file

@ -0,0 +1,82 @@
:PROPERTIES:
:ID: a26802fe-8bc3-458e-8f06-7cb856fef2cd
:END:
#+title: Display Settings
#+filetags: emacs-load
Adjust the font, based on the specific host.
#+begin_src emacs-lisp
(use-package isoevka-font
:no-require t
:init
(defvar magic_rb/fixed-width-font "Iosevka Term Extended"
"The font used for fixed width text.")
(defvar magic_rb/variable-pitch-font "Iosevka Aile"
"The font used for variable pitch text.")
(defun magic_rb/apply-fonts ()
(interactive)
(pcase (system-name)
("heater" (set-face-attribute 'default nil :family magic_rb/fixed-width-font :slant 'normal :height 105))
("omen" (set-face-attribute 'default nil :family magic_rb/fixed-width-font :slant 'normal :height 105)))
(set-face-attribute 'fixed-pitch nil :family magic_rb/fixed-width-font :slant 'normal :height 1.0)
(set-face-attribute 'variable-pitch nil :family magic_rb/variable-pitch-font :height 1.0))
:config
(magic_rb/apply-fonts))
#+end_src
Load Modus Vivendi, but change the background color to not-black, it's a bit less depressing and in my opinion nicer
on the eyes.
#+BEGIN_SRC emacs-lisp
(use-package modus-vivendi-semi-black
:no-require t
:init
(setq modus-vivendi-theme-override-colors-alist
'(("bg-main" . "#111519")))
:config
(load-theme 'modus-vivendi t))
#+END_SRC
Enable ~doom-modeline~, much better than the default and unlike ~powerline~ it's usable with TRAMP, so that's great.
#+BEGIN_SRC emacs-lisp
(use-package doom-modeline
:straight t
:config
(doom-modeline-mode))
#+END_SRC
Only show buffer encoding conditionally, there's no reason to have ~LF UTF-8~ down there, rather only show when the
encoding is something we don't expect, like ~CRLF~ or ~UTF-16~. Inspired by [[https://tecosaur.github.io/emacs-config/config.html#theme-modeline][tecosaur]].
#+BEGIN_SRC emacs-lisp
(use-package doom-modeline-conditional-buffer-encoding
:no-require t
:init
(defun tecosaur/doom-modeline-conditional-buffer-encoding ()
"We expect the encoding to be LF UTF-8, so only show the modeline when this is not the case"
(setq-local doom-modeline-buffer-encoding
(unless (or (eq buffer-file-coding-system 'utf-8-unix)
(eq buffer-file-coding-system 'utf-8)))))
:hook
(after-change-major-mode-hook . tecosaur/doom-modeline-conditional-buffer-encoding))
#+END_SRC
Disable GTK decorations, they're not that great looking and I don't really want to have Emacs affected by GTK themes.
#+BEGIN_SRC emacs-lisp
(if (fboundp 'tool-bar-mode) (tool-bar-mode -1))
(menu-bar-mode -1)
(scroll-bar-mode -1)
#+END_SRC
Load ~all-the-icons~, it's required used by ~treemacs~ and ~doom-modeline~. You also must run
~all-the-icons-install-fonts~ if you haven't already.
#+BEGIN_SRC emacs-lisp
(use-package all-the-icons
:straight t)
#+END_SRC

View file

@ -0,0 +1,33 @@
:PROPERTIES:
:header-args: emacs-lisp: :comments link :results none
:ID: 3ed6a2d6-c84e-439c-aca6-6978dd82bd51
:END:
#+title: El Secretario
#+filetags: emacs-load
#+begin_src emacs-lisp :noweb yes
(use-package el-secretario
:straight (el-secretario :type git :host nil :repo "https://git.sr.ht/~magic_rb/el-secretario")
:defer t
:config
(setq el-secretario-session-end-hook nil)
(setq el-secretario-session-start-hook nil))
#+end_src
#+begin_src emacs-lisp
(defun el-secretario-emacs-lisp-review ()
"Review all Org-Roam nodes tagged as 'emacs-lisp'."
(interactive)
(el-secretario-start-session
(el-secretario-files-make-source
(seq-map #'car
(org-roam-db-query
[:select [nodes:file]
:from tags
:left-join nodes
:on (= tags:node-id nodes:id)
:where (like tag (quote "%\"emacs-load\""))]))
)))
#+end_src

21
emacs-lisp/elixir.org Normal file
View file

@ -0,0 +1,21 @@
:PROPERTIES:
:ID: 9879bd30-7f42-433a-aaa4-269f5ef110fb
:END:
#+title: Elixir
#+filetags: emacs-load
# SPDX-FileCopyrightText: 2022 Richard Brežák <richard@brezak.sk>
#
# SPDX-License-Identifier: LGPL-3.0-or-later
#+BEGIN_QUOTE
Elixir is a dynamic, functional language for building scalable and maintainable applications.
#+END_QUOTE
First we need a Elixir major mode.
#+BEGIN_SRC emacs-lisp
(use-package elixir-mode
:straight t
:hook (elixir-mode-hook . lsp-deferred))
#+END_SRC

61
emacs-lisp/emacs_rofi.org Normal file
View file

@ -0,0 +1,61 @@
:PROPERTIES:
:header-args:emacs-lisp: :comments link :results none
:ID: 0d92c672-5ac7-44dc-b021-cc58544f8eea
:END:
#+title: Emacs Rofi
#+filetags: emacs-load
It is possible to make a fake rofi, from emacs ~completing-read~. This file facilitates that. First we define some LISP functions.
#+begin_src emacs-lisp
(defun completing-read-frame-popup-file (prompt file width height &rest args)
""
(with-temp-buffer
(insert-file-contents file)
(message "%s" (string-lines (buffer-string)))
(apply #'completing-read-frame-popup prompt (string-lines (substring-no-properties (buffer-string))) args)))
#+end_src
#+begin_src emacs-lisp
(defvar completing-read-frame nil)
(defun completing-read-frame-popup (prompt collection &rest args)
""
(unless completing-read-frame
(setq completing-read-frame
(make-frame `((minibuffer . only)
(name . "emacs-completing-read-float")
(unsplittable . t)
(no-other-frame . t)
(width . ,width)
(height . ,height)
(left . 0.5)
(top . 0.5))))
(make-frame-invisible completing-read-frame))
(make-frame-visible completing-read-frame)
(raise-frame completing-read-frame)
(with-selected-frame completing-read-frame
(unwind-protect
(let ((selection (apply #'completing-read prompt collection args)))
(make-frame-invisible completing-read-frame)
selection)
(make-frame-invisible completing-read-frame))))
#+end_src
Next a bash helper is needed.
#+begin_src shell
function emacs-rofi()
{
tmp=$(mktemp)
tee > $tmp
emacs -Q --batch --eval $"(progn (require 'server) (princ (format \"%s\\n\" (server-eval-at \"server\" '(completing-read-frame-popup-file \"$1\" \"$tmp\" $2 $3)))))"
rm $tmp
}
#+end_src
Which then ought to be used like so.
#+begin_src shell
echo -e "test1\ntest2\ntest3" | emacs-rofi "test"
#+end_src

78
emacs-lisp/email.org Normal file
View file

@ -0,0 +1,78 @@
:PROPERTIES:
:ID: b9c06fb0-a985-4649-8133-14eeeaa708bc
:ROAM_REFS: https://jherrlin.github.io/posts/emacs-mu4e/
:END:
#+title: Email
#+filetags: emacs-load
# SPDX-FileCopyrightText: 2022 Richard Brežák <richard@brezak.sk>
#
# SPDX-License-Identifier: LGPL-3.0-or-later
Email is a complicated beast, I decided to use *mu4e* and *mbsync*.
* smtpmail
#+BEGIN_SRC emacs-lisp :results none
(require 'smtpmail)
(with-eval-after-load 'smtpmail
(setq smtpmail-debug-info t
message-send-mail-function 'smtpmail-send-it
smtpmail-stream-type 'starttls))
#+END_SRC
* mu4e
:PROPERTIES:
:ID: 9958efaf-51b2-4cee-bf37-c363d1c56055
:END:
#+BEGIN_SRC emacs-lisp :results none
(let*
((mu-path
(file-name-directory (directory-file-name (file-name-directory (executable-find "mu")))))
(mu-load-path (concat mu-path "share/emacs/site-lisp/mu4e/")))
(add-to-list 'load-path mu-load-path))
(require 'mu4e)
(setq auth-sources '((:source "~/.password-store/.authinfo.gpg")))
(setq auth-source-debug t)
(with-eval-after-load 'mu4e
(setq mu4e-get-mail-command "usbs=$(for dev in /sys/bus/usb/devices/* ; do [ -f ${dev}/idVendor ] && [ -f ${dev}/idProduct ] && ( env cat ${dev}/idVendor | tr -d [:space:] ; printf : ; env cat ${dev}/idProduct ); done) ; yubi=0 ; for usb in $usbs ; do [ $usb = \"1050:0407\" ] && yubi=1 ; done ; [ $yubi = 1 ] && mbsync -a || exit 1"
mu4e-update-interval 300
message-kill-buffer-on-exit t)
(defun magic_rb/eval-file (file)
"Execute FILE and return the result of the last expression."
(eval
(ignore-errors
(read-from-whole-string
(with-temp-buffer
(insert-file-contents file)
(buffer-string))))))
(setq mu4e-contexts (magic_rb/eval-file "~/.emacs.d/mu4e-contexts")
;; When Emacs is loading, mu4e will ask for which context to use. Set a default.
mu4e-context-policy 'pick-first)
(add-hook 'after-init-hook (lambda () (mu4e t))))
#+END_SRC
By default, when mu4e is asking for messages (be it unread or inbox) it'll ask for related as well, which means if you have a very long thread in your emails, say 100 message long, then that thread will eat up a 100 message spots in the 500 fetched from the mailbox, that is quite annoying. Change the behavior.
#+begin_src emacs-lisp
(setq mu4e-headers-include-related nil)
#+end_src
* mu4e-alert
#+BEGIN_SRC emacs-lisp
(use-package mu4e-alert
:straight t
:after mu4e
:config
(mu4e-alert-set-default-style 'notifications)
(mu4e-alert-enable-mode-line-display)
(mu4e-alert-enable-notifications))
#+END_SRC

24
emacs-lisp/embark.org Normal file
View file

@ -0,0 +1,24 @@
:PROPERTIES:
:ID: d8339d6a-8b2f-43d8-bb08-a1b89db76b02
:END:
#+title: Embark
#+filetags: emacs-load
# SPDX-FileCopyrightText: 2022 Richard Brežák <richard@brezak.sk>
#
# SPDX-License-Identifier: LGPL-3.0-or-later
#+BEGIN_QUOTE
This package provides a sort of right-click contextual menu for Emacs, accessed through the embark-act command (which you should bind to a convenient key), offering you relevant actions to use on a target determined by the context:
#+END_QUOTE
#+BEGIN_SRC emacs-lisp
(use-package embark
:straight t
:bind
(("C-." . embark-act)
("C-;" . embark-dwim)
("C-h B" . embark-bindings))
:init
(setq embark-indicators '(embark-minimal-indicator)))
#+END_SRC

65
emacs-lisp/ement_el.org Normal file
View file

@ -0,0 +1,65 @@
:PROPERTIES:
:ID: cfb02bea-f9a2-4c7c-8971-d082feedab22
:END:
#+title: ement.el
#+filetags: emacs-load
#+begin_src emacs-lisp
(use-package password-store
:straight t)
(defun ement-connect-sentinel (process msg)
(when (memq (process-status process) '(exit signal))
(with-current-buffer " *ement-pass*"
(ement-connect
:uri-prefix "http://localhost:8008"
:password (string-trim (substring-no-properties (buffer-string)))
:user-id "@magic_rb:matrix.redalder.org")
(kill-buffer))))
(defun after-init-ement-connect ()
(set-process-sentinel (start-process "ement-pass" " *ement-pass*" "pass" "Matrix/@magic_rb:matrix.redalder.org") #'ement-connect-sentinel))
(use-package ement
:straight '(ement :type git :host github :repo "alphapapa/ement.el")
:after (password-store)
:custom
(ement-save-sessions t)
:config
(remove-hook 'ement-after-initial-sync-hook #'ement-room-list--after-initial-sync)
(add-hook 'after-init-hook #'after-init-ement-connect))
#+end_src
#+begin_src emacs-lisp
(defun ement-send-anyways ()
(interactive)
(when (ement-room-p ement-room)
(let ((ement-room- ement-room)
(ement-session- ement-session))
(save-excursion
(panctl "*panctl-temp-send-anyway*")
(vterm-insert "send-anyways " (ement-user-id (ement-session-user ement-session-)) " " (ement-room-id ement-room-))
(vterm-send-return)
(vterm-send-C-c)))))
#+end_src
Enable message composition in [[id:986ca7a5-d225-49bb-9e35-f2dffafe8aee][Org Mode]] by default.
#+begin_src emacs-lisp
(setq ement-room-send-message-filter #'ement-room-send-org-filter)
#+end_src
Define an interactive command to open [[https://github.com/matrix-org/pantalaimon][pantalaimon]] in Emacs.
#+begin_src emacs-lisp
(defun panctl (&optional name)
(interactive)
(let* ((name- (or name "panctl"))
(buffer (get-buffer name-))
(vterm-shell "panctl"))
(if buffer
(switch-to-buffer buffer)
(vterm name-)
(whitespace-mode -1))))
#+end_src

View file

@ -0,0 +1,23 @@
:PROPERTIES:
:ID: 50d451b0-eddf-4192-afc4-c505a5bb3b20
:END:
#+title: Filling and unfilling paragraphs
#+filetags: emacs-load
# SPDX-FileCopyrightText: 2022 Richard Brežák <richard@brezak.sk>
#
# SPDX-License-Identifier: LGPL-3.0-or-later
#+begin_src emacs-lisp
;;; Stefan Monnier <foo at acm.org>. It is the opposite of fill-paragraph
(defun unfill-paragraph (&optional region)
"Takes a multi-line paragraph and makes it into a single line of text."
(interactive (progn (barf-if-buffer-read-only) '(t)))
(let ((fill-column (point-max))
;; This would override `fill-column' if it's an integer.
(emacs-lisp-docstring-fill-column t))
(fill-paragraph nil region)))
;; Handy key definition
(define-key global-map "\M-Q" 'unfill-paragraph)
#+end_src

66
emacs-lisp/flycheck.org Normal file
View file

@ -0,0 +1,66 @@
:PROPERTIES:
:ID: 334a4188-93e6-4378-b22d-b0c302fc26a1
:END:
#+title: Flycheck
#+filetags: emacs-load
# SPDX-FileCopyrightText: 2022 Richard Brežák <richard@brezak.sk>
#
# SPDX-License-Identifier: LGPL-3.0-or-later
* Flycheck Posframe
Display flycheck messages in a posframe.
#+begin_src emacs-lisp :noweb yes
(use-package flycheck-posframe
:straight t
:config
(setq flycheck-posframe-position 'frame-bottom-right-corner)
<<flycheck-display-errors-delay>>
<<lsp-ui-sideline-show-diagnostics>>
:hook (flycheck-mode . flycheck-posframe-mode))
#+end_src
Flycheck calls ~flycheck-display-errors-function~ every ~flycheck-display-errors-delay~.
#+name: flycheck-display-errors-delay
#+begin_src emacs-lisp
(setq flycheck-display-errors-delay 0.1)
#+end_src
Since we get errors and such in a posframe, we don't need them in the sideline.
#+name: lsp-ui-sideline-show-diagnostics
#+begin_src emacs-lisp
(setq lsp-ui-sideline-show-diagnostics nil)
#+end_src
Since flycheck recalls ~flycheck-display-errors-function~ on every point movement, it creates this really ugly flicker and also lags a bit, so if the diagnostic message didn't change, filter out the call.
#+name: flycheck-posframe-change-filter
#+begin_src emacs-lisp
(defvar flycheck-posframe-last-error-list '())
(advice-add
'flycheck-posframe-hidehandler
:override
(lambda (info)
(if (not (equal
(flycheck-overlay-errors-at (point))
flycheck-posframe-last-error-list))
(progn
(setq flycheck-posframe-last-error-list nil)
t)
nil))
'((name . "flycheck-error-display-filter")))
(advice-add
'flycheck-posframe-show-posframe
:before-while
(lambda (diagnostic)
(let ((last-list flycheck-posframe-last-error-list))
(setq flycheck-posframe-last-error-list diagnostic)
(if (equal diagnostic last-list) nil t)))
'((name . "flycheck-error-display-filter")))
#+end_src

20
emacs-lisp/general_el.org Normal file
View file

@ -0,0 +1,20 @@
:PROPERTIES:
:ID: 1c6981a5-4371-4657-b4ea-435497a80010
:END:
#+title: general.el
#+filetags: emacs-load
# SPDX-FileCopyrightText: 2022 Richard Brežák <richard@brezak.sk>
#
# SPDX-License-Identifier: LGPL-3.0-or-later
#+BEGIN_QUOTE
~general.el~ provides a more convenient method for binding keys in emacs (for both evil and non-evil users). Like
use-package, which provides a convenient, unified interface for managing packages, general.el is intended to provide a
convenient, unified interface for key definitions.
#+END_QUOTE
#+BEGIN_SRC emacs-lisp
(use-package general
:straight t)
#+END_SRC

16
emacs-lisp/go.org Normal file
View file

@ -0,0 +1,16 @@
:PROPERTIES:
:ID: efc50bb2-7197-4225-b4d2-66aed96a5104
:END:
#+title: Go
#+filetags: emacs-load
# SPDX-FileCopyrightText: 2022 Richard Brežák <richard@brezak.sk>
#
# SPDX-License-Identifier: LGPL-3.0-or-later
Go is a horrible language, but for some reason all the DevOps things are written in it.
#+begin_src emacs-lisp
(use-package go-mode
:straight t)
#+end_src

View file

@ -0,0 +1,78 @@
:PROPERTIES:
:ID: 22a6cb0e-5466-4edf-b0da-a8b76d879cf9
:END:
#+title: Keybindings
#+filetags: emacs-load
# SPDX-FileCopyrightText: 2022 Richard Brežák <richard@brezak.sk>
#
# SPDX-License-Identifier: LGPL-3.0-or-later
This file contains all keybindings of my Emacs configuration. I chose to put them all into one file for easy reference and also cross package consistency is easier to ensure when you have everything on one screen.
First we need to define a new minor mode.
#+begin_src emacs-lisp
(define-minor-mode magic_rb/userbind-mode
"Minor mode for user keybindings of Magic_RB."
:lighter " userbind."
:global t
:keymap (make-sparse-keymap))
#+end_src
Then we hook our minor mode on ~meow-mode-hook~, but only after ~meow-mode~ is loaded.
#+begin_src emacs-lisp
(add-hook 'after-init-hook 'magic_rb/userbind-mode)
#+end_src
#+begin_src emacs-lisp
(general-def
:keymaps '(magic_rb/userbind-mode-map)
:prefix "C-c"
"o f" 'org-roam-node-find
"o i" 'org-roam-node-insert
"o t" 'org-roam-tag-add
"o T" 'org-roam-tag-remove
"o r" 'org-roam-ref-add
"o R" 'org-roam-ref-remove
"o c" 'org-roam-capture
"o b" 'org-roam-buffer-toggle
"o a" 'org-agenda
"j f" 'consult-fd
"j r" 'consult-ripgrep
"j l" 'consult-line
"j b" 'consult-project-buffer
"p v" 'projectile-run-vterm
"p m" 'projectile-vc
"p s" 'projectile-switch-project
"r c" 'popper-cycle
"r p" 'popper-toggle-latest
"r t" 'popper-toggle-type
"w t" 'windmove-left
"w r" 'windmove-up
"w n" 'windmove-down
"w s" 'windmove-right
"w a" 'ace-window
"b i" 'indent-region
"b c" 'comment-dwim
"l l" 'lsp
"l r" 'lsp-workspace-restart
"l e" 'lsp-execute-code-action
"e l" 'ement-list-rooms
"e v" 'ement-view-room
"M-c" 'tempel-insert
:keymaps '(special-mode-map)
:prefix ""
"q" 'nil
"k" 'quit-window)
#+end_src

142
emacs-lisp/lsp.org Normal file
View file

@ -0,0 +1,142 @@
:PROPERTIES:
:ID: cc668372-8d95-461b-a7c6-3e2b51de3f40
:END:
#+title: LSP
#+filetags: emacs-load
# SPDX-FileCopyrightText: 2022 Richard Brežák <richard@brezak.sk>
#
# SPDX-License-Identifier: LGPL-3.0-or-later
Disable server downloading suggestions, and other features.
#+begin_src emacs-lisp
(setq lsp-enable-suggest-server-download nil
lsp-enable-snippet nil
lsp-enable-dap-auto-configure nil
lsp-enable-on-type-formatting nil)
#+end_src
* Python
Using the Microsoft language server as it's the best afaik. It's weird because it doesn't lookup the path to itself via PATH but has to be statically set.
#+BEGIN_SRC emacs-lisp
(defun magic_rb/locate-python-executable-lsp-deffered ()
"Locates the python executable available to the current buffer and only then calls `lsp-deferred'."
(lambda ()
(require 'lsp-python-ms)
(envrc-mode)
(setq-local lsp-python-ms-executable (executable-find "python-language-server"))
(lsp-deferred)))
(use-package lsp-python-ms
:straight t
:after (lsp-mode)
:hook (python-mode . magic_rb/locate-python-executable-lsp-deffered)
:config
(defvar-local lsp-python-ms-executable ""))
#+END_SRC
* C/C++
This just requires hooking lsp onto ~c-mode~ and ~c++-mode~.
#+BEGIN_SRC emacs-lisp
(use-package lsp-c++-c
:no-require t
:after (lsp-mode)
:hook ((c-mode-hook c++-mode-hook) . lsp-deferred))
#+END_SRC
* Haskell
Enable ~haskell-mode~, and ~lsp-haskell~
#+BEGIN_SRC emacs-lisp
(use-package haskell-mode
:straight t
:hook
(((haskell-mode haskell-literate-mode) . interactive-haskell-mode)
((heskell-mode haskell-literate-mode) . haskell-indentation-mode))
:config
(setq lsp-haskell-plugin-ghcide-type-lenses-global-on nil
lsp-haskell-plugin-import-lens-code-lens-on nil))
(use-package lsp-haskell
:straight t
:after (haskell-mode lsp-mode)
:hook ((haskell-mode haskell-literate-mode) . lsp-deferred))
#+END_SRC
Disable the ~haskell-stack-ghc~ flycheck checker, it's not used when lsp starts, but it does get loaded just before it. Loading and unloading it is slow and causes Emacs to freeze for a few seconds, so just disable it.
#+BEGIN_SRC emacs-lisp
(with-eval-after-load "flycheck"
(add-to-list 'flycheck-disabled-checkers 'haskell-stack-ghc))
#+END_SRC
* Javascript
Enable ~rjsx-mode~ instead of ~javascript-mode~ or ~js2-mode~ as it properly handles inline HTML.
#+BEGIN_SRC emacs-lisp
(use-package rjsx-mode
:straight t
:config
:mode ("\\.js\\'" . rjsx-mode)
:mode ("\\.jsx\\'" . rjsx-mode)
:hook (rjsx-mode . lsp-deferred)
:init
;; Originally this function exits with a call to `error`, which causes the simple "PATH lookup"
;; scheme to not be tried
(cl-defun lsp--npm-dependency-path (&key package path &allow-other-keys)
"Return npm dependency PATH for PACKAGE."
(let ((path (executable-find
(f-join lsp-server-install-dir "npm" package
(cond ((eq system-type 'windows-nt) "")
(t "bin"))
path))))
(unless (and path (f-exists? path))
nil)
path)))
#+END_SRC
* Typescript
Enable ~typescript-mode~ for =.ts=, =.tsx= and hook ~lsp-mode~ on it. It doesn't specifically support inline HTML,
but aside from minor indentation issues it works fine.
#+BEGIN_SRC emacs-lisp
(use-package typescript-mode
:straight t
:config
:mode ("\\.ts\\'" . typescript-mode)
:mode ("\\.tsx\\'" . typescript-mode)
:hook (typescript-mode . lsp-deferred))
#+END_SRC
* HTML Markup Language
Enable ~web-mode~ for =.html=, =.xhtml= and hook ~lsp-mode~ on it.
#+BEGIN_SRC emacs-lisp
(use-package web-mode
:straight t
:mode ("\\.html\\'" . web-mode)
:mode ("\\.xhtml\\'" . web-mode)
:hook (web-mode . lsp-deferred))
#+END_SRC
* CSS Style Sheet Language
Enable ~css-mode~ for =.css=, =.scss= and hook ~lsp-mode~ on it. Also make ~flycheck~ happy.
#+BEGIN_SRC emacs-lisp
(use-package css-mode
:mode ("\\.css\\'" . css-mode)
:mode ("\\.scss\\'". css-mode)
:hook (css-mode . lsp-deferred)
:config
(with-eval-after-load "flycheck"
(flycheck-add-mode 'javascript-eslint 'web-mode)))
#+END_SRC

28
emacs-lisp/magit.org Normal file
View file

@ -0,0 +1,28 @@
:PROPERTIES:
:ID: aa25248c-197c-4bf5-8fc1-aea93008e194
:END:
#+title: Magit
#+filetags: emacs-load
# SPDX-FileCopyrightText: 2022 Richard Brežák <richard@brezak.sk>
#
# SPDX-License-Identifier: LGPL-3.0-or-later
~magit~ is literally the best package right after OrgMode of course. Therefore enable it.
#+BEGIN_SRC emacs-lisp
(defun magit-reset-visibility-indicators (frame)
(with-selected-frame frame
(when (display-graphic-p)
(setq magit-section-visibility-indicator
(if (window-system)
'(magit-fringe-bitmap> . magit-fringe-bitmapv)
(cons (if (char-displayable-p ?…) "…" "...")
t)))
(remove-hook 'after-make-frame-functions #'magit-reset-visibility-indicators))))
(use-package magit
:straight t
:config
(add-hook 'after-make-frame-functions #'magit-reset-visibility-indicators))
#+END_SRC

22
emacs-lisp/marginalia.org Normal file
View file

@ -0,0 +1,22 @@
:PROPERTIES:
:ID: 921e105a-01ff-4ab3-9478-4d967a61ff3f
:ROAM_REFS: https://github.com/minad/marginalia
:END:
#+title: Marginalia
#+filetags: emacs-load
# SPDX-FileCopyrightText: 2022 Richard Brežák <richard@brezak.sk>
#
# SPDX-License-Identifier: LGPL-3.0-or-later
#+BEGIN_QUOTE
This package provides marginalia-mode which adds marginalia to the minibuffer completions. Marginalia are marks or annotations placed at the margin of the page of a book or in this case helpful colorful annotations placed at the margin of the minibuffer for your completion candidates.
#+END_QUOTE
#+BEGIN_SRC emacs-lisp
(use-package marginalia
:straight t
:init
(marginalia-mode))
#+END_SRC

130
emacs-lisp/meow.org Normal file
View file

@ -0,0 +1,130 @@
:PROPERTIES:
:ID: b88618f2-258f-4f3a-93f7-46fd45bc833f
:END:
#+title: Meow
#+filetags: emacs-load
# SPDX-FileCopyrightText: 2022 Richard Brežák <richard@brezak.sk>
#
# SPDX-License-Identifier: LGPL-3.0-or-later
Meow is a modal editing framework, it's a bit like evil but also very different. This keymap is setup for KOY.
#+begin_src emacs-lisp
(defun magic_rb/meow-prev (arg)
"Runs meow-prev except for some specific cases"
(interactive "P")
(pcase major-mode
('ement-room-list-mode (forward-button (* (or arg 1) -1)))
(mode (meow-prev arg))))
(defun magic_rb/meow-next (arg)
"Runs meow-prev except for some specific cases"
(interactive "P")
(pcase major-mode
('ement-room-list-mode (forward-button (or arg 1)))
(mode (meow-next arg))))
;; (add-hook #'ement-room-list-mode-hook (lambda () (unless (button-at (point)) (forward-button 1))))
(defun meow-setup ()
(setq meow-cheatsheet-layout meow-cheatsheet-layout-qwerty)
(general-def
:keymaps 'meow-insert-state-keymap
"j" (general-key-dispatch 'self-insert-command
:timeout 0.25
"j" 'meow-insert-exit))
(meow-motion-overwrite-define-key
'("r" . magic_rb/meow-prev)
'("n" . magic_rb/meow-next)
'("<escape>" . ignore))
(meow-leader-define-key
;; SPC r/n will run the original command in MOTION state.
'("r" . "H-r")
'("n" . "H-n")
;; Use SPC (0-9) for digit arguments.
'("1" . meow-digit-argument)
'("2" . meow-digit-argument)
'("3" . meow-digit-argument)
'("4" . meow-digit-argument)
'("5" . meow-digit-argument)
'("6" . meow-digit-argument)
'("7" . meow-digit-argument)
'("8" . meow-digit-argument)
'("9" . meow-digit-argument)
'("0" . meow-digit-argument)
'("/" . meow-keypad-describe-key)
'("?" . meow-cheatsheet))
(meow-normal-define-key
'("0" . meow-expand-0)
'("9" . meow-expand-9)
'("8" . meow-expand-8)
'("7" . meow-expand-7)
'("6" . meow-expand-6)
'("5" . meow-expand-5)
'("4" . meow-expand-4)
'("3" . meow-expand-3)
'("2" . meow-expand-2)
'("1" . meow-expand-1)
'("-" . negative-argument)
'("d" . meow-reverse)
'("w" . meow-inner-of-thing)
'("m" . meow-bounds-of-thing)
'("z" . meow-beginning-of-thing)
'("f" . meow-end-of-thing)
'("h" . meow-append)
'("H" . meow-open-below)
'("ö" . meow-back-word)
'("Ö" . meow-back-symbol)
'("ä" . meow-change)
'("e" . meow-delete)
'("E" . meow-backward-delete)
'("o" . meow-next-word)
'("O" . meow-next-symbol)
'("i" . meow-find)
'("u" . meow-cancel-selection)
'("U" . meow-grab)
'("c" . meow-insert)
'("C" . meow-open-above)
'("t" . meow-left)
'("T" . meow-left-expand)
'("r" . meow-prev)
'("R" . meow-prev-expand)
'("n" . meow-next)
'("N" . meow-next-expand)
'("s" . meow-right)
'("S" . meow-right-expand)
'("p" . meow-join)
'("b" . meow-search)
'("l" . meow-block)
'("L" . meow-to-block)
'("ß" . meow-clipboard-yank)
'("k" . meow-quit)
'("K" . meow-goto-line)
'("," . meow-replace)
'("" . meow-swap-grab)
'("a" . meow-clipboard-kill)
'("y" . meow-till)
'("g" . meow-undo)
'("G" . meow-undo-in-selection)
'("ü" . avy-goto-char-2)
'("." . meow-mark-word)
'("•" . meow-mark-symbol)
'("q" . meow-line)
'("Q" . meow-goto-line)
'("v" . meow-clipboard-save)
'("V" . meow-sync-grab)
'("x" . meow-pop-selection)
'("D" . repeat)
'("<escape>" . ignore)))
#+end_src
#+begin_src emacs-lisp
(use-package meow
:straight t
:config
(meow-setup)
(meow-global-mode 1))
#+end_src

View file

@ -0,0 +1,12 @@
:PROPERTIES:
:header-args:emacs-lisp: :comments link :results none
:ID: 9f801382-e771-4929-8eb3-f76afde9aba2
:END:
#+title: Native Compilation
#+filetags: emacs-load
When Emacs is native compiling, it'll constantly raised the warning buffer on every message, of which there are a lot. As far as I know, they are harmless and can be safely ignored. Therefore raised the minimum raising level to ~error~.
#+begin_src emacs-lisp
(setq warning-minimum-level :error)
#+end_src

21
emacs-lisp/orderless.org Normal file
View file

@ -0,0 +1,21 @@
:PROPERTIES:
:ID: 6bbcf471-95ee-4cd5-abee-d412a1eba068
:ROAM_REFS: https://github.com/oantolin/orderless
:END:
#+title: Orderless
#+filetags: emacs-load
# SPDX-FileCopyrightText: 2022 Richard Brežák <richard@brezak.sk>
#
# SPDX-License-Identifier: LGPL-3.0-or-later
#+BEGIN_QUOTE
This package provides an orderless completion style that divides the pattern into space-separated components, and matches candidates that match all of the components in any order. Each component can match in any one of several ways: literally, as a regexp, as an initialism, in the flex style, or as multiple word prefixes. By default, regexp and literal matches are enabled.
#+END_QUOTE
#+BEGIN_SRC emacs-lisp
(use-package orderless
:straight t
:config
(setq completion-styles '(orderless)))
#+END_SRC

168
emacs-lisp/org_agenda.org Normal file
View file

@ -0,0 +1,168 @@
:PROPERTIES:
:ID: 22d678ce-7a3a-486c-abfb-f6cebdd77f90
:END:
#+title: Org Agenda
#+filetags: :emacs-load:
# SPDX-FileCopyrightText: 2022 Richard Brežák <richard@brezak.sk>
#
# SPDX-License-Identifier: LGPL-3.0-or-later
Put state changes into the ~LOGBOOK~ section and not into a random spot.
#+BEGIN_SRC emacs-lisp
(setq org-log-into-drawer t)
#+END_SRC
Set priority levels to A, B, and C.
#+BEGIN_SRC emacs-lisp :resutls none
(setq org-highest-priority ?A)
(setq org-default-priority ?B)
(setq org-lowest-priority ?C)
#+END_SRC
* Dynamic Org Agenda using Org Roam DB
#+BEGIN_NOTE
This whole system depends on [[id:a56794cf-b8f9-4537-a390-bd7ee6bb35ae][Vulpea]]
#+END_NOTE
#+BEGIN_SRC emacs-lisp :results none
(with-eval-after-load "vulpea"
#+END_SRC
First we have to exclude the =agenda= tag from inheritance.
#+BEGIN_SRC emacs-lisp :results none
(add-to-list 'org-tags-exclude-from-inheritance "project")
#+END_SRC
Then we need a function to check whether a buffer contains any todo entry.
#+BEGIN_SRC emacs-lisp :results none
(defun vulpea-project-p ()
"Return non-nil if current buffer has any todo entry.
TODO entries marked as done are ignored, meaning the this
function returns nil if current buffer contains only completed
tasks."
(when (eq major-mode 'org-mode)
(org-element-map
(org-element-parse-buffer 'headline)
'headline
(lambda (h)
(eq (org-element-property :todo-type h)
'todo))
nil 'first-match)))
#+END_SRC
Then we need a function which will check whether the current buffer contains any TODOs and if so, then add a roam tag to that file, so that we can easily get a list of all files with TODOs.
#+BEGIN_SRC emacs-lisp :results none
(add-hook 'find-file-hook #'vulpea-project-update-tag)
(add-hook 'before-save-hook #'vulpea-project-update-tag)
(defun vulpea-project-update-tag ()
"Update PROJECT tag in the current buffer."
(when (and (not (active-minibuffer-window))
(vulpea-buffer-p))
(save-excursion
(goto-char (point-min))
(let* ((tags (vulpea-buffer-tags-get))
(original-tags tags))
(if (vulpea-project-p)
(setq tags (cons "project" tags))
(setq tags (remove "project" tags)))
;; cleanup duplicates
(setq tags (seq-uniq tags))
;; update tags if changed
(when (or (seq-difference tags original-tags)
(seq-difference original-tags tags))
(apply #'vulpea-buffer-tags-set tags))))))
(defun vulpea-buffer-p ()
"Return non-nil if the currently visited buffer is a note."
(and buffer-file-name
(or (string-prefix-p
(expand-file-name (file-name-as-directory org-roam-directory))
(file-name-directory buffer-file-name))
(string-prefix-p
(expand-file-name (file-name-as-directory "~/dotfiles/emacs-lisp"))
(file-name-directory buffer-file-name)))))
#+END_SRC
Now for the second last function, we need to actually return the list of files containing the =project= tag, to be consumed by org-agenda.
#+BEGIN_SRC emacs-lisp :results none
(defun vulpea-project-files ()
"Return a list of note files containing 'project' tag." ;
(seq-uniq
(seq-map
#'car
(org-roam-db-query
[:select [nodes:file]
:from tags
:left-join nodes
:on (= tags:node-id nodes:id)
:where (or (like tag '"%project%") (like tag '"%project-forced%"))]))))
#+END_SRC
Finally we can update the list of project files before every =org-agenda= invocation.
#+BEGIN_SRC emacs-lisp :results none
(defun vulpea-agenda-files-update (&rest _)
"Update the value of `org-agenda-files'."
(setq org-agenda-files (vulpea-project-files)))
(advice-add 'org-agenda :before #'vulpea-agenda-files-update)
#+END_SRC
** Migration
To migrate existing org-roam files to this new system, run this elisp code.
#+BEGIN_SRC emacs-lisp :results none :tangle no
(dolist (file (org-roam-list-files))
(message "processing %s" file)
(with-current-buffer (or (find-buffer-visiting file)
(find-file-noselect file))
(vulpea-project-update-tag)
(save-buffer)))
#+END_SRC
#+BEGIN_SRC emacs-lisp :results none :exports none
)
#+END_SRC
* Custom Tags
Define a number of custom tags to ease organisation.
#+BEGIN_SRC emacs-lisp :results none
(defun my/org-match-at-point-p (match)
"Return non-nil if headline at point matches MATCH.
Here MATCH is a match string of the same format used by
`org-tags-view'."
(funcall (cdr (org-make-tags-matcher match))
(org-get-todo-state)
(org-get-tags-at)
(org-reduced-level (org-current-level))))
(defun my/org-agenda-skip-without-match (match)
"Skip current headline unless it matches MATCH.
Return nil if headline containing point matches MATCH (which
should be a match string of the same format used by
`org-tags-view'). If headline does not match, return the
position of the next headline in current buffer.
Intended for use with `org-agenda-skip-function', where this will
skip exactly those headlines that do not match."
(save-excursion
(unless (org-at-heading-p) (org-back-to-heading))
(let ((next-headline (save-excursion
(or (outline-next-heading) (point-max)))))
(if (my/org-match-at-point-p match) nil next-headline))))
#+END_SRC

294
emacs-lisp/org_gtd.org Normal file
View file

@ -0,0 +1,294 @@
:PROPERTIES:
:ID: 07d8e392-19ab-44d3-b4dc-cf68d73f64b6
:header-args:emacs-lisp: :comments link :results none
:END:
#+title: Org GTD
#+filetags: emacs-load
So let me preface this file with a little... preface. When I began this file, it was a few hours after I decided it's time to finally take up GTD and step my game up when it comes to organisation. So this file, along with [[id:18476d68-cccb-48f4-aa77-caefe213d8bd][Org Roam]] and [[id:986ca7a5-d225-49bb-9e35-f2dffafe8aee][Org Mode]] are the culmination of my efforts.
* End Goal
What I've very quickly, that GTD is only working properly when at no point, you stop to think "What did I want to/was supposed to do", if that ever happens to you, you're doing GTD wrong. With that in mind and me starting university in.. 5 days.. I want to ensure that forgetting an appointment, assignment, homework and forgetting to call a friend or reply to an email are all things of the past. To that end, I'll from now on, capture everything, be it on my phone or at one of my workstations.
** The Phone Thing
What I've learned after crafting my own workflows and using Emacs and Linux for almost 4 years now (WOW!) is that if a workflow isn't reliable, annoyance-free and convenient, I won't succeed in using it long term. Therefore any new workflow I adopt, must fill all those checkboxes or it won't stick. That's why I'm on the look out for [[id:3bc7f35e-bcb5-4e55-9ec7-623afa456a98][handheld computers]] or [[id:3bc7f35e-bcb5-4e55-9ec7-623afa456a98][linux phones]] which would enable me to use Emacs conveniently on the go. I've yet to find any which would be pocket sized or cheap enough that I could afford them. One requirement i have except for the Linux thing is that they must have a physical keyboard if I'm to lug around a second device.
For now, I've decided to make due with Emacs installed in Termux with [[id:3bc7f35e-bcb5-4e55-9ec7-623afa456a98][home-manager]].
* Implementation
So let's start with the entry point to the whole thing. Those would be the ~org-roam-capture-templates~ and ~org-roam-capture-ref-templates~. I've gone with more than just what was shown in [[id:c3b7951f-b8f2-41dc-856d-07373724ef99][Get Things Done with Emacs]] to remove some burden from me when I'm refiling each day. The cognitive overhead created by having to decide on what you're capturing isn't big enough for me to just capture everything into one disorganized heading. At least that's what I think now, we'll see how it goes.
I've split the capturing process into 7 different templates, first we have the resource templates, of which I have 2 currently, one for automatic capturing from a web browser and one for capturing manually from Emacs. Then we have a special ~event~ template, which can be quickly used to capture events and have them immediately show up in you agenda. Next up is a special template for capturing Emacs LISP code, that's mostly used when adding new packages and playing with the configuration. Second to last is a catch all email capturing template and lastly a catch all generic capturing template.
So the process for capturing is to trigger the capture with ~C-c o c~ and then quickly decide between one of the categories, simple enough hopefully.
#+begin_src emacs-lisp
(require 'org-roam-protocol)
(setq org-roam-capture-ref-templates
`(("rw" "Web resource" entry
,(concat "* ${title} :resource:inbox:\n"
":PROPERTIES:\n"
":CREATED: %U\n"
":ROAM_REFS: ${ref}\n"
":ID: %(org-id-uuid)\n"
":END:\n\n"
"${body}")
:target (file+olp "inbox.org" ("Resources")))
("s" "Shopping list" entry
,(concat "* ${title} :inbox:\n"
":PROPERTIES:\n"
":CREATED: %U\n"
":END:\n\n"
"\n"
"${ref}\n\n"
"${body}")
:target (file+olp "inbox.org" ("Shopping list")))))
(setq org-roam-capture-templates
`(("i" "Inbox" entry
,(concat "* ${title} :inbox:\n"
":PROPERTIES:\n"
":CREATED: %U\n"
":ID: %(org-id-uuid)\n"
":END:\n"
"#+setupfile: ~/roam/emacs-lisp/setupfiles/latex-base.org\n\n"
"%?")
:target (file+olp "inbox.org" ("Shopping list")))
("f" "File" plain "%?"
:target (file+head "${slug}.org"
,(concat ":PROPERTIES:\n"
":CREATED: %U\n"
":ID: %(org-id-uuid)\n"
":END:\n"
"#+setupfile: ~/roam/emacs-lisp/setupfiles/latex-base.org\n\n"
"#+title: ${title}\n"
"")))
("@" "Inbox [mu4e]" entry
,(concat "* Process \"%a\" %? :inbox:\n"
":PROPERTIES:\n"
":CREATED: %U\n"
":ID: %(org-id-uuid)\n"
":END:\n\n"
"%?")
:target (file+olp "inbox.org" ("All")))
("t" "TODO" entry
,(concat "* TODO ${title} :inbox:\n"
":PROPERTIES:\n"
":CREATED: %U\n"
":ID: %(org-id-uuid)\n"
":END:\n\n"
"%?")
:target (file+olp "inbox.org" ("Todo")))
("r" "Resource")
("rw" "Web resource" entry
,(concat "* ${title} :resource:inbox:\n"
":PROPERTIES:\n"
":CREATED: %U\n"
":ROAM_REFS: %(completing-read \"URL for resource: \" nil nil nil nil nil (or (substring-no-properties (car kill-ring)) nil))\n"
":ID: %(org-id-uuid)\n"
":END:\n\n")
:target (file+olp "inbox.org" ("Resources" "Web")))
("E" "Event" entry
,(concat "* ${title} :event:inbox:\n"
":PROPERTIES:\n"
":DATE: %(org-time-stamp nil)\n"
":CREATED: %U\n"
":ID: %(org-id-uuid)\n"
":END:\n\n"
"%?")
:target (file+olp "inbox.org" ("Events")))
("e" "Emacs Lisp" plain "%?"
:target (file+head "emacs-lisp/${slug}.org"
,(concat ":PROPERTIES:\n"
":header-args:emacs-lisp: :comments link :results none\n"
":END:\n"
"#+title: ${title}\n"
"#+filetags: emacs-load"
"")))))
#+end_src
A special version of ~org-refile~ follows. What makes it special is that it first asks you for which [[id:18476d68-cccb-48f4-aa77-caefe213d8bd][Org Roam]] node you want to refile to and only then refiles. This eases the workflow quite a lot and also makes refiling snappy is it only needs to parse one file not a few thousand.
#+begin_src emacs-lisp
;; Make the refile completing read prompt also list the file itself in case it's empty
;; and also not require multiple consecutive selections in case of nested headings.
(setq org-refile-use-outline-path 'file)
(setq org-outline-path-complete-in-steps nil)
(defun org-roam-refile-incremental ()
(interactive)
(let* ((node (org-roam-node-read))
(org-refile-target-verify-function nil)
(org-refile-targets `((,(org-roam-node-file node) :maxlevel . 9))))
(org-refile-cache-clear)
(call-interactively 'org-refile)))
#+end_src
Please ignore this next block, this is some code that took me way too long to figure out and even longer to realize it's already been implemented upstream.
#+begin_src emacs-lisp :tangle no
(element (org-element-at-point))
(while (not (eq (car element) 'headline))
(setq element (plist-get (car (cdr element)) :parent)))
(setq element (car (cdr element)))
(let ((properties (org-entry-properties
(plist-get element :begin)
'standard)))
(message "%s" properties))
(delete-region
(plist-get element :begin)
(plist-get element :end))
(if (org-roam-node-file node)
(progn)
(org-roam-capture-
:node node
:templates `()
:info `()
:keys ""
:props '(:finalize )))
#+end_src
This little advice cleans up after the ~org-roam-promote-entire-buffer~ function a bit. It leaves the buffer in a state that isn't quite what I want formatting and structure wise, so this just quickly fixes that.
#+begin_src emacs-lisp
(defun magic_rb/org-roam-promote-buffer-cleanup ()
(goto-char 1)
(org-roam-end-of-meta-data)
(delete-region (point) (progn (skip-chars-forward " \t") (point)))
(org-next-visible-heading 1)
(unless (eq (point) (point-max)) (insert "\n\n"))
(whitespace-cleanup)
(org-roam-db-update-file)
(org-roam-tag-remove '(inbox)))
(advice-add 'org-roam-promote-entire-buffer :after #'magic_rb/org-roam-promote-buffer-cleanup)
(defun magic_rb/org-roam-promote-buffer-prepare ()
(org-with-point-at 1
(org-next-visible-heading 1)
;; (when (and (not (org-roam--buffer-promotable-p))
;; (org-roam-get-keyword "filetags")
;; (not (org-get-tags nil t)))
;; )
(org-todo "")
))
(advice-add 'org-roam-promote-entire-buffer :before #'magic_rb/org-roam-promote-buffer-prepare)
#+end_src
Next this function actually fixes a bug and cleans up after the ref capture. As of now [2022-08-31] the ~org-ref-capture~ protocol has a few minor issues:
1. you can't tell it not not create a ~ROAM_REFS~ property
2. it always creates the ~ROAM_REFS~ property at the root of the [[id:18476d68-cccb-48f4-aa77-caefe213d8bd][Org Roam]] node it's capturing into so if you're capturing into a heading for later refilling without an ID, it'll create a ~ROAM_REFS~ property but at the wrong place
3. when you capture into a buffer that already has a ~ROAM_REFS~ it'll break completely, so we must remove it after it adds it
#+begin_src emacs-lisp
(defun magic_rb/clear-roam-refs-if-in-inbox ()
(with-current-buffer (org-capture-get :buffer)
(let* ((target-file (file-name-nondirectory (buffer-file-name))))
(when (and (org-roam-capture-p)
(string-equal target-file "inbox.org"))
(save-excursion
(goto-char (point-min))
(org-entry-delete nil "ROAM_REFS"))))))
(add-hook 'org-capture-after-finalize-hook #'magic_rb/clear-roam-refs-if-in-inbox)
#+end_src
** Agenda
First we define a few functions, which I got from [[https://stackoverflow.com/questions/10074016/org-mode-filter-on-tag-in-agenda-view][Stack Overflow]]. They allow you to filter in [[id:22d678ce-7a3a-486c-abfb-f6cebdd77f90][Org Agenda]] views with the syntax as described in [[info:org#Matching tags and properties][Matching tags and properties]]. They're not used currently, but may come in handy so I just keep them here.
#+BEGIN_SRC emacs-lisp :results none
(defun my/org-match-at-point-p (match)
"Return non-nil if headline at point matches MATCH.
Here MATCH is a match string of the same format used by
`org-tags-view'."
(funcall (cdr (org-make-tags-matcher match))
(org-get-todo-state)
(org-get-tags-at)
(org-reduced-level (org-current-level))))
(defun my/org-agenda-skip-without-match (match)
"Skip current headline unless it matches MATCH.
Return nil if headline containing point matches MATCH (which
should be a match string of the same format used by
`org-tags-view'). If headline does not match, return the
position of the next headline in current buffer.
Intended for use with `org-agenda-skip-function', where this will
skip exactly those headlines that do not match."
(save-excursion
(unless (org-at-heading-p) (org-back-to-heading))
(let ((next-headline (save-excursion
(or (outline-next-heading) (point-max)))))
(if (my/org-match-at-point-p match) nil next-headline))))
#+END_SRC
Now the fun part. I only define one unified agenda view for now. It allows
#+BEGIN_SRC emacs-lisp :results none
(setq org-todo-keywords '((sequence "TODO(t)" "NEXT(n)" "INPROGRESS(i)" "STUCK(s)" "|" "DONE(d)" "CANCELLED(c)"))
org-use-fast-todo-selection t)
(setq org-agenda-custom-commands
'(("g" "Get Things Done (GTD)"
((agenda ""
((org-agenda-skip-function
'(org-agenda-skip-entry-if 'deadline))
(org-deadline-warning-days 0)))
(todo "INPROGRESS"
((org-agenda-skip-function
'(org-agenda-skip-entry-if 'deadline))
(org-agenda-prefix-format " %i %-12:c [%e] ")
(org-agenda-overriding-header "\nTasks started\n")))
(todo "NEXT"
((org-agenda-skip-function
'(org-agenda-skip-entry-if 'deadline))
(org-agenda-prefix-format " %i %-12:c [%e] ")
(org-agenda-overriding-header "\nTasks planned\n")))
(agenda nil
((org-agenda-entry-types '(:deadline))
(org-agenda-format-date "")
(org-deadline-warning-days 21)
(org-agenda-skip-function
'(org-agenda-skip-entry-if 'notregexp "\\* NEXT"))
(org-agenda-overriding-header "\nDeadlines")))
(todo "TODO"
((org-agenda-prefix-format " %?-12t% s")
(org-agenda-skip-function
'(my/org-agenda-skip-without-match "-inbox"))
(org-agenda-overriding-header "\nTo be done\n")))
(tags "inbox"
((org-agenda-prefix-format " %?-12t% s")
(org-agenda-overriding-header "\nInbox\n")))
(tags "CLOSED>=\"<today>\""
((org-agenda-overriding-header "\nCompleted today\n")))))))
#+END_SRC
** Keybindings
#+begin_src emacs-lisp
(defun org-capture-inbox ()
(interactive)
(call-interactively 'org-store-link)
(org-roam-capture nil "i"))
(defun org-capture-mail ()
(interactive)
(call-interactively 'org-store-link)
(org-roam-capture nil "@"))
(setq org-agenda-hide-tags-regexp (regexp-opt '("project" "inbox")))
(general-define-key
:keymaps 'global
"C-c i" 'org-capture-inbox)
(general-define-key
:keymaps '(mu4e-headers-mode-map mu4e-view-mode-map)
"C-c i" 'org-capture-mail)
#+end_src

23
emacs-lisp/org_habit.org Normal file
View file

@ -0,0 +1,23 @@
:PROPERTIES:
:ID: 28f65a55-f6b4-4c42-8b15-3e3a353c7c0a
:ROAM_REFS: https://www.reddit.com/r/emacs/comments/3ltjjc/org_reset_task_when_it_repeats
:END:
#+title: Org Habit
#+filetags: emacs-load
# SPDX-FileCopyrightText: 2022 Richard Brežák <richard@brezak.sk>
#
# SPDX-License-Identifier: LGPL-3.0-or-later
#+BEGIN_SRC emacs-lisp :results none
(require 'org-habit)
#+END_SRC
Setup a function which resets any checkboxes under a ~TODO~ which changes state to ~DONE~. Many thanks to [[https://www.reddit.com/user/davidglasser][davidglasser]], who had this exact same issue and solved it on [[https://www.reddit.com/r/emacs/comments/3ltjjc/org_reset_task_when_it_repeats/cv9gbj6?utm_source=share&utm_medium=web2x&context=3][Reddit]].
#+BEGIN_SRC emacs-lisp
(defun glasser-org-reset-check-on-repeat ()
(when (and (org-get-repeat) (member org-state org-done-keywords))
(org-reset-checkbox-state-subtree)))
(add-hook 'org-after-todo-state-change-hook 'glasser-org-reset-check-on-repeat)
#+END_SRC

211
emacs-lisp/org_mode.org Normal file
View file

@ -0,0 +1,211 @@
:PROPERTIES:
:ID: 986ca7a5-d225-49bb-9e35-f2dffafe8aee
:END:
#+title: Org Mode
#+filetags: emacs-load
# SPDX-FileCopyrightText: 2022 Richard Brežák <richard@brezak.sk>
#
# SPDX-License-Identifier: LGPL-3.0-or-later
I used to respect the 80 column limit, but why waste all the space when it can be dynamic. In this way all of the available screen space is utilized.
#+BEGIN_SRC emacs-lisp :results none
(add-hook 'org-mode-hook 'visual-line-mode)
#+END_SRC
Enable /"fake"/ indentation in =org-mode=, in other words, add indentation using overlays, but on disk the buffer is not indented.
#+BEGIN_SRC emacs-lisp :results none
(add-hook 'org-mode-hook 'org-indent-mode)
#+END_SRC
Increase the size of headings, in my personal opinion this makes the headings stand out a bit more and therefore easier to read.
#+BEGIN_SRC emacs-lisp :results none
(custom-set-faces
'(org-level-1 ((t (:inherit outline-1 :height 1.25))))
'(org-level-2 ((t (:inherit outline-2 :height 1.2))))
'(org-level-3 ((t (:inherit outline-3 :height 1.15))))
'(org-level-4 ((t (:inherit outline-4 :height 1.10))))
'(org-level-5 ((t (:inherit outline-5 :height 1.05)))))
#+END_SRC
Disable element cache for now, it freaks out all the damn time. God forbid I make a tiny syntax error...
#+begin_src emacs-lisp
(setq org-element-use-cache nil)
#+end_src
#+begin_src emacs-lisp
(setf org-blank-before-new-entry '((heading . t) (plain-list-item . nil)))
#+end_src
#+begin_src emacs-lisp
(setq org-src-window-setup 'current-window)
#+end_src
* Org Mark Ring
To go back to the previous mark, very useful with [[id:18476d68-cccb-48f4-aa77-caefe213d8bd][Org Roam]].
#+BEGIN_SRC emacs-lisp :results none
(general-def org-mode-map "C-c b" 'org-mark-ring-goto)
#+END_SRC
* Babel
Enable =tangle on save=, big thanks to Diego Zamboni for his amazing booklet about /[[https://leanpub.com/lit-config/read][Literate Configuration]]/.
#+BEGIN_SRC emacs-lisp :results none
(add-hook 'org-mode-hook
(lambda () (add-hook 'after-save-hook #'org-babel-tangle :append :local)))
#+END_SRC
After executing a source code block with =org-babel=, redisplay inline images, this speeds up the REPL-like workflow a lot.
#+BEGIN_SRC emacs-lisp :results none
(add-hook 'org-babel-after-execute-hook 'org-redisplay-inline-images)
#+END_SRC
Enable additional babel languages.
#+BEGIN_SRC emacs-lisp :results none
(org-babel-do-load-languages
'org-babel-load-languages
(cl-map 'list (lambda (lang) `(,lang . t))
'(python R shell dot latex plantuml)))
#+END_SRC
* Latex
For previews, create SVGs and not PNGs or something, use the ~dvisvgm-lua~ command.
#+BEGIN_SRC emacs-lisp :results none
(setq org-preview-latex-default-process 'dvisvgm)
#+END_SRC
Actually define ~dvisvgm-lua~.
#+begin_src emacs-lisp :results none
(add-to-list
'org-preview-latex-process-alist
'(dvisvgm-lua
:programs ("dvilualatex" "dvisvgm")
:description "dvi > svg"
:message "you need to install the programs: latex and dvisvgm."
:image-input-type "dvi"
:image-output-type "svg"
:image-size-adjust (1.7 . 1.5)
:latex-compiler ("dvilualatex -interaction nonstopmode -output-directory %o %f")
:image-converter ("dvisvgm %f -n -b min -c %S -o %O")))
#+end_src
Adjust size of LaTeX previews.
#+BEGIN_SRC emacs-lisp :results none
(pcase (system-name)
("heater" (setq org-format-latex-options (plist-put org-format-latex-options :scale 1.75)))
("omen" (setq org-format-latex-options (plist-put org-format-latex-options :scale 0.8))))
#+END_SRC
To support non-breakable whitespace, create a new ~org-entity~.
#+begin_src emacs-lisp
(add-to-list 'org-entities
'("space" "~" nil "&nbsp;" " " " " " "))
#+end_src
Enable fontification for inline LaTeX blocks which convieniently also makes in fixed-width.
#+begin_src emacs-lisp
(setq org-highlight-latex-and-related '(native entities))
#+end_src
** Sliced Previews
Normally a LaTeX preview is just one huge image which makes Emacs really jumpy and makes writing prose a really unpleasant experience. With these two functions, that's fixed. They work using mainly text properties (overlays are still involved but only one per preview, max two) so it should be fast still.
#+begin_src emacs-lisp
;;; -*- lexical-binding: t; -*-
(plist-put org-format-latex-options :background "Transparent")
(defadvice org-clear-latex-preview (after org-prop-img--org-clear-later-preview (beg end) activate)
(save-excursion
(goto-char beg)
(with-silent-modifications
(put-text-property beg end 'read-only nil)
(put-text-property beg end 'display nil)
(put-text-property beg end 'line-height nil))
(font-lock-fontify-region beg end)))
(defun org--make-preview-overlay (beg end image &optional imagetype)
"Build an overlay between BEG and END using IMAGE file.
Argument IMAGETYPE is the extension of the displayed image,
as a string. It defaults to \"png\"."
(let* ((imagetype (or (intern imagetype) 'png))
(image-spec (list 'image :type imagetype :file image :ascent 'center))
(ov (make-overlay beg end)))
(overlay-put ov 'org-overlay-type 'org-latex-overlay)
(overlay-put ov
'modification-hooks
(list (lambda (ov after &rest args)
(when (not after)
(org-clear-latex-preview (overlay-start ov) (overlay-end ov))))))
(if (> (count-lines beg end) 1)
(let ((image-height (cdr (image-size image-spec t)))
(y 0)
(endm (make-marker)))
(set-marker endm end)
(save-excursion
(goto-char beg)
(while (and (<= (point) endm) (< y image-height))
(let* ((dy (line-pixel-height)))
;; loop through and check for empty lines, those will break rendering
(when (= (line-beginning-position) (line-end-position))
(goto-char (line-beginning-position))
(insert "%")
(forward-char -1))
(when (> (* dy 2) (- image-height y))
(setq dy (- image-height y)))
(with-silent-modifications
;; place the image property on the current line
(put-text-property
(line-beginning-position) (line-end-position)
'display
(list
(list 'slice
0 y 1.0 dy)
image-spec))
;; ;; remove any fontification face so the images don't get colored
;; (put-text-property (line-beginning-position) (line-end-position)
;; 'face
;; nil)
)
(forward-line 1)
(setq y (+ y dy))))
(if (not (> (point) endm))
(let ((ov (make-overlay (- (point) 1) endm)))
(overlay-put ov 'org-overlay-type 'org-latex-overlay)
(overlay-put ov 'evaporate t)
(overlay-put ov 'invisible t))))
(set-marker endm nil))
(with-silent-modifications
(put-text-property beg end
'display
(list image-spec))))
(font-lock-fontify-region beg end)
(with-silent-modifications
(put-text-property beg end 'line-height t))))
#+end_src

186
emacs-lisp/org_roam.org Normal file
View file

@ -0,0 +1,186 @@
:PROPERTIES:
:ID: 18476d68-cccb-48f4-aa77-caefe213d8bd
:END:
#+title: Org Roam
#+filetags: emacs-load
# SPDX-FileCopyrightText: 2022 Richard Brežák <richard@brezak.sk>
#
# SPDX-License-Identifier: LGPL-3.0-or-later
#+BEGIN_NOTE
When exporting, running ~(org-id-update-id-locations (directory-files-recursively org-roam-directory ".org"))~
#+END_NOTE
#+BEGIN_SRC emacs-lisp :tangle no :results none
(defun replace-in-string (what with in)
(replace-regexp-in-string (regexp-quote what) with in nil 'literal))
(defun org-html--format-image (source attributes info)
(progn
(setq source (replace-in-string "%20" " " source))
(format "<img src=\"data:image/%s+xml;base64,%s\"%s />"
(or (file-name-extension source) "")
(base64-encode-string
(with-temp-buffer
(insert-file-contents-literally source)
(buffer-string)))
(file-name-nondirectory source))))
#+END_SRC
#+BEGIN_QUOTE
Org-roam is a plain-text knowledge management system. It brings some of Roam's more powerful features into the Org-mode ecosystem.
#+END_QUOTE
#+BEGIN_WARNING
SQLite3 must be on Emacs' PATH!
#+END_WARNING
#+BEGIN_SRC emacs-lisp :results none
(use-package org-roam
:straight
(org-roam
:type git
:host github
:repo "org-roam/org-roam"
:branch "main")
:init
(setq org-roam-v2-ack t)
:config
(add-hook 'after-init-hook 'org-roam-setup)
;; Add ignore for SyncThing
(setq org-roam-file-exclude-regexp (regexp-opt '(".stversions" ".sync-conflict-" "logseq")))
(setq org-roam-directory "~/roam")
;; Add more informative completion interface
(setq org-roam-node-display-template (concat "${title:*} " (propertize "${tags:30}" 'face 'org-tag)))
(defun magic_rb/org-roam-buffer-hook ()
(when (org-roam-buffer-p)
(make-local-variable 'org-link-frame-setup)
(add-to-list 'org-link-frame-setup '(file . find-file))))
(add-hook 'org-mode-hook 'magic_rb/org-roam-buffer-hook)
(defun magic_rb/org-roam-hook ()
(visual-line-mode))
(add-hook 'org-roam-mode-hook 'magic_rb/org-roam-hook))
(use-package shackle
:straight t
:init
(shackle-mode))
(setq shackle-rules
'((org-roam-mode
:align right
:size 0.25
:popup t)))
#+END_SRC
* Ref Capture
Using ~org-protocol~, one can capture a website from their browser directly into Org Roam.
#+BEGIN_SRC emacs-lisp :tangle no
(with-eval-after-load "org-roam"
(require 'org-roam-protocol)
(setq org-roam-capture-ref-templates
`(("r" "ref" plain "%?"
:target (file+head "%<%Y%m%d%H%M%S>-${slug}.org" "#+title: ${title}\n\n${body}")
:unnarrowed t))))
#+END_SRC
Then you need a desktop entry for ~org-protocol~. Such as:
#+BEGIN_SRC conf-desktop
[Desktop Entry]
Name=org-protocol
Exec=emacsclient %u
Type=Application
Terminal=false
Categories=System;
MimeType=x-scheme-handler/org-protocol;
#+END_SRC
or in Nix form:
#+BEGIN_SRC nix
makeDesktopItem {
name = "Org-Protocol";
exec = "emacsclient %u";
comment = "Org protocol";
desktopName = "org-protocol";
type = "Application";
mimeType = "x-scheme-handler/org-protocol";
}
#+END_SRC
Lastly a bookmarklet in Firefox.
#+BEGIN_SRC javascript
javascript:location.href ='org-protocol://roam-ref?template=rw&ref=' + encodeURIComponent(location.href) + '&title=' + encodeURIComponent(document.title) + '&body=' + encodeURIComponent(window.getSelection())
#+END_SRC
* Export
#+begin_src emacs-lisp :tangle no :results none
(require 'org-roam-export)
(require 'nxml-mode)
(defun magic_rb/org-html-publish-to-html-continue (plist filename pub-dir)
(org-html-publish-to-html plist filename pub-dir))
(defcustom org+-html-embed-svg nil
"Embed SVG images.
You can set this variable in Org files with
,#+HTML_EMBED_SVG: t
or
,#+OPTIONS: html-embed-svg:t"
:type 'boolean
:group 'org-export-html)
(cl-pushnew
'(:html-embed-svg "HTML_EMBED_SVG" "html-embed-svg" org+-html-embed-svg)
(org-export-backend-options (org-export-get-backend 'html)))
(defun org+-html-svg-image-embed (fun source attributes info)
"Make embedding of SVG images possible in org HTML export.
SVG images are embedded if :html-embed-svg is non-nil in the plist INFO.
Otherwise FUN called with SOURCE, ATTRIBUTES, and INFO as arguments.
SOURCE is the file name of the SVG file.
This is an around advice for `org-html--svg-image' as FUN."
(if (and
(member (plist-get info :html-embed-svg) '("yes" "t" t))
(string-equal "svg" (file-name-extension source)))
(with-temp-buffer
(message "embedding svg: %s" source)
(insert-file-contents source)
(with-syntax-table nxml-mode-syntax-table
(while (and (search-forward "<svg") ;; barfs if a "<svg" is not found in code
(nth 8 (syntax-ppss)))))
(delete-region (point-min) (match-beginning 0))
(buffer-string))
(funcall fun (concat "../" source) attributes info)))
(advice-add 'org-html--format-image :around #'org+-html-svg-image-embed)
(setq org-publish-project-alist
`(("org"
:base-directory "~/roam/"
:publishing-function org-html-publish-to-html ;; magic_rb/org-html-publish-to-html-continue
:publishing-directory "~/roam/published"
:exclude "^.*$"
:include ,(seq-map #'car
(org-roam-db-query
[:select [nodes:file]
:from tags
:left-join nodes
:on (= tags:node-id nodes:id)
:where (like tag (quote "%\"public-publish\""))]))
)))
(org-publish "org" t)
#+end_src
https://emacs.stackexchange.com/questions/59149/why-is-latex-preview-and-latex-to-html-export-via-dvisvgm-not-working-in-org-mod

View file

@ -0,0 +1,20 @@
:PROPERTIES:
:ID: 3e36a34a-7038-4466-847a-e4023f1f4827
:END:
#+title: Org Variable Pitch
#+filetags: emacs-load
# SPDX-FileCopyrightText: 2022 Richard Brežák <richard@brezak.sk>
#
# SPDX-License-Identifier: LGPL-3.0-or-later
Enable ~org-variable-pitch~, it makes ~org-mode~ feel like a proper writing instrument.
#+BEGIN_SRC emacs-lisp
(use-package org-variable-pitch
:straight t
:config
(set-face-attribute 'org-variable-pitch-fixed-face nil
:inherit 'variable-pitch)
:hook (org-mode . org-variable-pitch--enable))
#+END_SRC

76
emacs-lisp/popper.org Normal file
View file

@ -0,0 +1,76 @@
:PROPERTIES:
:ID: 45da0115-42c7-4a9a-9288-c5d840a69b92
:END:
#+title: Popper
#+filetags: emacs-load
# SPDX-FileCopyrightText: 2022 Richard Brežák <richard@brezak.sk>
#
# SPDX-License-Identifier: LGPL-3.0-or-later
Enable ~popper~, a better version of ~popwin~, which might actually work. It groups popups by context and allows you to specify their exact positioning, or even a custom display function. It also seems to be better at restoring the previous layout.
#+NAME: popper
#+BEGIN_SRC emacs-lisp
(use-package popper
:straight (popper :type git :host github :repo "karthink/popper")
:config
(setq popper-reference-buffers
'("\\*Messages\\*"
"\\*Warnings\\*"
"\\*Error\\*"
"Output\\*$"
"\\*HS-Error\\*"
"\\*lsp-help\\*"
"^\\*Ement compose.*\\*$"
haskell-interactive-mode
help-mode
compilation-mode
rustic-compilation-mode
tex-shell))
(popper-mode +1))
#+END_SRC
Add a [[id:db1d0122-58d6-4dec-84f6-afcb52937fc7][consult]] source for popped buffers.
#+begin_src emacs-lisp
(with-eval-after-load 'consult
(setq magic_rb/consult-source-popper
`(:name "popper"
:narrow ?P
:category buffer
:face consult-buffer
:history buffer-name-history
:state consult--buffer-state
:items
(lambda ()
(let ((group-name (when popper-group-function
(with-current-buffer buf (funcall popper-group-function)))))
(mapcar #'buffer-name
(append
(mapcar #'cdr (alist-get group-name popper-buried-popup-alist))
(mapcar #'cdr (alist-get group-name popper-open-popup-alist))))))))
(add-to-list 'consult-buffer-sources 'magic_rb/consult-source-popper 'append))
#+end_src
Force user buffer switching to also obey ~display-buffer-alist~.
#+begin_src emacs-lisp
(setq switch-to-buffer-obey-display-actions t)
#+end_src
Set almost all popups to ~meow-motion-mode~, except for [[id:986ca7a5-d225-49bb-9e35-f2dffafe8aee][Org Mode]] popups and [[id:8fbb19be-bb8d-4fef-8a6a-9d5a3f5d06ec][Vterm]].
#+begin_src emacs-lisp :tangle no
(defun magic_rb/popper-meow-motion (buf &optional _act)
(with-current-buffer buf
(when
(and (popper-popup-p buf)
(not (equal major-mode 'vterm-mode))
(not ement-room-compose-buffer))
(meow-normal-mode) (meow-motion-mode))))
(advice-add 'popper-display-control-p :after 'magic_rb/popper-meow-motion)
#+end_src

14
emacs-lisp/racket.org Normal file
View file

@ -0,0 +1,14 @@
:PROPERTIES:
:ID: 3709b269-1b66-44c9-b282-c97f48716c52
:END:
#+title: Racket
#+filetags: emacs-load
# SPDX-FileCopyrightText: 2022 Richard Brežák <richard@brezak.sk>
#
# SPDX-License-Identifier: LGPL-3.0-or-later
#+BEGIN_SRC emacs-lisp
(use-package racket-mode
:straight t)
#+END_SRC

View file

@ -0,0 +1,16 @@
#+latex_header: \usepackage{xcolor}
#+latex_header: \usepackage{algorithm2e}
#+latex_header: \SetKwProg{Fn}{Function}{:}{end}
#+latex_header: \usepackage{cmbright}
#+latex_header: \usepackage{textcomp}
#+latex_header: \usepackage{tikz}
#+latex_header: \usetikzlibrary{shapes.geometric}
#+latex_header: \usepackage{mathtools}
#+latex_header: \usepackage{circuitikz}
#+latex_header: \usepackage{fancyvrb}
#+latex_header: \usepackage{blkarray}
#+latex_header: \usepackage{ifthen}
#+latex_header: \usepackage{array}
#+latex_header: \newenvironment*{dummyenv}{}{}
#+latex_header: \newcommand{\BlankLineEm}{\vskip 1em}
#+startup: latexpreview

167
emacs-lisp/tempel.org Normal file
View file

@ -0,0 +1,167 @@
:PROPERTIES:
:ID: a0514202-b2ef-41a4-9d77-01efaa7e8d64
:END:
#+title: Tempel
#+filetags: emacs-load
# SPDX-FileCopyrightText: 2022 Richard Brežák <richard@brezak.sk>
#
# SPDX-License-Identifier: LGPL-3.0-or-later
#+begin_quote
Tempel is a tiny template package for Emacs, which uses the syntax of the Emacs Tempo library. Tempo is an ancient
temple of the church of Emacs. It is 27 years old, but still in good shape since it successfully resisted change over
the decades. However it may look a bit dusty here and there. Therefore we present to you, Tempel, a modernized
implementation of Tempo, in the form of three commands.
#+end_quote
#+begin_src emacs-lisp :noweb yes
(use-package tempel
:straight '(tempel :type git :host github :repo "minad/tempel")
:config
<<tempel-path>>
:init
<<tempel-hooks>>
<<tempel-keymaps>>)
#+END_SRC
Set the template file to the result of tangling [[id:3e8f0e02-dbfe-4f34-9b00-8b7ecd0a238d][Tempel - Templates]].
#+name: tempel-path
#+begin_src emacs-lisp
(setq tempel-path (expand-file-name "~/roam/emacs-lisp/templates.lisp"))
#+end_src
Hook ~tempel-capf~ on both ~prog-mode~ and ~text-mode~.
#+name: tempel-hooks
#+begin_src emacs-lisp
(defun tempel-setup-capf ()
(add-hook 'completion-at-point-functions #'tempel-complete -100 'local))
(add-hook 'prog-mode-hook 'tempel-setup-capf)
(add-hook 'text-mode-hook 'tempel-setup-capf)
(add-hook 'lsp-mode-hook 'tempel-setup-capf)
#+end_src
Define keymaps, the defaults are unnecessarily hard to trigger.
#+name: tempel-keymaps
#+begin_src emacs-lisp
(general-define-key
:keymaps '(insert normal)
"C-n" 'nil
"C-p" 'nil)
(general-define-key
:keymaps 'tempel-map
"M-{" nil
"M-}" nil
"C-n" 'tempel-next
"C-p" 'tempel-previous)
#+end_src
Fix LSP not getting notified about changes, can be fixed by notifying it at the end of template expansion.
#+begin_src emacs-lisp
(advice-add
'tempel--disable
:before
(lambda (&rest r)
(when lsp-mode
(let* ((region-start (tempel--beginning))
(region-end (tempel--end)))
(lsp-on-change region-start region-end (- region-end region-start))))))
#+end_src
To setup a post template return point, use ~(tempel-retpoint-here)~ in a template.
#+begin_src emacs-lisp
(defun org-edit-special-latex-preview (&rest _)
(let ((datum (org-element-context)))
(when (and (memq (org-element-type datum) '(latex-environment latex-fragment))
(let ((beg (org-element-property :begin datum))
(end (org-element-property :end datum)))
(when (org-clear-latex-preview beg end)
(setq-local tempel-latex-preview t)))))))
(advice-add
'org-edit-special
:before
#'org-edit-special-latex-preview)
#+end_src
#+begin_src emacs-lisp
(defvar-local tempel-retpoint (make-marker))
(defvar-local tempel-latex-preview nil)
(defun tempel-retpoint-here ()
"Place a marker at `point' to allow for return on tempel exit."
(set-marker tempel-retpoint (point))
"")
(defun tempel-retpoint-goto ()
"Move `point' to `tempel-retpoint'."
(when (marker-position tempel-retpoint)
(goto-char (marker-position tempel-retpoint))
(set-marker tempel-retpoint nil)))
(add-hook
'tempel--disable
#'tempel-retpoint-goto)
(defvar org-src-mode-exit-hook nil)
(defun org-edit-src-exit-run-hooks (&rest _)
"Run hooks from `org-edit-src-exit-hook' upon exiting org-src edit buffer."
(run-hooks 'org-src-mode-exit-hook))
(advice-add
'org-edit-src-exit
:after
#'org-edit-src-exit-run-hooks)
(defun org-edit-src-exit-tempel-retpoint ()
"Return to `tempel-retpoint' if set."
(tempel-retpoint-goto))
(defun org-edit-src-exit-tempel-latex-preview ()
"Toggle LaTeX preview of templated LaTeX fragment."
(when tempel-latex-preview
(org-latex-preview)
(setq-local tempel-latex-preview nil)))
(add-hook
'org-src-mode-exit-hook
#'org-edit-src-exit-tempel-latex-preview)
(add-hook
'org-src-mode-exit-hook
#'org-edit-src-exit-tempel-retpoint)
(defun tempel-post-edit-latex (&optional preview move-back)
"Move `point' back and run `org-edit-special'.
If PREVIEW is non-nil then `org-latex-preview' will be called on
the resulting LaTeX block. Move point that MOVE-BACK lines back to
reach a good spot in the LaTeX block, defaults to `-2'."
(forward-line (or move-back -2))
(end-of-line)
(setq-local tempel-latex-preview preview)
(org-edit-special))
#+end_src
To allow for ~=>~ as template keys, ~'symbol~ won't work, but ~'evil-word~ will.
#+begin_src emacs-lisp
(defun tempel--prefix-bounds ()
"Return prefix bounds."
(if tempel-trigger-prefix
(let ((end (point))
(beg (save-excursion
(search-backward tempel-trigger-prefix
(line-beginning-position) 'noerror))))
(when (and beg (save-excursion
(not (re-search-backward "\\s-" beg 'noerror))))
(cons (+ beg (length tempel-trigger-prefix)) end)))
(bounds-of-thing-at-point 'symbol)))
#+end_src

View file

@ -0,0 +1,225 @@
:PROPERTIES:
:ID: 3e8f0e02-dbfe-4f34-9b00-8b7ecd0a238d
:header-args: :tangle ./templates.lisp
:END:
#+title: Tempel - Templates
# SPDX-FileCopyrightText: 2022 Richard Brežák <richard@brezak.sk>
#
# SPDX-License-Identifier: LGPL-3.0-or-later
* Fundamental Mode
#+BEGIN_SRC lisp
fundamental-mode ;; Available everywhere
(today (format-time-string "%Y-%m-%d"))
(heredoc "<<EOF\n" p "EOF\n")
#+END_SRC
* Prog Mode
#+BEGIN_SRC lisp
prog-mode
(fixme (if (derived-mode-p 'emacs-lisp-mode) ";; " comment-start) "FIXME ")
(todo (if (derived-mode-p 'emacs-lisp-mode) ";; " comment-start) "TODO ")
(bug (if (derived-mode-p 'emacs-lisp-mode) ";; " comment-start) "BUG ")
(hack (if (derived-mode-p 'emacs-lisp-mode) ";; " comment-start) "HACK ")
#+END_SRC
* Latex Mode
#+BEGIN_SRC lisp
latex-mode
(begin "\\begin{" (s env) "}" > n> r> "\\end{" (s env) "}")
(frac "\\frac{" p "}{" p "}")
(enumerate "\\begin{enumerate}\n\\item " r> n> "\\end{enumerate}")
(itemize "\\begin{itemize}\n\\item " r> n> "\\end{itemize}")
#+END_SRC
* Emacs List Mode
#+BEGIN_SRC lisp
emacs-lisp-mode
(lambda "(lambda (" p ")" n> r> ")")
(var "(defvar " p "\n \"" p "\")")
(const "(defconst " p "\n \"" p "\")")
(custom "(defcustom " p "\n \"" p "\"" n> ":type '" p ")")
(face "(defface " p " '((t :inherit " p "))\n \"" p "\")")
(group "(defgroup " p " nil\n \"" p "\"" n> ":group '" p n> ":prefix \"" p "-\")")
(macro "(defmacro " p " (" p ")\n \"" p "\"" n> r> ")")
(fun "(defun " p " (" p ")\n \"" p "\"" n> r> ")")
(let "(let (" p ")" n> r> ")")
(star "(let* (" p ")" n> r> ")")
(rec "(letrec (" p ")" n> r> ")")
(command "(defun " p " (" p ")\n \"" p "\"" n> "(interactive)" n> r> ")")
#+END_SRC
* Text Mode
#+BEGIN_SRC lisp
text-mode
(cut "--8<---------------cut here---------------start------------->8---" n r n
"--8<---------------cut here---------------end--------------->8---" n)
(asciibox "+-" (make-string (length str) ?-) "-+" n
"| " (s str) " |" n
"+-" (make-string (length str) ?-) "-+" n)
(rot13 (p "plain text" text) n "----" n (rot13 text))
(calc (p "taylor(sin(x),x=0,3)" formula) n "----" n (format "%s" (calc-eval formula)))
#+END_SRC
* Rst Mode
#+BEGIN_SRC lisp
rst-mode
(title (make-string (length title) ?=) n (p "Title: " title) n (make-string (length title) ?=) n)
#+END_SRC
* Java Mode
#+BEGIN_SRC lisp
java-mode
(class "public class " (p (file-name-base (or (buffer-file-name) (buffer-name)))) " {" n> r> n "}")
#+END_SRC
* C Mode
#+BEGIN_SRC lisp
c-mode :condition (re-search-backward "^\\w*$" (line-beginning-position) 'noerror)
(inc "#include <" (p (concat (file-name-base (or (buffer-file-name) (buffer-name))) ".h")) ">")
(incc "#include \"" (p (concat (file-name-base (or (buffer-file-name) (buffer-name))) ".h")) "\"")
#+END_SRC
* Org Mode
#+BEGIN_SRC lisp
org-mode
(title "#+title: " p n "#+author: Richard Brežák" n "#+language: en" n n)
(quote "#+begin_quote" n> r> n> "#+end_quote" n)
(example "#+begin_example" n> r> n> "#+end_example" n)
(center "#+begin_center" n> r> n> "#+end_center" n)
(comment "#+begin_comment" n> r> n> "#+end_comment" n)
(verse "#+begin_verse" n> r> n> "#+end_verse" n)
(src "#+begin_src " p n> r> n> "#+end_src" n
:post (org-edit-src-code))
(export "#+begin_export " p n
n
"#+end_export" n
:post (progn (previous-line) (org-edit-special)))
(elisp "#+begin_src emacs-lisp" n> r> n "#+end_src" n
:post (progn (org-edit-src-code)))
(abs "\\begin{abstract}" n> r> n> "\\end{abstract}" n)
(align "\\begin{align}" n
" " n
"\\end{align}\n" n
(tempel-retpoint-here)
:post (tempel-post-edit-latex t))
(align* "\\begin{align*}" n
" " n
"\\end{align*}\n" n
(tempel-retpoint-here)
:post (tempel-post-edit-latex t))
(arr "\\begin{array}" n
n
"\\end{array}" n
(tempel-retpoint-here)
:post (tempel-post-edit-latex t))
(begin "\\begin{" (p "environment" env) "}"
n n
"\\end{" env "}" n
(tempel-retpoint-here) q
:post (tempel-post-edit-latex t))
(bib "\\bibliographystyle{plain}" n "\\bibliography{" s "}" n)
(dm "\\[" n
" ." n
"\\]" q
(tempel-retpoint-here)
:post (tempel-post-edit-latex t))
(mm "$" p "$ " q
:post (org-latex-preview))
(mmc "$\\textcolor{" p "}{" p "}$ " q
:post (org-latex-preview))
(item "\\begin{itemize}" n p n "\\end{itemize}" n)
(it "\\item " r)
(itd "\\item[" (p "label") "] " r)
(fig "\\begin{figure}[htbp]" n "\\centering" n p n "\\caption{" p "}" n "\\label{" p "}" n "\\end{figure}" n)
(minipage "\\begin{minipage}[" (p "htbp") "]{" (p "1.0") (p "\\linewidth") "}" n
" " n
"\\end{minipage}\n" n
(tempel-retpoint-here)
:post (tempel-post-edit-latex t))
(frame "\\begin{frame}{" (p "Frame Title") "}"h n
" " n
"\\end{frame}" n
(tempel-retpoint-here)
:post (tempel-post-edit-latex t))
(package "#+LATEX_HEADER: \\usepackage[" p "]{" p "}" n)
(ref "\\ref{" p "}")
(table "\\begin{tabular}{" p "}" n
" " n
"\\end{tabular}" n
(tempel-retpoint-here)
:post (tempel-post-edit-latex t))
(algorithm "\\begin{algorithm}" n
" \\DontPrintSemicolon\\;" n
" " n
"\\end{algorithm}" n
(tempel-retpoint-here)
:post (tempel-post-edit-latex t))
(function "\\begin{dummyenv}" n
" \\DontPrintSemicolon\\;" n
" \\SetKwFunction{" (p "" function) "}{" function "}" n
" \\begin{algorithm}" n
" \\Fn{\\" function "{" p "}}{"n
" " n
" }" n
" \\end{algorithm}" n
"\\end{dummyenv}" n
(tempel-retpoint-here)
:post (tempel-post-edit-latex t -4))
org-mode :condition (org-inside-LaTeX-fragment-p)
(frac "\\frac{" p "}{" p "}")
(larrow "\\leftarrow")
(rarrow "\\rightarrow")
(bigo "\\mathcal{O}(" p ")")
#+END_SRC
* Haskell Mode
#+BEGIN_SRC lisp
haskell-mode
(case
"case " (p "x") " of " n>
(p "Data") " -> " (p "undefined") n>
(p "Data") " -> " (p "undefined"))
({-} "{- " p " -}")
(=> (p "Class") " " (p "m") " => ")
(idata "data " (p "Type" ndata) " = " (s ndata) " " (p "Int") n>
"deriving (" (p "Show, Eq") ")")
(newtype "newtype " (p "Type" ndata) " = " (s ndata) " " (p "Int") n>
"deriving (" (p "Show, Eq") ")")
(data "data " (p "Type" ndata) " = " (s ndata) n>
"{ " (p "field") " :: " (p "Type") n>
", " (p "field") " :: " (p "Type") (tempel-retpoint-here) n>
"}" n>
"deriving (" (p "Show, Eq") ")")
(fn (p "f" fname) " :: " (p "a") " -> " (p "b") n
(s fname) " " (p "x") " = " (p "undefined"))
(fnc (p "f" fname) " :: " (p "a") " -> " (p "b") n
(s fname) " " (p "pattern") " = " (p "undefined") n
(s fname) " " (p "pattern") " = " (p "undefined"))
; guarded fn
(<- (p "x") " <- " (p "undefined"))
#+END_SRC

174
emacs-lisp/templates.lisp Normal file
View file

@ -0,0 +1,174 @@
fundamental-mode ;; Available everywhere
(today (format-time-string "%Y-%m-%d"))
(heredoc "<<EOF\n" p "EOF\n")
prog-mode
(fixme (if (derived-mode-p 'emacs-lisp-mode) ";; " comment-start) "FIXME ")
(todo (if (derived-mode-p 'emacs-lisp-mode) ";; " comment-start) "TODO ")
(bug (if (derived-mode-p 'emacs-lisp-mode) ";; " comment-start) "BUG ")
(hack (if (derived-mode-p 'emacs-lisp-mode) ";; " comment-start) "HACK ")
latex-mode
(begin "\\begin{" (s env) "}" > n> r> "\\end{" (s env) "}")
(frac "\\frac{" p "}{" p "}")
(enumerate "\\begin{enumerate}\n\\item " r> n> "\\end{enumerate}")
(itemize "\\begin{itemize}\n\\item " r> n> "\\end{itemize}")
emacs-lisp-mode
(lambda "(lambda (" p ")" n> r> ")")
(var "(defvar " p "\n \"" p "\")")
(const "(defconst " p "\n \"" p "\")")
(custom "(defcustom " p "\n \"" p "\"" n> ":type '" p ")")
(face "(defface " p " '((t :inherit " p "))\n \"" p "\")")
(group "(defgroup " p " nil\n \"" p "\"" n> ":group '" p n> ":prefix \"" p "-\")")
(macro "(defmacro " p " (" p ")\n \"" p "\"" n> r> ")")
(fun "(defun " p " (" p ")\n \"" p "\"" n> r> ")")
(let "(let (" p ")" n> r> ")")
(star "(let* (" p ")" n> r> ")")
(rec "(letrec (" p ")" n> r> ")")
(command "(defun " p " (" p ")\n \"" p "\"" n> "(interactive)" n> r> ")")
text-mode
(cut "--8<---------------cut here---------------start------------->8---" n r n
"--8<---------------cut here---------------end--------------->8---" n)
(asciibox "+-" (make-string (length str) ?-) "-+" n
"| " (s str) " |" n
"+-" (make-string (length str) ?-) "-+" n)
(rot13 (p "plain text" text) n "----" n (rot13 text))
(calc (p "taylor(sin(x),x=0,3)" formula) n "----" n (format "%s" (calc-eval formula)))
rst-mode
(title (make-string (length title) ?=) n (p "Title: " title) n (make-string (length title) ?=) n)
java-mode
(class "public class " (p (file-name-base (or (buffer-file-name) (buffer-name)))) " {" n> r> n "}")
c-mode :condition (re-search-backward "^\\w*$" (line-beginning-position) 'noerror)
(inc "#include <" (p (concat (file-name-base (or (buffer-file-name) (buffer-name))) ".h")) ">")
(incc "#include \"" (p (concat (file-name-base (or (buffer-file-name) (buffer-name))) ".h")) "\"")
org-mode
(title "#+title: " p n "#+author: Richard Brežák" n "#+language: en" n n)
(quote "#+begin_quote" n> r> n> "#+end_quote" n)
(example "#+begin_example" n> r> n> "#+end_example" n)
(center "#+begin_center" n> r> n> "#+end_center" n)
(comment "#+begin_comment" n> r> n> "#+end_comment" n)
(verse "#+begin_verse" n> r> n> "#+end_verse" n)
(src "#+begin_src " p n> r> n> "#+end_src" n
:post (org-edit-src-code))
(export "#+begin_export " p n
n
"#+end_export" n
:post (progn (previous-line) (org-edit-special)))
(elisp "#+begin_src emacs-lisp" n> r> n "#+end_src" n
:post (progn (org-edit-src-code)))
(abs "\\begin{abstract}" n> r> n> "\\end{abstract}" n)
(align "\\begin{align}" n
" " n
"\\end{align}\n" n
(tempel-retpoint-here)
:post (tempel-post-edit-latex t))
(align* "\\begin{align*}" n
" " n
"\\end{align*}\n" n
(tempel-retpoint-here)
:post (tempel-post-edit-latex t))
(arr "\\begin{array}" n
n
"\\end{array}" n
(tempel-retpoint-here)
:post (tempel-post-edit-latex t))
(begin "\\begin{" (p "environment" env) "}"
n n
"\\end{" env "}" n
(tempel-retpoint-here) q
:post (tempel-post-edit-latex t))
(bib "\\bibliographystyle{plain}" n "\\bibliography{" s "}" n)
(dm "\\[" n
" ." n
"\\]" q
(tempel-retpoint-here)
:post (tempel-post-edit-latex t))
(mm "$" p "$ " q
:post (org-latex-preview))
(mmc "$\\textcolor{" p "}{" p "}$ " q
:post (org-latex-preview))
(item "\\begin{itemize}" n p n "\\end{itemize}" n)
(it "\\item " r)
(itd "\\item[" (p "label") "] " r)
(fig "\\begin{figure}[htbp]" n "\\centering" n p n "\\caption{" p "}" n "\\label{" p "}" n "\\end{figure}" n)
(minipage "\\begin{minipage}[" (p "htbp") "]{" (p "1.0") (p "\\linewidth") "}" n
" " n
"\\end{minipage}\n" n
(tempel-retpoint-here)
:post (tempel-post-edit-latex t))
(frame "\\begin{frame}{" (p "Frame Title") "}"h n
" " n
"\\end{frame}" n
(tempel-retpoint-here)
:post (tempel-post-edit-latex t))
(package "#+LATEX_HEADER: \\usepackage[" p "]{" p "}" n)
(ref "\\ref{" p "}")
(table "\\begin{tabular}{" p "}" n
" " n
"\\end{tabular}" n
(tempel-retpoint-here)
:post (tempel-post-edit-latex t))
(algorithm "\\begin{algorithm}" n
" \\DontPrintSemicolon\\;" n
" " n
"\\end{algorithm}" n
(tempel-retpoint-here)
:post (tempel-post-edit-latex t))
(function "\\begin{dummyenv}" n
" \\DontPrintSemicolon\\;" n
" \\SetKwFunction{" (p "" function) "}{" function "}" n
" \\begin{algorithm}" n
" \\Fn{\\" function "{" p "}}{"n
" " n
" }" n
" \\end{algorithm}" n
"\\end{dummyenv}" n
(tempel-retpoint-here)
:post (tempel-post-edit-latex t -4))
org-mode :condition (org-inside-LaTeX-fragment-p)
(frac "\\frac{" p "}{" p "}")
(larrow "\\leftarrow")
(rarrow "\\rightarrow")
(bigo "\\mathcal{O}(" p ")")
haskell-mode
(case
"case " (p "x") " of " n>
(p "Data") " -> " (p "undefined") n>
(p "Data") " -> " (p "undefined"))
({-} "{- " p " -}")
(=> (p "Class") " " (p "m") " => ")
(idata "data " (p "Type" ndata) " = " (s ndata) " " (p "Int") n>
"deriving (" (p "Show, Eq") ")")
(newtype "newtype " (p "Type" ndata) " = " (s ndata) " " (p "Int") n>
"deriving (" (p "Show, Eq") ")")
(data "data " (p "Type" ndata) " = " (s ndata) n>
"{ " (p "field") " :: " (p "Type") n>
", " (p "field") " :: " (p "Type") (tempel-retpoint-here) n>
"}" n>
"deriving (" (p "Show, Eq") ")")
(fn (p "f" fname) " :: " (p "a") " -> " (p "b") n
(s fname) " " (p "x") " = " (p "undefined"))
(fnc (p "f" fname) " :: " (p "a") " -> " (p "b") n
(s fname) " " (p "pattern") " = " (p "undefined") n
(s fname) " " (p "pattern") " = " (p "undefined"))
; guarded fn
(<- (p "x") " <- " (p "undefined"))

25
emacs-lisp/treemacs.org Normal file
View file

@ -0,0 +1,25 @@
:PROPERTIES:
:ID: ee891758-1259-4af4-aabc-418a1c644d2f
:ROAM_REFS: https://github.com/Alexander-Miller/treemacs
:END:
#+title: Treemacs
#+filetags: emacs-load
# SPDX-FileCopyrightText: 2022 Richard Brežák <richard@brezak.sk>
#
# SPDX-License-Identifier: LGPL-3.0-or-later
#+BEGIN_QUOTE
Treemacs is a file and project explorer similar to NeoTree or vims NerdTree, but largely inspired by the Project Explorer in Eclipse. It shows the file system outlines of your projects in a simple tree layout allowing quick navigation and exploration, while also possessing basic file management utilities.
#+END_QUOTE
Treemacs is really cool.
#+BEGIN_SRC emacs-lisp
(use-package treemacs
:straight t
:after (doom-themes)
:config
;; read input from a minibuffer not a child frame.
(setq treemacs-read-string-input 'from-minibuffer))
#+END_SRC

14
emacs-lisp/vertico.org Normal file
View file

@ -0,0 +1,14 @@
:PROPERTIES:
:header-args:emacs-lisp: :comments link :results none
:ID: fe60a97d-9dd8-4279-b953-32616158a644
:END:
#+title: Vertico
#+filetags: emacs-load
#+begin_src elisp
(use-package vertico
:straight t
:init
(vertico-mode))
#+end_src

19
emacs-lisp/vterm.org Normal file
View file

@ -0,0 +1,19 @@
:PROPERTIES:
:ID: 8fbb19be-bb8d-4fef-8a6a-9d5a3f5d06ec
:ROAM_REFS: https://github.com/akermu/emacs-libvterm
:END:
#+title: Vterm
#+filetags: emacs-load
# SPDX-FileCopyrightText: 2022 Richard Brežák <richard@brezak.sk>
#
# SPDX-License-Identifier: LGPL-3.0-or-later
#+BEGIN_QUOTE
Emacs-libvterm (vterm) is fully-fledged terminal emulator inside GNU Emacs based on libvterm, a C library. As a result of using compiled code (instead of elisp), emacs-libvterm is fully capable, fast, and it can seamlessly handle large outputs.
#+END_QUOTE
#+BEGIN_SRC emacs-lisp
(use-package vterm
:straight t)
#+END_SRC

19
emacs-lisp/vulpea.org Normal file
View file

@ -0,0 +1,19 @@
:PROPERTIES:
:ID: a56794cf-b8f9-4537-a390-bd7ee6bb35ae
:END:
#+title: Vulpea
#+filetags: emacs-load
# SPDX-FileCopyrightText: 2022 Richard Brežák <richard@brezak.sk>
#
# SPDX-License-Identifier: LGPL-3.0-or-later
#+BEGIN_QUOTE
A collection of functions for note taking based on org and org-roam. This repository primary goal is to be a tested library for other applications and utilities around note taking.
#+END_QUOTE
#+BEGIN_SRC emacs-lisp :results none
(use-package vulpea
:straight t)
#+END_SRC

View file

@ -0,0 +1,26 @@
:PROPERTIES:
:ID: 8cfa2b1a-9004-4fa0-8ca4-72876ece7d70
:END:
#+title: whitespace.el
#+filetags: emacs-load
# SPDX-FileCopyrightText: 2022 Richard Brežák <richard@brezak.sk>
#
# SPDX-License-Identifier: LGPL-3.0-or-later
Highlight trailing whitespace.
#+begin_src emacs-lisp
(use-package whitespace
:config
(setq whitespace-style '(face tabs trailing))
(face-spec-set
'whitespace-tabs
'((t :background "red"))
'face-defface-spec)
(face-spec-set
'whitespace-trailing
'((t :background "red"))
'face-defface-spec)
(global-whitespace-mode))
#+end_src