mirror of
https://git.sr.ht/~magic_rb/dotfiles
synced 2024-11-25 09:36:14 +01:00
Revert "Clean out the repository" - bring back emacs-lisp
This reverts commit b673fb12c1
.
This commit is contained in:
parent
6a36890077
commit
640de3fb86
1
emacs-lisp/.gitignore
vendored
Normal file
1
emacs-lisp/.gitignore
vendored
Normal file
|
@ -0,0 +1 @@
|
|||
*.el
|
18
emacs-lisp/avy.org
Normal file
18
emacs-lisp/avy.org
Normal 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
|
12
emacs-lisp/c_language_support.org
Normal file
12
emacs-lisp/c_language_support.org
Normal 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
101
emacs-lisp/corfu.org
Normal 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
63
emacs-lisp/cosult.org
Normal 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
25
emacs-lisp/daylies.org
Normal 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
14
emacs-lisp/dired.org
Normal 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
15
emacs-lisp/dirvish.org
Normal 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
|
||||
|
82
emacs-lisp/display_settings.org
Normal file
82
emacs-lisp/display_settings.org
Normal 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
|
33
emacs-lisp/el_secretario.org
Normal file
33
emacs-lisp/el_secretario.org
Normal 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
21
emacs-lisp/elixir.org
Normal 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
61
emacs-lisp/emacs_rofi.org
Normal 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
78
emacs-lisp/email.org
Normal 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
24
emacs-lisp/embark.org
Normal 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
65
emacs-lisp/ement_el.org
Normal 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
|
||||
|
23
emacs-lisp/filling_and_unfilling_paragraphs.org
Normal file
23
emacs-lisp/filling_and_unfilling_paragraphs.org
Normal 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
66
emacs-lisp/flycheck.org
Normal 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
20
emacs-lisp/general_el.org
Normal 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
16
emacs-lisp/go.org
Normal 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
|
78
emacs-lisp/keybindings.org
Normal file
78
emacs-lisp/keybindings.org
Normal 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
142
emacs-lisp/lsp.org
Normal 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
28
emacs-lisp/magit.org
Normal 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
22
emacs-lisp/marginalia.org
Normal 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
130
emacs-lisp/meow.org
Normal 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
|
12
emacs-lisp/native_compilation.org
Normal file
12
emacs-lisp/native_compilation.org
Normal 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
21
emacs-lisp/orderless.org
Normal 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
168
emacs-lisp/org_agenda.org
Normal 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
294
emacs-lisp/org_gtd.org
Normal 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
23
emacs-lisp/org_habit.org
Normal 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
211
emacs-lisp/org_mode.org
Normal 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 " " " " " " " "))
|
||||
#+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
186
emacs-lisp/org_roam.org
Normal 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
|
20
emacs-lisp/org_variable_pitch.org
Normal file
20
emacs-lisp/org_variable_pitch.org
Normal 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
76
emacs-lisp/popper.org
Normal 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
14
emacs-lisp/racket.org
Normal 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
|
16
emacs-lisp/setupfiles/latex-base.org
Normal file
16
emacs-lisp/setupfiles/latex-base.org
Normal 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
167
emacs-lisp/tempel.org
Normal 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
|
||||
|
225
emacs-lisp/tempel_templates.org
Normal file
225
emacs-lisp/tempel_templates.org
Normal 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
174
emacs-lisp/templates.lisp
Normal 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
25
emacs-lisp/treemacs.org
Normal 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 vim’s 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
14
emacs-lisp/vertico.org
Normal 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
19
emacs-lisp/vterm.org
Normal 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
19
emacs-lisp/vulpea.org
Normal 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
|
||||
|
26
emacs-lisp/whitespace_el.org
Normal file
26
emacs-lisp/whitespace_el.org
Normal 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
|
Loading…
Reference in a new issue