Files
memex/system/backups/!home!amr!org!notes!emacs.org.~18~

2918 lines
92 KiB
Plaintext
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
:PROPERTIES:
:ID: e67fd24d-6988-4c95-935e-c8604810212b
:END:
#+title: Emacs
#+property: header-args :tangle ../../.emacs.d/config.el
* DONE early-init.el
For straight.el to pick up before package.el
#+begin_src elisp :tangle ~/.emacs.d/early-init.el
(setq package-enable-at-startup nil)
#+end_src
* DONE [7/7] .emacs
:LOGBOOK:
- State "DONE" from "DONE" [2024-07-09 Tue 12:11]
- State "DONE" from "TODO" [2023-07-02 Sun 15:02]
:END:
**** DONE Front matter
#+begin_src elisp :tangle ~/.emacs
;;; .emacs --- Global settings
;;; Commentary:
;;; Code:
;; -*- lexical-binding: t; -*-
#+end_src
**** DONE Increase the garbage collection threshold to 500 MB to ease startup
#+begin_src elisp :tangle ~/.emacs
(setq gc-cons-threshold (* 500 1024 1024))
#+end_src
**** DONE Package.el
***** DONE List package archives and initialize them (package.el)
#+begin_src elisp :tangle no
(require 'package)
(setq package-archives '(
("gnu" . "https://elpa.gnu.org/packages/")
("melpa" . "https://melpa.org/packages/")
("nongnu" . "https://elpa.nongnu.org/nongnu/")
)
)
(setq package-install-upgrade-built-in t)
(setq package-check-signature "allow-unsigned")
(gnu-elpa-keyring-update)
(package-initialize)
(package-refresh-contents)
#+end_src
***** DONE Install use-package (package.el)
#+begin_src elisp :tangle no
(unless (package-installed-p 'use-package)
(package-refresh-contents)
(package-install 'use-package)
)
(eval-when-compile (require 'use-package)) ;; allow byte-compile while using use-package
#+end_src
***** DONE Make sure Org is installed (package.el)
#+begin_src elisp :tangle no
(unless (package-installed-p 'org)
(package-install 'org)
)
#+end_src
**** DONE Straight.el
***** DONE Bootstrap Straight.el and install use-package
#+begin_src elisp :tangle ~/.emacs
(eval-and-compile
(defvar bootstrap-version)
(let ((bootstrap-file
(expand-file-name "straight/repos/straight.el/bootstrap.el"
(or (bound-and-true-p straight-base-dir)
user-emacs-directory)))
(bootstrap-version 7))
(unless (file-exists-p bootstrap-file)
(with-current-buffer
(url-retrieve-synchronously "https://raw.githubusercontent.com/radian-software/straight.el/develop/install.el" 'silent 'inhibit-cookies)
(goto-char (point-max))
(eval-print-last-sexp)))
(load bootstrap-file nil 'nomessage))
(straight-use-package 'use-package)
)
#+end_src
***** DONE Integrate use-package and straight
#+begin_src elisp :tangle ~/.emacs
(setq straight-use-package-by-default t)
#+end_src
***** DONE Make sure Org is installed (straight.el)
[[https://github.com/org-roam/org-roam/issues/2361][Freezing Org@9.5.5]] fixes the issue with org-roam resulting in 'Wrong type argument: integer-or-marker-p, nil'
#+begin_src elisp :tangle ~/.emacs
(unless (file-directory-p "~/.emacs.d/straight/versions") (make-directory (concat user-emacs-directory "straight/versions")))
#+end_src
#+begin_src elisp :tangle no
;; :tangle ~/.emacs.d/straight/versions/default.el
;; (("org" . "8ef6205a560cd3a92f8c5f8fe34953b80121c2cb")) ; org@9.5.5
;; (("org" . "5890aca3d29e593640b728308096a052998355b1")) ; org@9.6.7
:gamma
#+end_src
#+begin_src elisp :tangle ~/.emacs
(use-package org)
#+end_src
**** DONE Tangle emacs.org
#+begin_src elisp :tangle ~/.emacs
(require 'ob-tangle)
;; Specify the input file and the output directory
(defvar config-org-file "~/org/notes/emacs.org")
(defvar config-el-file "~/.emacs.d/config.el")
(defvar org-use-property-inheritance t)
;; Tangle emacs.org into config.el and load config.el
(org-babel-tangle-file config-org-file)
(load-file config-el-file)
#+end_src
**** DONE Garbage collector - decrease threshold to 5 MB
#+begin_src elisp :tangle ~/.emacs
(add-hook 'after-init-hook (lambda () (setq gc-cons-threshold (* 5 1024 1024))))
#+end_src
**** DONE End matter
#+begin_src elisp :tangle ~/.emacs
(provide '.emacs)
;;; .emacs ends here
#+end_src
* TODO [2/12] config.el and custom.el
This Emacs configuration file is a fork of [[https://sriramkswamy.github.io/dotemacs/][Sri Ramkswamy's]] and [[https://pages.sachachua.com/.emacs.d/Sacha.html][Sacha Chusa's]] settings. I am sure there is much more to learn from them as I go. Worth revisiting.
** TODO [9/10] Startup and general configurations
:LOGBOOK:
- State "DONE" from "TODO" [2024-07-10 Wed 10:45]
:END:
*** DONE Front matter
#+begin_src elisp
;;; Package --- Summary
;;; Commentary:
;;; Code:
;; -*- lexical-binding: t; -*-
#+end_src
#+begin_src elisp :tangle ~/.emacs.d/custom.el
;;; Package --- Summary
;;; Commentary:
;;; Code:
;; -*- lexical-binding: t; -*-
#+end_src
*** DONE Run Emacs as a server
#+begin_src elisp
(require 'server)
(unless (server-running-p) (server-start))
(defvar server-max-buffers 100)
#+end_src
*** DONE Custom file
#+begin_src elisp
(setq custom-file (expand-file-name "custom.el" user-emacs-directory))
(when (file-exists-p custom-file) (load custom-file))
#+end_src
*** DONE [[https://github.com/jwiegley/use-package][use-package]]
:PROPERTIES:
:CLOSED: [2023-01-22 Sun 09:36]
:END:
:LOGBOOK:
- State "DONE" from "CNCL" [2024-07-16 Tue 18:02]
:END:
"A use-package declaration for simplifying your .emacs"
#+begin_src elisp
(require 'use-package)
(require 'bind-key)
;; (require 'use-package-ensure)
;; (setq use-package-always-ensure t) ; Ensure use-package installs all packages by default. Use :ensure nil to override.
;; (package-install-selected-packages)
#+end_src
*** CNCL [[https://github.com/quelpa/quelpa][Quelpa]]
#+begin_src elisp :tangle no
(unless (package-installed-p 'quelpa)
(with-temp-buffer
(url-insert-file-contents "https://raw.githubusercontent.com/quelpa/quelpa/master/quelpa.el")
(eval-buffer)
(quelpa-self-upgrade)))
#+end_src
*** DONE System information
:LOGBOOK:
- State "DONE" from "TODO" [2023-08-28 Mon 18:46]
- State "DONE" from "DONE" [2023-08-28 Mon 18:43]
- State "DONE" from "NEXT" [2023-08-03 Thu 13:03]
:END:
I took this from [[https://pages.sachachua.com/.emacs.d/Sacha.html][Sacha's settings]]. This allows for tweaking configuations according to platform. I intend to use more of this more as I develop Emacs configs across platforms.
#+begin_src elisp :tangle ~/.emacs.d/custom.el
(defvar my-laptop-p (equal (system-name) "lilitop"))
(defvar my-server-p (and (equal (system-name) "localhost") (equal user-login-name "root")))
(defvar my-phone-p (not (null (getenv "ANDROID_ROOT")))
"If non-nil, GNU Emacs is running on Termux.")
(when my-phone-p (defvar gnutls-algorithm-priority "NORMAL:-VERS-TLS1.3"))
(global-auto-revert-mode) ; simplifies syncing
#+end_src
*** DONE Persistent history
#+begin_src elisp
(savehist-mode)
#+end_src
*** DONE Personal information
#+begin_src elisp :tangle ~/.emacs.d/custom.el
(setq user-full-name "Amr Gharbeia")
(defvar email-address "amr@gharbeia.net")
#+end_src
*** DONE Coordinates
:LOGBOOK:
- State "DONE" from [2023-09-02 Sat 11:51]
:END:
#+begin_src elisp :tangle ~/.emacs.d/custom.el
(defvar calendar-latitude 39.0)
(defvar calendar-longitude -77.1)
(defvar calendar-location-name "Washington, DC")
(defvar calendar-time-zone -300)
(defvar calendar-standard-time-zone-name "EST")
(defvar calendar-daylight-time-zone-name "EDT")
#+end_src
*** TODO Add ~/org/info to when searching for INFO documentation after Info-mode has started
#+begin_src elisp :tangle no
(add-hook 'info-mode-hook
(lambda ()
(defvar info-additional-directory-list info-default-directory-list)
)
)
(global-set-key (kbd "C-c l") #'dictionary-lookup-definition)
#+end_src
** TODO [12/32] GUI, display, and sessions
:LOGBOOK:
- State "DONE" from "TODO" [2024-07-10 Wed 17:06]
:END:
*** DONE Set frame margins to zero, window margins to zero
#+begin_src elisp
(modify-all-frames-parameters '((internal-border-width . 0)))
#+end_src
*** TODO Set the initial frame size and position
:LOGBOOK:
- State "DONE" from "TODO" [2024-07-08 Mon 22:11]
:END:
#+begin_src elisp :tangle no
;; initial window
(setq initial-frame-alist
'((width . 192) ; characters in a line
(height . 37) ; number of lines
(top . 1) ; top position
(left . 1) ; left position
)
)
;; sebsequent frame
(setq default-frame-alist
'((width . 192) ; characters in a line
(height . 37) ; number of lines
)
)
#+end_src
*** TODO Initial screen
#+begin_src elisp :tangle no
(setq inhibit-splash-screen t)
(setq inhibit-startup-message t)
(setq initial-scratch-message "")
(setq initial-major-mode 'org-mode)
#+end_src
*** DONE Startup echo message
#+begin_src elisp
(defun display-startup-echo-area-message ()
"Display a welcome message."
(message "Ladies and gentlemen, we are floating in space!")
)
#+end_src
*** TODO Simpler GUI
#+begin_src elisp :tangle no
(when window-system
(tool-bar-mode 0)
(menu-bar-mode 0)
(scroll-bar-mode 0)
)
#+end_src
*** DONE [[https://protesilaos.com/emacs/ef-themes][Theme]]
:LOGBOOK:
- State "DONE" from "TODO" [2024-07-16 Tue 19:50]
- State "DONE" from "TODO" [2024-07-10 Wed 17:06]
:END:
#+begin_src elisp
;; Make customisations that affect Emacs faces BEFORE loading a theme
;; (any change needs a theme re-load to take effect).
;; (require 'ef-themes)
(use-package ef-themes
:config
;; If you like two specific themes and want to switch between them, you
;; can specify them in `ef-themes-to-toggle' and then invoke the command
;; `ef-themes-toggle'. All the themes are included in the variable
;; `ef-themes-collection'.
(defvar ef-themes-to-toggle '(ef-summer ef-winter))
(defvar ef-themes-headings ; read the manual's entry or the doc string
'((0 variable-pitch light 1.9)
(1 variable-pitch light 1.8)
(2 variable-pitch regular 1.7)
(3 variable-pitch regular 1.6)
(4 variable-pitch regular 1.5)
(5 variable-pitch 1.4) ; absence of weight means `bold'
(6 variable-pitch 1.3)
(7 variable-pitch 1.2)
(t variable-pitch 1.1)))
;; They are nil by default...
(defvar ef-themes-mixed-fonts t)
(defvar ef-themes-variable-pitch-ui t)
;; Disable all other themes to avoid awkward blending:
(mapc #'disable-theme custom-enabled-themes)
;; Load the theme of choice:
(load-theme 'ef-winter :no-confirm)
;; OR use this to load the theme which also calls `ef-themes-post-load-hook':
(ef-themes-select 'ef-winter)
;; The themes we provide are recorded in the `ef-themes-dark-themes',
;; `ef-themes-light-themes'.
;; We also provide these commands, but do not assign them to any key:
;;
;; - `ef-themes-toggle'
;; - `ef-themes-select'
;; - `ef-themes-select-dark'
;; - `ef-themes-select-light'
;; - `ef-themes-load-random'
;; - `ef-themes-preview-colors'
;; - `ef-themes-preview-colors-current'
)
#+end_src
*** TODO Set the cursor shape
#+begin_src elisp :tangle no
(setq-default cursor-type '(box . 1)) ; Bar cursor
(blink-cursor-mode -1) ; Don't blink the cursor
#+end_src
*** TODO Indicate cursor position
#+begin_src elisp :tangle no
(use-package beacon
:demand t
:diminish beacon-mode
:bind* (("M-m g z" . beacon-blink))
:config
(beacon-mode 1)
(which-key-add-key-based-replacements "g z" "blink cursor")
)
#+end_src
*** TODO Enable mouse scrolling in terminal
:LOGBOOK:
- State "DONE" from "TODO" [2023-07-07 Fri 11:50]
:END:
#+begin_src elisp :tangle no
(defvar alternating-scroll-down-next t)
(defvar alternating-scroll-up-next t)
(defun alternating-scroll-down-line ()
(interactive "@")
(when alternating-scroll-down-next (scroll-down-line))
(setq alternating-scroll-down-next (not alternating-scroll-down-next))
)
(defun alternating-scroll-up-line ()
(interactive "@")
(when alternating-scroll-up-next (scroll-up-line))
(setq alternating-scroll-up-next (not alternating-scroll-up-next))
)
(when (not (display-graphic-p))
(global-set-key (kbd "<mouse-4>") 'alternating-scroll-down-line)
(global-set-key (kbd "<mouse-5>") 'alternating-scroll-up-line)
)
#+end_src
*** TODO Tab bar
#+begin_src elisp :tangle no
(setq tab-bar-show nil)
#+end_src
*** DONE Tab Line
:LOGBOOK:
- State "DONE" from "TODO" [2024-07-16 Tue 19:51]
:END:
#+begin_src elisp
(global-tab-line-mode)
#+end_src
*** CNCL Add clock
:LOGBOOK:
- State "DONE" from "TODO" [2023-07-05 Wed 16:48]
:END:
Modify this later to show clock only in full-screen mode
#+begin_src elisp :tangle no
(display-time-mode nil)
#+end_src
*** TODO Fonts
:LOGBOOK:
- State "DONE" from [2023-08-22 Tue 11:10]
:END:
#+begin_src elisp :tangle no
(use-package unicode-fonts
:config
(defvar unicode-fonts-block-font-mapping
'(("Emoticons" ("Apple Color Emoji" "Symbola" "Quivira"))))
(defvar unicode-fonts-fontset-names '("fontset-default"))
(defvar unicode-skip-font-groups '(""))
(unicode-fonts-setup)
)
#+end_src
[[https://www.emacswiki.org/emacs/UnicodeFonts][EmacsWiki]]: If you are using a language written in Chinese or Arabic script, try customizing unicode-fonts-skip-font-groups to control which script you see, and send a friendly bug report.
#+begin_src elisp :tangle no
(set-face-attribute 'default nil :font "Arial") ;; default font
(set-fontset-font t nil "sans-serif" nil 'append) ;; fallback font
(set-fontset-font t 'arabic "Amiri") ;; default Arabic font
(set-face-attribute 'fixed-pitch nil :family "Thabit")
(set-fontset-font t 'arabic "Simplified Arabic" nil 'append) ;; default Arabic fallback
(set-fontset-font t 'arabic (font-spec :script 'arabic) nil 'append) ;; if font not available, don't display boxes
#+end_src
*** TODO [0/3] Icons
:LOGBOOK:
- State "DONE" from "TODO" [2024-07-09 Tue 17:08]
:END:
**** TODO [[https://github.com/domtronn/all-the-icons.el][all-the-icons.el]]
:LOGBOOK:
- State "DONE" from "TODO" [2024-06-27 Thu 11:02]
- State "DONE" from "TODO" [2023-08-28 Mon 18:55]
- State "DONE" from "DONE" [2023-08-18 Fri 12:31]
:END:
#+begin_src elisp :tangle no
(use-package all-the-icons
:if (display-graphic-p)
)
#+end_src
**** TODO all-the-icons-completion
#+begin_src elisp :tangle no
(use-package all-the-icons-completion
:if (display-graphic-p)
:after all-the-icons
:config
(all-the-icons-completion-mode)
)
#+end_src
**** TODO [0/4] all-the-icons Mode Line
:LOGBOOK:
- State "DONE" from "TODO" [2024-07-09 Tue 17:07]
- State "DONE" from "TODO" [2024-07-09 Tue 15:57]
- State "DONE" from "TODO" [2023-08-28 Mon 18:54]
:END:
#+begin_src elisp :tangle no
(setq mode-line-format '("%e"
(:eval
(concat
(custom-modeline-modified)
(custom-modeline-region-info)
(custom-modeline-flycheck-status)
(custom-modeline-icon-vc)
)
)
)
)
#+end_src
***** TODO Modified or read only
:LOGBOOK:
- State "DONE" from "TODO" [2024-06-27 Thu 11:15]
:END:
#+begin_src elisp :tangle no
(defun custom-modeline-modified ()
(let* ((config-alist
'(
("*" all-the-icons-faicon-family all-the-icons-faicon "chain-broken" :height 1.2 :v-adjust -0.0)
("-" all-the-icons-faicon-family all-the-icons-faicon "link" :height 1.2 :v-adjust -0.0)
("%" all-the-icons-octicon-family all-the-icons-octicon "lock" :height 1.2 :v-adjust 0.1)
)
)
(result (cdr (assoc (format-mode-line "%*") config-alist)))
)
(propertize (apply (cadr result) (cddr result))
'face `(:family ,(funcall (car result)))
)
)
)
#+end_src
***** TODO Region marking
:LOGBOOK:
- State "DONE" from "TODO" [2024-06-27 Thu 11:15]
- State "DONE" from "TODO" [2023-08-18 Fri 12:16]
:END:
#+begin_src elisp :tangle no
(defun custom-modeline-region-info ()
(when mark-active
(let ((words (count-lines (region-beginning) (region-end)))
(chars (count-words (region-end) (region-beginning))))
(concat
(propertize (format " %s" (all-the-icons-octicon "pencil") words chars)
'face `(:family ,(all-the-icons-octicon-family))
'display '(raise -0.0))
(propertize (format " (%s, %s)" words chars)
'face `(:height 0.9))))))
#+end_src
***** TODO Version control icon
:LOGBOOK:
- State "DONE" from "TODO" [2024-06-27 Thu 11:15]
- State "DONE" from "TODO" [2023-08-18 Fri 12:16]
- State "DONE" from "TODO" [2023-07-07 Fri 12:17]
:END:
#+begin_src elisp :tangle no
(defun -custom-modeline-github-vc ()
(let ((branch (mapconcat 'concat (cdr (split-string vc-mode "[:-]")) "-")))
(concat
(propertize (format " %s" (all-the-icons-alltheicon "git")) 'face `(:height 1.2) 'display '(raise -0.1))
" · "
(propertize (format "%s" (all-the-icons-octicon "git-branch"))
'face `(:height 1.3 :family ,(all-the-icons-octicon-family))
'display '(raise -0.1))
(propertize (format " %s" branch) 'face `(:height 0.9)))))
(defun -custom-modeline-svn-vc ()
(let ((revision (cadr (split-string vc-mode "-"))))
(concat
(propertize (format " %s" (all-the-icons-faicon "cloud")) 'face `(:height 1.2) 'display '(raise -0.1))
(propertize (format " · %s" revision) 'face `(:height 0.9)))))
(defun custom-modeline-icon-vc ()
(when vc-mode
(cond
((string-match "Git[:-]" vc-mode) (-custom-modeline-github-vc))
((string-match "SVN-" vc-mode) (-custom-modeline-svn-vc))
(t (format "%s" vc-mode)))))
#+end_src
***** TODO Flycheck checker information
:LOGBOOK:
- State "DONE" from "TODO" [2024-06-27 Thu 11:16]
- State "DONE" from "TODO" [2023-08-18 Fri 11:49]
:END:
#+begin_src elisp :tangle no
(defun custom-modeline-flycheck-status ()
(let* ((text (pcase flycheck-last-status-change
(`finished (if flycheck-current-errors
(let ((count (let-alist (flycheck-count-errors flycheck-current-errors)
(+ (or .warning 0) (or .error 0)))))
(format "✖ %s Issue%s" count (unless (eq 1 count) "s")))
"✔ No Issues"))
(`running "⟲ Running")
(`no-checker "⚠ No Checker")
(`not-checked "✖ Disabled")
(`errored "⚠ Error")
(`interrupted "⛔ Interrupted")
(`suspicious ""))))
(propertize text
'help-echo "Show Flycheck Errors"
'mouse-face '(:box 1)
'local-map (make-mode-line-mouse-map
'mouse-1 (lambda () (interactive) (flycheck-list-errors))))))
#+end_src
*** TODO [0/2] Mode Line
:LOGBOOK:
- State "DONE" from "DONE" [2024-07-09 Tue 17:08]
:END:
**** TODO Default
#+begin_src elisp :tangle no
(setq mode-line-format '("%e"
mode-line-front-space
mode-line-mule-info
mode-line-client
mode-line-modified
mode-line-remote
mode-line-frame-identification
mode-line-buffer-identification
mode-line-position (vc-mode vc-mode)
mode-line-modes
mode-line-misc-info
mode-line-end-spaces
)
)
#+end_src
**** TODO [[https://gitlab.com/jessieh/mood-line][Moodline]]
:LOGBOOK:
- State "DONE" from "TODO" [2024-07-09 Tue 16:18]
:END:
#+begin_src elisp :tangle no
(use-package mood-line
;; Enable mood-line
:config
(mood-line-mode)
;; Use pretty Fira Code-compatible glyphs
(defvar mood-line-glyph-alist mood-line-glyphs-fira-code)
)
#+end_src
#+begin_src elisp :tangle no
;; Default format:
;; * init.el 4:32 Top ELisp ! Issues: 2
(defvar mood-line-format mood-line-format-default)
#+end_src
#+begin_src elisp :tangle no
;; Extended format:
;; * init.el 4:32:52 Top SPCx2 LF UTF-8 ELisp ! Issues: 2
(defvar mood-line-format mood-line-format-default-extended)
#+end_src
#+begin_src elisp :tangle no
;; Custom format:
;; * init.el : ELisp Top 4:32 | ! Issues: 2
(setq mood-line-format
(mood-line-defformat
:left
(((mood-line-segment-buffer-status) . " ")
((mood-line-segment-buffer-name) . " : ")
(mood-line-segment-major-mode))
:right
(((mood-line-segment-scroll) . " ")
((mood-line-segment-cursor-position) . " ")
((when (mood-line-segment-checker) "|") . " ")
((mood-line-segment-checker) . " "))))
#+end_src
#+begin_src elisp :tangle no
;; The default set of glyphs:
;; * myModifiedFile.js Replace*3 + main JavaScript ! Issues: 2
(defvar mood-line-glyph-alist mood-line-glyphs-ascii)
#+end_src
#+begin_src elisp :tangle no
;; A set of Fira Code-compatible Unicode glyphs:
;; ● myModifiedFile.js Replace×3 + main JavaScript → Issues: 2
(setq mood-line-glyph-alist mood-line-glyphs-fira-code)
#+end_src
#+begin_src elisp :tangle no
;; A set of Unicode glyphs:
;; ● myModifiedFile.js Replace✕3 🞤 main JavaScript ⚑ Issues: 2
(defvar mood-line-glyph-alist mood-line-glyphs-unicode)
#+end_src
*** DONE [[https://github.com/emacsmirror/diminish][Diminish]] minor modes from the mode line
:LOGBOOK:
- State "DONE" from "NEXT" [2023-08-03 Thu 13:05]
:END:
#+begin_src elisp
(use-package diminish
:demand t
:diminish (visual-line-mode . "ω")
:diminish abbrev-mode
:diminish auto-fill-function
)
#+end_src
*** TODO [2/3] Window Management
:LOGBOOK:
- State "DONE" from "DONE" [2024-07-16 Tue 20:04]
- State "DONE" from "TODO" [2024-07-16 Tue 20:02]
:END:
**** DONE Save windows arrangement
#+begin_src elisp
(when (fboundp 'winner-mode)
(winner-mode t)
)
#+end_src
**** DONE Switch to other-window
:LOGBOOK:
- State "DONE" from "TODO" [2024-07-16 Tue 20:04]
:END:
#+begin_src elisp
(use-package ace-window
:config
(global-set-key (kbd "M-o") 'ace-window)
(defvar aw-dispatch-always nil) ; works for less than three buffers
)
#+end_src
**** TODO Repeat mode
#+begin_src elisp :tangle no
(repeat-mode)
#+end_src
*** TODO Scroll to the first and last line of the buffer
#+begin_src elisp :tangle no
(setq scroll-error-top-bottom t)
#+end_src
*** DONE Lazy prompts
#+begin_src elisp
(defalias 'yes-or-no-p 'y-or-n-p)
#+end_src
*** DONE Narrow to region
#+begin_src elisp
(put 'narrow-to-region 'disabled nil)
#+end_src
*** TODO Neotree
:LOGBOOK:
- State "DONE" from "TODO" [2023-07-05 Wed 16:48]
:END:
#+begin_src elisp :tangle no
(use-package neotree
:init (defvar neo-smart-open t)
:config (defvar neo-theme (if (display-graphic-p) 'icons 'arrow))
)
#+end_src
*** CNCL Discover major mode
:LOGBOOK:
- State "CNCL" from "DONE" [2024-07-10 Wed 11:30] \\
Not needed
- State "DONE" from "TODO" [2023-07-05 Wed 16:48]
:END:
#+begin_src elisp :tangle no
(use-package discover-my-major
:bind (("C-h C-m" . discover-my-major)
("C-h M-m" . discover-my-mode)
)
)
#+end_src
*** TODO [[https://tuhdo.github.io/helm-intro.html][Helm]]
:LOGBOOK:
- State "DONE" from "NEXT" [2023-08-18 Fri 12:57]
:END:
#+begin_src elisp :tangle no
(use-package helm
:init (helm-mode)
:config
(defvar helm-M-x-fuzzy-match t)
(defvar helm-recentf-fuzzy-match t)
(defvar helm-buffers-fuzzy-matching t)
(defvar helm-locate-fuzzy-match t)
(defvar helm-mode-fuzzy-match t)
(defvar helm-split-window-inside-p nil) ; open helm buffer inside current window, not occupy whole other window
(defvar helm-lisp-fuzzy-completion t)
:bind (
("M-x" . helm-M-x) ;; Evaluate functions
("C-x C-f" . helm-find-files) ;; Open or create files
("C-x b" . helm-mini) ;; Select buffers
("C-x C-r" . helm-recentf) ;; Select recently saved files
("C-c i" . helm-imenu) ;; Select document heading
("M-y" . helm-show-kill-ring) ;; Show the kill ring
(:map helm-map
("C-z" . helm-select-action)
("<tab>" . helm-execute-persistent-action))
)
)
#+end_src
**** CNCL [[https://github.com/emacs-helm/helm-firefox][Display firefox bookmarks with emacs helm interface]] :emacs:web:archive:
:PROPERTIES:
:TITLE: GitHub - emacs-helm/helm-firefox: Display firefox bookmarks with emacs helm interface
:URI: tps://github.com/emacs-helm/helm-firefox
:CREATED: [2023-01-28 Sat 09:11]
:END:
:LOGBOOK:
- State "CNCL" from "TODO" [2023-08-18 Fri 12:56] \\
Not using Firefox bookmarks for now.
:END:
#+begin_src elisp :tangle no
(use-package helm-firefox)
#+end_src
*** TODO Allow refiling to level, override Helm to complete refiling target
:LOGBOOK:
- State "DONE" from "TODO" [2023-07-07 Fri 16:50]
:END:
#+begin_src elisp :tangle no
(setq org-refile-use-outline-path 'file)
#+end_src
*** DONE [[https://github.com/justbur/emacs-which-key][Which-key]]
Figure out the next keystroke. which-key package opens a small buffer at the bottom with suggestions for next keystroke and possible commands that are available
#+begin_src elisp
(use-package which-key
:config
(defvar which-key-sort-order 'which-key-key-order-alpha)
(defvar which-key-idle-delay 0.05)
(which-key-mode)
(which-key-setup-minibuffer)
(which-key-setup-side-window-right)
)
#+end_src
*** DONE Paragraph text wrapping
#+begin_src elisp
(setq global-visual-line-mode t)
#+end_src
*** TODO Increase line spacing
#+begin_src elisp :tangle no
(setq line-spacing 6)
#+end_src
*** TODO RTL Support
:LOGBOOK:
- State "DONE" from "TODO" [2023-07-05 Wed 12:19]
:END:
For a correct RTL display you can add the following snippet to your init file:
#+begin_src elisp :tangle no
(defun set-bidi-env ()
(interactive)
(setq bidi-paragraph-direction 'nil)
)
(add-hook 'org-mode-hook 'set-bidi-env)
#+end_src
*** TODO File encoding system
#+begin_src elisp :tangle no
(prefer-coding-system 'utf-8)
(setq buffer-file-coding-system 'utf-8-auto-unix)
#+end_src
*** DONE Overwrite selected text
#+begin_src elisp
(delete-selection-mode t)
#+end_src
*** TODO Expand region
:LOGBOOK:
- State "DONE" from "NEXT" [2023-08-03 Thu 13:11]
:END:
#+begin_src elisp :tangle no
(use-package expand-region
:bind ("C-=" . er/expand-region)
)
#+end_src
*** TODO [2/6] Shell
:LOGBOOK:
- State "DONE" from "TODO" [2024-07-09 Tue 17:11]
:END:
**** TODO Shell history
:LOGBOOK:
- State "DONE" from "TODO" [2023-08-18 Fri 13:01]
:END:
#+begin_src elisp :tangle no
(use-package helm-shell-history)
#+end_src
**** DONE Bash completion
:LOGBOOK:
- State "DONE" from "TODO" [2024-07-16 Tue 20:35]
- State "DONE" from "TODO" [2023-08-18 Fri 13:02]
:END:
#+begin_src elisp
(use-package bash-completion
:config
(require 'bash-completion)
(bash-completion-setup)
)
#+end_src
#+begin_src elisp :tangle no
(defvar shell-dynamic-complete-functions t)
#+end_src
**** TODO Use colors in eshell
:LOGBOOK:
- State "DONE" from "TODO" [2023-08-28 Mon 18:56]
:END:
#+begin_src elisp :tangle no
(use-package xterm-color
:commands (xterm-color-filter)
)
(use-package eshell
:after xterm-color
:config
(define-key eshell-hist-mode-map (kbd "M-r") #'consult-history)
(add-hook 'eshell-mode-hook
(lambda ()
(setenv "TERM" "xterm-256color")))
(add-hook 'eshell-before-prompt-hook (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)
)
)
#+end_src
**** TODO Eshell completion
#+begin_src elisp :tangle no
(add-hook 'eshell-mode-hook
(lambda ()
(add-hook 'completion-at-point-functions
'bash-completion-capf-nonexclusive nil t)))
#+end_src
**** TODO [[https://github.com/szermatt/emacs-bash-completion][Add programmable bash completion to Emacs shell-mode]]
:PROPERTIES:
:TITLE: GitHub - szermatt/emacs-bash-completion: Add programmable bash completion to Emacs shell-mode
:URI: https://github.com/szermatt/emacs-bash-completion
:CREATED: [2023-01-27 Fri 21:00]
:END:
:LOGBOOK:
- State "DONE" from "TODO" [2024-02-28 Wed 16:30]
:END:
#+begin_src elisp :tangle no
(require 'bash-completion)
(add-hook 'eshell-mode-hook
(lambda ()
(add-hook 'completion-at-point-functions
'bash-completion-capf-nonexclusive nil t
)
)
)
#+end_src
**** CNCL Emulate A Terminal (EAT)
:LOGBOOK:
- State "CNCL" from "TODO" [2024-04-01 Mon 15:52] \\
Moved to shell and eshell. Eat is not in repositories currently.
- State "DONE" from [2023-08-30 Wed 20:43]
:END:
#+begin_src elisp :tangle no
(use-package eat
:config
;; For `eat-eshell-mode'.
(add-hook 'eshell-load-hook #'eat-eshell-mode)
;; For `eat-eshell-visual-command-mode'.
(add-hook 'eshell-load-hook #'eat-eshell-visual-command-mode)
)
#+end_src
*** TODO [2/3] Session
:LOGBOOK:
- State "DONE" from "DONE" [2024-02-28 Wed 16:26]
:END:
**** DONE Close frame when done
:LOGBOOK:
- State "DONE" from "NEXT" [2023-08-03 Thu 13:21]
:END:
When a server buffer is done, the current window (frame) should be closed. This is useful in scenarios where Emacs is used as an external editor (for instance, from a version control system). When you're done editing, the frame closes automatically. If this is the only frame, Emacs will exit.
#+begin_src elisp
(add-hook 'server-done-hook (lambda () (delete-frame)))
#+end_src
**** DONE Save desktop session
#+begin_src elisp
(desktop-save-mode t)
#+end_src
**** TODO Tangle and reload Emacs configuations
:LOGBOOK:
- State "DONE" from "TODO" [2023-07-05 Wed 14:01]
:END:
#+begin_src elisp :tangle no
(defun my/tangle-and-reload-emacs-configuration ()
"Tangle Emacs configs stored in org file and produce a config file, then load that so changes take effect."
(interactive)
(org-babel-tangle-file config-org-file)
(load-file config-el-file)
)
#+end_src
** TODO [4/12] Files
:LOGBOOK:
- State "DONE" from "DONE" [2024-06-28 Fri 20:01]
- State "DONE" from "TODO" [2024-02-28 Wed 16:50]
- State "DONE" from "TODO" [2023-07-06 Thu 12:30]
:END:
*** DONE Recent files
#+begin_src elisp
;; Recentf mode changes
(defvar recentf-max-saved-items 1000)
(defvar recentf-exclude '("/tmp/" "/ssh:"))
(recentf-mode)
#+end_src
*** DONE Backup
Keep folders clean (create new directory when not yet existing)
#+begin_src elisp
(make-directory (expand-file-name "backups/" org-directory) t)
(setq backup-directory-alist `(("." . ,(expand-file-name "backups/" org-directory))))
#+end_src
*** DONE Save versions
:LOGBOOK:
- State "DONE" from "TODO" [2023-07-05 Wed 14:10]
:END:
I am not sure if I will end up using this or git, but here we are for now
#+begin_src elisp
(setq delete-old-versions -1)
(setq version-control t)
(setq vc-make-backup-files t)
(setq auto-save-file-name-transforms '((".*" "~/.emacs.d/auto-save-list/" t)))
#+end_src
*** DONE Auto saving
Away from my file tree
#+begin_src elisp
(setq auto-save-file-name-transforms `((".*" ,temporary-file-directory t))
create-lockfiles nil)
#+end_src
*** TODO Large file warning
#+begin_src elisp :tangle no
(setq large-file-warning-threshold (* 15 1024 1024))
#+end_src
*** TODO Filetree navigator
:LOGBOOK:
- State "DONE" from "TODO" [2023-07-06 Thu 11:59]
:END:
#+begin_src elisp :tangle no
(use-package dired
:init
(setq dired-dwim-target t)
(setq dired-recursive-copies 'top)
(setq dired-recursive-deletes 'top)
(setq dired-listing-switches "-alh")
(setq dired-listing-switches "-agho --group-directories-first") ; Sort Dired buffers
(setq dired-dwim-target t) ; Copy and move files netween dired buffers
:config
(add-hook 'dired-mode-hook 'dired-hide-details-mode)
(add-hook 'dired-mode-hook 'all-the-icons-dired-mode)
:bind (:map dired-mode-map
("C-c C-e" . wdired-change-to-wdired-mode))
)
#+end_src
#+begin_src elisp :tangle no
;; Image-dired Keyboard shortcuts
(with-eval-after-load 'dired
(define-key dired-mode-map (kbd "C-t C-d") 'image-dired)
(define-key dired-mode-map (kbd "C-<return>") 'image-dired-dired-display-external)
)
(setq image-dired-external-viewer "/usr/bin/gimp") ; Define external image viewer/edito
(put 'dired-find-alternate-file 'disabled nil) ; Open dired in same buffer
#+end_src
#+begin_src elisp :tangle no
(use-package all-the-icons-dired
:if (display-graphic-p)
)
#+end_src
*** TODO Move deleted files to trash
#+begin_src elisp :tangle no
(setq delete-by-moving-to-trash t)
#+end_src
*** TODO [[https://github.com/magit/magit][Magit]]
:PROPERTIES:
:CREATED: [2023-01-29 Sun 10:12]
:CLOSED: [2023-02-01 Wed 21:58]
:END:
#+begin_src elisp :tangle no
(use-package magit)
#+end_src
*** TODO Interface to silversearch-ag for fast search among entire folders
:LOGBOOK:
- State "DONE" from "TODO" [2024-02-12 Mon 16:13]
:END:
#+begin_src elisp :tangle no
(use-package helm-ag)
#+end_src
*** TODO [[https://github.com/joostkremers/pandoc-mode][pandoc-mode]]
:PROPERTIES:
:TITLE: GitHub - joostkremers/pandoc-mode: An Emacs minor mode for interacting with Pandoc.
:URI: https://github.com/joostkremers/pandoc-mode
:CREATED: [2023-01-29 Sun 10:20]
:END:
:LOGBOOK:
- State "DONE" from "TODO" [2023-08-18 Fri 13:04]
- State "DONE" from "WAIT" [2023-07-07 Fri 15:00]
- State "DONE" from "TODO" [2023-07-07 Fri 14:53]
:END:
#+begin_src elisp :tangle no
(use-package pandoc-mode
:after hydra
:config
(add-hook 'markdown-mode-hook 'pandoc-mode) ;; Pandoc minor mode in markdown
(add-hook 'pandoc-mode-hook 'pandoc-load-default-settings) ;; if a settings file for this format exists
)
#+end_src
**** DONE Install [[https://pandoc.org/index.html][Pandoc - index]]
CLOSED: [2023-01-31 Tue 05:11]
:PROPERTIES:
:CREATED: [2023-01-29 Sun 10:15]
:CLOSED: [2023-01-31 Tue 05:11]
:END:
*** TODO [[https://github.com/DerBeutlin/date2name.el][Date2name: add ISO timestamps to files in dired]]
:PROPERTIES:
:TITLE: GitHub - DerBeutlin/date2name.el: Emacs package to add ISO timestamps to files in dired
:URI: https://github.com/DerBeutlin/date2name.el
:CREATED: [2023-01-28 Sat 06:20]
:END:
:LOGBOOK:
- State "DONE" from "TODO" [2023-07-12 Wed 12:44]
:END:
#+begin_src elisp :tangle no
(use-package date2name)
#+end_src
*** TODO [[https://github.com/DerBeutlin/filetags.el][Filetags: manage filetags in the filename]]
:PROPERTIES:
:TITLE: Filetags: Emacs package to manage filetags in the filename
:URI: https://github.com/DerBeutlin/filetags.el
:CREATED: [2023-01-28 Sat 08:58]
:END:
:LOGBOOK:
- State "DONE" from "TODO" [2023-07-12 Wed 12:43]
:END:
#+begin_src elisp :tangle no
(use-package filetags
:config
(setq filetags-enforce-controlled-vocabulary nil)
(setq filetags-controlled-vocabulary '(("winter" "summer") ("emacs")))
(setq filetags-load-controlled-vocabulary-from-file nil)
)
#+end_src
** TODO [18/32] Org-Mode
:LOGBOOK:
- State "DONE" from "TODO" [2024-02-28 Wed 16:49]
:END:
*** DONE Basic setup
#+begin_src elisp
(use-package org
:config
(defvar org-outline-path-complete-in-steps nil)
(defvar org-startup-folded 'shw2levels)
(org-babel-do-load-languages 'org-babel-load-languages '((shell . t))) ; enable shell scripting support in org-babel
:bind (("C-c l" . org-store-link)
("C-c a" . org-agenda)
("C-c c" . org-capture)
:map org-mode-map)
)
#+end_src
#+begin_src elisp :tangle ~/.emacs.d/custom.el
(defvar org-directory (concat (getenv "HOME") "/org/"))
#+end_src
*** DONE Looks
:LOGBOOK:
- State "DONE" from "TODO" [2024-07-16 Tue 21:51]
:END:
#+begin_src elisp
(defvar org-pretty-entities t) ; Improve org mode looks
(defvar org-hide-emphasis-markers t) ; Hide emphasis markup
(defvar org-num-mode nil)
#+end_src
*** DONE [[https://github.com/minad/org-modern][Org-modern]]
:LOGBOOK:
- State "DONE" from "TODO" [2024-07-16 Tue 21:27]
- State "DONE" from "TODO" [2024-06-27 Thu 13:06]
:END:
#+begin_src elisp
(use-package org-modern
:config
;; Choose some fonts
(set-face-attribute 'default nil :family "sans-serif")
(set-face-attribute 'variable-pitch nil :family "sans-serif")
(set-face-attribute 'org-modern-symbol nil :family "Iosevka")
;; Edit settings
(defvar org-auto-align-tags nil)
(defvar org-tags-column 0)
(defvar org-catch-invisible-edits 'show-and-error)
(defvar org-special-ctrl-a/e t)
(defvar org-insert-heading-respect-content t)
;; Org styling, hide markup etc.
(defvar org-hide-emphasis-markers t)
(defvar org-pretty-entities t)
;; Agenda styling
(defvar org-agenda-tags-column 0)
(defvar org-agenda-block-separator ?─)
(defvar org-agenda-time-grid
'((daily today require-timed)
(800 1000 1200 1400 1600 1800 2000)
" ┄┄┄┄┄ " "┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄"))
(defvar org-agenda-current-time-string
"◀── now ─────────────────────────────────────────────────")
;; Ellipsis styling
(defvar org-ellipsis "…")
(set-face-attribute 'org-ellipsis nil :inherit 'default :box nil)
(global-org-modern-mode)
)
#+end_src
*** DONE Indentation
:LOGBOOK:
- State "DONE" from "TODO" [2024-07-16 Tue 21:27]
- State "DONE" from [2023-08-28 Mon 18:17]
:END:
#+begin_src elisp
(defvar org-startup-indented t) ; Indent org heirarchy
(defvar org-adapt-indentation t)
(defvar org-hide-leading-stars t) ; Minimal Outline
(defvar org-odd-levels-only nil)
#+end_src
*** DONE Allow indented lists
:LOGBOOK:
- State "DONE" from [2024-02-11 Sun 13:15]
:END:
#+begin_src elisp
(setq org-list-demote-modify-bullet t)
#+end_src
*** DONE Highlight Sourcecode Syntax
#+begin_src elisp
(setq org-src-fontify-natively t)
(setq org-src-tab-acts-natively t)
#+end_src
*** TODO Images
#+begin_src elisp :tangle no
(setq org-startup-with-inline-images t)
(setq org-image-actual-width '(300))
#+end_src
*** DONE Basic org-roam setup
:LOGBOOK:
- State "DONE" from "TODO" [2024-07-16 Tue 21:30]
- State "DONE" from "TODO" [2023-07-05 Wed 17:11]
:END:
#+begin_src elisp
(use-package org-roam
:init (setq org-roam-v2-ack t) ;; Acknowledge V2 upgrade
:after org
:config
(org-roam-db-autosync-enable)
(require 'org-roam-dailies)
(setq org-roam-mode-sections
(list #'org-roam-backlinks-section
#'org-roam-reflinks-section
#'org-roam-unlinked-references-section
)
)
(add-to-list 'display-buffer-alist
'("\\*org-roam\\*"
(display-buffer-in-side-window)
(side . right)
(slot . 0)
(window-width . 0.33)
(window-parameters . ((no-other-window . t)
(no-delete-other-windows . t)))))
:bind (
("C-c n f" . org-roam-node-find)
("C-c n g" . org-roam-graph)
("C-c n r" . org-roam-node-random)
("C-c n h" . org-roam-node-convert-headline)
("C-c n i" . org-roam-node-insert)
("C-c n o" . org-id-get-create)
("C-c n t" . org-roam-tag-add)
("C-c n a" . org-roam-alias-add)
("C-c n l" . org-roam-buffer-display-dedicated)
)
)
#+end_src
#+begin_src elisp :tangle ~/.emacs.d/custom.el
(setq org-roam-directory org-directory)
(setq org-roam-dailies-directory (concat org-roam-directory "daily"))
#+end_src
*** TODO Exporting
From [[https://sriramkswamy.github.io/dotemacs/#orgheadline29][Sriramkswamy]]:
#+BEGIN_QUOTE
Org has a powerful exporting feature. Lets select the various formats to export and also mention how exactly we need it to export to LaTeX with syntax highlighting. I have also taken a good looking CSS configuration from [[http://gongzhitaao.org/orgcss/][Zhitao Gong]] and I use it for exporting by putting it [[https://sriramkswamy.github.io/dotemacs/org.css][in the same folder as my org file]] and adding #+HTML_HEAD: <link rel="stylesheet" type="text/css" href="org.css"/> to the top of my org file.
#+END_QUOTE
#+begin_src elisp :tangle no
(setq org-export-with-smart-quotes t)
(setq org-export-backends '(beamer html latex md))
#+end_src
*** DONE Agenda
#+begin_src elisp
(setq org-deadline-warning-days 7)
(setq org-agenda-skip-additional-timestamps-same-entry t)
(setq org-agenda-span 'fortnight)
(setq org-agenda-tags-column 'auto)
(setq org-agenda-skip-scheduled-if-deadline-is-shown t)
(setq org-agenda-files (list
(concat org-directory "inbox.org")
(concat org-directory "org-gtd-tasks.org")
)
)
#+end_src
*** TODO Better agenda views
#+begin_src elisp :tangle no
(use-package org-super-agenda)
#+end_src
*** DONE To-do
#+begin_src elisp
(setq org-todo-keywords
'(
(sequence "TODO(t)" "NEXT(n)" "|" "DONE(d!)")
(sequence "WAIT(w@/!)" "|" "CNCL(c@)")
)
)
(setq org-todo-keyword-faces
'(
("TODO" :foreground "red" :weight bold)
("NEXT" :foreground "red" :weight bold)
("WAIT" :foreground "yellow" :weight bold)
("DONE" :foreground "green" :weight bold)
("CNCL" :foreground "blue" :weight bold)
)
)
(setq org-enforce-todo-dependencies t)
(setq org-tags-exclude-from-inheritance '("crypt" "!private"))
#+end_src
#+begin_src elisp
(defun org-summary-todo (n-done n-not-done)
"Switch entry to 'DONE' when all subentries are done, to 'TODO' otherwise.
Uses N-DONE and N-NOT-DONE"
(let (org-log-done org-log-states) ; turn off logging
(org-todo (if (= n-not-done 0) "DONE" "TODO")
)
)
)
(add-hook 'org-after-todo-statistics-hook #'org-summary-todo)
#+end_src
*** DONE [[https://github.com/Trevoke/org-gtd.el][Getting Things Done (GTD)]]
I am now relying on [[https://github.com/Trevoke/org-gtd.el][org-gtd]] to create a GTD workflow:
1. everything comes into ~/org/inbox.org
2. Items are clarified with textual context, then with including:
- a horizon
- tags
Items are then goes into one of the following buckets:
- a single action
- a project
- an action within an existing project
- a sometime/maybe
- a habit
- a knowledge/reference item
- discarded as trash
3. The above categories are all now headers in ~/org-gtd-tasks.org, but should each have their own file in the future.
4. All actions are states
- TODO (instead of NEXT. Will decide if I will use next per the orthdoxy)
- WAIT
- DONE
- CNCL
I also used to have MAYBE and STARTED tags. Maybe to avoid having a different pool for it (GTD is old, relies on paper and is therefore sequential. Computers solved this problem). STARTED was the tag for the things I am doing, because my NEXT (TODO) list is huge at the moment, mainly because of decades of backlog.
5. Reference is ~/org/library.org. I am beginning to think I might split this further as it grows. My main ~/library is massive, obviously.
6. Calendar is still half connected to org-mode and GTD. Need to find a way to connect across devices. [[https://github.com/dengste/org-caldav][org-caldav]] looks promising.
#+begin_src elisp
(use-package org-gtd
:defer t
:init (setq org-gtd-update-ack "3.0.0")
:after org
:config
;; Keeping these two settings on instead of enabling (org-gtd-mode) until this issue is resolved https://github.com/Trevoke/org-gtd.el/issues/198
(setq org-edna-use-inheritance t)
(org-edna-mode)
;; (org-gtd-mode)
:bind (
("C-c d c" . org-gtd-capture)
("C-c d e" . org-gtd-engage)
("C-c d p" . org-gtd-process-inbox)
:map org-gtd-clarify-map
("C-c c" . org-gtd-organize)
)
)
#+end_src
#+begin_src elisp :tangle ~/.emacs.d/custom.el
(defvar org-gtd-directory org-directory)
(defvar org-gtd-organize-hooks '(org-gtd-set-area-of-focus org-set-tags-command))
(defvar org-gtd-organize-hooks '(org-gtd-set-area-of-focus))
(defvar org-gtd-areas-of-focus '(
"Atoms"
"Bits"
"Cells"
"Flags"
"Business"
"Wealth"
"Learning"
"Skills"
"Privacy"
"Archive"
"Library"
"Writing"
"Health"
"Home"
"Family"
"Social"
"Egypt"
)
)
(defvar org-gtd-clarify-show-horizons 'right)
#+end_src
*** DONE Logging
CLOSED: [2023-07-31 Mon 16:49]
#+begin_src elisp
(setq org-log-into-drawer "LOGBOOK")
#+end_src
*** DONE Clocking work
:LOGBOOK:
- State "DONE" from "NEXT" [2023-08-03 Thu 13:16]
:END:
#+begin_src elisp
(setq org-clock-into-drawer t)
#+end_src
*** DONE Habits
:LOGBOOK:
- State "DONE" from "TODO" [2024-07-16 Tue 21:36]
- State "DONE" from "TODO" [2023-07-31 Mon 14:33]
:END:
#+begin_src elisp
(setq org-habit-graph-column 80)
(setq org-habit-show-habits-only-for-today nil)
#+end_src
*** DONE Capture
:LOGBOOK:
- State "DONE" from "DONE" [2023-08-17 Thu 14:06]
- State "DONE" from "DONE" [2023-08-11 Fri 14:16]
- State "DONE" from "TODO" [2023-07-05 Wed 16:51]
:END:
#+begin_src elisp :tangle ~/.emacs.d/custom.el
(defvar org-default-notes-file (concat org-directory "inbox.org"))
#+end_src
#+begin_src elisp
(setq org-protocol-default-template-key "L")
#+end_src
*** DONE Org-protocol
:LOGBOOK:
- State "DONE" from "TODO" [2023-07-05 Wed 13:21]
:END:
For GNU/Linux setup, put this in ~/.local/share/applications/org-protocol.desktop
or in /usr/share/applications to set up system-wide.
#+begin_src bash :tangle no
[Desktop Entry]
Name=org-protocol
Comment=Intercept calls from emacsclient to trigger custom actions
Categories=Other;
Keywords=org-protocol;
Icon=emacs
Type=Application
Exec=emacsclient -- %u
Terminal=false
StartupWMClass=Emacs
MimeType=x-scheme-handler/org-protocol;
#+end_src
then update the cache database of MIME types handled by desktop files:
#+begin_src bash :tangle no
update-desktop-database ~/.local/share/applications/
#+end_src
#+begin_src elisp
(require 'org-protocol)
(setq org-protocol-default-buffer-for-file-links "*scratch*") ; fixes 'no buffers remain to edit error for org-protocol capturer
#+end_src
And finally, here are the capture templates for org-protocol captures.
#+begin_src elisp :tangle ~/.emacs.d/custom.el
(defvar org-capture-templates '(
("p" "Protocol"
entry
(file "inbox.org")
"* %^{Title}\nSource: %u, %c\n #+BEGIN_QUOTE\n%i\n#+END_QUOTE\n\n\n%?"
)
("L" "Protocol Link"
entry
(file "inbox.org")
"* %? [[%:link][%:description]]\n:PROPERTIES:\n:TITLE: %:description\n:URI: %:link\n:CREATED: %U\n:END:"
:prepend nil
:empty-lines 1
:created t
:kill-buffer t
)
)
)
#+end_src
*** DONE Convert Orgzly captures to org-protocol captures standard
:LOGBOOK:
- State "DONE" from "TODO" [2023-07-10 Mon 11:52]
:END:
This will create clickable titles, create "TITLE", " URL", and "CREATED" properties
#+begin_src elisp
(defun my/org-convert-orgzly-to-org-protocol ()
"Reformat Orgzly bookmark at point to org-protocol bookmark."
(interactive)
(when (org-at-heading-p)
(let ((headline (nth 4 (org-heading-components))))
;; Find and store the link. Delete the link line.
(search-forward-regexp "^https?://\\S-*" nil t)
(let ((link (match-string 0)))
(beginning-of-line)
(kill-line)
;; Delete any trailing blank spaces
(org-back-to-heading)
(end-of-line)
(when (not (org-on-heading-p))
(delete-char 1)
)
;; Set new headline
(goto-char (org-entry-beginning-position))
(org-edit-headline (format "[[%s][%s]]" link headline))
;; Set new properties
(org-set-property "TITLE" headline)
(org-set-property "URI" link)
(message "Reformatted Orgzly bookmark at point to org-protocol bookmark")
)
)
)
)
#+end_src
*** DONE org-refile targets
:LOGBOOK:
- State "DONE" from "TODO" [2024-07-16 Tue 21:38]
- State "DONE" from "TODO" [2023-07-07 Fri 16:51]
:END:
Allow refiling to agenda files, nine headers deep, either in current buffer or in agenda files.
#+begin_src elisp
(setq org-refile-targets '((nil :maxlevel . 9)
(org-agenda-files :maxlevel . 9)
)
)
#+end_src
*** TODO Allow filing to new parents created on the go after confirmation
:LOGBOOK:
- State "DONE" from "TODO" [2023-07-07 Fri 16:50]
:END:
#+begin_src elisp :tangle no
(setq org-refile-allow-creating-parent-nodes 'confirm)
#+end_src
*** TODO Set type of refile targets completion
:LOGBOOK:
- State "DONE" from "TODO" [2023-07-07 Fri 16:50]
:END:
This setting is related to the completion of refile targets. If set to `t`, you build the path in steps by selecting one note at a time. This might be useful with deep hierarchies, but can be slow. When set to `nil`, you can enter the path directly, and Org-Mode uses a Helm-like interface to auto-complete the path. This can be faster, but possibly more difficult with deep hierarchies.
#+begin_src elisp :tangle no
(setq org-outline-path-complete-in-steps nil)
#+end_src
*** DONE org-attach
#+begin_src elisp :tangle ~/.emacs.d/custom.el
(defvar org-attach-id-dir (concat org-directory "/library/documents"))
#+end_src
*** TODO [[https://github.com/rexim/org-cliplink][Insert org-mode links from clipboard]]
:PROPERTIES:
:TITLE: GitHub - rexim/org-cliplink: Insert org-mode links from clipboard
:URI: https://github.com/rexim/org-cliplink
:CREATED: [2023-02-13 Mon 12:45]
:END:
:LOGBOOK:
- State "DONE" from "TODO" [2023-08-18 Fri 13:10]
:END:
#+begin_src elisp :tangle no
(use-package org-cliplink
:bind
(("C-x p i" . org-cliplink))
)
#+end_src
*** TODO Include subdirectories in org-roam
:PROPERTIES:
:CREATED: [2023-07-06 Thu 03:18]
:END:
:LOGBOOK:
- State "DONE" from "TODO" [2023-07-06 Thu 12:54]
:END:
#+begin_src elisp :tangle no
(setq org-roam-file-exclude-regexp "^[.][.]?/") ; Include subdirectories
#+end_src
*** TODO [[https://emacs.stackexchange.com/questions/61290/how-to-see-files-of-a-particular-tag-in-org-roam][Filter org-roam nodes find by tag]]
:PROPERTIES:
:TITLE: org mode - How to see files of a particular tag in org-roam? - Emacs Stack Exchange
:URI: https://emacs.stackexchange.com/questions/61290/how-to-see-files-of-a-particular-tag-in-org-roam
:CREATED: [2023-08-19 Sat 12:47]
:END:
:LOGBOOK:
- State "DONE" from "TODO" [2023-08-19 Sat 18:13]
:END:
#+begin_src elisp :tangle no
(defun my/org-roam-node-has-tag (node tag)
"Filter function to check if the given NODE has the specified TAG."
(member tag (org-roam-node-tags node))
)
(defun my/org-roam-node-find-by-tag ()
"Find and open an Org-roam node based on a specified tag."
(interactive)
(let ((tag (read-string "Enter tag: ")))
(org-roam-node-find nil nil (lambda (node) (my/org-roam-node-has-tag node tag))))
)
#+end_src
*** TODO Configure what display in org-roam-buffer
#+begin_src elisp :tangle no
(setq org-roam-mode-sections
(list #'org-roam-backlinks-section
#'org-roam-reflinks-section
;; #'org-roam-unlinked-references-section ;; Note that computing unlinked references may be slow, and has not been added in by default.
)
)
#+end_src
*** TODO Deft
#+begin_src elisp :tangle no
(use-package deft
:commands (deft)
:init
(defvar deft-extensions '("org"))
(defvar deft-recursive nil)
(defvar deft-use-filename-as-title t)
:config
(defvar deft-directory org-directory)
(defvar deft-recursive t)
(defvar deft-strip-summary-regexp ":PROPERTIES:\n\\(.+\n\\)+:END:\n")
(defvar deft-use-filename-as-title t)
:bind ("C-c n d" . deft)
)
#+end_src
*** TODO Move org header to org-roam-daily
#+begin_src elisp :tangle no
(defun my/org-move-entry-to-daily-notes ()
"Move the current org-mode headline to the daily notes file based on its :CREATED: property."
(interactive)
(let*
(
(created-prop (org-entry-get nil "CREATED"))
(created-date (when created-prop
(org-parse-time-string created-prop)))
(year (nth 5 created-date)) ; Extract year (6th element)
(month (nth 4 created-date)) ; Extract month (5th element)
(day (nth 3 created-date)) ; Extract day (4th element)
(target-date (format "%04d-%02d-%02d" year month day)) ; Format date string
(target-file (org-roam-dailies-goto target-date))
)
(when target-file
(org-cut-subtree)
(find-file target-file)
(goto-char (point-max))
(unless (bolp) (newline))
(org-paste-subtree)
)
)
)
#+end_src
#+begin_src elisp :tangle no
(defun my/org-move-entry-to-daily-notes ()
"Move the current org-mode headline to the daily notes file based on its :CREATED: property."
(interactive)
(let*
(
(created-prop (org-entry-get nil "CREATED"))
(created-date (when created-prop
(org-parse-time-string created-prop)))
(year (nth 5 created-date)) ; Extract year (6th element)
(month (nth 4 created-date)) ; Extract month (5th element)
(day (nth 3 created-date)) ; Extract day (4th element)
(target-date (format "%04d-%02d-%02d" year month day)) ; Format date string
;(target-date "2024-01-01")
(target-file (concat org-roam-dailies-directory "/" target-date ".org"))
(find-file target-file)
)
)
(when target-file
(org-cut-subtree)
(find-file target-file)
(org-id-get-create)
;; #+title: target-date
(goto-char (point-max))
(unless (bolp) (newline))
(org-paste-subtree)
)
)
#+end_src
*** TODO [[https://git.ikl.sh/132ikl/dotfiles/src/branch/main/.doom.d/lisp/refile.el][Modified rose Refile to org-roam-dailies]]
Arrived to from [[https://www.reddit.com/r/OrgRoam/comments/ruc59q/tips_for_refiling_into_org_roam_dailies/][this conversation]]
Here's a breakdown of the functions and their roles:
0. org-roam-dailies--capture
#+begin_src elisp :tangle no
(defun org-roam-dailies--capture (time &optional goto keys)
"Capture an entry in a daily-note for TIME, creating it if necessary.
When GOTO is non-nil, go the note without creating an entry.
ELisp programs can set KEYS to a string associated with a template.
In this case, interactive selection will be bypassed."
(let ((org-roam-directory (expand-file-name org-roam-dailies-directory org-roam-directory))
(org-roam-dailies-directory "./"))
(org-roam-capture- :goto (when goto '(4))
:keys keys
:node (org-roam-node-create)
:templates org-roam-dailies-capture-templates
:props (list :override-default-time time)))
(when goto (run-hooks 'org-roam-dailies-find-file-hook)))
#+end_src
1. `my/refile`: This function refiles a single headline by finding the file, reverting the buffer, and replacing fuzzy links with roam: links.
#+begin_src elisp :tangle no
;;; lisp/refile.el -*- lexical-binding: t; -*-
(defun my/refile ()
"Refiles a headline (and its subtree) with a CREATED property to its corresponding daily."
(interactive)
(revert-buffer t t)
;; replace fuzzy links with roam: links (exclude non-fuzzy links, ie. links with `:')
(while (re-search-forward "\\[\\[\\([^:]+?\\)\\]\\]" nil t)
(replace-match "[[roam:\\1]]" nil nil))
; (org-roam-link-replace-all) ;; TODO create blank page if non-existent
;; remove blank lines because i think they are ugly
(while (re-search-forward "\n+" nil t)
(replace-match "\n" nil nil))
(let ((entries (org-map-entries #'my/refile--inbox-headline nil 'file)))
(message (format "Refiled %d headline(s)" (seq-count #'identity entries)))
)
)
#+end_src
2. `my/refile--inbox-headline`: This function refiles a headline at the current point by deleting the CREATED property and capturing the headline using org-capture.
#+begin_src elisp :tangle no
(defun my/refile--inbox-headline ()
"Refile headline at POINT."
(setq org-map-continue-from (point))
(if-let (capture-template (my/refile--get-template))
(my/refile--capture capture-template)
(my/refile--to-node)))
#+end_src
3. `my/refile--capture`: This function runs org-capture on an inbox heading and inserts the result into the buffer.
#+begin_src elisp :tangle no
(defun my/refile--capture (capture-template)
"Run 'org-capture' on inbox heading using CAPTURE-TEMPLATE."
;; (org-entry-delete nil "CREATED")
(let ((keys (car capture-template))
(heading (cdr capture-template))
(entry (org-no-properties (org-get-entry))))
(org-capture nil keys)
(insert heading "\n" entry))
(org-capture-finalize)
(org-cut-subtree)
)
#+end_src
4. `my/refile--get-template`: This function parses the capture template prefix from the heading and returns a cons cell containing the keys and heading.
#+begin_src elisp :tangle no
(defun my/refile--get-template ()
"Parse capture template prefix from heading."
(when-let* ((raw-heading (org-no-properties (org-get-heading)))
(match (string-match "@\\(\\w+\\) \\(.+\\)$" raw-heading))
(keys (match-string-no-properties 1 raw-heading))
(heading (match-string-no-properties 2 raw-heading)))
(cons keys heading))
)
#+end_src
5. `my/refile--to-node`: This function refiles a headline to an Org-roam node.
#+begin_src elisp :tangle no
(defun my/refile--to-node ()
"Refiles non-capture headings to org-roam node."
(if-let ((to (+org/entry-get-delete "TO")))
(my/refile--org-roam-node (org-roam-node-from-title-or-alias to))
(my/refile--to-daily)))
#+end_src
6. `my/refile--to-daily`: This function refiles a headline to a daily node based on its CREATED property.
#+begin_src elisp :tangle no
(defun my/refile--to-daily ()
"Refile headline at POINT to the associated daily node based on its `CREATED' property."
(when-let* ((created (org-entry-get nil "CREATED"))
(time (org-time-string-to-time created))
(daily-node (my/refile--get-daily-node time)))
(org-entry-delete nil "CREATED")
(my/refile--org-roam-node daily-node)))
#+end_src
7. `my/refile--get-daily-node`: This function returns the Org-roam node for a given time.
#+begin_src elisp :tangle no
(defun my/refile--get-daily-node (time)
"Return org-roam node for TIME."
(save-window-excursion
(org-roam-dailies--capture time t)
(org-roam-node-at-point)))
#+end_src
8. `my/refile--org-roam-node`: This function refiles a node to an Org-roam node.
The `my/refile--org-roam-node` function is quite long and complex, but it seems to be responsible for refiling a node to an Org-roam node. It takes several arguments, including the node to refile, and uses several org-roam functions to perform the refiling.
#+begin_src elisp :tangle no
(defun my/refile--org-roam-node (node)
"Refile NODE at point to an Org-roam node.
If region is active, then use it instead of the node at point.
Implementation of `org-roam-refile' from org-roam PR #2388."
(interactive
(list (org-roam-node-read nil nil nil 'require-match)))
(let* ((regionp (org-region-active-p))
(region-start (and regionp (region-beginning)))
(region-end (and regionp (region-end)))
(file (org-roam-node-file node))
(nbuf (or (find-buffer-visiting file)
(find-file-noselect file)))
level reversed)
(if (equal (org-roam-node-at-point) node)
(user-error "Target is the same as current node")
(if regionp
(progn
(org-kill-new (buffer-substring region-start region-end))
(org-save-markers-in-region region-start region-end))
(progn
(if (org-before-first-heading-p)
(org-roam-demote-entire-buffer))
(org-copy-subtree 1 nil t)))
(with-current-buffer nbuf
(org-with-wide-buffer
(goto-char (org-roam-node-point node))
(setq level (org-get-valid-level (funcall outline-level) 1)
reversed (org-notes-order-reversed-p))
(goto-char
(if reversed
(or (outline-next-heading) (point-max))
(or (save-excursion (org-get-next-sibling))
(org-end-of-subtree t t)
(point-max))))
(unless (bolp) (newline))
(org-paste-subtree level nil nil t)
(and org-auto-align-tags
(let ((org-loop-over-headlines-in-active-region nil))
(org-align-tags)))
(when (fboundp 'deactivate-mark) (deactivate-mark))))
(if regionp
(delete-region (point) (+ (point) (- region-end region-start)))
(org-preserve-local-variables
(delete-region
(and (org-back-to-heading t) (point))
(min (1+ (buffer-size)) (org-end-of-subtree t t) (point)))))
;; If the buffer end-up empty after the refile, kill it and delete its
;; associated file.
(when (eq (buffer-size) 0)
(if (buffer-file-name)
(delete-file (buffer-file-name)))
(set-buffer-modified-p nil)
;; If this was done during capture, abort the capture process.
(when (and org-capture-mode
(buffer-base-buffer (current-buffer)))
(org-capture-kill))
(kill-buffer (current-buffer))))))
#+end_src
#+begin_src elisp :tangle no
(defun +org/entry-get-delete (entry)
(prog1 (org-entry-get nil entry) (org-entry-delete nil entry)))
#+end_src
*** TODO [[https://systemcrafters.net/build-a-second-brain-in-emacs/5-org-roam-hacks/#automatically-copy-or-move-completed-tasks-to-dailies][Automatically copy (or move) completed tasks to dailies]]
#+begin_src elisp :tangle no
(defun my/org-roam-copy-todo-to-today ()
(interactive)
(let ((org-refile-keep t) ;; Set this to nil to delete the original!
(org-roam-dailies-capture-templates
'(("t" "tasks" entry "%?"
:if-new (file+head+olp "%<%Y-%m-%d>.org" "#+title: %<%Y-%m-%d>\n" ("Tasks")))))
(org-after-refile-insert-hook #'save-buffer)
today-file
pos)
(save-window-excursion
(org-roam-dailies--capture (current-time) t)
(setq today-file (buffer-file-name))
(setq pos (point)))
;; Only refile if the target file is different than the current file
(unless (equal (file-truename today-file)
(file-truename (buffer-file-name)))
(org-refile nil nil (list "Tasks" today-file nil pos)))))
(add-to-list 'org-after-todo-state-change-hook
(lambda ()
(when (equal org-state "DONE")
(my/org-roam-copy-todo-to-today))))
#+end_src
*** TODO org-roam-capture templates
:LOGBOOK:
- State "DONE" from "TODO" [2023-08-19 Sat 18:17]
:END:
#+begin_src elisp
(setq org-roam-capture-templates
'(
("L" "link" plain
(function org-roam--capture-get-point)
"%?"
:file-name "web/%<%Y-%m-%dT%H%M%S>.org"
:head "#+TITLE: ${title}\n#+CREATED: %<%Y-%m-%dT%H%M%S>"
:immediate-finish t
:unnarrowed t
)
("h" "hugo post" plain
"%?"
:target (file+head "posts/${slug}.org"
"#+TITLE: ${title}\n#+DATE: %U\n#+HUGO_BASE_DIR: ~/gharbeia.net\n#+HUGO_SECTION: ./posts\n#+HUGO_AUTO_SET_LASTMOD: t\n#+HUGO_TAGS: article\n#+HUGO_DRAFT: true\n")
:immediate-finish t
:unnarrowed t
)
("p" "person" plain
"%?"
:if-new (file+head "people/${slug}.org"
"#+TITLE: ${title}")
:immediate-finish t
:unnarrowed t
)
)
)
#+end_src
#+begin_src elisp
(setq org-roam-dailies-capture-templates
'(
("d" "daily" plain
""
:target ("file+heaed %<%Y-%m-%d>.org" "#+title: %<%Y-%m-%d>\n\n")
:immediate-finish t
)
)
)
#+end_src
** TODO [0/26] Reading and Writing
:LOGBOOK:
- State "DONE" from "TODO" [2023-07-06 Thu 12:32]
:END:
*** TODO Expand some words with auto-correct
#+begin_src elisp :tangle no
(setq save-abbrevs 'silently)
(setq-default abbrev-mode t)
#+end_src
*** TODO ediff
#+begin_src elisp :tangle no
(setq ediff-window-setup-function 'ediff-setup-windows-plain)
(setq ediff-split-window-function 'split-window-horizontally)
#+end_src
*** TODO tramp
#+begin_src elisp :tangle no
(setq tramp-default-method "ssh"
tramp-backup-directory-alist backup-directory-alist
tramp-ssh-controlmaster-options "ssh")
#+end_src
*** TODO Move correctly over camelCased words
#+begin_src elisp :tangle no
(subword-mode)
#+end_src
*** TODO Understand the more common sentence
#+begin_src elisp :tangle no
(setq sentence-end-double-space nil)
#+end_src
*** TODO Text completion
:LOGBOOK:
- State "DONE" from "TODO" [2023-07-05 Wed 16:46]
:END:
#+begin_src elisp :tangle no
(use-package company
:diminish company-mode
:config
(defvar company-minimum-prefix-length 3)
(defvar company-idle-delay 0)
(defvar company-global-modes t)
(defvar company-selection-wrap-around t)
(defvar company-tooltip-align-annotations t)
(defvar company-backends '((
company-capf
company-dabbrev-code
company-dabbrev
company-ispell
company-files
company-web
company-shell
company-posframe
)))
(global-company-mode)
(add-hook 'after-init-hook 'global-company-mode)
(add-hook 'after-init-hook 'company-tng-mode)
(global-set-key (kbd "<tab>") #'company-indent-or-complete-common)
(global-set-key (kbd "C-c C-/") #'company-other-backend)
(with-eval-after-load 'company
(define-key company-active-map (kbd "M-/") #'company-complete))
(with-eval-after-load 'company
(define-key company-active-map
(kbd "TAB")
#'company-complete-common-or-cycle)
(define-key company-active-map
(kbd "<backtab>")
(lambda ()
(interactive)
(company-complete-common-or-cycle -1))))
)
#+end_src
#+begin_src elisp :tangle no
(use-package company-shell
:after company
:config
(add-to-list 'company-backends '(company-shell
company-shell-env
company-fish-shell
)
)
(setq company-transformers '(delete-consecutive-dups
company-sort-by-occurrence))
)
#+end_src
#+begin_src elisp :tangle no
(use-package company-capf
:after company
:config
(add-to-list 'company-backends '(company-capf))
)
#+end_src
#+begin_src elisp :tangle no
(use-package company-ispell
:after company
)
(add-to-list 'company-backends '(company-ispell))
#+end_src
#+begin_src elisp :tangle no
(use-package company-files
:after company
)
(add-to-list 'company-backends '(company-files))
#+end_src
**** TODO Required for proportional font
:LOGBOOK:
- State "DONE" from "TODO" [2023-07-05 Wed 16:46]
:END:
#+begin_src elisp :tangle no
(use-package company-posframe
:diminish company-posframe-mode
:config (company-posframe-mode)
)
#+end_src
*** TODO [[https://pages.sachachua.com/.emacs.d/Sacha.html#orgcb6a264][Join lines into paragraph]]
:LOGBOOK:
- State "DONE" from "TODO" [2023-07-06 Thu 12:31]
:END:
#+begin_src elisp :tangle no
(defun my/fill-or-unfill-paragraph (&optional unfill region)
"Fill paragraph (or REGION). With the prefix argument UNFILL, fill it instead."
(interactive (progn
(barf-if-buffer-read-only)
(list (if current-prefix-arg 'fill) t)))
(let ((fill-column (if unfill fill-column (point-max))))
(fill-paragraph nil region)))
(bind-key "M-q" 'my/fill-or-unfill-paragraph)
#+end_src
#+begin_src elisp :tangle no
(defun my/fill-or-unfill-all-paragraphs (&optional unfill)
"Fill or unfill all paragraphs in the current buffer.
With the prefix argument UNFILL, fill them instead."
(interactive (list (if current-prefix-arg 'fill)))
(let ((fill-column (if unfill fill-column (point-max))))
(save-excursion
(goto-char (point-min))
(while (not (eobp))
(fill-paragraph nil t)
(forward-paragraph)))))
(bind-key "M-Q" 'my/fill-or-unfill-all-paragraphs)
#+end_src
#+begin_src elisp :tangle no
(remove-hook 'text-mode-hook #'turn-on-auto-fill)
(add-hook 'text-mode-hook 'turn-on-visual-line-mode)
#+end_src
*** TODO Transform <a href> links into org links
:LOGBOOK:
- State "DONE" from [2023-08-19 Sat 19:41]
:END:
#+begin_src elisp :tangle no
(defun my/transform-html-links-to-org ()
"Transform all HTML <a> links in the current buffer into 'org-mode' links."
(interactive)
(goto-char (point-min))
(while (re-search-forward "<a href=\"\\(.*?\\)\">\\(.*?\\)</a>" nil t)
(replace-match (org-make-link-string (match-string 1) (match-string 2)))))
#+end_src
*** TODO [[https://pages.sachachua.com/.emacs.d/Sacha.html#org9d2ca0e][Clean up space s]]
:LOGBOOK:
- State "DONE" from "TODO" [2023-07-06 Thu 12:32]
:END:
#+begin_src elisp :tangle no
(bind-key "M-SPC" 'cycle-spacing)
#+end_src
*** TODO Count words per minute
:LOGBOOK:
- State "DONE" from "TODO" [2023-07-06 Thu 12:32]
:END:
#+begin_src elisp :tangle no
(require 'org-clock)
(defun my/org-entry-wpm ()
(interactive)
(save-restriction
(save-excursion
(org-narrow-to-subtree)
(goto-char (point-min))
(let* ((words (count-words-region (point-min) (point-max)))
(minutes (org-clock-sum-current-item))
(wpm (/ words minutes)))
(message "WPM: %d (words: %d, minutes: %d)" wpm words minutes)
(kill-new (number-to-string wpm))
)
)
)
)
#+end_src
*** TODO Enable dict mode
#+begin_src elisp :tangle no
(setq dictionary-server "automatic")
#+end_src
*** TODO Convert DOuble capitals to single capitals
:LOGBOOK:
- State "DONE" from "TODO" [2024-06-27 Thu 13:02]
- State "DONE" from "NEXT" [2023-08-09 Wed 13:51]
:END:
#+begin_src elisp :tangle no
(defun my/dcaps-to-scaps ()
"Convert word in DOuble CApitals to Single Capitals."
(interactive)
(and (= ?w (char-syntax (char-before)))
(save-excursion
(and (if (called-interactively-p)
(skip-syntax-backward "w")
(= -3 (skip-syntax-backward "w"))
)
(let (case-fold-search)
(looking-at "\\b[[:upper:]]\\{2\\}[[:lower:]]")
)
(capitalize-word 1)
)
)
)
)
#+end_src
Then, lets define a minor mode for it to be activated.
#+begin_src elisp :tangle no
(define-minor-mode my-dubcaps-mode
"Toggle 'my-dubcaps-mode' and convert words in DOuble CApitals to Single Capitals as you type."
:init-value nil
:lighter (" DC")
(if my-dubcaps-mode
(add-hook 'post-self-insert-hook #'my/dcaps-to-scaps nil 'local)
(remove-hook 'post-self-insert-hook #'my/dcaps-to-scaps 'local)))
#+end_src
Finally, lets add a hook so that it is on for all the text files Emacs opens.
#+begin_src elisp :tangle no
(add-hook 'text-mode-hook #'my-dubcaps-mode)
#+end_src
Also, since we add a minor mode string (it might be useful sometimes), currently I prefer to diminish it.
#+begin_src elisp :tangle no
(defun my/diminish-dubcaps ()
(interactive)
(diminish 'my-dubcaps-mode ""))
(add-hook 'my-dubcaps-mode-hook 'my/diminish-dubcaps)
#+end_src
*** TODO Pick out passive voice and weasel words
:LOGBOOK:
- State "DONE" from "NEXT" [2023-08-09 Wed 13:52]
:END:
#+begin_src elisp :tangle no
(use-package writegood-mode
:diminish writegood-mode
:config
(progn (add-hook 'text-mode-hook 'writegood-mode))
)
#+end_src
*** TODO [[https://github.com/yoshiki/yaml-mode][Yaml]]
:LOGBOOK:
- State "DONE" from "TODO" [2024-06-27 Thu 13:03]
:END:
#+begin_src elisp :tangle no
(use-package yaml-mode
:config
(add-to-list 'auto-mode-alist '("\\.yml\\'" . yaml-mode))
(add-to-list 'auto-mode-alist '("\\.yaml\\'" . yaml-mode))
)
#+end_src
*** TODO Docker
:LOGBOOK:
- State "DONE" from "TODO" [2024-06-27 Thu 13:03]
:END:
#+begin_src elisp :tangle no
(use-package docker-compose-mode)
#+end_src
*** TODO [[https://github.com/ifitzpat/ob-docker-build][Org-babel docker]]
:LOGBOOK:
- State "DONE" from "TODO" [2024-07-09 Tue 16:58]
:END:
#+begin_src elisp :tangle no
(use-package ob-docker-build
:straight (ob-docker-build :type git :host github :repo "ifitzpat/ob-docker-build")
:defer t
:config
(add-to-list 'org-babel-load-languages '(docker-build . t))
(org-babel-do-load-languages 'org-babel-load-languages org-babel-load-languages)
)
#+end_src
*** TODO Spell checking and translation
:LOGBOOK:
- State "DONE" from "TODO" [2023-07-05 Wed 16:09]
:END:
This requires installation of hunspell
#+begin_src bash :tangle no
sudo apt install hunspell
#+end_src
#+begin_src elisp :tangle no
(use-package flyspell
:config (setq ispell-program-name "hunspell"
ispell-default-dictionary "en_US"
)
:diminish (flyspell-mode . "φ")
:hook (text-mode . flyspell-mode)
:bind (
("M-<f7>" . flyspell-buffer)
("<f7>" . flyspell-word)
("C-;" . flyspell-auto-correct-previous-word)
)
)
#+end_src
*** TODO [[https://github.com/d12frosted/flyspell-correct][Flyspell correct]]
:LOGBOOK:
- State "DONE" from [2024-07-02 Tue 13:13]
:END:
#+begin_src elisp :tangle no
(use-package flyspell-correct
:after flyspell
:bind (:map flyspell-mode-map ("C-;" . flyspell-correct-wrapper))
)
#+end_src
*** TODO [[https://www.flycheck.org/][Flycheck]]
:LOGBOOK:
- State "DONE" from "TODO" [2024-07-02 Tue 13:13]
:END:
Needs external checkers installed
#+begin_src elisp :tangle no
(use-package flycheck
:init (global-flycheck-mode)
:diminish (flycheck-mode . "")
:config
(add-hook 'after-init-hook #'global-flycheck-mode)
(setq flycheck-emacs-lisp-load-path 'inherit)
(setq flycheck-emacs-lisp-load-path (concat user-emacs-directory "straight/build"))
)
#+end_src
*** TODO [[https://github.com/cuonglm/flycheck-checkbashisms][Flycheck bash]]
#+begin_src bash :tangle no
sudo apt install devscripts
#+end_src
#+begin_src elisp :tangle no
(use-package flycheck-checkbashisms
:config
(flycheck-checkbashisms-setup)
)
#+end_src
*** TODO [[https://github.com/chenyanming/calibredb.el][Read ebooks]]
:PROPERTIES:
:CREATED: [2023-01-14 Sat 16:38]
:END:
:LOGBOOK:
- State "DONE" from "TODO" [2024-06-27 Thu 09:30]
- State "DONE" from "NEXT" [2023-08-09 Wed 13:27]
:END:
#+begin_src elisp :tangle no
(use-package calibredb)
#+end_src
#+begin_src elisp :tangle ~/.emacs.d/custom.el
(defvar calibredb-root-dir (concat (getenv "HOME") "/library/books"))
(defvar calibredb-db-dir (expand-file-name "metadata.db" calibredb-root-dir))
(defvar calibredb-library-alist (concat (getenv "HOME") "/library/books"))
#+end_src
Some keybindings
#+begin_src elisp
(defvar calibredb-show-mode-map
(let ((map (make-sparse-keymap)))
(define-key map "?" #'calibredb-entry-dispatch)
(define-key map "o" #'calibredb-find-file)
(define-key map "O" #'calibredb-find-file-other-frame)
(define-key map "V" #'calibredb-open-file-with-default-tool)
(define-key map "s" #'calibredb-set-metadata-dispatch)
(define-key map "e" #'calibredb-export-dispatch)
(define-key map "q" #'calibredb-entry-quit)
(define-key map "y" #'calibredb-yank-dispatch)
(define-key map "," #'calibredb-quick-look)
(define-key map "." #'calibredb-dired-open)
(define-key map "\M-/" #'calibredb-rga)
(define-key map "\M-t" #'calibredb-set-metadata--tags)
(define-key map "\M-a" #'calibredb-set-metadata--author_sort)
(define-key map "\M-A" #'calibredb-set-metadata--authors)
(define-key map "\M-T" #'calibredb-set-metadata--title)
(define-key map "\M-c" #'calibredb-set-metadata--comments)
map)
"Keymap for `calibredb-show-mode'.")
#+end_src
#+begin_src elisp
(defvar calibredb-search-mode-map
(let ((map (make-sparse-keymap)))
(define-key map [mouse-3] #'calibredb-search-mouse)
(define-key map (kbd "<RET>") #'calibredb-find-file)
(define-key map "?" #'calibredb-dispatch)
(define-key map "a" #'calibredb-add)
(define-key map "A" #'calibredb-add-dir)
(define-key map "c" #'calibredb-clone)
(define-key map "d" #'calibredb-remove)
(define-key map "D" #'calibredb-remove-marked-items)
(define-key map "j" #'calibredb-next-entry)
(define-key map "k" #'calibredb-previous-entry)
(define-key map "l" #'calibredb-virtual-library-list)
(define-key map "L" #'calibredb-library-list)
(define-key map "n" #'calibredb-virtual-library-next)
(define-key map "N" #'calibredb-library-next)
(define-key map "p" #'calibredb-virtual-library-previous)
(define-key map "P" #'calibredb-library-previous)
(define-key map "s" #'calibredb-set-metadata-dispatch)
(define-key map "S" #'calibredb-switch-library)
(define-key map "o" #'calibredb-find-file)
(define-key map "O" #'calibredb-find-file-other-frame)
(define-key map "v" #'calibredb-view)
(define-key map "V" #'calibredb-open-file-with-default-tool)
(define-key map "," #'calibredb-quick-look)
(define-key map "." #'calibredb-dired-open)
(define-key map "y" #'calibredb-yank-dispatch)
(define-key map "b" #'calibredb-catalog-bib-dispatch)
(define-key map "e" #'calibredb-export-dispatch)
(define-key map "r" #'calibredb-search-refresh-and-clear-filter)
(define-key map "R" #'calibredb-search-clear-filter)
(define-key map "q" #'calibredb-search-quit)
(define-key map "m" #'calibredb-mark-and-forward)
(define-key map "f" #'calibredb-toggle-favorite-at-point)
(define-key map "x" #'calibredb-toggle-archive-at-point)
(define-key map "h" #'calibredb-toggle-highlight-at-point)
(define-key map "u" #'calibredb-unmark-and-forward)
(define-key map "i" #'calibredb-edit-annotation)
(define-key map (kbd "<DEL>") #'calibredb-unmark-and-backward)
(define-key map (kbd "<backtab>") #'calibredb-toggle-view)
(define-key map (kbd "TAB") #'calibredb-toggle-view-at-point)
(define-key map "\M-n" #'calibredb-show-next-entry)
(define-key map "\M-p" #'calibredb-show-previous-entry)
(define-key map "/" #'calibredb-search-live-filter)
(define-key map "\M-t" #'calibredb-set-metadata--tags)
(define-key map "\M-a" #'calibredb-set-metadata--author_sort)
(define-key map "\M-A" #'calibredb-set-metadata--authors)
(define-key map "\M-T" #'calibredb-set-metadata--title)
(define-key map "\M-c" #'calibredb-set-metadata--comments)
map)
"Keymap for `calibredb-search-mode'.")
#+end_src
*** TODO Annotate [[https://github.com/org-noter/org-noter][PDFs and EPUBs]]
:LOGBOOK:
- State "DONE" from "NEXT" [2023-08-09 Wed 15:06]
:END:
#+begin_src elisp :tangle no
(use-package org-noter)
#+end_src
#+begin_src elisp :tangle ~/.emacs.d/custom.el
(defvar org-noter-notes-search-path (list (concat org-directory "/library/books")))
(defvar org-noter-default-notes-file-names '("books.org"))
#+end_src
*** TODO [[https://github.com/fuxialexander/org-pdftools][Link PDFs]]
:PROPERTIES:
:TITLE: GitHub - fuxialexander/org-pdftools: A custom org link type for pdf-tools
:URI: https://github.com/fuxialexander/org-pdftools
:CREATED: [2023-01-28 Sat 11:04]
:END:
:LOGBOOK:
- State "DONE" from "NEXT" [2023-08-12 Sat 14:05]
:END:
#+begin_src elisp :tangle no
(use-package org-noter-pdftools
:after org-noter
:config
;; Add a function to ensure precise note is inserted
(defun org-noter-pdftools-insert-precise-note (&optional toggle-no-questions)
(interactive "P")
(org-noter--with-valid-session
(let ((org-noter-insert-note-no-questions (if toggle-no-questions
(not org-noter-insert-note-no-questions)
org-noter-insert-note-no-questions))
(org-pdftools-use-isearch-link t)
(org-pdftools-use-freepointer-annot t))
(org-noter-insert-note (org-noter--get-precise-info)))))
;; fix https://github.com/weirdNox/org-noter/pull/93/commits/f8349ae7575e599f375de1be6be2d0d5de4e6cbf
(defun org-noter-set-start-location (&optional arg)
"When opening a session with this document, go to the current location.
With a prefix ARG, remove start location."
(interactive "P")
(org-noter--with-valid-session
(let ((inhibit-read-only t)
(ast (org-noter--parse-root))
(location (org-noter--doc-approx-location (when (called-interactively-p 'any) 'interactive))))
(with-current-buffer (org-noter--session-notes-buffer session)
(org-with-wide-buffer
(goto-char (org-element-property :begin ast))
(if arg
(org-entry-delete nil org-noter-property-note-location)
(org-entry-put nil org-noter-property-note-location
(org-noter--pretty-print-location location))))))))
(with-eval-after-load 'pdf-annot
(add-hook 'pdf-annot-activate-handler-functions #'org-noter-pdftools-jump-to-note)
)
)
#+end_src
*** TODO [[https://depp.brause.cc/nov.el/][View EPUBs]] :books:
:LOGBOOK:
- State "DONE" from "NEXT" [2023-08-09 Wed 13:19]
:END:
#+begin_src elisp :tangle no
(use-package nov
:config
(add-to-list 'auto-mode-alist '("\\.epub\\'" . nov-mode))
)
#+end_src
*** TODO View PDF files
#+begin_src elisp :tangle no
(setq doc-view-continuous t)
#+end_src
*** TODO [[https://github.com/tmalsburg/helm-bibtex][Zotero]]
#+begin_src elisp :tangle no
(use-package helm-bibtex)
#+end_src
#+begin_src elisp :tangle ~/.emacs.d/custom.el
(defvar bibtex-completion-bibliography '("~/bibliography/zotero.bib"))
#+end_src
** DONE [2/2] Security
:LOGBOOK:
- State "DONE" from "TODO" [2024-07-16 Tue 21:49]
- State "DONE" from "TODO" [2024-07-09 Tue 14:16]
:END:
*** DONE Password-store
:LOGBOOK:
- State "DONE" from "TODO" [2024-07-16 Tue 21:49]
- State "DONE" from "TODO" [2023-07-06 Thu 11:44]
:END:
#+begin_src elisp
(use-package password-store)
#+end_src
*** DONE Auth source
:LOGBOOK:
- State "DONE" from "TODO" [2023-07-06 Thu 11:45]
:END:
#+begin_src elisp
(use-package auth-source
:config (auth-source-pass-enable)
)
#+end_src
** TODO [0/3] AI
*** TODO [[https://github.com/s-kostyaev/ellama][Ellama]]
:LOGBOOK:
- State "DONE" from "TODO" [2024-06-27 Thu 07:40]
:END:
#+begin_src elisp :tangle no
;; YOU DON'T NEED NONE OF THIS CODE FOR SIMPLE INSTALL
;; IT IS AN EXAMPLE OF CUSTOMIZATION.
(use-package ellama
:init
;; setup key bindings
(setq ellama-keymap-prefix "C-c e")
)
#+end_src
#+begin_src elisp :tangle no
;; language you want ellama to translate to
(setq ellama-language "English")
(setq ellama-sessions-directory (concat org-directory "ellama-sessions"))
;; could be llm-openai for example
;;(require 'llm-openai)
;; (setq ellama-provider "openai")
(setq ellama-provider "groq")
(setq ellama-provider (make-llm-openai-compatible
:url "https://api.groq.com/openai/v1"
:key (auth-source-pass-get "api-key" "www/console.groq.com/groq@amr.gharbeia.net")
:chat-model "llama3-70b-8192"
:embedding-model "llama3-70b-8192"))
;; Predefined llm providers for interactive switching.
;; You shouldn't add ollama providers here - it can be selected interactively
;; without it. It is just example.
(setq ellama-providers
'(
("zephyr" . (make-llm-ollama
:chat-model "zephyr:7b-beta-q6_K"
:embedding-model "zephyr:7b-beta-q6_K"))
("mistral" . (make-llm-ollama
:chat-model "mistral:7b-instruct-v0.2-q6_K"
:embedding-model "mistral:7b-instruct-v0.2-q6_K"))
("mixtral" . (make-llm-ollama
:chat-model "mixtral:8x7b-instruct-v0.1-q3_K_M-4k"
:embedding-model "mixtral:8x7b-instruct-v0.1-q3_K_M-4k"))
("openai" . (make-llm-openai
:key (auth-source-pass-get "api-key" "www/openai.com/amr@gharbeia.net")
;; :chat-model "gpt-4-turbo-preview"
:chat-model "gpt-4o"
;; :chat-model "gpt-3.5-turbo"
:embedding-model "text-embedding-3-large"))
("groq" . (make-llm-openai-compatible
:url "https://api.groq.com/openai/v1"
:key (auth-source-pass-get "api-key" "www/console.groq.com/groq@amr.gharbeia.net")
:chat-model "llama3-70b-8192"
:embedding-model "llama3-70b-8192"))
)
)
;; Naming new sessions with llm
(setq ellama-naming-provider
(make-llm-openai-compatible
:url "https://api.groq.com/openai/v1"
:key (auth-source-pass-get "api-key" "www/console.groq.com/groq@amr.gharbeia.net")
:chat-model "llama3-70b-8192"
:embedding-model "llama3-70b-8192")
)
(setq ellama-naming-scheme 'ellama-generate-name-by-llm)
;; Translation llm provider
(setq ellama-translation-provider
(make-llm-openai-compatible
:url "https://api.groq.com/openai/v1"
:key (auth-source-pass-get "api-key" "www/console.groq.com/groq@amr.gharbeia.net")
:chat-model "llama3-70b-8192"
:embedding-model "llama3-70b-8192")
)
#+end_src
*** TODO Change gptel
:LOGBOOK:
- State "CNCL" from "DONE" [2024-04-01 Mon 15:32] \\
Moved to Ellama
- State "DONE" from "TODO" [2024-02-28 Wed 16:49]
:END:
#+begin_src elisp :tangle no
(use-package gptel
)
#+end_src
#+begin_src elisp :tangle no
(setq gptel-api-key (auth-source-pass-get "api-key" "www/openai.com/amr@gharbeia.net"))
#+end_src
*** TODO Elisa
#+begin_src elisp :tangle no
(use-package elisa
:init
(setopt elisa-limit 5)
(require 'llm-ollama)
(setopt elisa-embeddings-provider (make-llm-ollama :embedding-model "nomic-embed-text"))
(setopt elisa-chat-provider (make-llm-ollama
:chat-model "sskostyaev/openchat:8k-rag"
:embedding-model "nomic-embed-text"))
)
#+end_src
** TODO [[https://github.com/beancount/beancount-mode/][Accounting]]
:LOGBOOK:
- State "DONE" from "TODO" [2024-06-27 Thu 07:43]
:END:
#+begin_src elisp :tangle no
(use-package beancount
:straight (beancount :type git :host github :repo "beancount/beancount-mode")
:config
(add-to-list 'auto-mode-alist '("\\.beancount\\'" . beancount-mode))
(add-hook 'beancount-mode-hook #'outline-minor-mode)
(define-key beancount-mode-map (kbd "C-c C-n") #'outline-next-visible-heading)
(define-key beancount-mode-map (kbd "C-c C-p") #'outline-previous-visible-heading)
(add-hook 'beancount-mode-hook #'flymake-bean-check-enable)
)
#+end_src
On package.el, it is a manual install so far
#+begin_src elisp :tangle no
(make-directory (expand-file-name "manual-packages/" user-emacs-directory) t)
(make-directory (expand-file-name "beancount/" (concat user-emacs-directory "manual-packages")) t)
(add-to-list 'load-path "~/.emacs.d/manual-packages/beancount-mode")
(require 'beancount)
(add-to-list 'auto-mode-alist '("\\.beancount\\'" . beancount-mode))
(add-hook 'beancount-mode-hook #'outline-minor-mode)
(define-key beancount-mode-map (kbd "C-c C-n") #'outline-next-visible-heading)
(define-key beancount-mode-map (kbd "C-c C-p") #'outline-previous-visible-heading)
(add-hook 'beancount-mode-hook #'flymake-bean-check-enable)
#+end_src
#+begin_src bash :tangle no
cd ~/.emacs.d/manual-packages/
git clone https://github.com/beancount/beancount-mode/
#+end_src
** TODO Browser
:LOGBOOK:
- State "DONE" from "TODO" [2023-07-07 Fri 15:29]
:END:
#+begin_src elisp :tangle no
(use-package eww
:bind* (("M-m g x" . eww)
("M-m g :" . eww-browse-with-external-browser)
("M-m g #" . eww-list-histories)
("M-m g {" . eww-back-url)
("M-m g }" . eww-forward-url))
:config
(progn
(add-hook 'eww-mode-hook 'visual-line-mode)
)
)
#+end_src
** TODO [[https://github.com/Silex/docker.el][Manage Docker in Emacs]]
#+begin_src elisp :tangle no
(use-package docker
:bind ("C-c d" . docker)
)
#+end_src
** TODO [[https://github.com/sergiruiztrepat/chemtable][Periodic table of the elements]] :chemistry:
:PROPERTIES:
:CREATED: [2023-01-27 Fri 21:12]
:TITLE: GitHub - sergiruiztrepat/chemtable: Periodic table of the elements
:URI: https://github.com/sergiruiztrepat/chemtable
:END:
:LOGBOOK:
- State "DONE" from "TODO" [2023-08-21 Mon 13:27]
:END:
#+begin_src elisp :tangle no
(use-package chemtable)
#+end_src
** DONE End matter
#+begin_src elisp
(provide 'config)
;;; config.el ends here
#+end_src
#+begin_src elisp :tangle ~/.emacs.d/custom.el
(provide 'custom)
;;; custom.el ends here
#+end_src