2919 lines
91 KiB
Plaintext
2919 lines
91 KiB
Plaintext
: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 ~/.emacs.d/straight/versions/default.el no
|
||
|
||
;; (("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 [5/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 [10/11] 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]] (package.el)
|
||
:PROPERTIES:
|
||
:CLOSED: [2023-01-22 Sun 09:36]
|
||
:END:
|
||
|
||
"A use-package declaration for simplifying your .emacs"
|
||
|
||
#+begin_src elisp :tangle no
|
||
(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 [15/31] GUI, display, and sessions
|
||
:LOGBOOK:
|
||
- State "DONE" from "TODO" [2024-07-10 Wed 17:06]
|
||
- State "DONE" from "TODO" [2024-07-10 Wed 10:44]
|
||
:END:
|
||
|
||
*** 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
|
||
|
||
*** TODO [[https://protesilaos.com/emacs/ef-themes][Theme]]
|
||
:LOGBOOK:
|
||
- State "DONE" from "TODO" [2024-07-10 Wed 17:06]
|
||
:END:
|
||
|
||
#+begin_src elisp :tangle no
|
||
;; 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
|
||
|
||
*** TODO Tab Line
|
||
|
||
#+begin_src elisp :tangle no
|
||
(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
|
||
|
||
*** DONE Fonts
|
||
:LOGBOOK:
|
||
- State "DONE" from [2023-08-22 Tue 11:10]
|
||
:END:
|
||
|
||
#+begin_src elisp
|
||
(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
|
||
(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
|
||
|
||
*** DONE [3/3] Icons
|
||
:LOGBOOK:
|
||
- State "DONE" from "TODO" [2024-07-09 Tue 17:08]
|
||
:END:
|
||
|
||
**** DONE [[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
|
||
(use-package all-the-icons
|
||
:if (display-graphic-p)
|
||
)
|
||
#+end_src
|
||
|
||
**** DONE all-the-icons-completion
|
||
|
||
#+begin_src elisp
|
||
(use-package all-the-icons-completion
|
||
:if (display-graphic-p)
|
||
:after all-the-icons
|
||
:config
|
||
(all-the-icons-completion-mode)
|
||
)
|
||
#+end_src
|
||
**** DONE [4/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
|
||
|
||
***** DONE 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
|
||
|
||
***** DONE 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
|
||
|
||
***** DONE 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
|
||
|
||
***** DONE 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 [1/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
|
||
|
||
**** DONE [[https://gitlab.com/jessieh/mood-line][Moodline]]
|
||
:LOGBOOK:
|
||
- State "DONE" from "TODO" [2024-07-09 Tue 16:18]
|
||
:END:
|
||
|
||
#+begin_src elisp
|
||
(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
|
||
;; 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
|
||
;; 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
|
||
|
||
*** DONE Window Management
|
||
|
||
#+begin_src elisp
|
||
(when (fboundp 'winner-mode)
|
||
(winner-mode t)
|
||
)
|
||
#+end_src
|
||
|
||
#+begin_src elisp :tangle no
|
||
(global-set-key (kbd "M-o") 'other-window)
|
||
#+end_src
|
||
|
||
#+begin_src elisp
|
||
(repeat-mode)
|
||
#+end_src
|
||
|
||
#+begin_src elisp :tangle no
|
||
(use-package winum
|
||
:config
|
||
(winum-mode)
|
||
(setq winum-keymap
|
||
(let ((map (make-sparse-keymap)))
|
||
(define-key map (kbd "C-`") 'winum-select-window-by-number)
|
||
(define-key map (kbd "C-²") 'winum-select-window-by-number)
|
||
(define-key map (kbd "M-0") 'winum-select-window-0-or-10)
|
||
(define-key map (kbd "M-1") 'winum-select-window-1)
|
||
(define-key map (kbd "M-2") 'winum-select-window-2)
|
||
(define-key map (kbd "M-3") 'winum-select-window-3)
|
||
(define-key map (kbd "M-4") 'winum-select-window-4)
|
||
(define-key map (kbd "M-5") 'winum-select-window-5)
|
||
(define-key map (kbd "M-6") 'winum-select-window-6)
|
||
(define-key map (kbd "M-7") 'winum-select-window-7)
|
||
(define-key map (kbd "M-8") 'winum-select-window-8)
|
||
map)
|
||
)
|
||
)
|
||
#+end_src
|
||
|
||
#+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
|
||
|
||
*** DONE Scroll to the first and last line of the buffer
|
||
|
||
#+begin_src elisp
|
||
(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
|
||
|
||
*** DONE Neotree
|
||
:LOGBOOK:
|
||
- State "DONE" from "TODO" [2023-07-05 Wed 16:48]
|
||
:END:
|
||
|
||
#+begin_src elisp
|
||
(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
|
||
|
||
*** 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
|
||
|
||
*** DONE File encoding system
|
||
|
||
#+begin_src elisp
|
||
(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 [1/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
|
||
|
||
**** TODO Bash completion
|
||
:LOGBOOK:
|
||
- State "DONE" from "TODO" [2023-08-18 Fri 13:02]
|
||
:END:
|
||
|
||
#+begin_src elisp :tangle no
|
||
(use-package bash-completion
|
||
:config
|
||
(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 [11/13] 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
|
||
|
||
*** DONE Large file warning
|
||
|
||
#+begin_src elisp :tangle no
|
||
(setq large-file-warning-threshold (* 15 1024 1024))
|
||
#+end_src
|
||
|
||
*** DONE 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
|
||
(use-package all-the-icons-dired
|
||
:if (display-graphic-p)
|
||
)
|
||
#+end_src
|
||
|
||
*** DONE Move deleted files to trash
|
||
|
||
#+begin_src elisp
|
||
(setq delete-by-moving-to-trash t)
|
||
#+end_src
|
||
|
||
*** DONE [[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
|
||
(use-package magit)
|
||
#+end_src
|
||
|
||
*** DONE 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
|
||
(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:
|
||
|
||
*** DONE [[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
|
||
(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 [27/31] Org-Mode
|
||
:LOGBOOK:
|
||
- State "DONE" from "TODO" [2024-02-28 Wed 16:49]
|
||
:END:
|
||
|
||
*** DONE Basic setup
|
||
|
||
#+begin_src elisp
|
||
(use-package org
|
||
:diminish (org-mode . "Ω")
|
||
: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)
|
||
)
|
||
)
|
||
#+end_src
|
||
|
||
#+begin_src elisp :tangle ~/.emacs.d/custom.el
|
||
(defvar org-directory (concat (getenv "HOME") "/org/"))
|
||
#+end_src
|
||
|
||
*** DONE Looks
|
||
|
||
#+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-06-27 Thu 13:06]
|
||
:END:
|
||
#+begin_src elisp
|
||
(use-package org-modern
|
||
:config
|
||
;; (modus-themes-load-operandi)
|
||
|
||
;; Choose some fonts
|
||
(set-face-attribute 'default nil :family "Iosevka")
|
||
(set-face-attribute 'variable-pitch nil :family "Iosevka Aile")
|
||
(set-face-attribute 'org-modern-symbol nil :family "Iosevka")
|
||
|
||
;; Add frame borders and window dividers
|
||
(modify-all-frames-parameters
|
||
'((right-divider-width . 40)
|
||
(internal-border-width . 40)))
|
||
(dolist (face '(window-divider
|
||
window-divider-first-pixel
|
||
window-divider-last-pixel))
|
||
(face-spec-reset-face face)
|
||
(set-face-foreground face (face-attribute 'default :background)))
|
||
(set-face-background 'fringe (face-attribute 'default :background))
|
||
|
||
;; 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 [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
|
||
|
||
*** DONE Images
|
||
|
||
#+begin_src elisp
|
||
(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" [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
|
||
|
||
*** DONE Exporting
|
||
|
||
From [[https://sriramkswamy.github.io/dotemacs/#orgheadline29][Sriramkswamy]]:
|
||
|
||
#+BEGIN_QUOTE
|
||
Org has a powerful exporting feature. Let’s 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
|
||
(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
|
||
|
||
*** DONE Better agenda views
|
||
|
||
#+begin_src elisp
|
||
(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 1)
|
||
#+end_src
|
||
|
||
*** DONE Habits
|
||
:LOGBOOK:
|
||
- 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
|
||
- State "DONE" from "DONE" [2023-08-09 Wed 09:10]
|
||
: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
|
||
- State "DONE" from "DONE" [2023-08-09 Wed 09:10]
|
||
:LOGBOOK:
|
||
- 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
|
||
|
||
*** DONE 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 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
|
||
(setq org-refile-allow-creating-parent-nodes 'confirm)
|
||
#+end_src
|
||
|
||
*** DONE 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
|
||
(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
|
||
|
||
*** DONE [[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
|
||
(use-package org-cliplink
|
||
:bind
|
||
(("C-x p i" . org-cliplink))
|
||
)
|
||
#+end_src
|
||
|
||
*** DONE 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
|
||
(setq org-roam-file-exclude-regexp "^[.][.]?/") ; Include subdirectories
|
||
#+end_src
|
||
|
||
*** DONE [[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
|
||
(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
|
||
|
||
*** DONE Configure what display in org-roam-buffer
|
||
#+begin_src elisp
|
||
(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
|
||
|
||
*** DONE Deft
|
||
|
||
#+begin_src elisp
|
||
(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
|
||
(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
|
||
;;; 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
|
||
(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
|
||
(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
|
||
(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
|
||
(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
|
||
(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
|
||
(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
|
||
(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
|
||
(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 [19/26] Reading and Writing
|
||
:LOGBOOK:
|
||
- State "DONE" from "TODO" [2023-07-06 Thu 12:32]
|
||
:END:
|
||
*** DONE Expand some words with auto-correct
|
||
|
||
#+begin_src elisp
|
||
(setq save-abbrevs 'silently)
|
||
(setq-default abbrev-mode t)
|
||
#+end_src
|
||
|
||
*** DONE ediff
|
||
|
||
#+begin_src elisp
|
||
(setq ediff-window-setup-function 'ediff-setup-windows-plain)
|
||
(setq ediff-split-window-function 'split-window-horizontally)
|
||
#+end_src
|
||
|
||
*** DONE tramp
|
||
|
||
#+begin_src elisp
|
||
(setq tramp-default-method "ssh"
|
||
tramp-backup-directory-alist backup-directory-alist
|
||
tramp-ssh-controlmaster-options "ssh")
|
||
#+end_src
|
||
|
||
*** DONE Move correctly over camelCased words
|
||
|
||
#+begin_src elisp
|
||
(subword-mode)
|
||
#+end_src
|
||
|
||
*** DONE Understand the more common sentence
|
||
|
||
#+begin_src elisp
|
||
(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
|
||
(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
|
||
|
||
**** DONE Required for proportional font
|
||
:LOGBOOK:
|
||
- State "DONE" from "TODO" [2023-07-05 Wed 16:46]
|
||
:END:
|
||
#+begin_src elisp
|
||
(use-package company-posframe
|
||
:diminish company-posframe-mode
|
||
:config (company-posframe-mode)
|
||
)
|
||
#+end_src
|
||
|
||
*** DONE [[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
|
||
(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
|
||
(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
|
||
(remove-hook 'text-mode-hook #'turn-on-auto-fill)
|
||
(add-hook 'text-mode-hook 'turn-on-visual-line-mode)
|
||
#+end_src
|
||
|
||
*** DONE Transform <a href> links into org links
|
||
:LOGBOOK:
|
||
- State "DONE" from [2023-08-19 Sat 19:41]
|
||
:END:
|
||
|
||
#+begin_src elisp
|
||
(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
|
||
(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
|
||
|
||
*** DONE Enable dict mode
|
||
|
||
#+begin_src elisp
|
||
(setq dictionary-server "automatic")
|
||
#+end_src
|
||
|
||
*** DONE 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
|
||
(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, let’s define a minor mode for it to be activated.
|
||
|
||
#+begin_src elisp
|
||
(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, let’s add a hook so that it is on for all the text files Emacs opens.
|
||
#+begin_src elisp
|
||
(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
|
||
(defun my/diminish-dubcaps ()
|
||
(interactive)
|
||
(diminish 'my-dubcaps-mode ""))
|
||
(add-hook 'my-dubcaps-mode-hook 'my/diminish-dubcaps)
|
||
#+end_src
|
||
|
||
*** DONE Pick out passive voice and weasel words
|
||
:LOGBOOK:
|
||
- State "DONE" from "NEXT" [2023-08-09 Wed 13:52]
|
||
:END:
|
||
|
||
#+begin_src elisp
|
||
(use-package writegood-mode
|
||
:diminish writegood-mode
|
||
:config
|
||
(progn (add-hook 'text-mode-hook 'writegood-mode))
|
||
)
|
||
#+end_src
|
||
|
||
*** DONE [[https://github.com/yoshiki/yaml-mode][Yaml]]
|
||
:LOGBOOK:
|
||
- State "DONE" from "TODO" [2024-06-27 Thu 13:03]
|
||
:END:
|
||
|
||
#+begin_src elisp
|
||
(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
|
||
|
||
*** DONE Docker
|
||
:LOGBOOK:
|
||
- State "DONE" from "TODO" [2024-06-27 Thu 13:03]
|
||
:END:
|
||
#+begin_src elisp
|
||
(use-package docker-compose-mode)
|
||
#+end_src
|
||
|
||
*** DONE [[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
|
||
(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
|
||
(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
|
||
|
||
*** DONE [[https://www.flycheck.org/][Flycheck]]
|
||
:LOGBOOK:
|
||
- State "DONE" from "TODO" [2024-07-02 Tue 13:13]
|
||
:END:
|
||
|
||
Needs external checkers installed
|
||
|
||
#+begin_src elisp
|
||
(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
|
||
(use-package flycheck-checkbashisms
|
||
:config
|
||
(flycheck-checkbashisms-setup)
|
||
)
|
||
#+end_src
|
||
|
||
*** DONE [[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
|
||
(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
|
||
|
||
*** DONE 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
|
||
(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
|
||
|
||
*** DONE [[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
|
||
(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
|
||
|
||
*** DONE [[https://depp.brause.cc/nov.el/][View EPUBs]] :books:
|
||
:LOGBOOK:
|
||
- State "DONE" from "NEXT" [2023-08-09 Wed 13:19]
|
||
:END:
|
||
#+begin_src elisp
|
||
(use-package nov
|
||
:config
|
||
(add-to-list 'auto-mode-alist '("\\.epub\\'" . nov-mode))
|
||
)
|
||
#+end_src
|
||
|
||
*** DONE View PDF files
|
||
|
||
#+begin_src elisp
|
||
(setq doc-view-continuous t)
|
||
#+end_src
|
||
|
||
*** TODO [[https://github.com/tmalsburg/helm-bibtex][Zotero]]
|
||
#+begin_src elisp
|
||
(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-09 Tue 14:16]
|
||
:END:
|
||
*** DONE Password-store
|
||
:LOGBOOK:
|
||
- 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 [2/3] AI
|
||
*** DONE [[https://github.com/s-kostyaev/ellama][Ellama]]
|
||
:LOGBOOK:
|
||
- State "DONE" from "TODO" [2024-06-27 Thu 07:40]
|
||
:END:
|
||
#+begin_src elisp
|
||
;; 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
|
||
|
||
*** CNCL 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
|
||
|
||
** DONE [[https://github.com/beancount/beancount-mode/][Accounting]]
|
||
:LOGBOOK:
|
||
- State "DONE" from "TODO" [2024-06-27 Thu 07:43]
|
||
:END:
|
||
|
||
#+begin_src elisp
|
||
(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
|
||
|
||
** DONE Browser
|
||
:LOGBOOK:
|
||
- State "DONE" from "TODO" [2023-07-07 Fri 15:29]
|
||
:END:
|
||
#+begin_src elisp
|
||
(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
|
||
|
||
** DONE [[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
|
||
(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
|