Commit 6f760e2658e2

Vincent Demeester <vincent@sbr.pm>
2025-06-17 13:04:12
tools/emacs: move init to main and main to old
The mini configuration is good enough, so let's switch to it by default. Next we'll remove the mini *and* old folders. Signed-off-by: Vincent Demeester <vincent@sbr.pm>
1 parent 4fec525
Changed files (241)
home
common
desktop
tools
emacs
config
eshell
etc
eshell
orgmode
transient
yasnippet
host
lisp
transient
home/common/desktop/sway/default.nix
@@ -4,10 +4,6 @@ let
     #!/usr/bin/env bash
     fd . -d 3 --type d ~/src | ${pkgs.wofi}/bin/wofi -dmenu | xargs -I {} zsh -i -c "cd {}; emacs ."
   '';
-  emacs-mini = pkgs.writeScript "emacs-mini" ''
-    #!/usr/bin/env bash
-    emacs --init-directory=$HOME/src/home/tools/emacs/mini
-  '';
   fontConf = {
     names = [ "JetBrains Mono" ];
     size = 12.0;
@@ -124,7 +120,7 @@ in
           "${mod}+Shift+Return" = "exec emacsclient -c";
           "${mod}+Control+Return" = "exec emacs";
           "${mod}+Control+Shift+Return" = "exec ${emacs-in-folder}";
-          "${mod}+Control+Alt+Return" = "exec ${emacs-mini}";
+          "${mod}+Control+Alt+Return" = "exec emacs"; # TODO: remove this
 
           "${mod}+Left" = "focus left";
           "${mod}+Down" = "focus down";
@@ -232,7 +228,7 @@ in
           always = true;
         }
         # Probably put a condition here.
-        { command = "emacs --init-directory=$HOME/src/home/tools/emacs/mini --fg-daemon"; }
+        { command = "emacs --init-directory=$HOME/src/home/tools/emacs --fg-daemon"; }
         { command = "i3-back"; }
         { command = "firefox"; }
         { command = "${pkgs.kitty}/bin/kitty --title metask --class metask"; }
@@ -244,7 +240,7 @@ in
         inherit (config.wayland.windowManager.sway.config) menu;
       in
       ''
-        bindcode ${mod}+Control+Shift+Alt+41 exec ${emacs-mini}
+        bindcode ${mod}+Control+Shift+Alt+41 exec emacs
         bindcode ${mod}+33 exec "${menu}"
         bindcode ${mod}+Shift+33 exec "raffi -I"
         bindcode ${mod}+Control+33 exec "${pkgs.wofi-emoji}/bin/wofi-emoji -G"
tools/emacs/config/00-clean.el
@@ -1,79 +0,0 @@
-;;; 00-clean.el --- -*- lexical-binding: t; -*-
-;;; Commentary:
-;;; no-littering and recentf configurations
-;;; Note: this file is autogenerated from an org-mode file.
-;;; Code:
-
-(setopt make-backup-files nil)
-(setopt backup-inhibited nil) ; Not sure if needed, given `make-backup-files'
-(setopt create-lockfiles nil)
-
-(use-package recentf
-  :hook (after-init . recentf-mode)
-  :custom
-  (recentf-max-saved-items 500)
-  (recentf-save-file (locate-user-emacs-file "auto-save-list/recent-file-list.el"))
-  (recentf-auto-cleanup "8:00am")
-  (recentf-show-file-shortcuts-flag nil)
-  (recentf-exclude
-   '("\\.?cache" ".cask" "url" "COMMIT_EDITMSG\\'" "bookmarks"
-     "\\.\\(?:gz\\|gif\\|svg\\|elc\\|png\\|jpe?g\\|bmp\\|xpm\\)$"
-     "\\.?ido\\.last$" "\\.revive$" "/G?TAGS$" "/.elfeed/"
-     "^/tmp/" "^/var/folders/.+$" "^/sudo:" "^/su:" "^/ssh:" "^/sshfs:"
-     (lambda (file) (file-in-directory-p file package-user-dir))))
-  :config
-  (push (expand-file-name recentf-save-file) recentf-exclude)
-  ;; Magic advice to rename entries in recentf when moving files in
-  ;; dired.
-  (defun rjs/recentf-rename-notify (oldname newname &rest args)
-    (if (file-directory-p newname)
-        (rjs/recentf-rename-directory oldname newname)
-      (rjs/recentf-rename-file oldname newname)))
-
-  (defun rjs/recentf-rename-file (oldname newname)
-    (setq recentf-list
-          (mapcar (lambda (name)
-                    (if (string-equal name oldname)
-                        newname
-                      oldname))
-                  recentf-list))
-    recentf-cleanup)
-
-  (defun rjs/recentf-rename-directory (oldname newname)
-    ;; oldname, newname and all entries of recentf-list should already
-    ;; be absolute and normalised so I think this can just test whether
-    ;; oldname is a prefix of the element.
-    (setq recentf-list
-          (mapcar (lambda (name)
-                    (if (string-prefix-p oldname name)
-                        (concat newname (substring name (length oldname)))
-                      name))
-                  recentf-list))
-    recentf-cleanup)
-  (add-to-list 'recentf-filename-handlers 'abbreviate-file-name)
-  (advice-add 'dired-rename-file :after #'rjs/recentf-rename-notify))
-
-
-;; 2024-07-08: Do I have to setup this, or should I do like prot, disable *all* backup, lockfile, …
-(use-package no-littering               ; Keep .emacs.d clean
-  :config
-  (require 'recentf)
-  (add-to-list 'recentf-exclude no-littering-var-directory)
-  (add-to-list 'recentf-exclude no-littering-etc-directory)
-
-  ;; Move this in its own thing
-  (setq
-   create-lockfiles nil
-   delete-old-versions t
-   kept-new-versions 6
-   kept-old-versions 2
-   version-control t)
-
-  (setq
-   backup-directory-alist
-   `((".*" . ,(no-littering-expand-var-file-name "backup/")))
-   auto-save-file-name-transforms
-   `((".*" ,(no-littering-expand-var-file-name "auto-save/") t))))
-
-(provide '00-clean)
-;;; 00-clean.el ends here
tools/emacs/config/config-appearance.el
@@ -1,164 +0,0 @@
-;;; config-appearance.el --- -*- lexical-binding: t -*-
-;;; Commentary:
-;;; Appearance configuration
-;;; Code:
-
-(set-face-attribute 'fill-column-indicator nil
-                    :foreground "#717C7C") ; katana-gray
-(global-display-fill-column-indicator-mode 1)
-
-(setopt echo-keystrokes 0.1
-        line-number-display-limit-width 10000
-        indicate-buffer-boundaries 'left
-        indicate-empty-lines +1)
-
-(line-number-mode 1)
-(column-number-mode 1)
-
-;; let's enable it for all programming major modes
-(add-hook 'prog-mode-hook #'hl-line-mode)
-;; and for all modes derived from text-mode
-(add-hook 'text-mode-hook #'hl-line-mode)
-
-(use-package frame
-  :unless noninteractive
-  :commands vde/cursor-type-mode
-  :config
-  (setq-default cursor-type 'box)
-  (setq-default cursor-in-non-selected-windows '(bar . 2))
-  (setq-default blink-cursor-blinks 50)
-  (setq-default blink-cursor-interval nil) ; 0.75 would be my choice
-  (setq-default blink-cursor-delay 0.2)
-
-  (blink-cursor-mode -1)
-
-  (define-minor-mode vde/cursor-type-mode
-    "Toggle between static block and pulsing bar cursor."
-    :init-value nil
-    :global t
-    (if vde/cursor-type-mode
-        (progn
-          (setq-local blink-cursor-interval 0.75
-                      cursor-type '(bar . 2)
-                      cursor-in-non-selected-windows 'hollow)
-          (blink-cursor-mode 1))
-      (dolist (local '(blink-cursor-interval
-                       cursor-type
-                       cursor-in-non-selected-windows))
-        (kill-local-variable `,local))
-      (blink-cursor-mode -1))))
-
-(use-package emacs
-  :config
-  (setq-default custom-safe-themes t)
-  (setq-default custom--inhibit-theme-enable nil)
-
-  (defun vde/before-load-theme (&rest args)
-    "Clear existing theme settings instead of layering them.
-Ignores `ARGS'."
-    (mapc #'disable-theme custom-enabled-themes))
-
-  (advice-add 'load-theme :before #'vde/before-load-theme))
-
-(use-package emacs
-  :config
-  (setq window-divider-default-right-width 1)
-  (setq window-divider-default-bottom-width 1)
-  (setq window-divider-default-places 'right-only)
-  :hook (after-init . window-divider-mode))
-
-(use-package tab-bar
-  :unless noninteractive
-  :config
-  (setq-default tab-bar-close-button-show nil)
-  (setq-default tab-bar-close-last-tab-choice 'tab-bar-mode-disable)
-  (setq-default tab-bar-close-tab-select 'recent)
-  (setq-default tab-bar-new-tab-choice t)
-  (setq-default tab-bar-new-tab-to 'right)
-  (setq-default tab-bar-position nil)
-  (setq-default tab-bar-show t)
-  (setq-default tab-bar-tab-hints nil)
-  (setq-default tab-bar-tab-name-function 'vde/tab-bar-tab-name)
-
-  (defun vde/tab-bar-tab-name ()
-    "Generate tab name from the buffer of the selected window *or* projectile."
-    (cond
-     ((project-current) (let ((project-path (vde-project--project-current)))
-                          (cond ((string-prefix-p "~/src" project-path)
-                                 (directory-file-name (file-relative-name project-path "~/src")))
-                                ((string-prefix-p "~/desktop" project-path)
-                                 (directory-file-name (file-relative-name project-path "~/desktop")))
-                                ((string-prefix-p "/etc" project-path)
-                                 (directory-file-name (file-relative-name project-path "/etc")))
-                                (t
-                                 (file-relative-name project-path)))))
-     (t (tab-bar-tab-name-current-with-count))))
-
-  (defun vde/complete-tab-bar-tab-dwim ()
-    "Do-What-I-Mean function for getting to a `tab-bar-mode' tab.
-If no other tab exists, create one and switch to it.  If there is
-one other tab (so two in total) switch to it without further
-questions.  Else use completion to select the tab to switch to."
-    (interactive)
-    (let ((tabs (mapcar (lambda (tab)
-                          (alist-get 'name tab))
-                        (tab-bar--tabs-recent))))
-      (cond ((eq tabs nil)
-             (tab-new))
-            ((eq (length tabs) 1)
-             (tab-next))
-            (t
-             (tab-bar-switch-to-tab
-              (completing-read "Select tab: " tabs nil t))))))
-
-  :bind (("C-x t t" . vde/complete-tab-bar-tab-dwim)
-         ("C-x t s" . tab-switcher)
-	 ("C-<next>" . tab-next)
-	 ("C-<prior>" . tab-previous)))
-
-(use-package minions
-  :hook (after-init . minions-mode)
-  :config
-  (add-to-list 'minions-prominent-modes 'flymake-mode))
-
-(use-package time
-  :unless noninteractive
-  :config
-  (setq-default display-time-24hr-format t
-                display-time-day-and-date t
-                display-time-world-list '(("Europe/Paris" "Paris")
-                                          ("Europe/London" "London")
-                                          ("America/New_York" "Boston")
-                                          ("America/Los_Angeles" "San Francisco")
-                                          ("Asia/Calcutta" "Bangalore")
-                                          ("Australia/Brisbane" "Brisbane"))
-                display-time-string-forms
-                '((format "%s %s %s, %s:%s"
-                          dayname
-                          monthname day
-                          24-hours minutes)))
-  (display-time))
-
-(use-package tooltip
-  :unless noninteractive
-  :config
-  (setq tooltip-delay 0.5)
-  (setq tooltip-short-delay 0.5)
-  (setq x-gtk-use-system-tooltips nil)
-  (setq tooltip-frame-parameters
-        '((name . "tooltip")
-          (internal-border-width . 6)
-          (border-width . 0)
-          (no-special-glyphs . t)))
-  :hook (after-init . tooltip-mode))
-
-(use-package alert
-  :init
-  (defun alert-after-finish-in-background (buf str)
-    (when (or (not (get-buffer-window buf 'visible)) (not (frame-focus-state)))
-      (alert str :buffer buf)))
-  :config
-  (setq alert-default-style 'libnotify))
-
-(provide 'config-appearance)
-;;; config-appearance.el ends here
tools/emacs/config/config-buffers.el
@@ -1,109 +0,0 @@
-;;; config-buffers.el --- -*- lexical-binding: t; -*-
-;;; Commentary:
-;;; Buffer related configurations
-;;; Code:
-
-(use-package savehist
-  :unless noninteractive
-  :hook (after-init . savehist-mode)
-  :init
-  (setq savehist-file (no-littering-expand-var-file-name "savehist"))
-  :config
-  (setq-default history-length 10000
-                savehist-save-minibuffer-history t
-		savehist-delete-duplicates t
-                savehist-autosave-interval 180
-                savehist-additional-variables '(extended-command-history
-                                                search-ring
-                                                regexp-search-ring
-                                                comint-input-ring
-                                                compile-history
-                                                last-kbd-macro
-                                                shell-command-history)))
-
-(use-package uniquify
-  :unless noninteractive
-  :config
-  (setq-default uniquify-buffer-name-style 'post-forward
-                uniquify-separator ":"
-                uniquify-ignore-buffers-re "^\\*"
-                uniquify-after-kill-buffer-p t))
-
-(use-package ibuffer
-  :unless noninteractive
-  :commands (ibuffer)
-  :bind (("C-x C-b" . ibuffer)
-         ([remap list-buffers] . ibuffer))
-  :config
-  (setq-default ibuffer-expert t
-                ibuffer-filter-group-name-face 'font-lock-doc-face
-                ibuffer-default-sorting-mode 'filename/process
-                ibuffer-use-header-line t
-                ibuffer-show-empty-filter-groups nil)
-  ;; Use human readable Size column instead of original one
-  (define-ibuffer-column size-h
-    (:name "Size" :inline t)
-    (cond
-     ((> (buffer-size) 1000000) (format "%7.1fM" (/ (buffer-size) 1000000.0)))
-     ((> (buffer-size) 1000) (format "%7.1fk" (/ (buffer-size) 1000.0)))
-     (t (format "%8d" (buffer-size)))))
-
-  ;; (setq ibuffer-formats
-  ;;       '((mark modified read-only " "
-  ;;               (name 18 18 :left :elide)
-  ;;               " "
-  ;;               (size-h 9 -1 :right)
-  ;;               " "
-  ;;               (mode 16 16 :left :elide)
-  ;;               " "
-  ;;               filename-and-process)
-  ;;         (mark modified read-only " "
-  ;;               (name 18 18 :left :elide)
-  ;;               " "
-  ;;               (size 9 -1 :right)
-  ;;               " "
-  ;;               (mode 16 16 :left :elide)
-  ;;               " "
-  ;;               (vc-status 16 16 :left)
-  ;;               " "
-  ;;               filename-and-process)))
-  )
-
-(use-package ibuffer-vc
-  :unless noninteractive
-  :commands (ibuffer-vc-set-filter-groups-by-vc-root)
-  :hook (ibuffer . (lambda ()
-                     (ibuffer-vc-set-filter-groups-by-vc-root)
-                     (unless (eq ibuffer-sorting-mode 'filename/process)
-                       (ibuffer-do-sort-by-filename/process)))))
-
-;; (unless noninteractive
-;;   (require 'popper)
-;;   (setq popper-reference-buffers
-;;         '("\\*Messages\\*"
-;;           "Output\\*$"
-;;           "\\*Async Shell Command\\*"
-;; 	  "\\*Warnings\\*"
-;; 	  "\\*Compile-Log\\*"
-;;           help-mode
-;; 	  helpful-mode
-;;           compilation-mode
-;; 	  flymake-diagnostics-buffer-mode
-;; 	  flymake-project-diagnostics-mode
-;; 	  Man-mode
-;; 	  woman-mode))
-;;   (global-set-key (kbd "C-`") 'popper-toggle)
-;;   (global-set-key (kbd "M-`") 'popper-cycle)
-;;   (global-set-key (kbd "C-M-`") 'popper-toggle-type)
-;;   (popper-mode +1)
-;; 
-;;   ;; For echo-area hints
-;;   (require 'popper-echo)
-;;   (popper-echo-mode +1))
-
-(use-package goto-addr
-  :hook ((text-mode . goto-address-mode)
-         (prog-mode . goto-address-prog-mode)))
-
-(provide 'config-buffers)
-;;; config-buffers.el ends here
tools/emacs/config/config-compile.el
@@ -1,104 +0,0 @@
-;;; config-compile.el --- -*- lexical-binding: t; -*-
-;;; Commentary:
-;;; Generic compilation configuration
-;;; Code:
-
-(defun my-recompile (args)
-  (interactive "P")
-  (cond
-   ((eq major-mode #'emacs-lisp-mode)
-    (call-interactively 'eros-eval-defun))
-   ((bound-and-true-p my-vterm-command)
-    (my-vterm-execute-region-or-current-line my-vterm-command))
-   ((get-buffer "*compilation*")
-    (with-current-buffer"*compilation*"
-      (recompile)))
-   ((get-buffer "*Go Test*")
-    (with-current-buffer "*Go Test*"
-      (recompile)))
-   ((and (eq major-mode #'go-mode)
-         buffer-file-name
-         (string-match
-          "_test\\'" (file-name-sans-extension buffer-file-name)))
-    (my-gotest-maybe-ts-run))
-   ((and (get-buffer "*cargo-test*")
-         (boundp 'my-rustic-current-test-compile)
-         my-rustic-current-test-compile)
-    (with-current-buffer "*cargo-test*"
-      (rustic-cargo-test-run my-rustic-current-test-compile)))
-   ((get-buffer "*cargo-run*")
-    (with-current-buffer "*cargo-run*"
-      (rustic-cargo-run-rerun)))
-   ((get-buffer "*pytest*")
-    (with-current-buffer "*pytest*"
-      (recompile)))
-   ((eq major-mode #'python-mode)
-    (compile (concat python-shell-interpreter " " (buffer-file-name))))
-   ((call-interactively 'compile))))
-
-;; UseCompile
-(use-package compile
-  :unless noninteractive
-  :commands (compile)
-  :preface
-  (autoload 'ansi-color-apply-on-region "ansi-color")
-
-  (defvar compilation-filter-start)
-
-  (defun vde/colorize-compilation-buffer ()
-    (unless (or (derived-mode-p 'grep-mode)
-                (derived-mode-p 'ag-mode)
-                (derived-mode-p 'rg-mode))
-      (let ((inhibit-read-only t))
-        (ansi-color-apply-on-region compilation-filter-start (point)))))
-  :config
-  (setq-default compilation-scroll-output t
-                ;; I'm not scared of saving everything.
-                compilation-ask-about-save nil
-                ;; Automatically scroll and jump to the first error
-                ;; compilation-scroll-output 'next-error
-                ;; compilation-scroll-output 'first-error
-                ;; compilation-auto-jump-to-first-error t
-                ;; Skip over warnings and info messages in compilation
-                compilation-skip-threshold 2
-                ;; Don't freeze when process reads from stdin
-                compilation-disable-input t
-                ;; Show three lines of context around the current message
-                compilation-context-lines 3
-                )
-  (add-hook 'compilation-finish-functions #'alert-after-finish-in-background)
-  (add-hook 'comint-output-filter-functions
-            'comint-watch-for-password-prompt)
-  (setq-default comint-password-prompt-regexp
-                (concat
-                 "\\("
-                 "^Enter passphrase.*:"
-                 "\\|"
-                 "^Repeat passphrase.*:"
-                 "\\|"
-                 "[Pp]assword for '[a-z0-9_-.]+':"
-                 "\\|"
-                 "\\[sudo\\] [Pp]assword for [a-z0-9_-.]+:"
-                 "\\|"
-                 "[a-zA-Z0-9]'s password:"
-                 "\\|"
-                 "^[Pp]assword:"
-                 "\\|"
-                 "^[Pp]assword (again):"
-                 "\\|"
-                 ".*\\([Ww]ork\\|[Pp]ersonal\\).* password:"
-                 "\\|"
-                 "Password for '([^()]+)' GNOME keyring"
-                 "\\|"
-                 "Password for 'http.*github.*':"
-                 "\\)"))
-  (add-hook 'compilation-filter-hook #'vde/colorize-compilation-buffer))
-
-(use-package emacs
-  :bind
-  (:map prog-mode-map
-        ("C-M-<return>" . compile)
-        ("C-<return>"   . my-recompile)))
-
-(provide 'config-compile)
-;;; config-compile.el ends here
tools/emacs/config/config-completion.el
@@ -1,342 +0,0 @@
-;;; config-completion.el --- -*- lexical-binding: t -*-
-;;; Commentary:
-;;; Setup completion framework
-;;; Code
-
-(use-package which-key
-  :custom
-  (which-key-separator " → " )
-  :hook
-  (after-init . which-key-mode)
-  :config
-  
-  ;; Define custom, concise descriptions for `tab-bar` commands under "C-x t"
-  (which-key-add-key-based-replacements
-    "C-x t C-f" "Open file in new tab"
-    "C-x t RET" "Switch tabs"
-    "C-x t C-r" "Open file (read-only) in new tab"
-    "C-x t 0"   "Close current tab"
-    "C-x t 1"   "Close other tabs"
-    "C-x t 2"   "New empty tab"
-    "C-x t G"   "Group tabs"
-    "C-x t M"   "Move tab to position"
-    "C-x t N"   "New tab and switch to it"
-    "C-x t O"   "Previous tab"
-    "C-x t b"   "Switch buffer in new tab"
-    "C-x t d"   "Dired in new tab"
-    "C-x t f"   "Open file in new tab"
-    "C-x t m"   "Move tab left/right"
-    "C-x t n"   "Duplicate tab"
-    "C-x t o"   "Next tab"
-    "C-x t p"   "Project in new tab"
-    "C-x t r"   "Rename tab"
-    "C-x t t"   "Switch to other tab"
-    "C-x t u"   "Undo tab close"
-    "C-x t ^ f" "Detach tab window"))
-
-(use-package consult
-  :bind
-  ("M-g M-g" . consult-goto-line)
-  ("M-K" . consult-keep-lines)
-  ("M-s M-b" . consult-buffer)
-  ("M-s M-f" . consult-find)
-  ("M-s M-g" . consult-grep)
-  ("M-s M-r" . consult-ripgrep)
-  ("M-s M-h" . consult-history)
-  ("M-s M-l" . consult-line)
-  ("M-s M-m" . consult-mark)
-  ("M-s M-y" . consult-yank-pop)
-  ("M-s M-s" . consult-outline)
-  :config
-  ;; (general-leader
-  ;;   "y"  #'(consult-yank-pop :which-key "Clipboard history")
-  ;;   "b"  '(:ignore t :which-key "buffer")
-  ;;   "bb" #'(consult-buffer :which-key "switch buffer")
-  ;;   "bd" #'(kill-current-buffer :which-key "kill buffer")
-  ;;   "bD" #'((lambda ()(interactive)(kill-current-buffer)(tab-close)) :wk "Kill buffer and tab")
-  ;;   "bn" #'(next-buffer :which-key "next buffer")
-  ;;   "bp" #'(previous-buffer :which-key "previous buffer")
-  ;;   "s"  '(:ignore t :which-key "search")
-  ;;   "sg" #'(consult-grep :which-key "Consult grep in current directory")
-  ;;   "sR" #'(consult-ripgrep :which-key "Consult ripgrep in current directory")
-  ;;   "sr" '(:ignore t :which-key "rg.el")'
-  ;;   "srp" #'(rg-project :which-key "rg.el in current project")
-  ;;   "srs" #'(rg-dwim :which-key "rg.el Do What I Mean")
-  ;;   "sh"  #'(Info-goto-emacs-command-node :wk "Search help")
-  ;;   "sc"  #'(consult-mode-command :wk "Mode Command")
-  ;;   "s/"  #'(consult-isearch-history :wk "Consult Isearch history")
-  ;;   "g"  '(:ignore t :which-key "go")
-  ;;   "gu" #'(ffap-next-url :which-key "next url")
-  ;;   "gd" #'(xref-find-definitions :which-key "find definition")
-  ;;   "gD" #'(xref-find-definitions-other-window :which-key "find definition (other window)"))
-  )
-
-(use-package consult-imenu
-  :after (consult)
-  :commands (consult-imenu)
-  :bind
-  ("M-s M-i" . consult-imenu))
-
-(use-package consult-xref
-  :after (consult)
-  :commands (consult-xref)
-  :config
-  (setq xref-show-xrefs-function #'consult-xref
-        xref-show-definitions-function #'consult-xref)
-  (defvar consult--xref-history nil
-    "History for the `consult-recent-xref' results.")
-
-  (defun consult-recent-xref (&optional markers)
-    "Jump to a marker in MARKERS list (defaults to `xref--history'.
-
-The command supports preview of the currently selected marker position.
-The symbol at point is added to the future history."
-    (interactive)
-    (consult--read
-     (consult--global-mark-candidates
-      (or markers (flatten-list xref--history)))
-     :prompt "Go to Xref: "
-     :annotate (consult--line-prefix)
-     :category 'consult-location
-     :sort nil
-     :require-match t
-     :lookup #'consult--lookup-location
-     :history '(:input consult--xref-history)
-     :add-history (thing-at-point 'symbol)
-     :state (consult--jump-state))))
-
-;; https://github.com/oantolin/embark/blob/master/embark-consult.el
-(use-package embark
-  :unless noninteractive
-  :commands (emark-act embark-dwim embark-prefix-help-command)
-  :bind
-  ("C-." . embark-act)
-  ("M-." . embark-dwim)
-  ("C-h b" . embark-bindings)
-  ("C-h B" . embark-bindings-at-point)
-  ("C-h M" . embark-bindings-in-keymap)
-  ("C-h E" . embark-on-last-message)
-  (:map completion-list-mode-map
-        ("." . embark-act))
-  (:map embark-collect-mode-map
-        ("a") ; I don't like my own default :)
-        ("." . embark-act)
-        ("F" . consult-focus-lines))
-  (:map embark-package-map
-        ("t" . try))
-  (:map embark-identifier-map
-        ("(" . insert-parentheses)
-        ("[" . insert-pair-map))
-  (:map embark-expression-map
-        ("(" . insert-parentheses)
-        ("[" . insert-pair-map))
-  (:map embark-region-map
-        ("(" . insert-parentheses)
-        ("[" . insert-pair-map)
-        ("D" . dictionary-search))
-  (:map embark-email-map
-        ("+" . add-email-to-ecomplete)
-        ("\\" . remove-email-from-ecomplete))
-  (:map embark-encode-map
-        ("p" . topaz-paste-region))
-  (:map embark-url-map
-        ("x" . browse-url-generic)
-        ("p" . pocket-lib-add-urls))
-  (:map embark-identifier-map
-        ("D" . dictionary-lookup-definition))
-  :custom
-  (embark-quit-after-action t)
-  (prefix-help-command #'embark-prefix-help-command)
-  (embark-indicators '(embark-minimal-indicator
-                       embark-highlight-indicator
-                       embark-isearch-highlight-indicator))
-  (embark-cycle-key ".")
-  (embark-help-key "?")
-  (embark-confirm-act-all nil)
-  :config
-  (setq embark-candidate-collectors
-        (cl-substitute 'embark-sorted-minibuffer-candidates
-                       'embark-minibuffer-candidates
-                       embark-candidate-collectors))
-  (dolist (cmd '(comment-dwim
-                 insert-parentheses
-                 insert-pair
-                 markdown-insert-code
-                 markdown-insert-italic
-                 markdown-insert-bold
-                 org-emphasize
-                 cdlatex-math-modify
-                 TeX-font))
-    (push #'embark--mark-target (alist-get cmd embark-around-action-hooks)))
-  (push #'embark--xref-push-marker
-        (alist-get 'find-file embark-pre-action-hooks))
-  (defun embark-on-last-message (arg)
-    "Act on the last message displayed in the echo area."
-    (interactive "P")
-    (with-current-buffer "*Messages*"
-      (goto-char (1- (point-max)))
-      (embark-act arg)))
-
-  (defmacro ct/embark-display-in-side-window (side)
-    `(defun ,(intern (concat "display-in-side-window--" (symbol-name side))) (&optional buffer)
-       (interactive "b")
-       (when-let* ((buffer (or buffer (current-buffer)))
-                   (display-buffer-overriding-action '((display-buffer-in-side-window)
-                                                       (dedicated . t)
-                                                       (side . ,side)
-                                                       (window-parameters . ((no-delete-other-windows . t))))))
-	 (display-buffer buffer))))
-  (define-key embark-buffer-map (kbd "s b") (ct/embark-display-in-side-window bottom))
-  (define-key embark-buffer-map (kbd "s l") (ct/embark-display-in-side-window left))
-  (define-key embark-buffer-map (kbd "s r") (ct/embark-display-in-side-window right))
-  
-  (defun embark-which-key-indicator ()
-    "An embark indicator that displays keymaps using which-key.
-The which-key help message will show the type and value of the
-current target followed by an ellipsis if there are further
-targets."
-    (lambda (&optional keymap targets prefix)
-      (if (null keymap)
-          (which-key--hide-popup-ignore-command)
-	(which-key--show-keymap
-	 (if (eq (plist-get (car targets) :type) 'embark-become)
-             "Become"
-           (format "Act on %s '%s'%s"
-                   (plist-get (car targets) :type)
-                   (embark--truncate-target (plist-get (car targets) :target))
-                   (if (cdr targets) "…" "")))
-	 (if prefix
-             (pcase (lookup-key keymap prefix 'accept-default)
-               ((and (pred keymapp) km) km)
-               (_ (key-binding prefix 'accept-default)))
-           keymap)
-	 nil nil t (lambda (binding)
-                     (not (string-suffix-p "-argument" (cdr binding))))))))
-
-  (setq embark-indicators
-	'(embark-which-key-indicator
-	  embark-highlight-indicator
-	  embark-isearch-highlight-indicator))
-
-  (defun embark-hide-which-key-indicator (fn &rest args)
-    "Hide the which-key indicator immediately when using the completing-read prompter."
-    (which-key--hide-popup-ignore-command)
-    (let ((embark-indicators
-           (remq #'embark-which-key-indicator embark-indicators)))
-      (apply fn args)))
-
-  (advice-add #'embark-completing-read-prompter
-              :around #'embark-hide-which-key-indicator))
-
-(use-package embark-consult
-  :after (embark consult)
-  :unless noninteractive
-  :hook
-  (embark-collect-mode . consult-preview-at-point-mode))
-
-(setq minibuffer-prompt-properties
-      '(read-only t cursor-intangible t face minibuffer-prompt))
-(add-hook 'minibuffer-setup-hook #'cursor-intangible-mode)
-
-(use-package emacs
-  :unless noninteractive
-  :custom
-  (completion-cycle-threshold 2)
-  (completion-ignore-case t)
-  (completion-show-inline-help nil)
-  (completions-detailed t)
-  (enable-recursive-minibuffers t)
-  (read-buffer-completion-ignore-case t)
-  (read-file-name-completion-ignore-case t)
-  (resize-mini-windows t)
-  (tab-always-indent 'complete)
-  :config
-  (minibuffer-depth-indicate-mode 1)
-  (minibuffer-electric-default-mode 1))
-
-(use-package vertico
-  :unless noninteractive
-  :hook (after-init . vertico-mode))
-
-(use-package marginalia
-  :unless noninteractive
-  :hook (after-init . marginalia-mode))
-
-(use-package corfu
-  :unless noninteractive
-  :bind (("C-<tab>" . corfu-candidate-overlay-complete-at-point))
-  :hook (after-init . global-corfu-mode)
-  :init
-  (require 'corfu-popupinfo)
-  (require 'corfu-history)
-  (require 'corfu-candidate-overlay)
-  :config
-  (setq corfu-popupinfo-delay '(1.25 . 0.5))
-  (corfu-popupinfo-mode 1)
-  (corfu-candidate-overlay-mode)
-  ;; Sort by input history (no need to modify `corfu-sort-function').
-  (with-eval-after-load 'savehist
-    (corfu-history-mode 1)
-    (add-to-list 'savehist-additional-variables 'corfu-history))
-
-  ;; Adapted from Corfu's manual.
-  (defun contrib/corfu-enable-always-in-minibuffer ()
-    "Enable Corfu in the minibuffer if MCT or Vertico is not active.
-Useful for prompts such as `eval-expression' and `shell-command'."
-    (unless (or (bound-and-true-p vertico--input)
-                (bound-and-true-p mct--active))
-      (corfu-mode 1)))
-
-  (add-hook 'minibuffer-setup-hook #'contrib/corfu-enable-always-in-minibuffer 1))
-
-;; Seems like it is a bit impacting the performance somehow.
-;; (use-package corfu-candidate-overlay
-;;   :after corfu
-;;   :bind (("C-<tab>" . corfu-candidate-overlay-complete-at-point))
-;;   :config
-;;   (corfu-candidate-overlay-mode +1))
-
-(use-package cape
-  :bind (("C-c p f" . cape-file)
-         ("C-c p /" . cape-dabbrev)
-         :map corfu-map
-         ("M-/" . cape-dabbrev)
-         ("C-x C-f" . cape-file))
-  :config
-  (add-to-list 'completion-at-point-functions #'cape-file))
-
-(use-package orderless
-  :unless noninteractive
-  :config
-  (setq completion-styles
-	'(orderless basic substring initials flex partial-completion))
-  (setq completion-category-defaults nil)
-  (setq completion-category-overrides nil)
-  )
-
-(use-package tempel
-  :bind (("M-+" . tempel-complete) ;; Alternative tempel-expand
-         ("M-*" . tempel-insert))
-  :init
-  ;; (defun tempel-setup-capf ()
-  ;;   ;; Add the Tempel Capf to `completion-at-point-functions'.
-  ;;   ;; `tempel-expand' only triggers on exact matches. Alternatively use
-  ;;   ;; `tempel-complete' if you want to see all matches, but then you
-  ;;   ;; should also configure `tempel-trigger-prefix', such that Tempel
-  ;;   ;; does not trigger too often when you don't expect it. NOTE: We add
-  ;;   ;; `tempel-expand' *before* the main programming mode Capf, such
-  ;;   ;; that it will be tried first.
-  ;;   (setq-local completion-at-point-functions
-  ;;               (cons #'tempel-expand
-  ;;                     completion-at-point-functions)))
-  (setq tempel-path (expand-file-name "templates" user-emacs-directory))
-  ;; (add-hook 'conf-mode-hook 'tempel-setup-capf)
-  ;; (add-hook 'prog-mode-hook 'tempel-setup-capf)
-  ;; (add-hook 'text-mode-hook 'tempel-setup-capf)
-  )
-
-(use-package tempel-collection
-  :after tempel)
-
-(provide 'config-completion)
-;;; config-completion.el ends here
tools/emacs/config/config-dired.el
@@ -1,244 +0,0 @@
-;;; config-dired.el --  -*- lexical-binding: t; -*-
-;;; Commentary:
-;;; Configuration of Dired
-;;; Code:
-
-(defun my-substspaces (str)
-  (subst-char-in-string ?\s ?_ str))
-
-(defmacro vde/dired-fd (name doc prompt &rest flags)
-  "Make commands for selecting 'fd' results with completion.
-NAME is how the function should be named.  DOC is the function's
-documentation string.  PROMPT describes the scope of the query.
-FLAGS are the command-line arguments passed to the 'fd'
-executable, each of which is a string."
-  `(defun ,name (&optional arg)
-     ,doc
-     (interactive "P")
-     (let* ((vc (vc-root-dir))
-            (dir (expand-file-name (if vc vc default-directory)))
-            (regexp (read-regexp
-                     (format "%s matching REGEXP in %s: " ,prompt
-                             (propertize dir 'face 'bold))))
-            (names (process-lines "fd" ,@flags regexp dir))
-            (buf "*FD Dired*"))
-       (if names
-           (if arg
-               (dired (cons (generate-new-buffer-name buf) names))
-	     (find-file
-	      (completing-read (format "Items matching %s (%s): "
-				       (propertize regexp 'face 'success)
-				       (length names))
-			       names nil t))))
-       (user-error (format "No matches for « %s » in %s" regexp dir)))))
-
-(use-package dired
-  :unless noninteractive
-  :commands (dired find-name-dired)
-  :hook ((dired-mode . dired-hide-details-mode)
-	 (dired-mode . toggle-truncate-lines)
-	 (dired-mode . hl-line-mode))
-  :bind (("C-c RET" . vde/open-in-external-app)
-         ("C-c f g" . vde/dired-get-size)
-         ("M-s d" . vde/dired-fd-dirs)
-         ("M-s z" . vde/dired-fd-files-and-dirs)
-         ("C-c f f"    . find-name-dired)
-         (:map dired-mode-map
-               ("M-p"         . vde/dired-up)
-               ("^"           . vde/dired-up)
-               ("<backspace>" . vde/dired-up)
-               ("M-n"         . vde/dired-down)
-               ("!"           . vde/sudired)
-               ("<prior>"     . beginend-dired-mode-goto-beginning)
-               ("<next>"      . beginend-dired-mode-goto-end)
-	       ("b"           . dired-do-open)))
-  :config
-  (setq-default dired-auto-revert-buffer t
-                dired-recursive-copies 'always
-                dired-recursive-deletes 'always
-                dired-isearch-filenames 'dwim
-                delete-by-moving-to-trash t
-                dired-listing-switches "-lFaGh1v --group-directories-first"
-                dired-ls-F-marks-symlinks t
-                dired-dwim-target t)
-
-  (when (string= system-type "darwin")
-    (setq dired-use-ls-dired t
-          insert-directory-program "/usr/local/bin/gls"))
-
-  ;; Enable dired-find-alternate-file
-  (put 'dired-find-alternate-file 'disabled nil)
-
-  (defun vde/dired-substspaces (&optional arg)
-    "Rename all marked (or next ARG) files so that spaces are replaced with underscores."
-    (interactive "P")
-    (dired-rename-non-directory #'my-substspaces "Rename by substituting spaces" arg))
-  (if (keymap-lookup dired-mode-map "% s")
-    (message "Error: %% s already defined in dired-mode-map")
-  (define-key dired-mode-map "%s" 'vde/dired-substspaces))
-
-  (defun vde/dired-up ()
-    "Go to previous directory."
-    (interactive)
-    (find-alternate-file ".."))
-
-  (defun vde/dired-down ()
-    "Enter directory."
-    (interactive)
-    (dired-find-alternate-file))
-
-  (defun vde/open-in-external-app ()
-    "Open the file(s) at point with an external application."
-    (interactive)
-    (let* ((file-list
-            (dired-get-marked-files)))
-      (mapc
-       (lambda (file-path)
-         (let ((process-connection-type nil))
-           (start-process "" nil "xdg-open" file-path))) file-list)))
-
-  (defun find-file-reuse-dir-buffer ()
-    "Like `dired-find-file', but reuse Dired buffers."
-    (interactive)
-    (set-buffer-modified-p nil)
-    (let ((file (dired-get-file-for-visit)))
-      (if (file-directory-p file)
-          (find-alternate-file file)
-        (find-file file))))
-
-  (defun vde/sudired ()
-    "Open directory with sudo in Dired."
-    (interactive)
-    (require 'tramp)
-    (let ((dir (expand-file-name default-directory)))
-      (if (string-match "^/sudo:" dir)
-          (user-error "Already in sudo")
-        (dired (concat "/sudo::" dir)))))
-
-  (defun vde/dired-get-size ()
-    "Quick and easy way to get file size in Dired."
-    (interactive)
-    (let ((files (dired-get-marked-files)))
-      (with-temp-buffer
-        (apply 'call-process "du" nil t nil "-sch" files)
-        (message
-         "Size of all marked files: %s"
-         (progn
-           (re-search-backward "\\(^[0-9.,]+[A-Za-z]+\\).*total$")
-           (match-string 1))))))
-
-  (vde/dired-fd
-   vde/dired-fd-dirs
-   "Search for directories in VC root or PWD.
-With \\[universal-argument] put the results in a `dired' buffer.
-This relies on the external 'fd' executable."
-   "Subdirectories"
-   "-i" "-H" "-a" "-t" "d" "-c" "never")
-
-  (vde/dired-fd
-   vde/dired-fd-files-and-dirs
-   "Search for files and directories in VC root or PWD.
-With \\[universal-argument] put the results in a `dired' buffer.
-This relies on the external 'fd' executable."
-   "Files and dirs"
-   "-i" "-H" "-a" "-t" "d" "-t" "f" "-c" "never")
-  )
-
-(use-package find-dired
-  :after dired
-  :commands (find-name-dired)
-  :config
-  (setq-default find-ls-option ;; applies to `find-name-dired'
-                '("-ls" . "-AFhlv --group-directories-first")
-                find-name-arg "-iname"))
-
-(use-package dired-x
-  :after dired
-  :bind (("C-x C-j" . dired-jump))
-  :commands (dired-jump dired-omit-mode)
-  :config
-  (setq-default dired-omit-files (concat dired-omit-files "\\|^\\.+$\\|^\\..+$")
-                dired-omit-verbose nil
-                dired-clean-confirm-killing-deleted-buffers nil))
-
-(use-package dired-aux
-  :unless noninteractive
-  :after dired
-  :config
-  (setq-default
-   ;; Ask for creation of missing directories when copying/moving
-   dired-create-destination-dirs 'ask
-   dired-create-destination-dirs-on-trailing-dirsep t
-   ;; Search only file names when point is on a file name
-   dired-isearch-filenames'dwim))
-
-(use-package async)
-(use-package dired-async
-  :unless noninteractive
-  :after (dired async)
-  :commands (dired-async-mode)
-  :hook (dired-mode . dired-async-mode))
-
-(use-package dired-narrow
-  :unless noninteractive
-  :after dired
-  :commands (dired-narrow)
-  :bind (:map dired-mode-map
-              ("M-s n" . dired-narrow))
-  :config
-  (setq-default dired-narrow-exit-when-one-left t
-                dired-narrow-enable-blinking t
-                dired-narrow-blink-time 0.3))
-
-(use-package wdired
-  :unless noninteractive
-  :after dired
-  :commands (wdired-mode
-             wdired-change-to-wdired-mode)
-  :bind (:map dired-mode-map
-	      ("E" . wdired-change-to-wdired-mode))
-  :config
-  (setq-default wdired-allow-to-change-permissions t
-                wdired-create-parent-directories t))
-
-(use-package dired-rsync
-  :unless noninteractive
-  :after dired
-  :commands (dired-rsync)
-  :bind (:map dired-mode-map
-              ("r" . dired-rsync)))
-
-(use-package trashed
-  :unless noninteractive
-  :commands (trashed)
-  :config
-  (setq trashed-action-confirmer 'y-or-n-p)
-  (setq trashed-use-header-line t)
-  (setq trashed-sort-key '("Date deleted" . t))
-  (setq trashed-date-format "%Y-%m-%d %H:%M:%S"))
-
-;; (use-package dired-sidebar
-;;   :unless noninteractive
-;;   :commands (dired-sidebar-toggle-sidebar)
-;;   :bind ("C-c C-n" . dired-sidebar-toggle-sidebar)
-;;   :init
-;;   (add-hook 'dired-sidebar-mode-hook
-;;             (lambda ()
-;;               (unless (file-remote-p default-directory)
-;;                 (auto-revert-mode))))
-;;   :config
-;;   (push 'toggle-window-split dired-sidebar-toggle-hidden-commands)
-;;   (push 'rotate-windows dired-sidebar-toggle-hidden-commands)
-;; 
-;;   ;; (setq dired-sidebar-subtree-line-prefix "__")
-;;   ;;(setq dired-sidebar-use-custom-font t)
-;;   (setq dired-sidebar-theme 'arrow)
-;;   (setq dired-sidebar-use-term-integration t))
-
-(use-package casual-dired
-  :after dired
-  :commands (casual-dired-tmenu)
-  :bind (:map dired-mode-map ("C-o" . 'casual-dired-tmenu)))
-
-(provide 'config-dired)
-;; config-dired.el ends here
tools/emacs/config/config-editing.el
@@ -1,164 +0,0 @@
-;;; config-editing.el --- -*- lexical-binding: t; -*-
-;; Time-stamp: <Last changed 2025-05-07 22:55:12 by vincent>
-;;; Commentary:
-;;; Editing configuration
-;;; Code:
-
-(setq-default enable-remote-dir-locals t)
-
-;; When finding file in non-existing directory, offer to create the
-;; parent directory.
-(defun with-buffer-name-prompt-and-make-subdirs ()
-  (let ((parent-directory (file-name-directory buffer-file-name)))
-    (when (and (not (file-exists-p parent-directory))
-               (y-or-n-p (format "Directory `%s' does not exist! Create it? " parent-directory)))
-      (make-directory parent-directory t))))
-
-(add-to-list 'find-file-not-found-functions #'with-buffer-name-prompt-and-make-subdirs)
-
-;; Fix long line "problems"
-;; Disable some right-to-left behavior that might not be needed.
-;; Learning arabic might make me change this, but for now..
-(setq-default bidi-paragraph-direction 'left-to-right)
-(if (version<= "27.1" emacs-version)
-    (setq bidi-inhibit-bpa t))
-;; Detect if the line in a buffer are so long they could have a performance impact
-(if (version<= "27.1" emacs-version)
-    (global-so-long-mode 1))
-
-(use-package saveplace
-  :unless noninteractive
-  :config
-  (save-place-mode 1))
-
-(use-package vundo
-  :bind (("M-u"   . undo)
-         ("M-U"   . undo-redo)
-         ("C-x u" . vundo)))
-
-(use-package whitespace
-  :unless noninteractive
-  :commands (whitespace-mode vde/toggle-invisibles)
-  :config
-  (setq-default whitespace-style '(face tabs spaces trailing space-before-tab newline indentation empty space-after-tab space-mark tab-mark newline-mark))
-  (defun vde/toggle-invisibles ()
-    "Toggles the display of indentation and space characters."
-    (interactive)
-    (if (bound-and-true-p whitespace-mode)
-        (whitespace-mode -1)
-      (whitespace-mode)))
-  :bind ("<f6>" . vde/toggle-invisibles))
-
-(use-package easy-kill
-  :unless noninteractive
-  :commands (easy-kill easy-mark)
-  :bind
-  (([remap kill-ring-save] . easy-kill)
-   ([remap mark-sexp] . easy-mark)
-   ("M-r" . easy-mark)))
-
-(use-package display-line-numbers
-  :unless noninteractive
-  :hook (prog-mode . display-line-numbers-mode)
-  :config
-  (setq-default display-line-numbers-type 'relative)
-  (defun vde/toggle-line-numbers ()
-    "Toggles the display of line numbers.  Applies to all buffers."
-    (interactive)
-    (if (bound-and-true-p display-line-numbers-mode)
-        (display-line-numbers-mode -1)
-      (display-line-numbers-mode)))
-  :bind ("<f7>" . vde/toggle-line-numbers))
-
-(add-hook 'prog-mode-hook 'toggle-truncate-lines)
-
-;; (use-package comment-dwim-2
-;;   :bind (([remap comment-dwim] . comment-dwim-2)))
-(use-package newcomment
-  :unless noninteractive
-  :config
-  (setq-default comment-empty-lines t
-                comment-fill-column nil
-                comment-multi-line t
-                comment-style 'multi-line)
-  (defun prot/comment-dwim (&optional arg)
-    "Alternative to `comment-dwim': offers a simple wrapper
-around `comment-line' and `comment-dwim'.
-
-If the region is active, then toggle the comment status of the
-region or, if the major mode defines as much, of all the lines
-implied by the region boundaries.
-
-Else toggle the comment status of the line at point."
-    (interactive "*P")
-    (if (use-region-p)
-        (comment-dwim arg)
-      (save-excursion
-        (comment-line arg))))
-
-  :bind (("C-;" . prot/comment-dwim)
-         ("C-:" . comment-kill)
-         ("M-;" . comment-indent)
-         ("C-x C-;" . comment-box)))
-
-(use-package delsel
-  :unless noninteractive
-  :config
-  (delete-selection-mode 1))
-
-(use-package emacs
-  :unless noninteractive
-  :custom
-  (repeat-on-final-keystroke t)
-  (set-mark-command-repeat-pop t)
-  :bind (("M-z" . zap-up-to-char)
-	 ("M-S-<up>" . duplicate-dwim)))
-
-(use-package visual-regexp
-  :unless noninteractive
-  :commands (vr/replace vr/query-replace)
-  :bind (("C-c r"   . vr/replace)
-         ("C-c %"   . vr/query-replace)))
-
-(use-package emacs
-  :config
-  :bind (("M-SPC" . cycle-spacing)
-         ("M-o" . delete-blank-lines)
-         ("<C-f6>" . tear-off-window)))
-
-(use-package subword
-  :diminish
-  :hook (prog-mode-hook . subword-mode))
-
-(use-package surround
-  :bind-keymap ("M-'" . surround-keymap))
-
-(use-package substitute
-  :bind (("M-<insert> s" . substitute-target-below-point)
-	 ("M-<insert> r" . substitute-target-above-point)
-	 ("M-<insert> d" . substitute-target-in-defun)
-	 ("M-<insert> b" . substitute-target-in-buffer)))
-
-(use-package jinx
-  :hook (emacs-startup . global-jinx-mode)
-  :bind (([remap ispell-word] . jinx-correct) ;; ("M-$" . jinx-correct)
-         ("C-M-$" . jinx-languages)))
-
-(use-package re-builder)
-(use-package casual-re-builder
-  :bind (:map
-	 reb-mode-map ("C-o" . casual-re-builder-tmenu)
-	 :map
-	 reb-lisp-mode-map ("C-o" . casual-re-builder-tmenu))
-  :after (re-builder))
-
-(use-package time-stamp
-  :custom
-  (time-stamp-active t)
-  (time-stamp-line-limit 10)     ; Check first 10 buffer lines for Time-stamp: <>
-  (time-stamp-format "Last changed %Y-%02m-%02d %02H:%02M:%02S by %u")
-  :hook
-  (before-save . time-stamp))
-
-(provide 'config-editing)
-;;; config-editing.el ends here
tools/emacs/config/config-emms.el
@@ -1,78 +0,0 @@
-;;; config-emms.el --- EMMS configuration to play music from Emacs -*- lexical-binding: t -*-
-
-;; Author: Vincent Demeester
-
-;; This file is not part of GNU Emacs
-
-;; This program is free software: you can redistribute it and/or modify
-;; it under the terms of the GNU General Public License as published by
-;; the Free Software Foundation, either version 3 of the License, or
-;; (at your option) any later version.
-
-;; This program is distributed in the hope that it will be useful,
-;; but WITHOUT ANY WARRANTY; without even the implied warranty of
-;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-;; GNU General Public License for more details.
-
-;; You should have received a copy of the GNU General Public License
-;; along with this program.  If not, see <https://www.gnu.org/licenses/>.
-
-;;; Commentary:
-
-;; This configuration is used for controlling playing music from Emacs.
-
-;;; Code:
-
-(use-package emms
-  :custom
-  (emms-player-list '(emms-player-mpv))
-  (emms-source-file-default-directory "~/desktop/music")
-  (emms-player-mpv-parameters '("--quiet" "--really-quiet" "--no-audio-display" "--force-window=no" "--vo=null"))
-  :config
-  (require 'emms-source-file)
-  (require 'emms-source-playlist)
-  (require 'emms-player-simple)
-  (require 'emms-player-mpv)
-  (require 'emms-playlist-mode)
-  (require 'emms-info)
-  (require 'emms-info-mp3info)
-  (require 'emms-info-ogginfo)
-  (require 'emms-info-opusinfo)
-  (require 'emms-info-metaflac)
-  (require 'emms-info-tinytag)
-  (require 'emms-info-exiftool)
-  (require 'emms-info-native)
-  (require 'emms-cache)
-  (require 'emms-mode-line)
-  (require 'emms-mark)
-  (require 'emms-show-all)
-  (require 'emms-streams)
-  (require 'emms-playing-time)
-  (require 'emms-browser)
-  (require 'emms-mode-line-icon)
-  (require 'emms-cue)
-  (require 'emms-bookmarks)
-  (require 'emms-last-played)
-  (require 'emms-metaplaylist-mode)
-  (require 'emms-stream-info)
-  (require 'emms-history)
-  (require 'emms-i18n)
-  (require 'emms-volume)
-  (require 'emms-playlist-limit)
-  (require 'emms-mpris)
-  (require 'emms-idapi-musicbrainz)
-  (require 'emms-idapi-browser)
-  
-  (setq emms-playlist-default-major-mode #'emms-playlist-mode)
-  (add-to-list 'emms-track-initialize-functions #'emms-info-initialize-track)
-  (setq emms-info-functions '(emms-info-native emms-info-cueinfo))
-  (setq emms-track-description-function #'emms-info-track-description)
-  (when (fboundp 'emms-cache)		; work around compiler warning
-    (emms-cache 1))
-  (emms-mode-line-mode 1)
-  (emms-mode-line-blank)
-  (emms-playing-time-mode 1)
-  (add-hook 'emms-player-started-hook #'emms-last-played-update-current))
-
-(provide 'config-emms)
-;;; config-emms.el ends here
tools/emacs/config/config-files.el
@@ -1,89 +0,0 @@
-;;; config-files.el --- -*- lexical-binding: t; -*-
-;;; Commentary:
-;;; Files related configurations
-;;; Code:
-(use-package ffap
-  :hook
-  (after-init . ffap-bindings))
-;; (use-package autoinsert
-;;   :init
-;;   (setq-default auto-insert-query nil
-;;                 auto-insert-alist nil)
-;;   :config
-;;   (auto-insert-mode 1))
-
-(require 'hardhat)
-(global-hardhat-mode)
-
-(use-package files
-  :commands (revert-buffer)
-  :bind (("<f5>" . revert-buffer))
-  :config
-  (setq-default view-read-only t))
-
-(use-package envrc
-  :defer 2
-  :if (executable-find "direnv")
-  :bind (:map envrc-mode-map
-              ("C-c e" . envrc-command-map))
-  :config (envrc-global-mode))
-
-(use-package highlight-indentation
-  :unless noninteractive
-  :commands (highlight-indentation-mode highlight-indentation-current-column-mode)
-  :config
-  (set-face-background 'highlight-indentation-face "#e3e3d3")
-  (set-face-background 'highlight-indentation-current-column-face "#c3b3b3"))
-
-(defun vde/delete-this-file ()
-  "Delete the current file, and kill the buffer."
-  (interactive)
-  (or (buffer-file-name) (error "No file is currently being edited"))
-  (when (yes-or-no-p (format "Really delete '%s'?"
-                             (file-name-nondirectory buffer-file-name)))
-    (delete-file (buffer-file-name))
-    (kill-this-buffer)))
-
-(defun vde/rename-this-file-and-buffer (new-name)
-  "Renames both current buffer and file it's visiting to NEW-NAME."
-  (interactive "sNew name: ")
-  (let ((name (buffer-name))
-        (filename (buffer-file-name)))
-    (unless filename
-      (error "Buffer '%s' is not visiting a file!" name))
-    (if (get-buffer new-name)
-        (message "A buffer named '%s' already exists!" new-name)
-      (progn
-        (when (file-exists-p filename)
-          (rename-file filename new-name 1))
-        (rename-buffer new-name)
-        (set-visited-file-name new-name)))))
-
-(bind-key "C-c f D" #'vde/delete-this-file)
-(bind-key "C-c f R" #'vde/rename-this-file-and-buffer)
-
-;; Additional bindings for built-ins
-(bind-key "C-c f v d" #'add-dir-local-variable)
-(bind-key "C-c f v l" #'add-file-local-variable)
-(bind-key "C-c f v p" #'add-file-local-variable-prop-line)
-
-(defun vde/reload-dir-locals-for-current-buffer ()
-  "Reload dir locals for the current buffer."
-  (interactive)
-  (let ((enable-local-variables :all))
-    (hack-dir-local-variables-non-file-buffer)))
-
-(defun vde/reload-dir-locals-for-all-buffers-in-this-directory ()
-  "Reload dir-locals for all buffers in current buffer's `default-directory'."
-  (interactive)
-  (let ((dir default-directory))
-    (dolist (buffer (buffer-list))
-      (with-current-buffer buffer
-        (when (equal default-directory dir))
-        (vde/reload-dir-locals-for-current-buffer)))))
-
-(bind-key "C-c f v r" #'vde/reload-dir-locals-for-current-buffer)
-(bind-key "C-c f v r" #'vde/reload-dir-locals-for-all-buffers-in-this-directory)
-
-(provide 'config-files)
-;;; config-files.el ends here
tools/emacs/config/config-keybindings.el
@@ -1,61 +0,0 @@
-;;; config-keybindings.el --- -*- lexical-binding: t -*-
-;;; Commentary:
-;;; Key binding specific configuration
-;;; Code:
-
-;; Disable C-x C-n to avoid the disabled command buffer
-(unbind-key "C-x C-n" global-map)
-
-;; Remap dynamic-abbrev to hippie-expand
-;; See https://www.masteringemacs.org/article/text-expansion-hippie-expand
-(global-set-key [remap dabbrev-expand] 'hippie-expand)
-
-(use-package vde-simple
-  :demand t
-  :preface
-  (dolist (key '("C-M-<SPC>" "M-<SPC>"))
-    (global-unset-key (kbd key)))
-  :bind
-  (("M-<SPC> e" . dired-jump)
-   ("M-<SPC> x" . execute-extended-command)
-   ("M-<SPC> :" . eval-expression)
-   ("M-<SPC> <SPC>" . (lambda()(interactive)
-			(let ((consult-buffer-filter))
-			  (add-to-list 'consult-buffer-filter "\\*")
-			  (call-interactively 'consult-buffer))))
-   ("M-<SPC> f f" . project-find-file)
-   ("M-<SPC> f o" . ffap)
-   ("M-<SPC> f q" . read-only-mode)
-   ("M-<SPC> f r" . consult-recent-file)
-   ("M-<SPC> q q" . save-buffers-kill-terminal)))
-
-;; TODO add general configuration here
-;; (use-package general
-;;   :config
-;;   (dolist (key '("C-M-<SPC>" "M-<SPC>"))
-;;     (global-unset-key (kbd key)))
-;;   (general-create-definer general-leader :prefix "M-<SPC>")
-;;   (general-def "C-M-<SPC>" 'cycle-spacing)
-;; 
-;;   (general-leader
-;;     "z"   #'(repeat :which-key "Repeat")
-;;     "u"   #'(universal-argument :which-key "Universal argument")
-;;     "e"   #'(dired-jump :which-key "Dired")
-;;     "x"   #'(execute-extended-command :which-key "M-x")
-;;     "f"   '(:ignore t :which-key "File")
-;;     "SPC" #'((lambda()(interactive)
-;;                (let ((consult-buffer-filter))
-;;                  (add-to-list 'consult-buffer-filter "\\*")
-;;                  (call-interactively 'consult-buffer))) :wk "Switch to Buffer")
-;;     ":"   #'(eval-expression :wk "Eval expression")
-;;     "ff"  #'(project-find-file :which-key "Find in Project")
-;;     "fo"  #'(ffap :which-key "Find with context")
-;;     "fq"  #'(read-only-mode :which-key "Toggle Read Only")
-;;     "fr"  #'(consult-recent-file :which-key "Recent File")
-;;     "q"   #'(:ignore t :wk "Quit")
-;;     "qq"  #'(save-buffers-kill-terminal :wk "Quit Emacs")
-;;    ))
-
-;; 
-(provide 'config-keybindings)
-;;; config-keybindings.el ends here
tools/emacs/config/config-llm.el
@@ -1,283 +0,0 @@
-;;; config-llm.el --- -*- lexical-binding: t -*-
-;;; Commentary:
-;;; LLM configuration
-;;; Code:
-
-(use-package copilot
-  ;; :hook
-  ;; (prog-mode . copilot-mode)
-  ;; (markdown-mode . copilot-mode) ;; Enable this on-demand only
-  ;; (text-mode . copilot-mode) ;; I may not want copilot in org-mode for example.
-  ;; (log-edit-mode . copilot-mode)
-  ;; (vc-git-log-edit-mode . copilot-mode)
-  :bind
-  (:map copilot-completion-map
-        ("C-g" . copilot-clear-overlay)
-        ("C-j" . copilot-next-completion)
-        ("C-k" . copilot-previous-completion)
-        ("M-RET" . copilot-accept-completion)
-        ("C-f" . copilot-accept-completion)
-        ("C-l" . copilot-panel-complete))
-  :custom
-  (copilot-idle-delay 1)
-  (copilot-max-char -1)
-  (copile-indent-offset-warning-disable t))
-
-(setq copilot-chat-commit-prompt "Here is the result of running `git diff --cached`. Based on this, suggest a **Conventional Commit message**. Ensure the message includes both a clear title describing the change and a body explaining the change. Do not invent anything new; just comprehend the diff and explain it.
-
-- Do not add extra markdown formatting.
-- Always make sure the commit message is in markdown format.
-- Do not include any additional text outside the commit message.
-- Make sure the title is a max of 50 characters long and not more.
-- The summaries need to be wrapped to 80 characters long and not more (or break the line).
-- Avoid overused words and phrases often associated with AI-generated text. Do not use the following words: *delve, tapestry, vibrant, landscape, realm, embark, excels, vital, comprehensive, intricate, pivotal, moreover, arguably, notably.*
-- Avoid the following phrases: *dive into, it’s important to note, it’s important to remember, certainly, here are, important to consider, based on the information provided, remember that, navigating the [landscape]/[complexities of], delving into the intricacies of, a testament to.*
-- Do not include any generic AI disclaimers or self-references (e.g., \"As an AI language model...\").
-
-# Conventional Commits 1.0.0
-
-## Summary
-
-Conventional Commits is a specification for commit messages that follows these rules to ensure clarity and consistency:
-
-### Format
-
-`<type>[optional scope]: <description>`
-
-`[body]`
-
-### Types
-
-1. **fix:** A bug fix correlating to a PATCH version.
-2. **feat:** A new feature correlating to a MINOR version.
-
-Other types include:
-
-- **build:** Changes to build systems or dependencies.
-- **chore:** Maintenance tasks (e.g., dependency updates).
-- **ci:** Changes to CI configuration.
-- **refactor:** Code changes not adding features or fixing bugs.
-- **test:** Changes to or addition of tests.
-
-Here is the result of `git diff --cached`:")
-
-(use-package copilot-chat
-  :custom
-  (copilot-chat-model "claude-3.7-sonnet")
-  :bind
-  (("C-c a c p" . copilot-chat-prompt-transient-menu)
-   ("C-c a c c" . copilot-chat-insert-commit-message)
-   ("C-c a c o" . copilot-chat-optimize)
-   ("C-c a c m" . copilot-chat-set-model)
-   ("C-c a c w" . my-copilot-chat-copy-source-block)
-   ("C-c a c y" . copilot-chat-yank)
-   ("C-c a c Y" . copilot-chat-yank-pop)
-   ("C-c a c b" . copilot-chat-display)
-   ("C-c a c a" . copilot-chat-switch-to-buffer)
-   ("C-c a c f" . copilot-chat-custom-prompt-function)
-   ("C-c a c s" . copilot-chat-custom-prompt-selection)
-   (:map embark-general-map
-	 ("M a d" . copilot-chat-doc)
-	 ("M a e" . copilot-chat-explain)
-	 ("M a o" . copilot-chat-optimize)
-	 ("M a p" . copilot-chat-custom-prompt-selection)
-	 ("M a r" . copilot-chat-review))
-   (:map copilot-chat-prompt-mode-map
-         ("C-M-w" . my-copilot-chat-copy-source-block)
-         ("C-q" . delete-window)))
-  :config
-  (setq copilot-chat-prompts copilot-chat-markdown-prompt)
-  (defun my-copilot-chat-copy-source-block ()
-    "Copy the source block at point to kill ring."
-    (interactive)
-    (let* ((temp-buffer-name "*copilot-kr-temp*"))
-      (with-current-buffer (get-buffer-create temp-buffer-name)
-        (erase-buffer)
-        (copilot-chat-yank)
-        (kill-ring-save (point-min) (point-max))
-        (kill-buffer))
-      (message "Source block copied to kill ring")))
-
-  (defun copilot-chat-prompt-transient-menu ()
-    "Show a transient menu for Copilot Chat actions."
-    (interactive)
-    (unless (use-region-p)
-      (mark-defun))
-    (transient-define-prefix copilot-chat-prompt-menu ()
-      "Copilot Chat Menu"
-      ["Copilot Chat Actions"
-       ["Target"
-        ("c" "Commit" copilot-chat-insert-commit-message)
-        ("o" "Optimize" copilot-chat-optimize)
-        ("r" "Review" copilot-chat-review)
-        ("f" "Fix" copilot-chat-fix)
-        ("e" "Explain" copilot-chat-explain)
-        ("d" "Doc" copilot-chat-doc)]
-       ["Commands"
-        ("d" "Display chat" copilot-chat-display)
-        ("h" "Hide chat" copilot-chat-hide)
-        ("R" "Reset & reopen" (lambda ()
-                                (interactive)
-                                (copilot-chat-reset)
-                                (copilot-chat-display)))
-        ("x" "Reset" copilot-chat-reset)
-        ("g" "Go to buffer" copilot-chat-switch-to-buffer)
-        ("m" "Set model" copilot-chat-set-model)
-        ("q" "Quit" transient-quit-one)]
-       ["Actions"
-        ("p" "Custom prompt" copilot-chat-custom-prompt-selection)
-        ("i" "Ask and insert" copilot-chat-ask-and-insert)
-        ("m" "Insert commit message" copilot-chat-insert-commit-message)
-        ("b" "Buffers" copilot-chat-transient-buffers)]
-       ["Data"
-        ("y" "Yank last code block" copilot-chat-yank)
-        ("s" "Send code to buffer" copilot-chat-send-to-buffer)]])
-    (copilot-chat-prompt-menu))
-  :after (copilot embark)
-  :commands
-  (copilot-chat-mode))
-
-(use-package aidermacs
-  :bind (("C-c a a m" . aidermacs-transient-menu))
-  :custom
-  (aidermacs-use-architect-mode t)
-  (aidermacs-auto-commits nil)
-  :config
-  (aidermacs-setup-minor-mode))
-
-(use-package gptel
-  :commands (gptel gptel-mode)
-  :bind (("C-c a g" . gptel))
-  :hook
-  (gptel-mode . visual-line-mode)
-  :bind
-  (:map gptel-mode-map
-        ("C-c C-k" . gptel-abort)
-        ("C-c C-m" . gptel-menu)
-        ("C-c C-c" . gptel-send))
-  :custom
-  (gptel-default-mode #'markdown-mode)
-  :config
-  ;; (general-leader
-  ;;   "o"   '(:ignore t :wk "GPTel")
-  ;;   "o o" '(gptel :wk "Start GPTel")
-  ;;   "o m" '(gptel-menu :wk "GPTel menu"))
-  (setq mcp-hub-servers
-	`(("jira" :command "/home/vincent/src/github.com/chmouel/jayrah/.venv/bin/jayrah" :args ("mcp"))
-	  ("github" :command "github-mcp-server" :args ("stdio")
-	   :env (:GITHUB_PERSONAL_ACCESS_TOKEN ,(passage-get "github/vdemeester/github-mcp-server")))))
-  (require 'gptel-curl)
-  (require 'gptel-gemini)
-  (require 'gptel-ollama)
-  (require 'gptel-transient)
-  (require 'gptel-integrations)
-  (require 'gptel-rewrite)
-  (require 'gptel-org)
-  (require 'gptel-openai)
-  (require 'gptel-openai-extras)
-  (require 'gptel-autoloads)
-  (gptel-mcp-connect)
-  (setq gptel-model 'gemini-2.0-flash
-	gptel-backend (gptel-make-gemini "Gemini"
-			:key (passage-get "ai/gemini/api_key"))
-	)
-
-  (gptel-make-deepseek "Deepseek"
-		       :key  (passage-get "ai/deepseek/api_key")
-		       ;; :models '("deepseek-reasoner" "deepseek-chat" )
-		       )
-
-  (gptel-make-openai "MistralLeChat"
-    :host "api.mistral.ai/v1"
-    :endpoint "/chat/completions"
-    :protocol "https"
-    :key (passage-get "ai/mistralai/api_key")
-    :models '("mistral-small"))
-  
-  (gptel-make-openai "OpenRouter"
-    :host "openrouter.ai"
-    :endpoint "/api/v1/chat/completions"
-    :stream t
-    :key (passage-get "ai/openroute/api_key")
-    :models '(cognitivecomputations/dolphin3.0-mistral-24b:free
-	      cognitivecomputations/dolphin3.0-r1-mistral-24b:free
-	      deepseek/deepseek-r1-zero:free
-	      deepseek/deepseek-chat:free
-	      deepseek/deepseek-r1-distill-qwen-32b:free
-	      deepseek/deepseek-r1-distill-llama-70b:free
-	      google/gemini-2.0-flash-lite-preview-02-05:free
-	      google/gemini-2.0-pro-exp-02-05:free
-	      google/gemini-2.5-pro-exp-03-25
-	      google/gemini-2.5-pro-exp-03-25:free
-	      google/gemma-3-12b-it:free
-	      google/gemma-3-27b-it:free
-	      google/gemma-3-4b-it:free
-	      mistralai/mistral-small-3.1-24b-instruct:free
-	      open-r1/olympiccoder-32b:free
-	      qwen/qwen2.5-vl-3b-instruct:free
-	      qwen/qwen-2.5-coder-32b-instruct:free
-	      qwen/qwq-32b:free
-              codellama/codellama-70b-instruct
-              google/gemini-pro
-              google/palm-2-codechat-bison-32k
-              meta-llama/codellama-34b-instruct
-              mistralai/mixtral-8x7b-instruct
-	      openai/gpt-3.5-turbo))
-
-  (gptel-make-openai "Groq"
-    :host "api.groq.com"
-    :endpoint "/openai/v1/chat/completions"
-    :stream t
-    :key (passage-get "ai/groq/wakasu")
-    :models '("llama-3.3-70b-versatile"
-              "llama-3.1-70b-versatile"
-              "llama-3.1-8b-instant"
-              "llama3-70b-8192"
-              "llama3-8b-8192"
-              "deepseek-r1-distill-qwen-32b"
-              "deepseek-r1-distill-llama-70b-specdec"
-              "qwen-2.5-coder-32b"
-              "mixtral-8x7b-32768"
-              "gemma-7b-it"))
-  
-  (gptel-make-ollama "Ollama"
-    :host "localhost:11434"
-    :stream t
-    :models '("smollm:latest"
-              "llama3.1:latest"
-              "deepseek-r1:latest"
-              "mistral-small:latest"
-              "deepseek-r1:7b"
-              "nomic-embed-text:latest")))
-
-(use-package gptel-context
-  :after gptel
-  :config
-  ;; (general-leader
-  ;;   "o c" '(:ignore t :which-key "GPTel Context")
-  ;;   "o c a" 'gptel-context-add
-  ;;   "o c r" 'gptel-context-remove
-  ;;   "o c s" '(lambda ()
-  ;;              (interactive)
-  ;;              (gptel-context-remove-all nil)
-  ;;              (unless (use-region-p)
-  ;;                (mark-defun))
-  ;;              (gptel-context-add)
-  ;;              (my-switch-to-gptel-buffer)))
-  )
-
-(defun my-switch-to-gptel-buffer (&optional arg)
-  "Switch to the most recent buffer with gptel-mode enabled or start it."
-  (interactive "P")
-  (let (target-buffer)
-    (setq target-buffer (cl-find-if 
-                         (lambda (buf)
-                           (with-current-buffer buf
-                             (bound-and-true-p gptel-mode)))
-                         (buffer-list)))
-    (unless target-buffer
-      (call-interactively 'gptel))
-    (pop-to-buffer target-buffer)))
-
-(provide 'config-llm)
-;;; config-llm.el ends here
tools/emacs/config/config-misc.el
@@ -1,29 +0,0 @@
-;;; config-misc.el --- -*- lexical-binding: t; -*-
-;;; Commentary:
-;;; Miscellaneous modes configuration
-;;; Code:
-
-;; (use-package password-store
-;;   :custom
-;;   (password-store-executable "passage"))
-
-(defvar passage-program "passage"
-  "The path to the `passage` executable.")
-
-(defun passage-get (password-name)
-  "Return the password for PASSWORD-NAME from `passage show`."
-  (let ((password (shell-command-to-string (concat passage-program " show " (shell-quote-argument password-name)))))
-    (string-trim password))) ; Trim whitespace here
-
-(use-package helpful
-  :unless noninteractive
-  :bind (("C-h f" . helpful-callable)
-         ("C-h F" . helpful-function)
-         ("C-h M" . helpful-macro)
-         ("C-c h S" . helpful-at-point)
-         ("C-h k" . helpful-key)
-         ("C-h v" . helpful-variable)
-         ("C-h C" . helpful-command)))
-
-(provide 'config-misc)
-;;; config-misc.el ends here
tools/emacs/config/config-mouse.el
@@ -1,20 +0,0 @@
-;;; config-mouse.el --- -*- lexical-binding: t -*-
-;;; Commentary:
-;;; Mouse configuration
-;;; Code:
-
-(use-package mouse
-  :unless noninteractive
-  :config
-  (setq mouse-wheel-scroll-amount
-        '(1
-          ((shift) . 5)
-          ((meta) . 0.5)
-          ((control) . text-scale)))
-  (setq make-pointer-invisible t
-        mouse-wheel-progressive-speed t
-        mouse-wheel-follow-mouse t)
-  :hook (after-init . mouse-wheel-mode))
-
-(provide 'config-mouse)
-;;; config-mouse.el ends here
tools/emacs/config/config-mu4e.el
@@ -1,164 +0,0 @@
-;;; config-mu4e.el -- mu emacs client configuration -*- lexical-binding: t -*-
-;;; Commentary:
-;;; Code:
-
-(use-package mu4e
-  :commands (mu4e)
-  :custom
-  (mu4e-mu-home "/home/vincent/.local/cache/mu")
-  (mu4e-context-policy 'pick-first)
-  (mu4e-change-filenames-when-moving t)
-  (mu4e-attachment-dir "~/desktop/downloads")
-  :config
-  (setq mu4e-get-mail-command (concat (executable-find "mbsync") " --all"))
-  (setq mu4e-update-interval 1800) ; 30m
-  
-  (defun vde-mu4e--mark-get-copy-target ()
-    "Ask for a copy target, and propose to create it if it does not exist."
-    (let* ((target (mu4e-ask-maildir "Copy message to: "))
-           (target (if (string= (substring target 0 1) "/")
-                       target
-                     (concat "/" target)))
-           (fulltarget (mu4e-join-paths (mu4e-root-maildir) target)))
-      (when (mu4e-create-maildir-maybe fulltarget)
-	target)))
-
-  (defun copy-message-to-target(docid msg target)
-    (let (
-          (new_msg_path nil) ;; local variable                                                                
-          (msg_flags (mu4e-message-field msg :flags))                                                                                                       
-          )                                                                                                   
-      ;; 1. target is already determined interactively when executing the mark (:ask-target)                     
-
-      ;; 2. Determine the path for the new file: we use mu4e~draft-message-filename-construct from            
-      ;; mu4e-draft.el to create a new random filename, and append the original's msg_flags                   
-      (setq new_msg_path (format "%s/%s/cur/%s" mu4e-maildir target (mu4e~draft-message-filename-construct    
-								     (mu4e-flags-to-string msg_flags))))                                                                     
-
-      ;; 3. Copy the message using file system call (copy-file) to new_msg_path:                              
-      ;; (See e.g. mu4e-draft.el > mu4e-draft-open > resend)                                             
-      (copy-file (mu4e-message-field msg :path) new_msg_path)                                                 
-
-      ;; 4. Add the information to the database (may need to update current search query with 'g' if duplicating to current box. Try also 'V' to toggle the display of duplicates) 
-      (mu4e~proc-add new_msg_path (mu4e~mark-check-target target))                                              
-      )                                                                                                       
-    )
-
-  (defun vde-mu4e--refile (msg)
-    "Refile function to smartly move `MSG' to a given folder."
-    (cond
-     ;; FIXME
-     ((string= (plist-get (car-safe (mu4e-message-field msg :cc)) :email) "ci_activity@noreply.github.com")
-      "/icloud/Deleted Messages")
-     (t
-      (let ((year (format-time-string "%Y" (mu4e-message-field msg :date))))
-	(format "/icloud/Archives/%s" year)))))
-
-  (setq
-   mu4e-headers-draft-mark     '("D" . "💈")
-   mu4e-headers-flagged-mark   '("F" . "📍")
-   mu4e-headers-new-mark       '("N" . "🔥")
-   mu4e-headers-passed-mark    '("P" . "❯")
-   mu4e-headers-replied-mark   '("R" . "❮")
-   mu4e-headers-seen-mark      '("S" . "☑")
-   mu4e-headers-trashed-mark   '("T" . "💀")
-   mu4e-headers-attach-mark    '("a" . "📎")
-   mu4e-headers-encrypted-mark '("x" . "🔒")
-   mu4e-headers-signed-mark    '("s" . "🔑")
-   mu4e-headers-unread-mark    '("u" . "⎕")
-   mu4e-headers-list-mark      '("l" . "🔈")
-   mu4e-headers-personal-mark  '("p" . "👨")
-   mu4e-headers-calendar-mark  '("c" . "📅"))
-
-  (setopt mu4e-completing-read-function completing-read-function)
-  (setq mu4e-refile-folder 'vde-mu4e--refile)
-  (setq mu4e-contexts `( ,(make-mu4e-context
-			   :name "icloud"
-			   :match-func (lambda (msg) (when msg
-						       (string-prefix-p "/icloud" (mu4e-message-field msg :maildir))))
-			   :vars '(
-				   (user-mail-address . "vincent@demeester.fr")
-				   (mu4e-trash-folder . "/icloud/Deleted Messages")
-				   (mu4e-sent-folder . "/icloud/Sent Messages")
-				   (mu4e-draft-folder . "/icloud/Drafts")
-				   ;; (mu4e-get-mail-command . "mbsync icloud")
-				   ))
-			 ,(make-mu4e-context
-			   :name "gmail"
-			   :match-func (lambda (msg) (when msg
-						       (string-prefix-p "/gmail" (mu4e-message-field msg :maildir))))
-			   :vars '(
-				   (user-mail-address . "vinc.demeester@gmail.com")
-				   (mu4e-drafts-folder  . "/gmail/[Gmail]/Drafts")
-				   (mu4e-sent-folder  . "/gmail/[Gmail]/Sent Mail")
-				   ;; (mu4e-refile-folder  . "/gmail/[Gmail]/All Mail")
-				   (mu4e-trash-folder  . "/gmail/[Gmail]/Trash")
-				   ;; (mu4e-get-mail-command . "mbsync gmail")
-				   ))
-			 ,(make-mu4e-context
-			   :name "redhat"
-			   :match-func (lambda (msg) (when msg
-						       (string-prefix-p "/redhat" (mu4e-message-field msg :maildir))))
-			   :vars '(
-				   (user-mail-address . "vdemeest@redhat.com")
-				   (mu4e-drafts-folder  . "/redhat/[Gmail]/Drafts")
-				   (mu4e-sent-folder  . "/redhat/[Gmail]/Sent Mail")
-				   ;; (mu4e-refile-folder  . "/redhat/[Gmail]/All Mail")
-				   (mu4e-trash-folder  . "/redhat/[Gmail]/Trash")
-				   ;; (mu4e-get-mail-command . "mbsync redhat")
-				   ))
-			 ))
-  (add-to-list 'mu4e-bookmarks
-	       '( :name  "All Inboxes"
-		  :query "maildir:/icloud/INBOX OR maildir:/gmail/INBOX OR maildir:/redhat/INBOX"
-		  :key   ?b))
-  (with-eval-after-load "mm-decode"
-    (add-to-list 'mm-discouraged-alternatives "text/html")
-    (add-to-list 'mm-discouraged-alternatives "text/richtext")))
-
-(setq sendmail-program "msmtp"
-      send-mail-function 'smtpmail-send-it
-      message-sendmail-f-is-evil t
-      message-sendmail-extra-arguments '("--read-envelope-from")
-      message-send-mail-function 'message-send-mail-with-sendmail)
-
-(use-package consult-mu
-  :after mu4e
-  :custom
-  ;;maximum number of results shown in minibuffer
-  (consult-mu-maxnum 200)
-  ;;show preview when pressing any keys
-  (consult-mu-preview-key 'any)
-  ;;do not mark email as read when previewed. If you turn this to t, be aware that the auto-loaded preview if the preview-key above is 'any would also get marked as read!
-  (consult-mu-mark-previewed-as-read nil)
-  ;;mark email as read when selected.
-  (consult-mu-mark-viewed-as-read t)
-  ;;use reply to all when composing reply emails
-  (consult-mu-use-wide-reply t)
-  ;; define a template for headers view in minibuffer. The example below adjusts the width based on the width of the screen.
-  (consult-mu-headers-template (lambda () (concat "%f" (number-to-string (floor (* (frame-width) 0.15))) "%s" (number-to-string (floor (* (frame-width) 0.5))) "%d13" "%g" "%x")))
-
-  :config
-  ;;create a list of saved searches for quick access using `histroy-next-element' with `M-n' in minibuffer. Note the "#" character at the beginning of each query! Change these according to
-  (setq consult-mu-saved-searches-dynamics '("#flag:unread"))
-  (setq consult-mu-saved-searches-async '("#flag:unread"))
-  ;; require embark actions for marking, replying, forwarding, etc. directly from minibuffer
-  (require 'consult-mu-embark)
-  ;; require extra module for composing (e.g. for interactive attachment) as well as embark actions
-  (require 'consult-mu-compose)
-  (require 'consult-mu-compose-embark)
-  ;; require extra module for searching contacts and runing embark actions on contacts
-  (require 'consult-mu-contacts)
-  (require 'consult-mu-contacts-embark)
-  ;; change the prefiew key for compose so you don't open a preview of every file when selecting files to attach
-  (setq consult-mu-compose-preview-key "M-o")
-  ;; pick a key to bind to consult-mu-compose-attach in embark-file-map
-  (setq consult-mu-embark-attach-file-key "C-a")
-  (setq consult-mu-contacts-ignore-list '("^.*no.*reply.*"))
-  (setq consult-mu-contacts-ignore-case-fold-search t)
-  (consult-mu-compose-embark-bind-attach-file-key)
-  ;; choose if you want to use dired for attaching files (choice of 'always, 'in-dired, or nil)
-  (setq consult-mu-compose-use-dired-attachment 'in-dired))
-
-(provide 'config-mu4e)
-;;; config-mu4e.el ends here
tools/emacs/config/config-navigating.el
@@ -1,196 +0,0 @@
-;;; config-navigating.el --- -*- lexical-binding: t -*-
-;;; Commentary:
-;;; Navigation related configuration
-;;; Code:
-
-(use-package emacs
-  :config
-  (setq-default scroll-preserve-screen-position t)
-  (setq-default scroll-conservatively 1) ; affects `scroll-step'
-  (setq-default scroll-margin 0)
-
-  (define-minor-mode vde/scroll-centre-cursor-mode
-    "Toggle centred cursor scrolling behaviour."
-    :init-value nil
-    :lighter " S="
-    :global nil
-    (if vde/scroll-centre-cursor-mode
-        (setq-local scroll-margin (* (frame-height) 2)
-                    scroll-conservatively 0
-                    maximum-scroll-margin 0.5)
-      (dolist (local '(scroll-preserve-screen-position
-                       scroll-conservatively
-                       maximum-scroll-margin
-                       scroll-margin))
-        (kill-local-variable `,local))))
-
-  ;; C-c l is used for `org-store-link'.  The mnemonic for this is to
-  ;; focus the Line and also works as a variant of C-l.
-  :bind ("C-c L" . vde/scroll-centre-cursor-mode))
-
-(use-package replace
-  :config
-  (setq list-matching-lines-jump-to-current-line t)
-  ;; See my "Modus themes" for these inherited faces
-  (setq list-matching-lines-buffer-name-face
-        '(:inherit modus-theme-intense-neutral :weight bold))
-  (setq list-matching-lines-current-line-face
-        '(:inherit modus-theme-special-mild))
-
-  (defun vde/occur-url ()
-    "Produce list with all URLs in the current buffer."
-    (interactive)
-    (let ((urls browse-url-button-regexp))
-      (occur urls "\\&")))
-
-  :hook ((occur-mode . hl-line-mode)
-         (occur-mode . (lambda ()
-                         (toggle-truncate-lines t))))
-  :bind (("M-s M-o" . multi-occur)
-         :map occur-mode-map
-         ("t" . toggle-truncate-lines)))
-
-(use-package avy
-  :unless noninteractive
-  :commands (avy-goto-char avy-goto-line avy-goto-word-1 avy-pop-mark avy-goto-char-timer)
-  :bind (("C-c j w" . avy-goto-word-1)
-         ("C-c j b" . avy-pop-mark)
-         ("C-c j t" . avy-goto-char-timer)
-         ("C-c j l" . avy-goto-line)
-	 (:map isearch-mode-map ("C-j" . avy-isearch)))
-  :config
-  (defun avy-action-helpful (pt)
-    (save-excursion
-      (goto-char pt)
-      (helpful-at-point))
-    (select-window
-     (cdr (ring-ref avy-ring 0)))
-    t)
-
-  (setf (alist-get ?H avy-dispatch-alist) 'avy-action-helpful))
-
-(use-package casual-avy
-  :unless noninteractive
-  :bind ("C-c j j" . casual-avy-tmenu))
-
-(use-package mwim
-  :unless noninteractive
-  :commands (mwim-beginning-of-code-or-line mwim-end-of-code-or-line)
-  :bind (:map prog-mode-map
-              ("C-a" . mwim-beginning-of-code-or-line)
-              ("C-e" . mwim-end-of-code-or-line)))
-
-(use-package beginend
-  :unless noninteractive
-  :defer 5
-  :config
-  (beginend-global-mode 1))
-
-(use-package imenu
-  :unless noninteractive
-  :config
-  (setq-default imenu-use-markers t
-                imenu-auto-rescan t
-                imenu-auto-rescan-maxout 600000
-                imenu-max-item-length 100
-                imenu-use-popup-menu nil
-                imenu-eager-completion-buffer t
-                imenu-space-replacement " "
-                imenu-level-separator "/")
-
-  :hook ((imenu-after-jump . (lambda ()
-                               (when (and (eq major-mode 'org-mode)
-                                          (org-at-heading-p))
-                                 (org-show-entry)
-                                 (org-reveal t))))))
-
-(use-package flimenu
-  :unless noninteractive
-  :config
-  (flimenu-global-mode 1))
-
-(use-package man
-  :unless noninteractive
-  :commands (man)
-  :bind (:map Man-mode-map
-              ("i" . Man-goto-section)
-              ("g" . Man-update-manpage)))
-
-(use-package bookmark)
-(use-package casual-bookmarks
-  :bind (:map bookmark-bmenu-mode-map
-              ("C-o" . casual-bookmarks-tmenu)
-              ("S" . casual-bookmarks-sortby-tmenu)
-              ("J" . bookmark-jump))
-  :after (bookmark))
-
-(keymap-global-set "S-<down-mouse-2>" 'strokes-do-stroke)
-
-(use-package repeat
-  :config
-  (setq repeat-on-final-keystroke t)
-  (setq set-mark-command-repeat-pop t)
-
-  (repeat-mode 1)
-
-  (defvar isearch-repeat-map
-  (let ((map (make-sparse-keymap)))
-    (define-key map (kbd "s") #'isearch-repeat-forward)
-    (define-key map (kbd "r") #'isearch-repeat-backward)
-    map))
-
-  (dolist (cmd '(isearch-repeat-forward isearch-repeat-backward))
-    (put cmd 'repeat-map 'isearch-repeat-map))
-
-  (defvar buffer-navigation-map
-    (let ((map (make-sparse-keymap)))
-      (define-key map (kbd "n") #'next-line)
-      (define-key map (kbd "p") #'previous-line)
-      (define-key map (kbd "f") #'forward-word)
-      (define-key map (kbd "b") #'backward-word)
-      (define-key map (kbd "u") #'scroll-up-command)
-      (define-key map (kbd "d") #'scroll-down-command)
-      map))
-
-  (dolist (cmd '(next-line previous-line forward-word backward-word scroll-up-command scroll-down-command))
-    (put cmd 'repeat-map 'buffer-navigation-map)))
-
-(require 'view)
-
-(add-hook
- 'view-mode-hook
- (lambda ()
-   (cond ((derived-mode-p 'org-mode)
-          (define-key view-mode-map (kbd "p") 'org-previous-visible-heading)
-          (define-key view-mode-map (kbd "n") 'org-next-visible-heading))
-         ((derived-mode-p 'markdown-mode)
-          (define-key view-mode-map (kbd "p") 'markdown-outline-previous)
-          (define-key view-mode-map (kbd "n") 'markdown-outline-next))
-         ((derived-mode-p 'html-mode)
-          (define-key view-mode-map (kbd "p") 'sgml-skip-tag-backward)
-          (define-key view-mode-map (kbd "n") 'sgml-skip-tag-forward))
-         ((derived-mode-p 'python-mode)
-          (define-key view-mode-map (kbd "p") 'python-nav-backward-block)
-          (define-key view-mode-map (kbd "n") 'python-nav-forward-block))
-         ((derived-mode-p 'emacs-lisp-mode)
-          (define-key view-mode-map (kbd "p") 'backward-sexp)
-          (define-key view-mode-map (kbd "n") 'forward-sexp))
-         ((derived-mode-p 'makefile-mode)
-          (define-key view-mode-map (kbd "p") 'makefile-previous-dependency)
-          (define-key view-mode-map (kbd "n") 'makefile-next-dependency))
-         ((derived-mode-p 'c-mode)
-          (define-key view-mode-map (kbd "p") 'c-beginning-of-defun)
-          (define-key view-mode-map (kbd "n") 'c-end-of-defun))
-         (t
-          (define-key view-mode-map (kbd "p") 'scroll-down-command)
-          (define-key view-mode-map (kbd "n") 'scroll-up-command)))))
-
-(use-package outline-indent
-  :custom
-  (outline-indent-ellipsis " ▼ ")
-  :config
-  (add-hook 'yaml-mode-hook #'outline-indent-minor-mode)
-  (add-hook 'yaml-ts-mode-hook #'outline-indent-minor-mode))
-
-(provide 'config-navigating)
-;;; config-navigating.el ends here
tools/emacs/config/config-org.el
@@ -1,714 +0,0 @@
-;;; config-org.el --- -*- lexical-binding: t; -*-
-;;; Commentary:
-;;; Configuration of orgmode.
-;;; Code:
-
-(use-package s)
-(use-package dash)
-
-(defconst org-directory "~/desktop/org/"
-  "org-mode directory, where most of the org-mode file lives")
-(defconst org-notes-directory (expand-file-name "notes" org-directory)
-  "org-mode notes directory, for notes, managed by denote")
-(defconst org-inbox-file (expand-file-name "inbox.org" org-directory)
-  "New stuff collected in this file.")
-(defconst org-todos-file (expand-file-name "todos.org" org-directory)
-  "TODOs collected in this file.")
-;; I am not using this too much
-(defconst org-remember-file (expand-file-name "remember.org" org-directory)
-  "Remember file, very quick and dirty scratch notes, to be refiled later on.")
-
-(defconst org-archive-dir (expand-file-name "archive" org-directory)
-  "Directory of archived files.")
-
-(defconst org-people-dir (expand-file-name "people" org-notes-directory)
-  "People files directory.")
-
-(defconst src-www-dir (expand-file-name "~/src/www" org-directory)
-  "Directory of my www repository, can contain todos there.")
-
-(defconst org-babel-library-file (expand-file-name "org_library_of_babel.org" org-directory)
-  "Org babel library.")
-
-(set-register ?i `(file . ,org-inbox-file))
-(set-register ?t `(file . ,org-todos-file))
-(set-register ?o `(file . ,org-directory))
-(set-register ?P `(file . ,org-people-dir))
-
-(defun vde/agenda-goto-view ()
-  "Jump to the task narrowed but in view mode only to get a glance."
-  (interactive)
-  (org-agenda-goto)
-  (org-narrow-to-subtree)
-  (view-mode t))
-
-(defun vde/org-mode-hook ()
-  "Org-mode hook."
-  (setq show-trailing-whitespace t)
-  (when (not (eq major-mode 'org-agenda-mode))
-    (setq fill-column 90)
-    (auto-revert-mode 1)
-    (auto-fill-mode 1)
-    (org-indent-mode 1)
-    (visual-line-mode 1)
-    (add-hook 'before-save-hook 'org-update-all-dblocks)
-    (add-hook 'auto-save-hook 'org-update-all-dblocks)
-    (add-hook 'before-save-hook #'save-and-update-includes nil 'make-it-local)))
-
-(use-package org
-  :mode (("\\.org$" . org-mode)
-         ("\\.org.draft$" . org-mode))
-  :commands (org-agenda org-capture)
-  :bind (("C-c o l" . org-store-link)
-         ("C-c o r r" . org-refile)
-	 ("C-c o r R" . vde/reload-org-refile-targets)
-         ("C-c o a a" . org-agenda)
-	 ("C-c o a r" . vde/reload-org-agenda-files)
-	 ("C-c C-x i" . vde/org-clock-in-any-heading)
-         ("C-c o s" . org-sort)
-	 ("C-c O" . org-open-at-point-global)
-         ("<f12>" . org-agenda))
-  :hook (org-mode . vde/org-mode-hook)
-  :custom
-  ;; (org-reverse-note-order '((org-inbox-file . t) ;; Insert items on top of inbox
-  ;;                           (".*" . nil)))    ;; On any other file, insert at the bottom
-  (org-archive-location (concat org-archive-dir "/%s::datetree/"))
-  (org-agenda-file-regexp "^[a-zA-Z0-9-_]+.org$")
-  (org-agenda-remove-tags t)
-  (org-use-speed-commands t)
-  (org-special-ctrl-a/e t)
-  (org-special-ctrl-k t)
-  (org-hide-emphasis-markers t)
-  (org-pretty-entities t)
-  (org-ellipsis "…")
-  (org-return-follows-link t)
-  
-  (org-todo-keywords '((sequence "STRT(s)" "NEXT(n)" "TODO(t)" "WAIT(w)" "|" "DONE(d!)" "CANX(c@/!)")))
-  (org-todo-state-tags-triggers '(("CANX" ("CANX" . t))
-                                  ("WAIT" ("WAIT" . t))
-                                  (done ("WAIT"))
-                                  ("TODO" ("WAIT") ("CANX"))
-                                  ("NEXT" ("WAIT") ("CANX"))
-                                  ("DONE" ("WAIT") ("CANX"))))
-  (org-tag-alist
-   '((:startgroup)
-     ("Handson" . ?o)
-     (:grouptags)
-     ("Write" . ?w) ("Code" . ?c)
-     (:endgroup)
-     
-     (:startgroup)
-     ("Handsoff" . ?f)
-     (:grouptags)
-     ("Read" . ?r) ("Watch" . ?W) ("Listen" . ?l)
-     (:endgroup)))
-
-  (org-log-done 'time)
-  (org-log-redeadline 'time)
-  (org-log-reschedule 'time)
-  (org-log-into-drawer t)
-  (org-refile-use-cache t)
-  (org-refile-use-outline-path 'file)
-  (org-refile-allow-creating-parent-nodes 'confirm)
-  (org-list-demote-modify-bullet '(("+" . "-") ("-" . "+")))
-  (org-agenda-span 'day)
-  (org-agenda-start-on-weekday 1)
-  (org-agenda-window-setup 'current-window)
-  (org-agenda-skip-scheduled-if-deadline-is-shown t)
-  (org-agenda-skip-timestamp-if-deadline-is-shown t)
-  (org-agenda-skip-scheduled-if-done nil)
-  (org-agenda-current-time-string "")
-  (org-agenda-time-grid '((daily) () "" ""))
-  ;; ((agenda . " %i %-12:c%?-12t% s")
-  ;;  (todo . " %i %-12:c")
-  ;;  (tags . " %i %-12:c")
-  ;;  (search . " %i %-12:c"))
-  ;; (org-agenda-prefix-format "   %i %?-2 t%s")
-  (org-agenda-prefix-format '((agenda . " %i %?-12t% s")
-			      (todo . " %i")
-			      (tags . " %i")
-			      (search . " %i")))
-  (org-insert-heading-respect-content t)
-  (org-M-RET-may-split-line '((default . nil)))
-  (org-goto-interface 'outline-path-completion)
-  (org-outline-path-complete-in-steps nil)
-  (org-goto-max-level 2)
-
-  (org-agenda-category-icon-alist `(("personal"  ,(list (propertize "🏡")))
-				    ("work"  ,(list (propertize "🏢")))
-				    ("appointments"  ,(list (propertize "📅")))
-				    ("health"  ,(list (propertize "⚕️")))
-				    ("systems"  ,(list (propertize "🖥️")))
-				    ("journal"  ,(list (propertize "📝")))
-				    ("project--" ,(list (propertize "💼" )))
-				    ("tekton", (list (propertize "😼")))
-				    ("openshift-pipelines", (list (propertize "🎩")))
-				    ("redhat", (list (propertize "🎩")))
-				    ("area--"  ,(list (propertize"🏢" )))
-				    ("area--home"  ,(list (propertize "🏡")))
-				    ("home"  ,(list (propertize "🏡")))
-				    ("home-services" ,(list (propertize "☕ ")))
-				    ("email"  ,(list (propertize"📨" )))
-				    ("people"  ,(list (propertize"👤" )))
-				    ("machine" ,(list (propertize "🖥️")))
-				    ("website" ,(list (propertize "🌍")))
-				    ("bike" ,(list (propertize "🚴‍♂️")))
-				    ("security" ,(list (propertize "🛡️")))
-				    ("i*" ,(list (propertize "📒")))))
-  (org-agenda-sticky t)
-  :config
-
-  (defun vde/org-use-speed-commands-for-headings-and-lists ()
-    "Activate speed commands on list items too."
-    (or (and (looking-at org-outline-regexp) (looking-back "^\**" nil))
-	(save-excursion (and (looking-at (org-item-re)) (looking-back "^[ \t]*" nil)))))
-  (setq org-use-speed-commands 'vde/org-use-speed-commands-for-headings-and-lists)
-  ;; TODO: see https://sachachua.com/blog/2025/03/org-mode-cutting-the-current-list-item-including-nested-lists-with-a-speed-command/
-  
-  ;; Refile org-mode cache when emacs has been idled for 5 minutes
-  (run-with-idle-timer 300 t (lambda ()
-                               (org-refile-cache-clear)
-                               (org-refile-get-targets)))
-  
-  ;; Org Babel configurations
-  (when (file-exists-p org-babel-library-file)
-    (org-babel-lob-ingest org-babel-library-file))
-  (defun vde/all-org-agenda-files ()
-    (seq-filter (lambda(x) (and (not (string-match "/archive/" (file-name-directory x)))
-				(not (string-match ".*==readwise=.*" x))))
-		(apply 'append
-		       (mapcar
-			(lambda (directory)
-			  (directory-files-recursively
-			   directory org-agenda-file-regexp))
-			`(,org-directory)))))
-  ;; (defun vde/reload-org-agenda-files ()
-  ;;   "Reload org-agenda-files variables with up-to-date org files"
-  ;;   (interactive)
-  ;;   (setq org-agenda-files (vde/org-agenda-files)))
-  (defun vde/reload-org-refile-targets ()
-    "Reload org-refile-targets variables with up-to-date org files"
-    (interactive)
-    (setq org-refile-targets (vde/org-refile-targets)))
-  (defun vde/org-refile-targets ()
-    (append '((org-inbox-file :level . 0))
-	    (->>
-	     (directory-files org-directory nil ".org$")
-	     (--remove (s-starts-with? "." it))
-	     (--map (format "%s/%s" org-directory it))
-	     (--map `(,it :maxlevel . 3)))
-	    (->>
-	     (directory-files org-notes-directory nil ".org$")
-	     (--remove (s-starts-with? "." it))
-	     (--map (format "%s/%s" org-notes-directory it))
-	     (--map `(,it :maxlevel . 3)))
-	    (->>
-	     (directory-files-recursively org-people-dir ".org$")
-	     (--remove (s-starts-with? (format "%s/legacy" org-people-dir) it))
-	     (--map (format "%s" it))
-	     (--map `(,it :maxlevel . 3)))))
-  (setq org-agenda-files `(,org-inbox-file ,org-todos-file)
-	;; TODO: extract org-refile-targets into a function
-	org-refile-targets (vde/org-refile-targets))
-  (setopt org-agenda-sorting-strategy
-	  '((agenda time-up deadline-up scheduled-up todo-state-up priority-down)
-	    (todo todo-state-up priority-down deadline-up)
-	    (tags todo-state-up priority-down deadline-up)
-	    (search todo-state-up priority-down deadline-up)))
-  (setq org-agenda-custom-commands
-	'(
-	  ;; Archive tasks
-   	  ("#" "To archive" todo "DONE|CANX")
-	  ;; TODO take inspiration from those
-	  ;; ("$" "Appointments" agenda* "Appointments")
-	  ;; ("b" "Week tasks" agenda "Scheduled tasks for this week"
-   	  ;;  ((org-agenda-category-filter-preset '("-RDV")) ; RDV for Rendez-vous
-   	  ;;   (org-agenda-use-time-grid nil)))
-   	  ;; 
-   	  ;; ;; Review started and next tasks
-   	  ;; ("j" "STRT/NEXT" tags-todo "TODO={STRT\\|NEXT}")
-   	  ;; 
-   	  ;; ;; Review other non-scheduled/deadlined to-do tasks
-   	  ;; ("k" "TODO" tags-todo "TODO={TODO}+DEADLINE=\"\"+SCHEDULED=\"\"")
-   	  ;; 
-   	  ;; ;; Review other non-scheduled/deadlined pending tasks
-   	  ;; ("l" "WAIT" tags-todo "TODO={WAIT}+DEADLINE=\"\"+SCHEDULED=\"\"")
-   	  ;; 
-   	  ;; ;; Review upcoming deadlines for the next 60 days
-   	  ;; ("!" "Deadlines all" agenda "Past/upcoming deadlines"
-   	  ;;  ((org-agenda-span 1)
-   	  ;;   (org-deadline-warning-days 60)
-   	  ;;   (org-agenda-entry-types '(:deadline))))
-
-	  ("d" "Daily Agenda"
-	   ((agenda ""
-		    ((org-agenda-span 'day)
-		     (org-deadline-warning-days 5)))
-	    (tags-todo "+PRIORITY=\"A\""
-		       ((org-agenda-overriding-header "High Priority Tasks")))
-	    (todo "NEXT"
-		  ((org-agenda-overriding-header "Next Tasks")))))
-	  ("D" "Daily Agenda (old)"
-	   ((agenda ""
-		    ((org-agenda-files (vde/all-org-agenda-files))
-		     (org-agenda-span 'day)
-		     (org-deadline-warning-days 5)))
-	    (tags-todo "+PRIORITY=\"A\""
-		       ((org-agenda-files (vde/all-org-agenda-files))
-			(org-agenda-overriding-header "High Priority Tasks")))
-	    (todo "NEXT"
-		  ((org-agenda-files (vde/all-org-agenda-files))
-		   (org-agenda-overriding-header "Next Tasks")))))
-	  ("i" "Inbox (triage)"
-	   ((tags-todo ".*"
-		       ((org-agenda-files `(,org-inbox-file)) ;; FIXME use constant here
-			(org-agenda-overriding-header "Unprocessed Inbox Item")))))
-	  ("A" "All (old)"
-	   ((tags-todo ".*"
-		       ((org-agenda-files (vde/all-org-agenda-files))))))
-	  ("u" "Untagged Tasks"
-	   ((tags-todo "-{.*}"
-		       ((org-agenda-overriding-header "Untagged tasks")))))
-	  ("w" "Weekly Review"
-	   ((agenda ""
-		    ((org-agenda-overriding-header "Completed Tasks")
-		     (org-agenda-skip-function '(org-agenda-skip-entry-if 'nottodo 'done))
-		     (org-agenda-span 'week)))
-	    (agenda ""
-		    ((org-agenda-overriding-header "Unfinished Scheduled Tasks")
-		     (org-agenda-skip-function '(org-agenda-skip-entry-if 'todo 'done))
-		     (org-agenda-span 'week)))))
-	  ;; FIXME Should only take into account projects and areas ?
-	  ("R" "Review projects" tags-todo "-CANX/"
-           ((org-agenda-overriding-header "Reviews Scheduled")
-            (org-agenda-skip-function 'org-review-agenda-skip)
-            (org-agenda-cmp-user-defined 'org-review-compare)
-	    (org-agenda-sorting-strategy '(user-defined-down)))))))
-
-(use-package org-review
-  :defer t
-  :after (org)
-  :config
-  (setopt org-review-delay "+1w")
-  (add-hook 'org-agenda-mode-hook
-          (lambda ()
-            (local-set-key (kbd "C-c C-r")
-                           'org-review-insert-last-review))))
-
-;; Make sure we load org-protocol
-(use-package org-protocol
-  :after org)
-
-(use-package org-tempo
-  :after (org)
-  :custom
-  (org-structure-template-alist '(("a" . "aside")
-				  ("c" . "center")
-				  ("C" . "comment")
-				  ("e" . "example")
-				  ("E" . "export")
-				  ("Ea" . "export ascii")
-				  ("Eh" . "export html")
-				  ("El" . "export latex")
-				  ("q" . "quote")
-				  ("s" . "src")
-				  ("se" . "src emacs-lisp")
-				  ("sE" . "src emacs-lisp :results value code :lexical t")
-				  ("sg" . "src go")
-				  ("sr" . "src rust")
-				  ("sp" . "src python")
-				  ("v" . "verse"))))
-
-(use-package org-id
-  :after org
-  :commands contrib/org-id-headlines
-  :init
-  (defun contrib/org-id-headlines ()
-    "Add CUSTOM_ID properties to all headlines in the current
-file which do not already have one."
-    (interactive)
-    (org-map-entries
-     (funcall 'contrib/org-get-id (point) 'create)))
-  :config
-  (setq org-id-link-to-org-use-id
-        'create-if-interactive-and-no-custom-id))
-
-(use-package org-capture
-  :after org
-  :commands (org-capture)
-  :config
-
-  ;; TODO: refine this, create a function that reset this
-  (add-to-list 'org-capture-templates
-               `("l" "Link" entry
-                 (file ,org-inbox-file)
-                 "* %a\n%U\n%?\n%i"
-                 :empty-lines 1))
-  (add-to-list 'org-capture-templates
-	       `("d" "daily entry" entry
-		 (function denote-journal-extras-new-or-existing-entry)
-                 "* %a\n%U\n%?\n%i"
-                 :empty-lines 1))
-  (add-to-list 'org-capture-templates
-               `("t" "Tasks"))
-  (add-to-list 'org-capture-templates
-               `("tt" "New task" entry
-                 (file ,org-inbox-file)
-                 "* %?\n:PROPERTIES:\n:CREATED:\t%U\n:END:\n\n%i\n\nFrom: %a"
-                 :empty-lines 1))
-  ;; Refine this
-  (add-to-list 'org-capture-templates
-               `("tr" "PR Review" entry
-                 (file ,org-inbox-file)
-                 "* TODO review gh:%^{issue} :review:\n:PROPERTIES:\n:CREATED:%U\n:END:\n\n%i\n%?\nFrom: %a"
-                 :empty-lines 1))
-  ;; emails
-  (add-to-list 'org-capture-templates
-	       `("m" "Email Workflow"))
-  (add-to-list 'org-capture-templates
-	       `("mf" "Follow Up" entry
-		 (file ,org-inbox-file)
-		 "* TODO Follow up with %:from on %a\nSCHEDULED:%t\nDEADLINE: %(org-insert-time-stamp (org-read-date nil t \"+2d\"))\n\n%i"
-		 :immediate-finish t))
-  (add-to-list 'org-capture-templates
-	       `("mr" "Read Later" entry
-		 (file ,org-inbox-file)
-		 "* TODO Read %:subject\nSCHEDULED:%t\nDEADLINE: %(org-insert-time-stamp (org-read-date nil t \"+2d\"))\n\n%a\n\n%i" :immediate-finish t))
-  ;; (add-to-list 'org-capture-templates
-  ;;              `("m" "Meeting notes" entry
-  ;;                (file+datetree ,org-meeting-notes-file)
-  ;;                (file ,(concat user-emacs-directory "/etc/orgmode/meeting-notes.org"))))
-
-  (add-to-list 'org-capture-templates
-               `("w" "Writing"))
-  (add-hook 'org-capture-after-finalize-hook #'vde/window-delete-popup-frame)
-  :bind (("C-c o c" . org-capture)))
-
-(defun vde/dired-notes ()
-  "Open a dired buffer with all my notes"
-  (interactive)
-  (find-dired org-directory "-type f -not -path '*/archive/*'"))
-
-;; Using denote as the "source" of my second brain *in* org-mode.
-(use-package denote
-  :commands (denote denote-region denote-type denote-date
-		    denote-signature denote-subdirectory
-		    denote-template denote-link-or-create
-		    denote-add-links denote-find-link
-		    denote-find-backlink denote-rename-file
-		    denote-rename-file-using-front-matter)
-  :bind (("C-c n n" . vde/dired-notes)
-	 ("C-c n N" . denote)
-	 ("C-c n c" . denote-region)
-	 ("C-c n N" . denote-type)
-	 ("C-c n d" . denote-date)
-	 ("C-c n z" . denote-signature)
-	 ("C-c n S" . denote-subdirectory)
-	 ("C-c n t" . denote-template)
-	 ;; Links
-	 ("C-c n i" . denote-link-or-create)
-	 ("C-c n I" . denote-add-links)
-	 ("C-c n b" . denote-backlinks)
-	 ("C-c n F f" . denote-find-link)
-	 ("C-c n F b" . denote-find-backlink)
-	 ;; Renaming
-	 ("C-c n r" . denote-rename-file)
-	 ("C-c n R" . denote-rename-file-using-front-matter)
-	 ;; Dired
-	 (:map dired-mode-map
-	       ("C-c C-d C-i" . denote-link-dired-marked-notes)))
-  :custom
-  (denote-directory org-notes-directory)
-  (denote-rename-buffer-format "📝 %t")
-  (denote-date-prompt-denote-date-prompt-use-org-read-date t)
-  (denote-prompts '(subdirectory title keywords))
-  (denote-backlinks-display-buffer-action
-   '((display-buffer-reuse-window
-      display-buffer-in-side-window)
-     (side . bottom)
-     (slot . 99)
-     (window-width . 0.3)
-     (dedicated . t)
-     (preserve-size . (t . t))))
-  :hook (dired-mode . denote-dired-mode)
-  :config
-  (denote-rename-buffer-mode 1)
-  (defun my-denote-always-rename-on-save-based-on-front-matter ()
-    "Rename the current Denote file, if needed, upon saving the file.
-Rename the file based on its front matter, checking for changes in the
-title or keywords fields.
-
-Add this function to the `after-save-hook'."
-    (let ((denote-rename-confirmations nil)
-          (denote-save-buffers t)) ; to save again post-rename
-      (when (and buffer-file-name (denote-file-is-note-p buffer-file-name))
-	(ignore-errors (denote-rename-file-using-front-matter buffer-file-name))
-	(message "Buffer saved; Denote file renamed"))))
-
-  (add-hook 'after-save-hook #'my-denote-always-rename-on-save-based-on-front-matter)
-  
-  (with-eval-after-load 'org-capture
-    (setq denote-org-capture-specifiers "%l\n%i\n%?")
-    (add-to-list 'org-capture-templates
-		 '("n" "New note (with denote.el)" plain
-                   (file denote-last-path)
-                   #'denote-org-capture
-                   :no-save t
-                   :immediate-finish nil
-                   :kill-buffer t
-                   :jump-to-captured t)))
-  (defun vde/org-category-from-buffer ()
-    "Get the org category (#+category:) value from the buffer"
-    (cond
-     ((string-match "__journal.org$" (buffer-file-name))
-      "journal")
-     (t
-      (denote-sluggify (denote--retrieve-title-or-filename (buffer-file-name) 'org))))))
-
-(use-package denote-journal
-  :commands (denote-journal-new-entry
-             denote-journal-new-or-existing-entry
-             denote-journal-link-or-create-entry)
-  :custom
-  (denote-journal-directory nil) ;; use denote-directory
-  (denote-journal-title-format 'day-date-month-year)
-  :hook (calendar-mode . denote-journal-calendar-mode)
-  :bind (("C-c n j j" . denote-journal-new-or-existing-entry)
-	 ("C-c n j i" . denote-journal-link-or-create-entry)
-	 ("C-c n j n" . denote-journal-new-entry)))
-
-(use-package denote-org
-  :after denote)
-
-(use-package denote-menu
-  :after denote
-  :bind (("C-c n m" . list-denotes)
-	 (:map denote-menu-mode-map
-	       ("c" . denote-menu-clear-filters)
-	       ("/ r" . denote-menu-filter)
-	       ("/ k" . denote-menu-filter-by-keyword)
-	       ("/ o" . denote-menu-filter-out-keyword)
-	       ("e" . denote-menu-export-to-dired))))
-
-(use-package consult-denote
-  :commands (consult-denote-mode
-	     consult-denote-find
-	     consult-denote-grep)
-  :bind (("C-c n f" . consult-denote-find)
-	 ("C-c n s" . consult-denote-grep))
-  :config
-  (consult-denote-mode 1))
-
-(use-package orgit
-  :defer t)
-
-(use-package ob-async
-  :after org
-  :commands (ob-async-org-babel-execute-src-block))
-(use-package ob-emacs-lisp
-  :after org
-  :commands (org-babel-execute:emacs-lisp org-babel-execute:elisp))
-(use-package ob-go
-  :after org
-  :commands (org-babel-execute:go))
-(use-package ob-python
-  :after org
-  :commands (org-babel-execute:python))
-(use-package ob-shell
-  :after org
-  :commands (org-babel-execute:ash
-             org-babel-execute:bash
-             org-babel-execute:csh
-             org-babel-execute:dash
-             org-babel-execute:fish
-             org-babel-execute:ksh
-             org-babel-execute:mksh
-             org-babel-execute:posh
-             org-babel-execute:sh
-             org-babel-execute:shell
-             org-babel-execute:zsh))
-;; my personal
-(use-package ol-github
-  :after (org))
-(use-package ol-gitlab
-  :after (org))
-(use-package ol-rg
-  :disabled
-  :after (org))
-(use-package ol-grep
-  :after (org))
-
-;; built-in org-mode
-(use-package ol-eshell
-  :after (org))
-(use-package ol-git-link
-  :defer 2
-  :after (org))
-(use-package ol-gnus
-  :defer 2
-  :after (org))
-(use-package ol-irc
-  :defer 2
-  :after (org))
-(use-package ol-info
-  :defer 2
-  :after (org))
-(use-package ol-man
-  :defer 2
-  :after (org))
-;; (use-package ol-notmuch
-;;   :defer 2
-;;   :after (org))
-;; (use-package ob-dot
-;;   :after org
-;;   :commands (org-babel-execute:dot))
-;; (use-package ob-ditaa
-;;   :after org
-;;   :commands (org-babel-execute:ditaa)
-;;   :config
-;;   (setq org-ditaa-jar-path "/home/vincent/.nix-profile/lib/ditaa.jar"))
-;; (use-package ob-doc-makefile
-;;   :after org
-;;   :commands (org-babel-execute:makefile))
-
-(use-package org-nix-shell
-  :hook (org-mode . org-nix-shell-mode))
-
-(use-package org-rich-yank
-  :after org
-  :bind (:map org-mode-map
-              ("C-M-y" . org-rich-yank)))
-
-;; from https://sachachua.com/blog/2024/01/using-consult-and-org-ql-to-search-my-org-mode-agenda-files-and-sort-the-results-to-prioritize-heading-matches/
-(defun my-consult-org-ql-agenda-jump ()
-  "Search agenda files with preview."
-  (interactive)
-  (let* ((marker (consult--read
-                  (consult--dynamic-collection
-                   #'my-consult-org-ql-agenda-match)
-                  :state (consult--jump-state)
-                  :category 'consult-org-heading
-                  :prompt "Heading: "
-                  :sort nil
-                  :lookup #'consult--lookup-candidate))
-         (buffer (marker-buffer marker))
-         (pos (marker-position marker)))
-    ;; based on org-agenda-switch-to
-    (unless buffer (user-error "Trying to switch to non-existent buffer"))
-    (pop-to-buffer-same-window buffer)
-    (goto-char pos)
-    (when (derived-mode-p 'org-mode)
-      (org-fold-show-context 'agenda)
-      (run-hooks 'org-agenda-after-show-hook))))
-
-(defun my-consult-org-ql-agenda-format (o)
-  (propertize
-   (org-ql-view--format-element o)
-   'consult--candidate (org-element-property :org-hd-marker o)))
-
-(defun my-consult-org-ql-agenda-match (string)
-  "Return candidates that match STRING.
-Sort heading matches first, followed by other matches.
-Within those groups, sort by date and priority."
-  (let* ((query (org-ql--query-string-to-sexp string))
-         (sort '(date reverse priority))
-         (heading-query (-tree-map (lambda (x) (if (eq x 'rifle) 'heading x)) query))
-         (matched-heading
-          (mapcar #'my-consult-org-ql-agenda-format
-                  (org-ql-select 'org-agenda-files heading-query
-				 :action 'element-with-markers
-				 :sort sort)))
-         (all-matches
-          (mapcar #'my-consult-org-ql-agenda-format
-                  (org-ql-select 'org-agenda-files query
-				 :action 'element-with-markers
-				 :sort sort))))
-    (append
-     matched-heading
-     (seq-difference all-matches matched-heading))))
-
-(use-package org-ql
-  :after org
-  :bind ("M-s a" . my-consult-org-ql-agenda-jump))
-
-(use-package org-ql-view
-  :after org-ql)
-
-(defun my-org-todo-set-keyword-faces ()
-  (setq org-todo-keyword-faces
-        `(("TODO" . (:foreground ,(modus-themes-get-color-value 'red-faint) :weight bold))
-          ("NEXT" . (:foreground ,(modus-themes-get-color-value 'yellow-warmer) :weight bold))
-          ("STARTED" . (:foreground ,(modus-themes-get-color-value 'yellow-intense) :weight bold))
-          ("IN-REVIEW" . (:foreground ,(modus-themes-get-color-value 'blue-faint) :weight bold))
-          ("DONE" . (:foreground ,(modus-themes-get-color-value 'green-warmer) :weight bold))
-          ("CANX" . (:foreground ,(modus-themes-get-color-value 'comment) :weight bold))
-          ("WAIT" . (:foreground ,(modus-themes-get-color-value 'magenta-faint) :weight bold))
-          ("SOMEDAY" . (:foreground ,(modus-themes-get-color-value 'cyan-warmer) :weight bold))
-          ("IDEA" . (:foreground ,(modus-themes-get-color-value 'magenta-cooler) :weight bold))))
-  (when (derived-mode-p 'org-mode)
-    (font-lock-fontify-buffer)))
-(my-org-todo-set-keyword-faces)
-(with-eval-after-load 'modus-themes
-  (add-hook 'modus-themes-after-load-theme-hook #'my-org-todo-set-keyword-faces))
-
-(use-package ox-publish
-  :after org
-  :commands (org-publish org-publish-all org-publish-project org-publish-current-project org-publish-current-file)
-  :config
-  (setq org-html-coding-system 'utf-8-unix
-	org-publish-use-timestamps-flag nil)
-  (defun vde-org-git-exportable-files (directory)
-    "Return a list of files from `DIRECTORY' that can be exported."
-    (directory-files directory nil ".*_www.*\\.org$"))
-  (setq org-publish-project-alist
-	`(("resources"
-	   :base-directory ,org-directory
-	   :base-extension "org"
-	   ;; :include ".*_www*.org"
-	   :include ,(vde-org-git-exportable-files org-directory)
-	   :exclude ".*"
-	   :publishing-directory ,(expand-file-name "resources" src-www-dir)
-	   :publishing-function org-html-publish-to-html
-	   :recursive t
-	   :with-toc nil
-	   :section-numbers nil
-	   :html-head "<link rel=\"stylesheet\" type=\"text/css\" href=\"../css/2022.css\" />"
-	   :html-head-extra "<link rel=\"stylesheet\" type=\"text/css\" href=\"../css/syntax.css\" />"
-	   :html-preamble t
-	   :html-postamble t
-	   :auto-sitemap t
-	   :sitemap-filename "index.org"
-	   :sitemap-title "Resources"
-	   :sitemap-sort-files anti-chronologically
-	   :sitemap-file-entry-format "%d %t"
-	   :sitemap-date-format "%Y-%m-%d"
-	   ;; :sitemap-function org-publish-org-sitemap
-	   ))))
-(use-package org-habit
-  :after (org)
-  :config
-  (setq org-habit-show-habits-only-for-today nil
-        org-habit-graph-column 80))
-(use-package org-download
-  :after (org)
-  :hook ((dired-mode . org-download-enable)
-         (org-mode . org-download-enable))
-  :config
-  (org-download-enable)
-  (setq org-startup-with-inline-images t)
-  (setq org-download-display-inline-images t)
-  (setq org-download-method 'attach))
-
-;; Persistent notes (like persistent-scratch, but built-in)
-(setq remember-data-file org-remember-file
-      remember-handler-functions '(remember-append-to-file)
-      remember-notes-initial-major-mode 'org-mode
-      remember-notes-auto-save-visited-file-name t
-      remember-in-new-frame t)
-
-(use-package consult-org
-  :after (consult org)
-  :commands (consult-org-agenda consult-org-heading))
-
-(provide 'config-org)
-;;; config-org.el ends here
tools/emacs/config/config-programming.el
@@ -1,120 +0,0 @@
-;;; config-programming.el --- -*- lexical-binding: t; -*-
-;;; Commentary:
-;;; Configure general programming
-;;; Code:
-
-(declare-function vde-project--project-root-or-default-directory "proj-func")
-
-(defun my-recompile (args)
-  (interactive "P")
-  (cond
-   ((eq major-mode #'emacs-lisp-mode)
-    (call-interactively 'eros-eval-defun))
-   ((bound-and-true-p my-vterm-command)
-    (my-vterm-execute-region-or-current-line my-vterm-command))
-   ((get-buffer "*compilation*")
-    (with-current-buffer"*compilation*"
-      (recompile)))
-   ((get-buffer "*Go Test*")
-    (with-current-buffer "*Go Test*"
-      (recompile)))
-   ((and (eq major-mode #'go-mode)
-         buffer-file-name
-         (string-match
-          "_test\\'" (file-name-sans-extension buffer-file-name)))
-    (my-gotest-maybe-ts-run))
-   ((and (get-buffer "*cargo-test*")
-         (boundp 'my-rustic-current-test-compile)
-         my-rustic-current-test-compile)
-    (with-current-buffer "*cargo-test*"
-      (rustic-cargo-test-run my-rustic-current-test-compile)))
-   ((get-buffer "*cargo-run*")
-    (with-current-buffer "*cargo-run*"
-      (rustic-cargo-run-rerun)))
-   ((get-buffer "*pytest*")
-    (with-current-buffer "*pytest*"
-      (recompile)))
-   ((eq major-mode #'python-mode)
-    (compile (concat python-shell-interpreter " " (buffer-file-name))))
-   ((call-interactively 'compile))))
-
-(defun run-command-recipes-make--commands (makefile)
-  "Return the list of commands names that was defined in MAKEFILE."
-  (let ((s (f-read makefile))
-        (commands nil)
-        (pos 0))
-    (while (string-match "^\\([^ \n]+\\):" s pos)
-      (push (match-string 1 s) commands)
-      (setq pos (match-end 0)))
-    commands))
-
-;; TODO github run-command: if remote is github.com, add a gh create pr command, and other "goodies"…
-;; TODO tektoncd run-command: if project is tektoncd
-;; TODO redhat run-command: if it's a redhat project
-;; TODO local run-command: figure out how it works
-
-(use-package run-command
-  :bind ("C-c c" . run-command)
-  :config
-  (defun run-command-recipe-make()
-    "Returns a dynamic list of commands based of a Makefile.
-
-This is condition to the following:
-- `make' executable found
-- `Makefile' file present in project root *or* the default directory."
-    (let* ((dir (vde-project--project-root-or-default-directory))
-	   (makefile (expand-file-name "Makefile" dir)))
-    (when (and
-	   (executable-find "make")
-	   (file-exists-p makefile))
-      (message "Makefile present")
-      (let ((targets (run-command-recipes-make--commands makefile)))
-	(mapcar (lambda (target)
-		  (unless (or (string-prefix-p "." target)
-			      (string-prefix-p "$" target)
-			      (string= "FORCE" target))
-		    (list :command-line (concat "make " target)
-			  :command-name target
-			  :working-dir dir
-			  :runner 'run-command-runner-compile)))
-		targets)))))
-  (defun run-command-recipe-hack ()
-    "Returns a dynamic list of commands based of the presence of an `hack' folder
-in the project root *or* the default-directory."
-    (let* ((dir (vde-project--project-root-or-default-directory))
-	   (hack-dir (expand-file-name "hack" dir))
-	   (files (or (ignore-errors (directory-files hack-dir)) [])))
-      (when (file-accessible-directory-p hack-dir)
-	(mapcar (lambda (file)
-		  (let ((hack-file (expand-file-name file hack-dir)))
-		    (when (and (file-regular-p hack-file)
-			       (file-executable-p hack-file))
-		      (list :command-line hack-file
-			    :command-name file
-			    :working-dir dir
-			    :runner 'run-command-runner-compile))))
-		files))))
-  (add-to-list 'run-command-recipes 'run-command-recipe-hack)
-  (add-to-list 'run-command-recipes 'run-command-recipe-make))
-
-(defvar highlight-codetags-keywords
-  '(("\\<\\(TODO\\|FIXME\\|BUG\\|XXX\\)\\>" 1 font-lock-warning-face prepend)
-    ("\\<\\(NOTE\\|HACK\\)\\>" 1 font-lock-doc-face prepend)))
-
-(define-minor-mode highlight-codetags-local-mode
-  "Highlight codetags like TODO, FIXME..."
-  :global nil
-  (if highlight-codetags-local-mode
-      (font-lock-add-keywords nil highlight-codetags-keywords)
-    (font-lock-remove-keywords nil highlight-codetags-keywords))
-
-  ;; Fontify the current buffer
-  (when (bound-and-true-p font-lock-mode)
-    (if (fboundp 'font-lock-flush)
-        (font-lock-flush)
-      (with-no-warnings (font-lock-fontify-buffer)))))
-
-(add-hook 'prog-mode-hook #'highlight-codetags-local-mode)
-
-(provide 'config-programming)
-;;; config-programming.el ends here
tools/emacs/config/config-projects.el
@@ -1,91 +0,0 @@
-;;; config-projects.el --- -*- lexical-binding: t; -*-
-;;; Commentary:
-;;; Project related configuration.
-;;; Code:
-
-(require 'json)
-
-(use-package project
-  :commands (project-find-file project-find-regexp vde/project-vterm vde/project-run-in-vterm)
-  :custom ((project-switch-commands '((?f "File" project-find-file)
-				      (?g "Grep" project-find-regexp)
-				      (?d "Dired" project-dired)
-				      (?b "Buffer" project-switch-to-buffer)
-				      (?q "Query replace" project-query-replace-regexp)
-				      (?m "Magit" vde-project-magit-status)
-				      (?e "Eshell" project-eshell)
-				      (?E "Eat" vde/project-eat)
-				      (?s "Vterm" vde/project-vterm)
-				      (?R "README" vde/open-readme)
-				      (?g "Checkout GitHub PR" checkout-github-pr)))
-	   (project-mode-line t))
-  :bind (("C-x p v" . vde-project-magit-status)
-         ("C-x p s" . vde/project-vterm)
-         ("C-x p X" . vde/project-run-in-vterm)
-	 ("C-x p E" . vde/project-eat)
-	 ("C-x p G" . checkout-github-pr))
-  :init
-  ;; (require project-rootfile)
-  ;; (add-to-list 'project-find-functions #'project-rootfile-try-detect t)
-  ;; (setq project-rootfile-list '(".project"
-  ;;   "default.nix" "flake.nix"                               ; nix
-  ;;   "Makefile" "GNUMakefile" "CMakeLists.txt"               ; Make & CMake
-  ;;   "Cask" "Eldev" "Keg" "Eask"                             ; Emacs
-  ;;   "stack.yaml"                                            ; Haskell
-  ;;   "Cargo.toml"                                            ; Rust
-  ;;   "go.mod"                                                ; Go
-  ;;   ))
-  :config
-  (setq vde/project-local-identifier '(".project")) ;; "go.mod"
-
-  ;; (add-hook 'project-find-functions #'vde/project-try-local)
-
-  (setq-default project-compilation-buffer-name-function 'project-prefixed-buffer-name)
-  (defun vde-project-magit-status ()
-    "Run `magit-status' on project."
-    (interactive)
-    (magit-status (vde-project--project-current)))
-
-  ;; (general-leader
-  ;;   "p"  '(:ignore :which-key "Project")
-  ;;   "pp"  #'(project-switch-project :which-key "Switch to Project")
-  ;;   "ps"  #'(project-search :which-key "Grep in Project")
-  ;;   "pf"  #'(project-find-file :which-key "Find in Project")
-  ;;   "pd"  #'(project-dired :which-key "Dired in Project")
-  ;;   "pc"  #'(project-compile :which-key "Compile in Project")
-  ;;   "pb"  #'(project-switch-to-buffer :which-key "Switch to Project Buffer")
-  ;;   "pk"  #'(project-kill-buffers :which-key "Kill Project Buffers")
-  ;;   "ps"  #'(vde/project-vterm :which-key "Start a vterm in Project")
-  ;;   "pe"  #'(project-eshell :which-key "Start a eshell in Project")
-  ;;   "pE"  #'(vde/project-eat :which-key "Start a eat term in Project")
-  ;;   "px"  #'(vde/project-run-in-vterm :which-key "Execute command in vterm in Project"))
-  )
-
-(use-package conner
-  :bind (("C-x p C" . conner-run-project-command))
-  :commands (conner-run-project-command)
-  :config
-  (require 'vterm))
-
-(use-package project-x
-  :after project
-  :config
-  (add-hook 'project-find-functions 'project-x-try-local 90)
-  (add-hook 'kill-emacs-hook 'project-x--window-state-write)
-  (add-to-list 'project-switch-commands
-               '(?j "Restore windows" project-x-windows) t)
-  :bind (("C-x p w" . project-x-window-state-save)
-         ("C-x p j" . project-x-window-state-load)))
-
-(use-package jira
-  :commands (jira-issues)
-  :config
-  (setq jira-base-url "https://issues.redhat.com"
-	jira-username "vdemeest@redhat.com"
-	jira-token (passage-get "redhat/issues/token/myji")
-	jira-token-is-personal-access-token t
-	jira-api-version 2
-	jira-issues-max-results 500))
-
-(provide 'config-projects)
-;;; config-projects.el ends here
tools/emacs/config/config-search.el
@@ -1,183 +0,0 @@
-;;; config-search.el --- -*- lexical-binding: t; -*-
-;;; Commentary:
-;;; Search related configuration
-;;; Code:
-
-(setq xref-search-program
-      (cond
-       ((or (executable-find "ripgrep")
-            (executable-find "rg"))
-        'ripgrep)
-       ((executable-find "ugrep")
-        'ugrep)
-       (t
-        'grep)))
-
-;; UseISearch
-(use-package isearch
-  :unless noninteractive
-  :config
-  (defun my-project-search-from-isearch ()
-    (interactive)
-    (let ((query (if isearch-regexp
-               isearch-string
-             (regexp-quote isearch-string))))
-      (isearch-update-ring isearch-string isearch-regexp)
-      (let (search-nonincremental-instead)
-        (ignore-errors (isearch-done t t)))
-      (project-find-regexp query)))
-  (defun my-occur-from-isearch ()
-    (interactive)
-    (let ((query (if isearch-regexp
-		     isearch-string
-		   (regexp-quote isearch-string))))
-      (isearch-update-ring isearch-string isearch-regexp)
-      (let (search-nonincremental-instead)
-        (ignore-errors (isearch-done t t)))
-      (occur query)))
-  (setq-default search-whitespace-regexp ".*?"
-                isearch-lax-whitespace t
-                isearch-regexp-lax-whitespace nil
-		isearch-lazy-count t
-		lazy-count-prefix-format nil
-		lazy-count-suffix-format "   (%s/%s)")
-  (defun stribb/isearch-region (&optional not-regexp no-recursive-edit)
-    "If a region is active, make this the isearch default search
-pattern."
-    (interactive "P\np")
-    (when (use-region-p)
-      (let ((search (buffer-substring-no-properties
-                     (region-beginning)
-                     (region-end))))
-        (message "stribb/ir: %s %d %d" search (region-beginning) (region-end))
-        (setq deactivate-mark t)
-        (isearch-yank-string search))))
-  (advice-add 'isearch-forward-regexp :after 'stribb/isearch-region)
-  (advice-add 'isearch-forward :after 'stribb/isearch-region)
-  (advice-add 'isearch-backward-regexp :after 'stribb/isearch-region)
-  (advice-add 'isearch-backward :after 'stribb/isearch-region)
-
-  (defun contrib/isearchp-remove-failed-part-or-last-char ()
-    "Remove failed part of search string, or last char if successful.
-Do nothing if search string is empty to start with."
-    (interactive)
-    (if (equal isearch-string "")
-        (isearch-update)
-      (if isearch-success
-          (isearch-delete-char)
-        (while (isearch-fail-pos) (isearch-pop-state)))
-      (isearch-update)))
-
-  (defun contrib/isearch-done-opposite-end (&optional nopush edit)
-    "End current search in the opposite side of the match.
-Particularly useful when the match does not fall within the
-confines of word boundaries (e.g. multiple words)."
-    (interactive)
-    (funcall #'isearch-done nopush edit)
-    (when isearch-other-end (goto-char isearch-other-end)))
-  :bind (("M-s M-o" . multi-occur)
-         :map isearch-mode-map
-	 ("C-o" . my-occur-from-isearch)
-	 ("C-f" . my-project-search-from-isearch)
-	 ("C-d" . isearch-forward-symbol-at-point)
-         ("DEL" . contrib/isearchp-remove-failed-part-or-last-char)
-         ("<C-return>" . contrib/isearch-done-opposite-end)))
-;; -UseISearch
-
-;; UseGrep
-(use-package grep
-  :commands (find-grep grep find-grep-dired find-name-dired)
-  :bind (("M-s n" . find-name-dired)
-         ("M-s F" . find-grep)
-         ("M-s G" . grep)
-         ("M-s d" . find-grep-dired))
-  :hook ((hook-mode . toggle-truncate-lines))
-  :config
-  (setq-default grep-template (string-join '("ugrep"
-                                             "--color=always"
-                                             "--ignore-binary"
-                                             "--ignore-case"
-                                             "--include=<F>"
-                                             "--line-number"
-                                             "--null"
-                                             "--recursive"
-                                             "--regexp=<R>")
-                                           " "))
-  (add-to-list 'grep-find-ignored-directories "auto")
-  (add-to-list 'grep-find-ignored-directories "elpa"))
-;; -UseGrep
-
-;; UseWgrep
-(use-package wgrep
-  :unless noninteractive
-  :commands (wgrep-change-to-wgrep-mode)
-  :defer 2
-  :custom
-  (wgrep-auto-save-buffer t)
-  (wgrep-change-readonly-file t))
-;; -UseWgrep
-
-;; UseRG
-(use-package rg
-  :if (executable-find "rg")
-  :commands (rg rg-project rg-dwim)
-  :bind (("M-s r r" . rg)
-         ("M-s r p" . rg-project)
-         ("M-s r s" . rg-dwim))
-  :config
-  (setq rg-group-result t)
-  (setq rg-hide-command t)
-  (setq rg-show-columns nil)
-  (setq rg-show-header t)
-  (setq rg-default-alias-fallback "all")
-  (cl-pushnew '("tmpl" . "*.tmpl") rg-custom-type-aliases)
-  (cl-pushnew '("gotest" . "*_test.go") rg-custom-type-aliases)
-  (defun vde/rg-buffer-name ()
-    "Generate a rg buffer name from project if in one"
-    (let ((p (project-root (project-current))))
-      (if p
-	  (format "rg: %s" (abbreviate-file-name p))
-	"rg")))
-  (setq rg-buffer-name #'vde/rg-buffer-name)
-  ;; (when (f-dir-p "~/src/home/")
-  ;;   (rg-define-search rg-projects-dotemacs
-  ;;     "Search home"
-  ;;     :dir "~/src/home/"
-  ;;     :files "*.*"
-  ;;     :menu ("Projects" "H" "home")))
-  ;; (when (f-dir-p "~/src/github.com/NixOS/nixpkgs/")
-  ;;   (rg-define-search rg-projects-nixpkgs
-  ;;     "Search nixpkgs"
-  ;;     :dir "~/src/github.com/NixOS/nixpkgs/"
-  ;;     :files "*.*"
-  ;;     :menu ("Projects" "N" "nixpkgs")))
-  ;; (when (f-dir-p "~/src/tektoncd/pipeline/")
-  ;;   (rg-define-search rg-projects-tektoncd-pipeline
-  ;;     "Search tektoncd/pipeline"
-  ;;     :dir "~/src/tektoncd/pipeline/"
-  ;;     :files "*.*"
-  ;;     :menu ("tektoncd" "P" "pipeline")))
-  ;; (when (f-dir-p "~/src/tektoncd/operator/")
-  ;;   (rg-define-search rg-projects-tektoncd-operator
-  ;;     "Search tektoncd/operator"
-  ;;     :dir "~/src/tektoncd/operator/"
-  ;;     :files "*.*"
-  ;;     :menu ("tektoncd" "P" "operator")))
-  ;; (when (f-dir-p "~/src/tektoncd/cli/")
-  ;;   (rg-define-search rg-projects-tektoncd-cli
-  ;;     "Search tektoncd/cli"
-  ;;     :dir "~/src/tektoncd/cli/"
-  ;;     :files "*.*"
-  ;;     :menu ("tektoncd" "C" "cli")))
-  ;; (when (f-dir-p "~/src/chmouel/")
-  ;;   (rg-define-search rg-projects-chmouel
-  ;;     "Search chmouel"
-  ;;     :dir "~/src/chmouel/"
-  ;;     :files "*.*"
-  ;;     :menu ("Configs" "ch" "chmouel")))
-  )
-
-;; -UseRG
-
-(provide 'config-search)
-;;; config-search.el ends here
tools/emacs/config/config-shells.el
@@ -1,442 +0,0 @@
-;;; config-shells.el --- -*- lexical-binding: t; -*-
-;;; Commentary:
-;;; Shell scripting
-;;; Code:
-
-(defvar ISATUIN (executable-find "atuin")
-  "Whether atuin is available for shell/eshell history.")
-
-(use-package shell
-  :commands (shell)
-  :bind (("<f1>"      . shell)
-         (:map shell-mode-map
-               ("<tab>" . completion-at-point)))
-  :config
-  (setq-default explicit-shell-file-name "zsh"
-                shell-file-name "zsh")
-  (unbind-key "C-c C-l" shell-mode-map)
-  (bind-key "C-c C-l" #'counsel-shell-history shell-mode-map))
-
-(defun run-in-compile (base-cmd &rest ARGS)
-  "Use `compile' to run the BASE-CMD and ARGS, from eshell."
-  (compile (concat base-cmd " " (apply #'concat ARGS))))
-
-;; TODO: understand and rework eshell completion
-(use-package eshell
-  :commands (eshell eshell-here)
-  :bind* ("C-x m t" . eshell-here)
-  :config
-  (defun eshell/make (&rest ARGS)
-    "Shortcut to more easily run builds in a compile buffer"
-    (cond ((or (file-exists-p "Makefile")
-	       (file-exists-p "makefile"))
-	   (run-in-compile "make" ARGS))
-	  ((file-exists-p "build.zig")
-	   (run-in-compile "zig build"))
-	  (t "No supported build system found.")))
-  (defun eshell-here ()
-    "Open EShell in the directory associated with the current buffer's file.
-The EShell is renamed to match that directory to make multiple windows easier."
-    (interactive)
-    (let* ((parent (if (buffer-file-name)
-                       (file-name-directory (buffer-file-name))
-                     default-directory))
-           (name   (car (last (split-string parent "/" t)))))
-      (eshell "new")
-      (rename-buffer (concat "*eshell: " name "*"))))
-
-  ;; Handy aliases
-  (defalias 'ff 'find-file)
-  (defalias 'emacs 'find-file)
-  (defalias 'e 'find-file)
-  (defalias 'ec 'find-file)
-  (defalias 'd 'dired)
-
-  (defun eshell/gs (&rest args)
-    (magit-status (pop args) nil)
-    (eshell/echo))                      ; The echo command suppresses output
-
-  (defun eshell/cdg ()
-    "Change directory to the project's root."
-    (eshell/cd (locate-dominating-file default-directory ".git")))
-
-  (defun eshell/extract (file)
-    "One universal command to extract FILE (for bz2, gz, rar, etc.)"
-    (eshell-command-result (format "%s %s" (cond ((string-match-p ".*\.tar.bz2" file)
-                                                  "tar xzf")
-                                                 ((string-match-p ".*\.tar.gz" file)
-                                                  "tar xzf")
-                                                 ((string-match-p ".*\.bz2" file)
-                                                  "bunzip2")
-                                                 ((string-match-p ".*\.rar" file)
-                                                  "unrar x")
-                                                 ((string-match-p ".*\.gz" file)
-                                                  "gunzip")
-                                                 ((string-match-p ".*\.tar" file)
-                                                  "tar xf")
-                                                 ((string-match-p ".*\.tbz2" file)
-                                                  "tar xjf")
-                                                 ((string-match-p ".*\.tgz" file)
-                                                  "tar xzf")
-                                                 ((string-match-p ".*\.zip" file)
-                                                  "unzip")
-                                                 ((string-match-p ".*\.jar" file)
-                                                  "unzip")
-                                                 ((string-match-p ".*\.Z" file)
-                                                  "uncompress")
-                                                 (t
-                                                  (error "Don't know how to extract %s" file)))
-                                   file)))
-
-  ;; From https://karthinks.com/software/jumping-directories-in-eshell/
-  (defun eshell/j (&optional regexp)
-    "Navigate to a previously visited directory in eshell, or to
-any directory proferred by `consult-dir'."
-    (let ((eshell-dirs (delete-dups
-                        (mapcar 'abbreviate-file-name
-                                (ring-elements eshell-last-dir-ring)))))
-      (cond
-       ((and (not regexp) (featurep 'consult-dir))
-        (let* ((consult-dir--source-eshell `(:name "Eshell"
-                                                   :narrow ?e
-                                                   :category file
-                                                   :face consult-file
-                                                   :items ,eshell-dirs))
-               (consult-dir-sources (cons consult-dir--source-eshell
-                                          consult-dir-sources)))
-          (eshell/cd (substring-no-properties
-                      (consult-dir--pick "Switch directory: ")))))
-       (t (eshell/cd (if regexp (eshell-find-previous-directory regexp)
-                       (completing-read "cd: " eshell-dirs)))))))
-
-  (add-hook
-   'eshell-mode-hook
-   (lambda ()
-     (let ((ls (if (executable-find "exa") "exa" "ls")))
-       (eshell/alias "ls" (concat ls " $*"))
-       (eshell/alias "ll" (concat ls " -l $*"))
-       (eshell/alias "l" (concat ls " -lah $*")))
-     (eshell-smart-initialize)
-     (eshell-dirs-initialize)
-     (bind-keys :map eshell-mode-map
-                ("C-c C-l"                . counsel-esh-history)
-                ([remap eshell-pcomplete] . completion-at-point)
-                )))
-
-  ;; Use system su/sudo
-  (with-eval-after-load "em-unix"
-    '(progn
-       (unintern 'eshell/su nil)
-       (unintern 'eshell/sudo nil)))
-
-  (add-hook 'eshell-mode-hook #'with-editor-export-editor))
-
-(use-package eshell-atuin
-  :when ISATUIN
-  :after eshell
-  ;; :bind* ( :map eshell-mode-map
-  ;;          ([remap eshell-previous-matching-input] . eshell-atuin-history))
-  :bind (("C-r" . eshell-atuin-history)
-	 ([remap eshell-list-history] . eshell-atuin-history))
-  :config
-  (eshell-atuin-mode)
-  (setopt eshell-atuin-filter-mode 'global
-          eshell-atuin-search-fields '(time duration command directory host)
-	  eshell-atuin-search-options '() ;; default --exit 0 ignores all the one imported… which is a shame
-          eshell-atuin-history-format "%-80c %-40i %>10t %h"))
-
-(use-package em-prompt
-  :after eshell
-  :config
-  (defun vde/eshell-quit-or-delete-char (arg)
-    "Use C-d to either delete forward char or exit EShell."
-    (interactive "p")
-    (if (and (eolp) (looking-back eshell-prompt-regexp nil nil))
-        (progn
-          (eshell-life-is-too-much))
-      (delete-char arg)))
-
-  (add-hook 'eshell-mode-hook
-            (lambda ()
-              (bind-key "C-d"
-                        #'vde/eshell-quit-or-delete-char eshell-mode-map))))
-
-(use-package esh-mode
-  :disabled
-  :after eshell
-  :bind (:map eshell-mode-map
-              ("<tab>" . vde/esh-mode-completion-at-point))
-  :config
-  (setq-default eshell-scroll-to-bottom-on-input 'all)
-  (defun vde/esh-mode-completion-at-point ()
-    "Same as `completion-at-point' except for some commands."
-    (interactive)
-    ;; unbinding pcomplete/make gives a chance to `bash-completion'
-    ;; to complete make rules. Bash-completion is indeed more
-    ;; powerfull than `pcomplete-make'.
-    (cl-letf (((symbol-function 'pcomplete/make) nil))
-      (completion-at-point))))
-
-(use-package em-smart
-  :after eshell)
-(use-package em-dirs
-  :after eshell)
-
-(use-package em-cmpl
-  :after eshell
-  :hook (eshell-mode . eshell-cmpl-initialize)
-  :config
-  (defun my/eshell-bash-completion ()
-    (let ((bash-completion-nospace t))
-      (while (pcomplete-here
-              (nth 2 (bash-completion-dynamic-complete-nocomint
-                      (save-excursion (eshell-bol) (point))
-                      (point)))))))
-  (when (require 'bash-completion nil t)
-    (setq eshell-default-completion-function #'my/eshell-bash-completion))
-
-  (add-to-list 'eshell-command-completions-alist
-               '("gunzip" "gz\\'"))
-  (add-to-list 'eshell-command-completions-alist
-               '("tar" "\\(\\.tar|\\.tgz\\|\\.tar\\.gz\\)\\'")))
-
-(use-package em-hist
-  :after eshell
-  :config (setq eshell-hist-ignoredups t))
-
-(use-package em-tramp
-  :after eshell)
-
-(use-package em-term
-  :after eshell
-  :config
-  (add-to-list 'eshell-visual-commands "ssh")
-  (add-to-list 'eshell-visual-commands "htop")
-  (add-to-list 'eshell-visual-commands "top")
-  (add-to-list 'eshell-visual-commands "tail")
-  (add-to-list 'eshell-visual-commands "npm")
-  (add-to-list 'eshell-visual-commands "ncdu"))
-
-(use-package em-banner
-  :after eshell
-  :config
-  (setq eshell-banner-message "
-  Welcome to the Emacs
-
-                         _/                  _/  _/
-      _/_/      _/_/_/  _/_/_/      _/_/    _/  _/
-   _/_/_/_/  _/_/      _/    _/  _/_/_/_/  _/  _/
-  _/            _/_/  _/    _/  _/        _/  _/
-   _/_/_/  _/_/_/    _/    _/    _/_/_/  _/  _/
-
-"))
-
-(use-package eshell-prompt-extras
-  :after eshell
-  :custom
-  (eshell-highlight-prompt nil)
-  (eshell-prompt-function 'vde-theme-lambda)
-  :config
-  (setq epe-path-style 'fish
-	epe-fish-path-max-len 20)
-  (defun vde-kubernetes-current-context ()
-    "Return the current context"
-    (if (not (string-empty-p (getenv "KUBECONFIG")))
-        (epe-trim-newline (shell-command-to-string (concat
-                                                    "env KUBECONFIG="
-                                                    (getenv "KUBECONFIG")
-                                                    " kubectl config current-context")))
-      (epe-trim-newline (shell-command-to-string "kubectl config current-context"))))
-  (defun vde-kubernetes-p ()
-    "If you have kubectl install and a config set,
-using either KUBECONFIG or ~/.kube/config"
-    (and (eshell-search-path "kubectl")
-         (not (string-empty-p (vde-kubernetes-current-context)))
-         (not (string-match-p "error: current-context is not set" (vde-kubernetes-current-context)))))
-  ;; From epe-theme-lambda
-  (defun vde-theme-lambda ()
-    "A eshell-prompt lambda theme."
-    (setq eshell-prompt-regexp "^[^#\nλ]*[#λ] ")
-    (concat
-     (when (epe-remote-p)
-       (epe-colorize-with-face
-        (concat (epe-remote-user) "@" (epe-remote-host) " ")
-        'epe-remote-face))
-     (when (and epe-show-python-info (bound-and-true-p venv-current-name))
-       (epe-colorize-with-face (concat "(" venv-current-name ") ") 'epe-venv-face))
-     (let ((f (cond ((eq epe-path-style 'fish) 'epe-fish-path)
-                    ((eq epe-path-style 'single) 'epe-abbrev-dir-name)
-                    ((eq epe-path-style 'full) 'abbreviate-file-name))))
-       (epe-colorize-with-face (funcall f (eshell/pwd)) 'epe-dir-face))
-     (when (epe-git-p)
-       (concat
-        (epe-colorize-with-face ":" 'epe-dir-face)
-        (epe-colorize-with-face
-         (concat (epe-git-branch)
-                 (epe-git-dirty)
-                 (epe-git-untracked)
-                 (let ((unpushed (epe-git-unpushed-number)))
-                   (unless (= unpushed 0)
-                     (concat ":" (number-to-string unpushed)))))
-         'epe-git-face)))
-     (when (vde-kubernetes-p)
-       (concat (epe-colorize-with-face " (" 'epe-dir-face)
-               (epe-colorize-with-face (vde-kubernetes-current-context) 'epe-dir-face)
-               (epe-colorize-with-face ")" 'epe-dir-face)))
-     (epe-colorize-with-face " λ" 'epe-symbol-face)
-     (epe-colorize-with-face (if (= (user-uid) 0) "#" "") 'epe-sudo-symbol-face)
-     " ")))
-
-(use-package eat
-  :commands (eat)
-  :init (setq eat-kill-buffer-on-exit t
-	      eat-enable-yank-to-terminal t)
-  :hook ((eshell-mode . eat-eshell-mode)
-	 (eshell-mode . eat-eshell-visual-command-mode)))
-
-(use-package xterm-color
-  :after eshell
-  :init
-  ;; (setq comint-output-filter-functions
-  ;;       (remove 'ansi-color-process-output comint-output-filter-functions))
-  (add-hook 'shell-mode-hook
-            (lambda ()
-              ;; Disable font-locking in this buffer to improve performance
-              (font-lock-mode -1)
-              ;; Prevent font-locking from being re-enabled in this buffer
-              (make-local-variable 'font-lock-function)
-              (setq font-lock-function (lambda (_) nil))
-              (add-hook 'comint-preoutput-filter-functions 'xterm-color-filter nil t)))
-  (add-hook 'eshell-before-prompt-hook
-            (lambda ()
-              (setenv "TERM" "xterm-256color")
-              (setq xterm-color-preserve-properties t)))
-  (add-to-list 'eshell-preoutput-filter-functions 'xterm-color-filter)
-  (setq eshell-output-filter-functions (remove 'eshell-handle-ansi-color eshell-output-filter-functions))
-  (setq compilation-environment '("TERM=xterm-256color")))
-
-(use-package vterm
-  :commands (vterm vde/vterm-toggle)
-  :bind (("C-c t v" . vde/vterm-toggle)
-         ("C-c t r" . vde/run-in-vterm))
-  :custom
-  (vterm-kill-buffer-on-exit t)
-  (vterm-max-scrollback 100000)
-  (vterm-tramp-shells '(("scp" "/usr/bin/env zsh")
-			("ssh" "/usr/bin/env zsh")
-			("sshx" "/usr/bin/env zsh")
-			("sshfs" "/usr/bin/env zsh")
-			("docker" "/bin/sh")))
-  :config
-  (defun vde/vterm-tramp-get-method-parameter (method param)
-    "Return the method parameter PARAM.
-If the `tramp-methods' entry does not exist, return NIL."
-    (let ((entry (assoc param (assoc method tramp-methods))))
-      (when entry (cadr entry))))
-  (add-hook 'vterm-set-title-functions 'vterm--rename-buffer-as-title)
-  ;; TODO: hook into projectile-run-vterm instead
-  ;; Also, look into vterm-toggle way of doing things.. I thing it is trying to be too smart about it..
-  ;; I prefer an easy projectile integration (or projects integration)
-  (defun vde/vterm ()
-    ""
-    (interactive)
-    (let* ((dir (expand-file-name default-directory))
-           cd-cmd cur-host vterm-dir vterm-host cur-user cur-port remote-p cur-method login-cmd)
-      (if (ignore-errors (file-remote-p dir))
-          (with-parsed-tramp-file-name dir nil
-            (setq remote-p t)
-            (setq cur-host host)
-            (setq cur-method (tramp-find-method method user cur-host))
-            (setq cur-user (or (tramp-find-user cur-method user cur-host) ""))
-            (setq cur-port (or port ""))
-            (setq dir localname))
-        (setq cur-host (system-name)))
-      (setq login-cmd (vde/vterm-tramp-get-method-parameter cur-method 'tramp-login-program))
-      (setq cd-cmd (concat " cd " (shell-quote-argument dir)))
-      (setq shell-buffer (format "vterm %s %s" cur-host dir))
-      (if (buffer-live-p shell-buffer)
-          (switch-to-buffer shell-buffer)
-        (progn
-          (message (format "buffer '%s' doesn't exists" shell-buffer))
-          (vterm shell-buffer)
-          (with-current-buffer shell-buffer
-            (message (format "%s" remote-p))
-            (when remote-p
-              (let* ((method (if (string-equal login-cmd "ssh") "ssh" cur-method))
-                     (login-opts (vde/vterm-tramp-get-method-parameter method 'tramp-login-args))
-                     (login-shell (vde/vterm-tramp-get-method-parameter method 'tramp-remote-shell))
-                     (login-shell-args (tramp-get-sh-extra-args login-shell))
-                     ;; (vterm-toggle-tramp-get-method-parameter cur-method 'tramp-remote-shell)
-                     (spec (format-spec-make
-			                ?h cur-host ?u cur-user ?p cur-port ?c ""
-			                ?l (concat login-shell " " login-shell-args)))
-                     (cmd
-                      (concat login-cmd " "
-                              (mapconcat
-		                       (lambda (x)
-			                     (setq x (mapcar (lambda (y) (format-spec y spec)) x))
-			                     (unless (member "" x) (string-join x " ")))
-		                       login-opts " "))))
-                (vterm-send-string cmd)
-                (vterm-send-return)))
-            (vterm-send-string cd-cmd)
-            (vterm-send-return))))))
-  (defun vde/vterm-toggle ()
-    "Toggle between the main vterm buffer and the current buffer.
-If you are in a vterm buffer, switch the window configuration
-back to your code buffers. Otherwise, create at least one vterm
-buffer if it doesn't exist already, and switch to it. On every
-toggle, the current window configuration is saved in a register."
-    (interactive)
-    (if (eq major-mode 'vterm-mode)
-        (jump-to-register ?W)
-      ;; Save current window config and jump to shell
-      (window-configuration-to-register ?W)
-      (condition-case nil
-          (jump-to-register ?Z)
-        (error
-         (vterm)
-         (when (= (length (window-list)) 2)
-           (other-window 1)
-           (vterm 1)
-           (other-window 1))))
-      (window-configuration-to-register ?Z)))
-  (buffer-name)
-  (defun vde/run-in-vterm ()
-    (interactive)
-    (with-current-buffer "vterm"
-      (vterm-send-string (read-string "Command: "))
-      (vterm-send-C-j))))
-
-(use-package multi-vterm
-  :commands (multi-vterm multi-vterm-projectile multi-vterm-dedicated-toggle)
-  :bind (("C-c t t" . multi-vterm-dedicated-toggle)
-         ("C-c t p" . multi-vterm-prev)
-         ("C-c t n" . multi-vterm-next)
-         ("C-c t s" . multi-vterm)))
-;; for fish in ansi-term
-(add-hook 'term-mode-hook 'toggle-truncate-lines)
-
-(use-package tramp
-  :defer t
-  :config
-  (setq-default tramp-use-ssh-controlmaster-options nil ; Don't override SSH config.
-                tramp-default-method "ssh") ; ssh is faster than scp and supports ports.
-  (add-to-list 'tramp-remote-path "/run/current-system/sw/bin")
-  (add-to-list 'tramp-remote-path "/etc/profiles/per-user/root/bin/")
-  (add-to-list 'tramp-remote-path "/etc/profiles/per-user/vincent/bin/")
-  (add-to-list 'tramp-remote-path "~/.nix-profile/bin")
-  (add-to-list 'tramp-remote-path "~/bin")
-  (add-to-list 'tramp-remote-path 'tramp-own-remote-path))
-
-(defun generic-term-init ()
-  (visual-line-mode -1)
-  (setq-local global-hl-line-mode nil)
-  (setq-local scroll-margin 0))
-
-(add-hook 'term-mode-hook #'generic-term-init)
-(add-hook 'shell-mode-hook #'generic-term-init)
-(add-hook 'eshell-mode-hook #'generic-term-init)
-
-(provide 'config-shells)
-;;; config-shells.el ends here
tools/emacs/config/config-vcs.el
@@ -1,395 +0,0 @@
-;;; config-vcs.el --- -*- lexical-binding: t; -*-
-;;; Commentary:
-;;; Version control configuration
-;;; Code:
-
-
-(defun vde/vc-browse-remote (&optional current-line)
-  "Open the repository's remote URL in the browser.
-If CURRENT-LINE is non-nil, point to the current branch, file, and line.
-Otherwise, open the repository's main page."
-  (interactive "P")
-  (let* ((remote-url (string-trim (vc-git--run-command-string nil "config" "--get" "remote.origin.url")))
-		 (branch (string-trim (vc-git--run-command-string nil "rev-parse" "--abbrev-ref" "HEAD")))
-		 (file (string-trim (file-relative-name (buffer-file-name) (vc-root-dir))))
-		 (line (line-number-at-pos)))
-	(message "Opening remote on browser: %s" remote-url)
-	(if (and remote-url (string-match "\\(?:git@\\|https://\\)\\([^:/]+\\)[:/]\\(.+?\\)\\(?:\\.git\\)?$" remote-url))
-		(let ((host (match-string 1 remote-url))
-			  (path (match-string 2 remote-url)))
-		  ;; Convert SSH URLs to HTTPS (e.g., git@github.com:user/repo.git -> https://github.com/user/repo)
-		  (when (string-prefix-p "git@" host)
-			(setq host (replace-regexp-in-string "^git@" "" host)))
-		  ;; Construct the appropriate URL based on CURRENT-LINE
-		  (browse-url
-		   (if current-line
-			   (format "https://%s/%s/blob/%s/%s#L%d" host path branch file line)
-			 (format "https://%s/%s" host path))))
-	  (message "Could not determine repository URL"))))
-
-(global-set-key (kbd "C-x v B") 'vde/vc-browse-remote)
-
-(use-package vc
-  :config
-  (setq-default vc-find-revision-no-save t
-                vc-follow-symlinks t)
-  :bind (("C-x v f" . vc-log-incoming)  ;  git fetch
-         ("C-x v F" . vc-update)
-         ("C-x v d" . vc-diff)))
-
-(use-package vc-dir
-  :config
-  (defun vde/vc-dir-project ()
-    "Unconditionally display `vc-diff' for the current project."
-    (interactive)
-    (vc-dir (vc-root-dir)))
-
-  (defun vde/vc-dir-jump ()
-    "Jump to present directory in a `vc-dir' buffer."
-    (interactive)
-    (vc-dir default-directory))
-  :bind (("C-x v p" . vde/vc-dir-project)
-         ("C-x v j" . vde/vc-dir-jump) ; similar to `dired-jump'
-         :map vc-dir-mode-map
-         ("f" . vc-log-incoming) ; replaces `vc-dir-find-file' (use RET)
-         ("F" . vc-update)       ; symmetric with P: `vc-push'
-         ("d" . vc-diff)         ; align with D: `vc-root-diff'
-         ("k" . vc-dir-clean-files)))
-
-(use-package vc-git
-  :config
-  (setq vc-git-diff-switches "--patch-with-stat")
-  (setq vc-git-print-log-follow t))
-
-(use-package vc-annotate
-  :config
-  (setq vc-annotate-display-mode 'scale)
-  :bind (("C-x v a" . vc-annotate)
-         :map vc-annotate-mode-map
-         ("t" . vc-annotate-toggle-annotation-visibility)))
-
-(use-package ediff
-  :commands (ediff ediff-files ediff-merge ediff3 ediff-files3 ediff-merge3)
-  :config
-  (setq ediff-window-setup-function 'ediff-setup-windows-plain)
-  (setq ediff-split-window-function 'split-window-horizontally)
-  (setq ediff-diff-options "-w")
-  (add-hook 'ediff-after-quit-hook-internal 'winner-undo))
-
-(use-package diff
-  :config
-  (setq diff-default-read-only nil)
-  (setq diff-advance-after-apply-hunk t)
-  (setq diff-update-on-the-fly t)
-  (setq diff-refine 'font-lock)
-  (setq diff-font-lock-prettify nil)
-  (setq diff-font-lock-syntax nil))
-
-(use-package magit-popup)
-
-(defun th/magit--with-difftastic (buffer command)
-  "Run COMMAND with GIT_EXTERNAL_DIFF=difft then show result in BUFFER."
-  (let ((process-environment
-         (cons (concat "GIT_EXTERNAL_DIFF=difft --width="
-                       (number-to-string (frame-width)))
-               process-environment)))
-    ;; Clear the result buffer (we might regenerate a diff, e.g., for
-    ;; the current changes in our working directory).
-    (with-current-buffer buffer
-      (setq buffer-read-only nil)
-      (erase-buffer))
-    ;; Now spawn a process calling the git COMMAND.
-    (make-process
-     :name (buffer-name buffer)
-     :buffer buffer
-     :command command
-     ;; Don't query for running processes when emacs is quit.
-     :noquery t
-     ;; Show the result buffer once the process has finished.
-     :sentinel (lambda (proc event)
-                 (when (eq (process-status proc) 'exit)
-                   (with-current-buffer (process-buffer proc)
-                     (goto-char (point-min))
-                     (ansi-color-apply-on-region (point-min) (point-max))
-                     (setq buffer-read-only t)
-                     (view-mode)
-                     (end-of-line)
-                     ;; difftastic diffs are usually 2-column side-by-side,
-                     ;; so ensure our window is wide enough.
-                     (let ((width (current-column)))
-                       (while (zerop (forward-line 1))
-                         (end-of-line)
-                         (setq width (max (current-column) width)))
-                       ;; Add column size of fringes
-                       (setq width (+ width
-                                      (fringe-columns 'left)
-                                      (fringe-columns 'right)))
-                       (goto-char (point-min))
-                       (pop-to-buffer
-                        (current-buffer)
-                        `(;; If the buffer is that wide that splitting the frame in
-                          ;; two side-by-side windows would result in less than
-                          ;; 80 columns left, ensure it's shown at the bottom.
-                          ,(when (> 80 (- (frame-width) width))
-                             #'display-buffer-at-bottom)
-                          (window-width
-                           . ,(min width (frame-width))))))))))))
-(defun th/magit-show-with-difftastic (rev)
-  "Show the result of \"git show REV\" with GIT_EXTERNAL_DIFF=difft."
-  (interactive
-   (list (or
-          ;; If REV is given, just use it.
-          (when (boundp 'rev) rev)
-          ;; If not invoked with prefix arg, try to guess the REV from
-          ;; point's position.
-          (and (not current-prefix-arg)
-               (or (magit-thing-at-point 'git-revision t)
-                   (magit-branch-or-commit-at-point)))
-          ;; Otherwise, query the user.
-          (magit-read-branch-or-commit "Revision"))))
-  (if (not rev)
-      (error "No revision specified")
-    (th/magit--with-difftastic
-     (get-buffer-create (concat "*git show difftastic " rev "*"))
-     (list "git" "--no-pager" "show" "--ext-diff" rev))))
-(defun th/magit-diff-with-difftastic (arg)
-  "Show the result of \"git diff ARG\" with GIT_EXTERNAL_DIFF=difft."
-  (interactive
-   (list (or
-          ;; If RANGE is given, just use it.
-          (when (boundp 'range) range)
-          ;; If prefix arg is given, query the user.
-          (and current-prefix-arg
-               (magit-diff-read-range-or-commit "Range"))
-          ;; Otherwise, auto-guess based on position of point, e.g., based on
-          ;; if we are in the Staged or Unstaged section.
-          (pcase (magit-diff--dwim)
-            ('unmerged (error "unmerged is not yet implemented"))
-            ('unstaged nil)
-            ('staged "--cached")
-            (`(stash . ,value) (error "stash is not yet implemented"))
-            (`(commit . ,value) (format "%s^..%s" value value))
-            ((and range (pred stringp)) range)
-            (_ (magit-diff-read-range-or-commit "Range/Commit"))))))
-  (let ((name (concat "*git diff difftastic"
-                      (if arg (concat " " arg) "")
-                      "*")))
-    (th/magit--with-difftastic
-     (get-buffer-create name)
-     `("git" "--no-pager" "diff" "--ext-diff" ,@(when arg (list arg))))))
-
-(use-package magit
-  :unless noninteractive
-  :commands (magit-status magit-clone magit-pull magit-blame magit-log-buffer-file magit-log)
-  :bind (("C-c v c" . magit-commit)
-         ("C-c v C" . magit-checkout)
-         ("C-c v b" . magit-branch)
-         ("C-c v d" . magit-dispatch)
-         ("C-c v f" . magit-fetch)
-         ("C-c v g" . magit-blame)
-         ("C-c v l" . magit-log-buffer-file)
-         ("C-c v L" . magit-log)
-         ("C-c v p" . magit-pull)
-         ("C-c v P" . magit-push)
-         ("C-c v r" . magit-rebase)
-	 ("C-c v s" . magit-stage)
-         ("C-c v v" . magit-status))
-  :config
-  (transient-define-prefix th/magit-aux-commands ()
-    "My personal auxiliary magit commands."
-    ["Auxiliary commands"
-     ("d" "Difftastic Diff (dwim)" th/magit-diff-with-difftastic)
-     ("s" "Difftastic Show" th/magit-show-with-difftastic)])
-  (transient-append-suffix 'magit-dispatch "!"
-    '("#" "My Magit Cmds" th/magit-aux-commands))
-  (setq-default magit-save-repository-buffers 'dontask
-                magit-refs-show-commit-count 'all
-                magit-branch-prefer-remote-upstream '("main")
-		magit-display-buffer-function #'magit-display-buffer-fullframe-status-v1
-		magit-bury-buffer-function #'magit-restore-window-configuration
-		magit-refresh-status-buffer nil)
-
-  (setq-default git-commit-summary-max-length 50
-                git-commit-style-convention-checks
-                '(non-empty-second-line
-                  overlong-summary-line))
-
-;; TODO: complete with list of issues (async ?)
-;;   (transient-append-suffix 'git-commit-insert-trailer "t"
-;;   '("i" "Issue numero" hello))
-;; 
-;; (defun hello (foo)
-;;   (interactive (list (completing-read "Foo number"
-;; 				'("foo" "bar" "baz"))))
-;;   (message foo)
-;;   (git-commit--insert-trailer "Hello" foo))
-
-  ;; (magit-define-popup-option 'magit-rebase-popup
-  ;;                            ?S "Sign using gpg" "--gpg-sign=" #'magit-read-gpg-secret-key)
-  (magit-define-popup-switch 'magit-log-popup
-                             ?m "Omit merge commits" "--no-merges")
-  ;; cargo-culted from https://github.com/magit/magit/issues/3717#issuecomment-734798341
-  ;; valid gitlab options are defined in https://docs.gitlab.com/ee/user/project/push_options.html
-  ;;
-  ;; the second argument to transient-append-suffix is where to append
-  ;; to, not sure what -u is, but this works
-  (transient-append-suffix 'magit-push "-u"
-    '(1 "=s" "Skip gitlab pipeline" "--push-option=ci.skip"))
-  (transient-append-suffix 'magit-push "=s"
-    '(1 "=m" "Create gitlab merge-request" "--push-option=merge_request.create"))
-  (transient-append-suffix 'magit-push "=m"
-    '(1 "=o" "Set push option" "--push-option="))  ;; Will prompt, can only set one extra
-
-  (defun vde/fetch-and-rebase-from-upstream ()
-    ""
-    (interactive)
-    (magit-fetch-all "--quiet")
-    (magit-git-rebase (concat "upstream/" (vc-git--symbolic-ref (buffer-file-name))) "-sS"))
-  
-  ;; Hide "Recent Commits"
-  (magit-add-section-hook 'magit-status-sections-hook
-                          'magit-insert-modules
-                          'magit-insert-unpushed-to-upstream
-                          'magit-insert-unpulled-from-upstream)
-  ;; No need for tag in the status header
-  (remove-hook 'magit-status-sections-hook 'magit-insert-tags-header)
-  (setq-default magit-module-sections-nested nil)
-
-  ;; Show refined hunks during diffs
-  (set-default 'magit-diff-refine-hunk t))
-
-(use-package gitconfig-mode
-  :commands (gitconfig-mode)
-  :mode (("/\\.gitconfig\\'"  . gitconfig-mode)
-         ("/\\.git/config\\'" . gitconfig-mode)
-         ("/git/config\\'"    . gitconfig-mode)
-         ("/\\.gitmodules\\'" . gitconfig-mode)))
-
-(use-package gitignore-mode
-  :commands (gitignore-mode)
-  :mode (("/\\.gitignore\\'"        . gitignore-mode)
-         ("/\\.git/info/exclude\\'" . gitignore-mode)
-         ("/git/ignore\\'"          . gitignore-mode)))
-
-(use-package gitattributes-mode
-  :commands (gitattributes-mode)
-  :mode (("/\\.gitattributes" . gitattributes-mode)))
-
-(use-package dired-git-info
-  :disabled
-  :bind (:map dired-mode-map
-              (")" . dired-git-info-mode))
-  :defer 2)
-
-(defun git-blame-line ()
-  "Runs `git blame` on the current line and
-   adds the commit id to the kill ring"
-  (interactive)
-  (let* ((line-number (save-excursion
-                        (goto-char (point-at-bol))
-                        (+ 1 (count-lines 1 (point)))))
-         (line-arg (format "%d,%d" line-number line-number))
-         (commit-buf (generate-new-buffer "*git-blame-line-commit*")))
-    (call-process "git" nil commit-buf nil
-                  "blame" (buffer-file-name) "-L" line-arg)
-    (let* ((commit-id (with-current-buffer commit-buf
-                        (buffer-substring 1 9)))
-           (log-buf (generate-new-buffer "*git-blame-line-log*")))
-      (kill-new commit-id)
-      (call-process "git" nil log-buf nil
-                    "log" "-1" "--pretty=%h   %an   %s" commit-id)
-      (with-current-buffer log-buf
-        (message "Line %d: %s" line-number (buffer-string)))
-      (kill-buffer log-buf))
-    (kill-buffer commit-buf)))
-
-(use-package diff-hl
-  :hook (find-file . diff-hl-mode)
-  :hook (prog-mode . diff-hl-mode)
-  :hook (magit-post-refresh . diff-hl-magit-post-refresh)
-  :bind
-  (:map diff-hl-command-map
-	("n" . diff-hl-next-hunk)
-	("p" . diff-hl-previous-hunk)
-	("[" . nil)
-	("]" . nil)
-	("DEL"   . diff-hl-revert-hunk)
-	("<delete>" . diff-hl-revert-hunk)
-	("SPC" . diff-hl-mark-hunk)
-	:map vc-prefix-map
-	("n" . diff-hl-next-hunk)
-	("p" . diff-hl-previous-hunk)
-	("s" . diff-hl-stage-dwim)
-	("DEL"   . diff-hl-revert-hunk)
-	("<delete>" . diff-hl-revert-hunk)
-	("SPC" . diff-hl-mark-hunk))
-  :config
-  (put 'diff-hl-inline-popup-hide
-       'repeat-map 'diff-hl-command-map))
-
-(use-package diff-hl-inline-popup
-  :after (diff-hl))
-(use-package diff-hl-show-hunk
-  :after (diff-hl))
-
-(use-package diff-hl-dired
-  :after (diff-hl)
-  :hook (dired-mode . diff-hl-dired-mode))
-
-(use-package consult-vc-modified-files
-  :after consult
-  :bind
-  ("C-x v /" . consult-vc-modified-files))
-
-;; FIXME bind pr-review-submit-review
-(use-package pr-review
-  :commands (pr-review pr-review-open pr-review-submit-review)
-;;  :bind
-;;  (("M-<SPC> p r" . pr-review-submit-review))
-  :custom
-  (pr-review-ghub-host "api.github.com")
-  (pr-review-notification-include-read nil)
-  (pr-review-notification-include-unsubscribed nil))
-
-(use-package pr-review-search
-  :commands (pr-review-search pr-review-search-open pr-review-current-repository pr-review-current-repository-search)
-;;  :bind
-;;  (("M-<SPC> p a" . pr-review-current-repository)
-;;   ;; FIXME understand why this one doesn't work
-  ;;  ("M-<SPC> p s" . pr-review-current-repository-search)))
-  )
-
-(use-package pr-review-notification
-  :commands (pr-review-notification)
-;;  :bind
-  ;;  (("M-<SPC> p n" . pr-review-notification)))
-  )
-
-(defun pr-review-current-repository-search (query)
-  "Run pr-review-search on the current repository."
-  (interactive "sSearch query: ")
-  (pr-review-search (format "is:pr archived:false is:open repo:%s %s" (vde/gh-get-current-repo) query)))
-
-(defun pr-review-current-repository ()
-  "Run pr-review-search on the current repository."
-  (interactive)
-  (pr-review-search (format "is:pr archived:false is:open repo:%s" (vde/gh-get-current-repo))))
-
-;; (pr-review-search "build is:pr archive:false is:open repo:tektoncd/pipeline")
-;; (pr-review-search "build")
-
-;; TODO this is relatively slow. Cache result or ?
-(defun vde/gh-get-current-repo ()
-  "Get the current repository name using the `gh' command line."
-  (unless (executable-find "gh")
-    (error "GitHub CLI (gh) command not found"))
-
-  (with-temp-buffer
-    (let ((exit-code (call-process "gh" nil t nil "repo" "view" "--json" "owner,name" "--template" "{{.owner.login}}/{{.name}}")))
-      (unless (= exit-code 0)
-	(error "Failed to get repository info: gh command exited with code %d" exit-code))
-      (string-trim (buffer-string)))))
-
-
-(provide 'config-vcs)
-;;; config-vcs.el ends here
tools/emacs/config/config-web.el
@@ -1,97 +0,0 @@
-;;; config-web.el --- -*- lexical-binding: t; -*-
-;;; Commentary:
-;;; Web related configuration, notably the built-in web browser.
-;;; Code:
-
-;; (use-package shr
-;;   :config
-;;   (setq shr-use-fonts nil)
-;;   (setq shr-use-colors nil)
-;;   (setq shr-bullet "• ")
-;;   (setq shr-folding-mode t)
-;; 
-;;   (setq shr-max-image-proportion 0.7)
-;;   (setq shr-image-animate nil)
-;;   (setq shr-width (current-fill-column)))
-;; 
-;; (use-package shr-tag-pre-highlight
-;;   :after shr
-;;   :config
-;;   (add-to-list 'shr-external-rendering-functions
-;;                '(pre . shr-tag-pre-highlight))
-;;   (when (version< emacs-version "26")
-;;     (with-eval-after-load 'eww
-;;       (advice-add 'eww-display-html :around
-;;                   'eww-display-html--override-shr-external-rendering-functions))))
-;; 
-;; (use-package eww
-;;   :commands (eww
-;;              eww-browse-url
-;;              eww-search-words
-;;              eww-open-in-new-buffer
-;;              eww-open-file
-;;              vde/eww-visit-history)
-;;   :config
-;;   (setq eww-restore-desktop nil)
-;;   (setq eww-desktop-remove-duplicates t)
-;;   (setq eww-header-line-format "%u")
-;;   (setq eww-search-prefix "https://duckduckgo.com/html/?q=")
-;;   (setq url-privacy-level '(email agent cookies lastloc))
-;;   (setq eww-download-directory "~/desktop/downloads/")
-;;   (setq eww-suggest-uris
-;;         '(eww-links-at-point
-;;           thing-at-point-url-at-point))
-;;   (setq eww-bookmarks-directory "~/.emacs.d/eww-bookmarks/")
-;;   (setq eww-history-limit 150)
-;;   (setq eww-use-external-browser-for-content-type
-;;         "\\`\\(video/\\|audio/\\|application/pdf\\)")
-;;   (setq eww-browse-url-new-window-is-tab nil)
-;;   (setq eww-form-checkbox-selected-symbol "[X]")
-;;   (setq eww-form-checkbox-symbol "[ ]")
-;; 
-;;   ;; eww-view-source
-;; 
-;;   (defvar vde/eww-mode-global-map
-;;     (let ((map (make-sparse-keymap)))
-;;       (define-key map "s" 'eww-search-words)
-;;       (define-key map "o" 'eww-open-in-new-buffer)
-;;       (define-key map "f" 'eww-open-file)
-;;       map)
-;;     "Key map to scope `eww' bindings for global usage.
-;; The idea is to bind this to a prefix sequence, so that its
-;; defined keys follow the pattern of <PREFIX> <KEY>.")
-;;   :bind-keymap ("C-x w" . vde/eww-mode-global-map)
-;;   :bind (:map eww-mode-map
-;;               ("n" . next-line)
-;;               ("p" . previous-line)
-;;               ("f" . forward-char)
-;;               ("b" . backward-char)
-;;               ("B" . eww-back-url)
-;;               ("N" . eww-next-url)
-;;               ("P" . eww-previous-url)))
-
-(use-package browse-url
-  :after eww
-  :config
-
-  ;; (defun browse-url-xdg-desktop-portal (url &rest args)
-  ;;   "Open URL via a portal backend."
-  ;;   (dbus-call-method :session
-  ;;                     "org.freedesktop.portal.Desktop"
-  ;;                     "/org/freedesktop/portal/desktop"
-  ;;                     "org.freedesktop.portal.OpenURI"
-  ;;                     "OpenURI"
-  ;;                     "" url '(:array :signature "{sv}")))
-  ;; (setopt browse-url-browser-function #'browse-url-xdg-desktop-portal)
-  ;; (setq browse-url-browser-function #'eww-browse-url)
-
-  ;; (setq browse-url-generic-program "google-chrome-stable")
-  (setq browse-url-handlers '(("^https://gitlab.com.*" . browse-url-default-browser)
-                              ("^https://github.com.*" . browse-url-default-browser)
-                              ("^https://issues.redhat.com.*" . browse-url-default-browser)
-                              ("^https://.*redhat.com.*" . browse-url-default-browser)
-                              ("^https://docs.jboss.org.*" . browse-url-default-browser)
-                              (".*" . eww-browse-url))))
-
-(provide 'config-web)
-;;; config-web.el ends here
tools/emacs/config/config-windows.el
@@ -1,304 +0,0 @@
-;;; config-windows.el ---  -*- lexical-binding: t; -*-
-;; Commentary:
-;;; Windows configuration
-;; Code:
-
-(setq switch-to-buffer-obey-display-actions t)
-
-(defun vde/window-delete-popup-frame (&rest _)
-  "Kill selected selected frame if it has parameter `prot-window-popup-frame'.
-Use this function via a hook."
-  (when (frame-parameter nil 'vde/window-popup-frame)
-    (delete-frame)))
-
-(defun vde/save-desktop-no-ask ()
-  "Save the desktop without asking questions by modifying the modtime."
-  (interactive)
-  (require 'desktop)
-  (desktop--get-file-modtime)
-  (desktop-save (concat desktop-dirname)))
-(defun vde/desktop-load ()
-  "Load saved desktop"
-  (interactive)
-  (require 'desktop)
-  (desktop-read desktop-dirname))
-
-(bind-key "C-c d s" #'vde/save-desktop-no-ask)
-(bind-key "C-c d l" #'vde/desktop-load)
-
-;; Winner
-(use-package winner
-  :unless noninteractive
-  :defer 5
-  :config
-  (winner-mode 1))
-;; -UseWinner
-
-(defun toggle-maximize-buffer ()
-  "Maximize buffer"
-  (interactive)
-  (if (one-window-p)
-      (winner-undo)
-    (delete-other-windows)))
-
-;; UseAceWindow
-(use-package ace-window
-  :unless noninteractive
-  :commands (ace-window ace-swap-window)
-  :bind (("C-x o"   . ace-window)
-         ("C-c w w" . ace-window)
-         ("C-c w s" . ace-swap-window))
-  :config
-  (setq-default aw-keys '(?a ?u ?i ?e ?, ?c ?t ?r ?m)
-                aw-scope 'frame
-                aw-dispatch-always t
-                aw-dispatch-alist
-                '((?s aw-swap-window "Swap Windows")
-                  (?2 aw-split-window-vert "Split Window Vertically")
-                  (?3 aw-split-window-horz "Split Window Horizontally")
-                  (?? aw-show-dispatch-help))
-                aw-minibuffer-flag t
-                aw-ignore-current nil
-                aw-display-mode-overlay t
-                aw-background t))
-;; -UseAceWindow
-
-;; UseWindmove
-(use-package windmove
-  :unless noninteractive
-  :commands (windmove-left windmove-right windmove-down windmove-up)
-  :custom
-  (windmove-allow-all-windows t)
-  :bind (("C-M-<up>" . windmove-up)
-         ("C-M-<right>" . windmove-right)
-         ("C-M-<down>" . windmove-down)
-         ("C-M-<left>" . windmove-left)))
-;; -UseWindmove
-
-;; UseWindow
-(use-package window
-  :unless noninteractive
-  :commands (shrink-window-horizontally shrink-window enlarge-window-horizontally enlarge-window)
-  :bind (("S-C-<left>" . shrink-window-horizontally)
-         ("S-C-<right>" . enlarge-window-horizontally)
-         ("S-C-<down>" . shrink-window)
-         ("S-C-<up>" . enlarge-window)))
-;; -UseWindow
-
-;;;###autoload
-(defun prot-common-window-small-p ()
-  "Return non-nil if window is small.
-Check if the `window-width' or `window-height' is less than
-`split-width-threshold' and `split-height-threshold',
-respectively."
-  (or (and (numberp split-width-threshold)
-           (< (window-total-width) split-width-threshold))
-      (and (numberp split-height-threshold)
-           (> (window-total-height) split-height-threshold))))
-
-(defun prot-common-three-or-more-windows-p (&optional frame)
-  "Return non-nil if three or more windows occupy FRAME.
-If FRAME is non-nil, inspect the current frame."
-  (>= (length (window-list frame :no-minibuffer)) 3))
-
-(defun prot-window--get-display-buffer-below-or-pop ()
-  "Return list of functions for `prot-window-display-buffer-below-or-pop'."
-  (list
-   #'display-buffer-reuse-mode-window
-   (if (or (prot-common-window-small-p)
-           (prot-common-three-or-more-windows-p))
-       #'display-buffer-below-selected
-     #'display-buffer-pop-up-window)))
-
-(defun prot-window-display-buffer-below-or-pop (&rest args)
-  "Display buffer below current window or pop a new window.
-The criterion for choosing to display the buffer below the
-current one is a non-nil return value for
-`prot-common-window-small-p'.
-
-Apply ARGS expected by the underlying `display-buffer' functions.
-
-This as the action function in a `display-buffer-alist' entry."
-  (let ((functions (prot-window--get-display-buffer-below-or-pop)))
-    (catch 'success
-      (dolist (fn functions)
-        (when (apply fn args)
-          (throw 'success fn))))))
-
-(defvar prot-window-window-sizes
-  '( :max-height (lambda () (floor (frame-height) 3))
-     :min-height 10
-     :max-width (lambda () (floor (frame-width) 4))
-     :min-width 20)
-  "Property list of maximum and minimum window sizes.
-The property keys are `:max-height', `:min-height', `:max-width',
-and `:min-width'.  They all accept a value of either a
-number (integer or floating point) or a function.")
-
-(defun prot-window--get-window-size (key)
-  "Extract the value of KEY from `prot-window-window-sizes'."
-  (when-let ((value (plist-get prot-window-window-sizes key)))
-    (cond
-     ((functionp value)
-      (funcall value))
-     ((numberp value)
-      value)
-     (t
-      (error "The value of `%s' is neither a number nor a function" key)))))
-
-(defun prot-window-select-fit-size (window &rest _)
-  "Select WINDOW and resize it.
-The resize pertains to the maximum and minimum values for height
-and width, per `prot-window-window-sizes'.
-
-Use this as the `body-function' in a `display-buffer-alist' entry."
-  (select-window window)
-  (fit-window-to-buffer
-   window
-   (prot-window--get-window-size :max-height)
-   (prot-window--get-window-size :min-height)
-   (prot-window--get-window-size :max-width)
-   (prot-window--get-window-size :min-width)))
-
-(defun prot-window-shell-or-term-p (buffer &rest _)
-  "Check if BUFFER is a shell or terminal.
-This is a predicate function for `buffer-match-p', intended for
-use in `display-buffer-alist'."
-  (when (string-match-p "\\*.*\\(e?shell\\|v?term\\).*" (buffer-name (get-buffer buffer)))
-    (with-current-buffer buffer
-      ;; REVIEW 2022-07-14: Is this robust?
-      (and (not (derived-mode-p 'message-mode 'text-mode))
-           (derived-mode-p 'eshell-mode 'shell-mode 'comint-mode 'fundamental-mode)))))
-
-;; (setq display-buffer-alist
-;;       `(;; Default to no window
-;; 	("\\`\\*Async Shell Command\\*\\'"
-;; 	 (display-buffer-no-window))
-;; 	("\\`\\*Warnings\\*\\'"
-;;          (display-buffer-no-window)
-;; 	 (allow-no-window . t))
-;; 	("\\`\\*\\(Compile-Log\\|Org Links\\)\\*\\'"
-;;          (display-buffer-no-window))
-;; 	;; bottom side window
-;;         ("\\*Org \\(Select\\|Note\\)\\*" ; the `org-capture' key selection and `org-add-log-note'
-;;          (display-buffer-in-side-window)
-;;          (dedicated . t)
-;;          (side . bottom)
-;;          (slot . 0)
-;;          (window-parameters . ((mode-line-format . none))))
-;; 	;; bottom buffer (NOT side window)
-;;         ((or . ((derived-mode . flymake-diagnostics-buffer-mode)
-;;                 (derived-mode . flymake-project-diagnostics-mode)
-;;                 (derived-mode . messages-buffer-mode)
-;;                 (derived-mode . backtrace-mode)))
-;;          (display-buffer-reuse-mode-window display-buffer-at-bottom)
-;;          (window-height . 0.3)
-;;          (dedicated . t)
-;;          (preserve-size . (t . t)))
-;; 	;; ((or . ((derived-mode . Man-mode)
-;; 	;; 	(derived-mode . woman-mode)
-;; 	;; 	"\\*\\(Man\\|woman\\).*"))
-;; 	;;  (display-buffer-reuse-mode-window display-buffer-below-selected)
-;;         ;;  (window-height . 0.3) ; note this is literal lines, not relative
-;;         ;;  (dedicated . t)
-;;         ;;  (preserve-size . (t . t)))
-;; 	;; below current window
-;; 	("\\(\\*Capture\\*\\|CAPTURE-.*\\)"
-;;          (display-buffer-reuse-mode-window display-buffer-below-selected))
-;; 	((derived-mode . reb-mode) ; M-x re-builder
-;;          (display-buffer-reuse-mode-window display-buffer-below-selected)
-;;          (window-height . 4) ; note this is literal lines, not relative
-;;          (dedicated . t)
-;;          (preserve-size . (t . t)))
-;; 	((or . ((derived-mode . occur-mode)
-;;                 (derived-mode . grep-mode)
-;;                 (derived-mode . Buffer-menu-mode)
-;;                 (derived-mode . log-view-mode)
-;; 		(derived-mode . helpful-mode)
-;;                 (derived-mode . help-mode) ; See the hooks for `visual-line-mode'
-;;                 "\\*\\(|Buffer List\\|Occur\\|vc-change-log\\).*"
-;;                 prot-window-shell-or-term-p
-;;                 ,world-clock-buffer-name))
-;;          (prot-window-display-buffer-below-or-pop)
-;;          (dedicated . t)
-;;          (body-function . prot-window-select-fit-size))
-;; 	))
-
-(use-package auto-side-windows
-  :custom
-  ;; Top side window configurations
-  (auto-side-windows-top-buffer-names
-   '("^\\*Backtrace\\*$" "^\\*Compile-Log\\*$" "^COMMIT_EDITMSG$"
-     "^\\*Org Src.*\\*" "^\\*Agenda Commands\\*$" "^\\*Org Agenda\\*$"
-     "^\\*Quick Help\\*$" "^\\*Multiple Choice Help\\*$" "^\\*TeX Help\\*$"
-     "^\\*TeX errors\\*$" "^\\*Warnings\\*$" "^\\*diff-hl\\*$"
-     "^\\*Process List\\*$"))
-  (auto-side-windows-top-buffer-modes
-   '(flymake-diagnostics-buffer-mode locate-mode occur-mode grep-mode
-                                     xref--xref-buffer-mode))
-
-  ;; Bottom side window configurations
-  (auto-side-windows-bottom-buffer-names
-   '("^\\*.*eshell.*\\*$" "^\\*.*shell.*\\*$" "^\\*.*term.*\\*$"
-     "^\\*.*vterm.*\\*$" "^\\*.*eat.*\\*$"))
-  (auto-side-windows-bottom-buffer-modes
-   '(eshell-mode shell-mode term-mode vterm-mode comint-mode compilation-mode debugger-mode))
-
-  ;; Right side window configurations
-  (auto-side-windows-right-buffer-names
-   '("^\\*eldoc.*\\*$" "^\\*info\\*$" "^\\*Metahelp\\*$"))
-  (auto-side-windows-right-buffer-modes
-   '(Info-mode TeX-output-mode pdf-view-mode eldoc-mode help-mode
-               helpful-mode shortdoc-mode))
-
-  ;; Example: Custom parameters for top windows (e.g., fit height to buffer)
-  ;; (auto-side-windows-top-alist '((window-height . fit-window-to-buffer)))
-  ;; (auto-side-windows-top-window-parameters '((mode-line-format . ...))) ;; Adjust mode-line
-
-  ;; Maximum number of side windows on the left, top, right and bottom
-  (window-sides-slots '(1 1 1 1)) ; Example: Allow one window per side
-
-  ;; Force left and right side windows to occupy full frame height
-  (window-sides-vertical t)
-  (window-combination-resize t)
-
-  ;; Make changes to tab-/header- and mode-line-format persistent when toggleling windows visibility
-  (window-persistent-parameters
-   (append window-persistent-parameters
-           '((tab-line-format . t)
-             (header-line-format . t)
-             (mode-line-format . t))))
-  :bind ;; Example keybindings (adjust prefix as needed)
-  (:map global-map ; Or your preferred keymap prefix
-        ("C-c w t" . auto-side-windows-display-buffer-top)
-        ("C-c w b" . auto-side-windows-display-buffer-bottom)
-        ("C-c w l" . auto-side-windows-display-buffer-left)
-        ("C-c w r" . auto-side-windows-display-buffer-right)
-        ("C-c w T" . auto-side-windows-toggle-side-window)) ; Toggle current buffer in/out of side window
-  :hook
-  (after-init . auto-side-windows-mode)) ; Activate the mode
-
-(use-package popper
-  :after auto-side-windows ; Ensure auto-side-windows variables are defined
-  :hook (auto-side-windows-mode . popper-mode) ; Activate popper alongside
-  :custom
-  ;; Tell Popper to consider buffers matching auto-side-windows rules as popups
-  (popper-reference-buffers
-   (append auto-side-windows-top-buffer-names auto-side-windows-top-buffer-modes
-           auto-side-windows-left-buffer-names auto-side-windows-left-buffer-modes
-           auto-side-windows-right-buffer-names auto-side-windows-right-buffer-modes
-           auto-side-windows-bottom-buffer-names auto-side-windows-bottom-buffer-modes))
-  ;; Optional: Don't let Popper decide where to display, auto-side-windows handles that
-  (popper-display-control nil) ; Or 'user if you prefer popper commands for display
-  :config
-  (require 'popper-echo)
-  (popper-mode +1) ; Enable popper-mode
-  (popper-echo-mode +1) ; Optional: echo area notifications
-  :bind
-  (("C-`" . popper-toggle)
-   ("C-M-`" . popper-toggle-type)
-   ("M-`" . popper-cycle)))
-;; TODO: Move display-buffer-alist here
-
-(provide 'config-windows)
-;;; config-windows ends here
tools/emacs/config/programming-config.el
@@ -1,227 +0,0 @@
-;;; programming-config.el --- -*- lexical-binding: t -*-
-;;; Commentary:
-;;; Configuration files mode configuration
-;;; Code:
-
-(defconst src-dir "~/src/"
-  "Where all my sources are.")
-(set-register ?s `(file . ,src-dir))
-
-(use-package symbol-overlay
-  :custom
-  (symbol-overlay-idle-time 0.2)
-  :bind
-  ("M-s s i" . symbol-overlay-put)
-  ("M-N" . symbol-overlay-jump-next)
-  ("M-P" . symbol-overlay-jump-prev)
-  ("M-s s r" . symbol-overlay-rename)
-  ("M-s s c" . symbol-overlay-remove-all)
-  :hook
-  (prog-mode . symbol-overlay-mode))
-
-(use-package devdocs
-  :commands (devdocs-lookup devdocs-install vde/install-devdocs)
-  :bind (("C-h D" . devdocs-lookup))
-  :config
-  (defun vde/install-devdocs ()
-    "Install the devdocs I am using the most."
-    (interactive)
-    (dolist (docset '("bash"
-		      "c"
-		      "click"
-		      "cpp"
-		      "css"
-		      "elisp"
-		      "flask"
-		      "git"
-		      "gnu_make"
-		      "go"
-		      "html"
-		      "htmx"
-		      "http"
-		      "javascript"
-		      "jq"
-		      "jquery"
-		      "kubectl"
-		      "kubernetes"
-		      "lua~5.4"
-		      "nix"
-		      "python~3.13"
-		      "python~3.12"
-		      "requests"
-		      "sqlite"
-		      "terraform"
-		      "werkzeug"
-		      "zig"))
-    (devdocs-install docset))))
-
-(use-package yaml-ts-mode
-  :mode "\\.ya?ml\\'"
-  :hook ((yaml-ts-mode . display-line-numbers-mode)
-	 (yaml-ts-mode . outline-minor-mode)
-	 (yaml-ts-mode . electric-pair-local-mode))
-  :config
-  (setq-local outline-regexp "^ *\\([A-Za-z0-9_-]*: *[>|]?$\\|-\\b\\)")
-  (font-lock-add-keywords
-   'yaml-ts-mode
-   '(("\\($(\\(workspaces\\|context\\|params\\)\.[^)]+)\\)" 1 'font-lock-constant-face prepend)
-     ("kind:\s*\\(.*\\)\n" 1 'font-lock-keyword-face prepend))))
-
-;; TODO https://github.com/zkry/yaml-pro?tab=readme-ov-file#easy-movement-with-repeat-map
-;; FIXME it currently gets in the way…
-;; (use-package yaml-pro
-;;   :after yaml-ts-mode
-;;   :hook (yaml-ts-mode . yaml-pro-ts-mode))
-
-(use-package consult-flymake
-  :after (consult)
-  :bind
-  ("M-s M-d" . consult-flymake)
-  :config
-  ;; (general-leader
-  ;;   "sd" #'(consult-flymake :which-key "Flymake diagnostics"))
-  )
-
-(use-package flymake-yamllint
-  :after yaml-ts-mode
-  :hook
-  (yaml-ts-mode . flymake-yamllint-setup))
-
-(use-package conf-mode
-  :mode ("\\.to?ml\\'" . conf-toml-mode))
-
-(use-package adoc-mode
-  :mode ("\\.adoc\\'" . conf-toml-mode))
-
-(defun repeatize (keymap)
-  "Add `repeat-mode' support to a KEYMAP."
-  (map-keymap
-   (lambda (_key cmd)
-     (when (symbolp cmd)
-       (put cmd 'repeat-map keymap)))
-   (symbol-value keymap)))
-
-(defvar flymake-repeat-map
-  (let ((map (make-sparse-keymap)))
-    (define-key map (kbd "n") 'flymake-goto-next-error)
-    (define-key map (kbd "p") 'flymake-goto-prev-error)
-    (define-key map (kbd "f") 'attrap-flymake)
-    (define-key map (kbd "M-n") 'flymake-goto-next-error)
-    (define-key map (kbd "M-p") 'flymake-goto-prev-error)
-    map))
-
-(use-package flymake
-  :defer t
-  :bind
-  (("C-c f e" . flymake-show-project-diagnostics))
-  (:map flymake-mode-map
-        ("M-n" . flymake-goto-next-error)
-        ("M-p" . flymake-goto-prev-error))
-  (
-   :map flymake-diagnostics-buffer-mode-map
-   ("p" .
-    (lambda()(interactive)
-      (previous-line)
-      (save-excursion
-        (flymake-show-diagnostic(point)))))
-   ("n" .
-    (lambda()(interactive)
-      (next-line)
-      (save-excursion
-        (flymake-show-diagnostic(point)))))
-   (
-    :map flymake-project-diagnostics-mode-map
-    ("p" .
-     (lambda()(interactive)
-       (previous-line)
-       (save-excursion
-         (flymake-show-diagnostic(point)))))
-    ("n" .
-     (lambda()(interactive)
-       (next-line)
-       (save-excursion
-         (flymake-show-diagnostic(point)))))))
-  :config
-  (repeatize 'flymake-repeat-map)
-  :hook
-  ;; (prog-mode . flyspell-prog-mode) rebind flyspell-auto-correct-previous-word
-  (prog-mode . flymake-mode))
-
-(defun my-gotest-get-current-test()
-  "Get the current test name, if we have a subtest (starting with name) then use it."
-  (interactive)
-  (require 'which-func)
-  (let ((subtest (when-let* ((subtest
-                              (progn
-                                (save-excursion
-                                  (goto-char (line-beginning-position))
-                                  (re-search-forward "name:[[:blank:]]*\"\\([^\"]*\\)\"" (line-end-position) t)))))
-                   (if subtest
-                       (shell-quote-argument (replace-regexp-in-string " " "_" (match-string-no-properties 1))))))
-        (gotest (when-let* ((test-name (which-function)))
-                  (if test-name test-name
-                    (error "No test selected")))))
-    (concat (format "^%s%s$" gotest (if subtest (concat "/" subtest) "")))))
-
-(use-package dape
-  :commands (my-dape-go-test-at-point)
-  :after go-ts-mode
-  :bind
-  (:map go-ts-mode-map
-        ("<f5>" . (lambda()(interactive)
-                    (if (dape--live-connections)
-                        (call-interactively 'dape-continue)
-                      (call-interactively 'dape))))
-        ("S-<f5>"   . dape-stop)
-        ("C-S-<f5>" . dape-restart)
-        ("<f9>"     . dape-breakpoint-toggle)
-        ("<f10>"    . dape-next)
-        ("<f11>"    . dape-step-in)
-        ("S-<f11>"    . dape-step-out))
-  :hook
-  (go-ts-mode . (lambda()
-                  (interactive)
-                  (if (string-suffix-p "_test.go"  (buffer-name))
-                      (setq-local dape-command '(delve-unit-test)))))
-  :config
-  (defun my-dape-go-test-at-point ()
-    (interactive)
-    (dape (dape--config-eval-1
-           `(modes (go-mode go-ts-mode)
-                   ensure dape-ensure-command
-                   fn dape-config-autoport
-                   command "dlv"
-                   command-args ("dap" "--listen" "127.0.0.1::autoport")
-                   command-cwd dape-cwd-fn
-                   port :autoport
-                   :type "debug"
-                   :request "launch"
-                   :mode "test"
-                   :cwd dape-cwd-fn
-                   :program (lambda () (concat "./" (file-relative-name default-directory (funcall dape-cwd-fn))))
-                   :args (lambda ()
-                           (when-let* ((test-name (my-gotest-get-current-test)))
-                             (if test-name `["-test.run" ,test-name]
-                               (error "No test selected")))))))))
-
-(defconst markdown-regex-italic
-    "\\(?:^\\|[^\\]\\)\\(?1:\\(?2:[_]\\)\\(?3:[^ \n\t\\]\\|[^ \n\t]\\(?:.\\|\n[^\n]\\)[^\\ ]\\)\\(?4:\\2\\)\\)")
-;; and/or
-(defconst markdown-regex-gfm-italic
-    "\\(?:^\\|[^\\]\\)\\(?1:\\(?2:[_]\\)\\(?3:[^ \\]\\2\\|[^ ]\\(?:.\\|\n[^\n]\\)\\)\\(?4:\\2\\)\\)")
-
-(use-package markdown-mode
-  :commands (markdown-mode gfm-mode)
-  :mode (("README\\.md\\'" . gfm-mode)
-         ("\\.md\\'" . markdown-mode)
-         ("\\.markdown\\'" . markdown-mode))
-  :hook ((markdown-mode . visual-line-mode)
-	 (gfm-mode . visual-line-mode)))
-
-(use-package orgalist
-  :commands (orgalist-mode)
-  :hook ((markdown-mode . orgalist-mode)
-	 (gfm-mode . orgalist-mode)))
-
-(provide 'programming-config)
-;;; programming-config.el ends here
tools/emacs/config/programming-containers.el
@@ -1,31 +0,0 @@
-;;; programming-containers.el --- -*- lexical-binding: t; -*-
-;;; Commentary:
-;;; Containers configuration
-;;; Code:
-(use-package dockerfile-mode
-  :mode ("Dockerfile\\'" . dockerfile-mode))
-
-;; I have a bunch of different 'profiles' for kubernetes by different cluster so
-;; i don't mess between things
-;; This allow me to set the KUBECONFIG variable between those easily
-;; TODO: add the current profile in modeline
-(defun my-switch-kubeconfig-env (&optional kubeconfig)
-  "Set KUBECONFIG environment variable for the current session"
-  (interactive
-   (list
-    (completing-read
-     "Kubeconfig: "
-     (mapcar
-      (lambda (x)
-        (replace-regexp-in-string
-         "^config\." ""
-         (file-name-nondirectory(directory-file-name x))))
-      (directory-files-recursively
-       (expand-file-name "~/.kube") "^config\.")) nil t )))
-  (setq kubeconfig (expand-file-name (format "~/.kube/config.%s" kubeconfig)))
-  (if (file-exists-p kubeconfig)
-      (setenv "KUBECONFIG" kubeconfig)
-    (error "Cannot find kubeconfig: %s" kubeconfig)))
-
-(provide 'programming-containers)
-;;; programming-containers.el ends here
tools/emacs/config/programming-cue.el
@@ -1,9 +0,0 @@
-;;; programming-cue.el --- -*- lexical-binding: t; -*-
-;;; Commentary:
-;;; Cue "data" language configuration
-;;; Code:
-(use-package cue-mode
-  :commands (cue-mode)
-  :mode "\\.cue$")
-
-(provide 'programming-cue)
tools/emacs/config/programming-eglot.el
@@ -1,49 +0,0 @@
-;;; programming-eglot.el --- -*- lexical-binding: t; -*-
-;;; Commentary:
-;;; Eglot configuration
-;;; Code:
-(use-package eglot
-  :bind
-  (:map eglot-mode-map
-        ("C-c e a" . eglot-code-actions)
-        ("C-c e r" . eglot-reconnect)
-        ("<f2>" . eglot-rename)
-        ("C-c e ?" . eldoc-print-current-symbol-info))
-  :config
-  (add-to-list 'eglot-ignored-server-capabilities :documentHighlightProvider)
-  (add-to-list 'eglot-server-programs `(json-mode  "vscode-json-language-server" "--stdio"))
-  (add-to-list 'eglot-server-programs '(nix-mode . ("nil")))
-  (setq-default eglot-workspace-configuration
-		'(:gopls (:usePlaceholders t)))
-  (setq-default
-   eglot-workspace-configuration
-   '((:gopls . ((gofumpt . t)))))
-  :hook
-  (before-save . gofmt-before-save)
-  (before-save . eglot-format-buffer)
-  (nix-mode . eglot-ensure)
-  (nix-ts-mode . eglot-ensure)
-  (rust-mode . eglot-ensure)
-  (rust-ts-mode . eglot-ensure)
-  (sh-script-mode . eglot-ensure)
-  (python-mode . eglot-ensure)
-  (json-mode . eglot-ensure)
-  (yaml-mode . eglot-ensure)
-  (c-mode . eglot-ensure)
-  (cc-mode . eglot-ensure)
-  (go-mode . eglot-ensure)
-  (go-ts-mode . eglot-ensure)
-  (js-mode . eglot-ensure)
-  (js2-mode . eglot-ensure)
-  (typescript-mode . eglot-ensure)
-  (typescript-ts-mode . eglot-ensure))
-
-(use-package eldoc-box
-  :hook
-  (eglot-managed-mode . eldoc-box-hover-mode)
-  :custom
-  (eldoc-box-max-pixel-width 1024))
-
-
-(provide 'programming-eglot)
-;;; programming-eglot.el ends here
tools/emacs/config/programming-elisp.el
@@ -1,9 +0,0 @@
-;;; programming-elisp.el --- -*- lexical-binding: t; -*-
-;;; Commentary:
-;;; Emacs lisp programming language configuration
-;;; Code:
-(use-package smartparens
-  :hook ((emacs-lisp-mode . smartparens-mode)))
-
-(provide 'programming-elisp)
-;;; programming-elisp.el ends here
tools/emacs/config/programming-go.el
@@ -1,107 +0,0 @@
-;;; programming-go.el --- -*- lexical-binding: t; -*-
-;;; Commentary:
-;;; Go programming language configuration
-;;; Code:
-
-(declare-function project-root "project")
-(declare-function project-current "project")
-(declare-function vde-project--project-root-or-default-directory "proj-func")
-(declare-function go-test--get-current-file-tests "gotest")
-
-(use-package gotest
-  :commands (my-gotest-maybe-ts-run go-test--get-current-test-info go-test--get-current-file-tests)
-  :after go-ts-mode
-  :custom
-  (go-test-verbose t)
-  :hook
-  (go-test-mode . (lambda () (pop-to-buffer (get-buffer "*Go Test*"))))
-  (go-mode . (lambda ()(interactive) (setq go-run-args "-v")))
-  (go-ts-mode . (lambda ()(interactive) (setq go-run-args "-v")))
-  :config
-  (defun my-go-test-current-project()
-    (interactive)
-    (let ((default-directory (project-root (project-current t))))
-      (go-test-current-project)))
-  (defun my-gotest-maybe-ts-run()
-    (interactive)
-    (let ((testrunname)
-          (gotest (cadr (go-test--get-current-test-info))))
-      (save-excursion
-        (goto-char (line-beginning-position))
-        (re-search-forward "name:[[:blank:]]*\"\\([^\"]*\\)\"" (line-end-position) t))
-      (setq testrunname (match-string-no-properties 1))
-      (if testrunname
-          (setq gotest (format "%s/%s" gotest (shell-quote-argument
-                                               (replace-regexp-in-string " " "_" testrunname)))))
-      (go-test--go-test (concat "-run " gotest "\\$ .")))))
-
-(use-package gotest-ts
-  :bind (("C-c C-t t" . gotest-ts-run-dwim)))
-
-(defun go-mode-p ()
-  "Return non-nil value when the major mode is `go-mode' or `go-ts-mode'."
-  (memq major-mode '(go-ts-mode go-mode)))
-
-;; TODO (defun run-command-recipe-ko ())
-
-(defun run-command-recipe-go ()
-  "Go `run-command' recipes."
-  (when (buffer-file-name) ;; no buffer-file-name means virtual buffer (dired, …)
-    
-    (let* ((dir (vde-project--project-root-or-default-directory))
-	   (package (file-name-directory (concat "./" (file-relative-name (buffer-file-name) dir)))))
-      (when (or (go-mode-p) (file-exists-p (expand-file-name "go.mod" dir)))
-	(append
-	 (and (buffer-file-name) (go-mode-p)
-	      (list
-	       (list :command-name "gofumpt"
-		     :command-line (concat "gofumpt -extra -w " (buffer-file-name))
-		     :working-dir dir
-		     :display "gofumpt (reformat) file")
-	       (list :command-name "go-fmt"
-		     :command-line (concat "go fmt " (buffer-file-name))
-		     :working-dir dir
-		     :display "gofmt (reformat) file")
-	       (list :command-name "go-run"
-		     :command-line (concat "go run " (buffer-file-name))
-		     :working-dir dir
-		     :display "Compile, execute file")))
-	 (and (string-suffix-p "_test.go" buffer-file-name) (go-mode-p)
-	      (list
-	       (let ((runArgs (go-test--get-current-file-tests)))
-		 ;; go test current test
-		 ;; go test current file
-		 (list :command-name "go-test-file"
-		       :command-line (concat "go test -v " package " -run " (shell-quote-argument runArgs))
-		       :working-dir dir
-		       :display (concat "Test file " (concat "./"(file-relative-name (buffer-file-name) dir)))
-		       :runner 'run-command-runner-compile)
-		 )))
-	 ;; TODO: handle test file as well
-	 (list
-	  (list :command-name "go-build-project"
-		:command-line "go build -v ./..."
-		:working-dir dir
-		:display "compile package and dependencies"
-		:runner 'run-command-runner-compile)
-	  (list :command-name "go-test-project"
-		:command-line "go test ./..."
-		:working-dir dir
-		:display "test all"
-		:runner 'run-command-runner-compile)
-	  (list :command-name "go-test-package"
-		:command-line (concat "go test -v " package)
-		:working-dir dir
-		:display (concat "Test package " package)
-		:runner 'run-command-runner-compile)))))))
-
-(with-eval-after-load 'run-command
-  (add-to-list 'run-command-recipes 'run-command-recipe-go))
-
-(use-package go-ts-mode
-  :mode (("\\.go$" . go-ts-mode)
-         ("\\.go" . go-ts-mode)
-         ("\\.go\\'" . go-ts-mode)))
-
-(provide 'programming-go)
-;;; programming-go.el ends here
tools/emacs/config/programming-js.el
@@ -1,24 +0,0 @@
-;;; programming-js.el --- -*- lexical-binding: t; -*-
-;;; Commentary:
-;;; Javascript and Typescript programming language configuration
-;;; Code:
-
-(use-package js2-mode
-  :hook
-  (js2-mode . js-ts-mode-hook))
-
-(use-package typescript-mode
-  :hook
-  (typescript-mode . typescript-ts-mode-hook))
-
-(use-package typescript-ts-mode
-  :mode (("\\.ts\\'" . typescript-ts-mode)
-         ("\\.tsx\\'" . tsx-ts-mode)))
-
-(use-package json-mode
-  :mode (("\\.json\\'" . json-ts-mode))
-  :hook
-  (json-mode . json-ts-mode-hook))
-  
-(provide 'programming-js)
-;;; programming-js.el ends here
tools/emacs/config/programming-nix.el
@@ -1,28 +0,0 @@
-;;; programming-nix.el --- -*- lexical-binding: t; -*-
-;;; Commentary:
-;;; Nix configuration
-;;; Code:
-(use-package nix-ts-mode
-  :if (executable-find "nix")
-  :mode ("\\.nix\\'" "\\.nix.in\\'"))
-
-(use-package nix-drv-mode
-  :if (executable-find "nix")
-  :after nix-mode
-  :mode "\\.drv\\'")
-
-(use-package nix-shell
-  :if (executable-find "nix")
-  :after nix-mode
-  :commands (nix-shell-unpack nix-shell-configure nix-shell-build))
-
-(use-package nixpkgs-fmt
-  :if (executable-find "nix")
-  :after nix-ts-mode
-  ;; :custom
-  ;; (nixpkgs-fmt-command "nixfmt")
-  :config
-  (add-hook 'nix-ts-mode-hook 'nixpkgs-fmt-on-save-mode))
-
-(provide 'programming-nix)
-;;; programming-nix.el ends here
tools/emacs/config/programming-treesitter.el
@@ -1,22 +0,0 @@
-;;; programming-treesitter.el --- -*- lexical-binding: t; -*-
-;;; Commentary:
-;;; Treesitter configuration
-;;; Code:
-
-
-(use-package indent-bars
-  :if (eq system-type 'gnu/linux)
-  :hook
-  (python-mode . indent-bars-mode)
-  (yaml-ts-mode . indent-bars-mode)
-  :config
-  (require 'indent-bars-ts)
-  :custom
-  (indent-bars-no-descend-lists t)
-  (indent-bars-treesit-support t)
-  (indent-bars-treesit-ignore-blank-lines-types '("module"))
-  (indent-bars-treesit-scope '((python function_definition class_definition for_statement
-	                               if_statement with_statement while_statement))))
-
-(provide 'programming-treesitter)
-;;; programming-treesitter.el ends here
tools/emacs/config/programming-web.el
@@ -1,41 +0,0 @@
-;;; programming-web.el --- -*- lexical-binding: t -*-
-;;; Commentary:
-;;; Programming the Web related configuration
-;;; Code:
-
-(use-package web-mode
-  :commands (web-mode)
-  :mode
-  ("\\.html\\'" . web-mode)
-  ("\\.phtml\\'" . web-mode)
-  ("\\.[agj]sp\\'" . web-mode)
-  ("\\.as[cp]x\\'" . web-mode)
-  ("\\.erb\\'" . web-mode)
-  ("\\.mustache\\'" . web-mode)
-  ("\\.djhtml\\'" . web-mode)
-  ("\\.jsp\\'" . web-mode)
-  ("\\.eex\\'" . web-mode)
-  ("\\.tsx\\'" . web-mode)
-  :config
-  (setq web-mode-attr-indent-offset 2)
-  (setq web-mode-code-indent-offset 2)
-  (setq web-mode-css-indent-offset 2)
-  (setq web-mode-indent-style 2)
-  (setq web-mode-markup-indent-offset 2)
-  (setq web-mode-sql-indent-offset 2)
-  (eval-after-load 'smartparens
-    (lambda ()
-      (setq web-mode-enable-auto-pairing nil)
-      (sp-with-modes '(web-mode)
-        (sp-local-pair "%" "%"
-                       :unless '(sp-in-string-p)
-                       :post-handlers '(((lambda (&rest _ignored)
-                                           (just-one-space)
-                                           (save-excursion (insert " ")))
-                                         "SPC" "=" "#")))
-        (sp-local-tag "%" "<% "  " %>")
-        (sp-local-tag "=" "<%= " " %>")
-        (sp-local-tag "#" "<%# " " %>")))))
-
-(provide 'programming-web)
-;;; programming-web.el ends here
tools/emacs/eshell/lastdir
@@ -1,8 +0,0 @@
-~
-/ssh:aomi.home:/home/vincent
-/ssh:aomi.home:/home/vincent/src
-/ssh:aomi.home:/home/vincent/src/osp
-/ssh:aomi.home:/home/vincent/src/osp/p12n
-/ssh:aomi.home:/home/vincent/src/osp/p12n/p12n
-/ssh:aomi.home:/home/vincent/src/osp/p12n/p12n/versions/1.9
-/ssh:aomi.home:/home/vincent/src/osp/p12n/p12n
tools/emacs/etc/eshell/aliases
@@ -1,3 +0,0 @@
-alias l exa -lah $*
-alias ll exa -l $*
-alias ls exa $*
tools/emacs/etc/orgmode/meeting-notes.org
@@ -1,20 +0,0 @@
-* %^{meeting}
-
-- Actions ::
-  #+BEGIN: columnview :id local :match "/TODO|DONE" :format "%ITEM(What) %TAGS(Who) %DEADLINE(When) %TODO(State)"
-  | What                                | Who        | When | State |
-  |-------------------------------------+------------+------+-------|
-  #+END:
-- Decisions ::
-  #+BEGIN: columnview :id local :match "Decision" :format "%ITEM(Decisions)"
-  | Decisions |
-  |-----------|
-  #+END:
-
-** Present at meeting
-  - [ ]
-** Agenda
-- %?
-** Notes
-- Use =:Decision:= tag for decision
-- Use entry with =TODO= (or =DONE=) for actions
tools/emacs/etc/orgmode/weekly.org
@@ -1,20 +0,0 @@
-** %(format-time-string org-journal-time-format) weekly review :weekly:review:
-%U
-
-- [ ] review [[file:../projects/inbox.org][~inbox.org~]]
-  Clean the file by either
-  - refiling it to ~incubate.org~
-  - removing it / archiving it
-- [ ] review [[file:../projects/incubate.org][~incubate.org~]]
-  - Is something worth becoming a project
-  - Is something not worth thinking about anymore ?
-- [ ] empty mail inbox (and create task if needed)
-  - [ ] work
-  - [ ] perso
-- [ ] Review next week ~F12 n w f~
-- [ ] review ~org-mode~ workflow
-  - *what works, what doesn't ?*
-  - *is there task / stuck projects ?*
-  - *enhancement possible ?*
-- Additional /notes/:
-  + …
tools/emacs/etc/transient/levels.el
@@ -1,4 +0,0 @@
-((magit-commit
-  (magit:--gpg-sign . 3))
- (magit-rebase
-  (magit:--gpg-sign . 3)))
tools/emacs/etc/transient/values.el
@@ -1,4 +0,0 @@
-((magit-commit "--signoff")
- (magit-fetch "--prune")
- (magit-submodule "--recursive" "--rebase" "--remote")
- (magit-tag "--sign"))
tools/emacs/etc/yasnippet/snippets/c++-mode/.yas-parents
@@ -1,1 +0,0 @@
-cc-mode
\ No newline at end of file
tools/emacs/etc/yasnippet/snippets/c-mode/.yas-parents
@@ -1,1 +0,0 @@
-cc-mode
\ No newline at end of file
tools/emacs/etc/yasnippet/snippets/cc-mode/add
@@ -1,4 +0,0 @@
-#name : /*** START TI ADD ***/ ... /*** END TI ADD ***/
-# --
-/*** START TI ADD ***/
-$0/*** END TI ADD ***/
tools/emacs/etc/yasnippet/snippets/cc-mode/addif
@@ -1,7 +0,0 @@
-#name : START TI ADD + #if OPENCL
-# --
-/*** START TI ADD ***/
-#if OPENCL_EXTENSIONS_SUPPORTED
-$0
-#endif /* OPENCL_EXTENSIONS_SUPPORTED */
-/*** END TI ADD ***/
\ No newline at end of file
tools/emacs/etc/yasnippet/snippets/cc-mode/class
@@ -1,71 +0,0 @@
-#name : class ... { ... }
-# --
-/**
- * @brief Summary
- *
- * Description.
- */
-class $1
-{
-  $0
-
-public:
-  /** @name Construction and Destruction
-      @{ */
-
-  $1() noexcept? {
-    TRACE_CTOR($1, "");
-  }
-
-#if defined(DEBUG_MODE)
-  virtual? ~$1() {
-    try {
-      TRACE_DTOR($1);
-    }
-    catch (...) {
-      std::terminate();
-    }
-  }
-#else
-  ~$1() = default|delete;
-#endif
-
-  /*@}*/
-
-  /** @name Assignment, Copy and Move
-      @{*/
-
-#if defined(DEBUG_MODE)
-  $1(const $1& rhs) noexcept? {
-    TRACE_CTOR($1, "copy");
-    *this = rhs;
-  }
-#else
-  $1(const $1&) = default|delete;
-#endif
-
-  $1& operator=(const $1&) = default|delete;
-  $1& operator=(const $1& rhs) noexcept? {
-    //if (this != &rhs) {
-    //}
-    return *this;
-  }
-
-#if defined(DEBUG_MODE)
-  $1($1&&r rhs) noexcept? {
-    TRACE_CTOR($1, "move");
-    *this = rhs;
-  }
-#else
-  $1($1&&r) = default|delete;
-#endif
-
-  $1& operator=($1&&r) = default|delete;
-  $1& operator=($1&&r rhs) noexcept? {
-    //if (this != &rhs) {
-    //}
-    return *this;
-  }
-
-  /*@}*/
-}; // class $1
tools/emacs/etc/yasnippet/snippets/cc-mode/com
@@ -1,6 +0,0 @@
-# -*- mode: snippet -*-
-# name: TI comment
-# --
-/*------------------------------------------------------------*/
-/* $0 */
-/*------------------------------------------------------------*/
tools/emacs/etc/yasnippet/snippets/cc-mode/fopen
@@ -1,3 +0,0 @@
-#name : FILE *fp = fopen(..., ...);
-# --
-FILE *${fp} = fopen(${"file"}, "${r}");
tools/emacs/etc/yasnippet/snippets/cc-mode/inc
@@ -1,3 +0,0 @@
-#name : #include "..."
-# --
-#include "$1"
tools/emacs/etc/yasnippet/snippets/cc-mode/inc.1
@@ -1,3 +0,0 @@
-#name : #include <...>
-# --
-#include <$1>
tools/emacs/etc/yasnippet/snippets/cc-mode/main
@@ -1,7 +0,0 @@
-#name: int main(argc, argv) { ... }
-# --
-int main(int argc, char *argv[])
-{
-    $0
-    return 0;
-}
tools/emacs/etc/yasnippet/snippets/cc-mode/misra
@@ -1,14 +0,0 @@
-#name : MISRA-C:2004 rule implementation
-# --
-/*** START TI ADD ***/
-#if MISRA_C_2004_VALIDATION
-         if (check_misra_c_2004)
-         {
-            /*----------------------------------------------------------------*/
-            /* MISRA-C:2004 - Rule ${1:Rule} (${2:required})                            */
-            /* ${3:Description} $0*/
-            /*----------------------------------------------------------------*/
-            diagnostic(misra_${2:required}_severity, ec_misra_c_2004_$1);
-         }              /* if */
-#endif /* MISRA_C_2004_VALIDATION */
-/*** END TI ADD ***/
tools/emacs/etc/yasnippet/snippets/cc-mode/ns
@@ -1,5 +0,0 @@
-#name : namespace ...
-# --
-namespace $1 {
-    $0
-}
tools/emacs/etc/yasnippet/snippets/cc-mode/once
@@ -1,8 +0,0 @@
-#name : #ifndef XXX; #define XXX; #endif
-# --
-#ifndef ${1:_`(upcase (file-name-nondirectory (file-name-sans-extension (buffer-file-name))))`_H_}
-#define $1
-
-$0
-
-#endif /* $1 */
\ No newline at end of file
tools/emacs/etc/yasnippet/snippets/cc-mode/tfunc
@@ -1,11 +0,0 @@
-#name : Texas Instruments function
-# --
-/******************************************************************************/
-/* jww (`(format-time-string "%Y-%m-%d")`): NYI                                                      */
-/******************************************************************************/
-a_boolean $1($2)
-{
-   a_boolean result = FALSE;
-   $0
-   return result;
-}				/* $1 */
tools/emacs/etc/yasnippet/snippets/cc-mode/using
@@ -1,4 +0,0 @@
-#name : using namespace ... 
-# --
-using namespace ${std};
-$0
\ No newline at end of file
tools/emacs/etc/yasnippet/snippets/emacs-lisp-mode/hdr
@@ -1,36 +0,0 @@
-;;; `(file-name-sans-extension (file-name-nondirectory buffer-file-name))` --- $1
-
-;; Copyright (C) `(format-time-string "%Y")` `user-full-name`
-
-;; Author: `user-full-name` <`user-mail-address`>
-;; Created: `(format-time-string "%d %b %Y")`
-;; Version: 1.0
-;; Keywords: $2
-;; X-URL: https://github.com/jwiegley/${3:`(file-name-sans-extension (file-name-nondirectory buffer-file-name))`}
-
-;; This program is free software; you can redistribute it and/or
-;; modify it under the terms of the GNU General Public License as
-;; published by the Free Software Foundation; either version 2, or (at
-;; your option) any later version.
-
-;; This program is distributed in the hope that it will be useful, but
-;; WITHOUT ANY WARRANTY; without even the implied warranty of
-;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-;; General Public License for more details.
-
-;; You should have received a copy of the GNU General Public License
-;; along with GNU Emacs; see the file COPYING.  If not, write to the
-;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-;; Boston, MA 02111-1307, USA.
-
-;;; Commentary:
-
-;; $0
-
-(defgroup `(file-name-sans-extension (file-name-nondirectory buffer-file-name))` nil
-  "$1"
-  :group '$4)
-
-(provide '`(file-name-sans-extension (file-name-nondirectory buffer-file-name))`)
-
-;;; `(file-name-nondirectory buffer-file-name)` ends here
tools/emacs/etc/yasnippet/snippets/emacs-lisp-mode/test
@@ -1,2 +0,0 @@
-(ert-deftest $1 ()
-  (should (equal $0)))
\ No newline at end of file
tools/emacs/etc/yasnippet/snippets/fundamental-mode/date
@@ -1,3 +0,0 @@
-#name : (current date)
-# --
-`(format-time-string "%Y-%m-%d")`
tools/emacs/etc/yasnippet/snippets/fundamental-mode/mail
@@ -1,3 +0,0 @@
-#name : (user's email)
-# --
-`user-mail-address`
\ No newline at end of file
tools/emacs/etc/yasnippet/snippets/fundamental-mode/time
@@ -1,3 +0,0 @@
-#name : (current time)
-# --
-`(current-time-string)`
\ No newline at end of file
tools/emacs/etc/yasnippet/snippets/go-mode/coloneq
@@ -1,5 +0,0 @@
-# -*- mode: snippet -*-
-# name: ... := ...
-# key: :=
-# --
-${1:x} := ${2:`%`}
\ No newline at end of file
tools/emacs/etc/yasnippet/snippets/go-mode/f
@@ -1,6 +0,0 @@
-# -*- mode: snippet -*-
-# name: func
-# --
-func ${1:fun}($2) {
-	$0
-}
\ No newline at end of file
tools/emacs/etc/yasnippet/snippets/go-mode/fm
@@ -1,6 +0,0 @@
-# -*- mode: snippet -*-
-# name: func (target) name(args) (results) { ... }
-# --
-func (${1:target}) ${2:name}(${3:args}) (${4:results}) {
-	$0
-}
\ No newline at end of file
tools/emacs/etc/yasnippet/snippets/go-mode/for
@@ -1,6 +0,0 @@
-# -*- mode: snippet -*-
-# name: for ... { ... }
-# --
-for $1 {
-	`%`$0
-}
\ No newline at end of file
tools/emacs/etc/yasnippet/snippets/go-mode/fore
@@ -1,6 +0,0 @@
-# -*- mode: snippet -*-
-# name: for key, value := range ... { ... }
-# --
-for ${1:key}, ${2:value} := range ${3:target} {
-	`%`$0
-}
\ No newline at end of file
tools/emacs/etc/yasnippet/snippets/go-mode/foreach
@@ -1,6 +0,0 @@
-# -*- mode: snippet -*-
-# name: for key, value := range ... { ... }
-# --
-for ${1:key}, ${2:value} := range ${3:target} {
-	`%`$0
-}
\ No newline at end of file
tools/emacs/etc/yasnippet/snippets/go-mode/fori
@@ -1,6 +0,0 @@
-# -*- mode: snippet -*-
-# name: for i := 0; i < n; i++ { ... }
-# --
-for ${1:i} := ${2:0}; $1 < ${3:10}; $1++ {
-	`%`$0
-}
\ No newline at end of file
tools/emacs/etc/yasnippet/snippets/go-mode/forw
@@ -1,6 +0,0 @@
-# -*- mode: snippet -*-
-# name : for ... { ... }
-# --
-for $1 {
-	`%`$0
-}
\ No newline at end of file
tools/emacs/etc/yasnippet/snippets/go-mode/func
@@ -1,6 +0,0 @@
-# -*- mode: snippet -*-
-# name: func
-# --
-func ${1:fun}($2) {
-	$0
-}
\ No newline at end of file
tools/emacs/etc/yasnippet/snippets/go-mode/iferr
@@ -1,6 +0,0 @@
-# -*- mode: snippet -*-
-# name: if err != nil { ... }
-# --
-if err != nil {
-	`%`$0
-}
\ No newline at end of file
tools/emacs/etc/yasnippet/snippets/go-mode/ifunc
@@ -1,6 +0,0 @@
-# -*- mode: snippet -*-
-# name: func (...) ... { ... }
-# --
-func ($1) $2 {
-	`%`$0
-}
\ No newline at end of file
tools/emacs/etc/yasnippet/snippets/go-mode/imp
@@ -1,4 +0,0 @@
-# -*- mode: snippet -*-
-# name: import
-# --
-import ${1:package}$0
\ No newline at end of file
tools/emacs/etc/yasnippet/snippets/go-mode/import
@@ -1,4 +0,0 @@
-# -*- mode: snippet -*-
-# name: import
-# --
-import ${1:package}$0
\ No newline at end of file
tools/emacs/etc/yasnippet/snippets/go-mode/main
@@ -1,6 +0,0 @@
-# -*- mode: snippet -*-
-# name: func main() { ... }
-# --
-func main() {
-   $0
-}
\ No newline at end of file
tools/emacs/etc/yasnippet/snippets/go-mode/map
@@ -1,4 +0,0 @@
-# -*- mode: snippet -*-
-# name: map
-# --
-map[${1:KeyType}]${2:ValueType}
\ No newline at end of file
tools/emacs/etc/yasnippet/snippets/go-mode/method
@@ -1,6 +0,0 @@
-# -*- mode: snippet -*-
-# name: func (target) name(args) (results) { ... }
-# --
-func (${1:target}) ${2:name}(${3:args}) (${4:results}) {
-	$0
-}
\ No newline at end of file
tools/emacs/etc/yasnippet/snippets/go-mode/package
@@ -1,4 +0,0 @@
-# -*- mode: snippet -*-
-# name: package
-# --
-package ${1:`(car (last (split-string (file-name-directory buffer-file-name) "/") 2))`}
\ No newline at end of file
tools/emacs/etc/yasnippet/snippets/go-mode/pkg
@@ -1,4 +0,0 @@
-# -*- mode: snippet -*-
-# name: package
-# --
-package ${1:`(car (last (split-string (file-name-directory buffer-file-name) "/") 2))`}
\ No newline at end of file
tools/emacs/etc/yasnippet/snippets/go-mode/pr
@@ -1,4 +0,0 @@
-# -*- mode: snippet -*-
-# name: printf
-# --
-fmt.Printf("$1\n"${2:, ${3:str}})
\ No newline at end of file
tools/emacs/etc/yasnippet/snippets/go-mode/printf
@@ -1,4 +0,0 @@
-# -*- mode: snippet -*-
-# name: printf
-# --
-fmt.Printf("$1\n"${2:, ${3:str}})
\ No newline at end of file
tools/emacs/etc/yasnippet/snippets/go-mode/struct
@@ -1,6 +0,0 @@
-# -*- mode: snippet -*-
-# name: type ... struct { ... }
-# --
-type $1 struct {
-	`%`$0
-}
\ No newline at end of file
tools/emacs/etc/yasnippet/snippets/go-mode/switch
@@ -1,8 +0,0 @@
-# -*- mode: snippet -*-
-# name: switch
-# key: switch
-# --
-switch {
-    case ${1:cond}:
-         $0
-}
\ No newline at end of file
tools/emacs/etc/yasnippet/snippets/go-mode/test
@@ -1,6 +0,0 @@
-# -*- mode: snippet -*-
-# name: func Test...() { ... }
-# --
-func Test${1:Name}(${2:t *testing.T}) {
-	`%`$0
-}
\ No newline at end of file
tools/emacs/etc/yasnippet/snippets/go-mode/while
@@ -1,6 +0,0 @@
-# -*- mode: snippet -*-
-# name : for ... { ... }
-# --
-for $1 {
-	`%`$0
-}
\ No newline at end of file
tools/emacs/etc/yasnippet/snippets/gud-mode/break
@@ -1,1 +0,0 @@
-break _ZL12diag_message13an_error_codeP17a_source_position17an_error_severity30a_diagnostic_category_kind_tag
\ No newline at end of file
tools/emacs/etc/yasnippet/snippets/gud-mode/cd
@@ -1,1 +0,0 @@
-cd ~/Contracts/TI/bugslayer/cl_
\ No newline at end of file
tools/emacs/etc/yasnippet/snippets/gud-mode/const
@@ -1,1 +0,0 @@
-(void)_Z11db_constantP10a_constant($0)
\ No newline at end of file
tools/emacs/etc/yasnippet/snippets/gud-mode/cree
@@ -1,1 +0,0 @@
-run --gcc -DUSE_ASCII -I/usr/local/opt/libffi/lib/libffi-3.0.11/include --llvm_file_name - ~/src/cree/test/wc.c
\ No newline at end of file
tools/emacs/etc/yasnippet/snippets/gud-mode/expr
@@ -1,1 +0,0 @@
-(void)_Z13db_expressionP12an_expr_node($0)
\ No newline at end of file
tools/emacs/etc/yasnippet/snippets/gud-mode/iar
@@ -1,1 +0,0 @@
-run --advice:power=all --diag_suppress=163 --ulp_standalone_mode=iar -D__IAR_SYSTEMS_ICC__ -D__TID__=11008 -D__intrinsic= -D__no_init= -D__persistent= --c iar.c
\ No newline at end of file
tools/emacs/etc/yasnippet/snippets/gud-mode/icd
@@ -1,1 +0,0 @@
-cd ~/Contracts/TI/tmp/iar
\ No newline at end of file
tools/emacs/etc/yasnippet/snippets/gud-mode/line
@@ -1,1 +0,0 @@
-(a_line_number)_Z15db_line_for_seqm (pos_curr_token.seq)
\ No newline at end of file
tools/emacs/etc/yasnippet/snippets/gud-mode/mrun
@@ -1,1 +0,0 @@
-run -I../../exec/arm -Imc2_headers --check_misra=all,-5.3 --c mc2_$0.c
\ No newline at end of file
tools/emacs/etc/yasnippet/snippets/gud-mode/opencl
@@ -1,1 +0,0 @@
-run --abi=eabi --opencl --c -I.. cl_$0.c
\ No newline at end of file
tools/emacs/etc/yasnippet/snippets/gud-mode/oper
@@ -1,1 +0,0 @@
-(void)_Z10db_operandP10an_operand($0)
\ No newline at end of file
tools/emacs/etc/yasnippet/snippets/gud-mode/operkind
@@ -1,1 +0,0 @@
-(an_expr_operator_kind_tag)$0->variant.operation.kind
\ No newline at end of file
tools/emacs/etc/yasnippet/snippets/gud-mode/run
@@ -1,1 +0,0 @@
-run --abi=eabi --opencl --c -I.. cl_$0.c
\ No newline at end of file
tools/emacs/etc/yasnippet/snippets/gud-mode/type
@@ -1,1 +0,0 @@
-(void)_Z7db_typeP6a_type($0->type)
\ No newline at end of file
tools/emacs/etc/yasnippet/snippets/gud-mode/ulpcd
@@ -1,1 +0,0 @@
-cd ~/Contracts/TI/bugslayer/ulp_
\ No newline at end of file
tools/emacs/etc/yasnippet/snippets/gud-mode/ulprun
@@ -1,1 +0,0 @@
-run --abi=eabi --advice:power=all --remarks --c -I.. ulp_$0.c
\ No newline at end of file
tools/emacs/etc/yasnippet/snippets/haskell-mode/haskell-mode/.yas-ignore-filenames-as-triggers
tools/emacs/etc/yasnippet/snippets/haskell-mode/haskell-mode/.yas-make-groups
tools/emacs/etc/yasnippet/snippets/haskell-mode/haskell-mode/case
@@ -1,9 +0,0 @@
-# -*- mode: snippet -*-
-# key: case
-# name: case
-# expand-env: ((yas-indent-line 'fixed))
-# contributor: Luke Hoersten <luke@hoersten.org>
-# --
-case ${1:x} of
-    ${2:Data} -> ${4:expression}
-    ${3:Data} -> ${5:expression}$0
\ No newline at end of file
tools/emacs/etc/yasnippet/snippets/haskell-mode/haskell-mode/comment.block
@@ -1,6 +0,0 @@
-# -*- mode: snippet -*-
-# key: {-
-# name: block comment
-# contributor: Luke Hoersten <luke@hoersten.org>
-# --
-{- $0 -}
\ No newline at end of file
tools/emacs/etc/yasnippet/snippets/haskell-mode/haskell-mode/constraint
@@ -1,6 +0,0 @@
-# -*- mode: snippet -*-
-# key: =>
-# name: Type constraint
-# contributor: Luke Hoersten <luke@hoersten.org>
-# --
-(${1:Class} ${2:m}) => $0
\ No newline at end of file
tools/emacs/etc/yasnippet/snippets/haskell-mode/haskell-mode/data.inline
@@ -1,7 +0,0 @@
-# -*- mode: snippet -*-
-# key: data
-# name: inline data
-# condition: (= (length "data") (current-column))
-# contributor: Luke Hoersten <luke@hoersten.org>
-# --
-data ${1:Type} = ${2:Data}$0 ${3:deriving (${4:Show, Eq})}
\ No newline at end of file
tools/emacs/etc/yasnippet/snippets/haskell-mode/haskell-mode/data.record
@@ -1,10 +0,0 @@
-# -*- mode: snippet -*-
-# key: data
-# name: record data
-# condition: (= (length "data") (current-column))
-# contributor: Luke Hoersten <luke@hoersten.org>
-# --
-data ${1:Type} = $1
-    { ${2:field} :: ${3:Type}
-    , ${4:field} :: ${5:Type}$0
-    } ${6:deriving (${7:Show, Eq})}
\ No newline at end of file
tools/emacs/etc/yasnippet/snippets/haskell-mode/haskell-mode/fn
@@ -1,9 +0,0 @@
-# -*- mode: snippet -*-
-# key: fn
-# name: simple function
-# condition: (= (length "fn") (current-column))
-# expand-env: ((yas-indent-line 'fixed))
-# contributor: Luke Hoersten <luke@hoersten.org>
-# --
-${1:f} :: ${2:a} ${3:-> ${4:b}}
-$1 ${5:x} = ${6:expression}$0
\ No newline at end of file
tools/emacs/etc/yasnippet/snippets/haskell-mode/haskell-mode/fn.clause
@@ -1,10 +0,0 @@
-# -*- mode: snippet -*-
-# key: fn
-# name: clause function
-# condition: (= (length "fn") (current-column))
-# expand-env: ((yas-indent-line 'fixed))
-# contributor: Luke Hoersten <luke@hoersten.org>
-# --
-${1:f} :: ${2:a} ${3:-> ${4:b}}
-$1 ${5:pattern} = ${7:expression}
-$1 ${6:pattern} = ${8:expression}$0
\ No newline at end of file
tools/emacs/etc/yasnippet/snippets/haskell-mode/haskell-mode/fn.guarded
@@ -1,11 +0,0 @@
-# -*- mode: snippet -*-
-# key: fn
-# name: guarded function
-# condition: (= (length "fn") (current-column))
-# expand-env: ((yas-indent-line 'fixed))
-# contributor: Luke Hoersten <luke@hoersten.org>
-# --
-${1:f} :: ${2:a} ${3:-> ${4:b}}
-$1 ${5:x}
-    | ${6:conditional} = ${8:expression}
-    | ${7:conditional} = ${9:expression}$0
\ No newline at end of file
tools/emacs/etc/yasnippet/snippets/haskell-mode/haskell-mode/get
@@ -1,6 +0,0 @@
-# -*- mode: snippet -*-
-# key: <-
-# name: monadic get
-# contributor: Luke Hoersten <luke@hoersten.org>
-# --
-${1:x} <- ${2:expression}$0
\ No newline at end of file
tools/emacs/etc/yasnippet/snippets/haskell-mode/haskell-mode/if.block
@@ -1,8 +0,0 @@
-# -*- mode: snippet -*-
-# key: if
-# name: block if
-# contributor: Luke Hoersten <luke@hoersten.org>
-# --
-if ${1:condition}
-    then ${2:expression}
-    else ${3:expression}$0
\ No newline at end of file
tools/emacs/etc/yasnippet/snippets/haskell-mode/haskell-mode/if.inline
@@ -1,6 +0,0 @@
-# -*- mode: snippet -*-
-# key: if
-# name: inline if
-# contributor: Luke Hoersten <luke@hoersten.org>
-# --
-if ${1:condition} then ${2:expression} else ${3:expression}$0
\ No newline at end of file
tools/emacs/etc/yasnippet/snippets/haskell-mode/haskell-mode/import
@@ -1,7 +0,0 @@
-# -*- mode: snippet -*-
-# key: imp
-# name: simple import
-# condition: (= (length "imp") (current-column))
-# contributor: Luke Hoersten <luke@hoersten.org>
-# --
-import           ${1:Module} ${2:(${3:f})}
\ No newline at end of file
tools/emacs/etc/yasnippet/snippets/haskell-mode/haskell-mode/import.qualified
@@ -1,9 +0,0 @@
-# -*- mode: snippet -*-
-# key: imp
-# name: qualified import
-# condition: (= (length "imp") (current-column))
-# contributor: Luke Hoersten <luke@hoersten.org>
-# --
-import qualified ${1:Module} as ${2:${1:$(let ((name (car (last (split-string yas-text "\\\.")))))
-                                              (if (not (nil-blank-string name)) ""
-                                                  (subseq name 0 1)))}}$0
\ No newline at end of file
tools/emacs/etc/yasnippet/snippets/haskell-mode/haskell-mode/instance
@@ -1,8 +0,0 @@
-# -*- mode: snippet -*-
-# key: inst
-# name: instance
-# condition: (= (length "inst") (current-column))
-# contributor: Luke Hoersten <luke@hoersten.org>
-# --
-instance ${1:Class} ${2:Data} where
-    ${3:f} = ${4:expression}$0
\ No newline at end of file
tools/emacs/etc/yasnippet/snippets/haskell-mode/haskell-mode/lambda
@@ -1,6 +0,0 @@
-# -*- mode: snippet -*-
-# key: \
-# name: lambda
-# contributor: Luke Hoersten <luke@hoersten.org>
-# --
-\\${1:x} -> ${2:expression}$0
\ No newline at end of file
tools/emacs/etc/yasnippet/snippets/haskell-mode/haskell-mode/lang-pragma
@@ -1,7 +0,0 @@
-# -*- mode: snippet -*-
-# key: lang
-# name: language pragma
-# condition: (= (length "lang") (current-column))
-# contributor: Luke Hoersten <luke@hoersten.org>, John Wiegley
-# --
-{-# LANGUAGE `(progn (require 'haskell-yas) (haskell-yas-complete "Extension: " haskell-yas-ghc-language-pragmas))` #-}
\ No newline at end of file
tools/emacs/etc/yasnippet/snippets/haskell-mode/haskell-mode/let
@@ -1,6 +0,0 @@
-# -*- mode: snippet -*-
-# key: let
-# name: let
-# contributor: Luke Hoersten <luke@hoersten.org>
-# --
-let ${1:x} = ${2:expression}$0
\ No newline at end of file
tools/emacs/etc/yasnippet/snippets/haskell-mode/haskell-mode/main
@@ -1,13 +0,0 @@
-# -*- mode: snippet -*-
-# key: main
-# name: main module
-# condition: (= (length "main") (current-column))
-# expand-env: ((yas-indent-line 'fixed))
-# contributor: Luke Hoersten <luke@hoersten.org>
-# --
-module Main where
-
-main :: IO ()
-main = do
-  ${1:expression}$0
-  return ()
\ No newline at end of file
tools/emacs/etc/yasnippet/snippets/haskell-mode/haskell-mode/module
@@ -1,14 +0,0 @@
-# -*- mode: snippet -*-
-# key: mod
-# name: simple module
-# condition: (= (length "mod") (current-column))
-# expand-env: ((yas-indent-line 'fixed))
-# contributor: Luke Hoersten <luke@hoersten.org>
-# --
-module ${1:`(if (not buffer-file-name) "Module"
-                (let ((name (file-name-sans-extension (buffer-file-name))))
-                     (if (search "src/" name)
-                         (replace-regexp-in-string "/" "." (car (last (split-string name "src/"))))
-                         (file-name-nondirectory name))))`} where
-
-$0
\ No newline at end of file
tools/emacs/etc/yasnippet/snippets/haskell-mode/haskell-mode/module.exports
@@ -1,17 +0,0 @@
-# -*- mode: snippet -*-
-# key: mod
-# name: exports module
-# condition: (= (length "mod") (current-column))
-# expand-env: ((yas-indent-line 'fixed))
-# contributor: Luke Hoersten <luke@hoersten.org>
-# --
-module ${1:`(if (not buffer-file-name) "Module"
-                (let ((name (file-name-sans-extension (buffer-file-name))))
-                     (if (search "src/" name)
-                         (replace-regexp-in-string "/" "." (car (last (split-string name "src/"))))
-                         (file-name-nondirectory name))))`}
-    ( ${3:export}
-    ${4:, ${5:export}}
-    ) where
-
-$0
\ No newline at end of file
tools/emacs/etc/yasnippet/snippets/haskell-mode/haskell-mode/newtype
@@ -1,7 +0,0 @@
-# -*- mode: snippet -*-
-# key: new
-# name: newtype
-# condition: (= (length "new") (current-column))
-# contributor: Luke Hoersten <luke@hoersten.org>
-# --
-newtype ${1:Type} = $1 { un$1 :: ${2:a} } ${3:deriving (${4:Show, Eq})}
\ No newline at end of file
tools/emacs/etc/yasnippet/snippets/haskell-mode/.hgignore
@@ -1,7 +0,0 @@
-syntax: regexp
-~$
-\#.*$
-\.DS_Store
-\.yas-compiled-snippets\.el$
-
-
tools/emacs/etc/yasnippet/snippets/haskell-mode/hdr.yasnippet
@@ -1,23 +0,0 @@
-# -*- mode: snippet -*-
-# key: hdr
-# name: haskell header
-# expand-env: ((yas-indent-line 'fixed))
-# contributor: John Wiegley <johnw@newartisans.com>
-# --
-{-# LANGUAGE OverloadedStrings #-}
-
-module `(file-name-sans-extension (buffer-name))` where
-
-import Control.Applicative
-import Control.Monad
-import Control.Monad.IO.Class
-import Control.Monad.Trans.Class
-import Control.Monad.Trans.Control
-import Data.Maybe
-import Data.Monoid
-
-$1 :: $0
-$1 = undefined
-
-main :: IO ()
-main = undefined
\ No newline at end of file
tools/emacs/etc/yasnippet/snippets/haskell-mode/README.md
@@ -1,89 +0,0 @@
-# Shnippet
-
-
-**Shnippet** is a collection of
-[YASnippet][yas]
-[Haskell][haskell] snippets for Emacs.
-
-
-## Installation
-
-Clone repository:
-
-    $ cd ~/.emacs.d/snippets
-    $ git clone https://github.com/LukeHoersten/shnippet
-    OR
-    $ hg clone https://bitbucket.org/LukeHoersten/shnippet
-
-Add the cloned repository to YASnippet's `yas-snippet-dirs`:
-
-    (setq yas-snippet-dirs
-          '("~/.emacs.d/snippets/shnippet"
-            "/other/paths/"
-            ))
-
-Snippets may have to be recompiled and reloaded in Emacs if YASnippet
-is already in use:
-
-    M-x yas-recompile-all
-    M-x yas-reload-all
-
-
-Haskell snippts should now be available to use! In a `haskell-mode`
-buffer, type `fn<TAB>`. A prompt should appear asking which `fn`
-snippet to expand.
-
-I **highly** recommend using YASnippet with [ido-mode]. Configure
-Emacs:
-
-    (setq-default yas-prompt-functions '(yas-ido-prompt yas-dropdown-prompt))
-
-This is important so that alternatives (like `import` vs. `import
-qualified`) can quickly be selected with a single key stroke.
-
-
-## Available Expansion Keys
-
-* `new` - newtype
-* `mod` - module [simple, exports]
-* `main ` - main module and function
-* `let` - let bindings
-* `lang` - language extension pragmas
-* `\` - lambda function
-* `inst` - instance declairation
-* `imp` - import modules [simple, qualified]
-* `if` - if conditional [inline, block]
-* `<-` - monadic get
-* `fn` - top level function [simple, guarded, clauses]
-* `data` - data type definition [inline, record]
-* `=>` - type constraint
-* `{-` - block comment
-* `case` - case statement
-
-
-## Design Ideals
-
-* Keep snippet keys (the prefix used to auto-complete) to four
-  characters or less while still being as easy to guess as possible.
-
-* Have as few keys as possible. The more keys there are to remember,
-  the harder snippets are to use and learn.
-
-* Leverage [ido-mode][] when reasonable. For instance, to keep the
-  number of snippet keys to a minimum as well as auto complete things
-  like [Haskell Langauge Extension Pragmas][lang-pragma]. When
-  multiple snippets share a key (ex: `fn`), the `ido-mode` prompts are
-  unique to one character (ex: `guarded function` and `simple
-  function` are `g` and `s` respectively).
-
-
-## Authors
-
-This code is written and maintained by Luke Hoersten,
-<luke@hoersten.org>.
-
-
-[yas]: https://github.com/capitaomorte/yasnippet
-[ido-mode]: http://www.emacswiki.org/emacs/InteractivelyDoThings
-[lang-pragma]: http://hackage.haskell.org/packages/archive/Cabal/1.16.0.3/doc/html/Language-Haskell-Extension.html#t:KnownExtension
-[haskell]: http://haskell.org/
tools/emacs/etc/yasnippet/snippets/haskell-mode/tr.yasnippet
@@ -1,6 +0,0 @@
-# -*- mode: snippet -*-
-# key: tr
-# name: trace
-# contributor: John Wiegley <johnw@newartisans.com>
-# --
-trace ("$1: " ++ show ($1)) $ 
\ No newline at end of file
tools/emacs/etc/yasnippet/snippets/js-mode/commonjs.require
@@ -1,5 +0,0 @@
-# -*- mode: snippet; require-final-newline: nil -*-
-# name: commonjs.require
-# key: req
-# --
-var ${3:${1:$(s-lower-camel-case (file-name-nondirectory yas/text))}} = require("${1:module}")$2;$0
\ No newline at end of file
tools/emacs/etc/yasnippet/snippets/js-mode/es6.import
@@ -1,6 +0,0 @@
-# -*- mode: snippet; require-final-newline: nil -*-
-# name: es6.import
-# key: imp
-# binding: direct-keybinding
-# --
-import ${3:${1:$(s-lower-camel-case (file-name-nondirectory yas/text))}} from "${1:module}";$0
\ No newline at end of file
tools/emacs/etc/yasnippet/snippets/js-mode/js.es5exportedfunction
@@ -1,6 +0,0 @@
-# -*- mode: snippet; require-final-newline: nil -*-
-# name: js.exportedfunction
-# key: 5xf
-# --
-function $1($2) {$0};
-module.exports.$1 = $1;
tools/emacs/etc/yasnippet/snippets/js-mode/js.exportedconst
@@ -1,5 +0,0 @@
-# -*- mode: snippet; require-final-newline: nil -*-
-# name: js.exportedconst
-# key: xc
-# --
-export const $1 = $0;
tools/emacs/etc/yasnippet/snippets/js-mode/js.exportedfunction
@@ -1,7 +0,0 @@
-# -*- mode: snippet; require-final-newline: nil -*-
-# name: js.exportedfunction
-# key: xf
-# --
-export function ${1:f}($2) {
-  $0
-}
tools/emacs/etc/yasnippet/snippets/js-mode/js.exportedvar
@@ -1,5 +0,0 @@
-# -*- mode: snippet; require-final-newline: nil -*-
-# name: js.exportedvar
-# key: xv
-# --
-var $1 = module.exports.$1 = $0;
tools/emacs/etc/yasnippet/snippets/js-mode/js.function
@@ -1,5 +0,0 @@
-# -*- mode: snippet; require-final-newline: nil -*-
-# name: js.function
-# key: fn
-# --
-function($1) {$0}
\ No newline at end of file
tools/emacs/etc/yasnippet/snippets/js-mode/js.generator
@@ -1,5 +0,0 @@
-# -*- mode: snippet; require-final-newline: nil -*-
-# name: js.generator
-# key: gen
-# --
-function*() {$0}
\ No newline at end of file
tools/emacs/etc/yasnippet/snippets/js-mode/jsdoc
@@ -1,7 +0,0 @@
-# -*- mode: snippet; require-final-newline: nil -*-
-# name: jsdoc
-# key: jd
-# --
-/**
- * $0
- */
\ No newline at end of file
tools/emacs/etc/yasnippet/snippets/latex-mode/acro
@@ -1,1 +0,0 @@
-\newacronym{$1}{${1:$(upcase yas-text)}}{$0}
\ No newline at end of file
tools/emacs/etc/yasnippet/snippets/latex-mode/code
@@ -1,10 +0,0 @@
-# -*- mode: snippet -*-
-# key: code
-# expand-env: ((yas-indent-line 'fixed))
-# --
-\begin{listing}[!ht]
-  \begin{minted}[frame=single,gobble=4]{coq}
-    $0
-  \end{minted}
-  \caption{$1}
-\end{listing}
\ No newline at end of file
tools/emacs/etc/yasnippet/snippets/latex-mode/gloss
@@ -1,4 +0,0 @@
-\newglossaryentry{$1}{
-  name={$1},
-  description={$0}
-}
\ No newline at end of file
tools/emacs/etc/yasnippet/snippets/latex-mode/hafez
@@ -1,3 +0,0 @@
-\begin{hafez}{$1}{${2:pp.~1--2}}
-  $0
-\end{hafez}
\ No newline at end of file
tools/emacs/etc/yasnippet/snippets/lisp-mode/case
@@ -1,8 +0,0 @@
-# -*- mode: snippet -*-
-# contributor: Mark Karpov
-# name: case
-# key: case
-# --
-(case ${1:key-form}
-  (${2:match} ${3:result})${4:
-  (t ${5:otherwise})})
\ No newline at end of file
tools/emacs/etc/yasnippet/snippets/lisp-mode/ccase
@@ -1,7 +0,0 @@
-# -*- mode: snippet -*-
-# contributor: Mark Karpov
-# name: ccase
-# key: ccase
-# --
-(ccase ${1:key-form}
-  (${2:match} ${3:result}))
\ No newline at end of file
tools/emacs/etc/yasnippet/snippets/lisp-mode/cond
@@ -1,7 +0,0 @@
-# -*- mode: snippet -*-
-# contributor: Mark Karpov
-# name: cond
-# key: cond
-# --
-(cond (${1:test} ${2:then})
-      (t ${3:else}))
\ No newline at end of file
tools/emacs/etc/yasnippet/snippets/lisp-mode/ctypecase
@@ -1,7 +0,0 @@
-# -*- mode: snippet -*-
-# contributor: Mark Karpov
-# name: ctypecase
-# key: ctypecase
-# --
-(ctypecase ${1:key-form}
-  (${2:match} ${3:result}))
\ No newline at end of file
tools/emacs/etc/yasnippet/snippets/lisp-mode/defclass
@@ -1,8 +0,0 @@
-# -*- mode: snippet -*-
-# contributor: Mark Karpov
-# name: defclass
-# key: defclass
-# --
-(defclass ${1:name} (${2:parents})
-  ($0)${3:
-  (:documentation "${4:doc}")})
\ No newline at end of file
tools/emacs/etc/yasnippet/snippets/lisp-mode/defconstant
@@ -1,8 +0,0 @@
-# -*- mode: snippet -*-
-# contributor: Mark Karpov
-# name: defconstant
-# key: defconstant
-# --
-(defconstant +${1:name}+ ${2:nil}${3:
- "${4:doc}"})
-$0
\ No newline at end of file
tools/emacs/etc/yasnippet/snippets/lisp-mode/defgeneric
@@ -1,8 +0,0 @@
-# -*- mode: snippet -*-
-# contributor: Mark Karpov
-# name: defgeneric
-# key: defgeneric
-# --
-(defgeneric ${1:name} (${2:args})${3:
-  (:documentation "${4:doc}")})
-$0
\ No newline at end of file
tools/emacs/etc/yasnippet/snippets/lisp-mode/define-compiler-macro
@@ -1,7 +0,0 @@
-# -*- mode: snippet -*-
-# contributor: Mark Karpov
-# name: define-compiler-macro
-# key: define-compiler-macro
-# --
-(define-compiler-macro ${1:name} (${2:args})
-  $0)
\ No newline at end of file
tools/emacs/etc/yasnippet/snippets/lisp-mode/define-condition
@@ -1,8 +0,0 @@
-# -*- mode: snippet -*-
-# contributor: Mark Karpov
-# name: define-condition
-# key: define-condition
-# --
-(define-condition ${1:name} (${2:parents})
-  ($0)${3:
-  (:documentation "${4:doc}")})
\ No newline at end of file
tools/emacs/etc/yasnippet/snippets/lisp-mode/define-symbol-macro
@@ -1,7 +0,0 @@
-# -*- mode: snippet -*-
-# contributor: Mark Karpov
-# name: define-symbol-macro
-# key: define-symbol-macro
-# --
-(define-symbol-macro ${1:name} ${2:expansion})
-$0
\ No newline at end of file
tools/emacs/etc/yasnippet/snippets/lisp-mode/defmacro
@@ -1,8 +0,0 @@
-# -*- mode: snippet -*-
-# contributor: Mark Karpov
-# name: defmacro
-# key: defmacro
-# --
-(defmacro ${1:name} (${2:args }${3:&body body})${4:
-  "${5:doc}"}
-  $0)
\ No newline at end of file
tools/emacs/etc/yasnippet/snippets/lisp-mode/defmethod
@@ -1,7 +0,0 @@
-# -*- mode: snippet -*-
-# contributor: Mark Karpov
-# name: defmethod
-# key: defmethod
-# --
-(defmethod ${1:name} (${2:args})
-  $0)
\ No newline at end of file
tools/emacs/etc/yasnippet/snippets/lisp-mode/defpackage
@@ -1,12 +0,0 @@
-# -*- mode: snippet -*-
-# contributor: Mark Karpov
-# name: defpackage
-# key: defpackage
-# --
-(defpackage   :${1:package}${2:
-  (:nicknames ${3:nicks})}${4:
-  (:use       ${5:packages})}${6:
-  (:shadow    ${7:packages})}${8:
-  (:export    ${9:packages})}${10:
-  (:documentation "${11:doc}")})
-$0
\ No newline at end of file
tools/emacs/etc/yasnippet/snippets/lisp-mode/defparameter
@@ -1,8 +0,0 @@
-# -*- mode: snippet -*-
-# contributor: Mark Karpov
-# name: defparameter
-# key: defparameter
-# --
-(defparameter *${1:name}* ${2:nil}${3:
- "${4:doc}"})
-$0
\ No newline at end of file
tools/emacs/etc/yasnippet/snippets/lisp-mode/defstruct
@@ -1,8 +0,0 @@
-# -*- mode: snippet -*-
-# contributor: Mark Karpov
-# name: defstruct
-# key: defstruct
-# --
-(defstruct ${1:name}${2:
-  "${3:doc}"}
-  ($0))
\ No newline at end of file
tools/emacs/etc/yasnippet/snippets/lisp-mode/defsystem
@@ -1,14 +0,0 @@
-# -*- mode: snippet -*-
-# contributor: Mark Karpov
-# name: defsystem
-# key: defsystem
-# --
-(asdf:defsystem :${1:system}${2:
-  :version      "${3:0.1.0}"}${4:
-  :description  "${5:description}"}${6:
-  :author       "${7:`user-full-name` <`user-mail-address`>}"}${8:
-  :serial       t}${10:
-  :license      "${11:GNU GPL, version 3}"}${12:
-  :components   (${13:(:file "file.lisp")})}${14:
-  :depends-on   (${15:#:alexandria})})
-$0
\ No newline at end of file
tools/emacs/etc/yasnippet/snippets/lisp-mode/deftype
@@ -1,8 +0,0 @@
-# -*- mode: snippet -*-
-# contributor: Mark Karpov
-# name: deftype
-# key: deftype
-# --
-(deftype ${1:name} (${2:args})${3:
-  "${4:doc}"}
-  $0)
\ No newline at end of file
tools/emacs/etc/yasnippet/snippets/lisp-mode/defun
@@ -1,8 +0,0 @@
-# -*- mode: snippet -*-
-# contributor: Mark Karpov
-# name: defun
-# key: defun
-# --
-(defun ${1:name} (${2:args})${3:
-  "${4:doc}"}
-  $0)
\ No newline at end of file
tools/emacs/etc/yasnippet/snippets/lisp-mode/defvar
@@ -1,8 +0,0 @@
-# -*- mode: snippet -*-
-# contributor: Mark Karpov
-# name: defvar
-# key: defvar
-# --
-(defvar *${1:name}*${2: nil}${3:
- "${4:doc}"})
-$0
\ No newline at end of file
tools/emacs/etc/yasnippet/snippets/lisp-mode/destructuring-bind
@@ -1,7 +0,0 @@
-# -*- mode: snippet -*-
-# contributor: Mark Karpov
-# name: destructuring-bind
-# key: dbind
-# --
-(destructuring-bind (${1:vars}) ${2:value}
-  $0)
\ No newline at end of file
tools/emacs/etc/yasnippet/snippets/lisp-mode/do
@@ -1,8 +0,0 @@
-# -*- mode: snippet -*-
-# contributor: Mark Karpov
-# name: do
-# key: do
-# --
-(do (${1:vars})
-    (${2:end-test-form}${3: result})
-  $0)
\ No newline at end of file
tools/emacs/etc/yasnippet/snippets/lisp-mode/do_
@@ -1,8 +0,0 @@
-# -*- mode: snippet -*-
-# contributor: Mark Karpov
-# name: do*
-# key: do*
-# --
-(do* (${1:vars})
-     (${2:end-test-form}${3: result})
-  $0)
\ No newline at end of file
tools/emacs/etc/yasnippet/snippets/lisp-mode/dolist
@@ -1,7 +0,0 @@
-# -*- mode: snippet -*-
-# contributor: Mark Karpov
-# name: dolist
-# key: dolist
-# --
-(dolist (${1:var} ${2:list}${3: result})
-  $0)
\ No newline at end of file
tools/emacs/etc/yasnippet/snippets/lisp-mode/dotimes
@@ -1,7 +0,0 @@
-# -*- mode: snippet -*-
-# contributor: Mark Karpov
-# name: dotimes
-# key: dotimes
-# --
-(dotimes (${1:var} ${2:count}${3: result})
-  $0)
\ No newline at end of file
tools/emacs/etc/yasnippet/snippets/lisp-mode/ecase
@@ -1,7 +0,0 @@
-# -*- mode: snippet -*-
-# contributor: Mark Karpov
-# name: ecase
-# key: ecase
-# --
-(ecase ${1:key-form}
-  (${2:match} ${3:result}))
\ No newline at end of file
tools/emacs/etc/yasnippet/snippets/lisp-mode/etypecase
@@ -1,7 +0,0 @@
-# -*- mode: snippet -*-
-# contributor: Mark Karpov
-# name: etypecase
-# key: etypecase
-# --
-(etypecase ${1:key-form}
-  (${2:match} ${3:result}))
\ No newline at end of file
tools/emacs/etc/yasnippet/snippets/lisp-mode/flet
@@ -1,9 +0,0 @@
-# -*- mode: snippet -*-
-# contributor: Toni Querol
-# name: flet
-# key: flet
-# --
-(flet ((${1:name} (${2:args})${3:
-  "${4:doc}"}
-  ${5:body}))
-  $0)
\ No newline at end of file
tools/emacs/etc/yasnippet/snippets/lisp-mode/format
@@ -1,6 +0,0 @@
-# -*- mode: snippet -*-
-# contributor: Mark Karpov
-# name: format
-# key: format
-# --
-(format ${1:nil} ${2:str} $0)
\ No newline at end of file
tools/emacs/etc/yasnippet/snippets/lisp-mode/gnugpl
@@ -1,25 +0,0 @@
-# -*- mode: snippet -*-
-# contributor: Mark Karpov
-# name: GNU GPL 3 Header
-# key: gnugpl
-# --
-;;; -*- Mode: Lisp; Syntax: ANSI-Common-Lisp; -*-
-;;;
-;;; ${1:description}
-;;;
-;;; Copyright © ${2:`(format-time-string "%Y")`} `user-full-name` <`user-mail-address`>
-;;;
-;;; ${3:This program$(prog1 yas-text (fill-paragraph))} is free software:
-;;; you can redistribute it and/or modify it under the terms of the GNU
-;;; General Public License as published by the Free Software Foundation,
-;;; either version 3 of the License, or (at your option) any later version.
-;;;
-;;; ${3:$(prog1 yas-text (fill-paragraph))} is distributed in the hope that
-;;; it will be useful, but WITHOUT ANY WARRANTY; without even the implied
-;;; warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-;;; GNU General Public License for more details.
-;;;
-;;; You should have received a copy of the GNU General Public License along
-;;; with this program. If not, see <http://www.gnu.org/licenses/>.
-
-$0
\ No newline at end of file
tools/emacs/etc/yasnippet/snippets/lisp-mode/if
@@ -1,6 +0,0 @@
-# -*- mode: snippet -*-
-# contributor: Mark Karpov
-# name: if
-# key: if
-# --
-(if ${1:test} ${2:then}${3: else})
tools/emacs/etc/yasnippet/snippets/lisp-mode/in-package
@@ -1,7 +0,0 @@
-# -*- mode: snippet -*-
-# contributor: Mark Karpov
-# name: in-package
-# key: in-package
-# --
-(in-package #:${1:package})
-$0
\ No newline at end of file
tools/emacs/etc/yasnippet/snippets/lisp-mode/labels
@@ -1,9 +0,0 @@
-# -*- mode: snippet -*-
-# contributor: Toni Querol
-# name: labels
-# key: labels
-# --
-(labels ((${1:name} (${2:args})${3:
-  "${4:doc}"}
-  ${5:body}))
-  $0)
\ No newline at end of file
tools/emacs/etc/yasnippet/snippets/lisp-mode/let
@@ -1,6 +0,0 @@
-# -*- mode: snippet -*-
-# name: let
-# key: let
-# --
-(let ((${1:var} ${2:val}))
-  $0)
tools/emacs/etc/yasnippet/snippets/lisp-mode/mapc
@@ -1,7 +0,0 @@
-# -*- mode: snippet -*-
-# contributor: Mark Karpov
-# name: mapc
-# key: mapc
-# --
-(mapc ${1:fnc} ${2:list})
-$0
\ No newline at end of file
tools/emacs/etc/yasnippet/snippets/lisp-mode/mapcar
@@ -1,7 +0,0 @@
-# -*- mode: snippet -*-
-# contributor: Mark Karpov
-# name: mapcar
-# key: mapcar
-# --
-(mapcar ${1:fnc} ${2:list})
-$0
\ No newline at end of file
tools/emacs/etc/yasnippet/snippets/lisp-mode/mitlic
@@ -1,31 +0,0 @@
-# -*- mode: snippet -*-
-# contributor: Mark Karpov
-# name: MIT License Header
-# key: mitlic
-# --
-;;; -*- Mode: Lisp; Syntax: ANSI-Common-Lisp; -*-
-;;;
-;;; ${1:description}
-;;;
-;;; Copyright © ${2:`(format-time-string "%Y")`} `user-full-name` <`user-mail-address`>
-;;;
-;;; Permission is hereby granted, free of charge, to any person obtaining a
-;;; copy of this software and associated documentation files (the
-;;; "Software"), to deal in the Software without restriction, including
-;;; without limitation the rights to use, copy, modify, merge, publish,
-;;; distribute, sublicense, and/or sell copies of the Software, and to
-;;; permit persons to whom the Software is furnished to do so, subject to
-;;; the following conditions:
-;;;
-;;; The above copyright notice and this permission notice shall be included
-;;; in all copies or substantial portions of the Software.
-;;;
-;;; THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
-;;; OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-;;; MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-;;; NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
-;;; LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
-;;; OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
-;;; WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-
-$0
\ No newline at end of file
tools/emacs/etc/yasnippet/snippets/lisp-mode/typecase
@@ -1,8 +0,0 @@
-# -*- mode: snippet -*-
-# contributor: Mark Karpov
-# name: typecase
-# key: typecase
-# --
-(typecase ${1:key-form}
-  (${2:match} ${3:result})${4:
-  (t ${5:otherwise})})
\ No newline at end of file
tools/emacs/etc/yasnippet/snippets/message-mode/check
@@ -1,4 +0,0 @@
-Hi $1,
-
-On $2 you mentioned you were going to check part $3. How's it going?
-
tools/emacs/etc/yasnippet/snippets/message-mode/granted
@@ -1,38 +0,0 @@
-# expand-env: ((yas-indent-line 'fixed) (yas-wrap-around-region 'nil))
-# --
-
-Your wish has been granted. You can commit to Emacs and GNU ELPA. Feel free to
-use this power, but please try to be extra careful and prove yourself worthy
-of this privilege:
-
-- Send your patches for review before installing them.
-
-- Only install changes whose code follows the usual coding conventions. Some
-  of those conventions are documented in http://www.gnu.org/prep/standards;
-  you'll discover others during code review.
-
-- Always provide a good commit message (copied into or from the ChangeLog for
-  emacs.git), following the GNU coding standards (e.g. using the
-  present/imperative tense, and syntax described at
-  http://www.gnu.org/prep/standards/html_node/Change-Logs.html), and properly
-  labelling the author of the code.
-
-- If the change is a new feature or a change in behavior, don't forget to
-  mention it in the etc/NEWS file and to update the Texinfo doc accordingly.
-
-- Be sure your change is accepted as being for the better by the package's
-  maintainer. As a general rule send your patch for review before installing
-  it, unless you're absolutely positively 200% sure that everyone will be
-  pleased with the content and the form of the patch.
-
-Last but not least:
-
-- And make extra sure that all the code you install has the proper copyright:
-  if it is not your own code, make sure the author has signed the relevant
-  copyright papers (for non-trivial contributions), and indicate the author
-  correctly in the commit (and the ChangeLog if applicable).
-
-If you have the slightest doubt about any of those points, send your question
-or your patch to emacs-devel@gnu.org (or bug-gnu-emacs@gnu.org).
-
-Thank you very much for your contribution to Emacs,
tools/emacs/etc/yasnippet/snippets/message-mode/proof
@@ -1,22 +0,0 @@
-The list of sections still needing to be proofread is here:
-
-  http://ftp.newartisans.com/pub/emacs-manual.html
-
-If you'd like a suggestion, how about:
-
-| Chapter | Part | Title                          | Page | Length |
-|---------+------+--------------------------------+------+--------|
-|      24 |   17 | Compiling and Testing Programs |  277 |     20 |
-
-Otherwise, please pick any section(s) without a "Checked By" name, and e-mail
-emacs-manual-bugs@gnu.org with the Ch/Pt numbers. I'll then add you to the
-volunteered list. Once you have some edits, send them to the same list, and
-I'll add you to the Checked By column for that section.
-
-It's OK to proofread something that's already been done, if you were hoping to
-brush up on that part of the manual. It's our goal to make sure everything is
-seen at least three times.
-
-Richard has sent instructions to many of you, but in case you haven't received
-them yet, they can be found here:
-https://lists.gnu.org/archive/html/help-gnu-emacs/2018-01/msg00295.html
tools/emacs/etc/yasnippet/snippets/message-mode/suggest
@@ -1,21 +0,0 @@
-Hi $1,
-
-I was wondering if you'd be willing to check any of these parts for us:
-
-| Ch |  Pt | Title                                       | Page | Len |
-|----+-----+---------------------------------------------+------+-----|
-| 11 |  7a | Chapter Beginning - Font Lock mode          |   72 |   9 |
-| 13 |   9 | Commands for Fixing Typos                   |  119 |   6 |
-| 14 |     | Keyboard Macros                             |  125 |   8 |
-|    | 10b | Reverting a Buffer - Chapter End            |      |  13 |
-| 17 |     | Multiple Windows                            |  167 |   7 |
-| 24 |  17 | Compiling and Testing Programs              |  277 |  20 |
-|    | 18b | Change Logs - Chapter End                   |      |  13 |
-| 28 |  21 | The Calendar and the Diary                  |  351 |  19 |
-| 30 |  23 | Reading Mail with Rmail                     |  379 |  20 |
-|    | 26b | Customizing Key Bindings - Chapter End      |      |  14 |
-|  C |  29 | Command Line Arguments for Emacs Invocation |  507 |  15 |
-|  E |     | Emacs 25 Antinews                           |  529 |   3 |
-|  F |  31 | Emacs and Mac OS / GNUstep                  |  532 |   3 |
-|  G |     | Emacs and Microsoft Windows/MS-DOS          |  535 |  10 |
-| GL |  33 | Glossary                                    |  553 |  23 |
tools/emacs/etc/yasnippet/snippets/org-mode/appt
@@ -1,7 +0,0 @@
-#name : APPT
-# --
-APPT $0
-SCHEDULED: `(with-temp-buffer (org-insert-time-stamp (current-time)))`
-:PROPERTIES:
-:ID:       `(shell-command-to-string "uuidgen")`:CREATED: `(with-temp-buffer (org-insert-time-stamp (current-time) t t))`
-:END:
\ No newline at end of file
tools/emacs/etc/yasnippet/snippets/org-mode/assem
@@ -1,31 +0,0 @@
-* NOTE Assembly meeting agenda for `(with-temp-buffer (org-insert-time-stamp (current-time) nil t))`
-:PROPERTIES:
-:ID:       `(shell-command-to-string "uuidgen")`:CREATED: `(with-temp-buffer (org-insert-time-stamp (current-time) t t))`
-:OVERLAY: (face (:background "#e8f9e8"))
-:END:
-** Opening Prayers
-** Attendance [0/9]
-- [$0 ] Caroline Delaney
-- [ ] Todd Zeigler
-- [ ] Becky Thomas
-- [ ] Pamela Fox
-- [ ] Nasim Wiegley
-- [ ] Beth Youker-Schwab
-- [ ] Gail Hill
-- [ ] Christina Stone
-- [ ] John Wiegley
-** Review prior minutes of [2013-01-01 Tue]
-** New Business
-** Outstanding business
-** Upcoming events
-** Secretary's report
-** Feast suggestions
-** Treasurer's Report
-** Consultation
-** Affairs of the Local Spiritual Assembly
-*** P.I. Rep: Caroline
-*** Center Manager: Caroline
-*** Children's Education: Mary Anne, Sisi, Keith
-*** Teaching Committee: Mary Anne, Christina, JohnW and Katy
-*** Center Improvement Committee: Beth, Pamela
-** Next Assembly meeting is [2013-01-01 Tue 00:00]
tools/emacs/etc/yasnippet/snippets/org-mode/bbdb
@@ -1,3 +0,0 @@
-#name : bbdb
-# --
-[[bbdb:$1][$1]] $0
\ No newline at end of file
tools/emacs/etc/yasnippet/snippets/org-mode/hask
@@ -1,2 +0,0 @@
-#+begin_src haskell
-$0#+end_src
tools/emacs/etc/yasnippet/snippets/org-mode/list
@@ -1,7 +0,0 @@
-#name : List NOTE
-# --
-*** NOTE $1 [/]
-- [ ] $0
-:PROPERTIES:
-:ID:       `(shell-command-to-string "uuidgen")`:CREATED: `(with-temp-buffer (org-insert-time-stamp (current-time) t t))`
-:END:
\ No newline at end of file
tools/emacs/etc/yasnippet/snippets/org-mode/note
@@ -1,6 +0,0 @@
-#name : NOTE
-# --
-NOTE $0
-:PROPERTIES:
-:ID:       `(shell-command-to-string "uuidgen")`:CREATED: `(with-temp-buffer (org-insert-time-stamp (current-time) t t))`
-:END:
\ No newline at end of file
tools/emacs/etc/yasnippet/snippets/org-mode/out
@@ -1,4 +0,0 @@
-#name : :OUTPUT: ... :END:
-# --
-:OUTPUT:
-$0:END:
tools/emacs/etc/yasnippet/snippets/org-mode/proj
@@ -1,6 +0,0 @@
-#name : PROJECT
-# --
-PROJECT $0
-:PROPERTIES:
-:ID:       `(shell-command-to-string "uuidgen")`:CREATED: `(with-temp-buffer (org-insert-time-stamp (current-time) t t))`
-:END:
\ No newline at end of file
tools/emacs/etc/yasnippet/snippets/org-mode/sh
@@ -1,2 +0,0 @@
-#+begin_src sh
-$0#+end_src
tools/emacs/etc/yasnippet/snippets/org-mode/skip
@@ -1,3 +0,0 @@
-:PROPERTIES:
-:BEAMER_act: <2->
-:END:
tools/emacs/etc/yasnippet/snippets/org-mode/src
@@ -1,4 +0,0 @@
-# --
-#+begin_src $1
-$0
-#+end_src
tools/emacs/etc/yasnippet/snippets/org-mode/status
@@ -1,23 +0,0 @@
-**** NOTE Status Report for `(with-temp-buffer (org-insert-time-stamp (current-time) nil t))`
-:PROPERTIES:
-:ID:       `(shell-command-to-string "uuidgen")`:CREATED: `(with-temp-buffer (org-insert-time-stamp (current-time) t t))`
-:END:
-***** Planned and implemented
-
-- 
-
-***** Not planned but implemented
-
-- 
-
-***** Planned but not implemented
-
-- 
-
-***** Planned for next week
-
-- 
-
-***** Questions and concerns
-
-- None this week.
tools/emacs/etc/yasnippet/snippets/org-mode/teach
@@ -1,21 +0,0 @@
-* NOTE Assembly meeting agenda for `(with-temp-buffer (org-insert-time-stamp (current-time) nil t))`
-:PROPERTIES:
-:ID:       `(shell-command-to-string "uuidgen")`:CREATED: `(with-temp-buffer (org-insert-time-stamp (current-time) t t))`
-:OVERLAY: (face (:background "#e8f9e8"))
-:END:
-** Opening Prayers
-** Attendance [0/9]
-- [$0 ] Caroline Delaney
-- [ ] Sisi Mereness
-- [ ] John Tempey
-- [ ] Pamela Fox
-- [ ] Nami Peymani
-- [ ] Beth Youker-Schwab
-- [ ] Gail Hill
-- [ ] Christina Stone
-- [ ] John Wiegley
-** Not reviewing prior minutes at this meeting
-** Teaching
-** Consultation
-** New Business
-** Next Assembly meeting is [2013-01-01 Tue 00:00]
\ No newline at end of file
tools/emacs/etc/yasnippet/snippets/org-mode/todo
@@ -1,7 +0,0 @@
-#name : TODO
-# --
-TODO $0
-SCHEDULED: `(with-temp-buffer (org-insert-time-stamp (current-time)))`
-:PROPERTIES:
-:ID:       `(shell-command-to-string "uuidgen")`:CREATED: `(with-temp-buffer (org-insert-time-stamp (current-time) t t))`
-:END:
\ No newline at end of file
tools/emacs/etc/yasnippet/snippets/python-mode/def
@@ -1,36 +0,0 @@
-# -*- coding: utf-8 -*-
-# name: de
-# contributor: Orestis Markou
-# contributor: Yasser González Fernández <yglez@uh.cu>
-# contributor: Tibor Simko <tibor.simko@cern.ch>
-# --
-def ${1:name}($2):
-    """
-    $3
-    ${2:$
-    (let* ((indent
-            (concat "\n" (make-string (current-column) 32)))
-           (args
-            (mapconcat
-             '(lambda (x)
-                (if (not (string= (nth 0 x) ""))
-                    (concat "@param " (nth 0 x) ": " indent
-                            "@type " (nth 0 x) ": ")))
-             (mapcar
-              '(lambda (x)
-                 (mapcar
-                  '(lambda (x)
-                     (replace-regexp-in-string "[[:blank:]]*$" ""
-                      (replace-regexp-in-string "^[[:blank:]]*" "" x)))
-                  x))
-              (mapcar '(lambda (x) (split-string x "="))
-                      (split-string yas-text ",")))
-             indent)))
-      (if (string= args "")
-          (concat indent "@return: " indent "@rtype: " indent (make-string 3 34))
-        (mapconcat
-         'identity
-         (list "" args "@return: " "@rtype: " (make-string 3 34))
-         indent)))
-    }
-    $0
tools/emacs/etc/yasnippet/snippets/rust-mode/clone
@@ -1,7 +0,0 @@
-# -*- mode: snippet -*-
-# name: clone
-# key: clone
-# --
-clone(&self) -> Self {
-    $0
-}
\ No newline at end of file
tools/emacs/etc/yasnippet/snippets/rust-mode/default
@@ -1,7 +0,0 @@
-# -*- mode: snippet -*-
-# name: default
-# key: default
-# --
-default() -> Self {
-    ${0:Self::new()}
-}
\ No newline at end of file
tools/emacs/etc/yasnippet/snippets/rust-mode/fmt
@@ -1,7 +0,0 @@
-# -*- mode: snippet -*-
-# name: fmt
-# key: fmt
-# --
-fmt(&self, f: &mut Formatter) -> Result<(), Error> {
-    $0
-}
\ No newline at end of file
tools/emacs/etc/yasnippet/snippets/rust-mode/impl
@@ -1,7 +0,0 @@
-# -*- mode: snippet -*-
-# name: impl
-# key: impl
-# --
-impl$3 ${1:Trait} for ${2:Type}$3 {
-    $0
-}
\ No newline at end of file
tools/emacs/etc/yasnippet/snippets/rust-mode/implClone
@@ -1,9 +0,0 @@
-# -*- mode: snippet -*-
-# name: implClone
-# key: Clone
-# --
-impl$2 Clone for ${1:Type}$2 {
-    fn clone(&self) -> Self {
-        $0
-    }
-}
\ No newline at end of file
tools/emacs/etc/yasnippet/snippets/rust-mode/implDefault
@@ -1,9 +0,0 @@
-# -*- mode: snippet -*-
-# name: implDefault
-# key: Default
-# --
-impl$2 Default for ${1:Type}$2 {
-    fn default() -> Self {
-        ${0:Self::new()}
-    }
-}
\ No newline at end of file
tools/emacs/etc/yasnippet/snippets/rust-mode/is_empty
@@ -1,7 +0,0 @@
-# -*- mode: snippet -*-
-# name: is_empty
-# key: is_empty
-# --
-is_empty(&self) -> bool {
-    ${0:self.len() == 0}
-}
\ No newline at end of file
tools/emacs/etc/yasnippet/snippets/rust-mode/len
@@ -1,7 +0,0 @@
-# -*- mode: snippet -*-
-# name: len
-# key: len
-# --
-len(&self) -> usize {
-    $0
-}
\ No newline at end of file
tools/emacs/etc/yasnippet/snippets/rust-mode/new
@@ -1,7 +0,0 @@
-# -*- mode: snippet -*-
-# name: new
-# key: new
-# --
-new() -> Self {
-    $0
-}
\ No newline at end of file
tools/emacs/etc/yasnippet/snippets/text-mode/ggit
@@ -1,1 +0,0 @@
-https://github.com/vdemeester/$0
tools/emacs/etc/pandoc.css
@@ -1,245 +0,0 @@
-/***************************************************************************/
-/* My Stylesheet for Pandoc generated files                                */
-/* Copyright (c) 2015 Sebastian Wiesner <swiesner@lunaryorn.com>           */
-/*                                                                         */
-/* Permission is hereby granted, free of charge, to any person obtaining a */
-/* copy of this software and associated documentation files (the           */
-/* "Software"), to deal in the Software without restriction, including     */
-/* without limitation the rights to use, copy, modify, merge, publish,     */
-/* distribute, sublicense, and/or sell copies of the Software, and to      */
-/* permit persons to whom the Software is furnished to do so, subject to   */
-/* the following conditions:                                               */
-/*                                                                         */
-/* The above copyright notice and this permission notice shall be included */
-/* in all copies or substantial portions of the Software.                  */
-/*                                                                         */
-/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS */
-/* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF              */
-/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND                   */
-/* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE  */
-/* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION  */
-/* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION   */
-/* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.         */
-/***************************************************************************/
-
-body {
-  font-family: "Source Sans Pro", sans-serif;
-  font-size: 16px;
-  line-height: 1.35;
-  color: #444;
-  font-feature-settings: "onum", "kern", "liga", "clig", "dlig", "calt";
-  -webkit-font-feature-settings: "onum", "kern", "liga", "clig", "dlig", "calt";
-  margin: 0 auto;
-  padding: 15px;
-  margin-bottom: 1.35em;
-  word-wrap: break-word;
-}
-
-p {
-  margin: 0 0;
-  text-indent: 1.5em;
-  text-align: left;
-}
-
-p:only-child {
-  text-indent: 0;
-}
-
-strong {
-  font-weight: 600;
-}
-
-ul, ol {
-  margin: 1em 4em;
-  padding: 0;
-}
-
-ol {
-  list-style-type: decimal;
-}
-
-ul {
-  list-style-type: disc;
-}
-
-small, sup {
-  font-size: 0.86em;
-}
-
-h1 small, h2 small, h3 small, h4 small {
-  font-weight: normal;
-  font-size: 0.65em;
-  line-height: 1;
-  color: #777;
-}
-
-blockquote {
-  margin: 1.2em 0;
-  padding: 0 2em;
-  line-height: 1.25;
-  font-size: 0.9em;
-  border-left: 5px solid #EEE;
-}
-
-a {
-  color: #333;
-  text-decoration: underline;
-}
-
-a:hover {
-  background-color: #fbf3f3;
-  border-radius: 4px;
-  transition-property: background;
-  transition-duration: 0.2s;
-}
-
-.footnoteRef {                  /* Use body font for footnotes */
-  font-size: 1rem;
-  text-decoration: none;
-}
-
-h1, h2, h3, h4 {                /* Text headings*/
-  font-family: "Source Sans Pro", sans-serif;
-  font-weight: 600;
-  line-height: 1;
-  color: #222;
-  margin-top: 2em;
-  margin-bottom: 0.8em;
-  hyphens: none;
-  font-feature-settings: "salt", "lnum";
-  -webkit-font-feature-settings: "salt", "lnum";
-}
-
-h1 {
-  font-size: 1.2em;
-}
-
-h2 {
-  font-size: 1.1em;
-}
-
-h3 {
-  font-size: 1em;
-}
-
-.header-section-number {
-  margin-right: 0.5em;
-}
-
-.header-section-number:after {
-  content: "."
-}
-
-hr {
-  border-width: 1px;
-  border-color: #CCC;
-  border-style: none none solid;
-  margin: 1.35em 0;
-}
-
-/* Images and figures */
-img {
-  max-width: 100%;
-  max-height: 100%;
-}
-
-figure {
-  margin: 2em;
-}
-
-figcaption {
-  margin-top: 0.8em;
-  text-align: center;
-  font-size: 0.9em;
-}
-
-figcaption:before {
-  content: "Figure.";
-  font-weight: 700;
-  margin-right: 0.5em;
-}
-
-/* Code and pre-formatted text */
-kbd, code {
-  font-family: "Source Code Pro", monospace;
-  font-size: 0.83em;
-}
-
-kbd {
-  border: 1px solid #CCC;
-  border-radius: 4px;
-  box-shadow: 0 1px 0 rgba(0, 0, 0, 0.2), 0 0 0 2px #FFF inset;
-  padding: 0 4px;
-}
-
-code {
-  padding: 0.11em 0.22em;
-}
-
-pre {
-  overflow: auto;
-  padding: 10px;
-  border: 1px solid #CCC;
-  border-radius: 4px;
-}
-
-pre:hover {                     /* Auto-expand pre on hover */
-  position: relative;
-  width: 900px;
-  z-index: 99;
-}
-
-pre code {
-  padding: 0;
-}
-
-.title {               /* Page title */
-  font-size: 1.5rem;
-  font-weight: 700;
-  margin-bottom: 0.2em;
-  margin-top: 0;
-}
-
-nav {
-  margin: 1em;
-  font-feature-settings: "salt", "lnum";
-  -webkit-font-feature-settings: "salt", "lnum";
-}
-
-nav a {
-  text-decoration: none;
-}
-
-nav ul {
-  list-style: none inside disc;
-  margin: 0;
-  padding: 0 0.5em;
-}
-
-header {
-  border-width: 1px;
-  border-color: #CCC;
-  border-style: none none solid;
-  margin: 1.35em 0;
-}
-
-
-@media print {
-  body {
-    width: auto;
-    height: auto;
-    font-size: 10pt;
-  }
-}
-
-@media screen and (min-width: 650px) {     /* Larger devices */
-  body {
-    width: 600px;
-  }
-}
-
-@page
-{
-  size: A4;
-  margin: 24.75mm 17.50mm;
-}
tools/emacs/host/naruhodo.el
@@ -1,1 +0,0 @@
-../../sync/emacs/naruhodo.el
\ No newline at end of file
tools/emacs/host/README.org
@@ -1,1 +0,0 @@
-Put stuff here that are local to a specific machine, those are private, aka not shared via this git repository.
tools/emacs/host/wakasu.el
@@ -1,1 +0,0 @@
-../../sync/emacs/wakasu.el
\ No newline at end of file
tools/emacs/lisp/auto-side-windows
@@ -1,1 +0,0 @@
-Subproject commit a18be7988b8f0f329b53f117dd517b2340bd4bc4
tools/emacs/lisp/consult-mu
@@ -1,1 +0,0 @@
-Subproject commit e1dc63674b924698b30a9ecc0400a05864711c85
tools/emacs/lisp/gh-notifications-mode.el
@@ -1,513 +0,0 @@
-;;; github-notifications-gh.el --- Display GitHub notifications in Emacs using gh CLI -*- lexical-binding: t -*-
-
-;; Author: Your Name
-;; Version: 1.0
-;; Package-Requires: ((emacs "27.1"))
-
-;;; Commentary:
-;; This package provides functionality to fetch and display GitHub notifications
-;; in a dedicated buffer using the GitHub CLI (gh) and tabulated-list-mode.
-;; Make sure you have gh installed and authenticated before using this package.
-
-;;; For pull-request, fetch the diff from the diff_url field
-;;; For CI status, use the statuses_url
-
-;;; Code:
-
-(require 'json)
-(require 'tabulated-list)
-(require 'diff-mode)
-
-(defgroup github-notifications nil
-  "GitHub notifications in Emacs."
-  :group 'applications)
-
-(defcustom github-notifications-refresh-interval 300
-  "Number of seconds between automatic refresh of notifications."
-  :type 'integer
-  :group 'github-notifications)
-
-(defface github-notifications-unread-face
-  '((t :weight bold))
-  "Face for unread notifications."
-  :group 'github-notifications)
-
-(defvar github-notifications-buffer-name "*GitHub Notifications*"
-  "Name of the buffer for displaying GitHub notifications.")
-
-(defvar github-notifications-mode-map
-  (let ((map (make-sparse-keymap)))
-    (define-key map (kbd "g") 'github-notifications-refresh)
-    (define-key map (kbd "m") 'github-notifications-mark-read)
-    (define-key map (kbd "c") 'github-notifications-comment-on-pr)
-    (define-key map (kbd "d") 'github-notifications-mark-done)
-    (define-key map (kbd "a") 'github-notifications-approve-pr)
-    (define-key map (kbd "w") 'github-notifications-copy-url)
-    (define-key map (kbd "r") 'github-notifications-request-changes-on-pr)
-    (define-key map (kbd "v") 'github-notifications-show-details)
-    (define-key map (kbd "RET") 'github-notifications-open-at-point)
-    ;; m for mark
-    map)
-  "Keymap for GitHub notifications buffer.")
-
-(defvar github-notifications-detail-buffer-name "*GitHub Notification Detail*"
-  "Name of the buffer for displaying GitHub notification details.")
-
-(defvar github-notifications-detail-mode-map
-  (let ((map (make-sparse-keymap)))
-    (define-key map (kbd "q") 'quit-window)
-    map)
-  "Keymap for GitHub notification detail buffer.")
-
-(define-derived-mode github-notifications-detail-mode special-mode "GitHub-Notification-Detail"
-  "Major mode for displaying GitHub notification details."
-  (setq buffer-read-only t))
-
-(defvar github-notifications--process-buffer "*github-notifications-process*"
-  "Buffer for GitHub notifications processes.")
-
-(defun github-notifications--call-process-async (callback _buf name &rest args)
-  "Call gh process asynchronously with ARGS and CALLBACK when done.
-Creates a temporary buffer for the process output."
-  (let ((temp-buffer (generate-new-buffer (format " *gh-%s*" name))))
-    (setenv "TERM" "dumb")
-    (setenv "CLICOLOR" "0")
-    (setenv "PAGER" "cat")
-    (make-process
-     :name name
-     :buffer temp-buffer
-     :command (cons "gh" args)
-     :sentinel (lambda (process _event)
-                 (unwind-protect
-                     (when (eq (process-status process) 'exit)
-                       (if (= (process-exit-status process) 0)
-                           (with-current-buffer (process-buffer process)
-                             (funcall callback (buffer-string)))
-                         (message "GitHub CLI process failed")))
-                   (kill-buffer temp-buffer))))))
-
-(define-derived-mode github-notifications-mode tabulated-list-mode "GitHub-Notifications"
-  "Major mode for displaying GitHub notifications."
-  (setq tabulated-list-format
-        [("Status" 6 t)
-         ("CI" 8 t)
-         ("Repository" 30 t)
-         ("Type" 15 t)
-         ("Title" 60 t)
-         ("Updated" 20 t)])
-  (setq tabulated-list-sort-key '("Updated" . t))
-  (setq tabulated-list-padding 2)
-  (tabulated-list-init-header))
-
-(defun github-notifications--ensure-gh ()
-  "Ensure gh command line tool is available."
-  (unless (executable-find "gh")
-    (error "GitHub CLI (gh) not found. Please install it first")))
-
-(defun github-notifications--parse-json (json-string)
-  "Parse JSON-STRING into Lisp objects."
-  (json-read-from-string json-string))
-
-(defun github-notifications--format-time (time-string)
-  "Format TIME-STRING to a human-readable format."
-  (format-time-string
-   "%Y-%m-%d %H:%M"
-   (date-to-time time-string)))
-
-(defun github-notifications--format-list-entry (notification)
-  "Format a NOTIFICATION as a tabulated list entry."
-  (let-alist notification
-    (list .id
-          (vector
-           (github-notifications--format-unread .unread)
-           (if (string= .type "PullRequest")
-	       (github-notifications--format-ci-status .ci_status)
-	     " ")
-	   ;; (if (string= .type "PullRequest")
-	   ;; 	 (or .ci_status "?")
-           ;;   "")
-           .repo
-           .type
-           (propertize .title
-                       'notification-id .id
-                       'notification-url .url  ; Add this line
-                       'github-notifications--copy-url .url
-                       'notification-type .type
-                       'repo .repo)
-           (github-notifications--format-time .updated)))))
-
-(defun github-notifications-fetch ()
-  "Fetch notifications using gh CLI asynchronously."
-  (github-notifications--ensure-gh)
-  (github-notifications--call-process-async
-   (lambda (output)
-     (let* ((raw-notifications (github-notifications--parse-json output))
-            (normalized-notifications
-             (mapcar #'github-notifications--normalize-notification raw-notifications)))
-       ;; For each PR notification, fetch its status
-       (dolist (notif normalized-notifications)
-         (when (and (equal (alist-get 'type notif) "PullRequest"))
-           (github-notifications--get-pr-statuses notif))
-	 ;; FIXME there is a bug here, it share the same thing
-         (github-notifications--display normalized-notifications))))
-   (get-buffer-create github-notifications--process-buffer)
-   "github-notifications"
-   "api"
-   "-H" "Accept: application/vnd.github+json"
-   "/notifications?all=true"))
-
-(defun github-notifications--normalize-notification (notif)
-  "Convert raw notification to normalized format."
-  (let-alist notif
-    `((id . ,.id)
-      (type . ,.subject.type)
-      (title . ,.subject.title)
-      (repo . ,.repository.full_name)
-      (url . ,.subject.url)
-      (updated . ,.updated_at)
-      (unread . ,.unread)
-      (ci_status . nil)
-      (statuses_url . ,.subject.statuses_url))))
-
-(defun github-notifications--display (notifications)
-  "Display NOTIFICATIONS in the buffer."
-  (with-current-buffer (get-buffer-create github-notifications-buffer-name)
-    (github-notifications-mode)
-    (setq tabulated-list-entries
-          (mapcar #'github-notifications--format-list-entry notifications))
-    (tabulated-list-print t)))
-
-(defun github-notifications-refresh ()
-  "Refresh the notifications buffer."
-  (interactive)
-  (github-notifications-fetch))
-
-(defun github-notifications-mark-read ()
-  "Mark notification at point as read."
-  (interactive)
-  (when-let* ((entry (github-notifications--get-entry-data))
-              (id (nth 4 entry)))
-    (github-notifications--ensure-gh)
-    (with-temp-buffer
-      (unless (= 0 (call-process "gh" nil t nil
-                                 "api"
-                                 "-X" "PATCH"
-                                 (format "/notifications/threads/%s" id)))
-        (error "Failed to mark notification as read")))
-    (github-notifications-refresh)))
-
-(defun github-notifications-mark-done ()
-  "Mark notification at point as done."
-  (interactive)
-  (when-let* ((entry (github-notifications--get-entry-data))
-              (id (nth 4 entry)))
-    (github-notifications--ensure-gh)
-    (with-temp-buffer
-      (unless (= 0 (call-process "gh" nil t nil
-                                 "api"
-                                 "-X" "DELETE"
-                                 (format "/notifications/threads/%s" id)))
-        (error "Failed to mark notification as done")))
-    (github-notifications-refresh)))
-
-(defun github-notifications--copy-url ()
-  "Copy the URL of the notification item at point."
-  (interactive)
-  (let* ((entry (github-notifications--get-entry-data))
-	 (api-url (nth 3 entry))
-	 (url (replace-regexp-in-string
-               "api\\.github\\.com/repos"
-               "github.com"
-               (replace-regexp-in-string
-                "/pulls/"
-                "/pull/"
-                api-url))))
-    (kill-new url)))
-
-(defun github-notifications-open-at-point ()
-  "Open the notification at point in a web browser."
-  (interactive)
-  (when-let* ((entry (tabulated-list-get-entry))
-              (title-col (aref entry 3))
-              (url (get-text-property 0 'notification-url title-col)))
-    (let ((web-url (replace-regexp-in-string
-                    "api\\.github\\.com/repos"
-                    "github.com"
-                    (replace-regexp-in-string
-                     "/pulls/"
-                     "/pull/"
-                     url))))
-      (browse-url web-url))))
-
-(defun github-notifications--get-entry-data ()
-  "Get PR data from current entry."
-  (let* ((entry (tabulated-list-get-entry))
-	 (id (aref entry 3))
-         (title-cell (aref entry 4))
-         (repo (get-text-property 0 'repo title-cell))
-         (url (get-text-property 0 'notification-url title-cell))
-         (notification-id (get-text-property 0 'notification-id title-cell))
-         (pr-number (github-notifications--get-pr-number url)))
-    (list id repo pr-number url notification-id)))
-
-(defun github-notifications-comment-on-pr ()
-  "Add a comment to the pull request at point."
-  (interactive)
-  (let* ((pr-data (github-notifications--get-entry-data))
-         (repo (nth 1 pr-data))
-         (pr-number (nth 2 pr-data))
-         (comment (read-string "Comment: "))),
-    (when (and repo pr-number (not (string-empty-p comment)))
-      (let ((default-directory (make-temp-file "gh-pr" t)))
-        (call-process "gh" nil "*github-notifications process*" nil
-                      "pr" "comment"
-		      pr-number
-                      "--body" comment
-		      "--repo" repo)
-        (message "Comment posted successfully")))))
-
-(defun github-notifications-request-changes-on-pr ()
-  "Add a comment to the pull request at point."
-  (interactive)
-  (let* ((pr-data (github-notifications--get-entry-data))
-         (repo (nth 1 pr-data))
-         (pr-number (nth 2 pr-data))
-         (comment (read-string "Comment: ")))
-    (when (and repo pr-number (not (string-empty-p comment)))
-      (let ((default-directory (make-temp-file "gh-pr" t)))
-        (call-process "gh" nil "*github-notifications process*" nil
-                      "pr" "review"
-		      pr-number
-                      "--body" comment
-		      "--request-changes"
-		      "--repo" repo)
-        (message "Comment posted successfully")))))
-
-(defun github-notifications-approve-pr (&optional comment)
-  "Approve the pull request at point with an optional comment."
-  (interactive
-   (list (read-string "Approval comment (optional): ")))
-  (let* ((pr-data (github-notifications--get-entry-data))
-         (repo (nth 1 pr-data))
-         (pr-number (nth 2 pr-data))
-         (args (list "pr" "review"
-                     pr-number
-                     "--approve"
-		     "--repo" repo)))
-    (when (and repo pr-number)
-      (when (and comment (not (string-empty-p comment)))
-        (setq args (append args (list "--body" comment))))
-      (let ((default-directory (make-temp-file "gh-pr" t)))
-        (apply #'call-process "gh" nil "*github-notifications process*" nil args)
-        (message "PR approved successfully")))))
-
-(defun github-notifications--get-pr-statuses (notification)
-  "Get CI statuses for a PR using the GitHub GraphQL API."
-  (let* ((url (alist-get 'url notification))
-         (repo (alist-get 'repo notification))
-	 (pr-number(github-notifications--get-pr-number url)))
-    (when (and repo pr-number)
-      (with-temp-buffer
-	(github-notifications--call-process-async
-	 (lambda (output)
-	   (let* ((response (github-notifications--parse-json (buffer-string)))
-		  (contexts (thread-last response
-					 (alist-get 'data)
-					 (alist-get 'repository)
-					 (alist-get 'pullRequest)
-					 (alist-get 'commits)
-					 (alist-get 'nodes)
-					 (seq-first)
-					 (alist-get 'commit)
-					 (alist-get 'statusCheckRollup)
-					 (alist-get 'contexts)
-					 (alist-get 'nodes)))
-		  (statuses (seq-map
-			     (lambda (ctx)
-                               (let ((state (or (alist-get 'state ctx)
-						(alist-get 'conclusion ctx))))
-				 (cond
-				  ((member state '("SUCCESS" "success" "COMPLETED")) "success")
-				  ((member state '("FAILURE" "failure" "ERROR" "error")) "failure")
-				  (t "pending"))))
-			     contexts))
-		  (total (length statuses))
-		  (successes (seq-count (lambda (s) (string= s "success")) statuses))
-		  (failures (seq-count (lambda (s) (string= s "failure")) statuses))
-		  (pendings (seq-count (lambda (s) (string= s "pending")) statuses))
-		  (ci-status (list :total total
-				   :successes successes
-				   :failures failures
-				   :pendings pendings)))
-	     (setf (alist-get 'ci_status notification) ci-status)))
-	 (get-buffer-create (format "*github-notifications-%s-%s-process*" repo pr-number))
-	 (format "github-notifications-%s-%s" repo pr-number)
-	 "api" "graphql" "-f"
-	 (format "query=%s"
-		 (github-notifications--make-graphql-query repo pr-number)))))))
-
-(defun github-notifications--format-ci-status (statuses)
-  "Format CI status with appropriate face and count information."
-  (if (null statuses)
-      (propertize "?" 'face '(:foreground "gray"))
-    (let* ((total (plist-get statuses :total))
-           (successes (plist-get statuses :successes))
-           (failures (plist-get statuses :failures))
-           (pendings (plist-get statuses :pendings))
-           (indicator
-            (cond
-             ((> failures 0) "✗")
-             ((> pendings 0) "○")
-             ((= successes total) "✓")
-             (t "?")))
-           (face
-            (cond
-             ((> failures 0) '(:foreground "red"))
-             ((> pendings 0) '(:foreground "orange"))
-             ((= successes total) '(:foreground "green"))
-             (t '(:foreground "gray"))))
-           (count-str (format "%d/%d" successes total)))
-      (concat
-       (propertize indicator 'face face)
-       " "
-       (propertize count-str 'face face)))))
-
-(defun github-notifications--make-graphql-query (repo pr-number)
-  "Create a GraphQL query for PR status checks."
-  (format "query {
-    repository(owner: \"%s\", name: \"%s\") {
-      pullRequest(number: %s) {
-        commits(last: 1) {
-          nodes {
-            commit {
-              statusCheckRollup {
-                state
-                contexts(first: 100) {
-                  nodes {
-                    ... on StatusContext {
-                      state
-                      context
-                    }
-                    ... on CheckRun {
-                      status
-                      conclusion
-                      name
-                    }
-                  }
-                }
-              }
-            }
-          }
-        }
-      }
-    }
-  }"
-          (car (split-string repo "/"))
-          (cadr (split-string repo "/"))
-          pr-number))
-
-(defun github-notifications--format-unread (unread)
-  "Return a propertized string to showcase the status of the notifications"
-  ;; (cond ((unread) (propertize "●" 'face 'github-notifications-unread-face))
-  ;; 	((not unread) (propertize "○" 'face 'github-notifications-unread-face))
-  ;; 	(t (propertize "?" 'face 'github-notifications-unread-face)))
-  (cond (unread (propertize "●" 'face 'github-notifications-unread-face))
-	((not unread) (propertize "○" 'face 'github-notifications-unread-face))
-	(t (propertize "?" 'face 'github-notifications-unread-face))))
-
-(defun github-notifications--get-pr-number (url)
-  "Extract pull request number from URL."
-  (when (string-match "/pulls/\\([0-9]+\\)" url)
-    (match-string 1 url)))
-
-(defun github-notifications-show-details ()
-  "Show detailed view of the notification at point."
-  (interactive)
-  (when-let* ((entry (tabulated-list-get-entry))
-              (title-cell (aref entry 4))
-              (type (get-text-property 0 'notification-type title-cell))
-              (repo (get-text-property 0 'repo title-cell))
-              (url (get-text-property 0 'github-notifications--copy-url title-cell)))
-    (let ((buffer (get-buffer-create github-notifications-detail-buffer-name)))
-      (with-current-buffer buffer
-        (let ((inhibit-read-only t))
-          (erase-buffer)
-          (github-notifications-detail-mode)
-          (cond
-           ((string= type "PullRequest")
-            (github-notifications--show-pr-details repo url))
-           ((string= type "Issue")
-            (github-notifications--show-issue-details repo url))
-           (t
-            (insert "No detailed view available for this notification type."))))
-        (goto-char (point-min)))
-      (display-buffer buffer))))
-
-(defun github-notifications--show-pr-details (repo url)
-  "Show pull request details for REPO and URL."
-  (let ((pr-number (github-notifications--get-pr-number url)))
-    (when pr-number
-      (insert (format "=== Pull Request #%s ===\n\n" pr-number))
-      ;; Fetch PR details
-      (github-notifications--call-process-async
-       (lambda (output)
-         (let ((inhibit-read-only t))
-           (save-excursion
-             (goto-char (point-min))
-             (forward-line 2)
-             (let* ((pr-data (github-notifications--parse-json output)))
-               (insert (format "Title: %s\n" (alist-get 'title pr-data)))
-               (insert (format "State: %s\n" (alist-get 'state pr-data)))
-               (insert (format "\nDescription:\n%s\n" (alist-get 'body pr-data)))))))
-       nil
-       "pr-details"
-       "pr" "view" pr-number "--json" "title,body,state" "--repo" repo)
-      
-      ;; Fetch and display diff
-      (insert "\n=== Diff ===\n\n")
-      (github-notifications--call-process-async
-       (lambda (output)
-         (let ((inhibit-read-only t))
-           (save-excursion
-             (goto-char (point-max))
-             (insert output)
-             (let ((diff-start (save-excursion
-                                 (goto-char (point-min))
-                                 (search-forward "\n=== Diff ===\n\n" nil t))))
-               (when diff-start
-                 (diff-mode-setup))))))
-       nil
-       "pr-diff"
-       "pr" "diff" pr-number "--repo" repo))))
-
-(defun github-notifications--get-issue-number (url)
-  "Extract issue number from URL."
-  (when (string-match "/issues/\\([0-9]+\\)" url)
-    (match-string 1 url)))
-
-(defun github-notifications--format-checks (checks)
-  "Format checks data for display."
-  (mapconcat
-   (lambda (check)
-     (let-alist check
-       (format "%s: %s"
-               .name
-               (propertize .status 'face
-                           (pcase .status
-                             ("success" '(:foreground "green"))
-                             ("failure" '(:foreground "red"))
-                             (_ '(:foreground "yellow")))))))
-   checks "\n"))
-
-;;;###autoload
-(defun github-notifications ()
-  "Display GitHub notifications in a buffer."
-  (interactive)
-  (github-notifications--ensure-gh)
-  (let ((buffer (get-buffer-create github-notifications-buffer-name)))
-    (with-current-buffer buffer
-      (github-notifications-fetch))
-    (switch-to-buffer buffer)))
-
-(provide 'github-notifications-gh)
-;;; github-notifications-gh.el ends here
tools/emacs/lisp/gotest-ui.el
@@ -1,631 +0,0 @@
-;;; gotest-ui.el --- Major mode for running go test -json
-
-;; Copyright 2018 Andreas Fuchs
-;; Authors: Andreas Fuchs <asf@boinkor.net>
-
-;; URL: https://github.com/antifuchs/gotest-ui-mode
-;; Created: Feb 18, 2018
-;; Keywords: languages go
-;; Version: 0.1.0
-;; Package-Requires: ((emacs "25") (s "1.12.0") (gotest "0.14.0"))
-
-;; This file is not a part of GNU Emacs.
-
-;; This program is free software; you can redistribute it and/or
-;; modify it under the terms of the GNU General Public License as
-;; published by the Free Software Foundation; either version 3.0, or
-;; (at your option) any later version.
-
-;; This program is distributed in the hope that it will be useful,
-;; but WITHOUT ANY WARRANTY; without even the implied warranty of
-;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-;; GNU General Public License for more details.
-
-;; You should have received a copy of the GNU General Public License
-;; along with this program; if not, write to the Free Software
-;; Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
-;;; Commentary:
-
-;;  Provides support for running go tests with a nice user interface
-;;  that allows folding away output, highlighting failing tests.
-
-;;; Code:
-
-(eval-when-compile
-  (require 'cl))
-
-(require 'subr-x)
-(require 'ewoc)
-(require 'json)
-(require 'compile)
-
-(defgroup gotest-ui nil
-  "The go test runner."
-  :group 'tools)
-
-(defface gotest-ui-pass-face '((t :foreground "green"))
-  "Face for displaying the status of a passing test."
-  :group 'gotest-ui)
-
-(defface gotest-ui-skip-face '((t :foreground "grey"))
-  "Face for displaying the status of a skipped test."
-  :group 'gotest-ui)
-
-(defface gotest-ui-fail-face '((t :foreground "pink" :weight bold))
-  "Face for displaying the status of a failed test."
-  :group 'gotest-ui)
-
-(defface gotest-ui-link-face '((t :foreground "white" :weight bold))
-  "Face for displaying links to go source files."
-  :group 'gotest-ui)
-
-(defcustom gotest-ui-expand-test-statuses '(fail)
-  "Statuses to expand test cases for.
-Whenever a test enters this state, it is automatically expanded."
-  :group 'gotest-ui)
-
-(defcustom gotest-ui-test-binary '("go")
-  "Command list used to invoke the `go' binary."
-  :group 'gotest-ui)
-
-(defcustom gotest-ui-test-args '("test" "-json")
-  "Argument list used to run tests with JSON output."
-  :group 'gotest-ui)
-
-(defcustom gotest-ui-additional-test-args '()
-  "Additional args to pass to `go test'."
-  :group 'gotest-ui)
-
-;;;; Data model:
-
-(defstruct (gotest-ui-section :named
-                              (:constructor gotest-ui-section-create)
-                              (:type vector)
-                              (:predicate gotest-ui-section-p))
-  title tests node)
-
-;;; `gotest-ui-thing' is a thing that can be under test: a
-;;; package, or a single test.
-
-(defstruct gotest-ui-thing
-  (name)
-  (node)
-  (expanded-p)
-  (status)
-  (buffer)    ; the buffer containing this test's output
-  (elapsed)   ; a floating-point amount of seconds
-  )
-
-;;; `gotest-ui-test' is a single test. It contains a status and
-;;; output.
-(defstruct (gotest-ui-test (:include gotest-ui-thing)
-                           (:constructor gotest-ui--make-test-1))
-  (package)
-  (reason))
-
-(defun gotest-ui-test->= (test1 test2)
-  "Returns true if TEST1's name sorts greater than TEST2's."
-  (let ((pkg1 (gotest-ui-test-package test1))
-        (pkg2 (gotest-ui-test-package test2))
-        (name1 (or (gotest-ui-thing-name test1) ""))
-        (name2 (or (gotest-ui-thing-name test2) "")))
-    (if (string= pkg1 pkg2)
-        (string> name1 name2)
-      (string> pkg1 pkg2))))
-
-(defstruct (gotest-ui-status (:constructor gotest-ui--make-status-1))
-  (state)
-  (cmdline)
-  (dir)
-  (output)
-  (node))
-
-(cl-defun gotest-ui--make-status (ewoc cmdline dir)
-  (let ((status (gotest-ui--make-status-1 :state 'run :cmdline (s-join " " cmdline) :dir dir)))
-    (let ((node (ewoc-enter-first ewoc status)))
-      (setf (gotest-ui-status-node status) node))
-    status))
-
-(cl-defun gotest-ui--make-test (ewoc &rest args &key status package name &allow-other-keys)
-  (apply #'gotest-ui--make-test-1 :status (or status "run") args))
-
-;;; Data manipulation routines:
-
-(cl-defun gotest-ui-ensure-test (ewoc package-name base-name &key (status 'run))
-  (let* ((test-name (format "%s.%s" package-name base-name))
-         (test (gethash test-name gotest-ui--tests)))
-    (if test
-        test
-      (setf (gethash test-name gotest-ui--tests)
-            (gotest-ui--make-test ewoc :name base-name :package package-name :status status)))))
-
-(defun gotest-ui-update-status (new-state)
-  (setf (gotest-ui-status-state gotest-ui--status) new-state)
-  (ewoc-invalidate gotest-ui--ewoc (gotest-ui-status-node gotest-ui--status)))
-
-(defun gotest-ui-update-status-output (new-output)
-  (setf (gotest-ui-status-output gotest-ui--status) new-output)
-  (ewoc-invalidate gotest-ui--ewoc (gotest-ui-status-node gotest-ui--status)))
-
-(defun gotest-ui-ensure-output-buffer (thing)
-  (unless (gotest-ui-thing-buffer thing)
-    (with-current-buffer
-        (setf (gotest-ui-thing-buffer thing)
-              (generate-new-buffer (format " *%s" (gotest-ui-thing-name thing))))
-      (setq-local gotest-ui-parse-marker (point-min-marker))
-      (setq-local gotest-ui-insertion-marker (point-min-marker))
-      (set-marker-insertion-type gotest-ui-insertion-marker t)))
-  (gotest-ui-thing-buffer thing))
-
-(defun gotest-ui-mouse-open-file (event)
-  "In gotest-ui mode, open the file/line reference in another window."
-  (interactive "e")
-  (let ((window (posn-window (event-end event)))
-        (pos (posn-point (event-end event)))
-        file line)
-    (if (not (windowp window))
-        (error "No file chosen"))
-    (with-current-buffer (window-buffer window)
-      (goto-char pos)
-      (gotest-ui-open-file-at-point))))
-
-(defun gotest-ui-open-file-at-point ()
-  (interactive)
-  (let ((file (gotest-ui-get-file-for-visit))
-        (line (gotest-ui-get-line-for-visit)))
-    (unless (file-exists-p file)
-      (error "Could not open %s:%d" file line))
-    (with-current-buffer (find-file-other-window file)
-      (goto-char (point-min))
-      (when line
-        (forward-line (1- line))))))
-
-(defun gotest-ui-get-file-for-visit ()
-  (get-text-property (point) 'gotest-ui-file))
-
-(defun gotest-ui-get-line-for-visit ()
-  (string-to-number (get-text-property (point) 'gotest-ui-line)))
-
-(defun gotest-ui-file-from-gopath (package file-basename)
-  (if (or (file-name-absolute-p file-basename)
-          (string-match-p "/" file-basename))
-      file-basename
-    (let ((gopath (or (getenv "GOPATH")
-                      (expand-file-name "~/go"))))
-      (expand-file-name (concat gopath "/src/" package "/" file-basename)))))
-
-(defvar gotest-ui-click-map
-  (let ((map (make-sparse-keymap)))
-    (define-key map [mouse-2] 'gotest-ui-mouse-open-file)
-    map))
-
-(defun gotest-ui-ensure-parsed (thing)
-  (save-excursion
-    (goto-char gotest-ui-parse-marker)
-    (while (re-search-forward "\\([^ \t]+\\.go\\):\\([0-9]+\\)" gotest-ui-insertion-marker t)
-      (let* ((file-basename (match-string 1))
-             (file (gotest-ui-file-from-gopath (gotest-ui-test-package thing) file-basename)))
-        (set-text-properties (match-beginning 0) (match-end 0)
-                             `(face gotest-ui-link-face
-                                    gotest-ui-file ,file
-                                    gotest-ui-line ,(match-string 2)
-                                    keymap ,gotest-ui-click-map
-                                    follow-link t
-                                    ))))
-    (set-marker gotest-ui-parse-marker gotest-ui-insertion-marker)))
-
-(defun gotest-ui-update-thing-output (thing output)
-  (with-current-buffer (gotest-ui-ensure-output-buffer thing)
-    (goto-char gotest-ui-insertion-marker)
-    (let ((overwrites (split-string output "\r")))
-      (insert (car overwrites))
-      (dolist (segment (cdr overwrites))
-        (let ((delete-to (point)))
-          (forward-line 0)
-          (delete-region (point) delete-to))
-        (insert segment)))
-    (set-marker gotest-ui-insertion-marker (point))
-    (gotest-ui-ensure-parsed thing)))
-
-;; TODO: clean up buffers on kill
-
-;;;; Mode definition
-
-(defvar gotest-ui-mode-map
-  (let ((m (make-sparse-keymap)))
-    (suppress-keymap m)
-    ;; key bindings go here
-    (define-key m (kbd "TAB") 'gotest-ui-toggle-expanded)
-    (define-key m (kbd "g") 'gotest-ui-rerun)
-    (define-key m (kbd "RET") 'gotest-ui-open-file-at-point)
-    m))
-
-(define-derived-mode gotest-ui-mode special-mode "go test UI"
-  "Major mode for running go test with JSON output."
-  (setq truncate-lines t)
-  (setq buffer-read-only t)
-  (setq-local line-move-visual t)
-  (setq show-trailing-whitespace nil)
-  (setq list-buffers-directory default-directory)
-  (make-local-variable 'text-property-default-nonsticky)
-  (push (cons 'keymap t) text-property-default-nonsticky))
-
-
-(defun gotest-ui--clear-buffer (buffer)
-  (let ((dir default-directory))
-    (with-current-buffer buffer
-      (when (buffer-live-p gotest-ui--process-buffer)
-        (kill-buffer gotest-ui--process-buffer))
-      (kill-all-local-variables)
-      (let  ((buffer-read-only nil))
-        (erase-buffer))
-      (buffer-disable-undo)
-      (setq-local default-directory dir))))
-
-(defun gotest-ui--setup-buffer (buffer name cmdline dir)
-  (setq-local default-directory dir)
-  (setq gotest-ui--cmdline cmdline
-        gotest-ui--dir dir)
-  (let ((ewoc (ewoc-create 'gotest-ui--pp-test nil nil t))
-        (tests (make-hash-table :test #'equal)))
-    (setq gotest-ui--tests tests)
-    (setq gotest-ui--ewoc ewoc)
-    ;; Drop in the first few ewoc nodes:
-    (setq gotest-ui--status (gotest-ui--make-status ewoc cmdline dir))
-    (gotest-ui-add-section gotest-ui--ewoc 'fail "Failed Tests:")
-    (gotest-ui-add-section gotest-ui--ewoc 'run "Currently Running:")
-    (gotest-ui-add-section gotest-ui--ewoc 'skip "Skipped:")
-    (gotest-ui-add-section gotest-ui--ewoc 'pass "Passed Tests:"))
-  ;; Set up the other buffers:
-  (setq gotest-ui--stderr-process-buffer (generate-new-buffer (format " *%s (stderr)" name)))
-  (with-current-buffer gotest-ui--stderr-process-buffer
-    (setq gotest-ui--ui-buffer buffer))
-  (setq gotest-ui--process-buffer (generate-new-buffer (format " *%s" name)))
-  (with-current-buffer gotest-ui--process-buffer
-    (setq gotest-ui--ui-buffer buffer)))
-
-(defun gotest-ui-add-section (ewoc state name)
-  (let ((section (gotest-ui-section-create :title name :tests (list nil))))
-    (setf (gotest-ui-section-node section)
-          (ewoc-enter-last ewoc section))
-    (push (cons state section) gotest-ui--section-alist)))
-
-(defun gotest-ui-sort-test-into-section (test previous-state)
-  (let (invalidate-nodes)
-    (when-let ((previous-section* (and previous-state
-                                       (assoc previous-state gotest-ui--section-alist))))
-      (let ((previous-section (cdr previous-section*)))
-        (setf (gotest-ui-section-tests previous-section)
-              (delete test (gotest-ui-section-tests previous-section)))
-        (when (null (cdr (gotest-ui-section-tests previous-section)))
-          (push (gotest-ui-section-node previous-section) invalidate-nodes))))
-    ;; Drop the node from the buffer:
-    (when-let (node (gotest-ui-thing-node test))
-      (let ((buffer-read-only nil))
-        (ewoc-delete gotest-ui--ewoc node))
-      (setf (gotest-ui-thing-node test) nil))
-
-    ;; Put it in the next secion:
-    (when-let ((section* (assoc (gotest-ui-thing-status test)
-                                gotest-ui--section-alist)))
-      (let* ((section (cdr section*))
-             (insertion-cons (gotest-ui-section-tests section)))
-        (while (and (cdr insertion-cons)
-                    (gotest-ui-test->= test (cadr insertion-cons)))
-          (setq insertion-cons (cdr insertion-cons)))
-        (rplacd insertion-cons (cons test (cdr insertion-cons)))
-        (let ((insertion-node (if (car insertion-cons)
-                                  (gotest-ui-thing-node (car insertion-cons))
-                                (gotest-ui-section-node section))))
-         (setf (gotest-ui-thing-node test)
-               (ewoc-enter-after gotest-ui--ewoc insertion-node test)))
-        (when (null (cddr (gotest-ui-section-tests section)))
-          (push (gotest-ui-section-node section) invalidate-nodes))))
-    (unless (null invalidate-nodes)
-      (apply 'ewoc-invalidate gotest-ui--ewoc invalidate-nodes))
-    (gotest-ui-thing-node test)))
-
-;;;; Commands:
-
-(defun gotest-ui-toggle-expanded ()
-  "Toggle expandedness of a test/package node"
-  (interactive)
-  (let* ((node (ewoc-locate gotest-ui--ewoc (point)))
-         (data (ewoc-data node)))
-    (when (and data (gotest-ui-thing-p data))
-      (setf (gotest-ui-thing-expanded-p data)
-            (not (gotest-ui-thing-expanded-p data)))
-      (ewoc-invalidate gotest-ui--ewoc node))))
-
-(defun gotest-ui-rerun ()
-  (interactive)
-  (gotest-ui gotest-ui--cmdline :dir gotest-ui--dir))
-
-;;;; Displaying the data:
-
-(defvar-local gotest-ui--tests nil)
-(defvar-local gotest-ui--section-alist nil)
-(defvar-local gotest-ui--ewoc nil)
-(defvar-local gotest-ui--status nil)
-(defvar-local gotest-ui--process-buffer nil)
-(defvar-local gotest-ui--stderr-process-buffer nil)
-(defvar-local gotest-ui--ui-buffer nil)
-(defvar-local gotest-ui--process nil)
-(defvar-local gotest-ui--stderr-process nil)
-(defvar-local gotest-ui--cmdline nil)
-(defvar-local gotest-ui--dir nil)
-
-(cl-defun gotest-ui (cmdline &key dir)
-  (let* ((dir (or dir default-directory))
-         (name (format "*go test: %s in %s" (s-join " " cmdline) dir))
-         (buffer (get-buffer-create name)))
-    (unless (eql buffer (current-buffer))
-      (display-buffer buffer))
-    (with-current-buffer buffer
-      (let ((default-directory dir))
-        (gotest-ui--clear-buffer buffer)
-        (gotest-ui-mode)
-        (gotest-ui--setup-buffer buffer name cmdline dir))
-      (setq gotest-ui--stderr-process
-            (make-pipe-process :name (s-concat name "(stderr)")
-                               :buffer gotest-ui--stderr-process-buffer
-                               :sentinel #'gotest-ui--stderr-process-sentinel
-                               :filter #'gotest-ui-read-stderr))
-      (setq gotest-ui--process
-            (make-process :name name
-                          :buffer gotest-ui--process-buffer
-                          :sentinel #'gotest-ui--process-sentinel
-                          :filter #'gotest-ui-read-stdout
-                          :stderr gotest-ui--stderr-process
-                          :command cmdline)))))
-
-(defun gotest-ui-pp-status (status)
-  (propertize (format "%s" status)
-              'face
-              (case status
-                (fail 'gotest-ui-fail-face)
-                (skip 'gotest-ui-skip-face)
-                (pass 'gotest-ui-pass-face)
-                (otherwise 'default))))
-
-(defun gotest-ui--pp-test-output (test)
-  (with-current-buffer (gotest-ui-ensure-output-buffer test)
-    (propertize (buffer-substring (point-min) (point-max))
-                'line-prefix "\t")))
-
-(defun gotest-ui--pp-test (test)
-  (cond
-   ((gotest-ui-section-p test)
-    (unless (null (cdr (gotest-ui-section-tests test)))
-      (insert "\n" (gotest-ui-section-title test) "\n")))
-   ((gotest-ui-status-p test)
-    (insert (gotest-ui-pp-status (gotest-ui-status-state test)))
-    (insert (format " %s in %s\n\n"
-                    (gotest-ui-status-cmdline test)
-                    (gotest-ui-status-dir test)))
-    (unless (zerop (length (gotest-ui-status-output test)))
-      (insert (format "\n\n%s" (gotest-ui-status-output test)))))
-   ((gotest-ui-test-p test)
-    (let ((status (gotest-ui-thing-status test))
-          (package (gotest-ui-test-package test))
-          (name (gotest-ui-thing-name test)))
-      (insert (gotest-ui-pp-status status))
-      (insert " ")
-      (insert (if name
-                  (format "%s.%s" package name)
-                package))
-      (when-let ((elapsed (gotest-ui-thing-elapsed test)))
-        (insert (format " (%.3fs)" elapsed)))
-      (when-let ((reason (gotest-ui-test-reason test)))
-        (insert (format " [%s]" reason))))
-    (when (and (gotest-ui-thing-expanded-p test)
-               (> (length (gotest-ui--pp-test-output test)) 0))
-      (insert "\n")
-      (insert (gotest-ui--pp-test-output test)))
-    (insert "\n"))))
-
-;;;; Handling input:
-
-(defun gotest-ui--process-sentinel (proc event)
-  (let* ((process-buffer (process-buffer proc))
-         (ui-buffer (with-current-buffer process-buffer gotest-ui--ui-buffer))
-         (inhibit-quit t))
-    (with-local-quit
-      (with-current-buffer ui-buffer
-        (cond
-         ((string= event "finished\n")
-          (gotest-ui-update-status 'pass))
-         ((s-prefix-p "exited abnormally" event)
-          (gotest-ui-update-status 'fail))
-         (t
-          (gotest-ui-update-status event)))))))
-
-(defun gotest-ui--stderr-process-sentinel (proc event)
-  ;; ignore all events
-  nil)
-
-(defun gotest-ui-read-stderr (proc input)
-  (let* ((process-buffer (process-buffer proc))
-         (ui-buffer (with-current-buffer process-buffer gotest-ui--ui-buffer))
-         (inhibit-quit t))
-    (with-local-quit
-      (when (buffer-live-p process-buffer)
-        (with-current-buffer process-buffer
-          (gotest-ui-read-compiler-spew proc process-buffer ui-buffer input))))))
-
-(defun gotest-ui-read-stdout (proc input)
-  (let* ((process-buffer (process-buffer proc))
-         (ui-buffer (with-current-buffer process-buffer gotest-ui--ui-buffer))
-         (inhibit-quit t))
-    (with-local-quit
-      (when (buffer-live-p process-buffer)
-        (gotest-ui-read-json process-buffer (process-mark proc) input)))))
-
-(defun gotest-ui-read-json (process-buffer marker input)
-  (with-current-buffer process-buffer
-    (gotest-ui-read-json-1 process-buffer marker gotest-ui--ui-buffer input)))
-
-(defvar-local gotest-ui--current-failing-test nil)
-
-(defun gotest-ui-read-failing-package (ui-buffer)
-  (when (looking-at "^# \\(.*\\)$")
-    (let* ((package (match-string 1))
-           test)
-      (with-current-buffer ui-buffer
-        (setq test (gotest-ui-ensure-test gotest-ui--ewoc package nil :status 'fail))
-        (gotest-ui-maybe-expand test)
-        (gotest-ui-sort-test-into-section test nil))
-      (forward-line 1)
-      test)))
-
-(defun gotest-ui-read-compiler-spew (proc process-buffer ui-buffer input)
-  (with-current-buffer process-buffer
-    (save-excursion
-      (goto-char (point-max))
-      (insert input)
-      (goto-char (process-mark proc))
-      (while (and (/= (point-max) (line-end-position)) ; incomplete line
-                  (/= (point-max) (point)))
-        (cond
-         (gotest-ui--current-failing-test
-          (cond
-           ((looking-at "^# \\(.*\\)$")
-            (gotest-ui-read-failing-package ui-buffer))
-           (t
-            (let* ((line (buffer-substring (point) (line-end-position)))
-                   (test gotest-ui--current-failing-test))
-              (forward-line 1)
-              (set-marker (process-mark proc) (point))
-              (with-current-buffer ui-buffer
-                (gotest-ui-update-thing-output test (concat line "\n"))
-                (ewoc-invalidate gotest-ui--ewoc (gotest-ui-thing-node test)))))))
-         (t
-          (let ((test (gotest-ui-read-failing-package ui-buffer)))
-            (setq gotest-ui--current-failing-test test)
-            (set-marker (process-mark proc) (point))
-            (with-current-buffer ui-buffer
-              (ewoc-invalidate gotest-ui--ewoc (gotest-ui-thing-node test))))))))))
-
-(defun gotest-ui-read-json-1 (process-buffer marker ui-buffer input)
-  (with-current-buffer process-buffer
-    (save-excursion
-      ;; insert the chunk of output at the end
-      (goto-char (point-max))
-      (insert input)
-
-      ;; try to read the next object (which is hopefully complete now):
-      (let ((nodes
-             (cl-loop
-              for (node . continue) = (gotest-ui-read-test-event process-buffer marker ui-buffer)
-              when node collect node into nodes
-              while continue
-              finally (return nodes))))
-        (when nodes
-          (with-current-buffer ui-buffer
-            (apply #'ewoc-invalidate gotest-ui--ewoc
-                   (cl-remove-if-not (lambda (node) (marker-buffer (ewoc-location node))) (cl-remove-duplicates nodes)))))))))
-
-(defun gotest-ui-read-test-event (process-buffer marker ui-buffer)
-  (goto-char marker)
-  (when (= (point) (line-end-position))
-    (forward-line 1))
-  (case (char-after (point))
-    (?\{
-     ;; It's JSON:
-     (condition-case err
-         (let ((obj (json-read)))
-           (set-marker marker (point))
-           (with-current-buffer ui-buffer
-             (cons (gotest-ui-update-test-status obj) t)))
-       (json-error (cons nil nil))
-       (wrong-type-argument
-        (if (and (eql (cadr err) 'characterp)
-                 (eql (caddr err) :json-eof))
-            ;; This is peaceful & we can ignore it:
-            (cons nil nil)
-          (signal 'wrong-type-argument err)))))
-    (?\F
-     ;; It's a compiler error:
-     (when (looking-at "^FAIL\t\\(.*\\)\s+\\[\\([^]]+\\)\\]\n")
-       (let* ((package-name (match-string 1))
-              (reason (match-string 2))
-              test node)
-         (with-current-buffer ui-buffer
-           (setq test (gotest-ui-ensure-test gotest-ui--ewoc package-name nil :status 'fail)
-                 node (gotest-ui-thing-node test))
-           (setf (gotest-ui-test-reason test) reason)
-           (gotest-ui-sort-test-into-section test nil)
-           (gotest-ui-maybe-expand test))
-         (forward-line 1)
-         (set-marker marker (point))
-         (cons node t))))
-    (otherwise
-     ;; We're done:
-     (cons nil nil))))
-
-(defun gotest-ui-maybe-expand (test)
-  (when (memq (gotest-ui-test-status test) gotest-ui-expand-test-statuses)
-    (setf (gotest-ui-test-expanded-p test) t)))
-
-(defun gotest-ui-update-test-status (json)
-  (let-alist json
-    (let* ((action (intern .Action))
-           (test (gotest-ui-ensure-test gotest-ui--ewoc .Package .Test))
-           (previous-status (gotest-ui-thing-status test)))
-      (case action
-        (run
-         (gotest-ui-sort-test-into-section test nil))
-        (output (gotest-ui-update-thing-output test .Output))
-        (pass
-         (setf (gotest-ui-thing-status test) 'pass
-               (gotest-ui-thing-elapsed test) .Elapsed)
-         (gotest-ui-sort-test-into-section test previous-status)
-         (gotest-ui-maybe-expand test))
-        (fail
-         (setf (gotest-ui-thing-status test) 'fail
-               (gotest-ui-thing-elapsed test) .Elapsed)
-         (gotest-ui-sort-test-into-section test previous-status)
-         (gotest-ui-maybe-expand test))
-        (skip
-         (setf (gotest-ui-thing-status test) 'skip
-               (gotest-ui-thing-elapsed test) .Elapsed)
-         (gotest-ui-sort-test-into-section test previous-status)
-         (gotest-ui-maybe-expand test))
-        (otherwise
-         (setq test nil)))
-      (when test (gotest-ui-thing-node test)))))
-
-;;;; Commands for go-mode:
-
-(defun gotest-ui--command-line (&rest cmdline)
-  (append gotest-ui-test-binary gotest-ui-test-args gotest-ui-additional-test-args
-          cmdline))
-
-;;;###autoload
-(defun gotest-ui-current-test ()
-  "Launch go test with the test that (point) is in."
-  (interactive)
-  (cl-destructuring-bind (test-suite test-name) (go-test--get-current-test-info)
-    (let ((test-flag (if (> (length test-suite) 0) "-m" "-run")))
-      (when test-name
-        (gotest-ui (gotest-ui--command-line test-flag (s-concat test-name "$") "."))))))
-
-;;;###autoload
-(defun gotest-ui-current-file ()
-  "Launch go test on the current buffer file."
-  (interactive)
-  (let* ((data (go-test--get-current-file-testing-data))
-         (run-flag (s-concat "-run=" data "$")))
-    (gotest-ui (gotest-ui--command-line run-flag "."))))
-
-;;;###autoload
-(defun gotest-ui-current-project ()
-  "Launch go test on the current buffer's project."
-  (interactive)
-  (let ((default-directory (projectile-project-root)))
-    (gotest-ui (gotest-ui--command-line "./..."))))
-
-(provide 'gotest-ui)
-
-;;; gotest-ui.el ends here
tools/emacs/lisp/init-func.el
@@ -1,19 +0,0 @@
-;;; init-func.el --- -*- lexical-binding: t -*-
-;;
-
-;;;###autoload
-(defun vde/el-load-dir (dir)
-  "Load el files from the given folder `DIR'."
-  (let ((files (directory-files dir nil "\.el$")))
-    (while files
-      (load-file (concat dir (pop files))))))
-
-;;;###autoload
-(defun vde/short-hostname ()
-  "Return hostname in short (aka wakasu.local -> wakasu)."
-  (string-match "[0-9A-Za-z-]+" system-name)
-  (substring system-name (match-beginning 0) (match-end 0)))
-
-
-(provide 'init-func)
-;;; init-func.el ends here
tools/emacs/lisp/mcp-hub.el
@@ -1,313 +0,0 @@
-;;; mcp-hub.el --- manager mcp server                -*- lexical-binding: t; -*-
-
-;; Copyright (C) 2025  lizqwer scott
-
-;; Author: lizqwer scott <lizqwerscott@gmail.com>
-;; Keywords: ai, mcp
-
-;; This program is free software; you can redistribute it and/or modify
-;; it under the terms of the GNU General Public License as published by
-;; the Free Software Foundation, either version 3 of the License, or
-;; (at your option) any later version.
-
-;; This program is distributed in the hope that it will be useful,
-;; but WITHOUT ANY WARRANTY; without even the implied warranty of
-;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-;; GNU General Public License for more details.
-
-;; You should have received a copy of the GNU General Public License
-;; along with this program.  If not, see <https://www.gnu.org/licenses/>.
-
-;;; Commentary:
-
-;;
-
-;;; Code:
-
-(require 'mcp)
-
-(defcustom mcp-hub-servers nil
-  "Configuration for MCP servers.
-Each server configuration is a list of the form
- (NAME . (:command COMMAND :args ARGS)) or (NAME . (:url URL)), where:
-- NAME is a string identifying the server.
-- COMMAND is the command to start the server.
-- ARGS is a list of arguments passed to the command.
-- URL is a string arguments to connect sse mcp server."
-  :group 'mcp-hub
-  :type '(list (cons string (list symbol string))))
-
-(defun mcp-hub--start-server (server &optional inited-callback)
-  "Start an MCP server with the given configuration.
-SERVER should be a cons cell of the form (NAME . CONFIG) where:
-- NAME is a string identifying the server
-- CONFIG is a plist containing either:
-  - :command and :args for local servers
-  - :url for remote servers
-
-Optional argument INITED-CALLBACK is a function called when the server
-has successfully initialized and tools are available. The callback
-receives no arguments."
-  (apply #'mcp-connect-server
-         (append (list (car server))
-                 (cdr server)
-                 (list :initial-callback
-                       #'(lambda (_)
-                           (mcp-hub-update))
-                       :tools-callback
-                       #'(lambda (_ _)
-                           (mcp-hub-update)
-                           (when inited-callback
-                             (funcall inited-callback)))
-                       :prompts-callback
-                       #'(lambda (_ _)
-                           (mcp-hub-update))
-                       :resources-callback
-                       #'(lambda (_ _)
-                           (mcp-hub-update))
-                       :error-callback
-                       #'(lambda (_ _)
-                           (mcp-hub-update))))))
-
-;;;###autoload
-(cl-defun mcp-hub-get-all-tool (&key asyncp categoryp)
-  "Retrieve all available tools from connected MCP servers.
-This function collects all tools from currently connected MCP servers,
-filtering out any invalid entries. Each tool is created as a text tool
-that can be used for interaction.
-
-When ASYNCP is non-nil, the tools will be created asynchronously.
-
-When CATEGORYP is non-nil, the tools will be add to a category.
-
-Returns a list of text tools created from all valid tools across all
-connected servers. The list excludes any tools that couldn't be created
-due to missing or invalid names.
-
-Example:
-  (mcp-hub-get-all-tool)  ; Get all tools synchronously
-  (mcp-hub-get-all-tool t)  ; Get all tools asynchronously"
-  (let ((res ))
-    (maphash #'(lambda (name server)
-                 (when (and server
-                          (equal (mcp--status server)
-                                 'connected))
-                   (when-let* ((tools (mcp--tools server))
-                               (tool-names (mapcar #'(lambda (tool) (plist-get tool :name)) tools)))
-                     (dolist (tool-name tool-names)
-                       (push (let ((tool (mcp-make-text-tool name tool-name asyncp)))
-                               (if categoryp
-                                   (plist-put
-                                    tool
-                                    :category
-                                    (format "mcp-%s"
-                                            name))
-                                 tool))
-                             res)))))
-             mcp-server-connections)
-    (nreverse res)))
-
-;;;###autoload
-(defun mcp-hub-start-all-server (&optional callback servers)
-  "Start all configured MCP servers.
-This function will attempt to start each server listed in `mcp-hub-servers'
-if it's not already running.
-
-Optional argument CALLBACK is a function to be called when all servers have
-either started successfully or failed to start.The callback receives no
-arguments.
-
-Optional argument SERVERS is a list of server names (strings) to filter which
-servers should be started. When nil, all configured servers are considered."
-  (interactive)
-  (let* ((servers-to-start (cl-remove-if (lambda (server)
-                                           (or (not (cl-find (car server) servers :test #'string=))
-                                               (gethash (car server) mcp-server-connections)))
-                                         mcp-hub-servers))
-         (total (length servers-to-start))
-         (started 0))
-    (if (zerop total)
-        (progn
-          (message "All MCP servers already running")
-          (when callback (funcall callback)))
-      (message "Starting %d MCP server(s)..." total)
-      (dolist (server servers-to-start)
-        (condition-case err
-            (mcp-hub--start-server
-             server
-             (lambda ()
-               (cl-incf started)
-               (message "Started server %s (%d/%d)" (car server) started total)
-               (when (and callback (>= started total))
-                 (funcall callback))))
-          (error
-           (message "Failed to start server %s: %s" (car server) err)
-           (cl-incf started)
-           (when (and callback (>= started total))
-             (funcall callback))))))))
-
-;;;###autoload
-(defun mcp-hub-close-all-server ()
-  "Stop all running MCP servers.
-This function will attempt to stop each server listed in `mcp-hub-servers'
-that is currently running."
-  (interactive)
-  (dolist (server mcp-hub-servers)
-    (when (gethash (car server)
-                   mcp-server-connections)
-      (mcp-stop-server (car server))))
-  (mcp-hub-update))
-
-;;;###autoload
-(defun mcp-hub-restart-all-server ()
-  "Restart all configured MCP servers.
-This function first stops all running servers, then starts them again.
-It's useful for applying configuration changes or recovering from errors."
-  (interactive)
-  (mcp-hub-close-all-server)
-  (mcp-hub-start-all-server))
-
-(defun mcp-hub-get-servers ()
-  "Retrieve status information for all configured servers.
-Returns a list of server statuses, where each status is a plist containing:
-- :name - The server's name
-- :status - Either `connected' or `stop'
-- :tools - Available tools (if connected)
-- :resources - Available resources (if connected)
-- :prompts - Available prompts (if connected)"
-  (mapcar #'(lambda (server)
-              (let ((name (car server)))
-                (if-let* ((connection (gethash name mcp-server-connections)))
-                    (list :name name
-                          :type (mcp--connection-type connection)
-                          :status (mcp--status connection)
-                          :tools (mcp--tools connection)
-                          :resources (mcp--resources connection)
-                          :prompts (mcp--prompts connection))
-                  (list :name name :status 'stop))))
-          mcp-hub-servers))
-
-(defun mcp-hub-update ()
-  "Update the MCP Hub display with current server status.
-If called interactively, ARG is the prefix argument.
-When SILENT is non-nil, suppress any status messages.
-This function refreshes the *Mcp-Hub* buffer with the latest server information,
-including connection status, available tools, resources, and prompts."
-  (interactive "P")
-  (when-let* ((server-list (mcp-hub-get-servers))
-              (server-show (mapcar #'(lambda (server)
-                                       (let* ((name (plist-get server :name))
-                                              (status (plist-get server :status)))
-                                         (append (list name
-                                                       (symbol-name (plist-get server :type))
-                                                       (pcase status
-                                                         ('connected
-                                                          (propertize (symbol-name status)
-                                                                      'face 'success))
-                                                         ('error
-                                                          (propertize (symbol-name status)
-                                                                      'face 'error))
-                                                         (_
-                                                          (symbol-name status))))
-                                                 (if (equal status 'connected)
-                                                     (mapcar #'(lambda (x)
-                                                                 (format "%d"
-                                                                         (length x)))
-                                                             (list (plist-get server :tools)
-                                                                   (plist-get server :resources)
-                                                                   (plist-get server :prompts)))
-                                                   (list "nil" "nil" "nil")))))
-                                   server-list)))
-    (with-current-buffer (get-buffer-create "*Mcp-Hub*")
-      (setq tabulated-list-entries
-            (cl-mapcar #'(lambda (statu index)
-                           (list (format "%d" index)
-                                 (vconcat statu)))
-                       server-show
-                       (number-sequence 1 (length server-list))))
-      (tabulated-list-print t))))
-
-;;;###autoload
-(defun mcp-hub ()
-  "View mcp hub server."
-  (interactive)
-  ;; start all server
-  (when (and mcp-hub-servers
-           (= (hash-table-count mcp-server-connections)
-              0))
-    (mcp-hub-start-all-server))
-  ;; show buffer
-  (pop-to-buffer "*Mcp-Hub*" nil)
-  (mcp-hub-mode))
-
-;;;###autoload
-(defun mcp-hub-start-server ()
-  "Start the currently selected MCP server.
-This function starts the server that is currently highlighted in the *Mcp-Hub*
-buffer. It sets up callbacks for connection status, tools, prompts, and
-resources updates, and refreshes the hub view after starting the server."
-  (interactive)
-  (when-let* ((server (tabulated-list-get-entry))
-              (name (elt server 0))
-              (server-arg (cl-find name mcp-hub-servers :key #'car :test #'equal)))
-    (mcp-hub--start-server server-arg)
-    (mcp-hub-update)))
-
-;;;###autoload
-(defun mcp-hub-close-server ()
-  "Stop the currently selected MCP server.
-This function stops the server that is currently highlighted in the *Mcp-Hub*
-buffer and updates the hub view to reflect the change in status."
-  (interactive)
-  (when-let* ((server (tabulated-list-get-entry))
-              (name (elt server 0)))
-    (mcp-stop-server name)
-    (mcp-hub-update)))
-
-;;;###autoload
-(defun mcp-hub-restart-server ()
-  "Restart the currently selected MCP server.
-This function stops and then starts the server that is currently highlighted
-in the *Mcp-Hub* buffer. It's useful for applying configuration changes or
-recovering from errors."
-  (interactive)
-  (mcp-hub-close-server)
-  (mcp-hub-start-server))
-
-;;;###autoload
-(defun mcp-hub-view-log ()
-  "View the event log for the currently selected MCP server.
-This function opens a buffer showing the event log for the server that is
-currently highlighted in the *Mcp-Hub* buffer."
-  (interactive)
-  (when-let* ((server (tabulated-list-get-entry))
-              (name (elt server 0)))
-    (switch-to-buffer (format "*%s events*"
-                              name))))
-
-(define-derived-mode mcp-hub-mode tabulated-list-mode "Mcp Hub"
-  "A major mode for viewing a list of mcp server."
-  (setq-local revert-buffer-function #'mcp-hub-update)
-  (setq tabulated-list-format
-        [("Name" 18 t)
-         ("Type" 10 t)
-         ("Status" 15 t)
-         ("Tools" 10 t)
-         ("Resources" 10 t)
-         ("Prompts" 10 t)])
-  (setq tabulated-list-padding 2)
-  (setq tabulated-list-sort-key '("Name" . nil))
-  (tabulated-list-init-header)
-
-  (keymap-set mcp-hub-mode-map "l" #'mcp-hub-view-log)
-  (keymap-set mcp-hub-mode-map "s" #'mcp-hub-start-server)
-  (keymap-set mcp-hub-mode-map "k" #'mcp-hub-close-server)
-  (keymap-set mcp-hub-mode-map "r" #'mcp-hub-restart-server)
-  (keymap-set mcp-hub-mode-map "S" #'mcp-hub-start-all-server)
-  (keymap-set mcp-hub-mode-map "R" #'mcp-hub-restart-all-server)
-  (keymap-set mcp-hub-mode-map "K" #'mcp-hub-close-all-server)
-
-  (mcp-hub-update))
-
-(provide 'mcp-hub)
-;;; mcp-hub.el ends here
tools/emacs/lisp/mcp.el
@@ -1,973 +0,0 @@
-;;; mcp.el --- Model Context Protocol                -*- lexical-binding: t; -*-
-
-;; Copyright (C) 2025  lizqwer scott
-
-;; Author: lizqwer scott <lizqwerscott@gmail.com>
-;; Version: 0.1.0
-;; Package-Requires: ((emacs "30.1") (jsonrpc "1.0.25"))
-;; Keywords: ai, mcp
-;; URL: https://github.com/lizqwerscott/mcp.el
-
-;; This program is free software; you can redistribute it and/or modify
-;; it under the terms of the GNU General Public License as published by
-;; the Free Software Foundation, either version 3 of the License, or
-;; (at your option) any later version.
-
-;; This program is distributed in the hope that it will be useful,
-;; but WITHOUT ANY WARRANTY; without even the implied warranty of
-;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-;; GNU General Public License for more details.
-
-;; You should have received a copy of the GNU General Public License
-;; along with this program.  If not, see <https://www.gnu.org/licenses/>.
-
-;;; Commentary:
-
-;;
-
-;;; Code:
-
-(require 'jsonrpc)
-(require 'cl-lib)
-(require 'url)
-
-(defconst *MCP-VERSION* "2024-11-05"
-  "MCP support version.")
-
-(defcustom mcp-server-start-time 60
-  "The Seconds of mcp server start time."
-  :group 'mcp
-  :type 'integer)
-
-(defcustom mcp-server-wait-initial-time 2
-  "Seconds to wait after server init before fetching MCP resources.
-
-This delay is applied after server initialization completes, but
-before requesting tools, prompts and resources. Gives the server
-time to fully initialize all components before handling requests."
-  :group 'mcp
-  :type 'integer)
-
-(defcustom mcp-log-level 'info
-  "The min log level for mcp server.
-Available levels:
-- debug: Detailed debugging information (function entry/exit points)
-- info: General informational messages (operation progress updates)
-- notice: Normal but significant events (configuration changes)
-- warning: Warning conditions (deprecated feature usage)
-- error: Error conditions (operation failures)
-- critical: Critical conditions (system component failures)
-- alert: Action must be taken immediately (data corruption detected)
-- emergency: System is unusable (complete system failure)"
-  :group 'mcp
-  :type '(choice (const :tag "debug" debug)
-          (const :tag "info" info)
-          (const :tag "notice" notice)
-          (const :tag "warning" warning)
-          (const :tag "error" error)
-          (const :tag "critical" critical)
-          (const :tag "alert" alert)
-          (const :tag "emergency" emergency)))
-
-(defclass mcp-process-connection (jsonrpc-process-connection)
-  ((connection-type
-    :initarg :connection-type
-    :accessor mcp--connection-type)
-   (-status
-    :initform 'init
-    :accessor mcp--status)
-   (-capabilities
-    :initform nil
-    :accessor mcp--capabilities)
-   (-serverinfo
-    :initform nil
-    :accessor mcp--server-info)
-   (-prompts
-    :initform nil
-    :accessor mcp--prompts)
-   (-tools
-    :initform nil
-    :accessor mcp--tools)
-   (-resources
-    :initform nil
-    :accessor mcp--resources))
-  :documentation "A MCP connection over an Emacs process.")
-
-(defclass mcp-sse-process-connection (mcp-process-connection)
-  ((-host
-    :initarg :host
-    :accessor mcp--host)
-   (-port
-    :initarg :port
-    :accessor mcp--port)
-   (-tls
-    :initarg :tls
-    :accessor mcp--tls)
-   (-endpoint
-    :initform nil
-    :accessor mcp--endpoint))
-  :documentation "A sse MCP connection over an Emacs process.")
-
-(defclass mcp-stdio-process-connection (mcp-process-connection)
-  ()
-  :documentation "A stdio MCP connection over an Emacs process.")
-
-(cl-defmethod initialize-instance :after ((_ mcp-process-connection) slots)
-  "Init mcp process connection."
-  (cl-destructuring-bind (&key ((:process proc)) &allow-other-keys) slots
-    (set-process-filter proc #'mcp--process-filter)))
-
-(cl-defmethod jsonrpc-connection-send ((connection mcp-process-connection)
-                                       &rest args
-                                       &key
-                                       id
-                                       method
-                                       _params
-                                       (_result nil result-supplied-p)
-                                       error
-                                       _partial)
-  "Send JSON-RPC message to CONNECTION.
-CONNECTION is an MCP process connection instance. ARGS is a plist
-containing the message components:
-
-METHOD - Method name (string, symbol or keyword)
-PARAMS - Parameters for the method (optional)
-ID     - Request ID (optional)
-RESULT - Response result (for replies)
-error   - Error object (for error replies)
-partial - Partial response flag (optional)
-
-For requests, both :method and :id should be provided.
-For notifications, only :method is required.
-For replies, either :_result or :error should be provided.
-
-The message is sent differently based on connection type:
-- SSE connections use HTTP POST requests
-- Stdio connections write directly to the process"
-  (when method
-    ;; sanitize method into a string
-    (setq args
-          (plist-put args :method
-                     (cond ((keywordp method) (substring (symbol-name method) 1))
-                           ((symbolp method) (symbol-name method))
-                           ((stringp method) method)
-                           (t (error "[jsonrpc] invalid method %s" method))))))
-  (let* ((kind (cond ((or result-supplied-p error) 'reply)
-                     (id 'request)
-                     (method 'notification)))
-         (converted (jsonrpc-convert-to-endpoint connection args kind))
-         (json (jsonrpc--json-encode converted)))
-    (pcase (mcp--connection-type connection)
-      ('sse
-       (let ((url-request-method "POST")
-             (url-request-extra-headers
-              '(("Content-Type" . "application/json")))
-             (url-request-data (encode-coding-string
-                                json
-                                'utf-8))
-             (url (format "%s://%s:%s%s"
-                          (if (mcp--tls connection) "https" "http")
-                          (mcp--host connection)
-                          (mcp--port connection)
-                          (mcp--endpoint connection))))
-         (url-retrieve url
-                       #'(lambda (_)
-                           (when (buffer-live-p (current-buffer))
-                             (goto-char (point-min))
-                             ;; (when (search-forward "\n\n" nil t)
-                             ;;   (let* ((headers (buffer-substring (point-min) (point)))
-                             ;;          (body (buffer-substring (point) (point-max)))
-                             ;;          (response-code (string-match "HTTP/.* \\([0-9]+\\)" headers)))))
-                             (kill-buffer))))))
-      ('stdio
-       (process-send-string
-        (jsonrpc--process connection)
-        (format "%s\r\n" json))))
-    (jsonrpc--event
-     connection
-     'client
-     :json json
-     :kind  kind
-     :message args
-     :foreign-message converted)))
-
-(defvar mcp--in-process-filter nil
-  "Non-nil if inside `mcp--process-filter'.")
-
-(cl-defun mcp--process-filter (proc string)
-  "Called when new data STRING has arrived for PROC."
-  (when mcp--in-process-filter
-    ;; Problematic recursive process filters may happen if
-    ;; `jsonrpc-connection-receive', called by us, eventually calls
-    ;; client code which calls `process-send-string' (which see) to,
-    ;; say send a follow-up message.  If that happens to writes enough
-    ;; bytes for pending output to be received, we will lose JSONRPC
-    ;; messages.  In that case, remove recursiveness by re-scheduling
-    ;; ourselves to run from within a timer as soon as possible
-    ;; (bug#60088)
-    (run-at-time 0 nil #'mcp--process-filter proc string)
-    (cl-return-from mcp--process-filter))
-  (when (buffer-live-p (process-buffer proc))
-    (with-current-buffer (process-buffer proc)
-      (let* ((conn (process-get proc 'jsonrpc-connection))
-             (queue (or (process-get proc 'jsonrpc-mqueue) nil))
-             (buf (or (process-get proc 'jsonrpc-pending)
-                      (plist-get (process-put
-                                  proc 'jsonrpc-pending
-                                  (generate-new-buffer " *mcp-jsonrpc-pending*"))
-                                 'jsonrpc-pending)))
-             (data (with-current-buffer buf
-                     (goto-char (point-max))
-                     (insert string)
-                     (buffer-string)))
-             (type (mcp--connection-type conn))
-             (parsed-messages nil)
-             (lines (split-string data "\n"))
-             (parsed-index 0)
-             (endpoint-waitp nil)
-             (line-index 0))
-        (dolist (line lines)
-          (pcase type
-            ('sse
-             (cond
-              ((and (<= (+ line-index 1) (length lines))
-                    (string-prefix-p "event:" (elt lines (+ line-index 1)))))
-              ((string-prefix-p "event: endpoint" line)
-               (setq endpoint-waitp t))
-              ((string-prefix-p "data: " line)
-               (let ((json-str (if (and endpoint-waitp
-                                        (string-match "http://[^/]+\\(/[^[:space:]]+\\)" line))
-                                   (match-string 1 line)
-                                 (string-trim (substring line 6)))))
-                 (unless (string-empty-p json-str)
-                   (if endpoint-waitp
-                       (setf (mcp--endpoint conn) json-str)
-                     (push (cons parsed-index json-str) parsed-messages)
-                     (cl-incf parsed-index)))))
-              ((and (mcp--endpoint conn)
-                    (not (or (string-prefix-p "2d" line)
-                             (string-prefix-p ": ping" line)
-                             (string-prefix-p "event: message" line)))
-                    (not (with-current-buffer buf (= (point-min) (point-max)))))
-               (let ((json-str (string-trim line)))
-                 (unless (string-empty-p json-str)
-                   (push (cons parsed-index json-str) parsed-messages)
-                   (cl-incf parsed-index))))))
-            ('stdio
-             (let ((json-str (string-trim line)))
-               (unless (string-empty-p json-str)
-                 (push (cons parsed-index json-str) parsed-messages)
-                 (cl-incf parsed-index)))))
-          (cl-incf line-index))
-        (setq parsed-messages (nreverse parsed-messages))
-
-        (with-current-buffer buf (erase-buffer))
-        ;; Add messages to MQUEUE
-        (dolist (msg parsed-messages)
-          (pcase-let ((`(,_index . ,json-str) msg))
-            (let ((json nil)
-                  (json-str (with-current-buffer buf
-                              (if (= (point-min) (point-max))
-                                  json-str
-                                (goto-char (point-max))
-                                (insert json-str)
-                                (buffer-string)))))
-              (condition-case-unless-debug err
-                  (setq json (json-parse-string json-str
-                                                :object-type 'plist
-                                                :null-object nil
-                                                :false-object :json-false))
-                (json-parse-error
-                 ;; parse error and not because of incomplete json
-                 (jsonrpc--warn "Invalid JSON: %s\t %s" (cdr err) json-str))
-                (json-end-of-file
-                 ;; Save remaining data to pending for next processing
-                 (with-current-buffer buf
-                   (goto-char (point-max))
-                   (insert json-str)
-                   (process-put proc 'jsonrpc-pending buf))))
-              (when json
-                (with-current-buffer buf (erase-buffer))
-                (when (listp json)
-                  (setq json (plist-put json :jsonrpc-json json-str))
-                  (push json queue))))))
-
-        ;; Save updated queue
-        (process-put proc 'jsonrpc-mqueue queue)
-
-        ;; Dispatch messages in timer
-        (cl-loop with time = (current-time)
-                 for msg = (pop queue) while msg
-                 do (let ((timer (timer-create)))
-                      (timer-set-time timer time)
-                      (timer-set-function timer
-                                          (lambda (conn msg)
-                                            (with-temp-buffer
-                                              (jsonrpc-connection-receive conn msg)))
-                                          (list conn msg))
-                      (timer-activate timer)))
-
-        ;; Save final queue (might have been consumed by timer pop)
-        (process-put proc 'jsonrpc-mqueue queue)))))
-
-(defun mcp--sse-connect (process host port path)
-  "Establish SSE connection to server.
-PROCESS is the network process object. HOST and PORT specify the
-server address. PATH is the endpoint path for SSE connection.
-Sends HTTP GET request with SSE headers to initiate the event
-stream connection. Used internally by MCP for SSE-based JSON-RPC
-communication."
-  (process-send-string process
-                       (concat
-                        (format "GET %s HTTP/1.1\r\n"
-                                path)
-                        (format "Host: %s:%s\r\n"
-                                host
-                                port)
-                        "Accept: text/event-stream\r\n"
-                        "Cache-Control: no-cache\r\n"
-                        "Connection: keep-alive\r\n\r\n")))
-
-(cl-defun mcp-notify (connection method &optional (params nil))
-  "Send notification to CONNECTION without expecting response.
-METHOD is the notification name (string or symbol). PARAMS is an
-optional plist of parameters.
-This is a thin wrapper around =jsonrpc-connection-send' that
-omits the :id parameter to indicate it's a notification rather
-than a request."
-  (apply #'jsonrpc-connection-send
-         `(,connection
-           :method ,method
-           ,@(when params
-               (list :params params)))))
-
-(defvar mcp-server-connections (make-hash-table :test #'equal)
-  "Mcp server process.")
-
-(defun mcp-request-dispatcher (name method params)
-  "Default handler for MCP server requests.
-NAME identifies the server connection. METHOD is the requested
-method name. PARAMS contains the method parameters.
-
-This basic implementation just logs the request. Applications
-should override this to implement actual request handling."
-  (message "%s Received request: method=%s, params=%s" name method params))
-
-(defun mcp-notification-dispatcher (connection name method params)
-  "Handle notifications from MCP server.
-CONNECTION is the JSON-RPC connection object. NAME identifies the
-server. METHOD is the notification name. PARAMS contains the
-notification data."
-  (pcase method
-    ('notifications/message
-     (cond ((or (plist-member (mcp--capabilities connection) :logging)
-                (and (plist-member params :level)
-                     (plist-member params :data)))
-            (cl-destructuring-bind (&key level data &allow-other-keys) params
-              (let ((logger (plist-get params :logger)))
-                (message "[mcp][%s][%s]%s: %s"
-                         name
-                         level
-                         (if logger
-                             (format "[%s]" logger)
-                           "")
-                         data))))))
-    (_
-     (message "%s Received notification: method=%s, params=%s" name method params))))
-
-(defun mcp-on-shutdown (name)
-  "When NAME mcp server shutdown."
-  (message "%s connection shutdown" name))
-
-(defun mcp--parse-http-url (url)
-  "Parse HTTP/HTTPS URL into connection components.
-URL should be a string in format http(s)://host[:port][/path].
-
-Returns a plist with connection parameters:
-:tls   - Boolean indicating HTTPS (t) or HTTP (nil)
-:host  - Server hostname (string)
-:port  - Port number (integer, defaults to 80/443)
-:path  - URL path component (string)
-
-Returns nil if URL is invalid or not HTTP/HTTPS."
-  (when-let* ((url (url-generic-parse-url url))
-              (type (url-type url))
-              (host (url-host url))
-              (filename (url-filename url)))
-    (when (or (string= type "http")
-              (string= type "https"))
-      (let ((port (url-port url))
-            (tls (string= "https" type)))
-        (list :tls tls
-              :host host
-              :port (if port
-                        port
-                      (if tls
-                          443
-                        80))
-              :path filename)))))
-
-;;;###autoload
-(cl-defun mcp-connect-server (name &key command args url env initial-callback
-                                   tools-callback prompts-callback
-                                   resources-callback error-callback)
-  "Connect to an MCP server with NAME, COMMAND, and ARGS or URL.
-
-NAME is a string representing the name of the server.
-COMMAND is a string representing the command to start the server
-in stdio mcp server.
-ARGS is a list of arguments to pass to the COMMAND.
-URL is a string arguments to connect sse mcp server.
-ENV is a plist argument to set mcp server env.
-
-INITIAL-CALLBACK is a function called when the server completes
-the connection.
-TOOLS-CALLBACK is a function called to handle the list of tools
-provided by the server.
-PROMPTS-CALLBACK is a function called to handle the list of prompts
-provided by the server.
-RESOURCES-CALLBACK is a function called to handle the list of
-resources provided by the server.
-ERROR-CALLBACK is a function to call on error.
-
-This function creates a new process for the server, initializes a connection,
-and sends an initialization message to the server. The connection is stored
-in the `mcp-server-connections` hash table for future reference."
-  (unless (gethash name mcp-server-connections)
-    (when-let* ((server-config (cond (command
-                                      (list :connection-type 'stdio
-                                            :command command
-                                            :args args))
-                                     (url
-                                      (when-let* ((res (mcp--parse-http-url url)))
-                                        (plist-put res
-                                                   :connection-type 'sse)))))
-                (connection-type (plist-get server-config :connection-type))
-                (buffer-name (format "*Mcp %s server*" name))
-                (process-name (format "mcp-%s-server" name))
-                (process (pcase connection-type
-                           ('sse
-                            (get-buffer-create buffer-name)
-                            (open-network-stream process-name
-                                                 buffer-name
-                                                 (plist-get server-config :host)
-                                                 (plist-get server-config :port)
-                                                 :type (if (plist-get server-config :tls)
-                                                           'tls
-                                                         'network)))
-                           ('stdio
-                            (let ((env (mapcar #'(lambda (item)
-                                                   (pcase-let* ((`(,key ,value) item))
-                                                     (let ((key (symbol-name key)))
-                                                       (list (substring key 1)
-                                                             (format "%s" value)))))
-                                               (seq-partition env 2)))
-                                  (process-environment (copy-sequence process-environment)))
-                              (when env
-                                (dolist (elem env)
-                                  (setenv (car elem) (cadr elem))))
-                              (make-process
-                               :name name
-                               :command (append (list command)
-                                                (plist-get server-config :args))
-                               :connection-type 'pipe
-                               :coding 'utf-8-emacs-unix
-                               ;; :noquery t
-                               :stderr (get-buffer-create
-                                        (format "*%s stderr*" name))
-                               ;; :file-handler t
-                               ))))))
-      (when (equal connection-type 'sse)
-        (mcp--sse-connect process
-                          (plist-get server-config :host)
-                          (plist-get server-config :port)
-                          (plist-get server-config :path)))
-      (let ((connection (apply #'make-instance
-                               `(,(pcase connection-type
-                                    ('sse
-                                     'mcp-sse-process-connection)
-                                    ('stdio
-                                     'mcp-stdio-process-connection))
-                                 :connection-type ,connection-type
-                                 :name ,name
-                                 :process ,process
-                                 :request-dispatcher ,(lambda (_ method params)
-                                                        (funcall #'mcp-request-dispatcher name method params))
-                                 :notification-dispatcher ,(lambda (connection method params)
-                                                             (funcall #'mcp-notification-dispatcher connection name method params))
-                                 :on-shutdown ,(lambda (_)
-                                                 (funcall #'mcp-on-shutdown name))
-                                 ,@(when (equal connection-type 'sse)
-                                     (list :host (plist-get server-config :host)
-                                           :port (plist-get server-config :port)
-                                           :tls (plist-get server-config :tls))))))
-            (initial-use-time 0)
-            (initial-timer nil))
-        ;; Initialize connection
-        (puthash name connection mcp-server-connections)
-        (when (equal connection-type 'sse)
-          (setf (mcp--status connection)
-                'waitendpoint))
-        ;; Send the Initialize message
-        (setf initial-timer
-              (run-with-idle-timer
-               1
-               t
-               #'(lambda ()
-                   (cl-incf initial-use-time)
-                   (if (jsonrpc-running-p connection)
-                       (when (or (equal connection-type 'stdio)
-                                 (and (equal connection-type 'sse)
-                                      (mcp--endpoint connection)))
-                         (cancel-timer initial-timer)
-                         (mcp-async-initialize-message
-                          connection
-                          #'(lambda (protocolVersion serverInfo capabilities)
-                              (if (string= protocolVersion *MCP-VERSION*)
-                                  (progn
-                                    (message "[mcp] Connected! Server `MCP (%s)' now managing." (jsonrpc-name connection))
-                                    (setf (mcp--capabilities connection) capabilities
-                                          (mcp--server-info connection) serverInfo)
-                                    ;; Notify server initialized
-                                    (mcp-notify connection
-                                                :notifications/initialized)
-                                    ;; handle logging
-                                    (when (plist-member capabilities :logging)
-                                      (mcp-async-set-log-level connection mcp-log-level))
-                                    (when initial-callback
-                                      (funcall initial-callback connection))
-                                    (run-with-idle-timer mcp-server-wait-initial-time
-                                                         nil
-                                                         #'(lambda ()
-                                                             ;; Get prompts
-                                                             (when (plist-member capabilities :prompts)
-                                                               (mcp-async-list-prompts connection prompts-callback))
-                                                             ;; Get tools
-                                                             (when (plist-member capabilities :tools)
-                                                               (mcp-async-list-tools connection tools-callback))
-                                                             ;; Get resources
-                                                             (when (plist-member capabilities :resources)
-                                                               (mcp-async-list-resources connection resources-callback)))
-                                                         )
-                                    (setf (mcp--status connection)
-                                          'connected))
-                                (progn
-                                  (message "[mcp] Error %s server protocolVersion(%s) not support, client Version: %s."
-                                           (jsonrpc-name connection)
-                                           protocolVersion
-                                           *MCP-VERSION*)
-                                  (mcp-stop-server (jsonrpc-name connection)))))
-                          #'(lambda (code message)
-                              (when error-callback
-                                (funcall error-callback code message))
-                              (setf (mcp--status connection)
-                                    'error)
-                              (message "Sadly, mpc server reports %s: %s"
-                                       code message)))
-                         (when (> initial-use-time mcp-server-start-time)
-                           (mcp-stop-server name)
-                           (cancel-timer initial-timer)
-                           (message "Sadly: mcp server start error timeout")))
-                     (cancel-timer initial-timer)
-                     (when error-callback
-                       (funcall error-callback -1 "mcp server process start error")
-                       (setf (mcp--status connection)
-                             'error)
-                       (message "Sadly, %s mcp server process start error" name))))))))))
-
-;;;###autoload
-(defun mcp-stop-server (name)
-  "Stop the MCP server with the given NAME.
-If the server is running, it will be shutdown and its connection will be removed
-from `mcp-server-connections'. If no server with the given NAME is found,
-a message will be displayed indicating that the server is not running."
-  (if-let* ((connection (gethash name mcp-server-connections)))
-      (progn
-        (jsonrpc-shutdown connection)
-        (setf (gethash name mcp-server-connections) nil))
-    (message "mcp %s server not started" name)))
-
-(defun mcp--parse-tool-args (properties required)
-  "Parse tool arguments from PROPERTIES and REQUIRED lists.
-
-PROPERTIES is a plist of tool argument properties.
-REQUIRED is a list of required argument names.
-
-The function processes each argument in PROPERTIES, marking optional arguments
-if they are not in REQUIRED. Each argument is parsed into a structured plist
-with :name, :type, and :optional fields.
-
-Returns a list of parsed argument plists."
-  (let ((need-length (- (/ (length properties) 2)
-                        (length required))))
-    (cl-mapcar #'(lambda (arg-value required-name)
-                   (pcase-let* ((`(,key ,value) arg-value))
-                     `( :name ,(substring (symbol-name key) 1)
-                        ,@value
-                        ,@(unless required-name
-                            `(:optional t)))))
-               (seq-partition properties 2)
-               (append required
-                       (when (> need-length 0)
-                         (make-list need-length nil))))))
-
-
-(defun mcp--parse-tool-call-result (res)
-  "Parse the result of a tool call from RES.
-
-RES is a plist representing the tool call result.
-
-The function extracts text content from the result, concatenating it into
-a single string if multiple text entries are present.
-
-Returns the concatenated text or nil if no text content is found."
-  (string-join
-   (cl-remove-if #'null
-                 (mapcar #'(lambda (content)
-                             (when (string= "text" (plist-get content :type))
-                               (plist-get content :text)))
-                         (plist-get res :content)))
-   "\n"))
-
-(defun mcp--generate-tool-call-args (args properties)
-  "Generate tool call arguments from ARGS and PROPERTIES.
-
-ARGS is a list of argument values provided by the caller.
-PROPERTIES is a plist of tool argument properties.
-
-The function matches ARGS to PROPERTIES, filling in default values for missing
-optional arguments. It ensures the generated arguments match the tool's schema.
-
-Returns a plist of argument names and values ready for tool invocation."
-  (let ((need-length (- (/ (length properties) 2)
-                        (length args))))
-    (apply #'append
-           (cl-mapcar #'(lambda (arg value)
-                          (when-let* ((value (if value
-                                                 value
-                                               (plist-get (cl-second arg)
-                                                          :default))))
-                            (list (cl-first arg)
-                                  value)))
-                      (seq-partition properties 2)
-                      (append args
-                              (when (> need-length 0)
-                                (make-list need-length nil)))))))
-
-;;;###autoload
-(defun mcp-make-text-tool (name tool-name &optional asyncp)
-  "Create a `gptel' tool with the given NAME, TOOL-NAME, and ASYNCP.
-
-NAME is the name of the server connection.
-TOOL-NAME is the name of the tool to be created.
-
-Currently, only synchronous messages are supported.
-
-This function retrieves the tool definition from the server connection,
-constructs a basic tool with the appropriate properties, and returns it.
-The tool is configured to handle input arguments, call the server, and process
-the response to extract and return text content."
-  (when-let* ((connection (gethash name mcp-server-connections))
-              (tools (mcp--tools connection))
-              (tool (cl-find tool-name tools :test #'equal :key #'(lambda (tool) (plist-get tool :name)))))
-    (cl-destructuring-bind (&key description ((:inputSchema input-schema)) &allow-other-keys) tool
-      (cl-destructuring-bind (&key properties required &allow-other-keys) input-schema
-        (list
-         :function (if asyncp
-                       #'(lambda (callback &rest args)
-                           (when (< (length args) (length required))
-                             (error "Error: args not match: %s -> %s" required args))
-                           (if-let* ((connection (gethash name mcp-server-connections)))
-                               (mcp-async-call-tool connection
-                                                    tool-name
-                                                    (mcp--generate-tool-call-args args properties)
-                                                    #'(lambda (res)
-                                                        (funcall callback
-                                                                 (mcp--parse-tool-call-result res)))
-                                                    #'(lambda (code message)
-                                                        (funcall callback
-                                                                 (format "call %s tool error with %s: %s"
-                                                                         tool-name
-                                                                         code
-                                                                         message))))
-                             (error "Error: %s server not connect" name)))
-                     #'(lambda (&rest args)
-                         (when (< (length args) (length required))
-                           (error "Error: args not match: %s -> %s" required args))
-                         (if-let* ((connection (gethash name mcp-server-connections)))
-                             (if-let* ((res (mcp-call-tool connection
-                                                           tool-name
-                                                           (mcp--generate-tool-call-args args properties))))
-                                 (mcp--parse-tool-call-result res)
-                               (error "Error: call %s tool error" tool-name))
-                           (error "Error: %s server not connect" name))))
-         :name tool-name
-         :async asyncp
-         :description description
-         :args
-         (mcp--parse-tool-args properties (or required '())))))))
-
-(defun mcp-async-set-log-level (connection log-level)
-  "Asynchronously set the log level for the MCP server.
-
-CONNECTION is the MCP connection object.
-LOG-LEVEL is the desired log level, which must be one of:
-- `debug': Detailed debugging information (function entry/exit points)
-- `info': General informational messages (operation progress updates)
-- `notice': Normal but significant events (configuration changes)
-- `warning': Warning conditions (deprecated feature usage)
-- `error': Error conditions (operation failures)
-- `critical': Critical conditions (system component failures)
-- `alert': Action must be taken immediately (data corruption detected)
-- `emergency': System is unusable (complete system failure)
-
-On success, displays a message confirming the log level change.
-On error, displays an error message with the server's response code and message."
-  (jsonrpc-async-request connection
-                         :logging/setLevel
-                         (list :level (format "%s" log-level))
-                         :success-fn
-                         #'(lambda (res)
-                             (message "[mcp] setLevel success: %s" res))
-                         :error-fn (jsonrpc-lambda (&key code message _data)
-                                     (message "Sadly, mpc server reports %s: %s"
-                                              code message))))
-
-(defun mcp-async-ping (connection)
-  "Send an asynchronous ping request to the MCP server via CONNECTION.
-
-The function uses `jsonrpc-async-request' to send a ping request.
-On success, it displays a message with the response.
-On error, it displays an error message with the code from the server."
-  (jsonrpc-async-request connection
-                         :ping
-                         nil
-                         :success-fn
-                         #'(lambda (res)
-                             (message "[mcp] ping success: %s" res))
-                         :error-fn (jsonrpc-lambda (&key code message _data)
-                                     (message "Sadly, mpc server reports %s: %s"
-                                              code message))))
-
-(defun mcp-async-initialize-message (connection callback &optional error-callback)
-  "Sending an `initialize' request to the CONNECTION.
-
-CONNECTION is the MCP connection object.
-CALLBACK is a function to call upon successful initialization.
-ERROR-CALLBACK is an optional function to call if an error occurs.
-
-This function sends an `initialize' request to the server
-with the client's capabilities and version information."
-  (jsonrpc-async-request connection
-                         :initialize
-                         (list :protocolVersion "2024-11-05"
-                               :capabilities '(:roots (:listChanged t))
-                               :clientInfo '(:name "mcp-emacs" :version "0.1.0"))
-                         :success-fn
-                         #'(lambda (res)
-                             (cl-destructuring-bind (&key protocolVersion serverInfo capabilities &allow-other-keys) res
-                               (funcall callback protocolVersion serverInfo capabilities)))
-                         :error-fn
-                         (jsonrpc-lambda (&key code message _data)
-                           (if error-callback
-                               (funcall error-callback code message)
-                             (message "Sadly, mpc server reports %s: %s"
-                                      code message)))))
-
-(defun mcp-async-list-tools (connection &optional callback error-callback)
-  "Get a list of tools from the MCP server using the provided CONNECTION.
-
-CONNECTION is the MCP connection object.
-CALLBACK is a function to call with the result of the request.
-ERROR-CALLBACK is an optional function to call if the request fails.
-
-This function sends a request to the server to list available tools.
-The result is stored in the `mcp--tools' slot of the CONNECTION object."
-  (jsonrpc-async-request connection
-                         :tools/list
-                         '(:cursor "")
-                         :success-fn
-                         #'(lambda (res)
-                             (cl-destructuring-bind (&key tools &allow-other-keys) res
-                               (setf (mcp--tools connection)
-                                     tools)
-                               (when callback
-                                 (funcall callback connection tools))))
-                         :error-fn
-                         (jsonrpc-lambda (&key code message _data)
-                           (if error-callback
-                               (funcall error-callback code message)
-                             (message "Sadly, mpc server reports %s: %s"
-                                      code message)))))
-
-(defun mcp-call-tool (connection name arguments)
-  "Call a tool on the remote CONNECTION with NAME and ARGUMENTS.
-
-CONNECTION is the MCP connection object.
-NAME is the name of the tool to call.
-ARGGUMENTS is a list of arguments to pass to the tool."
-  (jsonrpc-request connection
-                   :tools/call
-                   (list :name name
-                         :arguments (if arguments
-                                        arguments
-                                      #s(hash-table)))))
-
-(defun mcp-async-call-tool (connection name arguments callback error-callback)
-  "Async Call a tool on the remote CONNECTION with NAME and ARGUMENTS.
-
-CONNECTION is the MCP connection object.
-NAME is the name of the tool to call.
-ARGUMENTS is a list of arguments to pass to the tool.
-CALLBACK is a function to call on success.
-ERROR-CALLBACK is a function to call on error."
-  (jsonrpc-async-request connection
-                         :tools/call
-                         (list :name name
-                               :arguments (if arguments
-                                              arguments
-                                            #s(hash-table)))
-                         :success-fn
-                         #'(lambda (res)
-                             (funcall callback res))
-                         :error-fn
-                         (jsonrpc-lambda (&key code message _data)
-                           (funcall error-callback code message))))
-
-(defun mcp-async-list-prompts (connection &optional callback error-callback)
-  "Get list of prompts from the MCP server using the provided CONNECTION.
-
-CONNECTION is the MCP connection object. CALLBACK is an optional function to
-call on success,which will receive the CONNECTION and the list of prompts.
-ERROR-CALLBACK is an optional function to call on error, which will receive the
-error code and message.
-
-The result is stored in the `mcp--prompts' slot of the CONNECTION object."
-  (jsonrpc-async-request connection
-                         :prompts/list
-                         '(:cursor "")
-                         :success-fn
-                         #'(lambda (res)
-                             (cl-destructuring-bind (&key prompts &allow-other-keys) res
-                               (setf (mcp--prompts connection)
-                                     prompts)
-                               (when callback
-                                 (funcall callback connection prompts))))
-                         :error-fn
-                         (jsonrpc-lambda (&key code message _data)
-                           (if error-callback
-                               (funcall error-callback code message)
-                             (message "Sadly, mpc server reports %s: %s"
-                                      code message)))))
-
-(defun mcp-get-prompt (connection name arguments)
-  "Call a prompt on the remote CONNECTION with NAME and ARGUMENTS.
-
-CONNECTION is the MCP connection object.
-NAME is the name of the prompt to call.
-ARGGUMENTS is a list of arguments to pass to the prompt"
-  (jsonrpc-request connection
-                   :prompts/get
-                   (list :name name
-                         :arguments (if arguments
-                                        arguments
-                                      #s(hash-table)))))
-
-(defun mcp-async-get-prompt (connection name arguments callback error-callback)
-  "Async Call a prompt on the remote CONNECTION with NAME and ARGUMENTS.
-
-CONNECTION is the MCP connection object.
-NAME is the name of the prompt to call.
-ARGUMENTS is a list of arguments to pass to the prompt.
-CALLBACK is a function to call on successful response.
-ERROR-CALLBACK is a function to call on error."
-  (jsonrpc-async-request connection
-                         :prompts/get
-                         (list :name name
-                               :arguments (if arguments
-                                              arguments
-                                            #s(hash-table)))
-                         :success-fn
-                         #'(lambda (res)
-                             (funcall callback res))
-                         :error-fn
-                         (jsonrpc-lambda (&key code message _data)
-                           (funcall error-callback code message))))
-
-(defun mcp-async-list-resources (connection &optional callback error-callback)
-  "Get list of resources from the MCP server using the provided CONNECTION.
-
-CONNECTION is the MCP connection object. CALLBACK is an optional function to
-call upon successful retrieval of resources. ERROR-CALLBACK is an optional
-function to call if an error occurs during the request.
-
-The result is stored in the `mcp--resources' slot of the CONNECTION object."
-  (jsonrpc-async-request connection
-                         :resources/list
-                         '(:cursor "")
-                         :success-fn
-                         #'(lambda (res)
-                             (cl-destructuring-bind (&key resources &allow-other-keys) res
-                               (setf (mcp--resources connection)
-                                     resources)
-                               (when callback
-                                 (funcall callback connection resources))))
-                         :error-fn
-                         (jsonrpc-lambda (&key code message _data)
-                           (if error-callback
-                               (funcall error-callback code message)
-                             (message "Sadly, mpc server reports %s: %s"
-                                      code message)))))
-(defun mcp-read-resource (connection uri)
-  "Call a resource on the remote CONNECTION with URI.
-
-CONNECTION is the MCP connection object.
-URI is the uri of the resource to call."
-  (jsonrpc-request connection
-                   :resources/read
-                   (list :uri uri)))
-
-(defun mcp-async-read-resource (connection uri &optional callback error-callback)
-  "Call a resource on the remote CONNECTION with URI.
-
-CONNECTION is the MCP connection object.
-URI is the URI of the resource to call.
-CALLBACK is a function to call with the result on success.
-ERROR-CALLBACK is a function to call with the error code and message on failure.
-
-This function asynchronously reads a resource from the remote connection
-using the specified URI. The result is passed to CALLBACK if the request
-succeeds, or ERROR-CALLBACK if it fails."
-  (jsonrpc-async-request connection
-                         :resources/read
-                         (list :uri uri)
-                         :success-fn
-                         #'(lambda (res)
-                             (funcall callback res))
-                         :error-fn
-                         (jsonrpc-lambda (&key code message _data)
-                           (funcall error-callback code message))))
-
-(defun mcp-async-list-resource-templates (connection &optional callback error-callback)
-  "Get list of resource templates from the MCP server using the CONNECTION.
-
-CONNECTION is the MCP connection object. CALLBACK is an optional function to
-call upon successful retrieval of resources. ERROR-CALLBACK is an optional
-function to call if an error occurs during the request."
-  (jsonrpc-async-request connection
-                         :resources/templates/list
-                         '(:cursor "")
-                         :success-fn
-                         #'(lambda (res)
-                             (cl-destructuring-bind (&key resourceTemplates &allow-other-keys) res
-                               (when callback
-                                 (funcall callback connection resourceTemplates))))
-                         :error-fn
-                         (jsonrpc-lambda (&key code message _data)
-                           (if error-callback
-                               (funcall error-callback code message)
-                             (message "Sadly, mpc server reports %s: %s"
-                                      code message)))))
-
-(provide 'mcp)
-;;; mcp.el ends here
tools/emacs/lisp/ol-github.el
@@ -1,70 +0,0 @@
-;;; ol-github.el --- Links to GitHub -*- lexical-binding: t; -*-
-
-;; Copyright (C) 2020 Vincent Demeester
-
-;; Author: Vincent Demeester <vincent@sbr.pm>
-;; Keywords: org link github
-;; Version: 0.1
-;; URL: https://gitlab.com/vdemeester/vorg
-;; Package-Requires: ((emacs "26.0") (org "9.0"))
-;;
-;; This file is not part of GNU Emacs.
-
-;; This program is free software; you can redistribute it and/or
-;; modify it under the terms of the GNU General Public License as
-;; published by the Free Software Foundation; either version 3.0, or
-;; (at your option) any later version.
-
-;; This program is distributed in the hope that it will be useful,
-;; but WITHOUT ANY WARRANTY; without even the implied warranty of
-;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-;; GNU General Public License for more details.
-
-;; You should have received a copy of the GNU General Public License
-;; along with this program; if not, write to the Free Software
-;; Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-;;
-;;; Commentary:
-
-;; This file implements links to GitHub from within Org mode.
-;; gh:tektoncd/pipeline   : project
-;; gh:tektoncd/pipeline#1 : issue or pr #1
-
-;;; Code:
-
-(require 'ol)
-
-;; Install the link type
-(org-link-set-parameters "gh"
-                         :follow #'org-github-follow-link
-                         :export #'org-github-export
-                         :face '(:foreground "DimGrey" :underline t))
-
-
-(defun org-github-export (link description format)
-  "Export a github page link from Org files."
-  (let ((path (org-github-get-url link))
-        (desc (or description link)))
-    (cond
-     ((eq format 'html) (format "<a hrefl=\"_blank\" href=\"%s\">%s</a>" path desc))
-     ((eq format 'latex) (format "\\href{%s}{%s}" path desc))
-     ((eq format 'texinfo) (format "@uref{%s,%s}" path desc))
-     ((eq format 'ascii) (format "%s (%s)" desc path))
-     (t path))))
-
-(defun org-github-follow-link (issue)
-  "Browse github issue/pr specified."
-  (browse-url (org-github-get-url issue)))
-
-(defun org-github-get-url (path)
-  "Translate org-mode link `gh:foo/bar#1' to github url."
-  (setq expressions (split-string path "#"))
-  (setq project (nth 0 expressions))
-  (setq issue (nth 1 expressions))
-  (if issue
-      (format "https://github.com/%s/issues/%s" project issue)
-    (format "https://github.com/%s" project)))
-
-(provide 'ol-github)
-;;; ol-github.el ends here
tools/emacs/lisp/ol-gitlab.el
@@ -1,81 +0,0 @@
-;;; ol-gitlab.el --- Links to Gitlab -*- lexical-binding: t; -*-
-
-;; Copyright (C) 2020 Vincent Demeester
-
-;; Author: Vincent Demeester <vincent@sbr.pm>
-;; Keywords: org link gitlab
-;; Version: 0.1
-;; URL: https://gitlab.com/vdemeester/vorg
-;; Package-Requires: ((emacs "26.0") (org "9.0"))
-;;
-;; This file is not part of GNU Emacs.
-
-;; This program is free software; you can redistribute it and/or
-;; modify it under the terms of the GNU General Public License as
-;; published by the Free Software Foundation; either version 3.0, or
-;; (at your option) any later version.
-
-;; This program is distributed in the hope that it will be useful,
-;; but WITHOUT ANY WARRANTY; without even the implied warranty of
-;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-;; GNU General Public License for more details.
-
-;; You should have received a copy of the GNU General Public License
-;; along with this program; if not, write to the Free Software
-;; Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-;;
-;;; Commentary:
-
-;; This file implements links to Gitlab from within Org mode.
-;; gl:vdemeester/emacs-config    : project
-;; gl:vdemeester/emacs-config#1  : issue #1
-;; gl:vdemeester/emacs-config##1 : merge-request #1
-
-;;; Code:
-
-(require 'ol)
-
-;; Install the link type
-(org-link-set-parameters "gl"
-                         :follow #'org-gitlab-follow-link
-                         :export #'org-gitlab-export
-                         :face '(:foreground "DimGrey" :underline t))
-
-
-(defun org-gitlab-export (link description format)
-  "Export a gitlab page link from Org files."
-  (let ((path (org-gitlab-get-url link))
-        (desc (or description link)))
-    (cond
-     ((eq format 'html) (format "<a hrefl=\"_blank\" href=\"%s\">%s</a>" path desc))
-     ((eq format 'latex) (format "\\href{%s}{%s}" path desc))
-     ((eq format 'texinfo) (format "@uref{%s,%s}" path desc))
-     ((eq format 'ascii) (format "%s (%s)" desc path))
-     (t path))))
-
-(defun org-gitlab-follow-link (issue)
-  "Browse gitlab issue/pr specified."
-  (browse-url (org-gitlab-get-url issue)))
-
-(defun org-gitlab-get-url (path)
-  "Translate org-mode link `gh:foo/bar#1' to gitlab url."
-  (setq expressions (split-string path "#"))
-  (setq project (nth 0 expressions))
-  (setq issue (nth 1 expressions))
-  (setq mr (nth 2 expressions))
-  (message (format "issue: %s" issue))
-  (message (format "mr: %s" mr))
-  (if (not (empty-string-p mr))
-      (format "https://gitlab.com/%s/-/merge_requests/%s" project mr)
-    (if (not (empty-string-p issue))
-        (format "https://gitlab.com/%s/-/issues/%s" project issue)
-      (format "https://gitlab.com/%s" project))))
-
-(defun empty-string-p (string)
-  "Return true if the STRING is empty or nil. Expects string type."
-  (or (null string)
-      (zerop (length (string-trim string)))))
-
-(provide 'ol-gitlab)
-;;; ol-gitlab.el ends here
tools/emacs/lisp/ol-grep.el
@@ -1,57 +0,0 @@
-;;; ol-grep.el --- Links to Grep -*- lexical-binding: t; -*-
-
-;; Copyright (C) 2020 Vincent Demeester
-
-;; Author: Vincent Demeester <vincent@sbr.pm>
-;; Keywords: org link grep
-;; Version: 0.1
-;; URL: https://gitlab.com/vdemeester/vorg
-;; Package-Requires: ((emacs "26.0") (org "9.0"))
-;;
-;; This file is not part of GNU Emacs.
-
-;; This program is free software; you can redistribute it and/or
-;; modify it under the terms of the GNU General Public License as
-;; published by the Free Software Foundation; either version 3.0, or
-;; (at your option) any later version.
-
-;; This program is distributed in the hope that it will be useful,
-;; but WITHOUT ANY WARRANTY; without even the implied warranty of
-;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-;; GNU General Public License for more details.
-
-;; You should have received a copy of the GNU General Public License
-;; along with this program; if not, write to the Free Software
-;; Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-;;
-;;; Commentary:
-
-;; This file implements links to Grep from within Org mode.
-;; grep:orgmode         : run grep on current working dir with orgmode expression
-;; grep:orgmode:config/ : run grep on config/ dir with orgmode expression
-
-;;; Code:
-
-(require 'ol)
-
-;; Install the link type
-(org-link-set-parameters "rg"
-                         :follow #'org-grep-follow-link
-                         :face '(:foreground "DarkRed" :underline t))
-
-(defun org-grep-follow-link (issue)
-  "Run `rgrep' with REGEXP and FOLDER as argument,
-like this : [[grep:REGEXP:FOLDER]]."
-  (setq expressions (split-string regexp ":"))
-  (setq exp (nth 0 expressions))
-  (grep-compute-defaults)
-  (if (= (length expressions) 1)
-      (progn
-        (rgrep exp "*" (expand-file-name "./")))
-    (progn
-      (setq folder (nth 1 expressions))
-      (rgrep exp "*" (expand-file-name folder)))))
-
-(provide 'ol-grep)
-;;; ol-grep.el ends here
tools/emacs/lisp/ol-rg.el
@@ -1,61 +0,0 @@
-;;; ol-rg.el --- Links to rg -*- lexical-binding: t; -*-
-
-;; Copyright (C) 2020 Vincent Demeester
-
-;; Author: Vincent Demeester <vincent@sbr.pm>
-;; Keywords: org link ripgrep rg.el
-;; Version: 0.1
-;; URL: https://gitlab.com/vdemeester/vorg
-;; Package-Requires: ((emacs "26.0") (org "9.0") (rg "1.8.0"))
-;;
-;; This file is not part of GNU Emacs.
-
-;; This program is free software; you can redistribute it and/or
-;; modify it under the terms of the GNU General Public License as
-;; published by the Free Software Foundation; either version 3.0, or
-;; (at your option) any later version.
-
-;; This program is distributed in the hope that it will be useful,
-;; but WITHOUT ANY WARRANTY; without even the implied warranty of
-;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-;; GNU General Public License for more details.
-
-;; You should have received a copy of the GNU General Public License
-;; along with this program; if not, write to the Free Software
-;; Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-;;
-;;; Commentary:
-
-;; This file implements links to Ripgrep from within Org mode.
-;; rg:orgmode             : run ripgrep on current working dir with orgmode expression
-;; rg:orgmode:config/     : run ripgrep on config/ dir with orgmode expression
-;; rg:orgmode:config/#org : run ripgrep on config/ dir with orgmode expression
-
-;;; Code:
-
-(require 'rg)
-(require 'ol)
-
-;; Install the link type
-(org-link-set-parameters "rg"
-                         :follow #'org-rg-follow-link
-                         :face '(:foreground "DarkGreen" :underline t))
-
-(defun org-rg-follow-link (regexp)
-  "Run `rg` with REXEP as argument,
-like this : [[rg:REGEXP:FOLDER#FILTER]]"
-  (setq expressions (split-string regexp ":"))
-  (setq exp (nth 0 expressions))
-  (setq folderpart (nth 1 expressions))
-  (setq files (split-string folderpart "#"))
-  (setq folder (nth 0 files))
-  (setq filter (nth 1 files))
-  (if folderpart
-      (if filter
-          (rg exp (concat "*." filter) folder)
-        (rg exp "*" folder))
-    (rg exp "*" "./")))
-
-(provide 'ol-rg)
-;;; ol-rg.el ends here
tools/emacs/lisp/org-extra-emphasis.el
@@ -1,805 +0,0 @@
-;;; org-extra-emphasis.el --- Extra Emphasis markers for Org -*- lexical-binding: t; coding: utf-8-emacs; -*-
-
-;; Copyright (C) 2022 Jambunathan K <kjambunathan at gmail dot com>
-;; Copyright (C) 2004-2022 Free Software Foundation, Inc.
-
-;; Author: Jambunathan K <kjambunathan at gmail dot com>
-;; Keywords: org
-;; Homepage: https://github.com/kjambunathan/org-extra-emphasis
-;; Version: 1.0
-;; Package-Requires: ((ox-odt "9.5.3.467"))
-
-;; This file is NOT part of GNU Emacs.
-
-;; This program is free software: you can redistribute it and/or
-;; modify it under the terms of the GNU General Public License as
-;; published by the Free Software Foundation, either version 3 of the
-;; License, or (at your option) any later version.
-
-;; This program is distributed in the hope that it will be useful, but
-;; WITHOUT ANY WARRANTY; without even the implied warranty of
-;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-;; General Public License for more details.
-
-;; You should have received a copy of the GNU General Public License
-;; along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.
-
-;;; Commentary:
-
-;; Overview
-;; ========
-;;
-;; This library provides two additional markers `!!' and `!@' over
-;; and above those in `org-emphasis-alist'.'
-;;
-;; - Text enclosed in `!!' is highlighted in yellow, and exported likewise
-;; - Text enclosed in `!@' is displayed in red, and exported likewise
-;;
-;; Following backends are supported: HTML and ODT. For export of extra
-;; emphasis markers to the ODT side, you need
-;; [[https://github.com/kjambunathan/org-mode-ox-odt][Enhanced ODT]]
-;; exporter with version >= 9.5.3.467 (dtd. June 14, 2022 IST).  This
-;; is the first version of the exporter that defines the user option
-;; `org-odt-extra-styles'.
-;;
-;; Example
-;; =======
-;;
-;; Setup
-;; =====
-;;
-;; Add the following to your `user-init-file' and restart Emacs.
-;;
-;;    (requrie 'org-extra-emphasis)
-;;
-;; Test Run
-;; ========
-;;
-;; 1. Create an `org' file, say `org-export-emphasis.org' and fill it
-;;    with following content or you can download the file from
-;;    https://raw.githubusercontent.com/kjambunathan/org-extra-emphasis/main/org-extra-emphasis.org
-
-	  ;; #+TITLE: Test file for ==org-extra-emphasis== library
-
-	  ;; * Demo of extra emphasis markers ==!!== and ==!@==
-
-	  ;; !!Ea consectetur laboris adipiscing et ipsum labore esse qui minim
-	  ;; pariatur et sunt sunt nostrud anim laborum culpa.!!
-
-	  ;; !@Minim reprehenderit excepteur elit, dolore elit, veniam, eu.
-	  ;; Ullamco dolore elit, cupidatat sed labore ea aute.!@
-
-	  ;; Pariatur !!et lorem cupidatat !@minim irure!@ proident, ad.!!  Eiusmod
-	  ;; sunt et lorem labore ex aliqua aute esse.
-
-	  ;; Ut mollit !@duis velit est est magna in quis ipsum.  !!Aliqua aliqua
-	  ;; non laboris exercitation cupidatat aliqua incididunt.!!  Qui voluptate
-	  ;; irure aute occaecat laborum cillum est.!@  Quis magna dolor ullamco
-	  ;; magna do consectetur est laborum enim ut.
-
-	  ;; * !!Demo of extra emphasis markers in a styled paragraph!!
-
-	  ;; #+ATTR_ODT: :target "extra_styles"
-	  ;; #+begin_src nxml
-	  ;; <style:style style:name="Warn"
-	  ;;	     style:parent-style-name="Text_20_body"
-	  ;;	     style:family="paragraph">
-	  ;;   <style:paragraph-properties>
-	  ;;     <style:tab-stops />
-	  ;;   </style:paragraph-properties>
-	  ;;   <style:text-properties fo:background-color="#ff0000"
-	  ;;		       fo:color="#ffffff"
-	  ;;		       fo:font-size="20pt"
-	  ;;		       fo:font-style="italic"
-	  ;;		       fo:font-weight="bold" />
-	  ;; </style:style>
-	  ;; #+end_src
-
-	  ;; #+ATTR_ODT: :style "Warn"
-	  ;; Proident, duis dolore consectetur sed nisi ea pariatur.  Esse
-	  ;; proident, cillum duis qui ullamco sint cillum magna.  !!Eiusmod
-	  ;; veniam, !@sint officia!@ non consectetur laboris cillum.!!  Cillum
-	  ;; mollit consequat eu dolore ullamco qui reprehenderit anim cillum
-	  ;; in consectetur consequat sunt dolore aliquip voluptate
-	  ;; consectetur anim ea.  Voluptate nisi est incididunt aliquip
-	  ;; excepteur aliqua id do enim ut non consequat.
-;;
-;; 2. Note that portions of text marked with `!!' and `!@' are fontified as described above.
-;;
-;; 3. Export the file to HTML with `C-c C-e h O'.
-;;
-;;    Note that the text enclosed in the above emphasis markers are
-;;    colorized in HTML file.
-;;
-;; 4. Export the file to ODT with `C-c C-e o O'.
-;;
-;;    Note that the text enclosed in the above emphasis markers are
-;;    colorized in ODT file.
-;;
-;; The HTML, ODT, PDF generated in steps (3) and (4) above are
-;; available at https://github.com/kjambunathan/org-extra-emphasis and
-;; the screenshots can be seen in https://github.com/kjambunathan/org-extra-emphasis/tree/main/screenshots
-;;
-
-;; Default Settings
-;; ================
-;;
-;; 16 Emphasis Markers
-;; ===================
-;;
-;; This library defines the following 16 emphasis markers,
-;;
-;; |----+----+----+----|
-;; | !! | !@ | !% | !& |
-;; |----+----+----+----|
-;; | @! | @@ | @% | @& |
-;; |----+----+----+----|
-;; | %! | %@ | %% | %& |
-;; |----+----+----+----|
-;; | &! | &@ | &% | && |
-;; |----+----+----+----|
-;;
-;; The above markers are all pairings of the following four characters:
-;;     ! @ % &
-;;
-;; It is hoped that these set of emphasis markers don't pose issues
-;; while exporting.
-;;
-;; 17 Extra Emphasis Faces
-;; =======================
-;;
-;; This library defines 17 faces:
-;;
-;; - one base face `org-extra-emphasis'
-;; - 16 more faces `org-extra-emphasis-01',`org-extra-emphasis-02',
-;;  ..., `org-extra-emphasis-16'.
-;;
-;; The later 16 faces derive from `org-extra-emphasis' face.  Of
-;; these, only the first two faces `org-extra-emphasis-01' and
-;; `org-extra-emphasis-02' are explicitly configured.  If you are
-;; using more than 2 emphasis markers, you may want to configure the
-;; other 14 faces.
-;;
-;; `org-extra-emphasis-alist' already associated 16 emphasis markers
-;; with 16 different faces.
-;;
-;; Customization
-;; =============
-;;
-;; Configuring your own Emphasis Markers
-;; =====================================
-;;
-;; 16 numbers of emphasis markers should suffice in practice.
-;; However, if none of the above emphasis markers resonate with you,
-;; you can customize `org-extra-emphasis-alist', and plug in your own
-;; markers.  When choosing your own marker, ensure that you exercise
-;; some care.  For example, if you choose `#' as a marker you are
-;; likely to get malformed `html' and `odt' files.
-;;
-;; Configuring Extra Emphasis Faces
-;; ===============================
-;;
-;; You can use `M-x customize-group RET org-extra-emphasis-faces RET'
-;; to configure the extra emphasis faces.
-;;
-;; Disabling the Extra Emphasis
-;; =============================
-;;
-;; You can use `M-x org-extra-emphasis-mode' to toggle this feature.
-;;
-;; Adding additional export backends
-;; =================================
-;;
-;; To add additional backends, modify `org-extra-emphasis-formatter'
-;; and `org-extra-emphasis-build-backend-regexp'.
-
-;;; Code:
-
-(require 'org)
-(require 'ox-odt)
-(require 'rx)
-(require 'htmlfontify)
-
-;;; PART-1: `org-extra-emphasis-mode'
-
-;;;; Internal Variables
-
-(defvar org-extra-emphasis-backends
-  '(html odt ods))
-
-(defvar org-extra-emphasis-info
-  (list :enabled nil))
-
-;; Helper snippets to convert a Emacs Face to Inine CSS and ODT Text Properties
-;;
-;; (defun org-extra-emphasis-emacs-face->inline-css (face)
-;;   (let ((s (cdr (hfy-face-to-css-default face))))
-;;     (when (string-match (rx-to-string '(and "{" (group (zero-or-more any)) "}")) s)
-;;       (format "<span style=\"%s\">%%s</span>" (match-string 1 s)))))
-;;
-;; (org-extra-emphasis-emacs-face->inline-css 'hi-yellow)
-;; (org-extra-emphasis-emacs-face->inline-css 'hi-red-b)
-;;
-;; (defun org-extra-emphasis-emacs-face->odt-text-properties (face)
-;;   (org-odt--lisp-to-xml
-;;    (assoc 'style:text-properties
-;;	  (org-odt--xml-to-lisp
-;;	   (cdr (org-odt-hfy-face-to-css face))))))
-;;
-;; (org-extra-emphasis-emacs-face->odt-text-properties 'hi-yellow)
-;; (org-extra-emphasis-emacs-face->odt-text-properties 'hi-red-b)
-
-(defun org-extra-emphasis-update (&rest _ignored)
-  "Workhorse function that responds to configuration changes.
-
-Current state is maintined in `org-extra-emphasis-info', a plist."
-  ;; When `org-extra-emaphasis' is ON, override use
-  ;; `org-extra-emphasis-org-do-emphasis-faces'.
-  ;; Otherwise, use `org-do-emphasis-faces'.
-  (cond
-   ((plist-get org-extra-emphasis-info :enabled)
-    (advice-add 'org-do-emphasis-faces :override
-		'org-extra-emphasis-org-do-emphasis-faces))
-   (t
-    (advice-remove 'org-do-emphasis-faces
-		   'org-extra-emphasis-org-do-emphasis-faces)))
-  ;; `org-extra-emphasis-alist' is effective only if
-  ;; `org-extra-emphasis' is enabled.
-  (plist-put org-extra-emphasis-info :work-alist
-	     (when (plist-get org-extra-emphasis-info :enabled)
-	       (plist-get org-extra-emphasis-info :alist)))
-  ;; Set properties that control fontification.
-  ;; The property names and their values mimics the corresponding
-  ;; variables in `org-set-emph-re'.
-  (plist-put org-extra-emphasis-info :org-emphasis-alist
-	     (when (and (boundp 'org-emphasis-regexp-components)
-			org-emphasis-alist org-emphasis-regexp-components)
-	       (append (plist-get org-extra-emphasis-info :work-alist)
-		       org-emphasis-alist)))
-  (plist-put org-extra-emphasis-info :org-emph-re-template
-	     (when (and (boundp 'org-emphasis-regexp-components)
-			org-emphasis-alist org-emphasis-regexp-components)
-	       (pcase-let*
-		   ((`(,pre ,post ,border ,body ,nl) org-emphasis-regexp-components)
-		    (body (if (<= nl 0) body
-			    (format "%s*?\\(?:\n%s*?\\)\\{0,%d\\}" body body nl))))
-		 (format (concat "\\([%s]\\|^\\)" ;before markers
-				 "\\(\\(%%s\\)\\([^%s]\\|[^%s]%s[^%s]\\)\\3\\)"
-				 "\\([%s]\\|$\\)") ;after markers
-			 pre border border body border post))))
-  (plist-put org-extra-emphasis-info :org-emph-re
-	     (format (plist-get org-extra-emphasis-info :org-emph-re-template)
-		     (rx-to-string
-		      `(or ,@(mapcar #'car
-				     (cl-remove-if (lambda (l)
-						     (eq 'verbatim (nth 2 l)))
-						   (plist-get org-extra-emphasis-info :org-emphasis-alist)))))))
-  (plist-put org-extra-emphasis-info :org-verbatim-re
-	     (format (plist-get org-extra-emphasis-info :org-emph-re-template)
-		     (rx-to-string
-		      `(or ,@(mapcar #'car
-				     (cl-remove-if-not (lambda (l)
-							 (eq 'verbatim (nth 2 l)))
-						       (plist-get org-extra-emphasis-info :org-emphasis-alist)))))
-		     (rx-to-string
-		      `(or ,@(mapcar #'car
-				     (cl-remove-if-not (lambda (l)
-							 (eq 'verbatim (nth 2 l)))
-						       (plist-get org-extra-emphasis-info :org-emphasis-alist)))))))
-  ;; Set properties that control Export backends
-  ;; - Regexp to search for in the final exported document
-  (plist-put org-extra-emphasis-info :export-alist
-	     (org-extra-emphasis-build-backend-regexp))
-
-  ;; - Generate ODT character styles for the extra emphasis faces and
-  ;;   dump those in `org-odt-extra-styles' and `org-ods-automatic-styles'.
-  (plist-put org-extra-emphasis-info :odt-extra-styles
-	     (let* ((odt-styles
-		     (concat (mapconcat #'identity
-					(cl-loop for (_marker face) in (plist-get org-extra-emphasis-info :alist)
-						 collect (cdr (org-odt-hfy-face-to-css face)))
-					"\n\n"))))
-	       (with-no-warnings
-		 (unless (boundp 'org-odt-extra-styles)
-		   (message "`org-odt-extra-styles' not found.  Upgrade to `ox-odt-9.5.3.467' or later.")
-		   ;; (sleep-for 2)
-		   (setq org-odt-extra-styles nil))
-		 (setq org-odt-extra-styles
-		       (concat (or (when (boundp 'org-odt-extra-styles)
-				     (get 'org-odt-extra-styles 'saved-value))
-				   "")
-			       "\n\n"
-			       odt-styles))
-		 (setq org-ods-automatic-styles
-		       (concat (or (when (boundp 'org-ods-automatic-styles)
-				     (get 'org-ods-automatic-styles 'saved-value))
-				   "")
-			       "\n\n"
-			       odt-styles))
-		 (message "`org-odt-extra-styles' and `org-ods-automatic-styles' is updated for this session")
-		 ;; (sleep-for 1)
-		 )
-	       odt-styles))
-  ;; Re-fontify all Org buffers based on current configuration.
-  (dolist (buffer (buffer-list))
-    (with-current-buffer buffer
-      (when (derived-mode-p 'org-mode)
-	(font-lock-flush)))))
-
-;;;; Fontify Extra Emphasis Markers
-
-(defun org-extra-emphasis-org-do-emphasis-faces (limit)
-  "Workhorse function that does fontification This function is
-based on `org-do-emphasis-faces'.  The property names and values
-correspond to the variables used in `org-do-emphasis-faces'.  Key
-differences are:
-
-    - `:org-emphasis-alist' includes entries for both standard
-      emphasis markers and extra emphasis markers.
-
-    - The regexes used for search-based fontification allow for
-      the possibility that the emphasis markers _in all
-      likelihood_ are multi-char strings, as opposed to single
-      chars."
-  (let* ((quick-re (format "\\([%s]\\|^\\)\\(%s\\)"
-			   (car org-emphasis-regexp-components)
-			   (rx-to-string
-			    `(or ,@(mapcar #'car (plist-get org-extra-emphasis-info :org-emphasis-alist)))))))
-    (catch :exit
-      (while (re-search-forward quick-re limit t)
-	(let* ((marker (match-string 2))
-	       (verbatim? (member marker '("~" "="))))
-	  (when (save-excursion
-		  (goto-char (match-beginning 0))
-		  (and
-		   ;; Do not match table hlines.
-		   (not (and (equal marker "+")
-			     (org-match-line
-			      "[ \t]*\\(|[-+]+|?\\|\\+[-+]+\\+\\)[ \t]*$")))
-		   ;; Do not match headline stars.  Do not consider
-		   ;; stars of a headline as closing marker for bold
-		   ;; markup either.
-		   (not (and (equal marker "*")
-			     (save-excursion
-			       (forward-char)
-			       (skip-chars-backward "*")
-			       (looking-at-p org-outline-regexp-bol))))
-		   ;; Match full emphasis markup regexp.
-		   (looking-at (if verbatim? (plist-get org-extra-emphasis-info :org-verbatim-re)
-				 (plist-get org-extra-emphasis-info :org-emph-re)))
-		   ;; Do not span over paragraph boundaries.
-		   (not (string-match-p org-element-paragraph-separate
-					(match-string 2)))
-		   ;; Do not span over cells in table rows.
-		   (not (and (save-match-data (org-match-line "[ \t]*|"))
-			     (string-match-p "|" (match-string 4))))))
-	    (pcase-let ((`(,_ ,face ,_) (assoc marker (plist-get org-extra-emphasis-info :org-emphasis-alist)))
-			(m (if org-hide-emphasis-markers 4 2)))
-	      (font-lock-prepend-text-property
-	       (match-beginning m) (match-end m) 'face face)
-	      (when verbatim?
-		(org-remove-flyspell-overlays-in
-		 (match-beginning 0) (match-end 0))
-		(remove-text-properties (match-beginning 2) (match-end 2)
-					'(display t invisible t intangible t)))
-	      (add-text-properties (match-beginning 2) (match-end 2)
-				   '(font-lock-multiline t org-emphasis t))
-	      (when (and org-hide-emphasis-markers
-			 (not (org-at-comment-p)))
-		(add-text-properties (match-end 4) (match-beginning 5)
-				     '(invisible t))
-		(add-text-properties (match-beginning 3) (match-end 3)
-				     '(invisible t)))
-	      (throw :exit t))))))))
-
-;; There is no `:set' function for `deffaces'.  So, when the extra
-;; faces `org-extra-emphasis-01', `org-extra-emphasis-02' reconfigured,
-;; we don't get a notification.  The following export hook ensures
-;; that `org-extra-emphasis-info' is in sync with user configuration.
-(add-hook 'org-export-before-processing-hook 'org-extra-emphasis-update)
-
-;;;; Export Extra Emphasis Markers
-
-(defun org-extra-emphasis-formatter (marker text backend)
-  "Style TEXT in the same font face as the face MARKER is mapped to.
-Note that TEXT is in BACKEND format.
-
-This currently supports HTML and ODT backends.
-
-See `org-extra-emphasis-alist' for MARKER to face mappings."
-  (let* ((face (car (assoc-default marker (plist-get org-extra-emphasis-info :work-alist))))
-         (encode-attribute-value
-	  (lambda (text)
-	    (dolist (pair '(("&" . "&amp;")
-			    ("<" . "&lt;")
-			    (">" . "&gt;")
-			    ("'" . "&apos;")
-			    ("\"" . "&quot;")))
-	      (setq text (replace-regexp-in-string (car pair) (cdr pair) text t t)))
-	    text)))
-    (cl-case backend
-      ((odt ods)
-       (format "<text:span text:style-name=\"%s\">%s</text:span>"
-	       (car (org-odt-hfy-face-to-css face)) text))
-      (html
-       (format "<span class=\"%s\" style=\"%s\">%s</span>"
-	       face
-	       ;; An alternate implementation of
-	       ;; `hfy-face-to-css-default' which performs correctly
-	       ;; when a face specifies a `:family', and/or inherits
-	       ;; some attributes from other faces.  Note that the
-	       ;; flattening (or non-duplication) of face attributes
-	       ;; here is done by Emacs itself.
-	       (mapconcat (lambda (x)
-			    (when (cdr x)
-			      (format "%s: %s;" (car x)
-                                      (funcall encode-attribute-value (cdr x)))))
-			  (hfy-face-to-style-i
-			   (cl-loop with props = (mapcar #'car face-attribute-name-alist)
-				    for prop in props
-				    for value = (face-attribute face prop nil 'default)
-				    unless (eq prop :inherit)
-				    append (list prop value)))
-			  " ")
-	       text))
-      (_ text))))
-
-(defun org-extra-emphasis-build-backend-regexp ()
-  "Regexp to search for emphasized text in exported file.
-This function transcode an emphasis MARKER which is in plain text
-format, to the BACKEND format.  That is, if you use `<<' as an
-emphasis marker, you need to search for `&lt;&lt;' in the
-exported HTML file.
-
-See `org-extra-emphasis-alist' for more information"
-  (cl-loop for (marker . spec) in (plist-get org-extra-emphasis-info :work-alist) collect
-	   (cons marker
-		 (cl-loop for backend in org-extra-emphasis-backends collect
-			  (cons backend
-				(rx-to-string `(and ,(org-export-data-with-backend marker backend nil)
-						    (group (minimal-match
-							    (zero-or-more (or any "\n"))))
-						    ,(org-export-data-with-backend marker backend nil))))))))
-
-(defun org-extra-emphasis-plain-text-filter (text backend _info)
-  "Transcode TEXT in to BACKEND format.
-Uses `org-extra-emphasis-formatter' to do the transcoding.
-
-Search TEXT for one or more transcoded MARKERs, and mark it up as
-specified in `org-extra-emphasis-alist'."
-  (with-temp-buffer
-    (insert text)
-    (cl-loop for (marker . spec) in (plist-get org-extra-emphasis-info :export-alist)
-	     for regex = (assoc-default backend spec)
-	     do (goto-char (point-min))
-	     (if (not regex) text
-	       (while (re-search-forward regex nil t)
-		 (let* ((contents (match-string 1))
-			(emphasized-contents (save-match-data
-					       (org-extra-emphasis-formatter
-						marker contents backend))))
-		   (replace-match emphasized-contents t t)))))
-    (buffer-substring-no-properties (point-min) (point-max))))
-
-;; Install export filter for transcoding extra emphasis markers.
-(defun org-extra-emphasis-update-filter-functions (&optional export-filter-functions)
-  (let* ((all-filter-functions (thread-last org-export-filters-alist
-					    (seq-map #'cdr)
-					    (seq-sort #'string<))))
-    (dolist (filter-fn '(org-extra-emphasis-plain-text-filter org-extra-emphasis-strip-zws-maybe))
-      (dolist (it all-filter-functions)
-        (set it (delq filter-fn (symbol-value it))))
-      (dolist (it export-filter-functions)
-        (add-to-list it filter-fn)))))
-
-;;;; User Options & Commands
-
-;;;;; Custom Groups
-
-(defgroup org-extra-emphasis nil
-  "Options for highlighting and exporting extra emphasis markers in Org files."
-  :tag "Org Extra Emphasis"
-  :group 'org)
-
-(defgroup org-extra-emphasis-faces nil
-  "Faces for Org Extra Emphasis."
-  :group 'org-extra-emphasis
-  :group 'faces)
-
-;;;; Custom Faces
-
-(defface org-extra-emphasis nil
-  "A face for Org Extra Emphasis."
-  :group 'org-extra-emphasis-faces)
-
-(defface org-extra-emphasis-01
-  '((t (:inherit org-extra-emphasis :background "yellow")))
-  "A face for Org Extra Emphasis."
-  :group 'org-extra-emphasis-faces)
-
-(defface org-extra-emphasis-02
-  '((t (:inherit org-extra-emphasis :foreground "red")))
-  "A face for Org Extra Emphasis."
-  :group 'org-extra-emphasis-faces)
-
-(defface org-extra-emphasis-03
-  '((t (:inherit org-extra-emphasis)))
-  "A face for Org Extra Emphasis."
-  :group 'org-extra-emphasis-faces)
-
-(defface org-extra-emphasis-04
-  '((t (:inherit org-extra-emphasis)))
-  "A face for Org Extra Emphasis."
-  :group 'org-extra-emphasis-faces)
-
-(defface org-extra-emphasis-05
-  '((t (:inherit org-extra-emphasis)))
-  "A face for Org Extra Emphasis."
-  :group 'org-extra-emphasis-faces)
-
-(defface org-extra-emphasis-06
-  '((t (:inherit org-extra-emphasis)))
-  "A face for Org Extra Emphasis."
-  :group 'org-extra-emphasis-faces)
-
-(defface org-extra-emphasis-07
-  '((t (:inherit org-extra-emphasis)))
-  "A face for Org Extra Emphasis."
-  :group 'org-extra-emphasis-faces)
-
-(defface org-extra-emphasis-08
-  '((t (:inherit org-extra-emphasis)))
-  "A face for Org Extra Emphasis."
-  :group 'org-extra-emphasis-faces)
-
-(defface org-extra-emphasis-09
-  '((t (:inherit org-extra-emphasis)))
-  "A face for Org Extra Emphasis."
-  :group 'org-extra-emphasis-faces)
-
-(defface org-extra-emphasis-10
-  '((t (:inherit org-extra-emphasis)))
-  "A face for Org Extra Emphasis."
-  :group 'org-extra-emphasis-faces)
-
-(defface org-extra-emphasis-11
-  '((t (:inherit org-extra-emphasis)))
-  "A face for Org Extra Emphasis."
-  :group 'org-extra-emphasis-faces)
-
-(defface org-extra-emphasis-12
-  '((t (:inherit org-extra-emphasis)))
-  "A face for Org Extra Emphasis."
-  :group 'org-extra-emphasis-faces)
-
-(defface org-extra-emphasis-13
-  '((t (:inherit org-extra-emphasis)))
-  "A face for Org Extra Emphasis."
-  :group 'org-extra-emphasis-faces)
-
-(defface org-extra-emphasis-14
-  '((t (:inherit org-extra-emphasis)))
-  "A face for Org Extra Emphasis."
-  :group 'org-extra-emphasis-faces)
-
-(defface org-extra-emphasis-15
-  '((t (:inherit org-extra-emphasis)))
-  "A face for Org Extra Emphasis."
-  :group 'org-extra-emphasis-faces)
-
-(defface org-extra-emphasis-16
-  '((t (:inherit org-extra-emphasis)))
-  "A face for Org Extra Emphasis."
-  :group 'org-extra-emphasis-faces)
-
-;;;;; Useful Org Setting
-
-(setcar (last org-emphasis-regexp-components) 5)
-
-(defcustom org-extra-emphasis-alist
-  '(("!!" org-extra-emphasis-01)
-    ("!@" org-extra-emphasis-02)
-    ("!%" org-extra-emphasis-03)
-    ("!&" org-extra-emphasis-04)
-    ("@!" org-extra-emphasis-05)
-    ("@@" org-extra-emphasis-06)
-    ("@%" org-extra-emphasis-07)
-    ("@&" org-extra-emphasis-08)
-    ("%!" org-extra-emphasis-09)
-    ("%@" org-extra-emphasis-10)
-    ("%%" org-extra-emphasis-11)
-    ("%&" org-extra-emphasis-12)
-    ("&!" org-extra-emphasis-13)
-    ("&@" org-extra-emphasis-14)
-    ("&%" org-extra-emphasis-15)
-    ("&&" org-extra-emphasis-16))
-  "Alist of emphasis marker and its associated face."
-  :group 'org-extra-emphasis
-  :type '(repeat
-	  (list
-	   (string :tag "Emphasis Marker")
-	   (face :tag "Face")))
-  :set (lambda (var val)
-	 (set var val)
-	 (plist-put org-extra-emphasis-info :alist val)
-	 (org-extra-emphasis-update)))
-
-(defcustom org-extra-emphasis t
-  "When non-nil, enable Org Extra Emphasis."
-  :group 'org-extra-emphasis
-  :type '(boolean "Org Extra Emphasis")
-  :set (lambda (var val)
-	 (set var val)
-	 (plist-put org-extra-emphasis-info :enabled val)
-	 (org-extra-emphasis-update)))
-
-(defcustom org-extra-emphasis-filter-functions
-  '(
-    org-export-filter-headline-functions
-    org-export-filter-paragraph-functions
-    org-export-filter-table-cell-functions
-    )
-  "List of places to which `org-extra-emphasis-plain-text-filter'
-and `org-extra-emphasis-strip-zws-maybe' hooks itself.
-
-The places should be one among the values that occur in
-`org-export-filters-alist'.
-
-By default, the list includes
-    - `org-export-filter-headline-functions'
-    - `org-export-filter-paragraph-functions'
-    - `org-export-filter-table-cell-functions',
-
-This means that text with extra emphasis which appears as plain
-text, or within headlines and table cells will be, fontified."
-  :group 'org-extra-emphasis
-  :type `(set
-          ,@(thread-last org-export-filters-alist
-			 (seq-map #'cdr)
-                         (seq-sort #'string<)
-			 (seq-map (lambda (it)
-			            (list 'const it)))))
-  :set (lambda (var value)
-         (set-default var value)
-         (org-extra-emphasis-update-filter-functions value)))
-
-;;;;; `M-x org-extra-emphasis-mode'
-
-(defun org-extra-emphasis-mode (&optional arg)
-  "Enable / Disable Org Extra Emphasis.
-
-If called interactively, toggle Extra Emphasis.
-
-When called non-interactively, enable Extra Emphasis if ARG is
-positive; disable otherwise."
-  (interactive "p")
-  (cond
-   ;; Called interactively; Toggle
-   ((called-interactively-p 'any)
-    (setq org-extra-emphasis (not org-extra-emphasis)))
-   ;; Called programatically; enable if arg >= 1
-   ((and (numberp arg)
-	 (>= arg 1))
-    (setq org-extra-emphasis t))
-   ;; Otherwise, disable
-   (t
-    (setq org-extra-emphasis nil)))
-  (plist-put org-extra-emphasis-info :enabled org-extra-emphasis)
-  (org-extra-emphasis-update))
-
-;;; PART-2: `org-extra-emphasis-intraword-emphasis-mode'
-
-;;;; User options
-
-(defface org-extra-emphasis-zws-face
-  '((t (:inherit org-extra-emphasis :foreground "red")))
-  "Use this face to highlight the ZERO WIDTH SPACE character."
-  :group 'org-extra-emphasis-faces)
-
-(defcustom org-extra-emphasis-zws-display-char ?\N{SPACING UNDERSCORE}
-  "Use the glyph of this character to display ZERO WIDTH SPACE.
-
-Set this to nil, if you want the ZERO WIDTH SPACE to remain
-inconspicuous in the buffer.  Note that even if ZERO WIDTH SPACE
-is inconspicuos in the buffer, the ZERO WIDTH SPACE will be
-stripped from the export output accoding to the value of
-`org-extra-emphasis-intraword-emphasis-mode'."
-  :type '(choice (const :tag "Disabled" nil)
-		 (character :tag "Display ZERO WIDTH SPACE as "))
-  :group 'org-extra-emphasis)
-
-;;;; Internal Variables
-
-(defvar-local org-extra-emphasis-stashed-display-table nil
-  "Stashed value of `buffer-display-table'.
-
-This is the value of `buffer-display-table' before
-`org-extra-emphasis-intraword-emphasis-mode' is turned on in the
-buffer.
-
-Use this value to restore a buffer's `buffer-display-table' when
-`org-extra-emphasis-intraword-emphasis-mode' is turned off in the
-buffer.")
-
-;;;;  `M-x org-extra-emphasis-intraword-emphasis-mode'
-
-;;;###autoload
-(define-minor-mode org-extra-emphasis-intraword-emphasis-mode
-  "Toggle intra word emphasis in `org-mode' export.
-
-When `org-extra-emphasis-intraword-emphasis-mode' is enabled:
-
-- ZERO WIDTH SPACE characters are stripped from export backends.
-- ZERO WIDTH SPACE characters are displayed using
-  `org-extra-emphasis-zws-display-char' and highlighted with
-  `org-extra-emphasis-zws-face' space.
-
-TIPS for the user:
-
-1. You can insert ZERO WIDTH SPACE using
-
-       `M-x insert-char RET ZERO WIDTH SPACE RET'
-
-   One another way is to store that the ZERO WIDTH SPACE in a
-   register, say SPC, and
-
-       (set-register ?\N{SPACE} \"\N{ZERO WIDTH SPACE}\")
-       
-   and use the \\[insert-register] command on that register to insert
-   the ZERO WIDTH SPACE character.
-
-2. You can examine the presence of ZERO WIDTH SPACE character in the
-   export output by turning on the `glyphless-display-mode'."
-  :lighter " ZWS"
-  :init-value nil
-  :global t
-  :group 'org-extra-emphasis
-  (cond
-   ;; Turn ON `org-extra-emphasis-intraword-emphasis-mode'
-   (org-extra-emphasis-intraword-emphasis-mode
-    (when org-extra-emphasis-zws-display-char
-	    ;; Display ZERO WIDTH CHAR in a conspicuous way.
-	    (setq org-extra-emphasis-stashed-display-table (copy-sequence buffer-display-table))
-	    (unless buffer-display-table
-	      (setq buffer-display-table (make-display-table)))
-	    (aset buffer-display-table
-		  ?\N{ZERO WIDTH SPACE}
-		  (vector (make-glyph-code org-extra-emphasis-zws-display-char
-					   'org-extra-emphasis-zws-face)))))
-   (t
-    ;; Turn OFF `org-extra-emphasis-intraword-emphasis-mode'
-    (when org-extra-emphasis-zws-display-char
-      ;; Restore the buffer's original `buffer-display-table'.
-      (setq buffer-display-table org-extra-emphasis-stashed-display-table)))))
-
-;; Adjust `buffer-display-table' so that ZERO WIDTH SPACE characters
-;; are displayed.
-(add-hook 'org-mode-hook 'org-extra-emphasis-intraword-emphasis-mode t)
-
-;;;; Export hook to strip ZERO WIDTH SPACE
-
-(defun org-extra-emphasis-strip-zws-maybe (text _backend _info)
-  "Strip ZERO WIDTH SPACE from TEXT.
-
-If `org-extra-emphasis-intraword-emphasis-mode' is enabled, strip
-ZERO WIDTH SPACE from TEXT.  Otherwise, return TEXT unmodified."
-  (cond
-   ;; `org-extra-emphasis-intraword-emphasis-mode' is ON
-   (org-extra-emphasis-intraword-emphasis-mode
-    ;; Strip ZERO WIDTH SPACE.
-    (replace-regexp-in-string
-     (rx-to-string `(one-or-more ,(char-to-string ?\N{ZERO WIDTH SPACE})))
-     "" text t t))
-   ;; `org-extra-emphasis-intraword-emphasis-mode' is OFF.
-   (t
-    ;; Nothing to do.
-    text)))
-
-;; Configure Org Export Engine to strip ZERO WIDTH SPACE, if needed.
-;; (dolist (it '(org-export-filter-table-cell-functions
-;; 	      org-export-filter-paragraph-functions))
-;;   (add-to-list it 'org-extra-emphasis-strip-zws-maybe it))
-
-(provide 'org-extra-emphasis)
-
-;;; org-extra-emphasis.el ends here
tools/emacs/lisp/org-focus.el
@@ -1,49 +0,0 @@
-;; From http://www.howardism.org/Technical/Emacs/focused-work.html
-;; Write something a bit similar, but better ?
-
-(defvar vde/focus-timer nil "A timer reference for the vde/focus functions")
-
-(defun vde/focus-countdown-timer (minutes fun)
-  (let ((the-future (* minutes 60)))
-    (run-at-time the-future nil fun)))
-
-(defun vde/focus-begin ()
-  "Start a concerted, focused effort, ala Pomodoro Technique.
-We first clock into the current org-mode header (or last one),
-start some music to indicate we are working, and set a timer.
-
-Call `ha-focus-break' when finished."
-  (interactive)
-  (vde/focus-countdown-timer 25 'vde/focus-break)
-  (vde/focus--command "playerctl play-pause")
-  (vde/focus--command "notify-send 'Let's focus.'")
-  (vde/focus--command "swaync-client -d")
-  (if (eq major-mode 'org-mode)
-      (org-clock-in)
-    (org-clock-in-last)))
-
-(defun vde/focus-break ()
-  "Stop the focused time by stopping the music.
-This also starts another break timer, that calls
-`ha-focus-break-over' when finished."
-  (interactive)
-  (vde/focus-countdown-timer 5 'vde/focus-break-over)
-  (vde/focus--command "swaync-client -d")
-  (vde/focus--command "notify-send 'Let's take a break.'")
-  (vde/focus--command "playerctl play-pause")
-  (org-clock-out)
-  (message "Time to take a break."))
-
-(defun vde/focus-break-over ()
-  "Message me to know that the break time is over. Notice that
-this doesn't start anything automatically, as I may have simply
-wandered off."
-  (vde/focus--command "notify-send 'Break is over.'"))
-
-(defun vde/focus--command (command)
-  "Runs COMMAND by passing to the `command' command asynchronously."
-  (async-start-process "focus-os" "zsh" 'vde/focus--command-callback "-c" command))
-
-(defun vde/focus--command-callback (proc)
-  "Asynchronously called when the `osascript' process finishes."
-  (message "Finished calling command."))
tools/emacs/lisp/org-func.el
@@ -1,193 +0,0 @@
-;;; org-func.el --- -*- lexical-binding: t -*-
-;;
-
-;; https://endlessparentheses.com/updating-org-mode-include-statements-on-the-fly.html
-;;;###autoload
-(defun save-and-update-includes ()
-  "Update the line numbers of #+INCLUDE:s in current buffer.
-Only looks at INCLUDEs that have either :range-begin or :range-end.
-This function does nothing if not in `org-mode', so you can safely
-add it to `before-save-hook'."
-  (interactive)
-  (when (derived-mode-p 'org-mode)
-    (save-excursion
-      (goto-char (point-min))
-      (while (search-forward-regexp
-              "^\\s-*#\\+INCLUDE: *\"\\([^\"]+\\)\".*:range-\\(begin\\|end\\)"
-              nil 'noerror)
-        (let* ((file (expand-file-name (match-string-no-properties 1)))
-               lines begin end)
-          (forward-line 0)
-          (when (looking-at "^.*:range-begin *\"\\([^\"]+\\)\"")
-            (setq begin (match-string-no-properties 1)))
-          (when (looking-at "^.*:range-end *\"\\([^\"]+\\)\"")
-            (setq end (match-string-no-properties 1)))
-          (setq lines (decide-line-range file begin end))
-          (when lines
-            (if (looking-at ".*:lines *\"\\([-0-9]+\\)\"")
-                (replace-match lines :fixedcase :literal nil 1)
-              (goto-char (line-end-position))
-              (insert " :lines \"" lines "\""))))))))
-
-(defun decide-line-range (file begin end)
-  "Visit FILE and decide which lines to include.
-BEGIN and END are regexps which define the line range to use."
-  (let (l r)
-    (save-match-data
-      (with-temp-buffer
-        (insert-file-contents file)
-        (goto-char (point-min))
-        (if (null begin)
-            (setq l "")
-          (search-forward-regexp begin)
-          (setq l (line-number-at-pos (match-beginning 0))))
-        (if (null end)
-            (setq r "")
-          (search-forward-regexp end)
-          (setq r (1+ (line-number-at-pos (match-end 0)))))
-        (format "%s-%s" (+ l 1) (- r 1)))))) ;; Exclude wrapper
-
-(defun vde/get-outline-path (element)
-  "Return the outline path (as a list of titles) for ELEMENT, which is a headline."
-  (let (path)
-    (while (and element (eq (org-element-type element) 'headline))
-      (let ((title (org-element-property :title element)))
-        (when title
-          (push title path)))
-      (setq element (org-element-property :parent element)))
-    (reverse path)))
-
-;;;###autoload
-(defun vde/org-clock-in-any-heading ()
-  "Clock into any Org heading from `org-agenda-files' that is not DONE or CANCELED."
-  (interactive)
-  (let (headings)
-    (dolist (file org-agenda-files)
-      (when (file-exists-p file)
-        (with-current-buffer (find-file-noselect file)
-          (org-map-entries (lambda ()
-                              (let* ((element (org-element-context))
-                                     (todo (org-element-property :todo-keyword element)))
-                                (when (not (member todo '("DONE" "CANCELED")))
-                                  (let* ((path (vde/get-outline-path element)))
-                                    (push (list :path path
-                                                :file (buffer-file-name)
-                                                :position (point))
-                                          headings)))))
-                           t 'file))))
-    (let* (candidates)
-      (dolist (h headings)
-        (let* ((path (plist-get h :path))
-               (path-str (mapconcat 'identity path " > "))
-               (file (plist-get h :file))
-               (candidate (format "%s : %s" path-str (file-name-nondirectory file)))
-               (data (list file (plist-get h :position))))
-          (push (cons candidate data) candidates)))
-      (let* ((selected-candidate (completing-read "Select heading: " candidates))
-             (matching (cl-find-if (lambda (c) (string= (car c) selected-candidate)) candidates)))
-        (when matching
-          (let* ((data (cdr matching))
-                 (file (car data))
-                 (pos (cadr data)))
-            (find-file file)
-            (goto-char pos)
-            (org-clock-in)))))))
-
-;;;###autoload
-(defun vde/org-next-visible-heading-or-link (&optional arg)
-  "Move to the next visible heading or link, whichever comes first.
-With prefix ARG and the point on a heading(link): jump over subsequent
-headings(links) to the next link(heading), respectively.  This is useful
-to skip over a long series of consecutive headings(links)."
-  (interactive "P")
-  (let ((next-heading (save-excursion
-                        (org-next-visible-heading 1)
-                        (when (org-at-heading-p) (point))))
-        (next-link (save-excursion
-                     (when (vde/org-next-visible-link) (point)))))
-    (when arg
-      (if (and (org-at-heading-p) next-link)
-          (setq next-heading nil)
-        (if (and (looking-at org-link-any-re) next-heading)
-            (setq next-link nil))))
-    (cond
-     ((and next-heading next-link) (goto-char (min next-heading next-link)))
-     (next-heading (goto-char next-heading))
-     (next-link (goto-char next-link)))))
-
-;;;###autoload
-(defun vde/org-previous-visible-heading-or-link (&optional arg)
-  "Move to the previous visible heading or link, whichever comes first.
-With prefix ARG and the point on a heading(link): jump over subsequent
-headings(links) to the previous link(heading), respectively.  This is useful
-to skip over a long series of consecutive headings(links)."
-  (interactive "P")
-  (let ((prev-heading (save-excursion
-                        (org-previous-visible-heading 1)
-                        (when (org-at-heading-p) (point))))
-        (prev-link (save-excursion
-                     (when (vde/org-next-visible-link t) (point)))))
-    (when arg
-      (if (and (org-at-heading-p) prev-link)
-          (setq prev-heading nil)
-        (if (and (looking-at org-link-any-re) prev-heading)
-            (setq prev-link nil))))
-    (cond
-     ((and prev-heading prev-link) (goto-char (max prev-heading prev-link)))
-     (prev-heading (goto-char prev-heading))
-     (prev-link (goto-char prev-link)))))
-
-;; Adapted from org-next-link to only consider visible links
-;;;###autoload
-(defun vde/org-next-visible-link (&optional search-backward)
-  "Move forward to the next visible link.
-When SEARCH-BACKWARD is non-nil, move backward."
-  (interactive)
-  (let ((pos (point))
-        (search-fun (if search-backward #'re-search-backward
-                      #'re-search-forward)))
-    ;; Tweak initial position: make sure we do not match current link.
-    (cond
-     ((and (not search-backward) (looking-at org-link-any-re))
-      (goto-char (match-end 0)))
-     (search-backward
-      (pcase (org-in-regexp org-link-any-re nil t)
-        (`(,beg . ,_) (goto-char beg)))))
-    (catch :found
-      (while (funcall search-fun org-link-any-re nil t)
-        (let ((folded (org-invisible-p nil t)))
-          (when (or (not folded) (eq folded 'org-link))
-            (let ((context (save-excursion
-                             (unless search-backward (forward-char -1))
-                             (org-element-context))))
-              (pcase (org-element-lineage context '(link) t)
-                (link
-                 (goto-char (org-element-property :begin link))
-                 (throw :found t)))))))
-      (goto-char pos)
-      ;; No further link found
-      nil)))
-
-;;;###autoload
-(defun vde/org-shifttab (&optional arg)
-  "Move to the previous visible heading or link.
-If already at a heading, move first to its beginning.  When inside a table,
-move to the previous field."
-  (interactive "P")
-  (cond
-   ((org-at-table-p) (call-interactively #'org-table-previous-field))
-   ((and (not (bolp)) (org-at-heading-p)) (beginning-of-line))
-   (t (call-interactively #'vde/org-previous-visible-heading-or-link))))
-
-;;;###autoload
-(defun vde/org-tab (&optional arg)
-  "Move to the next visible heading or link.
-When inside a table, re-align the table and move to the next field."
-  (interactive)
-  (cond
-   ((org-at-table-p) (org-table-justify-field-maybe)
-    (call-interactively #'org-table-next-field))
-   (t (call-interactively #'vde/org-next-visible-heading-or-link))))
-
-(provide 'org-func)
-;;; org-func.el ends here
tools/emacs/lisp/org-menu.el
@@ -1,989 +0,0 @@
-;;; org-menu.el --- A discoverable menu for org-mode using transient -*- lexical-binding: t -*-
-;;
-;; Copyright 2021  Jan Rehders
-;;
-;; Author: Jan Rehders <nospam@sheijk.net>
-;; Version: 0.1alpha
-;; Package-Requires: ((emacs "26.1") (transient "0.1"))
-;; URL: https://github.com/sheijk/org-menu
-;;
-;; This file is free software; you can redistribute it and/or modify
-;; it under the terms of the GNU General Public License as published by
-;; the Free Software Foundation; either version 2, or (at your option)
-;; any later version.
-;;
-;; This file is distributed in the hope that it will be useful,
-;; but WITHOUT ANY WARRANTY; without even the implied warranty of
-;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-;; GNU General Public License for more details.
-;;
-;; You should have received a copy of the GNU General Public License
-;; along with GNU Emacs; see the file COPYING.  If not, write to
-;; the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-;; Boston, MA 02111-1307, USA.
-;;
-;;; Commentary:
-;;
-;; Usage:
-;;
-;; Add this to your ~/.emacs to bind the menu to `C-c m':
-;;
-;; (with-eval-after-load 'org
-;;   (require 'org-menu) ;; not needed if installing by package manager
-;;   (define-key org-mode-map (kbd "C-c m") #'org-menu))
-;;
-;; The menu should be pretty self-explanatory.  It is context dependent and
-;; offers different commands for headlines, tables, timestamps, etc.
-;; The task menu provides entry points for task that work from anywhere.
-
-;;; Code:
-
-(require 'org)
-(require 'transient)
-(require 'org-capture)
-(require 'org-timer)
-(require 'cl-lib)
-
-(defgroup org-menu nil
-  "Options for `org-menu'."
-  :group 'org)
-
-(defcustom org-menu-use-q-for-quit t
-  "Whether to add a q binding to quit to all menus.
-
-Use this if you prefer to be consistent with magit.  It will also
-change some other bindings to use Q instead of q."
-  :type 'boolean)
-
-(defcustom org-menu-global-toc-depth 10
-  "The number of heading levels to show when displaying the global content."
-  :type 'natnum)
-
-(defcustom org-menu-expand-snippet-function #'org-menu-expand-snippet-default
-  "The function used to expand a snippet.
-
-See `org-menu-expand-snippet-default' for a list of snippet ids
-which need to be supported.  `org-menu-expand-snippet-yasnippet'
-shows how to invoke snippets."
-  :type 'function)
-
-(defun org-menu-show-columns-view-options-p ()
-  "Return whether `org-columns' mode is active."
-  (bound-and-true-p org-columns-overlays))
-
-(defun org-menu-show-heading-options-p ()
-  "Whether to show commands operating on headings."
-  (unless (org-menu-show-columns-view-options-p)
-    (org-at-heading-p)))
-
-(defun org-menu-show-table-options-p ()
-  "Whether to show commands operating on tables."
-  (unless (org-menu-show-columns-view-options-p)
-    (org-at-table-p)))
-
-(defun org-menu-show-list-options-p ()
-  "Whether to show commands operating on lists."
-  (unless (org-menu-show-columns-view-options-p)
-    (org-at-item-p)))
-
-(defun org-menu-show-text-options-p ()
-  "Whether to show commands operating on text."
-  (not (or (org-menu-show-columns-view-options-p)
-           (org-at-heading-p)
-           (org-at-table-p)
-           (org-in-item-p)
-           (org-in-src-block-p))))
-
-(defun org-menu-show-src-options-p ()
-  "Whether to show commands operating on src blocks."
-  (unless (org-menu-show-columns-view-options-p)
-    (org-in-src-block-p)))
-
-(defun org-menu-show-link-options-p ()
-  "Whether to show commands operating on links.
-
-Conditions have been adapted from `org-insert-link'"
-  (unless (org-menu-show-columns-view-options-p)
-    (or
-     ;; Use variable from org-compat to support Emacs 26
-     (org-in-regexp (symbol-value 'org-bracket-link-regexp) 1)
-     (when (boundp 'org-link-angle-re)
-       (org-in-regexp org-link-angle-re))
-     (when (boundp 'org-link-plain-re)
-       (org-in-regexp org-link-plain-re)))))
-
-(defun org-menu-show-timestamp-options-p ()
-  "Whether to show commands operating on timestamps."
-  (unless (org-menu-show-columns-view-options-p)
-    (org-at-timestamp-p 'lax)))
-
-(defun org-menu-show-footnote-options-p ()
-  "Whether to show commands operating on footnotes."
-  (unless (org-menu-show-columns-view-options-p)
-    (or (org-footnote-at-definition-p)
-        (org-footnote-at-reference-p))))
-
-(defun org-menu-heading-navigate-items (check-for-heading &optional cycle-function)
-  "Items to navigate headings.
-
-These will be added to most sub menus.  If `CHECK-FOR-HEADING' is
-true the items will only be added if on a heading.  `CYCLE-FUNCTION' is the
-function to be used to cycle visibility of current element."
-  (setq cycle-function (or cycle-function #'org-cycle))
-  `(["Navigate"
-     :pad-keys t
-     ,@(and check-for-heading '(:if org-menu-show-heading-options-p))
-     ("p" "prev" org-previous-visible-heading :transient t)
-     ("n" "next" org-next-visible-heading :transient t)
-     ("c" "cycle" ,cycle-function :transient t)
-     ("u" "parent" outline-up-heading :transient t)
-     ("M-p" "prev (same level)" org-backward-heading-same-level :transient t)
-     ("M-n" "next (same level)" org-forward-heading-same-level :transient t)
-     ("M-w" "store link" org-store-link :transient t :if-not region-active-p)
-     ("C-_" "undo" undo :transient t)]))
-
-(defun org-menu-expand-snippet-default (snippet-id)
-  "Insert a fixed text for each `SNIPPET-ID'."
-  (pcase snippet-id
-    ('block (insert "#+BEGIN:\n#+END:\n"))
-    ('option (insert "#+"))
-    ('subscript (insert "a_b"))
-    ('superscript (insert "a^b"))
-    ('plot
-     (insert
-      "#+plot: type:2d file:\"plot.svg\"
-| A |  B |
-|---+----|
-| 1 | 10 |
-| 2 |  8 |
-| 3 |  9 |
-
-#+attr_org: :width 400px
-[[file:plot.svg]]
-"))
-    (_ (error "Unknown snippet type %s" snippet-id))))
-
-(autoload 'yas-expand-snippet "yasnippet")
-(autoload 'yas-expand-from-trigger-key "yasnippet")
-
-(defun org-menu-expand-snippet-yasnippet (snippet-id)
-  "Expand a yasnippet for each `SNIPPET-ID'."
-  (unless (require 'yasnippet nil 'noerror)
-    (error "Yasnippet not installed, could not expand %s" snippet-id))
-  (pcase snippet-id
-    ('block
-     (insert "beg")
-     (yas-expand-from-trigger-key))
-    ('option
-     (insert "opt")
-     (yas-expand-from-trigger-key))
-    ('subscript
-     (yas-expand-snippet "${1:text}_{${2:sub}}"))
-    ('superscript
-     (yas-expand-snippet "${1:text}^{${2:super}}"))
-    ('plot
-     (yas-expand-snippet
-      "#+plot: type:${1:2d} file:\"${2:plot.svg}\"
-| A |  B |
-|---+----|
-| 1 | 10 |
-| 2 |  8 |
-| 3 |  9 |
-
-#+attr_org: :width ${3:400px}
-[[file:$2]]
-"))
-    (_
-     (error "Unknown snippet type %s" snippet-id))))
-
-;; If yasnippet gets loaded it will be used automatically
-(with-eval-after-load 'yasnippet
-  (unless (equal org-menu-expand-snippet-function #'org-menu-expand-snippet-default)
-    (setq org-menu-expand-snippet-function #'org-menu-expand-snippet-yasnippet)))
-
-(defun org-menu-expand-snippet (snippet-id)
-  "Will expand the given snippet named `SNIPPET-ID' with `ARGS'."
-  (funcall org-menu-expand-snippet-function snippet-id))
-
-(defun org-menu-show-headline-content ()
-  "Will show the complete content of the current headline and it's children."
-  (interactive)
-  (save-excursion
-    (outline-hide-subtree)
-    (with-no-warnings
-      (org-show-children 4))
-    (org-goto-first-child)
-    (org-reveal '(4))))
-
-;;;###autoload (autoload 'org-menu-visibility "org-menu" nil t)
-(transient-define-prefix org-menu-visibility ()
-  "A menu to control visibility of `org-mode' items."
-  ["Visibility"
-   ["Heading"
-    ("a" "all" org-show-subtree :if-not org-at-block-p :transient t)
-    ("a" "all" org-hide-block-toggle :if org-at-block-p :transient t)
-    ("c" "cycle" org-cycle :transient t)
-    ("t" "content" org-menu-show-headline-content :if-not org-at-block-p :transient t)
-    ("h" "hide" outline-hide-subtree :if-not org-at-block-p :transient t)
-    ("h" "hide" org-hide-block-toggle :if org-at-block-p :transient t)
-    ("r" "reveal" (lambda () (interactive) (org-reveal t)) :if-not org-at-block-p :transient t)]
-   ["Global"
-    :pad-keys t
-    ("C" "cycle global" org-global-cycle :transient t)
-    ("go" "overview" org-overview)
-    ("gt" "content" (lambda () (interactive) (org-content org-menu-global-toc-depth)))
-    ("ga" "all" org-show-all)
-    ("gd" "default" (lambda () (interactive) (org-set-startup-visibility)))]
-   ["Narrow"
-    :pad-keys t
-    ("nn" "toggle" org-toggle-narrow-to-subtree)
-    ("nb" "to block" org-narrow-to-block :if org-at-block-p)
-    ("ns" "to sub tree" org-narrow-to-subtree)
-    ("ne" "to element" org-narrow-to-element)
-    ("w" "widen" widen)]
-   ["Quit"
-    :if-non-nil org-menu-use-q-for-quit
-    ("q" "quit" transient-quit-all)]])
-
-(transient-define-prefix org-menu-visibility-columns ()
-  "A menu to control visibility of `org-mode' items in `org-columns' mode."
-  ["Visibility"
-   ["Columns view"
-    :if org-menu-show-columns-view-options-p
-    ("t" "content" org-columns-content :transient t)
-    ("o" "overview" org-overview :transient t)
-    ("g" "refresh" org-columns-redo :transient t)]
-   ["Quit"
-    :if-non-nil org-menu-use-q-for-quit
-    ("q" "quit" transient-quit-all)]])
-
-(defun org-menu-eval-src-items ()
-  "Return the items to evaluate a source block."
-  (list
-   ["Source"
-    :if org-menu-show-src-options-p
-    ("e" "run block" org-babel-execute-src-block)
-    ("c" "check headers" org-babel-check-src-block)
-    ("k" "clear results" org-babel-remove-result-one-or-many)
-    ("'" "edit" org-edit-special)]))
-
-;;;###autoload (autoload 'org-menu-eval "org-menu" nil t)
-(transient-define-prefix org-menu-eval ()
-  "A menu to evaluate buffers, tables, etc. in `org-mode'."
-  ["dummy"])
-
-(defun org-menu-run-gnuplot ()
-  "Will call `org-plot/gnuplot' and update inline images."
-  (interactive)
-  (org-plot/gnuplot)
-  (when org-inline-image-overlays
-    (org-redisplay-inline-images)))
-
-(transient-insert-suffix 'org-menu-eval (list 0)
-  `["Evaluation"
-    ["Table"
-     :if org-at-table-p
-     ("e" "table" (lambda () (interactive) (org-table-recalculate 'iterate)))
-     ("1" "one iteration" (lambda () (interactive) (org-table-recalculate t)))
-     ("l" "line" (lambda () (interactive) (org-table-recalculate nil)))
-     ("f" "format" org-table-align :if org-at-table-p)]
-    ,@(org-menu-eval-src-items)
-    ["Heading"
-     :if-not org-in-src-block-p
-     ("c" "update checkbox count" org-update-checkbox-count)]
-    ["Plot"
-     ("p" "gnuplot" org-menu-run-gnuplot)]
-    ["Export"
-     ("t" "tangle source files" org-babel-tangle)
-     ("x" "export" org-export-dispatch)]
-    ["Quit"
-     :if-non-nil org-menu-use-q-for-quit
-     ("q" "quit" transient-quit-all)]])
-
-(defun org-menu-insert-block (str)
-  "Insert an org mode block of type `STR'."
-  (interactive)
-  (insert (format "#+begin_%s\n#+end_%s\n" str str)))
-
-(defun org-menu-insert-horizontal-rule ()
-  "Insert a horizontal rule."
-  (interactive)
-  (insert "-----"))
-
-;;;###autoload (autoload 'org-menu-insert-blocks "org-menu" nil t)
-(transient-define-prefix org-menu-insert-blocks ()
-  "A menu to insert new blocks in `org-mode'."
-  [["Insert block"
-    ("s" "source" (lambda () (interactive) (org-menu-insert-block "src")))
-    ("e" "example" (lambda () (interactive) (org-menu-insert-block "example")))
-    ("v" "verbatim" (lambda () (interactive) (org-menu-insert-block "verbatim")))
-    ("a" "ascii" (lambda () (interactive) (org-menu-insert-block "ascii")))
-    ("q" "quote" (lambda () (interactive) (org-menu-insert-block "quote")) :if-nil org-menu-use-q-for-quit)
-    ("Q" "quote" (lambda () (interactive) (org-menu-insert-block "quote")) :if-non-nil org-menu-use-q-for-quit)
-    ("d" "dynamic block" org-dynamic-block-insert-dblock)]
-   ["Quit"
-    :if-non-nil org-menu-use-q-for-quit
-    ("q" "quit" transient-quit-all)]])
-
-;;;###autoload (autoload 'org-menu-insert-heading "org-menu" nil t)
-(transient-define-prefix org-menu-insert-heading ()
-  "A menu to insert new headings in `org-mode'."
-  [["Heading"
-    ("h" "heading" org-insert-heading)
-    ("H" "heading (after)" org-insert-heading-after-current)
-    ("T" "todo" org-insert-todo-heading)]
-   ["Items"
-    ("d" "drawer" org-insert-drawer)]
-   ["Quit"
-    :if-non-nil org-menu-use-q-for-quit
-    ("q" "quit" transient-quit-all)]])
-
-;;;###autoload (autoload 'org-menu-insert-template "org-menu" nil t)
-(transient-define-prefix org-menu-insert-template ()
-  "A menu to insert new templates in `org-mode'."
-  [["Templates"
-    ("S" "structure template" org-insert-structure-template)
-    ("B" "blocks" (lambda () (interactive) (org-menu-expand-snippet 'block)))
-    ("O" "options" (lambda () (interactive) (org-menu-expand-snippet 'option)))]
-   ["Quit"
-    :if-non-nil org-menu-use-q-for-quit
-    ("q" "quit" transient-quit-all)]])
-
-;;;###autoload (autoload 'org-menu-insert-timestamp "org-menu" nil t)
-(transient-define-prefix org-menu-insert-timestamp ()
-  "A menu to insert timestamps in Org Mode."
-  [["Active"
-    ("." "Time stamp" org-time-stamp)
-    ("t" "Today" (lambda () (interactive) (org-insert-time-stamp (current-time) nil nil)))
-    ("n" "Today + time" (lambda () (interactive) (org-insert-time-stamp (current-time) t nil)))]
-   ["Inactive"
-    ("!" "Time stamp (i)" org-time-stamp-inactive)
-    ("T" "Today (i)" (lambda () (interactive) (org-insert-time-stamp (current-time) nil t)))
-    ("N" "Today + time (i)" (lambda () (interactive) (org-insert-time-stamp (current-time) t t)))]
-   ["Quit"
-    :if-non-nil org-menu-use-q-for-quit
-    ("q" "quit" transient-quit-all)]])
-
-(defun org-menu-table-insert-row-below ()
-  "Insert a new table column below point."
-  (interactive)
-  (org-table-insert-row '4))
-
-(defun org-menu-table-insert-column-left ()
-  "Insert a new column to the left of point."
-  (interactive)
-  (org-table-insert-column)
-  (org-table-move-column-right))
-
-;;;###autoload (autoload 'org-menu-insert-table "org-menu" nil t)
-(transient-define-prefix org-menu-insert-table ()
-  "A menu to insert table items in `org-mode'."
-  [["Table"
-    ("t" "table" org-table-create-or-convert-from-region :if-not org-at-table-p)
-    ("i" "import" org-table-import :if-not org-at-table-p)]
-   ["Rows/columns"
-    :if org-at-table-p
-    ("r" "row above" org-table-insert-row :transient t)
-    ("R" "row below" org-menu-table-insert-row-below :transient t)
-    ("c" "column left" org-table-insert-column :transient t)
-    ("C" "column right" org-menu-table-insert-column-left :transient t)
-    ("-" "horiz. line" org-table-insert-hline :transient t)]
-   ["Quit"
-    :if-non-nil org-menu-use-q-for-quit
-    ("q" "quit" transient-quit-all)]])
-
-(defun org-menu-insert-superscript ()
-  "Insert a text with superscript."
-  (interactive)
-  (org-menu-expand-snippet 'superscript))
-
-(defun org-menu-insert-subscript ()
-  "Insert a text with subscript."
-  (interactive)
-  (org-menu-expand-snippet 'subscript))
-
-(defun org-menu-parse-formatting (format-char)
-  "Will return the bounds of the format markup `FORMAT-CHAR'."
-  (let ((original-point (point))
-        start end)
-    (ignore-errors
-      (save-excursion
-        (save-restriction
-          (save-match-data
-            (org-narrow-to-element)
-            (goto-char (search-backward (format "%c" format-char)))
-            (setq start (point))
-            (goto-char original-point)
-            (goto-char (search-forward (format "%c" format-char)))
-            (setq end (point))
-            (cons start end)))))))
-
-(defun org-menu-toggle-format (format-char)
-  "Will either remove `FORMAT-CHAR' or add it around region/point."
-  (let ((range (org-menu-parse-formatting format-char))
-        (format-string (format "%c" format-char)))
-    (if (null range)
-        (org-menu-insert-text format-string format-string t)
-      (goto-char (cdr range))
-      (delete-char -1)
-      (goto-char (car range))
-      (delete-char 1))))
-
-;;;###autoload (autoload 'org-menu-insert-list "org-menu" nil t)
-(transient-define-prefix org-menu-insert-list ()
-  "A menu to insert lists."
-  [["List"
-    ("-" "item" (lambda () (interactive) (insert "- ")))
-    ("+" "+" (lambda () (interactive) (insert "+ ")))
-    ("*" "*" (lambda () (interactive) (insert "* ")))
-    ("." "1." (lambda () (interactive) (insert "1. ")))
-    (")" "1)" (lambda () (interactive) (insert "1) ")))]
-   ["Todo"
-    ("t" "todo" (lambda () (interactive) (insert "- [ ] ")))
-    ("d" "done" (lambda () (interactive) (insert "- [X] ")))
-    ("p" "partial" (lambda () (interactive) (insert "- [-] ")))]
-   ["Quit"
-    :if-non-nil org-menu-use-q-for-quit
-    ("q" "quit" transient-quit-all)]])
-
-(defun org-menu-insert-plot ()
-  "Insert a small example plot for `gnu-plot'."
-  (interactive)
-  (beginning-of-line 1)
-  (org-menu-expand-snippet 'plot))
-
-(defun org-menu-insert-option-line-smart (line)
-  "Insert `LINE'.  If inside a block move to right before it."
-  (beginning-of-line 1)
-  (insert line "\n"))
-
-(defun org-menu-insert-name (name)
-  "Insert a #+NAME for the next element."
-  (interactive "MName? ")
-  (org-menu-insert-option-line-smart (format "#+NAME: %s" name)))
-
-(defun org-menu-insert-caption (caption)
-  "Insert a #+CAPTION for the next element."
-  (interactive "MCaption? ")
-  (org-menu-insert-option-line-smart (format "#+CAPTION: %s" caption)))
-
-(defun org-menu-insert-startup-setting (setting)
-  "Insert a buffer `SETTING'."
-  (interactive (list (completing-read "Startup setting? "
-                                (mapcar 'car org-startup-options))))
-  (org-menu-insert-option-line-smart (format "#+STARTUP: %s" setting)))
-
-(defun org-menu-insert-buffer-setting (setting)
-  "Insert a buffer `SETTING'."
-  (interactive (list (completing-read "Buffer setting? " org-options-keywords)))
-  (insert (format "#+%s " setting)))
-
-(defun org-menu-insert-footnote-definition (name definition)
-  "Insert a definition for a footnote.
-
-Named `NAME' using `DEFINITION'."
-  (interactive "MName? \nMDefinition? ")
-  (org-menu-insert-option-line-smart (format "[fn:%s] %s" name definition)))
-
-(defun org-menu-insert-footnote-inline (name definition)
-  "Insert a definition for an inline footnote.
-
-Named `NAME' with `DEFINITION'."
-  (interactive "MName? \nMDefinition? ")
-  (insert (format "[fn:%s: %s]" name definition)))
-
-;;;###autoload (autoload 'org-menu-insert "org-menu" nil t)
-(transient-define-prefix org-menu-insert ()
-  "A menu to insert new items in `org-mode'."
-  ["Insert"
-   ["Element"
-    ("." "time" org-menu-insert-timestamp)
-    ("l" "link (new)" org-insert-link)
-    ("L" "link (stored)" org-insert-last-stored-link :transient t)
-    ("T" "templates" org-menu-insert-template)]
-   ["Structure"
-    ("h" "heading" org-menu-insert-heading)
-    ("-" "list" org-menu-insert-list)
-    ("H" "hor. rule" org-menu-insert-horizontal-rule)]
-   ["Block/table"
-    ("b" "block" org-menu-insert-blocks)
-    ("t" "table" org-menu-insert-table)
-    ("p" "plot" org-menu-insert-plot)]
-   ["Format"
-    ("^" "superscript" org-menu-insert-superscript)
-    ("_" "subscript" org-menu-insert-subscript)]
-   ["Footnotes"
-    ("fd" "define" org-menu-insert-footnote-definition)
-    ("fi" "inline" org-menu-insert-footnote-inline)]
-   ["Options"
-    ("n" "name" org-menu-insert-name)
-    ("c" "caption" org-menu-insert-caption)
-    ("s" "startup option" org-menu-insert-startup-setting)
-    ("o" "buffer option" org-menu-insert-buffer-setting)]
-   ["Quit"
-    :if-non-nil org-menu-use-q-for-quit
-    ("q" "quit" transient-quit-all)]])
-
-(defun org-menu-comment-line ()
-  "Toggle line comment w/o moving cursor."
-  (interactive)
-  (save-excursion (comment-line 1)))
-
-(defun org-menu-fix-timestamp ()
-  "Fix the timestamp at `(point)'."
-  (interactive)
-  (org-timestamp-change 0 'day))
-
-(defun org-menu-insert-text (left right &optional surround-whitespace)
-  "Will insert left|right and put the curser at |.
-
-If region is active it will be surrounded by `LEFT' and `RIGHT' and
-the point will be at end of region.  Will add spaces before/after text if
-`SURROUND-WHITESPACE' is true and it's needed."
-  (let ((start (point))
-        (end (point)))
-    (when (region-active-p)
-      (setq start (region-beginning)
-            end (region-end))
-      (deactivate-mark))
-    (when (> start end)
-      (cl-psetq start end
-                end start))
-
-    (goto-char start)
-    (when (and surround-whitespace
-               (not (bolp))
-               (not (looking-back " +" nil)))
-      (insert " "))
-    (insert left)
-
-    (forward-char (- end start))
-
-    (save-excursion
-      (insert right)
-      (when (and surround-whitespace
-                 (not (eolp))
-                 (not (looking-at " +")))
-        (insert " ")))))
-
-;;;###autoload (autoload 'org-menu-goto "org-menu" nil t)
-(transient-define-prefix org-menu-goto ()
-  "Menu to go to different places by name."
-  [["Go to"
-    ("h" "heading" imenu)
-    ("s" "source block" org-babel-goto-named-src-block)
-    ("r" "result block" org-babel-goto-named-result)
-    ("." "calendar" org-goto-calendar :if org-menu-show-timestamp-options-p)]
-   ["Quit"
-    :if-non-nil org-menu-use-q-for-quit
-    ("q" "quit" transient-quit-all)]])
-
-(defun org-menu-toggle-zwspace ()
-  "Will remove zero-width space before/after point or insert it if none found."
-  (interactive)
-  (let ((zww (string ?\N{ZERO WIDTH SPACE})))
-    (save-excursion
-      (skip-chars-backward zww)
-      (if (looking-at (rx (+ (literal zww))))
-      (replace-match "")
-    (insert zww)))))
-
-(defun org-menu-text-format-items (check-for-table)
-  "Items to format text.
-
-Will add an ':if org-menu-show-text-options-p' criteria if
-`CHECK-FOR-TABLE' is true."
-  (list
-   `["Navigate"
-     ,@(when check-for-table '(:if org-menu-show-text-options-p))
-     :pad-keys t
-     ("p" "up" previous-line :transient t)
-     ("n" "down" next-line :transient t)
-     ("b" "left" backward-word :transient t)
-     ("f" "right" forward-word :transient t)
-     ("u" "parent" org-up-element :transient t)
-     ("M-w" "store link" org-store-link :transient t :if-not region-active-p)
-     ("C-_" "undo" undo :transient t)
-     ("SPC" "mark" set-mark-command :transient t)
-     ("C-x C-x" "exchange" exchange-point-and-mark :transient t)]
-   `["Formatting"
-     ,@(when check-for-table '(:if org-menu-show-text-options-p))
-     :pad-keys t
-     ("*" "Bold" (lambda nil (interactive) (org-menu-toggle-format ?*)) :transient t)
-     ("/" "italic" (lambda nil (interactive) (org-menu-toggle-format ?/)) :transient t)
-     ("_" "underline" (lambda nil (interactive) (org-menu-toggle-format ?_)) :transient t)
-     ("+" "strikethrough" (lambda nil (interactive) (org-menu-toggle-format ?+)) :transient t)
-     ("S-SPC" "zero-width space" org-menu-toggle-zwspace :transient t)]
-   `["Source"
-     ,@(when check-for-table '(:if org-menu-show-text-options-p))
-     ("~" "code" (lambda nil (interactive) (org-menu-toggle-format ?~)) :transient t)
-     ("=" "verbatim" (lambda nil (interactive) (org-menu-toggle-format ?=)) :transient t)]))
-
-;;;###autoload (autoload 'org-menu-text-in-element "org-menu" nil t)
-(transient-define-prefix org-menu-text-in-element ()
-  "Add formatting for text inside other elements like lists and tables."
-  ["dummy"])
-
-(transient-insert-suffix 'org-menu-text-in-element (list 0)
-  `[,@(org-menu-text-format-items nil)
-    ["Quit"
-     :if-non-nil org-menu-use-q-for-quit
-     ("q" "quit" transient-quit-all)]])
-
-;;;###autoload (autoload 'org-menu-options "org-menu" nil t)
-(transient-define-prefix org-menu-options ()
-  "A menu to toggle options."
-  [["Display"
-    ("l" "show links" org-toggle-link-display)
-    ("i" "inline images" org-toggle-inline-images)
-    ("p" "pretty entities" org-toggle-pretty-entities)
-    ("I" "indent by level" org-indent-mode)
-    ("t" "timestamp overlay" org-toggle-time-stamp-overlays)
-    ("n" "numbered headings" org-num-mode)]
-   ["Quit"
-    :if-non-nil org-menu-use-q-for-quit
-    ("q" "quit" transient-quit-all)]])
-
-(defun org-menu-toggle-has-checkbox ()
-  "Toggle whether the current list item has a checkbox."
-  (interactive)
-  (save-excursion
-    (back-to-indentation)
-    (if (not (looking-at "- "))
-        (message "Not at list item")
-      (end-of-line 1)
-      (org-ctrl-c-ctrl-c '(4)))))
-
-(defun org-menu-is-timer-running ()
-  "Return whether a timer is currently running."
-  (and org-timer-start-time
-       (not org-timer-countdown-timer)
-       (not org-timer-pause-time)))
-
-(defun org-menu-is-timer-paused ()
-  "Return whether a timer has been started and is paused."
-  (and org-timer-start-time
-       (not org-timer-countdown-timer)
-       org-timer-pause-time))
-
-;;;###autoload (autoload 'org-menu-clock "org-menu" nil t)
-(transient-define-prefix org-menu-clock ()
-  "Time management using org-modes clock."
-  [["Clock"
-    :pad-keys t
-    ("<tab>" "in" org-clock-in :if-not org-clock-is-active)
-    ("TAB" "in" org-clock-in :if-not org-clock-is-active)
-    ("o" "out" org-clock-out :if org-clock-is-active)
-    ("j" "goto" org-clock-goto :if org-clock-is-active)
-    ("q" "cancel" org-clock-cancel
-     :if (lambda () (and (not org-menu-use-q-for-quit)
-                         (org-clock-is-active))))
-    ("Q" "cancel" org-clock-cancel
-     :if (lambda () (and org-menu-use-q-for-quit
-                         (org-clock-is-active))))
-    ("d" "display" org-clock-display :if org-clock-is-active)
-    ("x" "in again" org-clock-in-last :if-not org-clock-is-active)
-    ("z" "resolve" org-resolve-clocks)]
-   ["Timer"
-    ("0" "start" org-timer-start :if-nil org-timer-start-time)
-    ("_" "stop" org-timer-stop :if-non-nil org-timer-start-time)
-    ("." "insert" org-timer :if-non-nil org-timer-start-time)
-    ("-" "... item" org-timer-item :if-non-nil org-timer-start-time)
-    ("," "pause" org-timer-pause-or-continue :if org-menu-is-timer-running)
-    ("," "continue" org-timer-pause-or-continue :if org-menu-is-timer-paused)
-    (";" "countdown" org-timer-set-timer :if-nil org-timer-start-time)]
-   ["Effort"
-    ("e" "set effort" org-set-effort)
-    ("E" "increase" org-inc-effort)]
-   ["Quit"
-    :if-non-nil org-menu-use-q-for-quit
-    ("q" "quit" transient-quit-all)]])
-
-(defun org-menu-columns-globally ()
-  "Turn on `org-columns' globally."
-  (interactive)
-  (org-columns t))
-
-(transient-define-prefix org-menu-search-and-filter ()
-  "A menu to search and filter `org-mode' documents."
-  ["Search and filter"
-   ["Filter"
-    ("/" "only matching" org-sparse-tree)
-    ("q" "tags" org-tags-sparse-tree :if-nil org-menu-use-q-for-quit)
-    ("Q" "tags" org-tags-sparse-tree :if-non-nil org-menu-use-q-for-quit)
-    ("t" "todos" org-show-todo-tree)
-    ("d" "deadlines" org-check-deadlines)
-    ("r" "remove highlights" org-remove-occur-highlights :if-non-nil org-occur-highlights)]
-   ["Dates"
-    ("b" "before" org-check-before-date)
-    ("a" "after" org-check-after-date)
-    ("D" "range" org-check-dates-range)]
-   ["Views"
-    ("A" "agenda" org-agenda)
-    ("c" "columns" org-columns :if-nil org-columns-current-fmt)
-    ("c" "columns off" org-columns-quit :if-non-nil org-columns-current-fmt)
-    ("gc" "whole buffer" org-menu-columns-globally :if-nil org-columns-current-fmt)]
-   ["Quit"
-    :if-non-nil org-menu-use-q-for-quit
-    ("q" "quit" transient-quit-all)]])
-
-(transient-define-prefix org-menu-attachments ()
-  "A menu to manage attachments."
-  ["Attachments"
-   ["Add"
-    ("a" "file" org-attach-attach)
-    ("c" "copy" org-attach-attach-cp)
-    ("m" "move" org-attach-attach-mv)
-    ("l" "link" org-attach-attach-ln)
-    ("y" "symlink" org-attach-attach-lns)
-    ("u" "download" org-attach-url)
-    ("b" "buffer" org-attach-buffer)
-    ("n" "new" org-attach-new)]
-   ["Open"
-    ("o" "attachment" org-attach-open)
-    ("O" "in Emacs" org-attach-open-in-emacs)
-    ("f" "directory" org-attach-reveal)
-    ("F" "in Emacs" org-attach-reveal-in-emacs)]
-   ["Delete"
-    ("d" "delete" org-attach-delete-one)
-    ("D" "all" org-attach-delete-all)]
-   ["More"
-    ("s" "set directory" org-attach-set-directory)
-    ("S" "unset" org-attach-unset-directory)
-    ("z" "synchronize" org-attach-sync)]]
-  (interactive)
-  (require 'org-attach)
-  (transient-setup 'org-menu-attachments))
-
-(transient-define-prefix org-menu-archive ()
-  "A menu to archive items."
-  ["dummy"])
-
-(defun org-menu-force-cycle-archived ()
-  "Wrapper around deprecated `org-force-cycle-archived' to fix warning."
-  (interactive)
-  (with-no-warnings
-    (org-force-cycle-archived)))
-
-(transient-insert-suffix 'org-menu-archive (list 0)
-  `["Archive"
-    ,@(org-menu-heading-navigate-items nil #'org-menu-force-cycle-archived)
-    ["Archive to"
-     ("t" "tree" org-archive-subtree :transient t)
-     ("s" "sibling" org-archive-to-archive-sibling :transient t)
-     ("Q" "tag" org-toggle-archive-tag :transient t)]])
-
-(defun org-menu-insert-todo-heading-after-current ()
-  "Insert a new todo heading with same level as current, after subtree."
-  (interactive)
-  (org-insert-todo-heading '(16)))
-
-;;;###autoload (autoload 'org-menu "org-menu" nil t)
-(transient-define-prefix org-menu ()
-  "A discoverable menu to edit and view `org-mode' documents."
-  ["dummy"])
-
-(transient-insert-suffix 'org-menu (list 0)
-  `["Org mode"
-    ;; Items for headings
-    ,@(org-menu-heading-navigate-items t)
-
-    ["Move heading"
-     :if org-menu-show-heading-options-p
-     ("P" "up" org-metaup :transient t)
-     ("N" "down" org-metadown :transient t)
-     ("B" "left" org-shiftmetaleft :transient t)
-     ("F" "right" org-shiftmetaright :transient t)
-     ("b" "left (line)" org-metaleft :transient t)
-     ("f" "right (line)" org-metaright :transient t)
-     ("r" "refile" org-refile :transient t)]
-    ["Change heading"
-     :if org-menu-show-heading-options-p
-     ("*" "toggle" org-ctrl-c-star :if-not org-at-table-p :transient t)
-     ("t" "todo" org-todo :transient t)
-     ("q" "tags" org-set-tags-command :transient t :if-nil org-menu-use-q-for-quit)
-     ("Q" "tags" org-set-tags-command :transient t :if-non-nil org-menu-use-q-for-quit)
-     ("y" "property" org-set-property :transient t)
-     ("," "priority" org-priority :transient t)
-     ("A" "archive" org-menu-archive :transient t)
-     ("D" "deadline" org-deadline :transient t)
-     ("S" "schedule" org-schedule :transient t)
-     ("/" "comment" org-toggle-comment :transient t)
-     ("mn" "add note" org-add-note)]
-    ["Make new/delete"
-     :if org-menu-show-heading-options-p
-     :pad-keys t
-     ("mh" "make heading (before)" org-insert-heading)
-     ("mH" "make heading (after)" org-insert-heading-after-current)
-     ("mt" "make todo (before)" org-insert-todo-heading)
-     ("mT" "make todo (after)" org-menu-insert-todo-heading-after-current)
-     ("mc" "clone with time shift" org-clone-subtree-with-time-shift)
-     ("dh" "delete heading" org-cut-subtree :transient t)
-     ("dy" "delete property" org-delete-property :transient t)
-     ("a" "attachments" org-menu-attachments)
-     ("C-w" "cut tree" org-cut-special :transient t)
-     ("C-y" "yank tree" org-paste-special :transient t)]
-
-    ;; Items for tables
-    ["Navigate"
-     :if org-menu-show-table-options-p
-     :pad-keys t
-     ("p" "up" previous-line :transient t)
-     ("n" "down" next-line :transient t)
-     ("b" "left" org-table-previous-field :transient t)
-     ("f" "right" org-table-next-field :transient t)
-     ("u" "parent" outline-up-heading :transient t)
-     ("M-w" "store link" org-store-link :transient t :if-not region-active-p)
-     ("C-_" "undo" undo :transient t)]
-    ["Move r/c"
-     :if org-menu-show-table-options-p
-     ("P" "up" org-table-move-row-up :transient t)
-     ("N" "down" org-table-move-row-down :transient t)
-     ("B" "left" org-table-move-column-left :transient t)
-     ("F" "right" org-table-move-column-right :transient t)]
-    ["Field"
-     :if org-menu-show-table-options-p
-     :pad-keys t
-     ("'" "edit" org-table-edit-field)
-     ("SPC" "blank" org-table-blank-field :transient t)
-     ("RET" "from above" org-table-copy-down :transient t)
-     ("t" "text formatting" org-menu-text-in-element)]
-    ["Formulas"
-     :if org-menu-show-table-options-p
-     ("E" "edit all" org-table-edit-formulas :transient t)
-     ("=" "field" (lambda () (interactive) (org-table-eval-formula '(4))) :transient t)
-     ("+" "in place" (lambda () (interactive) (org-table-eval-formula '(16))))
-     ("c" "column" org-table-eval-formula :transient t)
-     ("h" "coordinates" org-table-toggle-coordinate-overlays :transient t)
-     ("D" "debug" org-table-toggle-formula-debugger :transient t)]
-    ["Table"
-     :if org-menu-show-table-options-p
-     :pad-keys t
-     ("dr" "delete row" org-shiftmetaup :transient t)
-     ("dc" "delete column" org-shiftmetaleft :transient t)
-     ("m" "make" org-menu-insert-table)
-     ,@(when (fboundp (function org-table-toggle-column-width))
-         ;; This will emit a warning during byte compilation. We can ignore it
-         (list '("S" "shrink column" org-table-toggle-column-width :transient t)))
-     ("r" "sort" org-table-sort-lines :transient t)
-     ("M-w" "copy rect" org-table-copy-region :transient t :if region-active-p)
-     ("C-w" "cut rect" org-table-cut-region :transient t :if region-active-p)
-     ("C-y" "yank rect" org-table-paste-rectangle :transient t)]
-
-    ;; Items for lists
-    ["Navigate"
-     :if org-menu-show-list-options-p
-     :pad-keys t
-     ("p" "prev" previous-line :transient t)
-     ("n" "next" next-line :transient t)
-     ("c" "cycle" org-cycle :transient t)
-     ("u" "parent" org-up-element :transient t)
-     ("M-p" "prev (same level)" org-backward-element :transient t)
-     ("M-n" "next (same level)" org-forward-element :transient t)
-     ("M-w" "store link" org-store-link :transient t :if-not region-active-p)
-     ("C-_" "undo" undo :transient t)]
-    ["Move list"
-     :if org-menu-show-list-options-p
-     ("P" "up" org-metaup :transient t)
-     ("N" "down" org-metadown :transient t)
-     ("B" "left" org-shiftmetaleft :transient t)
-     ("F" "right" org-shiftmetaright :transient t)
-     ("b" "left (line)" org-metaleft :transient t)
-     ("f" "right (line)" org-metaright :transient t)]
-    ["List"
-     :if org-menu-show-list-options-p
-     ("R" "repair" org-list-repair)
-     ("*" "turn into tree" org-list-make-subtree)
-     ("S" "sort" org-sort-list :transient t)
-     ("t" "text formatting" org-menu-text-in-element)]
-    ["Toggle"
-     :if org-menu-show-list-options-p
-     ("-" "list item" org-toggle-item :if-not org-at-table-p :transient t)
-     ("+" "list style" org-cycle-list-bullet :if-not org-at-table-p :transient t)
-     ("d" "done" org-toggle-checkbox :transient t)
-     ("h" "half-done"
-      (lambda () (interactive) (org-toggle-checkbox '(16)))
-      :transient t)
-     ("m" "checkbox" org-menu-toggle-has-checkbox :transient t)]
-
-    ;; Items for text
-    ,@(org-menu-text-format-items t)
-    ["Line"
-     :if org-menu-show-text-options-p
-     :pad-keys t
-     (":" "fixed width" org-toggle-fixed-width :transient t)
-     (";" "comment" org-menu-comment-line :transient t)
-     ("--" "list" org-toggle-item :transient t)
-     ("-*" "heading" org-ctrl-c-star :transient t)]
-
-    ;; Items for source blocks
-    ,@(org-menu-eval-src-items)
-
-    ["Link"
-     :if org-menu-show-link-options-p
-     ("e" "edit" org-insert-link :transient t)]
-
-    ["Timestamp"
-     :if org-menu-show-timestamp-options-p
-     ("." "type" org-toggle-timestamp-type :transient t)
-     ("e" "edit" org-time-stamp :transient t)
-     ("R" "repair" org-menu-fix-timestamp :transient t)]
-
-    ["Footnote"
-     :if org-menu-show-footnote-options-p
-     ("ed" "delete" (lambda () (interactive) (org-footnote-delete)))
-     ("es" "sort" (lambda () (interactive) (org-footnote-sort)))
-     ("er" "renumber" (lambda () (interactive) (org-footnote-renumber-fn:N)))
-     ("eS" "sort+renumber" (lambda () (interactive)
-                (org-footnote-renumber-fn:N)
-                (org-footnote-sort)))
-     ("en" "normalize" (lambda () (interactive) (org-footnote-normalize)))]
-
-    ;; Items for column view
-    ["Navigate"
-     :if org-menu-show-columns-view-options-p
-     :pad-keys t
-     ("p" "prev" org-columns-move-up :transient t)
-     ("n" "next" org-columns-move-down :transient t)
-     ("f" "forward" forward-char :transient t)
-     ("b" "backward" backward-char :transient t)
-     ("M-w" "store link" org-store-link :transient t :if-not region-active-p)
-     ("C-_" "undo" undo :transient t)]
-    ["Value"
-     :if org-menu-show-columns-view-options-p
-     :pad-keys t
-     ("e" "edit" org-columns-edit-value :transient t)
-     ("V" "show" org-columns-show-value :transient t)
-     ("M-n" "next" org-columns-next-allowed-value :transient t)
-     ("M-p" "previous" org-columns-previous-allowed-value :transient t)
-     ("a" "edit allowed" org-columns-edit-allowed :transient t)]
-    ["Column"
-     :if org-menu-show-columns-view-options-p
-     :pad-keys t
-     ("E" "edit column" org-columns-edit-attributes :transient t)
-     ("{" "narrow" org-columns-narrow :transient t)
-     ("}" "widen" org-columns-widen :transient t)
-     ("M-<right>" "move right" org-columns-move-right :transient t)
-     ("M-<left>" "move left" org-columns-move-left :transient t)
-     ("M-S-<right>" "new" org-columns-new :transient t)
-     ("M-S-<left>" "delete" org-columns-delete :transient t)]
-
-    ["Tasks"
-     ("v" "visibility" org-menu-visibility :if-not org-menu-show-columns-view-options-p)
-     ("v" "visibility" org-menu-visibility-columns :if org-menu-show-columns-view-options-p)
-     ("x" "evaluation" org-menu-eval)
-     ("i" "insert" org-menu-insert)
-     ("g" "go to" org-menu-goto)
-     ("s" "search" org-menu-search-and-filter)
-     ("o" "options" org-menu-options)
-     ("C" "clock (active)" org-menu-clock :if org-clock-is-active)
-     ("C" "clock" org-menu-clock :if-not org-clock-is-active)
-     ,@(when (fboundp #'org-capture-finalize)
-         (list '("C-c C-c" "confirm capture" org-capture-finalize :if-non-nil org-capture-mode)))
-     ,@(when (fboundp #'org-capture-kill)
-         (list '("C-c C-k" "abort capture" org-capture-kill :if-non-nil org-capture-mode)))
-     ""
-     ("q" "quit" transient-quit-all :if-non-nil org-menu-use-q-for-quit)]])
-
-(provide 'org-menu)
-;;; org-menu.el ends here
tools/emacs/lisp/org-protocol-capture-html.el
@@ -1,280 +0,0 @@
-;;; org-protocol-capture-html.el --- Capture HTML with org-protocol
-
-;; URL: https://github.com/alphapapa/org-protocol-capture-html
-;; Version: 0.1-pre
-;; Package-Requires: ((emacs "24.4"))
-
-;;; Commentary:
-
-;; This package captures Web pages into Org-mode using Pandoc to
-;; process HTML.  It can also use eww's eww-readable functionality to
-;; get the main content of a page.
-
-;; These are the helper functions that run in Emacs.  To capture pages
-;; into Emacs, you can use either a browser bookmarklet or the
-;; org-protocol-capture-html.sh shell script.  See the README.org file
-;; for instructions.
-
-;;; License:
-
-;; This program is free software; you can redistribute it and/or modify
-;; it under the terms of the GNU General Public License as published by
-;; the Free Software Foundation, either version 3 of the License, or
-;; (at your option) any later version.
-
-;; This program is distributed in the hope that it will be useful,
-;; but WITHOUT ANY WARRANTY; without even the implied warranty of
-;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-;; GNU General Public License for more details.
-
-;; You should have received a copy of the GNU General Public License
-;; along with this program.  If not, see <http://www.gnu.org/licenses/>.
-
-;;; Code:
-
-;;;; Require
-
-(require 'org-protocol)
-(require 'cl-lib)
-(require 'subr-x)
-(require 's)
-
-;;;; Vars
-
-(defcustom org-protocol-capture-html-demote-times 1
-  "How many times to demote headings in captured pages.
-You may want to increase this if you use a sub-heading in your capture template."
-  :group 'org-protocol-capture-html :type 'integer)
-
-;;;; Test Pandoc
-
-(defconst org-protocol-capture-html-pandoc-no-wrap-option nil
-  ;; Set this so it won't be unbound
-  "Option to pass to Pandoc to disable wrapping.
-Pandoc >= 1.16 deprecates `--no-wrap' in favor of
-`--wrap=none'.")
-
-(defun org-protocol-capture-html--define-pandoc-wrap-const ()
-  "Set `org-protocol-capture-html-pandoc-no-wrap-option'."
-  (setq org-protocol-capture-html-pandoc-no-wrap-option
-        ;; Pandoc >= 1.16 deprecates the --no-wrap option, replacing it with
-        ;; --wrap=none.  Sending the wrong option causes output to STDERR,
-        ;; which `call-process-region' doesn't like.  So we test Pandoc to see
-        ;; which option to use.
-        (with-temp-buffer
-          (let* ((process (start-process "test-pandoc" (current-buffer) "pandoc" "--dump-args" "--no-wrap"))
-                 (limit 3)
-                 (checked 0))
-            (while (process-live-p process)
-              (if (= checked limit)
-                  (progn
-                    ;; Pandoc didn't exit in time.  Kill it and raise
-                    ;; an error.  This function will return `nil' and
-                    ;; `org-protocol-capture-html-pandoc-no-wrap-option'
-                    ;; will remain `nil', which will cause this
-                    ;; function to run again and set the const when a
-                    ;; capture is run.
-                    (set-process-query-on-exit-flag process nil)
-                    (error "Unable to test Pandoc!  Please report this bug! (include the output of \"pandoc --dump-args --no-wrap\")"))
-                (sleep-for 0.2)
-                (cl-incf checked)))
-            (if (and (zerop (process-exit-status process))
-                     (not (string-match "--no-wrap is deprecated" (buffer-string))))
-                "--no-wrap"
-              "--wrap=none")))))
-
-;;;; Direct-to-Pandoc
-
-(defun org-protocol-capture-html--with-pandoc (data)
-  "Process an org-protocol://capture-html:// URL using DATA.
-
-This function is basically a copy of `org-protocol-do-capture', but
-it passes the captured content (not the URL or title) through
-Pandoc, converting HTML to Org-mode."
-
-  ;; It would be nice to not basically duplicate
-  ;; `org-protocol-do-capture', but passing the data back to that
-  ;; function would require re-encoding the data into a URL string
-  ;; with Emacs after Pandoc converts it.  Since we've already split
-  ;; it up, we might as well go ahead and run the capture directly.
-
-  (unless org-protocol-capture-html-pandoc-no-wrap-option
-    (org-protocol-capture-html--define-pandoc-wrap-const))
-
-  (let* ((template (or (plist-get data :template)
-                       org-protocol-default-template-key))
-         (url (org-protocol-sanitize-uri (plist-get data :url)))
-         (type (if (string-match "^\\([a-z]+\\):" url)
-                   (match-string 1 url)))
-         (title (or (org-protocol-capture-html--nbsp-to-space (string-trim (plist-get data :title))) ""))
-         (content (or (org-protocol-capture-html--nbsp-to-space (string-trim (plist-get data :body))) ""))
-         (orglink (org-make-link-string
-                   url (if (string-match "[^[:space:]]" title) title url)))
-         (org-capture-link-is-already-stored t)) ; avoid call to org-store-link
-
-    (setq org-stored-links
-          (cons (list url title) org-stored-links))
-    (kill-new orglink)
-
-    (with-temp-buffer
-      (insert content)
-      (if (not (zerop (call-process-region
-                       (point-min) (point-max)
-                       "pandoc" t t nil "-f" "html" "-t" "org" org-protocol-capture-html-pandoc-no-wrap-option)))
-          (message "Pandoc failed: %s" (buffer-string))
-        (progn
-          ;; Pandoc succeeded
-          (org-store-link-props :type type
-                                :annotation orglink
-                                :link url
-                                :description title
-                                :orglink orglink
-                                :initial (buffer-string)))))
-    (org-protocol-capture-html--do-capture)
-    nil))
-
-(add-to-list 'org-protocol-protocol-alist
-             '("capture-html"
-               :protocol "capture-html"
-               :function org-protocol-capture-html--with-pandoc
-               :kill-client t))
-
-;;;; eww-readable
-
-(defvar url-http-end-of-headers)
-
-(eval-when-compile
-  ;; eww-readable only works on Emacs >=25.1, but I think it's better
-  ;; to check for the actual symbols.  I think using
-  ;; `eval-when-compile' is the right way to do this, but I'm not
-  ;; sure.
-  (when (and (require 'eww nil t)
-             (require 'dom nil t)
-             (fboundp 'eww-score-readability))
-
-    (defun org-protocol-capture-html--capture-eww-readable (data)
-      "Capture content of URL with eww-readable.."
-
-      (unless org-protocol-capture-html-pandoc-no-wrap-option
-        (org-protocol-capture-html--define-pandoc-wrap-const))
-
-      (let* ((template (or (plist-get data :template)
-                           org-protocol-default-template-key))
-             (url (org-protocol-sanitize-uri (plist-get data :url)))
-             (type (if (string-match "^\\([a-z]+\\):" url)
-                       (match-string 1 url)))
-             (html (org-protocol-capture-html--url-html url))
-             (result (org-protocol-capture-html--eww-readable html))
-             (title (cdr result))
-             (content (with-temp-buffer
-                        (insert (org-protocol-capture-html--nbsp-to-space (car result)))
-                        ;; Convert to Org with Pandoc
-                        (unless (= 0 (call-process-region (point-min) (point-max)
-                                                          "pandoc" t t nil "-f" "html" "-t" "org"
-                                                          org-protocol-capture-html-pandoc-no-wrap-option))
-                          (error "Pandoc failed"))
-                        (save-excursion
-                          ;; Remove DOS CR/LF line endings
-                          (goto-char (point-min))
-                          (while (search-forward (string ?\C-m) nil t)
-                            (replace-match "")))
-                        ;; Demote page headings in capture buffer to below the
-                        ;; top-level Org heading and "Article" 2nd-level heading
-                        (save-excursion
-                          (goto-char (point-min))
-                          (while (re-search-forward (rx bol (1+ "*") (1+ space)) nil t)
-                            (beginning-of-line)
-                            (insert "**")
-                            (end-of-line)))
-                        (buffer-string)))
-             (orglink (org-make-link-string
-                       url (if (s-present? title) title url)))
-             ;; Avoid call to org-store-link
-             (org-capture-link-is-already-stored t))
-
-        (setq org-stored-links
-              (cons (list url title) org-stored-links))
-        (kill-new orglink)
-
-        (org-store-link-props :type type
-                              :annotation orglink
-                              :link url
-                              :description title
-                              :orglink orglink
-                              :initial content)
-        (org-protocol-capture-html--do-capture)
-        nil))
-
-    (add-to-list 'org-protocol-protocol-alist
-                 '("capture-eww-readable"
-                   :protocol "capture-eww-readable"
-                   :function org-protocol-capture-html--capture-eww-readable
-                   :kill-client t))
-
-    (defun org-protocol-capture-html--url-html (url)
-      "Return HTML from URL as string."
-      (let* ((response-buffer (url-retrieve-synchronously url nil t))
-             (encoded-html (with-current-buffer response-buffer
-                             (pop-to-buffer response-buffer)
-                             ;; Skip HTTP headers, using marker provided by url-http
-                             (delete-region (point-min) (1+ url-http-end-of-headers))
-                             (buffer-string))))
-        (kill-buffer response-buffer)     ; Not sure if necessary to avoid leaking buffer
-        (with-temp-buffer
-          ;; For some reason, running `decode-coding-region' in the
-          ;; response buffer has no effect, so we have to do it in a
-          ;; temp buffer.
-          (insert encoded-html)
-          (condition-case nil
-              ;; Fix undecoded text
-              (decode-coding-region (point-min) (point-max) 'utf-8)
-            (coding-system-error nil))
-          (buffer-string))))
-
-    (defun org-protocol-capture-html--eww-readable (html)
-      "Return `eww-readable' part of HTML with title.
-Returns list (HTML . TITLE)."
-      ;; Based on `eww-readable'
-      (let* ((html
-              ;; Convert "&nbsp;" in HTML to plain spaces.
-              ;; `libxml-parse-html-region' turns them into
-              ;; underlines.  The closest I can find to an explanation
-              ;; is at <http://www.perlmonks.org/?node_id=825188>.
-              (org-protocol-capture-html--nbsp-to-space html))
-             (dom (with-temp-buffer
-                    (insert html)
-                    (libxml-parse-html-region (point-min) (point-max))))
-             (title (cl-caddr (car (dom-by-tag dom 'title)))))
-        (eww-score-readability dom)
-        (cons (with-temp-buffer
-                (shr-dom-print (eww-highest-readability dom))
-                (buffer-string))
-              title)))))
-
-;;;; Helper functions
-
-(defun org-protocol-capture-html--nbsp-to-space (s)
-  "Convert HTML non-breaking spaces to plain spaces in S."
-  ;; Not sure why sometimes these are in the HTML and Pandoc converts
-  ;; them to underlines instead of spaces, but this fixes it.
-  (replace-regexp-in-string (rx "&nbsp;") " " s t t))
-
-(with-no-warnings
-  ;; Ignore warning about the dynamically scoped `template' variable.
-  (defun org-protocol-capture-html--do-capture ()
-    "Call `org-capture' and demote page headings in capture buffer."
-    (raise-frame)
-    (funcall 'org-capture nil template)
-
-    ;; Demote page headings in capture buffer to below the
-    ;; top-level Org heading
-    (save-excursion
-      (goto-char (point-min))
-      (re-search-forward (rx bol "*" (1+ space)) nil t) ; Skip 1st heading
-      (while (re-search-forward (rx bol "*" (1+ space)) nil t)
-        (dotimes (n org-protocol-capture-html-demote-times)
-          (org-demote-subtree))))))
-
-(provide 'org-protocol-capture-html)
-
-;;; org-protocol-capture-html.el ends here
tools/emacs/lisp/org-review.el
@@ -1,263 +0,0 @@
-;;; org-review.el --- Schedule reviews for Org entries
-;;
-;; Copyright (C) 2024 Alan Schmitt
-;;
-;; Author: Alan Schmitt <alan.schmitt@polytechnique.org>
-;; URL: https://github.com/brabalan/org-review
-;; Version: 0.3
-;; Keywords: calendar
-
-;; This file is not part of GNU Emacs.
-
-;; This program is free software; you can redistribute it and/or modify
-;; it under the terms of the GNU General Public License as published by
-;; the Free Software Foundation; either version 3, or (at your option)
-;; any later version.
-;;
-;; This program is distributed in the hope that it will be useful, but
-;; WITHOUT ANY WARRANTY; without even the implied warranty of
-;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-;; General Public License for more details.
-;;
-;; You should have received a copy of the GNU General Public License
-;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>.
-;;
-;;; Commentary:
-;;
-;; This allows to schedule reviews of org entries.
-;;
-;; Entries will be scheduled for review if their NEXT_REVIEW or their
-;; LAST_REVIEW property is set. The next review date is the
-;; NEXT_REVIEW date, if it is present, otherwise it is computed from
-;; the LAST_REVIEW property and the REVIEW_DELAY period, such as
-;; "+1m". If REVIEW_DELAY is absent, a default period is used. Note
-;; that the LAST_REVIEW property is not considered as inherited, but
-;; REVIEW_DELAY is, allowing to set it for whole subtrees.
-;;
-;; Checking of review dates is done through an agenda view, using the
-;; `org-review-agenda-skip' skipping function. This function is based
-;; on `org-review-toreview-p', that returns `nil' if no review is
-;; necessary (no review planned or it happened recently), otherwise it
-;; returns the date the review was first necessary (NEXT_REVIEW, or
-;; LAST_REVIEW + REVIEW_DELAY, if it is in the past).
-;;
-;; To mark an entry as reviewed, use the function
-;; `org-review-insert-last-review' to set the LAST_REVIEW date to the
-;; current date. If `org-review-sets-next-date' is set (which is the
-;; default), this function also computes the date of the next review
-;; and inserts it as NEXT_REVIEW.
-;;
-;; Example use.
-;;
-;; 1 - To display the things to review in the agenda.
-;;
-;;   (setq org-agenda-custom-commands (quote ( ...
-;;        ("R" "Review projects" tags-todo "-CANCELLED/"
-;;         ((org-agenda-overriding-header "Reviews Scheduled")
-;;         (org-agenda-skip-function 'org-review-agenda-skip)
-;;         (org-agenda-cmp-user-defined 'org-review-compare)
-;;         (org-agenda-sorting-strategy '(user-defined-down)))) ... )))
-;;
-;; 2 - To set a key binding to review from the agenda
-;;
-;;   (add-hook 'org-agenda-mode-hook (lambda () (local-set-key (kbd "C-c
-;;        C-r") 'org-review-insert-last-review)))
-
-;;; Changes
-;;
-;; 2022-04-11: systematically insert name of week day in date
-;; 2016-08-18: better detection of org-agenda buffers
-;; 2014-05-08: added the ability to specify next review dates
-
-;; TODO
-;; - be able to specify a function to run when marking an item reviewed
-
-;;; Code:
-
-(require 'org)
-(require 'org-agenda)
-
-;;; User variables:
-
-(defgroup org-review nil
-  "Org review scheduling."
-  :tag "Org Review Schedule"
-  :group 'org)
-
-(defcustom org-review-last-timestamp-format 'naked
-  "Timestamp format for last review properties."
-  :type '(radio (const naked)
-                (const inactive)
-                (const active))
-  :group 'org-review)
-
-(defcustom org-review-next-timestamp-format 'naked
-  "Timestamp format for last review properties."
-  :type '(radio (const naked)
-                (const inactive)
-                (const active))
-  :group 'org-review)
-
-(defcustom org-review-last-property-name "LAST_REVIEW"
-  "The name of the property for the date of the last review."
-  :type 'string
-  :group 'org-review)
-
-(defcustom org-review-delay-property-name "REVIEW_DELAY"
-  "The name of the property for setting the delay before the next review."
-  :type 'string
-  :group 'org-review)
-
-(defcustom org-review-next-property-name "NEXT_REVIEW"
-  "The name of the property for setting the date of the next review."
-  :type 'string
-  :group 'org-review)
-
-(defcustom org-review-delay "+1m"
-  "Time span between the date of last review and the next one.
-The default value for this variable (\"+1m\") means that entries
-will be marked for review one month after their last review.
-
-If the review delay cannot be retrieved from the entry or the
-subtree above, this delay is used."
-  :type 'string
-  :group 'org-review)
-
-(defcustom org-review-sets-next-date t
-  "Indicates whether marking a project as reviewed automatically
-sets the next NEXT_REVIEW according to the current date and
-REVIEW_DELAY."
-  :type 'boolean
-  :group 'org-review)
-
-;;; Functions:
-
-(defun org-review-last-planned (last delay)
-  "Computes the next planned review, given the LAST review
-date (in string format) and the review DELAY (in string
-format)."
-  (let ((lt (org-read-date nil t last))
-        (ct (current-time)))
-    (time-add lt (time-subtract (org-read-date nil t delay) ct))))
-
-;;;###autoload
-(defun org-review-last-review-prop (&optional pos)
-  "Return the value of the last review property of the headline
-at position POS, or the current headline if POS is not given."
-  (org-entry-get (or pos (point)) org-review-last-property-name))
-
-;;;###autoload
-(defun org-review-next-review-prop (&optional pos)
-  "Return the value of the review date property of the headline
-at position POS, or the current headline if POS is not given."
-  (org-entry-get (or pos (point)) org-review-next-property-name))
-
-(defun org-review-review-delay-prop (&optional pos)
-  "Return the value of the review delay property of the headline
-at position POS, or the current headline if POS is not given,
-considering inherited properties."
-  (org-entry-get (or pos (point)) org-review-delay-property-name t))
-
-(defun org-review-toreview-p (&optional pos)
-  "Check if the entry at point should be marked for review.
-Return nil if the entry does not need to be reviewed. Otherwise
-return the date when the entry was first scheduled to be
-reviewed.
-
-If there is a next review date, consider it. Otherwise, if there
-is a last review date, use it to compute the date of the next
-review (adding the value of the review delay property, or
-`org-review-delay' if there is no review delay property). If
-there is no next review date and no last review date, return
-nil."
-  (let* ((lp (org-review-last-review-prop pos))
-	 (np (org-review-next-review-prop pos))
-	 (nextreview
-	  (cond
-	   (np (org-read-date nil t np))
-	   (lp (org-review-last-planned
-		lp
-		(or (org-review-review-delay-prop pos)
-		    org-review-delay)))
-	   (t nil))))
-    (and nextreview
-	 (time-less-p nextreview (current-time))
-	 nextreview)))
-
-(defun org-review-insert-date (propname fmt date)
-  "Insert the DATE under property PROPNAME, in the format
-specified by FMT."
-  (org-entry-put
-   (if (equal major-mode 'org-agenda-mode)
-       (or (org-get-at-bol 'org-marker)
-	   (org-agenda-error))
-     (point))
-   propname
-   (cond
-    ((eq fmt 'inactive)
-     (concat "[" date "]"))
-    ((eq fmt 'active)
-     (concat "<" date ">"))
-    (t date))))
-
-;;;###autoload
-(defun org-review-insert-last-review (&optional prompt)
-  "Insert the current date as last review. If prefix argument:
-prompt the user for the date. If `org-review-sets-next-date' is
-set to t, also insert a next review date."
-  (interactive "P")
-  (let ((ts (if prompt
-                (format-time-string (car org-time-stamp-formats) (org-read-date nil t))
-              (format-time-string (car org-time-stamp-formats)))))
-    (org-review-insert-date org-review-last-property-name
-			    org-review-last-timestamp-format
-			    ts)
-    (when org-review-sets-next-date
-      (org-review-insert-date
-       org-review-next-property-name
-       org-review-next-timestamp-format
-       (format-time-string
-        (car org-time-stamp-formats)
-        (org-review-last-planned
-         ts
-         (or (org-review-review-delay-prop
-              (if (equal major-mode 'org-agenda-mode)
-                  (or (org-get-at-bol 'org-marker)
-                      (org-agenda-error))
-                (point)))
-             org-review-delay)))))))
-
-;;;###autoload
-(defun org-review-insert-next-review ()
-  "Prompt the user for the date of the next review, and insert
-it as a property of the headline."
-  (interactive)
-  (let ((ts (format-time-string (car org-time-stamp-formats) (org-read-date nil t))))
-    (org-review-insert-date org-review-next-property-name
-			    org-review-next-timestamp-format
-			    ts)))
-
-;;;###autoload
-(defun org-review-agenda-skip ()
-  "To be used as an argument of `org-agenda-skip-function' to
-skip entries that are not scheduled to be reviewed. This function
-does not move the point; it returns nil if the entry is to be
-kept, and the position to continue the search otherwise."
-  (and (not (org-review-toreview-p))
-       (org-with-wide-buffer (or (outline-next-heading) (point-max)))))
-
-(defun org-review-compare (a b)
-  "Compares the date of scheduled review for the two agenda
-entries, to be used with `org-agenda-cmp-user-defined'. Returns
-+1 if A has been scheduled for longer and -1 otherwise."
-  (let* ((ma (or (get-text-property 0 'org-marker a)
-                 (get-text-property 0 'org-hd-marker a)))
-         (mb (or (get-text-property 0 'org-marker b)
-                 (get-text-property 0 'org-hd-marker b)))
-	 (ra (org-review-toreview-p ma))
-	 (rb (org-review-toreview-p mb)))
-    (if (time-less-p ra rb) 1 -1)))
-
-(provide 'org-review)
-
-;;; org-review.el ends here
tools/emacs/lisp/ox-rss.el
@@ -1,414 +0,0 @@
-;;; ox-rss.el --- RSS 2.0 Back-End for Org Export Engine
-
-;; Copyright (C) 2013-2015  Bastien Guerry
-
-;; Author: Bastien Guerry <bzg@gnu.org>
-;; Keywords: org, wp, blog, feed, rss
-
-;; This file is not yet part of GNU Emacs.
-
-;; This program is free software: you can redistribute it and/or modify
-;; it under the terms of the GNU General Public License as published by
-;; the Free Software Foundation, either version 3 of the License, or
-;; (at your option) any later version.
-
-;; This program is distributed in the hope that it will be useful,
-;; but WITHOUT ANY WARRANTY; without even the implied warranty of
-;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-;; GNU General Public License for more details.
-
-;; You should have received a copy of the GNU General Public License
-;; along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.
-
-;;; Commentary:
-
-;; This library implements a RSS 2.0 back-end for Org exporter, based on
-;; the `html' back-end.
-;;
-;; It requires Emacs 24.1 at least.
-;;
-;; It provides two commands for export, depending on the desired output:
-;; `org-rss-export-as-rss' (temporary buffer) and `org-rss-export-to-rss'
-;; (as a ".xml" file).
-;;
-;; This backend understands two new option keywords:
-;;
-;; #+RSS_EXTENSION: xml
-;; #+RSS_IMAGE_URL: http://myblog.org/mypicture.jpg
-;;
-;; It uses #+HTML_LINK_HOME: to set the base url of the feed.
-;;
-;; Exporting an Org file to RSS modifies each top-level entry by adding a
-;; PUBDATE property.  If `org-rss-use-entry-url-as-guid', it will also add
-;; an ID property, later used as the guid for the feed's item.
-;;
-;; The top-level headline is used as the title of each RSS item unless
-;; an RSS_TITLE property is set on the headline.
-;;
-;; You typically want to use it within a publishing project like this:
-;;
-;; (add-to-list
-;;  'org-publish-project-alist
-;;  '("homepage_rss"
-;;    :base-directory "~/myhomepage/"
-;;    :base-extension "org"
-;;    :rss-image-url "http://lumiere.ens.fr/~guerry/images/faces/15.png"
-;;    :html-link-home "http://lumiere.ens.fr/~guerry/"
-;;    :html-link-use-abs-url t
-;;    :rss-extension "xml"
-;;    :publishing-directory "/home/guerry/public_html/"
-;;    :publishing-function (org-rss-publish-to-rss)
-;;    :section-numbers nil
-;;    :exclude ".*"            ;; To exclude all files...
-;;    :include ("index.org")   ;; ... except index.org.
-;;    :table-of-contents nil))
-;;
-;; ... then rsync /home/guerry/public_html/ with your server.
-;;
-;; By default, the permalink for a blog entry points to the headline.
-;; You can specify a different one by using the :RSS_PERMALINK:
-;; property within an entry.
-
-;;; Code:
-
-(require 'ox-html)
-(declare-function url-encode-url "url-util" (url))
-
-;;; Variables and options
-
-(defgroup org-export-rss nil
-  "Options specific to RSS export back-end."
-  :tag "Org RSS"
-  :group 'org-export
-  :version "24.4"
-  :package-version '(Org . "8.0"))
-
-(defcustom org-rss-image-url "http://orgmode.org/img/org-mode-unicorn-logo.png"
-  "The URL of the an image for the RSS feed."
-  :group 'org-export-rss
-  :type 'string)
-
-(defcustom org-rss-extension "xml"
-  "File extension for the RSS 2.0 feed."
-  :group 'org-export-rss
-  :type 'string)
-
-(defcustom org-rss-categories 'from-tags
-  "Where to extract items category information from.
-The default is to extract categories from the tags of the
-headlines.  When set to another value, extract the category
-from the :CATEGORY: property of the entry."
-  :group 'org-export-rss
-  :type '(choice
-	  (const :tag "From tags" from-tags)
-	  (const :tag "From the category property" from-category)))
-
-(defcustom org-rss-use-entry-url-as-guid t
-  "Use the URL for the <guid> metatag?
-When nil, Org will create ids using `org-icalendar-create-uid'."
-  :group 'org-export-rss
-  :type 'boolean)
-
-;;; Define backend
-
-(org-export-define-derived-backend 'rss 'html
-  :menu-entry
-  '(?r "Export to RSS"
-       ((?R "As RSS buffer"
-	    (lambda (a s v b) (org-rss-export-as-rss a s v)))
-	(?r "As RSS file" (lambda (a s v b) (org-rss-export-to-rss a s v)))
-	(?o "As RSS file and open"
-	    (lambda (a s v b)
-	      (if a (org-rss-export-to-rss t s v)
-		(org-open-file (org-rss-export-to-rss nil s v)))))))
-  :options-alist
-  '((:description "DESCRIPTION" nil nil newline)
-    (:keywords "KEYWORDS" nil nil space)
-    (:with-toc nil nil nil) ;; Never include HTML's toc
-    (:rss-extension "RSS_EXTENSION" nil org-rss-extension)
-    (:rss-image-url "RSS_IMAGE_URL" nil org-rss-image-url)
-    (:rss-categories nil nil org-rss-categories))
-  :filters-alist '((:filter-final-output . org-rss-final-function))
-  :translate-alist '((headline . org-rss-headline)
-		     (comment . (lambda (&rest args) ""))
-		     (comment-block . (lambda (&rest args) ""))
-		     (timestamp . (lambda (&rest args) ""))
-		     (plain-text . org-rss-plain-text)
-		     (section . org-rss-section)
-		     (template . org-rss-template)))
-
-;;; Export functions
-
-;;;###autoload
-(defun org-rss-export-as-rss (&optional async subtreep visible-only)
-  "Export current buffer to a RSS buffer.
-
-If narrowing is active in the current buffer, only export its
-narrowed part.
-
-If a region is active, export that region.
-
-A non-nil optional argument ASYNC means the process should happen
-asynchronously.  The resulting buffer should be accessible
-through the `org-export-stack' interface.
-
-When optional argument SUBTREEP is non-nil, export the sub-tree
-at point, extracting information from the headline properties
-first.
-
-When optional argument VISIBLE-ONLY is non-nil, don't export
-contents of hidden elements.
-
-Export is done in a buffer named \"*Org RSS Export*\", which will
-be displayed when `org-export-show-temporary-export-buffer' is
-non-nil."
-  (interactive)
-  (let ((file (buffer-file-name (buffer-base-buffer))))
-    (org-icalendar-create-uid file 'warn-user)
-    (org-rss-add-pubdate-property))
-  (org-export-to-buffer 'rss "*Org RSS Export*"
-    async subtreep visible-only nil nil (lambda () (text-mode))))
-
-;;;###autoload
-(defun org-rss-export-to-rss (&optional async subtreep visible-only)
-  "Export current buffer to a RSS file.
-
-If narrowing is active in the current buffer, only export its
-narrowed part.
-
-If a region is active, export that region.
-
-A non-nil optional argument ASYNC means the process should happen
-asynchronously.  The resulting file should be accessible through
-the `org-export-stack' interface.
-
-When optional argument SUBTREEP is non-nil, export the sub-tree
-at point, extracting information from the headline properties
-first.
-
-When optional argument VISIBLE-ONLY is non-nil, don't export
-contents of hidden elements.
-
-Return output file's name."
-  (interactive)
-  (let ((file (buffer-file-name (buffer-base-buffer))))
-    (org-icalendar-create-uid file 'warn-user)
-    (org-rss-add-pubdate-property))
-  (let ((outfile (org-export-output-file-name
-		  (concat "." org-rss-extension) subtreep)))
-    (org-export-to-file 'rss outfile async subtreep visible-only)))
-
-;;;###autoload
-(defun org-rss-publish-to-rss (plist filename pub-dir)
-  "Publish an org file to RSS.
-
-FILENAME is the filename of the Org file to be published.  PLIST
-is the property list for the given project.  PUB-DIR is the
-publishing directory.
-
-Return output file name."
-  (let ((bf (get-file-buffer filename)))
-    (if bf
-	  (with-current-buffer bf
-	    (org-icalendar-create-uid filename 'warn-user)
-	    (org-rss-add-pubdate-property)
-	    (write-file filename))
-      (find-file filename)
-      (org-icalendar-create-uid filename 'warn-user)
-      (org-rss-add-pubdate-property)
-      (write-file filename) (kill-buffer)))
-  (org-publish-org-to
-   'rss filename (concat "." org-rss-extension) plist pub-dir))
-
-;;; Main transcoding functions
-
-(defun org-rss-headline (headline contents info)
-  "Transcode HEADLINE element into RSS format.
-CONTENTS is the headline contents.  INFO is a plist used as a
-communication channel."
-  (unless (or (org-element-property :footnote-section-p headline)
-	      ;; Only consider first-level headlines
-	      (> (org-export-get-relative-level headline info) 1))
-    (let* ((author (and (plist-get info :with-author)
-			(let ((auth (plist-get info :author)))
-			  (and auth (org-export-data auth info)))))
-	   (htmlext (plist-get info :html-extension))
-	   (hl-number (org-export-get-headline-number headline info))
-	   (hl-home (file-name-as-directory (plist-get info :html-link-home)))
-	   (hl-pdir (plist-get info :publishing-directory))
-	   (hl-perm (org-element-property :RSS_PERMALINK headline))
-	   (anchor (org-export-get-reference headline info))
-	   (category (org-rss-plain-text
-		      (or (org-element-property :CATEGORY headline) "") info))
-	   (pubdate0 (org-element-property :PUBDATE headline))
-	   (pubdate (let ((system-time-locale "C"))
-		      (if pubdate0
-			  (format-time-string
-			   "%a, %d %b %Y %H:%M:%S %z"
-			   (org-time-string-to-time pubdate0)))))
-	   (title (or (org-element-property :RSS_TITLE headline)
-		      (replace-regexp-in-string
-		       org-bracket-link-regexp
-		       (lambda (m) (or (match-string 3 m)
-				  (match-string 1 m)))
-		       (org-element-property :raw-value headline))))
-	   (publink
-	    (or (and hl-perm (concat (or hl-home hl-pdir) hl-perm))
-		(concat
-		 (or hl-home hl-pdir)
-		 (file-name-nondirectory
-		  (file-name-sans-extension
-		   (plist-get info :input-file))) "." htmlext "#" anchor)))
-	   (guid (if org-rss-use-entry-url-as-guid
-		     publink
-		   (org-rss-plain-text
-		    (or (org-element-property :ID headline)
-			(org-element-property :CUSTOM_ID headline)
-			publink)
-		    info))))
-      (if (not pubdate0) "" ;; Skip entries with no PUBDATE prop
-	(format
-	 (concat
-	  "<item>\n"
-	  "<title>%s</title>\n"
-	  "<link>%s</link>\n"
-	  "<author>%s</author>\n"
-	  "<guid isPermaLink=\"false\">%s</guid>\n"
-	  "<pubDate>%s</pubDate>\n"
-	  (org-rss-build-categories headline info) "\n"
-	  "<description><![CDATA[%s]]></description>\n"
-	  "</item>\n")
-	 title publink author guid pubdate contents)))))
-
-(defun org-rss-build-categories (headline info)
-  "Build categories for the RSS item."
-  (if (eq (plist-get info :rss-categories) 'from-tags)
-      (mapconcat
-       (lambda (c) (format "<category><![CDATA[%s]]></category>" c))
-       (org-element-property :tags headline)
-       "\n")
-    (let ((c (org-element-property :CATEGORY headline)))
-      (format "<category><![CDATA[%s]]></category>" c))))
-
-(defun org-rss-template (contents info)
-  "Return complete document string after RSS conversion.
-CONTENTS is the transcoded contents string.  INFO is a plist used
-as a communication channel."
-  (concat
-   (format "<?xml version=\"1.0\" encoding=\"%s\"?>"
-	   (symbol-name org-html-coding-system))
-   "\n<rss version=\"2.0\"
-	xmlns:content=\"http://purl.org/rss/1.0/modules/content/\"
-	xmlns:wfw=\"http://wellformedweb.org/CommentAPI/\"
-	xmlns:dc=\"http://purl.org/dc/elements/1.1/\"
-	xmlns:atom=\"http://www.w3.org/2005/Atom\"
-	xmlns:sy=\"http://purl.org/rss/1.0/modules/syndication/\"
-	xmlns:slash=\"http://purl.org/rss/1.0/modules/slash/\"
-	xmlns:georss=\"http://www.georss.org/georss\"
-        xmlns:geo=\"http://www.w3.org/2003/01/geo/wgs84_pos#\"
-        xmlns:media=\"http://search.yahoo.com/mrss/\">"
-   "<channel>"
-   (org-rss-build-channel-info info) "\n"
-   contents
-   "</channel>\n"
-   "</rss>"))
-
-(defun org-rss-build-channel-info (info)
-  "Build the RSS channel information."
-  (let* ((system-time-locale "C")
-	 (title (plist-get info :title))
-	 (email (org-export-data (plist-get info :email) info))
-	 (author (and (plist-get info :with-author)
-		      (let ((auth (plist-get info :author)))
-			(and auth (org-export-data auth info)))))
-	 (date (format-time-string "%a, %d %b %Y %H:%M:%S %z")) ;; RFC 882
-	 (description (org-export-data (plist-get info :description) info))
-	 (lang (plist-get info :language))
-	 (keywords (plist-get info :keywords))
-	 (rssext (plist-get info :rss-extension))
-	 (blogurl (or (plist-get info :html-link-home)
-		      (plist-get info :publishing-directory)))
-	 (image (url-encode-url (plist-get info :rss-image-url)))
-	 (ifile (plist-get info :input-file))
-	 (publink
-	  (concat (file-name-as-directory blogurl)
-		  (file-name-nondirectory
-		   (file-name-sans-extension ifile))
-		  "." rssext)))
-    (format
-     "\n<title>%s</title>
-<atom:link href=\"%s\" rel=\"self\" type=\"application/rss+xml\" />
-<link>%s</link>
-<description><![CDATA[%s]]></description>
-<language>%s</language>
-<pubDate>%s</pubDate>
-<lastBuildDate>%s</lastBuildDate>
-<generator>%s</generator>
-<webMaster>%s (%s)</webMaster>
-<image>
-<url>%s</url>
-<title>%s</title>
-<link>%s</link>
-</image>
-"
-     title publink blogurl description lang date date
-     (concat (format "Emacs %d.%d"
-		     emacs-major-version
-		     emacs-minor-version)
-	     " Org-mode " (org-version))
-     email author image title blogurl)))
-
-(defun org-rss-section (section contents info)
-  "Transcode SECTION element into RSS format.
-CONTENTS is the section contents.  INFO is a plist used as
-a communication channel."
-  contents)
-
-(defun org-rss-timestamp (timestamp contents info)
-  "Transcode a TIMESTAMP object from Org to RSS.
-CONTENTS is nil.  INFO is a plist holding contextual
-information."
-  (org-html-encode-plain-text
-   (org-timestamp-translate timestamp)))
-
-(defun org-rss-plain-text (contents info)
-  "Convert plain text into RSS encoded text."
-  (let (output)
-    (setq output (org-html-encode-plain-text contents)
-	  output (org-export-activate-smart-quotes
-		  output :html info))))
-
-;;; Filters
-
-(defun org-rss-final-function (contents backend info)
-  "Prettify the RSS output."
-  (with-temp-buffer
-    (xml-mode)
-    (insert contents)
-    (indent-region (point-min) (point-max))
-    (buffer-substring-no-properties (point-min) (point-max))))
-
-;;; Miscellaneous
-
-(defun org-rss-add-pubdate-property ()
-  "Set the PUBDATE property for top-level headlines."
-  (let (msg)
-    (org-map-entries
-     (lambda ()
-       (let* ((entry (org-element-at-point))
-	      (level (org-element-property :level entry)))
-	 (when (= level 1)
-	   (unless (org-entry-get (point) "PUBDATE")
-	     (setq msg t)
-	     (org-set-property
-	      "PUBDATE" (format-time-string
-			 (cdr org-time-stamp-formats)))))))
-     nil nil 'comment 'archive)
-    (when msg
-      (message "Property PUBDATE added to top-level entries in %s"
-	       (buffer-file-name))
-      (sit-for 2))))
-
-(provide 'ox-rss)
-
-;;; ox-rss.el ends here
tools/emacs/lisp/paste-sbr.el
@@ -1,72 +0,0 @@
-;;; paste-sbr.el --- Paste to sbr.pm -*- lexical-binding: t; -*-
-
-;; Copyright (C) 2020 Vincent Demeester
-
-;; Author: Vincent Demeester <vincent@sbr.pm>
-;; Keywords: org link github
-;;
-;; This file is not part of GNU Emacs.
-
-;; This program is free software; you can redistribute it and/or
-;; modify it under the terms of the GNU General Public License as
-;; published by the Free Software Foundation; either version 3.0, or
-;; (at your option) any later version.
-
-;; This program is distributed in the hope that it will be useful,
-;; but WITHOUT ANY WARRANTY; without even the implied warranty of
-;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-;; GNU General Public License for more details.
-
-;; You should have received a copy of the GNU General Public License
-;; along with this program; if not, write to the Free Software
-;; Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-;;
-;;; Commentary:
-
-;; Take selection and share it to paste.sbr.pm
-
-;;; Code:
-
-(defvar htmlize-paste-it-target-directory
-  "desktop/sites/paste.sbr.pm")
-(defvar htmlize-paste-it-base-url
-  "https://paste.sbr.pm/")
-
-(defun htmlize-paste-it ()
-  "Htmlize region-or-buffer and copy to directory."
-  (interactive)
-  (let* ((start (if (region-active-p)
-                    (region-beginning) (point-min)))
-         (end (if (region-active-p)
-                  (region-end) (point-max)))
-
-         ;; We use a basename-hash.ext.html format
-         (basename (file-name-base (buffer-name)))
-         (extension (file-name-extension (buffer-name)))
-         (hash (sha1 (current-buffer) start end))
-         (file-name (concat basename
-                            "-" (substring hash 0 6)
-                            "." extension
-                            ".html"))
-
-         (new-file (expand-file-name (concat
-                                      htmlize-paste-it-target-directory
-                                      "/"
-                                      file-name) "~"))
-
-         (access-url (concat
-                      htmlize-paste-it-base-url
-                      file-name)))
-    ;; Region messes with clipboard, so deactivate it
-    (deactivate-mark)
-    (with-current-buffer (htmlize-region start end)
-      ;; Copy htmlized contents to target
-      (write-file new-file)
-      ;; Ensure target can be accessed by web server
-      (chmod new-file #o755))
-    ;; Put URL into clipboard
-    (kill-new access-url)))
-
-(provide 'paste-sbr)
-;;; paste-sbr.el ends here
tools/emacs/lisp/portal.el
@@ -1,644 +0,0 @@
-;;; portal.el --- Run processes in portals
-;;
-;; Copyright (C) 2024 Chris Done
-;;
-;; This file is free software; you can redistribute it and/or modify
-;; it under the terms of the GNU General Public License as published by
-;; the Free Software Foundation; either version 2, or (at your option)
-;; any later version.
-
-;; This file is distributed in the hope that it will be useful,
-;; but WITHOUT ANY WARRANTY; without even the implied warranty of
-;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-;; GNU General Public License for more details.
-
-;; You should have received a copy of the GNU General Public License
-;; along with GNU Emacs; see the file COPYING.  If not, write to
-;; the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-;; Boston, MA 02111-1307, USA.
-
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-;; Customizations
-
-(defgroup portal nil
-  "Portal group."
-  :group 'convenience)
-
-(defcustom portal-outputs-directory
-  "~/.local/share/portals/"
-  "Directory where to create output artifacts."
-  :type 'string :group 'portal)
-
-(defcustom portal-default-stdout-buffer-len
-  4096
-  "Default buffer length for the stdout preview."
-  :group 'portal :type 'number)
-
-(defcustom portal-default-stderr-buffer-len
-  4096
-  "Default buffer length for the stderr preview."
-  :group 'portal :type 'number)
-
-(defface portal-face
-  '((((class color) (background dark))
-     (:foreground "#fff" :bold t))
-    (((class color) (background light))
-     (:foreground "#000" :bold t)))
-  "Portal face."
-  :group 'portal)
-
-(defface portal-exited-stdout-face
-  '((t :foreground "#acac9e"))
-  "Portal exited stdout face."
-  :group 'portal)
-
-(defface portal-timestamp-face
-  '((t :foreground "#888888"))
-  "Portal exited stdout face."
-  :group 'portal)
-
-(defface portal-exited-stderr-face
-  '((t :foreground "#aa7070"))
-  "Portal exited stderr face."
-  :group 'portal)
-
-(defface portal-exit-success-face
-  '((t :foreground "#89b664"))
-  "Portal exit successful face."
-  :group 'portal)
-
-(defface portal-exit-failure-face
-  '((t :foreground "#ae6161"))
-  "Portal exit failure face."
-  :group 'portal)
-
-(defface portal-meta-face
-  '((t :foreground "#89b664"))
-  "Portal meta face."
-  :group 'portal)
-
-(defface portal-stdout-face
-  '((t :inherit 'default))
-  "Portal stdout face."
-  :group 'portal)
-
-(defface portal-stderr-face
-  '((t :foreground "#ae6161"))
-  "Portal stderr face."
-  :group 'portal)
-
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-;; Interactive commands
-
-(defun portal-insert-shell-command (command)
-  "Launch an asynchronous shell of COMMAND, make a portal associated
-with the current buffer and insert the portal into the current
-buffer."
-  (interactive "sCommand: ")
-  (portal-insert-command
-   (list shell-file-name shell-command-switch command)))
-
-(defun portal-open-stdout ()
-  "Open the stdout of the file at point."
-  (interactive)
-  (with-current-buffer (find-file-other-window (portal-file-name (portal-at-point) "stdout"))
-    (portal-ansi-colors-minor-mode)
-    (auto-revert-tail-mode)
-    (goto-char (point-max))
-    (push-mark (point-max))))
-
-(defun portal-open-stderr ()
-  "Open the stderr of the file at point."
-  (interactive)
-  (with-current-buffer (find-file-other-window (portal-file-name (portal-at-point) "stderr"))
-    (portal-ansi-colors-minor-mode)
-    (auto-revert-tail-mode)
-    (goto-char (point-max))
-    (push-mark (point-max))))
-
-(defun portal-interrupt ()
-  "Interrupt the process at point."
-  (interactive)
-  (let ((proc (get-process (portal-process-name (portal-at-point)))))
-    (when (process-live-p proc)
-      (interrupt-process proc))))
-
-(defun portal-rerun ()
-  "Re-run portal at point."
-  (interactive)
-  (portal-jump-to-portal)
-  (let* ((portal (portal-at-point))
-         (command (portal-read-json-file portal "command"))
-         (env (portal-read-json-file portal "env"))
-         (default-directory (portal-read-json-file portal "directory")))
-    (portal-interrupt)
-    (delete-region (line-beginning-position) (line-end-position))
-    (portal-wipe-summary)
-    (portal-insert-command (append command nil))
-    (portal-refresh-soon)))
-
-(defun portal-edit ()
-  "Edit and re-run portal at point."
-  (interactive)
-  (portal-jump-to-portal)
-  (portal-interrupt)
-  (let* ((portal (portal-at-point))
-         (command
-          (vector
-           shell-file-name
-           shell-command-switch
-           (read-from-minibuffer
-            "Edit command: "
-            (portal-as-shell-command (portal-read-json-file portal "command")))))
-         (env (portal-read-json-file portal "env"))
-         (default-directory (portal-read-json-file portal "directory")))
-    (delete-region (line-beginning-position) (line-end-position))
-    (portal-wipe-summary)
-    (portal-insert-command (append command nil))
-    (portal-refresh-soon)))
-
-(defun portal-clone ()
-  "Clone the portal at point."
-  (interactive)
-  (portal-jump-to-portal)
-  (let* ((portal (portal-at-point))
-         (command (portal-read-json-file portal "command"))
-         (env (portal-read-json-file portal "env"))
-         (default-directory (portal-read-json-file portal "directory")))
-    (save-excursion (insert "\n"))
-    (portal-insert-command (append  command nil))
-    (portal-refresh-soon)))
-
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-;; Launching processes
-
-(defun portal-start (buffer portal stdout-path stderr-path program program-args)
-  "Run PROGRAM-PATH with ARGS, connect it to portal PORTAL in buffer
-BUFFER, and write the stdout to STDOUT-PATH and stderr to
-STDERR-PATH."
-  (let* ((stderr-pipe
-          (make-pipe-process
-           :name (portal-stderr-process-name portal)
-           :buffer buffer
-           :noquery t
-           :filter 'portal-process-filter
-           :sentinel 'portal-stderr-pipe-sentinel))
-         (main-process
-          (make-process
-           :name (portal-process-name portal)
-           :buffer buffer
-           :command (cons program program-args)
-           :noquery nil
-           :connection-type 'pipe
-           :sentinel 'portal-main-process-sentinel
-           :filter 'portal-process-filter
-           :stderr stderr-pipe)))
-
-    (process-put stderr-pipe :portal portal)
-    (process-put stderr-pipe :output-path stderr-path)
-    (process-put stderr-pipe :buffer "")
-    (process-put stderr-pipe :buffer-len portal-default-stderr-buffer-len)
-
-    (process-put main-process :portal portal)
-    (process-put main-process :output-path stdout-path)
-    (process-put main-process :buffer "")
-    (process-put main-process :buffer-len portal-default-stdout-buffer-len)
-
-    ;; Connect the two processes.
-    (process-put main-process :stderr-process stderr-pipe)
-
-    (portal-write-json-file portal "command" (apply #'vector (cons program program-args)))
-    (portal-write-json-file portal "env" (apply #'vector process-environment))
-    (portal-write-json-file portal "directory" default-directory)
-    (portal-write-json-file portal "status" (format "%S" (process-status main-process)))))
-
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-;; Process filtering
-
-(defun portal-process-filter (process output)
-  (let ((filepath (process-get process :output-path)))
-    (when debug-on-error
-      (message "portal-process-filter: Writing to %s" filepath))
-    (portal-accumulate-buffer process output)
-    (with-temp-buffer
-      (insert output)
-      (write-region (point-min) (point-max) filepath :append :no-messages))))
-
-(defun portal-accumulate-buffer (process output)
-  "Accumulate some OUTPUT into PROCESS's preview buffer."
-  (process-put
-   process
-   :buffer (portal-shrink-preview
-            (process-get process :buffer-len)
-            (concat (process-get process :buffer) output))))
-
-(defun portal-shrink-preview (len string)
-  "Shrink a preview buffer STRING to the right length."
-  (if (> (length string) len)
-      (substring string (- len))
-    string))
-
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-;; Sentinels
-
-(defun portal-main-process-sentinel (process event)
-  "Handles the main process's status updates."
-  (when debug-on-error
-    (message "main-process-sentinel: %S: %S" process event))
-  (portal-write-json-file
-   (process-get process :portal)
-   "status" (format "%S" (process-exit-status process))))
-
-(defun portal-stderr-pipe-sentinel (process event)
-  "Handles the stderr pipe's status updates."
-  (when debug-on-error
-    (message "stderr-pipe-sentinel: %S: %S" process event)))
-
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-;; File/directory operations
-
-(defun portal-ensure-directory (portal)
-  "Create the stdout/stderr files for PORTAL in an appropriate
-location."
-  (let ((directory (concat (file-name-as-directory portal-outputs-directory) portal)))
-    (make-directory directory :including-parents)
-    directory))
-
-(defun portal-directory-exists-p (portal)
-  "Check PORTAL has a directory that exists."
-  (let ((directory (concat (file-name-as-directory portal-outputs-directory) portal)))
-    (file-exists-p directory)))
-
-(defun portal-file-exists-p (portal name)
-  "Check PORTAL has a file NAME that exists."
-  (let ((directory (concat (file-name-as-directory portal-outputs-directory) portal)))
-    (file-exists-p (concat (file-name-as-directory directory) name))))
-
-(defun portal-persist-file (portal name content)
-  "Persist CONTENT to disk with filename NAME."
-  (with-temp-buffer
-    (insert content)
-    (write-region
-     (point-min) (point-max)
-     (portal-file-name portal name)
-     nil ; no-append
-     :no-messages))
-  content)
-
-(defun portal-write-json-file (portal name expr)
-  "Print EXPR to disk with filename NAME."
-  (with-temp-buffer
-    (insert (json-serialize expr))
-    (write-region
-     (point-min) (point-max)
-     (portal-file-name portal name)
-     nil ; no-append
-     :no-messages))
-  expr)
-
-(defun portal-read-json-file (portal name)
-  "Read JSON content from file NAME for the given PORTAL."
-  (with-temp-buffer
-    (insert-file-contents (portal-file-name portal name))
-    (json-parse-string (buffer-string))))
-
-(defun portal-read-file (portal name)
-  "Read content from file NAME for the given PORTAL."
-  (with-temp-buffer
-    (let ((file (portal-file-name portal name)))
-      (when (file-exists-p file)
-        (insert-file-contents file)))
-    (buffer-string)))
-
-(defun portal-tail-file (portal n name)
-  "Tail last N lines of file NAME for the given PORTAL."
-  (with-temp-buffer
-    (let ((file (portal-file-name portal name)))
-      (if (file-exists-p file)
-          (portal-tail-n-lines n file)
-        ""))))
-
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-;; Nano-IDs
-
-(defun portal-generate-nanoid ()
-  "Generate a Nano ID of the form `portal_NGMyMDVkZjZiYTVlZTVhM' using SHA-1."
-  (let* ((random-string (format "%s%s%S" (emacs-pid) (current-time-string) (random)))
-         (sha1-hash (secure-hash 'sha1 random-string))
-         (base64-encoded (base64-encode-string sha1-hash))
-         (nanoid (string-trim-right (substring base64-encoded 0 21))))
-    (concat "portal_" nanoid)))
-
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-;; A minor mode for applying ansi-term colors to a buffer
-
-(define-minor-mode portal-ansi-colors-minor-mode
-  "Apply ANSI colors for terminal outputs."
-  :init-value nil
-  :lighter "ANSI"
-  (ansi-color-apply-on-region (point-min) (point-max)))
-
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-;; A small minor mode that just sets up a timer that runs a thing in a
-;; given buffer every N seconds
-
-(defvar-local portal-alpha-timer
-    nil)
-
-(define-minor-mode portal-alpha-minor-mode
-  "TODO"
-  :init-value nil
-  :lighter "@"
-  (when portal-alpha-timer (cancel-timer portal-alpha-timer))
-  (when portal-alpha-minor-mode
-    (setq portal-alpha-timer
-          (run-with-timer 1 2 'portal-beta-refresh (current-buffer)))))
-
-(defun portal-refresh-soon ()
-  "Trigger a refresh within the blink of an eye, but no sooner, or
-later."
-  (run-with-timer 0.100 nil 'portal-beta-refresh (current-buffer)))
-
-(defun portal-beta-refresh (buffer)
-  "Refresh portal displays."
-  (when (buffer-live-p buffer)
-    (let ((window (get-buffer-window buffer)))
-      (when window
-        (with-current-buffer buffer
-          (let ((point (point)))
-            (save-excursion
-              (goto-char (point-min))
-              (while (and (re-search-forward portal-regexp nil t nil)
-                          (<= (point) (window-end window)))
-                (when (<= (window-start window) (point) (window-end window))
-                  (let* ((portal (match-string 0))
-                         (process (get-process (portal-process-name portal)))
-                         (summary (if (portal-directory-exists-p portal)
-                                      (portal-summary portal process)
-                                    "# Invalid portal."))
-                         (match-end (match-end 0))
-                         (old-summary (get-text-property (line-beginning-position) 'portal-summary)))
-                    (unless (and old-summary (string= summary old-summary))
-                      (put-text-property (line-beginning-position) (point)
-                                         'portal-summary
-                                         summary)
-                      (put-text-property (line-beginning-position) (point)
-                                         'portal
-                                         portal)
-                      (portal-wipe-summary)
-                      (insert "\n" summary))))))
-            (goto-char point)))))))
-
-(defun portal-wipe-summary ()
-  "Wipe the '# summary' lines that follow the portal."
-  (save-excursion
-    (when (looking-at "\n#")
-      (forward-line 1)
-      (let ((point (point)))
-        (or (search-forward-regexp "^[^#]" nil t 1)
-            (goto-char (point-max)))
-        (delete-matching-lines "^#" point (point))))))
-
-(defun portal-summary (portal process)
-  "Generate a summary of the portal."
-  (let* ((command (portal-read-json-file portal "command"))
-         (directory (portal-read-json-file portal "directory"))
-         (status (portal-read-json-file portal "status"))
-         (stdout (if process
-                     (portal-last-n-lines
-                      5
-                      (process-get process :buffer))
-                   (portal-tail-file portal 5 "stdout")))
-         (stderr (if process
-                     (portal-last-n-lines
-                      5
-                      (process-get (process-get process :stderr-process) :buffer))
-                   (portal-tail-file portal 5 "stderr")))
-         (started-time
-          (file-attribute-modification-time (file-attributes (portal-file-name portal "command"))))
-         (exited-time
-          (file-attribute-modification-time (file-attributes (portal-file-name portal "status")))))
-    (with-temp-buffer
-      (insert (propertize
-               (concat "# (" (if (string= status "run") "🌀" status) ") " (portal-as-shell-command command))
-               'face
-               (if (string= status "run")
-                   'portal-meta-face
-                 (if (string= status "0")
-                     'portal-exit-success-face
-                   'portal-exit-failure-face))))
-      (insert "\n"
-              (concat
-               (propertize (format-time-string "# Started: %Y-%m-%d %T" started-time)
-                           'face 'portal-timestamp-face)
-               (if (string= status "run")
-                   ""
-                 (propertize (concat
-                              (format-time-string ", exited: %Y-%m-%d %T" exited-time)
-                              " => "
-                              (portal-display-time-difference started-time exited-time))
-                             'face 'portal-timestamp-face))))
-      ;; Only show if it's different to the current directory,
-      ;; otherwise it's noise.
-      (unless (string= default-directory directory) (insert "\n# " directory))
-      (unless (= 0 (length (string-trim stdout)))
-        (insert "\n"
-                (propertize (portal-clean-output stdout)
-                            'face (if (string= status "run")
-                                      'portal-stdout-face
-                                    'portal-exited-stdout-face))))
-      (unless (= 0 (length (string-trim stderr)))
-        (insert "\n"
-                (propertize (portal-clean-output stderr)
-                            'face
-                            (if (string= status "run")
-                                'portal-stderr-face
-                              'portal-exited-stderr-face))))
-      (propertize (buffer-string)
-                  'portal portal))))
-
-(defun portal-display-time-difference (start-time end-time)
-  "Display the time difference between START-TIME and END-TIME in human-readable format.
-START-TIME and END-TIME should be Emacs Lisp time values as returned by `current-time'.
-The function will display the time in the most appropriate unit (from ns to days)."
-  (let* ((diff (float-time (time-subtract end-time start-time))))
-    (apply #'format
-           (cons "%.3f %s"
-                 (cond
-                  ((< diff 1e-6)
-                   (list (* diff 1e9) "ns"))
-                  ((< diff 1e-3)
-                   (list (* diff 1e6) "us"))
-                  ((< diff 1)
-                   (list (* diff 1e3) "ms"))
-                  ((< diff 60)
-                   (list diff "s"))
-                  ((< diff 3600)
-                   (list (/ diff 60) "mins"))
-                  ((< diff 86400)
-                   (list (/ diff 3600) "hours"))
-                  (t
-                   (list (/ diff 86400) "days")))))))
-
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-;; String generation
-
-(defun portal-as-shell-command (command)
-  "If the vector COMMAND is a shell run, strip the prefix, else return the whole thing joined."
-  (if (and (= 3 (length command))
-           (string= (elt command 0) shell-file-name)
-           (string= (elt command 1) shell-command-switch))
-      (elt command 2)
-    (mapconcat 'shell-quote-argument command " ")))
-
-(defun portal-clean-output (output)
-  "Clean output for previewing, prefixed with #."
-  (portal-limit-lines-to-80-columns
-   (concat "# " (replace-regexp-in-string
-                 "\n" "\n# "
-                 (portal-no-empty-lines output)))))
-
-(defun portal-limit-lines-to-80-columns (string)
-  "Limit all lines in STRING to 80 columns."
-  (with-temp-buffer
-    (insert string)
-    (goto-char (point-min))
-    (while (not (eobp))
-      (move-to-column 80 t)
-      (delete-region (point) (line-end-position))
-      (forward-line))
-    (buffer-string)))
-
-(defun portal-process-name (portal)
-  (concat portal "-main-process"))
-
-(defun portal-stderr-process-name (portal)
-  (concat portal "-stderr-pipe"))
-
-(defun portal-file-name (portal name)
-  (concat (file-name-as-directory (portal-ensure-directory portal)) name))
-
-(defun portal-no-empty-lines (string)
-  "Drop empty lines from a string."
-  (replace-regexp-in-string
-   ;; Drop ANSI codes from terminal output
-   ;; <https://superuser.com/questions/380772/removing-ansi-color-codes-from-text-stream>
-   "\\(\x1B\\[[0-9;]*[A-Za-z]\\|[\x00-\x09\x0B-\x1F\x7F]\\|\n$\\|^\n\\)"
-   ""
-   string))
-
-(defun portal-last-n-lines (n string)
-  "Take last N lines from STRING."
-  (mapconcat #'identity (reverse (seq-take (reverse (split-string string "[\r\n]+" t)) n)) "\n"))
-
-(defun portal-tail-n-lines (n file-path)
-  "Tail the last N lines from FILE-PATH using tail, if possible. If
-not possible (due to lack of such tool), return nil."
-  (let ((this-buffer (current-buffer)))
-    (with-temp-buffer
-      (let ((out-buffer (current-buffer)))
-        (with-current-buffer this-buffer
-          (cl-case (call-process "tail" nil out-buffer nil "-n" (format "%d" n)
-                                 (expand-file-name file-path))
-            (0 (with-current-buffer out-buffer (buffer-string)))
-            (t "")))))))
-
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-;; Finding portals and gathering information for them
-
-(defconst portal-regexp "\\<portal_[A-Za-z0-9]\\{21\\}\\>"
-  "Match on a portal's unique ID.")
-
-(defun portal-at-point ()
-  "Return the portal at point."
-  (or (save-excursion
-        (goto-char (line-beginning-position))
-        (when (looking-at portal-regexp)
-          (buffer-substring (match-beginning 0) (match-end 0))))
-      (get-text-property (point) 'portal)
-      (error "Not at a portal.")))
-
-(defun portal-jump-to-portal ()
-  "If there's a portal at point or a summary of a portal at point,
-jump to the portal at the beginning of the line upwards within
-the same paragraph."
-  (let ((portal (portal-at-point)))
-    (goto-char
-     (save-excursion
-       (goto-char (line-end-position))
-       (re-search-backward
-        (concat "^" (regexp-quote portal))
-        (save-excursion (forward-paragraph -1))
-        nil
-        1)))))
-
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-;; Notes
-
-;; Use this on a portals buffer to stop it constantly being saved:
-;
-;; (setq buffer-save-without-query t)
-
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-;; Major mode
-
-(defvar-keymap portal-mode-map
-  "M-!" 'portal-dwim-execute
-  "C-c C-c" 'portal-interrupt
-  "RET" 'portal-jump-to-thing-at-point
-  "M-p" 'portal-rerun
-  )
-
-(define-derived-mode portal-mode
-  fundamental-mode "Portals"
-  "Major mode for portals."
-  (setq buffer-save-without-query t)
-  (portal-alpha-minor-mode))
-
-(defun portal-insert-command (command)
-  "Launch an asynchronous proc of COMMAND, make a portal associated
-with the current buffer and insert the portal into the current
-buffer."
-  (let* ((portal (portal-generate-nanoid)))
-    (portal-start
-     (current-buffer)
-     portal
-     (portal-file-name portal "stdout")
-     (portal-file-name portal "stderr")
-     (car command)
-     (cdr command))
-    (insert portal)))
-
-(defun portal-dwim-execute ()
-  (interactive)
-  (call-interactively
-   (if (condition-case nil
-           (portal-at-point)
-         (error nil))
-       'portal-edit
-     'portal-shell-command)))
-
-(defun portal-shell-command (command)
-  "Run a shell command and insert it at point."
-  (interactive "sCommand: ")
-  (portal-insert-command
-   (list shell-file-name shell-command-switch command)))
-
-(defun portal-jump-to-thing-at-point ()
-  "Jump to the thing at point, i.e. an stdout/stderr output jumps to
-the file."
-  (interactive)
-  (let ((face (get-text-property (point) 'face)))
-    (cond
-     ((eq face 'portal-stderr-face)
-      (portal-open-stderr))
-     ((eq face 'portal-exited-stderr-face)
-      (portal-open-stderr))
-     ((eq face 'portal-stdout-face)
-      (portal-open-stdout))
-     ((eq face 'portal-exited-stdout-face)
-      (portal-open-stdout))
-     (t (call-interactively 'newline)))))
-
-(provide 'portal)
-
tools/emacs/lisp/project-func.el
@@ -1,150 +0,0 @@
-;;; project-func.el --- -*- lexical-binding: t -*-
-;;; Commentary:
-;;; Code:
-(require 'project)
-(require 'vterm)
-(require 'json)
-(require 'vc)
-
-(defun in-git-repo-p ()
-  "Check if current directory is in a git repository."
-  (eq (vc-backend (or buffer-file-name default-directory))
-      'Git))
-
-(defun is-github-repo-p ()
-  "Check if current git repository has a GitHub remote."
-  (when (in-git-repo-p)
-    (string-match-p "github\\.com"
-                    (shell-command-to-string "git remote -v"))))
-
-(defun fetch-github-prs ()
-  "Fetch GitHub PRs synchronously."
-  (let* ((output (shell-command-to-string "gh pr list --limit=5000 --json number,title,author,url,baseRefName,labels"))
-         (prs (json-read-from-string output)))
-    prs))
-
-(defun format-pr-candidates (prs)
-  "Format PR data into candidates for completion."
-  (mapcar (lambda (pr)
-            (let-alist pr
-              (cons (format "#%d %s (by @%s) on %s" .number .title .author.login .baseRefName)
-                    .number)))
-          prs))
-
-;;;###autoload
-(defun checkout-github-pr ()
-  "Interactive function to select and checkout a GitHub PR."
-  (interactive)
-  (cond
-   ((not (in-git-repo-p))
-    (message "Not in a Git repository"))
-   ((not (is-github-repo-p))
-    (message "Not a GitHub repository"))
-   (t
-    (let* ((prs (fetch-github-prs))
-           (candidates (format-pr-candidates prs))
-           (selected (if candidates
-                         (cdr (assoc (completing-read "Checkout PR: " candidates)
-                                     candidates))
-                       nil)))
-      (if selected
-          (shell-command (format "gh pr checkout %d" selected))
-        (message "No pull requests found"))))))
-
-;;;###autoload
-(defun vde-project--project-current ()
-  "Return directory from `project-current' based on Emacs version."
-  (if (>= emacs-major-version 29)
-      (project-root (project-current))
-    (cdr (project-current))))
-
-;;;###autoload
-(defun vde-project--project-root-or-default-directory ()
-  "Return path to the project root *or* the default-directory."
-  (cond
-   ((and (featurep 'project) (project-current))
-    (project-root (project-current)))
-   (t default-directory)))
-
-;;;##autoload
-(defun vde/project-run-in-vterm (command &optional directory)
-  "Run the given `COMMAND' in a new vterm buffer in `project-root' or the
-given `DIRECTORY'.
-
-This is similar to `compile' but with vterm.
-One reason for this is to be able to run commands that needs a TTY."
-  (interactive "sCommand: ")
-  (let* ((cwd (or directory (vde-project--project-root-or-default-directory)))
-	 (default-directory cwd)
-	 (buffer-name (format "*vterm %s: %s*" cwd command))
-         (buffer (get-buffer buffer-name))
-         (vterm-kill-buffer-on-exit nil)
-	 (vterm-shell (concat "bash -c '" command ";exit'")))
-    (when buffer
-      (kill-buffer buffer))
-    (let ((buffer (generate-new-buffer buffer-name)))
-      (pop-to-buffer buffer)
-      (with-current-buffer buffer
-        (vterm-mode)))))
-
-;;;###autoload
-(defun vde/open-readme ()
-  "Open a README file in the current project.
-It will search for README.org, README.md or README in that order"
-  (interactive)
-  (let* ((default-directory (vde-project--project-current)))
-    (cond ((file-exists-p (expand-file-name "README.org" default-directory))
-	   (find-file "README.org"))
-	  ((file-exists-p (expand-file-name "README.md" default-directory))
-	   (find-file "README.md"))
-	  ((file-exists-p (expand-file-name "README" default-directory))
-	   (find-file "README")))))
-
-;;;###autoload
-(defun vde/project-try-local (dir)
-  "Determine if DIR is a non-VC project."
-  (if-let ((root (if (listp vde/project-local-identifier)
-                     (seq-some (lambda (n)
-                                 (locate-dominating-file dir n))
-                               vde/project-local-identifier)
-                   (locate-dominating-file dir vde/project-local-identifier))))
-      (cons 'local root)))
-
-;;;###autoload
-(defun vde/project-vterm (&optional command)
-  "Run `vterm' on project.
-If a buffer already exists for running a vterm shell in the project's root,
-switch to it. Otherwise, create a new vterm shell."
-  (interactive)
-  (let* ((default-directory (vde-project--project-current))
-         (default-project-vterm-name (project-prefixed-buffer-name "vterm"))
-         (vterm-buffer (get-buffer default-project-vterm-name)))
-    (if (and vterm-buffer (not current-prefix-arg))
-        (pop-to-buffer-same-window vterm-buffer)
-      (let* ((cd-cmd (concat " cd " (shell-quote-argument default-directory))))
-        (vterm default-project-vterm-name)
-        (with-current-buffer vterm-buffer
-          (vterm-send-string cd-cmd)
-          (vterm-send-return))))
-    (when command
-      (vterm-send-string command)
-      (vterm-send-return))))
-
-;;;###autoload
-(defun vde/project-eat ()
-  "Run Eat term in the current project's root directory.
-If a buffer already exists for running Eshell in the project's root,
-switch to it.  Otherwise, create a new Eshell buffer.
-With \\[universal-argument] prefix arg, create a new Eshell buffer even
-if one already exists."
-  (interactive)
-  (defvar eat-buffer-name)
-  (let* ((default-directory (project-root (project-current t)))
-	 (eat-buffer-name (project-prefixed-buffer-name "eat"))
-	 (eat-buffer (get-buffer eat-buffer-name)))
-    (if (and eat-buffer (not current-prefix-arg))
-	(pop-to-buffer eat-buffer (bound-and-true-p display-comint-buffer-action))
-      (eat shell-file-name))))
-
-(provide 'project-func)
-;;; project-func.el ends here
tools/emacs/lisp/project-headerline.el
@@ -1,920 +0,0 @@
-;;; project-headerline.el --- Customizable project headerline -*- lexical-binding: t -*-
-
-;; Copyright (C) 2025 Victor Gaydov and contributors
-;; Copyright (C) 2020 emacs-lsp maintainers
-
-;; Author: Victor Gaydov <victor@enise.org>
-;; Created: 03 Feb 2025
-;; URL: https://github.com/gavv/project-headerline
-;; Version: 0.4
-;; Package-Requires: ((emacs "28.2") (f "0.21.0") (s "1.13.0") (all-the-icons "5.0.0"))
-;; Keywords: convenience
-
-;;; License:
-
-;; This program is free software; you can redistribute it and/or modify
-;; it under the terms of the GNU General Public License as published by
-;; the Free Software Foundation, either version 3 of the License, or
-;; (at your option) any later version.
-
-;; This program is distributed in the hope that it will be useful,
-;; but WITHOUT ANY WARRANTY; without even the implied warranty of
-;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-;; GNU General Public License for more details.
-
-;; You should have received a copy of the GNU General Public License
-;; along with this program.  If not, see <https://www.gnu.org/licenses/>.
-
-;;; Notice:
-
-;; Several functions were ported from lsp-headerline.el, so the copyrights
-;; includes one from that module.
-
-;;; Commentary:
-
-;; project-headerline implements a minor mode that shows a headerline with
-;; current project name, and the path to current buffer from the project root.
-
-;; It is inspired by lsp-headerline, but it doesn't show symbol and diagnostic
-;; information, has no dependency on lsp, and can be used for buffers of any kind.
-
-;; Please refer to README.org and docstrings for further details.
-
-;;; Code:
-
-(require 'dired-aux)
-(require 'project)
-(require 'seq)
-(require 'vc)
-
-(require 'projectile nil 'noerror)
-(require 'magit nil 'noerror)
-(require 'all-the-icons nil 'noerror)
-
-(require 'f)
-(require 's)
-
-(defgroup project-headerline nil
-  "Customizable project headerline."
-  :prefix "project-headerline-"
-  :group 'convenience
-  :link '(url-link "https://github.com/gavv/project-headerline"))
-
-(defface project-headerline-project-name
-  '((t :inherit font-lock-string-face :weight bold))
-  "Face used for \\='project-name segment."
-  :package-version '(project-headerline . "0.1")
-  :group 'project-headerline)
-
-(defface project-headerline-path-in-project
-  '((t :inherit font-lock-keyword-face))
-  "Face used for \\='path-in-project segment."
-  :package-version '(project-headerline . "0.1")
-  :group 'project-headerline)
-
-(defface project-headerline-buffer-name
-  '((t :inherit font-lock-builtin-face))
-  "Face used for \\='buffer-name segment."
-  :package-version '(project-headerline . "0.1")
-  :group 'project-headerline)
-
-(defface project-headerline-segment-separator
-  '((t :inherit shadow :height 0.8))
-  "Face used for separator between segments."
-  :package-version '(project-headerline . "0.1")
-  :group 'project-headerline)
-
-(defface project-headerline-path-separator
-  '((t :inherit shadow :height 0.8))
-  "Face used for between path components inside `path-in-project' segment."
-  :package-version '(project-headerline . "0.1")
-  :group 'project-headerline)
-
-(defface project-headerline-space
-  '((t :height 0.5))
-  "Face used for spaces around segment and path separators."
-  :package-version '(project-headerline . "0.2")
-  :group 'project-headerline)
-
-(defcustom project-headerline-display-segments
-  '(
-    ;; list of pre-defined symbols, each symbol corresponds to a segment
-    project-name
-    path-in-project
-    buffer-name
-    ;;
-    )
-  "Which segments to show and in what order.
-
-Must be a list of symbols, where each symbol represents a segment:
-
-  - `project-name' - name of project where current file belongs
-  - `path-in-project' - relative path from project root up to the current file
-  - `buffer-name' - file name or buffer name
-
-`path-in-project' segment is present only if buffer is file or directory.
-`buffer-name' segment displays file or directory name if buffer is visiting one,
-and uses function (buffer-name) otherwise."
-  :package-version '(project-headerline . "0.1")
-  :group 'project-headerline
-  :type '(repeat
-          (choice (const :tag "Project name." project-name)
-                  (const :tag "Directories up to project." path-in-project)
-                  (const :tag "Buffer or file name." buffer-name)))
-  :initialize 'custom-initialize-default
-  :set 'project-headerline--set-variable)
-
-(defcustom project-headerline-segment-separator nil
-  "String or icon to separate segments.
-
-Icon is actually also a string, but with special properties.
-For example, you can create one using `all-the-icons-material'.
-
-When separator is nil, `project-headerline-icon-function' is used
-to create it with default icon name."
-  :package-version '(project-headerline . "0.1")
-  :group 'project-headerline
-  :type '(choice (const :tag "Default" nil)
-                 string)
-  :initialize 'custom-initialize-default
-  :set 'project-headerline--set-variable)
-
-(defcustom project-headerline-path-separator nil
-  "String or icon to separate path components inside \\='path-in-project segment.
-
-Icon is actually also a string, but with special properties.
-For example, you can create one using `all-the-icons-material'.
-
-When separator is nil, `project-headerline-icon-function' is used
-to create it with default icon name."
-  :package-version '(project-headerline . "0.1")
-  :group 'project-headerline
-  :type '(choice (const :tag "Default" nil)
-                 string)
-  :initialize 'custom-initialize-default
-  :set 'project-headerline--set-variable)
-
-(defcustom project-headerline-path-ellipsis "..."
-  "String or icon used when \\='path-in-project' segment is truncated.
-
-If the segment is too long, a few leading path components are
-replaced with the value of this variable."
-  :package-version '(project-headerline . "0.1")
-  :group 'project-headerline
-  :type 'string
-  :initialize 'custom-initialize-default
-  :set 'project-headerline--set-variable)
-
-(defcustom project-headerline-detect-alist
-  `(
-    ;; detect using projectile, if installed
-    (projectile :allow-remote nil
-                :describe ,(lambda ()
-                             (when (and (featurep 'projectile)
-                                        (projectile-project-p))
-                               (list :name (projectile-project-name)
-                                     :path (projectile-project-root)))))
-    ;; detect using builtin project.el package
-    (project :allow-remote nil
-             :describe ,(lambda ()
-                          (when-let* ((project (project-current)))
-                            (list :name (f-base (project-root project))
-                                  :path (project-root project)))))
-    ;; detect using magit, if installed
-    (magit :allow-remote nil
-           :describe ,(lambda ()
-                        (when (featurep 'magit)
-                          (when-let* ((magit-root (magit-toplevel)))
-                            (list :name (f-filename magit-root)
-                                  :path (f-full magit-root))))))
-    ;; detect using builtin vc package
-    (vc :allow-remote nil
-        :describe ,(lambda ()
-                     (when-let* ((vc-root (vc-root-dir)))
-                       (list :name (f-filename vc-root)
-                             :path (f-full vc-root)))))
-    ;;
-    )
-  "Assoc list of project detection methods.
-
-Assoc list key is a symbol of your choice.
-Assoc list value is a plist with the following properties:
-  - `:allow-remote' - whether to use this method on remote files
-  - `:describe' - detection function
-
-`:allow-remote' is by default disabled for all methods because it
-may be very slow (depending on your connection).
-
-Detection function should take no arguments and return a plist:
-  - `:name' - project name
-  - `:path' - project path (tramp paths are allowed)
-
-Detection methods are tried one by one, until some of them
-returns non-nil.
-
-Used by default implementation of
-`project-headerline-describe-project-function'."
-  :package-version '(project-headerline . "0.1")
-  :group 'project-headerline
-  :type '(alist :key-type symbol
-                :value-type (plist :options ((:allow-remote boolean)
-                                             (:describe function))))
-  :initialize 'custom-initialize-default
-  :set 'project-headerline--set-variable)
-
-(defcustom project-headerline-fallback-alist
-  '(
-    ;; pseudo-project "~" for all orphan files under $HOME
-    ("~" . "~/")
-    ;; pseudo-project "/" for all other orphan files
-    ("/" . "/")
-    ;;
-    )
-  "Assoc list of fallback projects when normal detection fails.
-
-Assoc list key is project name.
-Assoc list value is project path.
-
-If no project was detected using `project-headerline-detect-alist',
-then `project-headerline-fallback-alist' is scanned.  A fallback
-project is selected if it's path is the parent of buffer's path.
-
-You can use it both for real projects with hard-coded paths
-\(e.g. if they're not identified by common methods), and for
-fallbacks for buffers that don't really belong to a project.
-
-By default, two `pseudo projects` are registered: `~' for any
-file inside home directory, and `/' for any file elsewhere
-on filesystem.  You can disable this by removing corresponding
-elements from the assoc list."
-  :package-version '(project-headerline . "0.1")
-  :group 'project-headerline
-  :type '(alist :key-type (string :tag "Project Name")
-                :value-type (string :tag "Project Path"))
-  :initialize 'custom-initialize-default
-  :set 'project-headerline--set-variable)
-
-(defcustom project-headerline-rename-alist
-  '(
-    ;; magit
-    ("^\\(magit\\):.*" . "\\1")
-    ("^\\(magit-[a-z]+\\):.*" . "\\1")
-    ;; compilation
-    ("^\\*compilation\\*<.*>" . "compilation")
-    ("^\\*compilation<.*>\\*" . "compilation")
-    ;;
-    )
-  "Assoc list of buffer rename rules.
-
-Assoc list key is a regular expression.
-Assoc list value is a replacement string that can use capture groups.
-
-Keys and values are passed to `replace-regexp-in-string' and FROM and
-TO arguments.  If any of the rule matches buffer, buffer name displayed
-in headerline is changed according to the replacement."
-  :package-version '(project-headerline . "0.1")
-  :group 'project-headerline
-  :type '(alist :key-type (string :tag "Buffer Name Regexp")
-                :value-type (string :tag "Buffer Name Replacement"))
-  :initialize 'custom-initialize-default
-  :set 'project-headerline--set-variable)
-
-(defcustom project-headerline-describe-project-function
-  #'project-headerline-describe-project
-  "Function that returns properties of current project.
-
-Takes no arguments and returns plist:
-  - `:name' - project name
-  - `:path' - project directory path
-
-Default implementation uses the following algorithm:
-  - if `project-headerline-current-project' is set, uses it
-  - tries rules from `project-headerline-detect-alist'
-  - tries paths from `project-headerline-fallback-alist'"
-  :package-version '(project-headerline . "0.1")
-  :group 'project-headerline
-  :type 'function
-  :initialize 'custom-initialize-default
-  :set 'project-headerline--set-variable)
-
-(defcustom project-headerline-describe-buffer-function
-  #'project-headerline-describe-buffer
-  "Function that returns properties of current buffer.
-
-Takes no arguments and returns plist:
-  - `:type' - kind of buffer, one of the symbols: `file', `dir', `other'
-  - `:dir' - path to buffer's directory
-  - `:name' - name of buffer
-
-For `file' buffers, `:dir' is path to directory containing the file.
-For `dir' buffers, `:dir' is path to directory itself.
-For `other' buffers, `:dir' is path to a directory associated with
-the buffer, typically `default-directory' inside that buffer.
-
-Default implementation reports `dir' for Dired buffers, `file' for
-buffers with non-empty variable `buffer-file-name', and `other' for
-the rest.  It also applies buffer renaming rules according to variable
-`project-headerline-rename-alist'."
-  :package-version '(project-headerline . "0.1")
-  :group 'project-headerline
-  :type 'function
-  :initialize 'custom-initialize-default
-  :set 'project-headerline--set-variable)
-
-(defcustom project-headerline-format-function
-  #'project-headerline-format
-  "Function to format headerline from project and buffer properties.
-
-Takes two arguments:
-  - `project' - plist from `project-headerline-describe-project-function'
-  - `buffer' - plist from `project-headerline-describe-buffer-function'
-
-Returns propertized string with headerline contents.
-
-Default implementation formats headerline according to variables
-`project-headerline-display-segments', `project-headerline-segment-separator',
-`project-headerline-path-separator' (or `project-headerline-icon-function'),
-and applies corresponding faces."
-  :package-version '(project-headerline . "0.1")
-  :group 'project-headerline
-  :type 'function
-  :initialize 'custom-initialize-default
-  :set 'project-headerline--set-variable)
-
-(defcustom project-headerline-icon-function
-  #'project-headerline-icon
-  "Function to create icon from name.
-
-Takes two arguments:
-  - `icon-name' - string name of the icon
-  - `icon-face' - face to apply to the icon
-
-Returns propertized string with the icon.
-If icon is not available, returns nil.  In this case fallback
-character will be used instead of the icon.
-
-Default implementation uses `all-the-icons-material' when it's
-available, or returns nil otherwise."
-  :package-version '(project-headerline . "0.1")
-  :group 'project-headerline
-  :type 'function
-  :initialize 'custom-initialize-default
-  :set 'project-headerline--set-variable)
-
-(defcustom project-headerline-width-function
-  #'project-headerline-width
-  "Function to return maximum headerline width.
-Takes no arguments and returns number of characters."
-  :package-version '(project-headerline . "0.1")
-  :group 'project-headerline
-  :type 'function
-  :initialize 'custom-initialize-default
-  :set 'project-headerline--set-variable)
-
-(defcustom project-headerline-mode-list
-  '(prog-mode
-    conf-mode
-    text-mode
-    dired-mode)
-  "Modes in which to enable `project-headerline-mode' automatically.
-
-When `global-project-headerline-mode' is enabled, it enables headerline
-in buffer if its major mode is derived from one of these modes.
-
-Note that minibuffer and hidden buffers are always excluded."
-  :package-version '(project-headerline . "0.1")
-  :group 'project-headerline
-  :type '(repeat symbol))
-
-(defvar-local project-headerline-current-project nil
-  "Overwrite current project path.
-
-If this variable is set, it is used instead of `project-headerline-detect-alist'
-and `project-headerline-fallback-alist' and defines project name and path.
-
-It can be either a string or a list:
-
- - If it's a string, it should be a path to project directory.  Project name
-   is set to the directory name.
-
- - If it's a list, it should be a plist with project properties, in the same
-   format as returned by `project-headerline-describe-project-function'.
-
-It's convenient to set this from local variables, e.g. in `.dir-locals.el'
-in the project root.")
-
-;; Forward-declate mode variable.
-(defvar project-headerline-mode)
-
-(defun project-headerline--set-variable (symbol value)
-  "Setter for defcustom.
-Assigns value to variable and invokes `project-headerline-reset'."
-  (set-default-toplevel-value symbol value)
-  (project-headerline-reset))
-
-(defvar-local project-headerline--cache nil)
-
-(defmacro project-headerline--cached (key form)
-  "Cached evaluation of form.
-If there is cached value for KEY, return it.
-Otherwise, evaluate FORM, store in cache, and return it."
-  `(let ((cache project-headerline--cache))
-     (unless cache
-       (setq cache (make-hash-table :test 'eq))
-       (setq-local project-headerline--cache cache))
-     (or (gethash ,key cache)
-         (puthash ,key ,form cache))))
-
-(defmacro project-headerline--call (func-or-cons &rest args)
-  "Call user function.
-On error, display warning and return nil."
-  (let ((func (if (consp func-or-cons)
-                  (car func-or-cons)
-                func-or-cons))
-        (name (if (consp func-or-cons)
-                  (cdr func-or-cons)
-                (symbol-name func-or-cons))))
-    `(condition-case err
-         (funcall ,func ,@args)
-       (error
-        (warn "Caught error from %s: %s" ,name
-              (error-message-string err))
-        nil))))
-
-(defun project-headerline-describe-project ()
-  "Get current project properties.
-Default implementation of `project-headerline-describe-project-function',
-see its docstring for details."
-  (or (project-headerline--project-from-variable)
-      (project-headerline--project-from-detect-alist)
-      (project-headerline--project-from-fallback-alist)))
-
-(defun project-headerline--project-from-variable ()
-  "Get project from `project-headerline-current-project'."
-  (when project-headerline-current-project
-    (cond ((stringp project-headerline-current-project)
-           (list :name (f-filename project-headerline-current-project)
-                 :path (f-full project-headerline-current-project)))
-          ((plistp project-headerline-current-project)
-           project-headerline-current-project)
-          (t
-           (warn "Invalid project-headerline-current-project")
-           nil))))
-
-(defun project-headerline--project-from-detect-alist ()
-  "Get project from `project-headerline-detect-alist'."
-  (seq-some (lambda (method)
-              (let ((allow-remote (plist-get (cdr method) :allow-remote))
-                    (describe-fn (plist-get (cdr method) :describe)))
-                (when (and (or allow-remote
-                               (not (file-remote-p default-directory)))
-                           describe-fn)
-                  (project-headerline--call
-                   (describe-fn . "project-headerline-detect-alist :describe")))))
-            project-headerline-detect-alist))
-
-(defun project-headerline--project-from-fallback-alist ()
-  "Get project from `project-headerline-fallback-alist'."
-  (let* ((directory (project-headerline--buffer-dir))
-         (server (file-remote-p directory)))
-    (when directory
-      (seq-some (lambda (proj)
-                  (let ((proj-name (car proj))
-                        (proj-path (cdr proj)))
-                    (if server
-                        (when (s-prefix-p (expand-file-name (s-concat server proj-path))
-                                          (expand-file-name directory))
-                          (list :name (s-concat server proj-name)
-                                :path (expand-file-name (s-concat server proj-path))))
-                      (when (s-prefix-p (f-full proj-path)
-                                        (f-full directory))
-                        (list :name proj-name
-                              :path (f-full proj-path))))))
-                project-headerline-fallback-alist))))
-
-(defun project-headerline-describe-buffer ()
-  "Get current buffer properties.
-Default implementation of `project-headerline-describe-buffer-function',
-see its docstring for details."
-  (let ((type (project-headerline--buffer-type))
-        (dir (project-headerline--buffer-dir))
-        (name (project-headerline--buffer-name)))
-    (setq name
-          (or (seq-some (lambda (rule)
-                          (let ((from (car rule))
-                                (to (cdr rule)))
-                            (when (string-match from name)
-                              (replace-regexp-in-string from to name))))
-                        project-headerline-rename-alist)
-              name))
-    (list :type type
-          :dir dir
-          :name name)))
-
-(defun project-headerline--buffer-type ()
-  "Detect current buffer's type."
-  (cond
-   ;; dired
-   ((derived-mode-p 'dired-mode)
-    'dir)
-   ;; special
-   ((derived-mode-p 'special-mode)
-    'other)
-   ;; file
-   (buffer-file-name
-    'file)
-   ;; very special
-   (t
-    'other)))
-
-(defun project-headerline--buffer-dir ()
-  "Detect current buffer's directory.
-Returns path with trailing slash or nil."
-  (cond
-   ;; dired
-   ((and (derived-mode-p 'dired-mode)
-         (bound-and-true-p dired-subdir-alist))
-    (f-full (dired-current-directory)))
-   ;; file
-   (buffer-file-name
-    (f-slash (f-parent (f-full buffer-file-name))))
-   ;; cwd
-   (default-directory
-    (f-full default-directory))))
-
-(defun project-headerline--buffer-name ()
-  "Detect current buffer's name.
-For files and directories, returns base name.
-Otherwise returns buffer name."
-  (cond
-   ;; dired
-   ((and (derived-mode-p 'dired-mode)
-         (bound-and-true-p dired-subdir-alist))
-    (f-filename (dired-current-directory)))
-   ;; file
-   (buffer-file-name
-    (f-filename buffer-file-name))
-   ;; other
-   (t
-    (buffer-name))))
-
-;; Forward-declare to ensure they are not byte-compiled as lexical.
-(defvar all-the-icons-scale-factor)
-(defvar all-the-icons-default-adjust)
-
-(defun project-headerline-icon (icon-name icon-face)
-  "Format propertized icon string from icon name and face.
-Default implementation of `project-headerline-icon-function',
-see its docstring for details."
-  (when (functionp 'all-the-icons-material)
-    (let ((all-the-icons-scale-factor 1.0)
-          (all-the-icons-default-adjust -0.15))
-      (when-let* ((icon (all-the-icons-material icon-name :face icon-face))
-                  (space (propertize " " 'font-lock-face 'project-headerline-space)))
-        (s-concat
-         space icon space)))))
-
-(defun project-headerline-width ()
-  "Return maximum number of characters in headerline.
-Default implementation of `project-headerline-width-function',
-see its docstring for details."
-  (window-width))
-
-(defun project-headerline--separator (key default-icon default-char)
-  "Make propertized icon string."
-  (project-headerline--cached
-   key
-   (let ((var-name (intern (format "project-headerline-%s-separator" key)))
-         (face-name (intern (format "project-headerline-%s-separator" key))))
-     (or
-      ;; user variable
-      (symbol-value var-name)
-      ;; default icon
-      (project-headerline--call project-headerline-icon-function
-                                default-icon face-name)
-      ;; default char
-      (let ((char (propertize default-char 'font-lock-face face-name))
-            (space (propertize " " 'font-lock-face 'project-headerline-space)))
-        (s-concat space char space))))))
-
-(defun project-headerline--path-components (root-path path)
-  "Split path from ROOT-PATH to CURR-PATH into components."
-  (let (path-components)
-    (while (and path
-                (or (not root-path)
-                    (not (f-same-p root-path path))))
-      (push (f-filename path) path-components)
-      (setq path (f-parent path)))
-    path-components))
-
-(defun project-headerline-format (project buffer)
-  "Format headerline string for project and buffer.
-Default implementation of `project-headerline-format-function',
-see its docstring for details."
-  (let* ((separator
-          (project-headerline--separator 'segment "chevron_right" ">"))
-         (margin
-          (- (or (car (window-margins)) 0)))
-         (max-width (project-headerline--call
-                     project-headerline-width-function))
-         (max-path (- max-width
-                      (seq-reduce
-                       '+ (seq-map (lambda (segment)
-                                     (if (eq segment 'path-in-project)
-                                         0
-                                       (let ((str (project-headerline--format-segment
-                                                   segment project buffer 0)))
-                                         (unless (s-blank-p str)
-                                           (+ (length separator)
-                                              (length str))))))
-                                   project-headerline-display-segments)
-                       (length separator))))
-         (segments (seq-map
-                    (lambda (segment)
-                      (project-headerline--format-segment
-                       segment project buffer max-path))
-                    project-headerline-display-segments))
-         (headerline (s-join separator
-                             (append '("")
-                                     (seq-remove 's-blank-p
-                                                 segments)))))
-    (put-text-property 0 1 'display `(space :align-to ,margin)
-                       headerline)
-    headerline))
-
-(defun project-headerline--format-segment (segment project buffer max-path)
-  "Build segment with given name."
-  (pcase segment
-    (`project-name
-     (project-headerline--format-project-name
-      project buffer))
-    (`path-in-project
-     (project-headerline--format-path-in-project
-      project buffer max-path))
-    (`buffer-name
-     (project-headerline--format-buffer-name
-      project buffer))))
-
-(defun project-headerline--format-project-name (project buffer)
-  "Build \\='project segment."
-  (ignore buffer)
-  (let ((project-name (plist-get project :name)))
-    (when (s-present-p project-name)
-      (propertize project-name
-                  'font-lock-face 'project-headerline-project-name))))
-
-(defun project-headerline--format-path-in-project (project buffer max-path)
-  "Build \\='path-in-project segment."
-  (let* ((project-path (plist-get project :path))
-         (buffer-type (plist-get buffer :type))
-         (buffer-dir (plist-get buffer :dir))
-         (path-in-project (cond
-                           ;; directory
-                           ((eq buffer-type 'dir)
-                            (if (and (seq-contains-p project-headerline-display-segments
-                                                     'buffer-name)
-                                     (not (f-same-p project-path
-                                                    buffer-dir)))
-                                (f-parent buffer-dir)
-                              buffer-dir))
-                           ;; file or other
-                           (t buffer-dir)))
-         (components (project-headerline--path-components project-path
-                                                          path-in-project))
-         (separator
-          (project-headerline--separator 'path "chevron_right" ">")))
-    (when components
-      (let ((max-components (length components))
-            result)
-        (while (or (not result)
-                   (and (> (length result) max-path 2)
-                        (> max-components 0)))
-          (setq result
-                (s-join separator
-                        (seq-map (lambda (seg)
-                                   (propertize
-                                    seg 'font-lock-face 'project-headerline-path-in-project))
-                                 (if (= max-components (length components))
-                                     components
-                                   (append (list project-headerline-path-ellipsis)
-                                           (seq-drop components
-                                                     (- (length components)
-                                                        max-components)))))))
-          (setq max-components (1- max-components)))
-        result))))
-
-(defun project-headerline--format-buffer-name (project buffer)
-  "Build \\='buffer segment."
-  (let* ((project-path (plist-get project :path))
-         (buffer-type (plist-get buffer :type))
-         (buffer-dir (plist-get buffer :dir))
-         (buffer-name (plist-get buffer :name))
-         (display-name (cond
-                        ;; project root
-                        ((and (eq buffer-type 'dir)
-                              (f-same-p project-path buffer-dir))
-                         ".")
-                        ;; anything else
-                        (t
-                         buffer-name))))
-    (when (s-present-p display-name)
-      (propertize display-name
-                  'font-lock-face 'project-headerline-buffer-name))))
-
-(defun project-headerline--compose ()
-  "Build propertized headerline string."
-  (project-headerline--cached
-   'headerline
-   (or
-    (when-let* ((project (project-headerline--call
-                          project-headerline-describe-project-function))
-                (buffer (project-headerline--call
-                         project-headerline-describe-buffer-function)))
-      (project-headerline--call
-       project-headerline-format-function project buffer))
-    "")))
-
-(defun project-headerline--composer-match (elem func)
-  "Match `header-line-format' element by composer function."
-  (when-let* ((form (car-safe (cdr-safe elem))))
-    (and (eq (car form) :eval)
-         (eq (caadr form) func))))
-
-(defun project-headerline--composer-append (func &rest args)
-  "Add composer function to the head of `header-line-format'."
-  (when (and header-line-format
-             (not (listp header-line-format)))
-    (setq header-line-format
-          (list header-line-format)))
-  (unless (seq-find (lambda (elem)
-                      (project-headerline--composer-match elem func))
-                    header-line-format)
-    (setq header-line-format
-          (append header-line-format
-                  `((t (:eval (,func ,@args))))))))
-
-(defun project-headerline--composer-prepend (func &rest args)
-  "Add composer function to the tail of `header-line-format'."
-  (when (and header-line-format
-             (not (listp header-line-format)))
-    (setq header-line-format
-          (list header-line-format)))
-  (unless (seq-find (lambda (elem)
-                      (project-headerline--composer-match elem func))
-                    header-line-format)
-    (setq header-line-format
-          (append `((t (:eval (,func ,@args))))
-                  header-line-format))))
-
-(defun project-headerline--composer-remove (func)
-  "Remove composer function from `header-line-format'."
-  (when (listp header-line-format)
-    (setq header-line-format
-          (seq-remove (lambda (elem)
-                        (project-headerline--composer-match elem func))
-                      header-line-format))))
-
-(defun project-headerline--magit-compose (text)
-  "Build magit headerline.
-If `project-headerline-mode' is off, produces same result as original
-`magit-set-header-line-format'.  Otherwise, produces right-aligned
-headerline that can be use together with `project-headerline'."
-  (project-headerline--cached
-   'magit-headerline
-   (s-concat
-    (propertize " " 'display
-                (if project-headerline-mode
-                    (let* ((margin (or (cdr (window-margins)) 0))
-                           (offset (- (length text)
-                                      margin)))
-                      `(space :align-to (- right-margin ,offset)))
-                  '(space :align-to 0)))
-    text)))
-
-(defun project-headerline--magit-advice (orig-fn &rest args)
-  "Wraps magit headrline builder to support `project-headerline' in magit buffers.
-If you don't use project-headerline with magit, no visible changes are made."
-  ;; safety check: don't follow advice if signature doesn't
-  ;; match what it used to be
-  (if (and (eq 1 (length args))
-           (stringp (car args)))
-      (project-headerline--composer-append 'project-headerline--magit-compose
-                                           (car args))
-    (apply orig-fn args)))
-
-(defun project-headerline--rename-file-advice (orig-fn &rest args)
-  "Wraps `rename-file' to update headerline on name change."
-  (unwind-protect
-      (apply orig-fn args)
-    (let ((from (car args))
-          (to (cadr args)))
-      (project-headerline--reset-paths from to))))
-
-(defun project-headerline--add-name-to-file-advice (orig-fn &rest args)
-  "Wraps `add-name-to-file' to update headerline on name change."
-  (unwind-protect
-      (apply orig-fn args)
-    (let ((from (car args))
-          (to (cadr args)))
-      (project-headerline--reset-paths from to))))
-
-(defun project-headerline--rename-buffer-advice (orig-fn &rest args)
-  "Wraps `rename-buffer' to update headerline on name change."
-  (unwind-protect
-      (apply orig-fn args)
-    (project-headerline--reset-buffer)))
-
-(defun project-headerline--enable-maybe ()
-  "Enable `project-headerline-mode' in current buffer, if needed.
-Headerline is enabled if buffer major mode is derived from one of the modes
-in `project-headerline-mode-list'.
-Never enables in minibuffer and hidden buffers."
-  (when (and (not (minibufferp))
-             (not (string-match "^ " (buffer-name)))
-             (seq-some #'derived-mode-p project-headerline-mode-list)
-             (not project-headerline-mode))
-    (project-headerline-mode 1)))
-
-(defun project-headerline--register-advices ()
-  "Register all advices, if not registered yet."
-  (when (featurep 'magit)
-    (advice-add 'magit-set-header-line-format
-                :around #'project-headerline--magit-advice))
-  (advice-add 'rename-file
-              :around #'project-headerline--rename-file-advice)
-  (advice-add 'add-name-to-file
-              :around #'project-headerline--add-name-to-file-advice)
-  (advice-add 'rename-buffer
-              :around #'project-headerline--rename-buffer-advice))
-
-(defun project-headerline--register-hooks ()
-  "Register all hooks."
-  (add-hook 'window-configuration-change-hook
-            #'project-headerline--reset-buffer nil :local)
-  (add-hook 'after-revert-hook
-            #'project-headerline--reset-buffer nil :local)
-  (add-hook 'after-set-visited-file-name-hook
-            #'project-headerline--reset-buffer nil :local))
-
-(defun project-headerline--unregister-hooks ()
-  "Unregister all hooks."
-  (remove-hook 'window-configuration-change-hook
-               #'project-headerline--reset-buffer :local)
-  (remove-hook 'after-revert-hook
-               #'project-headerline--reset-buffer :local)
-  (remove-hook 'after-set-visited-file-name-hook
-               #'project-headerline--reset-buffer :local))
-
-(defun project-headerline--reset-buffer (&optional buffer)
-  "Refresh headerline in given BUFFER (or current)."
-  (with-current-buffer (or buffer (current-buffer))
-    (when (bound-and-true-p project-headerline--cache)
-      (setq-local project-headerline--cache nil))
-    (when project-headerline-mode
-      (force-mode-line-update))))
-
-(defun project-headerline--reset-paths (&rest paths)
-  "Refresh headerline in buffers visiting any of PATHS."
-  (dolist (buffer (buffer-list))
-    (when-let* ((buffer-path (buffer-file-name buffer)))
-      (dolist (path paths)
-        (when (and path (f-same-p buffer-path path))
-          (project-headerline--reset-buffer buffer))))))
-
-;;;###autoload
-(defun project-headerline-reset (&optional buffer)
-  "Forcibly refresh headerline in all buffers.
-If BUFFER is given, refresh only that buffer."
-  (interactive)
-  (if buffer
-      (project-headerline--reset-buffer buffer)
-    (dolist (buffer (buffer-list))
-      (project-headerline--reset-buffer buffer))))
-
-;;;###autoload
-(define-minor-mode project-headerline-mode
-  "Customizable project headerline."
-  :group 'project-headerline
-  :init-value nil
-  :lighter nil
-  (if project-headerline-mode
-      ;; enable mode
-      (progn
-        (project-headerline--composer-prepend 'project-headerline--compose)
-        (project-headerline--register-advices)
-        (project-headerline--register-hooks)
-        (force-mode-line-update))
-    ;; disable mode
-    (project-headerline--unregister-hooks)
-    (project-headerline--composer-remove 'project-headerline--compose)
-    (project-headerline--reset-buffer)
-    (force-mode-line-update)))
-
-;;;###autoload
-(define-globalized-minor-mode global-project-headerline-mode
-  project-headerline-mode
-  project-headerline--enable-maybe
-  :group 'project-headerline)
-
-(provide 'project-headerline)
-;;; project-headerline.el ends here
tools/emacs/lisp/project-x.el
@@ -1,217 +0,0 @@
-;;; project-x.el --- Extra convenience features for project.el -*- lexical-binding: t -*-
-
-;; Copyright (C) 2021  Karthik Chikmagalur
-
-;; Author: Karthik Chikmagalur <karthik.chikmagalur@gmail.com>
-;; URL: https://github.com/karthink/project-x
-;; Version: 0.1.5
-;; Package-Requires: ((emacs "27.1"))
-
-;; This file is NOT part of GNU Emacs.
-
-;; This file is free software; you can redistribute it and/or modify
-;; it under the terms of the GNU General Public License as published by
-;; the Free Software Foundation; either version 3, or (at your option)
-;; any later version.
-;;
-;; This program is distributed in the hope that it will be useful,
-;; but WITHOUT ANY WARRANTY; without even the implied warranty of
-;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-;; GNU General Public License for more details.
-;;
-;; For a full copy of the GNU General Public License
-;; see <http://www.gnu.org/licenses/>.
-;;
-;;; Commentary:
-;;
-;; project-x provides some convenience features for project.el:
-;; - Recognize any directory with a `.project' file as a project.
-;; - Save and restore project files and window configurations across sessions
-;;
-;; COMMANDS:
-;;
-;; project-x-window-state-save : Save the window configuration of currently open project buffers
-;; project-x-window-state-load : Load a previously saved project window configuration
-;;
-;; CUSTOMIZATION:
-;;
-;; `project-x-window-list-file': File to store project window configurations
-;; `project-x-local-identifier': String matched against file names to decide if a
-;; directory is a project
-;; `project-x-save-interval': Interval in seconds between autosaves of the
-;; current project.
-;;
-;; by Karthik Chikmagalur
-;; <karthik.chikmagalur@gmail.com>
-
-;;; Code:
-
-(require 'project)
-(eval-when-compile (require 'subr-x))
-(eval-when-compile (require 'seq))
-(defvar project-prefix-map)
-(defvar project-switch-commands)
-(declare-function project-prompt-project-dir "project")
-(declare-function project--buffer-list "project")
-(declare-function project-buffers "project")
-
-(defgroup project-x nil
-  "Convenience features for the Project library."
-  :group 'project)
-
-;; Persistent project sessions
-;; -------------------------------------
-(defcustom project-x-window-list-file
-  (locate-user-emacs-file "project-window-list")
-  "File in which to save project window configurations by default."
-  :type 'file
-  :group 'project-x)
-
-(defcustom project-x-save-interval nil
-  "Saves the current project state with this interval.
-
-When set to nil auto-save is disabled."
-  :type '(choice (const :tag "Disabled" nil)
-                 integer)
-  :group 'project-x)
-
-(defvar project-x-window-alist nil
-  "Alist of window configurations associated with known projects.")
-
-(defvar project-x-save-timer nil
-  "Timer for auto-saving project state.")
-
-(defun project-x--window-state-write (&optional file)
-  "Write project window states to `project-x-window-list-file'.
-If FILE is specified, write to it instead."
-  (when project-x-window-alist
-    (require 'pp)
-    (unless file (make-directory (file-name-directory project-x-window-list-file) t))
-    (with-temp-file (or file project-x-window-list-file)
-      (insert ";;; -*- lisp-data -*-\n")
-      (let ((print-level nil) (print-length nil))
-        (pp project-x-window-alist (current-buffer))))
-    (message (format "Wrote project window state to %s" project-x-window-list-file))))
-
-(defun project-x--window-state-read (&optional file)
-  "Read project window states from `project-x-window-list-file'.
-If FILE is specified, read from it instead."
-  (and (or file
-           (file-exists-p project-x-window-list-file))
-       (with-temp-buffer
-         (insert-file-contents (or file project-x-window-list-file))
-         (condition-case nil
-             (if-let ((win-state-alist (read (current-buffer))))
-                 (setq project-x-window-alist win-state-alist)
-               (message (format "Could not read %s" project-x-window-list-file)))
-           (error (message (format "Could not read %s" project-x-window-list-file)))))))
-
-(defun project-x-window-state-save (&optional arg)
-  "Save current window state of project.
-With optional prefix argument ARG, query for project."
-  (interactive "P")
-  (when-let* ((dir (cond (arg (project-prompt-project-dir))
-                         ((project-current)
-                          (project-root (project-current)))))
-              (default-directory dir))
-    (unless project-x-window-alist (project-x--window-state-read))
-    (let ((file-list))
-      ;; Collect file-list of all the open project buffers
-      (dolist (buf
-               (funcall (if (fboundp 'project--buffers-list)
-                            #'project--buffers-list
-                          #'project-buffers)
-                        (project-current))
-               file-list)
-        (if-let ((file-name (or (buffer-file-name buf)
-                                (with-current-buffer buf
-                                  (and (derived-mode-p 'dired-mode)
-                                       dired-directory)))))
-            (push file-name file-list)))
-      (setf (alist-get dir project-x-window-alist nil nil 'equal)
-            (list (cons 'files file-list)
-                  (cons 'windows (window-state-get nil t)))))
-    (message (format "Saved project state for %s" dir))))
-
-(defun project-x-window-state-load (dir)
-  "Load the saved window state for project with directory DIR.
-If DIR is unspecified query the user for a project instead."
-  (interactive (list (project-prompt-project-dir)))
-  (unless project-x-window-alist (project-x--window-state-read))
-  (if-let* ((project-x-window-alist)
-            (project-state (alist-get dir project-x-window-alist
-                                      nil nil 'equal)))
-      (let ((file-list (alist-get 'files project-state))
-            (window-config (alist-get 'windows project-state)))
-        (dolist (file-name file-list nil)
-          (find-file file-name))
-        (window-state-put window-config nil 'safe)
-        (message (format "Restored project state for %s" dir)))
-    (message (format "No saved window state for project %s" dir))))
-
-(defun project-x-windows ()
-  "Restore the last saved window state of the chosen project."
-  (interactive)
-  (project-x-window-state-load (project-root (project-current))))
-
-;; Recognize directories as projects by defining a new project backend `local'
-;; -------------------------------------
-(defcustom project-x-local-identifier ".project"
-  "Filename(s) that identifies a directory as a project.
-
-You can specify a single filename or a list of names."
-  :type '(choice (string :tag "Single file")
-                 (repeat (string :tag "Filename")))
-  :group 'project-x)
-
-(cl-defmethod project-root ((project (head local)))
-  "Return root directory of current PROJECT."
-  (cdr project))
-
-(defun project-x-try-local (dir)
-  "Determine if DIR is a non-VC project.
-DIR must include a .project file to be considered a project."
-  (if-let ((root (if (listp project-x-local-identifier)
-                     (seq-some (lambda (n)
-                                 (locate-dominating-file dir n))
-                               project-x-local-identifier)
-                   (locate-dominating-file dir project-x-local-identifier))))
-      (cons 'local root)))
-
-;;;###autoload
-(define-minor-mode project-x-mode
-  "Minor mode to enable extra convenience features for project.el.
-When enabled, save and load project window states.
-Recognize any directory that contains (or whose parent
-contains) a special file as a project."
-  :global t
-  :version "0.10"
-  :lighter ""
-  :group 'project-x
-  (if project-x-mode
-      ;;Turning the mode ON
-      (progn
-        (add-hook 'project-find-functions 'project-x-try-local 90)
-        (add-hook 'kill-emacs-hook 'project-x--window-state-write)
-        (project-x--window-state-read)
-        (define-key project-prefix-map (kbd "w") 'project-x-window-state-save)
-        (define-key project-prefix-map (kbd "j") 'project-x-window-state-load)
-        (if (listp project-switch-commands)
-            (add-to-list 'project-switch-commands
-                         '(?j "Restore windows" project-x-windows) t)
-          (message "`project-switch-commands` is not a list, not adding 'restore windows' command"))
-        (when project-x-save-interval
-          (setq project-x-save-timer
-                (run-with-timer 0 (max project-x-save-interval 5)
-                                #'project-x-window-state-save))))
-    (remove-hook 'project-find-functions 'project-x-try-local 90)
-    (remove-hook 'kill-emacs-hook 'project-x--window-state-write)
-    (define-key project-prefix-map (kbd "w") nil)
-    (define-key project-prefix-map (kbd "j") nil)
-    (when (listp project-switch-commands)
-      (delete '(?j "Restore windows" project-x-windows) project-switch-commands))
-    (when (timerp project-x-save-timer)
-      (cancel-timer project-x-save-timer))))
-
-(provide 'project-x)
-;;; project-x.el ends here
tools/emacs/lisp/vde-buffers.el
@@ -1,11 +0,0 @@
-;;; vde-buffers.el --- -*- lexical-binding: t; -*-
-;; Commentary:
-;;; Helper function related to buffers
-;; Code:
-
-;;;###autoload
-(defun vde/buffer-has-project-p (buffer action)
-  (with-current-buffer buffer (project-current nil)))
-
-(provide 'vde-buffers)
-;;; vde-buffers.el ends here
tools/emacs/lisp/vde-simple.el
@@ -1,24 +0,0 @@
-;;; vde-simple --- Common functions for my configuration -*- lexical-binding: t -*-
-
-;; Copyright (C) 2025 Vincent Demeester
-;; Author: Vincent Demeester <vincent@sbr.pm>
-
-;; This file is NOT part of GNU Emacs.
-;;; Commentary:
-;;
-;; Simple and useful function for a lot of things.
-;;
-;;; Code:
-
-(defvar vde-simple-override-mode-map (make-sparse-keymap)
-  "Key map of `vde-simple-override-mode'.
-Enable that mode to have its key bindings to take effect over those of the major mode.")
-
-(define-minor-mode vde-simple-override-mode
-  "Enable the `vde-simple-override-mode-map'."
-  :init-value nil
-  :global t
-  :keymap vde-simple-override-mode-map)
-
-(provide 'vde-simple)
-;;; vde-simple.el ends here
tools/emacs/lisp/vde-windows.el
@@ -1,35 +0,0 @@
-;;; vde-windows.el --- -*- lexical-binding: t; -*-
-;; Commentary:
-;;; Helper function related to window management
-;; Code:
-
-;;;###autoload
-(defun vde/split-window-below (&optional arg)
-  "Split window below from the parent or from the roo with ARG."
-  (interactive "P")
-  (split-window (if arg (frame-root-window)
-		 (window-parent (selected-window)))
-	       nil 'below nil))
-
-;;;###autoload
-(defun vde/split-window-right (&optional arg)
-  "Split window right from the parent or from the roo with ARG."
-  (interactive "P")
-  (split-window (if arg (frame-root-window)
-		 (window-parent (selected-window)))
-		nil 'right nil))
-
-;;;###autoload
-(defun vde/toggle-window-dedication ()
-  "Toggles window dedication in the selected window."
-  (interactive)
-  (set-window-dedicated-p (selected-window)
-			  (not (window-dedicated-p (selected-window)))))
-
-;;;###autoload
-(defun make-display-buffer-matcher-function (major-modes)
-  (lambda (buffer-name action)
-    (with-current-buffer buffer-name (apply #'derived-mode-p major-modes))))
-
-(provide 'vde-windows)
-;;; vde-windows.el ends here
tools/emacs/transient/history.el
@@ -1,1 +1,20 @@
-nil
\ No newline at end of file
+((denote-transient nil)
+ (magit-blame
+  ("-w"))
+ (magit-branch nil)
+ (magit-commit nil
+	       ("--reset-author"))
+ (magit-dispatch nil)
+ (magit-fetch nil)
+ (magit-gitignore nil)
+ (magit-log
+  ("-n256" "--graph" "--decorate"))
+ (magit-push nil
+	     ("--force-with-lease"))
+ (magit-rebase
+  ("--autostash")
+  nil)
+ (magit-remote
+  ("-f"))
+ (magit-tag nil)
+ (rg-menu nil))
tools/emacs/early-init.el
@@ -1,39 +1,4 @@
-;;; early-init.el --- Early init configuration file -*- lexical-binding: t; -*-
-
-;; Copyright (c) 2020-2023  Vincent Demeester <vincent@sbr.pm>
-
-;; Author: Vincent Demeester <vincent@sbr.pm>
-;; URL: https://git.sr.ht/~vdemeester/home
-;; Version: 0.1.0
-;; Package-Requires: ((emacs "29.1"))
-
-;; This file is NOT part of GNU Emacs.
-
-;; This file is free software: you can redistribute it and/or modify it
-;; under the terms of the GNU General Public License as published by the
-;; Free Software Foundation, either version 3 of the License, or (at
-;; your option) any later version.
-;;
-;; This file is distributed in the hope that it will be useful, but
-;; WITHOUT ANY WARRANTY; without even the implied warranty of
-;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-;; General Public License for more details.
-;;
-;; You should have received a copy of the GNU General Public License
-;; along with this file.  If not, see <http://www.gnu.org/licenses/>.
-
-;;; Commentary:
-
-;; Prior to Emacs 27, the `init.el' was supposed to handle the
-;; initialisation of the package manager, by means of calling
-;; `package-initialize'.  Starting with Emacs 27, the default
-;; behaviour is to start the package manager before loading the init
-;; file.
-;;
-
-;; See my dotfiles: https://git.sr.ht/~vdemeester/home
-
-;;; Code:
+(add-to-list 'load-path (locate-user-emacs-file "site-lisp"))
 
 ;; Do not initialize installed packages
 (setopt package-enable-at-startup nil
@@ -73,7 +38,6 @@
 (setq file-name-handler-alist nil
       vc-handled-backends nil)
 
-
 ;; Ignore X resources; its settings would be redundant with the other settings
 ;; in this file and can conflict with later config (particularly where the
 ;; cursor color is concerned).
tools/emacs/init.el
@@ -1,33 +1,50 @@
-;;; init.el --- init configuration file -*- lexical-binding: t; -*-
-
-;; Copyright (c) 2020-2023  Vincent Demeester <vincent@sbr.pm>
+;;; init --- vdemeester's emacs configuration -*- lexical-binding: t -*-
 
+;; Copyright (C) 2025 Vincent Demeester
 ;; Author: Vincent Demeester <vincent@sbr.pm>
-;; URL: https://git.sr.ht/~vdemeester/home
-;; Version: 0.1.0
-;; Package-Requires: ((emacs "29.1"))
 
 ;; This file is NOT part of GNU Emacs.
-
-;; This file is free software: you can redistribute it and/or modify it
-;; under the terms of the GNU General Public License as published by the
-;; Free Software Foundation, either version 3 of the License, or (at
-;; your option) any later version.
-;;
-;; This file is distributed in the hope that it will be useful, but
-;; WITHOUT ANY WARRANTY; without even the implied warranty of
-;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-;; General Public License for more details.
-;;
-;; You should have received a copy of the GNU General Public License
-;; along with this file.  If not, see <http://www.gnu.org/licenses/>.
-
 ;;; Commentary:
-
-;; See my dotfiles: https://git.sr.ht/~vdemeester/home
-
+;; This is the "mini" version for now, but aims to become the default one.
 ;;; Code:
 
+;;; Some constants I am using across the configuration.
+(defconst org-directory "~/desktop/org/"
+  "`org-mode' directory, where most of the org-mode file lives.")
+(defconst org-notes-directory (expand-file-name "notes" org-directory)
+  "`org-mode' notes directory, for notes obviously, most likely managed by denote.")
+(defconst org-inbox-file (expand-file-name "inbox.org" org-directory)
+  "`org-mode' inbox file, where we collect entries to be triaged.")
+(defconst org-todos-file (expand-file-name "todos.org" org-directory)
+  "`org-mode' file for TODOs.  This is the main file for the org angenda entries.")
+(defconst org-journal-file (expand-file-name "journal.org" org-directory)
+  "`org-mode' journal file, for journal-ling.")
+(defconst org-archive-dir (expand-file-name "archive" org-directory)
+  "`org-mode' directory of archived files.")
+(defconst org-people-dir (expand-file-name "people" org-notes-directory)
+  "`org-mode' people files directory, most likely managed by denote.")
+
+;;; The configuration.
+
+;;; Quick access to certain key file using registers
+(set-register ?e `(file . ,(locate-user-emacs-file "init.el")))
+(set-register ?i `(file . ,org-inbox-file))
+(set-register ?t `(file . ,org-todos-file))
+(set-register ?j `(file . ,org-journal-file))
+(set-register ?o `(file . ,org-directory))
+(set-register ?n `(file . ,org-notes-directory))
+(set-register ?P `(file . ,org-people-dir))
+
+;;; Some GC optimizations
+(defun my-minibuffer-setup-hook ()
+  (setq gc-cons-threshold most-positive-fixnum))
+
+(defun my-minibuffer-exit-hook ()
+  (setq gc-cons-threshold 800000000))
+
+(setq gc-cons-threshold most-positive-fixnum)
+
+(run-with-idle-timer 1.2 t 'garbage-collect)
 
 (defconst emacs-start-time (current-time))
 
@@ -38,22 +55,13 @@
 (setq inhibit-default-init t)           ; Disable the site default settings
 
 (setq confirm-kill-emacs #'y-or-n-p)
-(setq initial-major-mode 'fundamental-mode
-      initial-scratch-message nil)
-
-;; Might not work as well on Windows but meh, I don't use it.
-(prefer-coding-system 'utf-8)
-(set-default-coding-systems 'utf-8)
-(set-language-environment 'utf-8)
-(set-selection-coding-system 'utf-8)
-(set-terminal-coding-system 'utf-8)
 
 (setq custom-file (locate-user-emacs-file "custom.el"))
 (setq
-   custom-buffer-done-kill nil          ; Kill when existing
-   custom-buffer-verbose-help nil       ; Remove redundant help text
-   custom-unlispify-tag-names nil       ; Show me the real variable name
-   custom-unlispify-menu-entries nil)
+ custom-buffer-done-kill nil          ; Kill when existing
+ custom-buffer-verbose-help nil       ; Remove redundant help text
+ custom-unlispify-tag-names nil       ; Show me the real variable name
+ custom-unlispify-menu-entries nil)
 ;; Create the custom-file if it doesn't exists
 (unless (file-exists-p custom-file)
   (write-region "" nil custom-file))
@@ -76,39 +84,6 @@
    (put command 'disabled nil))
  '(list-timers narrow-to-region narrow-to-page upcase-region downcase-region))
 
-(defun prot/keyboard-quit-dwim ()
-  "Do-What-I-Mean behaviour for a general `keyboard-quit'.
-
-The generic `keyboard-quit' does not do the expected thing when
-the minibuffer is open.  Whereas we want it to close the
-minibuffer, even without explicitly focusing it.
-
-The DWIM behaviour of this command is as follows:
-
-- When the region is active, disable it.
-- When a minibuffer is open, but not focused, close the minibuffer.
-- When the Completions buffer is selected, close it.
-- In every other case use the regular `keyboard-quit'."
-  (interactive)
-  (cond
-   ((region-active-p)
-    (keyboard-quit))
-   ((derived-mode-p 'completion-list-mode)
-    (delete-completion-window))
-   ((> (minibuffer-depth) 0)
-    (abort-recursive-edit))
-   (t
-    (keyboard-quit))))
-
-(define-key global-map (kbd "C-g") #'prot/keyboard-quit-dwim)
-
-(add-to-list 'load-path (concat user-emacs-directory "/lisp/"))
-(add-to-list 'load-path (concat user-emacs-directory "/lisp/aider.el"))
-(add-to-list 'load-path (concat user-emacs-directory "/lisp/auto-side-windows"))
-(add-to-list 'load-path (concat user-emacs-directory "/lisp/consult-mu"))
-(add-to-list 'load-path (concat user-emacs-directory "/lisp/consult-mu/extras"))
-(add-to-list 'load-path (concat user-emacs-directory "/config/"))
-
 (unless noninteractive
   (defconst font-height 130
     "Default font-height to use.")
@@ -145,59 +120,26 @@ The DWIM behaviour of this command is as follows:
   (set-fontset-font t 'symbol "Segoe UI Emoji" nil 'append)
   (set-fontset-font t 'symbol "Symbola" nil 'append)
 
-  (defvar contrib/after-load-theme-hook nil
-    "Hook run after a color theme is loaded using `load-theme'.")
-
-  (defun contrib/run-after-load-theme-hook (&rest _)
-    "Run `contrib/after-load-theme-hook'."
-    (run-hooks 'contrib/after-load-theme-hook))
-
-  (advice-add #'load-theme :after #'contrib/run-after-load-theme-hook)
-
   (require 'modus-themes)
-  (setq modus-themes-to-toggle '(modus-operandi modus-vivendi)
-	modus-themes-slanted-constructs nil
-	modus-themes-italic-constructs nil
-	modus-themes-bold-constructs nil
-	modus-themes-mixed-fonts t
-	modus-themes-subtle-diffs t
-	modus-themes-fringes 'subtle ; {nil,'subtle,'intense}
-	modus-themes-headings '((0 . (variable-pitch semilight 1.5))
-				(1 . (regular 1.4))
-				(2 . (regular 1.3))
-				(3 . (regular 1.2))
-				(agenda-structure . (variable-pitch light 2.2))
-				(agenda-date . (variable-pitch regular 1.3))
-				(t . (regular 1.15)))
-	modus-themes-intense-paren-match t
-	modus-themes-completions '(opinionated) ; {nil,'moderate,'opinionated}
-	modus-themes-diffs 'desaturated ; {nil,'desaturated,'fg-only}
-	modus-themes-org-blocks 'gray-background
-	modus-themes-paren-match '(subtle-bold)
-	modus-themes-variable-pitch-headings nil
-	modus-themes-rainbow-headings t
-	modus-themes-section-headings nil
-	modus-themes-scale-headings t
-	)
+  (setopt modus-themes-common-palette-overrides modus-themes-preset-overrides-cooler
+	  modus-themes-to-rotate '(modus-operandi modus-vivendi)
+	  modus-themes-mixed-fonts t
+	  modus-themes-headings '((0 . (variable-pitch semilight 1.5))
+				  (1 . (regular 1.4))
+				  (2 . (regular 1.3))
+				  (3 . (regular 1.2))
+				  (agenda-structure . (variable-pitch light 2.2))
+				  (agenda-date . (variable-pitch regular 1.3))
+				  (t . (regular 1.15))))
+  ;; Default modus-operandi on GUI and modus-vivendi on CLI
+  (if (display-graphic-p)
+      (load-theme 'modus-operandi :no-confirm)
+    (load-theme 'modus-vivendi :no-confirm)))
 
-  (defun my-update-active-mode-line-colors ()
-    (set-face-attribute
-     'mode-line nil
-     :foreground (modus-themes-get-color-value 'fg-mode-line-active)
-     :background (modus-themes-get-color-value 'bg-blue-nuanced)))
-  (add-hook 'modus-themes-after-load-theme-hook #'my-update-active-mode-line-colors)
-  (define-key global-map (kbd "C-<f5>") #'modus-themes-toggle)
-
-  (load-theme 'modus-operandi :no-confirm)
-  (my-update-active-mode-line-colors))
-
-(setq load-prefer-newer t)              ; Always load newer compiled files
-(setq ad-redefinition-action 'accept)   ; Silence advice redefinition warnings
-
-;; Init `delight'
-;; (unless (package-installed-p 'delight)
-;;   (package-refresh-contents)
-;;   (package-install 'delight))
+(setopt load-prefer-newer t)              ; Always load newer compiled files
+(setopt ad-redefinition-action 'accept)   ; Silence advice redefinition warnings
+(setopt debug-on-error t)
+(setopt byte-compile-debug t)
 
 ;; Configure `use-package' prior to loading it.
 (eval-and-compile
@@ -208,90 +150,1079 @@ The DWIM behaviour of this command is as follows:
   (setq use-package-enable-imenu-support t)
   (setq use-package-compute-statistics t))
 
-;; (unless (package-installed-p 'use-package)
-;;   (package-refresh-contents)
-;;   (package-install 'use-package))
-
 (eval-when-compile
   (require 'use-package))
 
-(setenv "SSH_AUTH_SOCK" "/run/user/1000/yubikey-agent/yubikey-agent.sock")
-;; (setenv "SSH_AUTH_SOCK" "/run/user/1000/gnupg/S.gpg-agent.ssh")
+(use-package emacs
+  :bind
+  ("C-x m" . mark-defun)
+  ("C-x C-b" . bs-show)
+  ("M-o" . other-window)
+  ("M-j" . duplicate-dwim)
+  ;; (:map completion-preview-active-mode-map
+  ;; ("M-n" . #'completion-preview-next-candidate)
+  ;; ("M-p" . #'completion-preview-prev-candidate))
+  :custom
+  (create-lockfiles nil)   ; No backup files
+  (make-backup-files nil)  ; No backup files
+  (backup-inhibited t)     ; No backup files
+  (tab-always-indent 'complete)
+  (enable-local-variables :all)
+  (select-enable-clipboard t)
+  (select-enable-primary t)
+  (comment-multi-line t)
+  (make-backup-files nil)
+  (read-extended-command-predicate #'command-completion-default-include-p)
+  (mouse-autoselect 1)
+  (completion-cycle-threshold 2)
+  (completion-ignore-case t)
+  (completion-show-inline-help nil)
+  (completions-detailed t)
+  (enable-recursive-minibuffers t)
+  (read-buffer-completion-ignore-case t)
+  (read-file-name-completion-ignore-case t)
+  (find-ls-option '("-exec ls -ldh {} +" . "-ldh"))  ; find-dired results with human readable sizes
+  (switch-to-buffer-obey-display-actions t)
+  :hook
+  (after-init . global-hl-line-mode)
+  (after-init . global-completion-preview-mode)
+  (after-init . auto-insert-mode)
+  (after-init . pixel-scroll-mode)
+  :config
+  (display-time-mode -1)
+  (tooltip-mode -1)
+  (blink-cursor-mode -1)
+  (setenv "GIT_EDITOR" (format "emacs --init-dir=%s " (shell-quote-argument user-emacs-directory)))
+  (setenv "EDITOR" (format "emacs --init-dir=%s " (shell-quote-argument user-emacs-directory)))
+  (delete-selection-mode 1)
+  (defun er-keyboard-quit ()
+    "Smater version of the built-in `keyboard-quit'.
 
-(defconst vde/custom-file (locate-user-emacs-file "custom.el")
-  "File used to store settings from Customization UI.")
+The generic `keyboard-quit' does not do the expected thing when
+the minibuffer is open.  Whereas we want it to close the
+minibuffer, even without explicitly focusing it."
+    (interactive)
+    (if (active-minibuffer-window)
+	(if (minibufferp)
+            (minibuffer-keyboard-quit)
+          (abort-recursive-edit))
+      (keyboard-quit)))
+  (global-set-key [remap keyboard-quit] #'er-keyboard-quit))
 
-;; Remove built-in org-mode
-(require 'cl-seq)
-(setq load-path
-      (cl-remove-if
-       (lambda (x)
-         (string-match-p "org$" x))
-       load-path))
+(use-package passage
+  :commands (passage-get))
 
-;; 2024-07-12: I wonder if I should be explicit instead, as using
-;; `require' explicitly. The benefit would be that I decide the order
-;; they load instead of relying on file-system.
-;; (vde/el-load-dir (concat user-emacs-directory "/config/"))
-(require 'init-func)
-(require 'org-func)
-(require 'project-func)
+(use-package ffap
+  :hook
+  (after-init . ffap-bindings))
 
-;; Make native compilation silent and prune its cache.
-(when (native-comp-available-p)
-  (setq native-comp-async-report-warnings-errors 'silent) ; Emacs 28 with native compilation
-  (setq native-compile-prune-cache t)
-  (setq native-comp-jit-compilation t)
-  (setq native-comp-async-query-on-exit t)) ; Emacs 29
+(use-package icomplete
+  :unless noninteractive
+  :hook
+  (icomplete-minibuffer-setup
+   . (lambda()(interactive) 
+       (setq-local completion-styles '(flex partial-completion initials basic))))
+  (after-init . fido-vertical-mode)
+  :custom
+  (icomplete-compute-delay 0.01))
 
-(setq byte-compile-warnings '(not free-vars unresolved noruntime lexical make-local))
+(use-package display-line-numbers
+  :unless noninteractive
+  :hook (prog-mode . display-line-numbers-mode)
+  :config
+  (setq-default display-line-numbers-type 'relative)
+  (defun vde/toggle-line-numbers ()
+    "Toggles the display of line numbers.  Applies to all buffers."
+    (interactive)
+    (if (bound-and-true-p display-line-numbers-mode)
+        (display-line-numbers-mode -1)
+      (display-line-numbers-mode)))
+  :bind ("<f7>" . vde/toggle-line-numbers))
 
-;; Refactor this completely. Reduce to the minimum.
-(unless noninteractive
-  (require '00-clean) ;; Maybe refactor no-littering
-  (require 'config-keybindings)
-  (require 'config-editing)
-  (require 'config-files)
-  (require 'config-misc)
-  (require 'config-appearance)
-  (require 'config-buffers)
-  (require 'config-compile)
-  (require 'config-completion)
-  (require 'config-dired)
-  (require 'config-mouse)
-  (require 'config-navigating)
-  (require 'config-org)
-  (require 'config-programming)
-  (require 'config-projects)
-  (require 'config-search)
-  (require 'config-shells)
-  (require 'config-vcs)
-  (require 'config-web)
-  (require 'config-windows)
-  (require 'config-llm)
-  (require 'programming-config)
-  (require 'programming-containers)
-  (require 'programming-cue)
-  (require 'programming-elisp)
-  (require 'programming-eglot)
-  (require 'programming-go)
-  (require 'programming-js)
-  (require 'programming-nix)
-  (require 'programming-treesitter)
-  (require 'programming-web)
-  (require 'config-mu4e))
+(use-package helpful
+  :unless noninteractive
+  :bind (("C-h f" . helpful-callable)
+         ("C-h F" . helpful-function)
+         ("C-h M" . helpful-macro)
+         ("C-c h S" . helpful-at-point)
+         ("C-h k" . helpful-key)
+         ("C-h v" . helpful-variable)
+         ("C-h C" . helpful-command)))
 
-(if (file-exists-p (downcase (concat user-emacs-directory "/hosts/" (vde/short-hostname) ".el")))
-    (load-file (downcase (concat user-emacs-directory "/hosts/" (vde/short-hostname) ".el"))))
+(use-package flymake
+  :bind
+  ("C-c f b" . flymake-show-buffer-diagnostics)
+  :hook
+  (prog-mode . flymake-mode))
 
-(let ((elapsed (float-time (time-subtract (current-time)
-                                          emacs-start-time))))
-  (message "Loading %s...done (%.3fs)" load-file-name elapsed))
+(use-package aggressive-indent
+  :commands (aggressive-indent-mode)
+  :hook
+  (emacs-lisp-mode . aggressive-indent-mode))
 
-(add-hook 'after-init-hook
-          `(lambda ()
-             (let ((elapsed
-                    (float-time
-                     (time-subtract (current-time) emacs-start-time))))
-               (message "Loading %s...done (%.3fs) [after-init]"
-                        ,load-file-name elapsed))) t)
+(use-package save-place
+  :defer 1
+  :config (save-place-mode 1))
+
+(use-package symbol-overlay
+  :custom
+  (symbol-overlay-idle-time 0.2)
+  :bind
+  ("M-s s i" . symbol-overlay-put)
+  ("M-N" . symbol-overlay-jump-next)
+  ("M-P" . symbol-overlay-jump-prev)
+  ("M-s s r" . symbol-overlay-rename)
+  ("M-s s c" . symbol-overlay-remove-all)
+  :hook
+  (prog-mode . symbol-overlay-mode))
+
+(use-package savehist
+  :unless noninteractive
+  :hook (after-init . savehist-mode)
+  :custom
+  (history-length 10000)
+  (savehist-save-minibuffer-history t)
+  (savehist-delete-duplicates t)
+  (savehist-autosave-interval 180)
+  (savehist-additional-variables '(extended-command-history
+				   search-ring
+				   regexp-search-ring
+				   comint-input-ring
+				   compile-history
+				   last-kbd-macro
+				   shell-command-history)))
+
+(use-package which-key
+  :custom
+  (which-key-separator " → " )
+  (which-key-prefix-prefix "… ")
+  (which-key-add-column-padding 1)
+  (which-key-max-description-length 40)
+  (which-key-idle-delay 1)
+  (which-key-idle-secondary-delay 0.25)
+  :hook
+  (after-init . which-key-mode)
+  :config
+  
+  ;; Define custom, concise descriptions for `tab-bar` commands under "C-x t"
+  (which-key-add-key-based-replacements
+    "C-c !"     "flymake"
+    "C-x t C-f" "Open file in new tab"
+    "C-x t RET" "Switch tabs"
+    "C-x t C-r" "Open file (read-only) in new tab"
+    "C-x t 0"   "Close current tab"
+    "C-x t 1"   "Close other tabs"
+    "C-x t 2"   "New empty tab"
+    "C-x t G"   "Group tabs"
+    "C-x t M"   "Move tab to position"
+    "C-x t N"   "New tab and switch to it"
+    "C-x t O"   "Previous tab"
+    "C-x t b"   "Switch buffer in new tab"
+    "C-x t d"   "Dired in new tab"
+    "C-x t f"   "Open file in new tab"
+    "C-x t m"   "Move tab left/right"
+    "C-x t n"   "Duplicate tab"
+    "C-x t o"   "Next tab"
+    "C-x t p"   "Project in new tab"
+    "C-x t r"   "Rename tab"
+    "C-x t t"   "Switch to other tab"
+    "C-x t u"   "Undo tab close"
+    "C-x t ^ f" "Detach tab window"
+    "C-x 8" "insert-special"
+    "C-x 8 ^" "superscript (⁰, ¹, ², …)"
+    "C-x 8 _" "subscript (₀, ₁, ₂, …)"
+    "C-x 8 a" "arrows & æ (←, →, ↔, æ)"
+    "C-x 8 e" "emojis (🫎, 🇧🇷, 🇮🇹, …)"
+    "C-x 8 *" "common symbols ( , ¡, €, …)"
+    "C-x 8 =" "macron (Ā, Ē, Ḡ, …)"
+    "C-x 8 N" "macron (№)"
+    "C-x 8 O" "macron (œ)"
+    "C-x 8 ~" "tilde (~, ã, …)"
+    "C-x 8 /" "stroke (÷, ≠, ø, …)"
+    "C-x 8 ." "dot (·, ż)"
+    "C-x 8 ," "cedilla (¸, ç, ą, …)"
+    "C-x 8 '" "acute (á, é, í, …)"
+    "C-x 8 `" "grave (à, è, ì, …)"
+    "C-x 8 \"" "quotation/dieresis (\", ë, ß, …)"
+    "C-x 8 1" "†, 1/…"
+    "C-x 8 2" "‡"
+    "C-x 8 3" "3/…"
+    "C-x 4" "other-window"
+    "C-x 5" "other-frame"))
+
+(use-package newcomment
+  :unless noninteractive
+  :custom
+  (comment-empty-lines t)
+  (comment-fill-column nil)
+  (comment-multi-line t)
+  (comment-style 'multi-line)
+  :config
+  (defun prot/comment-dwim (&optional arg)
+    "Alternative to `comment-dwim': offers a simple wrapper
+    around `comment-line' and `comment-dwim'.
+
+    If the region is active, then toggle the comment status of the
+    region or, if the major mode defines as much, of all the lines
+    implied by the region boundaries.
+
+    Else toggle the comment status of the line at point."
+    (interactive "*P")
+    (if (use-region-p)
+        (comment-dwim arg)
+      (save-excursion
+        (comment-line arg))))
+  :bind (("C-;" . prot/comment-dwim)
+    ("C-:" . comment-kill)
+    ("M-;" . comment-indent)
+    ("C-x C-;" . comment-box)))
+
+(use-package dired
+  :custom
+  (dired-hide-details-hide-information-lines 'nil)
+  (dired-kill-when-opening-new-dired-buffer 't)
+  :bind
+  (:map dired-mode-map
+	("E"   . wdired-change-to-wdired-mode)
+	("l"   . dired-find-file))
+  :hook
+  (dired-mode . dired-omit-mode)
+  (dired-mode . dired-hide-details-mode)
+  (dired-mode . dired-sort-toggle-or-edit))
+
+(use-package alert
+  :defer 2
+  :init
+  (defun alert-after-finish-in-background (buf str)
+    (when (or (not (get-buffer-window buf 'visible)) (not (frame-focus-state)))
+      (alert str :buffer buf)))
+  :config
+  (setq alert-default-style 'libnotify))
+
+(use-package elec-pair
+  :hook (after-init-hook . electric-pair-mode))
+
+(use-package uniquify
+  :custom
+  (uniquify-buffer-name-style 'forward)
+  (uniquify-strip-common-suffix t)
+  (uniquify-after-kill-buffer-p t))
+
+(use-package compile
+  :unless noninteractive
+  :commands (compile)
+  :custom
+  (compilation-always-kill t)
+  (compilation-scroll-output t)
+  (ansi-color-for-compilation-mode t)
+  :config
+  (add-hook 'compilation-finish-functions #'alert-after-finish-in-background))
+
+(use-package subword
+  :diminish
+  :hook (prog-mode-hook . subword-mode))
+
+;; Recentf
+(use-package recentf
+  :defer t
+  :hook
+  (after-nit . recentf-mode)
+  :bind (("C-x C-r" . recentf-open)))
+
+(use-package prog-mode
+  :hook
+  (prog-mode . eldoc-mode)
+  :custom
+  (eldoc-idle-delay 0.2))
+
+(use-package eglot
+  :bind
+  (:map eglot-mode-map
+        ("C-c e a" . eglot-code-actions)
+        ("C-c e r" . eglot-reconnect)
+        ("<f2>" . eglot-rename)
+        ("C-c e ?" . eldoc-print-current-symbol-info))
+  :custom
+  (eglot-autoshutdown t)
+  (eglot-confirm-server-initiated-edits nil)
+  :config
+  (add-to-list 'eglot-ignored-server-capabilities :documentHighlightProvider)
+  (add-to-list 'eglot-server-programs `(json-mode  "vscode-json-language-server" "--stdio"))
+  (add-to-list 'eglot-server-programs '(nix-mode . ("nil")))
+  (setq-default eglot-workspace-configuration
+		'(
+		  :gopls (
+			  :usePlaceholders t
+			  ;; See https://github.com/golang/tools/blob/master/gopls/doc/analyzers.md
+			  :analyses (
+				     :QF1006 t
+				     :QF1007 t
+				     :S1002 t
+				     :S1005 t
+				     :S1006 t
+				     :S1008 t
+				     :S1025 t
+				     :SA1003 t
+				     :SA1014 t
+				     :SA1015 t
+				     :SA1023 t
+				     :SA1032 t
+				     :SA2002 t
+				     :SA4023 t
+				     :SA4031 t
+				     :SA5000 t
+				     :SA5010 t
+				     :SA5000 t
+				     :SA6000 t
+				     :SA6001 t
+				     :SA6002 t
+				     :SA6003 t
+				     :SA9003 t
+				     :SA9007 t
+				     :ST1000 t
+				     :ST1001 t
+				     :ST1005 t
+				     :ST1013 t
+				     :ST1015 t
+				     :ST1016 t
+				     :ST1017 t
+				     :ST1019 t
+				     :ST1020 t
+				     :ST1021 t
+				     :ST1022 t
+				     :ST1023 t
+				     :shadow t
+				     )
+			  ;; See https://github.com/golang/tools/blob/master/gopls/doc/inlayHints.md
+			  :hints (:constantValues t :compositeLiteralTypes t :compositeLiteralFields t))
+		  :nil (
+			:formatting (:command ["nixfmt"])
+			:nix (
+			      :maxMemoryMB 2560
+			      :autoEvalInputs t
+			      :nixpkgsInputName "nixpkgs"
+			      )
+			)
+		  :pylsp (
+			  :configurationSources ["flake8"]
+			  :plugins (:pycodestyle (:enabled nil)
+						 :black (:enabled t)
+						 :mccabe (:enabled nil)
+						 :flake8 (:enabled t)))))
+  (defun eglot-format-buffer-on-save ()
+    (if (and (project-current) (eglot-managed-p))
+        (add-hook 'before-save-hook #'eglot-format-buffer nil 'local)
+      (remove-hook 'before-save-hook #'eglot-format-buffer 'local)))
+  (add-hook 'eglot-managed-mode-hook #'eglot-format-buffer-on-save)
+  :hook
+  ;; (before-save . gofmt-before-save)
+  ;; (before-save . eglot-format-buffer)
+  (nix-mode . eglot-ensure)
+  (nix-ts-mode . eglot-ensure)
+  (rust-mode . eglot-ensure)
+  (rust-ts-mode . eglot-ensure)
+  (python-mode . eglot-ensure)
+  (python-ts-mode . eglot-ensure)
+  (go-mode . eglot-ensure)
+  (go-ts-mode . eglot-ensure)
+  (sh-mode . eglot-ensure)
+  (sh-script-mode . eglot-ensure))
+
+(setq major-mode-remap-alist
+      '((python-mode . python-ts-mode)
+	(go-mode . go-ts-mode)))
+
+(use-package markdown-mode
+  :mode "\\.md\\'")
+
+(use-package yaml-ts-mode
+  :mode "\\.yaml\\'")
+
+(use-package go-ts-mode
+  :mode (("\\.go$" . go-ts-mode)
+         ("\\.go" . go-ts-mode)
+         ("\\.go\\'" . go-ts-mode)))
+
+(use-package nix-ts-mode
+  :if (executable-find "nix")
+  :mode ("\\.nix\\'" "\\.nix.in\\'"))
+
+(use-package nix-drv-mode
+  :if (executable-find "nix")
+  :after nix-mode
+  :mode "\\.drv\\'")
+
+(use-package nix-shell
+  :if (executable-find "nix")
+  :after nix-mode
+  :commands (nix-shell-unpack nix-shell-configure nix-shell-build))
+
+(use-package nixpkgs-fmt
+  :if (executable-find "nix")
+  :after nix-ts-mode
+  :custom
+  (nixpkgs-fmt-command "nixfmt")
+  :config
+  (add-hook 'nix-ts-mode-hook 'nixpkgs-fmt-on-save-mode))
+
+(use-package minions
+  :hook (after-init . minions-mode)
+  :config
+  (add-to-list 'minions-prominent-modes 'flymake-mode))
+
+(use-package vundo
+  :bind (("M-u"   . undo)
+         ("M-U"   . undo-redo)
+         ("C-x u" . vundo)))
+
+(use-package vde-vcs
+  :commands (vde/gh-get-current-repo vde/vc-browse-remote)
+  :bind (("C-x v B" . vde/vc-browse-remote)))
+
+(use-package project-func
+  :commands (vde/project-magit-status vde/project-eat vde/project-vterm vde/project-run-in-vterm vde/project-try-local vde/open-readme))
+
+(use-package project
+  :commands (project-find-file project-find-regexp)
+  :custom
+  (project-switch-commands '((?f "File" project-find-file)
+			     (?g "Grep" project-find-regexp)
+			     (?d "Dired" project-dired)
+			     (?b "Buffer" project-switch-to-buffer)
+			     (?q "Query replace" project-query-replace-regexp)
+			     (?m "Magit" vde/project-magit-status)
+			     (?e "Eshell" project-eshell)
+			     (?E "Eat" vde/project-eat)
+			     (?s "Vterm" vde/project-vterm)
+			     (?R "README" vde/open-readme)
+			     (?g "Checkout GitHub PR" checkout-github-pr)))
+  (project-mode-line t)
+  (project-compilation-buffer-name-function 'project-prefixed-buffer-name)
+  (project-vc-extra-root-markers '(".project" "Cargo.toml" "pyproject.toml" "requirements.txt" "go.mod"))
+  :bind
+  ("C-x p v" . vde/project-magit-status)
+  ("C-x p s" . vde/project-vterm)
+  ("C-x p X" . vde/project-run-in-vterm)
+  ("C-x p E" . vde/project-eat)
+  ("C-x p G" . checkout-github-pr)
+  ("C-x p F" . flymake-show-project-diagnostics))
+
+(use-package magit
+  :unless noninteractive
+  :commands (magit-status magit-clone magit-pull magit-blame magit-log-buffer-file magit-log)
+  :bind (("C-c v c" . magit-commit)
+         ("C-c v C" . magit-checkout)
+         ("C-c v b" . magit-branch)
+         ("C-c v d" . magit-dispatch)
+         ("C-c v f" . magit-fetch)
+         ("C-c v g" . magit-blame)
+         ("C-c v l" . magit-log-buffer-file)
+         ("C-c v L" . magit-log)
+         ("C-c v p" . magit-pull)
+         ("C-c v P" . magit-push)
+         ("C-c v r" . magit-rebase)
+	 ("C-c v s" . magit-stage)
+         ("C-c v v" . magit-status))
+  :custom
+  (magit-save-repository-buffers 'dontask)
+  (magit-refs-show-commit-count 'all)
+  (magit-branch-prefer-remote-upstream '("main"))
+  (magit-display-buffer-function #'magit-display-buffer-fullframe-status-v1)
+  (magit-bury-buffer-function #'magit-restore-window-configuration)
+  (magit-refresh-status-buffer nil)
+  :config
+  ;; cargo-culted from https://github.com/magit/magit/issues/3717#issuecomment-734798341
+  ;; valid gitlab options are defined in https://docs.gitlab.com/ee/user/project/push_options.html
+  ;;
+  ;; the second argument to transient-append-suffix is where to append
+  ;; to, not sure what -u is, but this works
+  (transient-append-suffix 'magit-push "-u"
+    '(1 "=s" "Skip gitlab pipeline" "--push-option=ci.skip"))
+  (transient-append-suffix 'magit-push "=s"
+    '(1 "=m" "Create gitlab merge-request" "--push-option=merge_request.create"))
+  (transient-append-suffix 'magit-push "=m"
+    '(1 "=o" "Set push option" "--push-option="))  ;; Will prompt, can only set one extra
+  )
+
+(use-package ediff
+  :commands (ediff ediff-files ediff-merge ediff3 ediff-files3 ediff-merge3)
+  :custom
+  (ediff-window-setup-function 'ediff-setup-windows-plain)
+  (ediff-split-window-function 'split-window-horizontally)
+  (ediff-diff-options "-w")
+  :hook
+  (ediff-after-quit-hook-internal . winner-undo))
+
+(use-package diff
+  :custom
+  (diff-default-read-only nil)
+  (diff-advance-after-apply-hunk t)
+  (diff-update-on-the-fly t)
+  (diff-refine 'font-lock)
+  (diff-font-lock-prettify nil)
+  (diff-font-lock-syntax nil))
+
+(use-package gitconfig-mode
+  :commands (gitconfig-mode)
+  :mode (("/\\.gitconfig\\'"  . gitconfig-mode)
+         ("/\\.git/config\\'" . gitconfig-mode)
+         ("/git/config\\'"    . gitconfig-mode)
+         ("/\\.gitmodules\\'" . gitconfig-mode)))
+
+(use-package gitignore-mode
+  :commands (gitignore-mode)
+  :mode (("/\\.gitignore\\'"        . gitignore-mode)
+         ("/\\.git/info/exclude\\'" . gitignore-mode)
+         ("/git/ignore\\'"          . gitignore-mode)))
+
+(use-package gitattributes-mode
+  :commands (gitattributes-mode)
+  :mode (("/\\.gitattributes" . gitattributes-mode)))
+
+(use-package diff-hl
+  :hook (find-file . diff-hl-mode)
+  :hook (prog-mode . diff-hl-mode)
+  :hook (magit-post-refresh . diff-hl-magit-post-refresh)
+  :bind
+  (:map diff-hl-command-map
+	("n" . diff-hl-next-hunk)
+	("p" . diff-hl-previous-hunk)
+	("[" . nil)
+	("]" . nil)
+	("DEL"   . diff-hl-revert-hunk)
+	("<delete>" . diff-hl-revert-hunk)
+	("SPC" . diff-hl-mark-hunk)
+	:map vc-prefix-map
+	("n" . diff-hl-next-hunk)
+	("p" . diff-hl-previous-hunk)
+	("s" . diff-hl-stage-dwim)
+	("DEL"   . diff-hl-revert-hunk)
+	("<delete>" . diff-hl-revert-hunk)
+	("SPC" . diff-hl-mark-hunk))
+  :config
+  (put 'diff-hl-inline-popup-hide
+       'repeat-map 'diff-hl-command-map))
+
+(use-package diff-hl-inline-popup
+  :after (diff-hl))
+(use-package diff-hl-show-hunk
+  :after (diff-hl))
+
+(use-package diff-hl-dired
+  :after (diff-hl)
+  :hook (dired-mode . diff-hl-dired-mode))
+
+(use-package corfu
+  :custom
+  (corfu-auto 't)
+  :bind
+  (:map corfu-map
+        ("TAB" . corfu-next)
+	("C-c" . corfu-quit)
+        ([tab] . corfu-next)
+        ("S-TAB" . corfu-previous)
+        ([backtab] . corfu-previous))
+  :hook
+  (after-init . global-corfu-mode))
+
+(use-package corfu-history
+  :after (corfu)
+  :hook
+  (after-init . corfu-history-mode))
+
+(use-package corfu-popupinfo
+  :after corfu
+  :config
+  (corfu-popupinfo-mode 1))
+
+(use-package corfu-terminal
+  :unless (display-graphic-p)
+  :ensure t
+  :hook
+  (after-init . corfu-terminal-mode))
+
+(use-package envrc
+  :defer 2
+  :if (executable-find "direnv")
+  :bind (:map envrc-mode-map
+              ("C-c e" . envrc-command-map))
+  :config (envrc-global-mode))
+
+(use-package cape
+  :init
+  (add-hook 'completion-at-point-functions #'cape-dabbrev)
+  (add-hook 'completion-at-point-functions #'cape-file)
+  (add-hook 'completion-at-point-functions #'cape-elisp-block))
+
+(use-package winner
+  :unless noninteractive
+  :hook
+  (after-init . winner-mode))
+
+(use-package windmove
+  :bind
+  ("S-<up>" . windmove-up)
+  ("S-<left>" . windmove-left)
+  ("S-<right>" . windmove-right)
+  ("S-<down>" . windmove-down)
+  ("M-S-<up>" . windmove-swap-states-up)
+  ("M-S-<left>" . windmove-swap-states-left)
+  ("M-S-<right>" . windmove-swap-states-right)
+  ("M-S-<down>" . windmove-swap-states-down))
+
+(use-package window
+  :unless noninteractive
+  :commands (shrink-window-horizontally shrink-window enlarge-window-horizontally enlarge-window)
+  :bind (("S-C-<left>" . shrink-window-horizontally)
+         ("S-C-<right>" . enlarge-window-horizontally)
+         ("S-C-<down>" . shrink-window)
+         ("S-C-<up>" . enlarge-window)))
+
+;; Prefer ripgrep (rg) if present (instead of grep)
+(setq xref-search-program
+      (cond
+       ((or (executable-find "ripgrep")
+            (executable-find "rg"))
+        'ripgrep)
+       ((executable-find "ugrep")
+        'ugrep)
+       (t
+        'grep)))
+
+(use-package rg
+  :if (executable-find "rg")
+  :commands (rg rg-project rg-dwim)
+  :bind (("M-s r r" . rg)
+         ("M-s r p" . rg-project)
+         ("M-s r s" . rg-dwim))
+  :custom
+  (rg-group-result t)
+  (rg-hide-command t)
+  (rg-show-columns nil)
+  (rg-show-header t)
+  (rg-default-alias-fallback "all")
+  :config
+  (cl-pushnew '("tmpl" . "*.tmpl") rg-custom-type-aliases)
+  (cl-pushnew '("gotest" . "*_test.go") rg-custom-type-aliases)
+  (defun vde/rg-buffer-name ()
+    "Generate a rg buffer name from project if in one"
+    (let ((p (project-root (project-current))))
+      (if p
+	  (format "rg: %s" (abbreviate-file-name p))
+	"rg")))
+  (setq rg-buffer-name #'vde/rg-buffer-name))
+
+(use-package wgrep
+  :unless noninteractive
+  :commands (wgrep-change-to-wgrep-mode)
+  :custom
+  (wgrep-auto-save-buffer t)
+  (wgrep-change-readonly-file t)
+  :bind (:map grep-mode-map
+              ("e" . wgrep-change-to-wgrep-mode)
+              ("C-x C-q" . wgrep-change-to-wgrep-mode)))
+
+(use-package tempel
+  :custom (tempel-path (expand-file-name "templates" user-emacs-directory))
+  :bind (("M-+" . tempel-complete) ;; Alternative tempel-expand
+         ("M-*" . tempel-insert)))
+
+(use-package embark
+  :unless noninteractive
+  :commands (embark-act embark-dwim embark-prefix-help-command)
+  :bind
+  ("C-." . embark-act)
+  ("M-." . embark-dwim)
+  ("C-h b" . embark-bindings)
+  ("C-h B" . embark-bindings-at-point)
+  ("C-h M" . embark-bindings-in-keymap)
+  (:map completion-list-mode-map
+        ("." . embark-act))
+  :custom
+  (embark-indicators '(embark-minimal-indicator
+                       embark-highlight-indicator
+                       embark-isearch-highlight-indicator))
+  (embark-cycle-key ".")
+  (embark-help-key "?"))
+
+(use-package pr-review
+  :commands (pr-review pr-review-open pr-review-submit-review)
+  :custom
+  (pr-review-ghub-host "api.github.com")
+  (pr-review-notification-include-read nil)
+  (pr-review-notification-include-unsubscribed nil))
+
+(use-package pr-review-search
+  :commands (pr-review-search pr-review-search-open pr-review-current-repository pr-review-current-repository-search)
+  :config
+  (defun pr-review-current-repository-search (query)
+    "Run pr-review-search on the current repository."
+    (interactive "sSearch query: ")
+    (pr-review-search (format "is:pr archived:false is:open repo:%s %s" (vde/gh-get-current-repo) query)))
+  
+  (defun pr-review-current-repository ()
+    "Run pr-review-search on the current repository."
+    (interactive)
+    (pr-review-search (format "is:pr archived:false is:open repo:%s" (vde/gh-get-current-repo)))))
+
+(use-package jinx
+  :hook (emacs-startup . global-jinx-mode)
+  :bind (([remap ispell-word] . jinx-correct) ;; ("M-$" . jinx-correct)
+         ("C-M-$" . jinx-languages)))
+
+(use-package eljira
+  :commands (eljira)
+  :ensure nil
+  :load-path "~/src/github.com/sawwheet/eljira/"
+  :custom
+  (eljira-token (passage-get "redhat/issues/token/myji"))
+  (eljira-username "vdemeest@redhat.com")
+  (eljira-url "https://issues.redhat.com"))
+
+(use-package chatgpt-shell
+  :commands (chatgpt-shell)
+  :custom
+  (chatgpt-shell-google-key (passage-get "ai/gemini/api_key"))
+  (chatgpt-shell-openrouter-key (passage-get "ai/openroute/api_key"))
+  (chatgpt-shell-deepseek-key (passage-get "ai/deepseek/api_key")))
+
+;; TODO window management
+;; TODO ORG mode configuration (BIG one)
+(use-package org
+  :if (file-exists-p org-directory)
+  :mode (("\\.org$" . org-mode)
+         ("\\.org.draft$" . org-mode))
+  :commands (org-agenda org-capture)
+  :bind (("C-c o l" . org-store-link)
+         ("C-c o r r" . org-refile)
+	 ;; ("C-c o r R" . vde/reload-org-refile-targets)
+         ("C-c o a a" . org-agenda)
+	 ;; ("C-c o a r" . vde/reload-org-agenda-files)
+	 ;; ("C-c C-x i" . vde/org-clock-in-any-heading)
+         ("C-c o s" . org-sort)
+	 ("C-c O" . org-open-at-point-global)
+         ("<f12>" . org-agenda))
+  :custom
+  (org-use-speed-commands t)
+  (org-special-ctrl-a/e t)
+  (org-special-ctrl-k t)
+  (org-hide-emphasis-markers t)
+  (org-pretty-entities t)
+  (org-ellipsis "…")
+  (org-return-follows-link t)
+  (org-todo-keywords '((sequence "STRT(s)" "NEXT(n)" "TODO(t)" "WAIT(w)" "|" "DONE(d!)" "CANX(c@/!)")))
+  (org-todo-state-tags-triggers '(("CANX" ("CANX" . t))
+                                  ("WAIT" ("WAIT" . t))
+                                  (done ("WAIT"))
+                                  ("TODO" ("WAIT") ("CANX"))
+                                  ("NEXT" ("WAIT") ("CANX"))
+                                  ("DONE" ("WAIT") ("CANX"))))
+  (org-tag-alist
+   '((:startgroup)
+     ("Handson" . ?o)
+     (:grouptags)
+     ("Write" . ?w) ("Code" . ?c)
+     (:endgroup)
+     
+     (:startgroup)
+     ("Handsoff" . ?f)
+     (:grouptags)
+     ("Read" . ?r) ("Watch" . ?W) ("Listen" . ?l)
+     (:endgroup)))
+  (org-log-done 'time)
+  (org-log-redeadline 'time)
+  (org-log-reschedule 'time)
+  (org-log-into-drawer t)
+  ;; https://jeffbradberry.com/posts/2025/05/orgmode-priority-cookies/
+  ;; 1 2 and 3 are high, 4 is default, 5 is "hide / whenever or maybe never"
+  (org-priority-highest 1)
+  (org-priority-lowest  5)
+  (org-priority-default 4)
+  (org-list-demote-modify-bullet '(("+" . "-") ("-" . "+")))
+  (org-agenda-file-regexp "^[a-zA-Z0-9-_]+.org$")
+  (org-agenda-files `(,org-inbox-file ,org-todos-file))
+  (org-agenda-remove-tags t)
+  (org-agenda-span 'day)
+  (org-agenda-start-on-weekday 1)
+  (org-agenda-window-setup 'current-window)
+  (org-agenda-sticky t)
+  (org-agenda-sorting-strategy
+   '((agenda time-up deadline-up scheduled-up todo-state-up priority-down)
+     (todo todo-state-up priority-down deadline-up)
+     (tags todo-state-up priority-down deadline-up)
+     (search todo-state-up priority-down deadline-up)))
+  (org-agenda-custom-commands
+   '(
+     ;; Archive tasks
+     ("#" "To archive" todo "DONE|CANX")
+     ;; TODO take inspiration from those
+     ;; ("$" "Appointments" agenda* "Appointments")
+     ;; ("b" "Week tasks" agenda "Scheduled tasks for this week"
+     ;;  ((org-agenda-category-filter-preset '("-RDV")) ; RDV for Rendez-vous
+     ;;   (org-agenda-use-time-grid nil)))
+     ;; 
+     ;; ;; Review started and next tasks
+     ;; ("j" "STRT/NEXT" tags-todo "TODO={STRT\\|NEXT}")
+     ;; 
+     ;; ;; Review other non-scheduled/deadlined to-do tasks
+     ;; ("k" "TODO" tags-todo "TODO={TODO}+DEADLINE=\"\"+SCHEDULED=\"\"")
+     ;; 
+     ;; ;; Review other non-scheduled/deadlined pending tasks
+     ;; ("l" "WAIT" tags-todo "TODO={WAIT}+DEADLINE=\"\"+SCHEDULED=\"\"")
+     ;; 
+     ;; ;; Review upcoming deadlines for the next 60 days
+     ;; ("!" "Deadlines all" agenda "Past/upcoming deadlines"
+     ;;  ((org-agenda-span 1)
+     ;;   (org-deadline-warning-days 60)
+     ;;   (org-agenda-entry-types '(:deadline))))
+
+     ("d" "Daily Agenda"
+      ((agenda ""
+	       ((org-agenda-span 'day)
+		(org-deadline-warning-days 5)))
+       (tags-todo "+PRIORITY=\"1\""
+		  ((org-agenda-overriding-header "High Priority Tasks")))
+       (todo "NEXT"
+	     ((org-agenda-overriding-header "Next Tasks")))))
+     ("D" "Daily Agenda (old)"
+      ((agenda ""
+	       ((org-agenda-files (vde/all-org-agenda-files))
+		(org-agenda-span 'day)
+		(org-deadline-warning-days 5)))
+       (tags-todo "+PRIORITY=\"A\""
+		  ((org-agenda-files (vde/all-org-agenda-files))
+		   (org-agenda-overriding-header "High Priority Tasks")))
+       (todo "NEXT"
+	     ((org-agenda-files (vde/all-org-agenda-files))
+	      (org-agenda-overriding-header "Next Tasks")))))
+     ("i" "Inbox (triage)"
+      ((tags-todo ".*"
+		  ((org-agenda-files `(,org-inbox-file)) ;; FIXME use constant here
+		   (org-agenda-overriding-header "Unprocessed Inbox Item")))))
+     ("A" "All (old)"
+      ((tags-todo ".*"
+		  ((org-agenda-files (vde/all-org-agenda-files))))))
+     ("u" "Untagged Tasks"
+      ((tags-todo "-{.*}"
+		  ((org-agenda-overriding-header "Untagged tasks")))))
+     ("w" "Weekly Review"
+      ((agenda ""
+	       ((org-agenda-overriding-header "Completed Tasks")
+		(org-agenda-skip-function '(org-agenda-skip-entry-if 'nottodo 'done))
+		(org-agenda-span 'week)))
+       (agenda ""
+	       ((org-agenda-overriding-header "Unfinished Scheduled Tasks")
+		(org-agenda-skip-function '(org-agenda-skip-entry-if 'todo 'done))
+		(org-agenda-span 'week)))))
+     ;; FIXME Should only take into account projects and areas ?
+     ("R" "Review projects" tags-todo "-CANX/"
+      ((org-agenda-overriding-header "Reviews Scheduled")
+       (org-agenda-skip-function 'org-review-agenda-skip)
+       (org-agenda-cmp-user-defined 'org-review-compare)
+       (org-agenda-sorting-strategy '(user-defined-down))))))
+  ;; TODO cleanup this list a bit
+  (org-agenda-category-icon-alist `(("personal"  ,(list (propertize "🏡")))
+				    ("work"  ,(list (propertize "🏢")))
+				    ("appointments"  ,(list (propertize "📅")))
+				    ("health"  ,(list (propertize "⚕️")))
+				    ("systems"  ,(list (propertize "🖥️")))
+				    ("journal"  ,(list (propertize "📝")))
+				    ("project--" ,(list (propertize "💼" )))
+				    ("tekton", (list (propertize "😼")))
+				    ("openshift-pipelines", (list (propertize "🎩")))
+				    ("redhat", (list (propertize "🎩")))
+				    ("area--"  ,(list (propertize"🏢" )))
+				    ("area--home"  ,(list (propertize "🏡")))
+				    ("home"  ,(list (propertize "🏡")))
+				    ("home-services" ,(list (propertize "☕ ")))
+				    ("email"  ,(list (propertize"📨" )))
+				    ("people"  ,(list (propertize"👤" )))
+				    ("machine" ,(list (propertize "🖥️")))
+				    ("website" ,(list (propertize "🌍")))
+				    ("bike" ,(list (propertize "🚴‍♂️")))
+				    ("security" ,(list (propertize "🛡️")))
+				    ("i*" ,(list (propertize "📒")))))
+  (org-agenda-prefix-format '((agenda . " %i %?-12t% s")
+			      (todo . " %i")
+			      (tags . " %i")
+			      (search . " %i")))
+  (org-insert-heading-respect-content t)
+  (org-M-RET-may-split-line '((default . nil)))
+  (org-goto-interface 'outline-path-completion)
+  (org-outline-path-complete-in-steps nil)
+  (org-goto-max-level 2)
+  :bind
+  (:map org-mode-map
+	("C-<left>" . org-shiftleft)
+	("C-<right>" . org-shiftright)
+	("C-<up>" . org-shiftup)
+	("C-<down>" . org-shiftdown))
+  :config
+  (unbind-key "S-<left>" org-mode-map)
+  (unbind-key "S-<right>" org-mode-map)
+  (unbind-key "S-<up>" org-mode-map)
+  (unbind-key "S-<down>" org-mode-map)
+  (unbind-key "M-S-<left>" org-mode-map)
+  (unbind-key "M-S-<right>" org-mode-map)
+  (unbind-key "M-S-<up>" org-mode-map)
+  (unbind-key "M-S-<down>" org-mode-map)
+  (unbind-key "C-S-<left>" org-mode-map)
+  (unbind-key "C-S-<right>" org-mode-map)
+  (unbind-key "C-S-<up>" org-mode-map)
+  (unbind-key "C-S-<down>" org-mode-map))
+
+(use-package org-agenda
+  :after org
+  :commands (org-agenda)
+  :config
+  (unbind-key "S-<left>" org-agenda-mode-map)
+  (unbind-key "S-<right>" org-agenda-mode-map)
+  (unbind-key "S-<up>" org-agenda-mode-map)
+  (unbind-key "S-<down>" org-agenda-mode-map)
+  (unbind-key "C-S-<left>" org-agenda-mode-map)
+  (unbind-key "C-S-<right>" org-agenda-mode-map))
+
+;; Make sure we load org-protocol
+(use-package org-protocol
+  :after org)
+
+(use-package org-tempo
+  :after (org)
+  :custom
+  (org-structure-template-alist '(("a" . "aside")
+				  ("c" . "center")
+				  ("C" . "comment")
+				  ("e" . "example")
+				  ("E" . "export")
+				  ("Ea" . "export ascii")
+				  ("Eh" . "export html")
+				  ("El" . "export latex")
+				  ("q" . "quote")
+				  ("s" . "src")
+				  ("se" . "src emacs-lisp")
+				  ("sE" . "src emacs-lisp :results value code :lexical t")
+				  ("sg" . "src go")
+				  ("sr" . "src rust")
+				  ("sp" . "src python")
+				  ("v" . "verse"))))
+
+(use-package org-capture
+  :after org
+  :commands (org-capture)
+  :config
+
+  (add-to-list 'org-capture-templates
+	       `("j" "Journal entry" item
+		 (file+datetree+prompt ,org-journal-file)
+		 "%U %?\n%i"))
+  
+  ;; TODO: refine this, create a function that reset this
+  (add-to-list 'org-capture-templates
+               `("l" "Link" entry
+                 (file ,org-inbox-file)
+                 "* %a\n%U\n%?\n%i"
+                 :empty-lines 1))
+  (add-to-list 'org-capture-templates
+               `("t" "Tasks"))
+  (add-to-list 'org-capture-templates
+               `("tt" "New task" entry
+                 (file ,org-inbox-file)
+                 "* %?\n:PROPERTIES:\n:CREATED:\t%U\n:END:\n\n%i\n\nFrom: %a"
+                 :empty-lines 1))
+  ;; Refine this
+  (add-to-list 'org-capture-templates
+               `("tr" "PR Review" entry
+                 (file ,org-inbox-file)
+                 "* TODO review gh:%^{issue} :review:\n:PROPERTIES:\n:CREATED:%U\n:END:\n\n%i\n%?\nFrom: %a"
+                 :empty-lines 1))
+  ;; emails
+  (add-to-list 'org-capture-templates
+	       `("m" "Email Workflow"))
+  (add-to-list 'org-capture-templates
+	       `("mf" "Follow Up" entry
+		 (file ,org-inbox-file)
+		 "* TODO Follow up with %:from on %a\nSCHEDULED:%t\nDEADLINE: %(org-insert-time-stamp (org-read-date nil t \"+2d\"))\n\n%i"
+		 :immediate-finish t))
+  (add-to-list 'org-capture-templates
+	       `("mr" "Read Later" entry
+		 (file ,org-inbox-file)
+		 "* TODO Read %:subject\nSCHEDULED:%t\nDEADLINE: %(org-insert-time-stamp (org-read-date nil t \"+2d\"))\n\n%a\n\n%i" :immediate-finish t))
+  ;; (add-to-list 'org-capture-templates
+  ;;              `("m" "Meeting notes" entry
+  ;;                (file+datetree ,org-meeting-notes-file)
+  ;;                (file ,(concat user-emacs-directory "/etc/orgmode/meeting-notes.org"))))
+  
+  (defun vde/window-delete-popup-frame (&rest _)
+    "Kill selected selected frame if it has parameter `prot-window-popup-frame'.
+Use this function via a hook."
+    (when (frame-parameter nil 'vde/window-popup-frame)
+      (delete-frame)))
+
+  (add-to-list 'org-capture-templates
+               `("w" "Writing"))
+  (add-hook 'org-capture-after-finalize-hook #'vde/window-delete-popup-frame)
+  :bind (("C-c o c" . org-capture)))
+
+(use-package org-habit
+  :after org
+  :custom
+  (org-habit-show-habits-only-for-today nil)
+  (org-habit-graph-column 80))
+
+(use-package denote
+  :commands (denote)
+  :bind (("C-c n c" . denote-region)
+	 ("C-c n i" . denote-link-or-create)
+	 ("C-c n b" . denote-backlinks)
+	 ("C-c n F f" . denote-find-link)
+	 ("C-c n F b" . denote-find-backlink))
+  :custom
+  (denote-directory org-notes-directory)
+  (denote-rename-buffer-format "📝 %t")
+  (denote-date-prompt-denote-date-prompt-use-org-read-date t)
+  (denote-prompts '(title keywords))
+  (denote-backlinks-display-buffer-action
+   '((display-buffer-reuse-window
+      display-buffer-in-side-window)
+     (side . bottom)
+     (slot . 99)
+     (window-width . 0.3)
+     (dedicated . t)
+     (preserve-size . (t . t))))
+  :hook (dired-mode . denote-dired-mode)
+  :config
+  (denote-rename-buffer-mode 1)
+  (defun my-denote-always-rename-on-save-based-on-front-matter ()
+    "Rename the current Denote file, if needed, upon saving the file.
+Rename the file based on its front matter, checking for changes in the
+title or keywords fields.
+
+Add this function to the `after-save-hook'."
+    (let ((denote-rename-confirmations nil)
+          (denote-save-buffers t)) ; to save again post-rename
+      (when (and buffer-file-name (denote-file-is-note-p buffer-file-name))
+	(ignore-errors (denote-rename-file-using-front-matter buffer-file-name))
+	(message "Buffer saved; Denote file renamed"))))
+
+  (add-hook 'after-save-hook #'my-denote-always-rename-on-save-based-on-front-matter)
+  
+  (defun vde/org-category-from-buffer ()
+    "Get the org category (#+category:) value from the buffer"
+    (cond
+     ((string-match "__journal.org$" (buffer-file-name))
+      "journal")
+     (t
+      (denote-sluggify (denote--retrieve-title-or-filename (buffer-file-name) 'org))))))
+
+(use-package denote-org
+  :after (denote org)
+  :defer 2)
+
+;; (use-package whisper
+;;   :commands (whisper-run whisper-file)
+;;   :custom
+;;   (whisper-install-whispercpp nil))
+;; TODO gptel configuration (and *maybe* copilot)
+
+(provide 'init)
+;;; init.el ends here
tools/emacs/nano.el
@@ -1,255 +0,0 @@
-;; nano-emacs.el --- NANO Emacs (minimal version)     -*- lexical-binding: t -*-
-
-;; Copyright (c) 2025  Nicolas P. Rougier
-;; Released under the GNU General Public License 3.0
-;; Author: Nicolas P. Rougier <nicolas.rougier@inria.fr>
-;; URL: https://github.com/rougier/nano-emacs
-
-;; This is NANO Emacs in 256 lines, without any dependency 
-;; Usage (command line):  emacs -Q -l nano.el -[light|dark]
-
-;; --- Speed benchmarking -----------------------------------------------------
-(setq init-start-time (current-time))
-
-;; --- Typography stack -------------------------------------------------------
-(set-face-attribute 'default nil
-                    :height 140 :weight 'light :family "Roboto Mono")
-(set-face-attribute 'bold nil :weight 'regular)
-(set-face-attribute 'bold-italic nil :weight 'regular)
-(set-display-table-slot standard-display-table 'truncation (make-glyph-code ?…))
-(set-display-table-slot standard-display-table 'wrap (make-glyph-code ?–))
-
-;; --- Frame / windows layout & behavior --------------------------------------
-(setq default-frame-alist
-      '((height . 44) (width  . 81) (left-fringe . 0) (right-fringe . 0)
-        (internal-border-width . 32) (vertical-scroll-bars . nil)
-        (bottom-divider-width . 0) (right-divider-width . 0)
-        (undecorated-round . t)))
-(modify-frame-parameters nil default-frame-alist)
-(setq-default pop-up-windows nil)
-
-;; --- Activate / Deactivate modes --------------------------------------------
-(tool-bar-mode -1) (menu-bar-mode -1) (blink-cursor-mode -1)
-(global-hl-line-mode 1) (icomplete-vertical-mode 1)
-(pixel-scroll-precision-mode 1)
-
-;; --- Minimal NANO (not a real) theme ----------------------------------------
-(defface nano-default '((t)) "")   (defface nano-default-i '((t)) "")
-(defface nano-highlight '((t)) "") (defface nano-highlight-i '((t)) "")
-(defface nano-subtle '((t)) "")    (defface nano-subtle-i '((t)) "")
-(defface nano-faded '((t)) "")     (defface nano-faded-i '((t)) "")
-(defface nano-salient '((t)) "")   (defface nano-salient-i '((t)) "")
-(defface nano-popout '((t)) "")    (defface nano-popout-i '((t)) "")
-(defface nano-strong '((t)) "")    (defface nano-strong-i '((t)) "")
-(defface nano-critical '((t)) "")  (defface nano-critical-i '((t)) "")
-
-(defun nano-set-face (name &optional foreground background weight)
-  "Set NAME and NAME-i faces with given FOREGROUND, BACKGROUND and WEIGHT"
-
-  (apply #'set-face-attribute `(,name nil
-                                ,@(when foreground `(:foreground ,foreground))
-                                ,@(when background `(:background ,background))
-                                ,@(when weight `(:weight ,weight))))
-  (apply #'set-face-attribute `(,(intern (concat (symbol-name name) "-i")) nil
-                                :foreground ,(face-background 'nano-default)
-                                ,@(when foreground `(:background ,foreground))
-                                :weight regular)))
-
-(defun nano-link-face (sources faces &optional attributes)
-  "Make FACES to inherit from SOURCES faces and unspecify ATTRIBUTES."
-
-  (let ((attributes (or attributes
-                        '( :foreground :background :family :weight
-                           :height :slant :overline :underline :box))))
-    (dolist (face (seq-filter #'facep faces))
-      (dolist (attribute attributes)
-        (set-face-attribute face nil attribute 'unspecified))
-      (set-face-attribute face nil :inherit sources))))
-
-(defun nano-install-theme ()
-  "Install THEME"
-
-  (set-face-attribute 'default nil
-                      :foreground (face-foreground 'nano-default)
-                      :background (face-background 'nano-default))
-  (dolist (item '((nano-default .  (variable-pitch variable-pitch-text
-                                    fixed-pitch fixed-pitch-serif))
-                  (nano-highlight . (hl-line highlight))
-                  (nano-subtle .    (match region
-                                     lazy-highlight widget-field))
-                  (nano-faded .     (shadow
-                                     font-lock-comment-face
-                                     font-lock-doc-face
-                                     icomplete-section
-                                     completions-annotations))
-                  (nano-popout .    (warning
-                                     font-lock-string-face))
-                  (nano-salient .   (success link
-                                     help-argument-name
-                                     custom-visibility
-                                     font-lock-type-face
-                                     font-lock-keyword-face
-                                     font-lock-builtin-face
-                                     completions-common-part))
-                  (nano-strong .    (font-lock-function-name-face
-                                     font-lock-variable-name-face
-                                     icomplete-first-match
-                                     minibuffer-prompt))
-                  (nano-critical .  (error
-                                     completions-first-difference))
-                  (nano-faded-i .   (help-key-binding))
-                  (nano-default-i . (custom-button-mouse
-                                     isearch))
-                  (nano-critical-i . (isearch-fail))
-                  ((nano-subtle nano-strong) . (custom-button
-                                                icomplete-selected-match))
-                  ((nano-faded-i nano-strong) . (show-paren-match))))
-    (nano-link-face (car item) (cdr item)))
-
-  ;; Mode & header lines 
-  (set-face-attribute 'header-line nil
-                      :background 'unspecified
-                      :underline nil
-                      :box `( :line-width 1
-                              :color ,(face-background 'nano-default))
-                      :inherit 'nano-subtle)
-  (set-face-attribute 'mode-line nil
-                      :background (face-background 'default)
-                      :underline (face-foreground 'nano-faded)
-                      :height 40 :overline nil :box nil)
-  (set-face-attribute 'mode-line-inactive nil
-                      :background (face-background 'default)
-                      :underline (face-foreground 'nano-faded)
-                      :height 40 :overline nil :box nil))
-
-(defun nano-light (&rest args)
-  "NANO light theme (based on material colors)"
-
-  (interactive)
-  (nano-set-face 'nano-default "#37474F" "#FFFFFF") ;; Blue Grey / L800
-  (nano-set-face 'nano-strong "#000000" nil 'regular) ;; Black
-  (nano-set-face 'nano-highlight nil "#FAFAFA") ;; Very Light Grey
-  (nano-set-face 'nano-subtle nil "#ECEFF1") ;; Blue Grey / L50
-  (nano-set-face 'nano-faded "#90A4AE") ;; Blue Grey / L300
-  (nano-set-face 'nano-salient "#673AB7") ;; Deep Purple / L500
-  (nano-set-face 'nano-popout "#FFAB91") ;; Deep Orange / L200
-  (nano-set-face 'nano-critical "#FF6F00") ;; Amber / L900
-  (nano-install-theme))
-  
-(defun nano-dark (&rest args)
-  "NANO dark theme (based on nord colors)"
-
-  (interactive)
-  (nano-set-face 'nano-default "#ECEFF4" "#2E3440") ;; Snow Storm 3 
-  (nano-set-face 'nano-strong "#ECEFF4" nil 'regular) ;; Polar Night 0
-  (nano-set-face 'nano-highlight nil "#3B4252")  ;; Polar Night 1
-  (nano-set-face 'nano-subtle nil "#434C5E") ;; Polar Night 2 
-  (nano-set-face 'nano-faded "#677691") ;; 
-  (nano-set-face 'nano-salient "#81A1C1")  ;; Frost 2
-  (nano-set-face 'nano-popout "#D08770") ;; Aurora 1
-  (nano-set-face 'nano-critical "#EBCB8B") ;; Aurora 2
-  (nano-install-theme))
-
-;; --- Command line theme chooser ---------------------------------------------
-(add-to-list 'command-switch-alist '("-dark"  . nano-dark))
-(add-to-list 'command-switch-alist '("-light" . nano-light))
-(if (member "-dark" command-line-args) (nano-dark) (nano-light))
-
-;; --- Minibuffer completion --------------------------------------------------
-(setq tab-always-indent 'complete
-      icomplete-delay-completions-threshold 0
-      icomplete-compute-delay 0
-      icomplete-show-matches-on-no-input t
-      icomplete-hide-common-prefix nil
-      icomplete-prospects-height 9
-      icomplete-separator " . "
-      icomplete-with-completion-tables t
-      icomplete-in-buffer t
-      icomplete-max-delay-chars 0
-      icomplete-scroll t
-      resize-mini-windows 'grow-only
-      icomplete-matches-format nil)
-(bind-key "TAB" #'icomplete-force-complete icomplete-minibuffer-map)
-(bind-key "RET" #'icomplete-force-complete-and-exit icomplete-minibuffer-map)
-
-;; --- Minimal key bindings ---------------------------------------------------
-(defun nano-quit ()
-  "Quit minibuffer from anywhere (code from Protesilaos Stavrou)"
-
-  (interactive)
-  (cond ((region-active-p) (keyboard-quit))
-        ((derived-mode-p 'completion-list-mode) (delete-completion-window))
-        ((> (minibuffer-depth) 0) (abort-recursive-edit))
-        (t (keyboard-quit))))
-
-(defun nano-kill ()
-  "Delete frame or kill emacs if there is only one frame left"
-
-  (interactive)
-  (condition-case nil
-      (delete-frame)
-    (error (save-buffers-kill-terminal))))
-
-(bind-key "C-x k" #'kill-current-buffer)
-(bind-key "C-x C-c" #'nano-kill)
-(bind-key "C-x C-r" #'recentf-open)
-(bind-key "C-g" #'nano-quit)
-(bind-key "M-n" #'make-frame)
-(bind-key "C-z"  nil) ;; No suspend frame
-(bind-key "C-<wheel-up>" nil) ;; No text resize via mouse scroll
-(bind-key "C-<wheel-down>" nil) ;; No text resize via mouse scroll
-
-;; --- Sane settings ----------------------------------------------------------
-(set-default-coding-systems 'utf-8)
-(setq-default indent-tabs-mode nil
-              ring-bell-function 'ignore
-              select-enable-clipboard t)
-
-;; --- OSX Specific -----------------------------------------------------------
-(when (eq system-type 'darwin)
-  (select-frame-set-input-focus (selected-frame))
-  (setq mac-option-modifier nil
-        ns-function-modifier 'super
-        mac-right-command-modifier 'hyper
-        mac-right-option-modifier 'alt
-        mac-command-modifier 'meta))
-
-;; --- Header & mode lines ----------------------------------------------------
-(setq-default mode-line-format "")
-(setq-default header-line-format
-  '(:eval
-    (let ((prefix (cond (buffer-read-only     '("RO" . nano-default-i))
-                        ((buffer-modified-p)  '("**" . nano-critical-i))
-                        (t                    '("RW" . nano-faded-i))))
-          (mode (concat "(" (downcase (cond ((consp mode-name) (car mode-name))
-                                            ((stringp mode-name) mode-name)
-                                            (t "unknow")))
-                        " mode)"))
-          (coords (format-mode-line "%c:%l ")))
-      (list
-       (propertize " " 'face (cdr prefix)  'display '(raise -0.25))
-       (propertize (car prefix) 'face (cdr prefix))
-       (propertize " " 'face (cdr prefix) 'display '(raise +0.25))
-       (propertize (format-mode-line " %b ") 'face 'nano-strong)
-       (propertize mode 'face 'header-line)
-       (propertize " " 'display `(space :align-to (- right ,(length coords))))
-       (propertize coords 'face 'nano-faded)))))
-
-;; --- Minibuffer setup -------------------------------------------------------
-(defun nano-minibuffer--setup ()
-  (set-window-margins nil 3 0)
-  (let ((inhibit-read-only t))
-    (add-text-properties (point-min) (+ (point-min) 1)
-      `(display ((margin left-margin)
-                 ,(format "# %s" (substring (minibuffer-prompt) 0 1))))))
-  (setq truncate-lines t))
-(add-hook 'minibuffer-setup-hook #'nano-minibuffer--setup)
-
-;; --- Speed benchmarking -----------------------------------------------------
-(let ((init-time (float-time (time-subtract (current-time) init-start-time)))
-      (total-time (string-to-number (emacs-init-time "%f"))))
-  (message (concat
-    (propertize "Startup time: " 'face 'bold)
-    (format "%.2fs " init-time)
-    (propertize (format "(+ %.2fs system time)"
-                        (- total-time init-time)) 'face 'shadow))))
tools/emacs/prot-init.el
@@ -1,170 +0,0 @@
-;; From https://protesilaos.com/codelog/2024-11-28-basic-emacs-configuration/
-;; For inspiration
-(setq custom-file (locate-user-emacs-file "custom.el"))
-(load custom-file :no-error-if-file-is-missing)
-
-;;; Set up the package manager
-
-(require 'package)
-(package-initialize)
-
-(add-to-list 'package-archives '("melpa" . "https://melpa.org/packages/"))
-
-(when (< emacs-major-version 29)
-  (unless (package-installed-p 'use-package)
-    (unless package-archive-contents
-      (package-refresh-contents))
-    (package-install 'use-package)))
-
-(add-to-list 'display-buffer-alist
-             '("\\`\\*\\(Warnings\\|Compile-Log\\)\\*\\'"
-               (display-buffer-no-window)
-               (allow-no-window . t)))
-
-;;; Basic behaviour
-
-(use-package delsel
-  :ensure nil
-  :hook (after-init . delete-selection-mode))
-
-(defun prot/keyboard-quit-dwim ()
-  "Do-What-I-Mean behaviour for a general `keyboard-quit'.
-
-The generic `keyboard-quit' does not do the expected thing when
-the minibuffer is open.  Whereas we want it to close the
-minibuffer, even without explicitly focusing it.
-
-The DWIM behaviour of this command is as follows:
-
-- When the region is active, disable it.
-- When a minibuffer is open, but not focused, close the minibuffer.
-- When the Completions buffer is selected, close it.
-- In every other case use the regular `keyboard-quit'."
-  (interactive)
-  (cond
-   ((region-active-p)
-    (keyboard-quit))
-   ((derived-mode-p 'completion-list-mode)
-    (delete-completion-window))
-   ((> (minibuffer-depth) 0)
-    (abort-recursive-edit))
-   (t
-    (keyboard-quit))))
-
-(define-key global-map (kbd "C-g") #'prot/keyboard-quit-dwim)
-
-;;; Tweak the looks of Emacs
-
-;; Those three belong in the early-init.el, but I am putting them here
-;; for convenience.  If the early-init.el exists in the same directory
-;; as the init.el, then Emacs will read+evaluate it before moving to
-;; the init.el.
-(menu-bar-mode 1)
-(scroll-bar-mode 1)
-(tool-bar-mode -1)
-
-(let ((mono-spaced-font "Monospace")
-      (proportionately-spaced-font "Sans"))
-  (set-face-attribute 'default nil :family mono-spaced-font :height 100)
-  (set-face-attribute 'fixed-pitch nil :family mono-spaced-font :height 1.0)
-  (set-face-attribute 'variable-pitch nil :family proportionately-spaced-font :height 1.0))
-
-(use-package modus-themes
-  :ensure t
-  :config
-  (load-theme 'modus-vivendi-tinted :no-confirm-loading))
-
-;; Remember to do M-x and run `nerd-icons-install-fonts' to get the
-;; font files.  Then restart Emacs to see the effect.
-(use-package nerd-icons
-  :ensure t)
-
-(use-package nerd-icons-completion
-  :ensure t
-  :after marginalia
-  :config
-  (add-hook 'marginalia-mode-hook #'nerd-icons-completion-marginalia-setup))
-
-(use-package nerd-icons-corfu
-  :ensure t
-  :after corfu
-  :config
-  (add-to-list 'corfu-margin-formatters #'nerd-icons-corfu-formatter))
-
-(use-package nerd-icons-dired
-  :ensure t
-  :hook
-  (dired-mode . nerd-icons-dired-mode))
-
-;;; Configure the minibuffer and completions
-
-(use-package vertico
-  :ensure t
-  :hook (after-init . vertico-mode))
-
-(use-package marginalia
-  :ensure t
-  :hook (after-init . marginalia-mode))
-
-(use-package orderless
-  :ensure t
-  :config
-  (setq completion-styles '(orderless basic))
-  (setq completion-category-defaults nil)
-  (setq completion-category-overrides nil))
-
-(use-package savehist
-  :ensure nil ; it is built-in
-  :hook (after-init . savehist-mode))
-
-(use-package corfu
-  :ensure t
-  :hook (after-init . global-corfu-mode)
-  :bind (:map corfu-map ("<tab>" . corfu-complete))
-  :config
-  (setq tab-always-indent 'complete)
-  (setq corfu-preview-current nil)
-  (setq corfu-min-width 20)
-
-  (setq corfu-popupinfo-delay '(1.25 . 0.5))
-  (corfu-popupinfo-mode 1) ; shows documentation after `corfu-popupinfo-delay'
-
-  ;; Sort by input history (no need to modify `corfu-sort-function').
-  (with-eval-after-load 'savehist
-    (corfu-history-mode 1)
-    (add-to-list 'savehist-additional-variables 'corfu-history)))
-
-;;; The file manager (Dired)
-
-(use-package dired
-  :ensure nil
-  :commands (dired)
-  :hook
-  ((dired-mode . dired-hide-details-mode)
-   (dired-mode . hl-line-mode))
-  :config
-  (setq dired-recursive-copies 'always)
-  (setq dired-recursive-deletes 'always)
-  (setq delete-by-moving-to-trash t)
-  (setq dired-dwim-target t))
-
-(use-package dired-subtree
-  :ensure t
-  :after dired
-  :bind
-  ( :map dired-mode-map
-    ("<tab>" . dired-subtree-toggle)
-    ("TAB" . dired-subtree-toggle)
-    ("<backtab>" . dired-subtree-remove)
-    ("S-TAB" . dired-subtree-remove))
-  :config
-  (setq dired-subtree-use-backgrounds nil))
-
-(use-package trashed
-  :ensure t
-  :commands (trashed)
-  :config
-  (setq trashed-action-confirmer 'y-or-n-p)
-  (setq trashed-use-header-line t)
-  (setq trashed-sort-key '("Date deleted" . t))
-  (setq trashed-date-format "%Y-%m-%d %H:%M:%S"))