This is my config file for emacs!
The gc-cons-threshold is set to a superlarge number for faster startup time. It is reset at reset gc-cons-threshold.
(setq gc-cons-threshold 402653184
gc-cons-percentage 0.6)
- State “SOME” from “NEXT” [2024-09-20 Fri 18:43]
I like to write my org-mode scientific papers such that each line has one sentence. This allows me to make more meaningful git commits per line. Often, these lines are quite long, however, and this makes emacs very slow. https://emacs.stackexchange.com/questions/598/how-do-i-prevent-extremely-long-lines-making-emacs-slow
(setq-default bidi-paragraph-direction 'left-to-right)
(setq-default bidi-inhibit-bpa t)
(global-so-long-mode 1)
;; (setq-default bidi-display-reordering nil) ;; officially unsupported
Use-package is an amazing resource to clean up my init file and have it play nice on both my desktop and laptop.
(eval-when-compile
(require 'use-package))
(setq use-package-always-ensure t)
(setq use-package-verbose t)
(use-package diminish) ; to abbreviate lines from the mode-line
(use-package delight) ; to omit lines from the mode-line
(use-package bind-key) ; for easy keybindings
define dirvars ‘org-in-file’, ‘org-gtd-file’, etc.
(defvar org-in-file "~/org/inbox.org"
"GTD Inbox")
(defvar org-gtd-file "~/org/todo.org"
"Personal TODO's")
(defvar org-tickler-file "~/org/tickler.org"
"Tickler")
(defvar org-clumped-file "~/org/clumpednotes.org"
"Work TODO's")
(defvar org-notes-file "~/org/notes.org"
"General Notes and Protocols")
(defvar org-someday-file "~/org/someday.org"
"Someday/Maybe")
(defvar org-journal-file "~/org/journal.org"
"Journal")
(defvar org-lists-file "~/org/lists.org"
"Lists of Movies etc.")
(defvar org-cal-file "~/org/calendars/gcal.org"
"Google Calendar")
(setq my/org-roam-files
(directory-files "~/SurfDrive/bibliography/notes/daily" t "org$"))
(setq inhibit-splash-screen t)
;; (setq initial-major-mode 'org-mode)
(setq large-file-warning-threshold 100000000) ;; change to ~100 MB
(scroll-bar-mode -1) ; turn off the scroll bar
(tool-bar-mode -1) ; turn off the tool bar
(menu-bar-mode -1) ; turn off the menu
(setq visible-bell 1) ; turn off beeps, make them flash!
(global-hl-line-mode t)
;; typing
(setq-default fill-column 79)
(setq sentence-end-double-space nil)
;; typed text will replace highlighted region
(delete-selection-mode 1)
;; backspace deletes one character instead of one column
(global-set-key (kbd "DEL") 'backward-delete-char)
;; remove trailing whitespace before save
(add-hook 'before-save-hook 'delete-trailing-whitespace)
;; prefer utf-8
(prefer-coding-system 'utf-8-unix)
(blink-cursor-mode 0)
;; (setq mouse-wheel-progressive-speed nil)
;; automatically re-open files that have been changed on disk
(global-auto-revert-mode 1)
(setq global-auto-revert-non-file-buffers t)
(defalias 'yes-or-no-p 'y-or-n-p)
(setq use-dialog-box nil) ; do not use graphical ui dialog boxes but use echo area (esp. for org-pomodoro)
;; always follow symlinks w/o asking
(require 'vc-hooks)
(setq vc-follow-symlinks t)
(setq auto-save-default t ;; let's try autosave for a while
backup-inhibited t
confirm-nonexistent-file-or-buffer nil
create-lockfiles nil)
(defun my-save-if-bufferfilename ()
(if (buffer-file-name)
(progn (save-buffer))
(message "no file is associated to this buffer: do nothing")))
;; this may be a bit too slow, especially with my whitespace remove hook.
;(add-hook 'evil-insert-state-exit-hook 'my-save-if-bufferfilename)
(recentf-mode 1)
;; Save what you enter into minibuffer prompts
(setq history-length 25)
(savehist-mode 1)
;; Remember and restore the last cursor location of opened files
(save-place-mode 1)
(electric-pair-mode 1) ; auto-insert matching bracket
(show-paren-mode 1) ; turn on paren match highlighting
(setq-default line-spacing 0)
(setq x-underline-at-descent-line t)
matching parenthesis are highlighted with rainbow colours.
(use-package rainbow-delimiters
:hook ((prog-mode LaTeX-mode) . rainbow-delimiters-mode))
(use-package modus-themes
:init
(setq modus-themes-bold-constructs t
modus-themes-italic-constructs t
modus-themes-mixed-fonts t
modus-themes-subtle-line-numbers t
modus-themes-tabs-accented t
modus-themes-variable-pitch-ui t
modus-themes-inhibit-reload t
modus-themes-fringes '(subtle)
modus-themes-lang-checkers nil
modus-themes-mode-line '(4)
modus-themes-markup '(background italic)
modus-themes-syntax '(faint)
modus-themes-intense-hl-line '(accented)
modus-themes-paren-match '(bold intense)
modus-themes-links '(neutral-underline background)
modus-themes-prompts '(intense bold)
modus-themes-completions '(opinionated)
modus-themes-mail-citations nil
modus-themes-region '(bg-only no-extend)
modus-themes-diffs '(desaturated)
modus-themes-org-blocks 'tinted-background
modus-themes-org-agenda
'((header-block . (variable-pitch 1.3))
(header-date . (grayscale workaholic bold-today 1.1))
(event . (accented varied))
(scheduled . rainbow)
(habit . traffic-light))
modus-themes-headings
'((1 . (variable-pitch 1.3))
(2 . (variable-pitch 1.1))
(3 . (variable-pitch semibold)))))
(use-package circadian
:custom
;; current location on earth for auto toggle between light and dark theme
(calendar-latitude 52.08) ;; Utrecht
(calendar-longitude 5.11)
;; (calendar-latitude 21.25) ;; Honolulu
;; (calendar-longitude -157.8)
;; (calendar-latitude 40.5) ;; New York
;; (calendar-longitude -74.5)
(circadian-themes '((:sunrise . modus-operandi)
(:sunset . modus-vivendi)))
:config
(circadian-setup))
;; (set-face-attribute 'default nil :family "Noto Mono" :height 130)
(set-face-attribute 'default nil :family "Noto Sans Mono" :height 150)
(set-face-attribute 'variable-pitch nil :family "Noto Serif" :height 1.0)
;;Tex Gyre Pagella
(set-face-attribute 'fixed-pitch nil :family "Noto Sans Mono" :height 1.0)
Highlight hex colours!
(use-package rainbow-mode
:defer t
:hook (html-mode r-mode))
Show plain-text emoji like :)
as images, but also unicode ☺
and :slight-smile:
. :D
https://github.com/iqbalansari/emacs-emojify
(use-package emojify
:hook (mu4e-mode . emojify-mode))
Highlight the current line when changing focus. It’s like beacon-mode but native! from https://karthinks.com/software/batteries-included-with-emacs/
(defun pulse-line (&rest _)
"Pulse the current line."
(pulse-momentary-highlight-one-line (point)))
(dolist (command '(scroll-up-command scroll-down-command
recenter-top-bottom other-window))
(advice-add command :after #'pulse-line))
This allows me to write nicely on a widescreen monitor in a single buffer.
(use-package visual-fill-column
:hook (org-mode . visual-fill-column-mode)
:custom
(global-visual-line-mode t)
;; (global-visual-fill-column-mode t)
;; (visual-fill-column-width 115) ;; instead prefer fill-column-width
(split-window-preferred-function 'visual-fill-column-split-window-sensibly)
(visual-fill-column-center-text t))
(defface org-todo-next
'((((class color) (min-colors 16) (background light))
(:family "Noto Sans Mono" :foreground "light goldenrod yellow"
:bold t :background "red"))
(((class color) (min-colors 16) (background dark))
(:family "Noto Sans Mono" :foreground "light goldenrod yellow"
:bold t :background "red"))
(((class color) (min-colors 8) (background light))
(:family "Noto Sans Mono" :foreground "light goldenrod yellow"
:bold t :background "red"))
(((class color) (min-colors 8) (background dark))
(:family "Noto Sans Mono" :foreground "light goldenrod yellow"
:bold t :background "red"))
(t (:inverse-video t :bold t)))
"Face for NEXT TODO keyword"
:group 'org-faces)
(defface org-todo-waiting
'((((class color) (min-colors 16) (background light))
(:family "Noto Sans Mono" :foreground "dim gray" :bold t
:background "yellow"))
(((class color) (min-colors 16) (background dark))
(:family "Noto Sans Mono" :foreground "dim gray" :bold t
:background "yellow"))
(((class color) (min-colors 8) (background light))
(:family "Noto Sans Mono" :foreground "dim gray" :bold t
:background "yellow"))
(((class color) (min-colors 8) (background dark))
(:family "Noto Sans Mono" :foreground "dim gray" :bold t
:background "yellow"))
(t (:inverse-video t :bold t)))
"Face for WAIT TODO keyword"
:group 'org-faces)
(defface org-todo-tick
'((((class color) (min-colors 16) (background light))
(:family "Noto Sans Mono" :bold t :background "light slate blue"))
(((class color) (min-colors 16) (background dark))
(:family "Noto Sans Mono" :bold t :background "light slate blue"))
(((class color) (min-colors 8) (background light))
(:family "Noto Sans Mono" :bold t :background "light slate blue"))
(((class color) (min-colors 8) (background dark))
(:family "Noto Sans Mono" :bold t :background "light slate blue"))
(t (:inverse-video t :bold t)))
"Face for TICK TODO keyword"
:group 'org-faces)
(defface org-todo-someday
'((((class color) (min-colors 16) (background light))
(:family "Noto Sans Mono" :foreground "ghost white" :bold t
:background "deep sky blue"))
(((class color) (min-colors 16) (background dark))
(:family "Noto Sans Mono" :foreground "ghost white" :bold t
:background "deep sky blue"))
(((class color) (min-colors 8) (background light))
(:family "Noto Sans Mono" :foreground "ghost white" :bold t
:background "deep sky blue"))
(((class color) (min-colors 8) (background dark))
(:family "Noto Sans Mono" :foreground "ghost white" :bold t
:background "deep sky blue"))
(t (:inverse-video t :bold t)))
"Face for SOME TODO keyword"
:group 'org-faces)
(defface org-done-done
'((((class color) (min-colors 16) (background light))
(:family "Noto Sans Mono" :foreground "green4" :bold t
:background "pale green"))
(((class color) (min-colors 16) (background dark))
(:family "Noto Sans Mono" :foreground "green4" :bold t
:background "pale green"))
(((class color) (min-colors 8))
(:family "Noto Sans Mono" :foreground "green"
:background "pale green"))
(t (:bold t)))
"Face used for todo keywords that indicate DONE items."
:group 'org-faces)
(defface org-done-cancelled
'((((class color) (min-colors 16) (background light))
(:family "Noto Sans Mono" :foreground "dim gray" :bold t
:background "gray"))
(((class color) (min-colors 16) (background dark))
(:family "Noto Sans Mono" :foreground "dim gray" :bold t
:background "gray"))
(((class color) (min-colors 8))
(:family "Noto Sans Mono" :foreground "dim gray"
:background "gray"))
(t (:bold t)))
"Face used for todo keywords that indicate CANC items."
:group 'org-faces)
Highlight diffs of current version-controlled buffer in the margin. Quite cool!
(use-package diff-hl
:init
(global-diff-hl-mode)
(setq diff-hl-gutter-mode t)
(diff-hl-flydiff-mode +1)
:hook (magit-post-refresh . diff-hl-magit-post-refresh))
git porcelain, essential!
(use-package magit
:commands magit-status
:config
(customize-set-variable 'magit-diff-refine-hunk t)
;; :after with-editor
)
https://github.com/alphapapa/org-make-toc
(use-package org-make-toc
:defer t)
beautiful help functions https://github.com/Wilfred/helpful
(use-package helpful
:commands (helpful-callable helpful-function helpful-variable helpful-mode))
Insert demos after describe function https://github.com/xuchunyang/elisp-demos
(use-package elisp-demos
:after helpful
:config
(advice-add 'helpful-update :after #'elisp-demos-advice-helpful-update))
(use-package which-key
:config (which-key-mode))
(global-set-key (kbd "<f5>") 'revert-buffer)
(defun fetch-calendar ()
(when (internet-up-p) (org-gcal-fetch)))
(defun my-org-agenda-recent-open-loops ()
(interactive)
(let ((org-agenda-start-with-log-mode t)
(org-agenda-use-time-grid nil))
(fetch-calendar)
(org-agenda-list nil (org-read-date nil nil "-2d") 4)
(beginend-org-agenda-mode-goto-beginning)))
from JKitchin’s blog
(defun get-labels ()
(interactive)
(save-excursion
(goto-char (point-min))
(let ((matches '()))
(while (re-search-forward "label:\\([a-zA-z0-9:-]*\\)" (point-max) t)
(add-to-list 'matches (match-string-no-properties 1) t))
matches)))
this allows the yasnippet template to autocomplete ref: with all the labels in the buffer.
If we call make-capture-frame from anywhere, it creates a new frame named capture which I can decorate using my window manager, and which disappears after the capturing is complete.
Sources:
- an old mailing list answer
- this blog: https://www.diegoberrocal.com/blog/2015/08/19/org-protocol/
- this more recent blog: https://fuco1.github.io/2017-09-02-Maximize-the-org-capture-buffer.html
- this very nice implementation: Emacs as an Org capture server
(defun make-capture-frame ()
"Create a new frame and org-capture."
(interactive)
;; (require 'cl-lib)
(make-frame '((name . "capture")))
(select-frame-by-name "capture")
(delete-other-windows)
(cl-letf (((symbol-function 'switch-to-buffer-other-window) #'switch-to-buffer))
(condition-case err
(org-capture nil "x")
(user-error (when (string= (cadr err) "Abort")
(delete-frame))))))
(defadvice org-capture-finalize
(after delete-capture-frame activate)
"Advice capture-finalize to close the frame"
(if (equal "capture" (frame-parameter nil 'name))
(delete-frame)))
https://emacs.stackexchange.com/questions/44664/apply-ansi-color-escape-sequences-for-org-babel-results This will apply the ANSI colour escape codes to source block outputs.
However, it will not store the results so it won’t show on export or the next time you open the file. The text will be plain, colourless, instead.
I still prefer this option because I have colours during my session/in the ESS process.
(defun my/babel-ansi ()
(when-let ((beg (org-babel-where-is-src-block-result nil nil)))
(save-excursion
(goto-char beg)
(when (looking-at org-babel-result-regexp)
(let ((end (org-babel-result-end))
(ansi-color-context-region nil))
(ansi-color-apply-on-region beg end))))))
(add-hook 'org-babel-after-execute-hook #'my/babel-ansi)
(defun internet-up-p (&optional host)
(= 0 (call-process "ping" nil nil nil "-c" "1" "-W" "1"
(if host host "www.google.com"))))
(setq browse-url-generic-program (executable-find "firefox")
browse-url-browser-function 'browse-url-generic)
from https://chainsawriot.com/postmannheim/2022/12/16/aoe16.html
(use-package atomic-chrome
:config
(atomic-chrome-start-server)
(setq atomic-chrome-buffer-open-style 'full)
(setq atomic-chrome-url-major-mode-alist
'(("github\\.com" . poly-markdown+r-mode)
("overleaf\\.com" . latex-mode))))
Evil allows me to use vi(m) keybindings in emacs.
vim emulator
(use-package evil
:init
(setq evil-want-integration t)
(setq evil-want-keybinding nil) ; this is needed for evil-collection
;; (setq evil-want-C-i-jump t) ; jump forward instead of tab insert
(setq evil-want-Y-yank-to-eol t)
(setq evil-v$-excludes-newline t) ; make v$ consistent with $ as motion
(setq evil-want-fine-undo t) ;; make smaller undo steps within insert mode
(customize-set-variable 'evil-respect-visual-line-mode nil)
;; TODO: decide if I want to use undo-tree?
(customize-set-variable 'evil-undo-system nil)
;; (setq evil-cross-lines t)
;; (setq evil-want-C-u-scroll t) ; C-u scrolls up half page
:config
(evil-mode 1))
(use-package evil-collection
:after evil vterm
:config
;; (add-hook 'evil-insert-state-entry-hook #'vterm-reset-cursor-point nil t)
(evil-collection-init))
https://github.com/Somelauw/evil-org-mode evil keymap for org-mode
(use-package evil-org
:demand ; do not defer
:after (:any org evil)
:init
(fset 'evil-redirect-digit-argument 'ignore)
:delight evil-org-mode
:hook (((org-mode org-agenda-mode). evil-org-mode)
(evil-org-mode . (lambda ()
(evil-org-set-key-theme
'(textobjects
insert
navigation
;; calendar ; M-h M-l next/previous day etc.
additional
shift
todo ;; heading
))))
;; I want to immediately type when I capture or log
(org-log-buffer-setup . evil-insert-state)
(org-capture-mode . evil-insert-state)
(yas-before-expand-snippet . evil-insert-state))
:config
(require 'evil-org-agenda)
(evil-org-agenda-set-keys)
;; TODO: rewrite to :bind syntax?
(evil-define-key 'motion 'org-agenda-mode-map (kbd "[") 'org-agenda-earlier)
(evil-define-key 'motion 'org-agenda-mode-map (kbd "]") 'org-agenda-later))
https://github.com/linktohack/evil-commentary comment/uncomment with gc over on systemcrafters they use evil-nerd-commentary, which has different keybindings by default main one: M-; or <leader>lc
this uses gc <word>
(use-package evil-commentary
:config
(evil-commentary-mode))
- Note taken on [2024-10-20 Sun 20:18]
no longer works, changed evil-magit to magit so my config can live on?
(use-package magit
; :after (magit evil)
:hook
(git-commit-mode . evil-insert-state)
(magit-mode . turn-off-evil-snipe-override-mode)
:config
(evil-set-initial-state 'magit-log-edit-mode 'insert))
No idea why but suddently I’ve been getting issues about the function define-short-documentation-group
not existing. This may fix it?
(require 'shortdoc)
org-in-file and org-gtd-file are defined in emacsdirs.el (private file).
;; TODO: figure out how to do this in a less stupid way
(defun open-gtd-file ()
"Open the GTD file."
(interactive)
(find-file org-gtd-file))
(defun open-inbox-file ()
"Open the inbox file."
(interactive)
(find-file org-in-file))
(defun open-clumped-file ()
"Open the clumped file."
(interactive)
(find-file org-clumped-file))
(use-package org
:demand ; do not defer
:ensure nil ; use the org-mode version included in Emacs
;; I had this setup before, but the org archive has been deprecated since version 9.6:
;; IMPORTANT: please install Org from GNU ELPA as Org ELPA will close
;; :ensure org-plus-contrib ; this is version 9.4.6
;; :delight org-indent-mode
:bind
(("C-c l" . org-store-link)
("C-c a" . org-agenda)
("C-c c" . org-capture)
("C-c g" . open-gtd-file)
("C-c i" . open-inbox-file)
("C-c t" . open-clumped-file)
("C-c !" . org-time-stamp-inactive))
:hook (
(org-mode . variable-pitch-mode)
;; update last-modified upon save
(before-save . zp/org-set-last-modified)
;; set created property on captures
(org-capture-prepare-finalize . zp/org-capture-set-created-property)
;; disable highlighting of matches in sparse trees so that customized TODO faces remain displayed :)
(org-occur . (lambda () (org-remove-occur-highlights nil nil nil)))
;; make sure the tags in the org-agenda aren't line-wrapped
(org-agenda-mode . (lambda ()
(visual-line-mode -1)
(toggle-truncate-lines 1)))
(org-babel-after-execute . org-redisplay-inline-images)
(org-babel-after-execute . my/babel-ansi)
)
:custom
(org-ctrl-k-protect-subtree t)
(org-return-follows-link t)
;; (setf org-special-ctrl-a/e t) ; I use evil's 0 and $ anyway
;; folded drawers no longer ruin new entries
(org-list-allow-alphabetical t) ; allow a. b. c. lists
(org-M-RET-may-split-line '((default . nil)))
;; (org-display-remote-inline-images 'cache)
;; (org-startup-with-inline-images t)
basic latex settings
;; (org-highlight-latex-and-related '(native script entities)) this gives me errors now <2023-07-18 Tue>
;; (org-latex-src-block-backend 'engraved)
;; (org-preview-latex-default-process 'dvipng)
;; (setq org-latex-default-figure-position 'htbp)
(org-latex-pdf-process
(list "latexmk -pdflatex='lualatex -shell-escape -interaction nonstopmode' -pdf -f %f"))
(org-latex-prefer-user-labels t)
(org-export-with-sub-superscripts '{})
(org-use-sub-superscripts '{})
(org-check-running-clock t)
(org-log-note-clock-out t)
(org-log-done 'time)
(org-log-into-drawer t)
;; (org-clock-auto-clockout-timer (* 10 60))
(org-tags-column -65)
(org-startup-indented t)
(org-startup-folded 'content)
(org-agenda-block-separator "")
(org-fontify-emphasized-text t)
;; org-fontify-todo-headline t ;; might be nice, but needs customisation of org-headline-todo face
(org-fontify-whole-heading-line t)
(org-fontify-quote-and-verse-blocks t)
(org-pretty-entities t)
(org-ellipsis "…") ;▼ … ◦
(org-hide-emphasis-markers t)
(org-file-apps
'((auto-mode . emacs)
("\\.x?html?\\'" . "xdg-open %s")
("\\.pdf\\'" . (lambda (file link)
(org-pdftools-open link)))
("\\.mp4\\'" . "xdg-open %s")
("\\.webm\\'" . "xdg-open %s")
("\\.mkv\\'" . "xdg-open %s")
("\\.pdf.xoj\\'" . "xournal %s")))
;; (setq org-agenda-files (list "<file1.org> etc."))
(calendar-week-start-day 1) ; 0:Sunday, 1:Monday
(org-deadline-warning-days 14)
(org-agenda-span 'day)
;; exclude scheduled items from all todo's in list
(org-agenda-todo-ignore-scheduled t)
;; (setq org-agenda-todo-ignore-deadlines t)
;; (setq org-agenda-todo-ignore-timestamp t)
;; (setq org-agenda-todo-ignore-with-date t)
;;(setq org-agenda-prefix-format " %-17:c%?-12t% s") ; TODO: see if I like the default
(org-agenda-include-all-todo nil)
all the org-files in my org-directory
;(setq org-directory "~/org/") ;; changed org-roam capture
(org-agenda-files (append
(directory-files-recursively "~/org" "\\.org$")
my/org-roam-files))
swyper makes refiling amazing!
(org-refile-targets (quote ((nil :maxlevel . 9) ;; current file
(org-gtd-file :maxlevel . 6)
(org-tickler-file :maxlevel . 2)
(org-notes-file :maxlevel . 2)
(org-lists-file :maxlevel . 2)
(org-someday-file :maxlevel . 2)
(org-clumped-file :maxlevel . 6)
;; (my/org-roam-files :maxlevel . 1) ;; comment out since org-roam-refile
)))
(org-outline-path-complete-in-steps nil) ;; Refile in a single go
(org-refile-use-outline-path 'file) ;; Show full paths for refiling
(org-refile-allow-creating-parent-nodes 'confirm)
Filter tasks by context (sorted by todo state)
(org-agenda-sorting-strategy
'((agenda habit-down time-up priority-down todo-state-up category-keep)
(todo todo-state-up priority-down category-keep)
(tags priority-down todo-state-up category-keep)
(search category-keep)))
(org-agenda-custom-commands
'(("i" "Inbox" tags "inbox")
("I" "Important"
((tags "PRIORITY=\"A\"/prj"
((org-agenda-overriding-header "High-priority projects:")))
(tags "PRIORITY=\"A\"/!-prj"
((org-agenda-skip-function '(org-agenda-skip-entry-if 'todo 'done))
(org-agenda-overriding-header "High-priority unfinished tasks:")))))
;; ("A" agenda*)
;; https://protesilaos.com/codelog/2021-12-09-emacs-org-block-agenda/
("A" "new block agenda"
((tags-todo "*"
((org-agenda-skip-function '(org-agenda-skip-if nil '(timestamp)))
(org-agenda-skip-function
`(org-agenda-skip-entry-if
'notregexp ,(format "\\[#%s\\]" (char-to-string org-priority-highest))))
(org-agenda-block-separator nil)
(org-agenda-overriding-header "Important tasks without a date")))
(todo "WAIT"
((org-agenda-overriding-header "\nTasks on hold")))
(agenda ""
((org-agenda-block-separator nil)
(org-agenda-span 1)
(org-deadline-warning-days 0)
(org-scheduled-past-days 0)
(org-deadline-past-days 0)
(org-agenda-day-face-function (lambda (date) 'org-agenda-date))
(org-agenda-format-date "%A %-e %B %Y")
(org-agenda-overriding-header "\nToday's agenda")))
(agenda ""
((org-agenda-start-on-weekday nil)
(org-agenda-start-day "+1d")
(org-agenda-span 7)
(org-deadline-warning-days 0)
(org-agenda-block-separator nil)
(org-agenda-skip-function '(org-agenda-skip-entry-if 'todo 'done))
(org-agenda-overriding-header "\nNext seven days")))
(agenda ""
((org-agenda-time-grid nil)
(org-agenda-start-on-weekday nil)
(org-agenda-start-day "+7d")
(org-agenda-span 14)
(org-agenda-show-all-dates nil)
(org-deadline-warning-days 0)
(org-agenda-block-separator nil)
(org-agenda-entry-types '(:deadline))
(org-agenda-skip-function '(org-agenda-skip-entry-if 'todo 'done))
(org-agenda-overriding-header "\nUpcoming deadlines (+14d)")))
(agenda ""
((org-agenda-overriding-header "\nOverdue")
(org-agenda-time-grid nil)
(org-agenda-block-separator nil)
(org-agenda-start-on-weekday nil)
(org-agenda-show-all-dates nil)
(org-agenda-format-date "") ;; Skip the date
(org-agenda-span 1)
(org-agenda-skip-function '(org-agenda-skip-entry-if 'todo 'done))
(org-agenda-entry-types '(:deadline :scheduled))
(org-scheduled-past-days 999)
(org-deadline-past-days 999)
(org-deadline-warning-days 0)))))
("n" "Next Actions" todo "NEXT")
("w" "Waiting" todo "WAIT")
;; ("s" "Someday/Maybe" todo "SOME")
("j" "Projects" tags "prj/-SOME-DONE-CANC")
("W" "Work" tags-todo "-Personal/!-WAIT"
((org-agenda-todo-ignore-scheduled t)))
("P" "Personal" tags-todo "-Work/!-WAIT"
((org-agenda-todo-ignore-scheduled t)))
("g" . "GTD contexts")
("gh" "Home" tags-todo "@home")
("gk" "Klusjes/Craft" tags-todo "@klusje")
("go" "Office" tags-todo "@office")
("ge" "Errands" tags-todo "@errands")
("gl" "Laboratory" tags-todo "@lab")
;; ("gt" "Travel" tags-todo "@travel")
("gt" "Teams" tags-todo "@teams")
("gc" "Computer" tags-todo "@computer")
("gB" "Phone" tags-todo "@phone")
("gm" "e-mail" tags-todo "@email")
("gb" "Bank" tags-todo "@bank")
("gw" "Write" tags-todo "@write")
("gp" "Program" tags-todo "@program")
("gC" "Create/Plot" tags-todo "@createplot")
("gr" "Read" tags-todo "@read")
("gg" "Research" tags-todo "@research")
("gs" "Schedule" tags-todo "@schedule")
("ga" "Agenda" tags-todo "@agenda")
("E" . "Energy")
("Ef" "Focus" tags-todo "@focus")
("Ed" "Braindead" tags-todo "@braindead")
("D" "DataSteward" tags-todo "DataSteward")
("p" . "People")
("pm" "Martin" tags-todo "Martin")
("pr" "Richard" tags-todo "Richard")
("pl" "Line" tags-todo "Line")
("pa" "Anne" tags-todo "Anne")
("pf" "FEST" tags-todo "FEST")
("pi" "Inigo" tags-todo "Inigo")))
(org-tags-exclude-from-inheritance '("prj")
org-stuck-projects '("+prj/-CANC-SOME-DONE"
("NEXT" "WAIT" "TICK") ())) ;; "SOME"
(org-hierarchical-todo-statistics nil) ;; look for not-done tasks recursively
;; (org-provide-todo-statistics '(("NEXT", "TICK") ("CANC", "SOME", "DONE", "WAIT")))
customize capture templates
(org-capture-templates
'(;("a" "Appointment" entry (file org-in-file)
; "* %?\n %^T\n")
("t" "Todo" entry (file org-in-file)
"* %?\n%a" :add-created t)
("x" "simple" entry (file org-in-file)
"* %?" :add-created t)
("T" "Todo-nolink-tag" entry (file org-in-file)
"* %? %^G\n" :add-created t)
("m" "Email" entry (file org-in-file)
"* %? from %:from on %:subject :@email:\n %i\n %a\n" :add-created t)
("w" "Website" entry (file org-in-file)
"* %?\nEntered on %U\n %i\n %a")
("r" "Weekly Review" entry (file "~/org/log.org")
(file "~/org/weekly_review.org") :clock-in t :clock-keep t :jump-to-captured t)
("p" "Protocol" entry (file org-in-file)
"* %:description%? :@web:\n[[%:link][%:description]]\n#+begin_quote\n%:initial\n#+end_quote\n" :add-created t)
("L" "Protocol Link" entry (file org-in-file)
"* %:description%? :@web:\n[[%:link][%:description]]" :add-created t)
("j" "Journal" entry (file+olp+datetree org-journal-file)
"* %?\nEntered on %U\n %i\n %a")))
(org-todo-keywords
'((sequence "NEXT(n)" "WAIT(w!/!)" "TICK(t)" "SOME(s!/!)" "|"
"DONE(d)" "CANC(c)")))
(org-todo-keyword-faces
'(("NEXT" . org-todo-next)
("WAIT" . org-todo-waiting)
("TICK" . org-todo-tick)
("SOME" . org-todo-someday)
("DONE" . org-done-done)
("CANC" . org-done-cancelled)))
(org-modern-todo-faces
'(("NEXT" . org-todo-next)
("WAIT" . org-todo-waiting)
("TICK" . org-todo-tick)
("SOME" . org-todo-someday)
("DONE" . org-done-done)
("CANC" . org-done-cancelled)))
(org-fast-tag-selection-single-key t)
(org-tag-alist '(("prj" . ?j)
(:startgroup . nil)
("@home" . ?h)
("@office" . ?o)
("@errands" . ?e)
("@lab" . ?l)
(:endgroup . nil)
("@computer" . ?c) ;; general in case I can't decide
("@klusje" . ?k) ;; crafts, things that require my toolbox
("@phone" . ?B) ;; b for Dutch "bellen"
("@email" . ?m)
("@teams" . ?t)
("@bank" . ?b) ;; I need my little reader thingie
("@write" . ?w)
("@program" . ?p)
("@createplot" . ?C)
("@read" . ?r)
("@research" . ?g)
("@schedule" . ?s)
("@agenda" . ?a) ;; things to discuss
;; ("@admin" . ??) ;; do I want admin? which key should it use?
(:startgroup . nil)
("@focus" . ?f)
("@braindead" . ?d)
(:endgroup . nil)
(:startgroup . nil)
("Work" . ?W) ("Personal" . ?P)
(:endgroup . nil)
;; ("DataSteward" . ?D)
;; tags to accompany the @agenda context
("Family" . ?F)
("Martin" . ?M)
("Richard" . ?R)
("Line" . ?L)
("Inigo" . ?I)
("Niels" . ?N)))
(org-src-fontify-natively t)
(org-src-tab-acts-natively t)
(org-src-window-setup 'current-window)
:config
(add-to-list 'org-global-properties
'("Effort_ALL". "0:05 0:15 0:30 1:00 2:00 3:00 4:00"))
(add-to-list 'org-modules 'org-habit t)
(org-babel-do-load-languages
'org-babel-load-languages
'((emacs-lisp . t)
(dot . t)
(python . t)
(latex . t)
(shell . t)
;; (stan . t)
(latex . t)
(R . t)
(julia . t)
;; (julia-vterm . t)
))
(require 'ob-org)
org-export ignore headlines with :ignore:
tag
(use-package org-contrib
:config
(require 'ox-extra)
(ox-extras-activate '(ignore-headlines)))
(require 'ox-latex)
- Note taken on [2023-06-05 Mon 14:55]
I’ve re-enabled this and added biblatex default options
(customize-set-variable 'org-latex-packages-alist
'(("version=4" "mhchem" t)
("" "siunitx" t)
("giveninits=true,uniquename=false,uniquelist=false,citestyle=authoryear-comp,bibstyle=authoryear-comp,date=year,hyperref=true,mincitenames=1,maxcitenames=2,backend=biber,backref,doi=true,url=false,isbn=false" "biblatex" t)
("" "amsmath" t)
("" "hyperref" t)
;; cleveref must be loaded after hyperref and amsmath
("capitalise,nameinlink,noabbrev" "cleveref" t)))
;; append colorlinks, allcolors, hidelinks here
;; (customize-set-value 'org-latex-hyperref-template "
;; \\hypersetup{\n pdfauthor={%a},\n pdftitle={%t},\n pdfkeywords={%k},
;; pdfsubject={%d},\n pdfcreator={%c},\n pdflang={%L},\n colorlinks=true}\n") % colorlinks=true,
;; % allcolors=blue,%
;; (customize-set-variable 'org-cite-global-bibliography '("/home/japhir/SurfDrive/bibliography/references.bib"))
(setq org-cite-csl-styles-dir "~/Zotero/styles")
;; (setq org-cite-csl--fallback-style-file "/home/japhir/Zotero/styles/paleoceanography.csl") ; doesn't have a bibliography style!
(setq org-cite-csl--fallback-style-file "/home/japhir/Zotero/styles/apa.csl")
;; (setq org-cite-csl--fallback-style-file "/home/japhir/Zotero/styles/nature.csl")
;; use biblatex for latex and csl for html.
(setq org-cite-export-processors '((latex biblatex)
(t csl)))
;; (setq org-cite-biblatex-options bibstyle=authoryear-comp)
(add-to-list 'load-path "/usr/bin/vendor_perl/")
(add-to-list 'org-latex-classes
'("ijkarticle"
"\\documentclass{article}"
("\\section{%s}" . "\\section*{%s}")
("\\subsection{%s}" . "\\subsection*{%s}")
("\\subsubsection{%s}" . "\\subsubsection*{%s}")
("\\paragraph{%s}" . "\\paragraph*{%s}")
("\\subparagraph{%s}" . "\\subparagraph*{%s}")))
Nice answer on how to have point on a blank line in code block
(add-to-list 'org-structure-template-alist
'("se" . "src emacs-lisp
"))
;; TODO figure out how to add multiple items to the list
(add-to-list 'org-structure-template-alist
'("sr" . "src R
"))
(add-to-list 'org-structure-template-alist
'("sc" . "src c
"))
(add-to-list 'org-structure-template-alist
'("sp" . "src python
"))
(add-to-list 'org-structure-template-alist
'("sj" . "src julia
"))
(add-to-list 'org-structure-template-alist
'("ss" . "src sh
"))
https://gist.github.com/jethrokuan/d6f80caaec7f49dedffac7c4fe41d132
(defun org-html--reference (datum info &optional named-only)
"Return an appropriate reference for DATUM.
DATUM is an element or a `target' type object. INFO is the
current export state, as a plist.
When NAMED-ONLY is non-nil and DATUM has no NAME keyword, return
nil. This doesn't apply to headlines, inline tasks, radio
targets and targets."
(let* ((type (org-element-type datum))
(user-label
(org-element-property
(pcase type
((or `headline `inlinetask) :CUSTOM_ID)
((or `radio-target `target) :value)
(_ :name))
datum))
(user-label (or user-label
(when-let ((path (org-element-property :ID datum)))
(concat "ID-" path)))))
(cond
((and user-label
(or (plist-get info :html-prefer-user-labels)
;; Used CUSTOM_ID property unconditionally.
(memq type '(headline inlinetask))))
user-label)
((and named-only
(not (memq type '(headline inlinetask radio-target target)))
(not user-label))
nil)
(t
(org-export-get-reference datum info)))))
(require 'org-protocol)
)
(customize-set-variable 'org-num-skip-unnumbered t)
(customize-set-variable 'org-num-skip-commented t)
(customize-set-variable 'org-num-skip-tags '("ignore" "nolatex" "noexport"))
(use-package org-modern
:after org
:config (global-org-modern-mode 1))
allow asyncronous code block evaluation https://github.com/astahlman/ob-async
(use-package ob-async
:after org)
got the function from this github issue
(use-package org-pomodoro
:after org
:bind ("C-c p" . org-pomodoro)
:hook (org-pomodoro-break-finished . org-pomodoro-prompt)
:custom
(org-pomodoro-manual-break t)
(org-pomodoro-long-break-length 15)
:config
(defun org-pomodoro-prompt ()
(interactive)
(org-clock-goto)
(if (y-or-n-p "Start a new pomodoro?")
(progn
(org-pomodoro))))
)
used to be org-pdfview
(use-package org-pdftools
:after (org pdf-tools)
:hook (org-mode . org-pdftools-setup-link))
dive into links/formatted entries https://github.com/awth13/org-appear
(use-package org-appear
;; :straight (org-appear :type git :host github :repo "awth13/org-appear")
:hook (org-mode . org-appear-mode)
:custom
(org-appear-autoentities t)
(org-appear-autolinks t)
(org-appear-autosubmarkers t)
(org-appear-delay 1))
(use-package org-tree-slide
:after org
:bind (:map org-mode-map ("<f9>" . org-tree-slide-mode)))
By default C-x 8 o = ° and C-x 8 m = µ. So:
(global-set-key (kbd "C-x 8 a") (lambda () (interactive) (insert "α")))
(global-set-key (kbd "C-x 8 b") (lambda () (interactive) (insert "β")))
(global-set-key (kbd "C-x 8 d") (lambda () (interactive) (insert "δ")))
(global-set-key (kbd "C-x 8 D") (lambda () (interactive) (insert "Δ")))
I also use compose-key, mapped to right alt with some custom settings for <ralt> g d, resulting in δ, for example.
https://github.com/domtronn/all-the-icons.el
(use-package all-the-icons)
(setq inhibit-compacting-font-caches t)
(use-package all-the-icons-dired
:after (dired all-the-icons)
:hook (dired-mode . all-the-icons-dired-mode))
usefull snippets for me: org-mode (fig_, )
(use-package yasnippet
:init
(yas-global-mode 1)
:delight yas-mode
:config
(require 'warnings)
(add-to-list 'warning-suppress-types '(yasnippet backquote-change))
(setq yas-indent-line t))
(use-package ispell
:config
(setq ispell-dictionary "british-ize-w_accents"))
(use-package flyspell
:hook (;(org-mode . flyspell-mode)
(prog-mode . flyspell-prog-mode))
:config
(add-to-list 'ispell-skip-region-alist '(":\\(PROPERTIES\\|LOGBOOK\\):" . ":END:"))
(add-to-list 'ispell-skip-region-alist '("#\\+begin_abstract" . "#\\+end_abstract"))
(add-to-list 'ispell-skip-region-alist '("#\\+BEGIN_SRC" . "#\\+END_SRC"))
(add-to-list 'ispell-skip-region-alist '("#\\+begin_src" . "#\\+end_src"))
(add-to-list 'ispell-skip-region-alist '("^#\\+begin_example " . "#\\+end_example$"))
(add-to-list 'ispell-skip-region-alist '("^#\\+BEGIN_EXAMPLE " . "#\\+END_EXAMPLE$")))
I use most of the minimal setup in this init-ivy config. Note that I’ve stopped using ivy, however.
; (add-hook 'bibtex-mode-hook 'flyspell-mode)
(setq bibtex-user-optional-fields
'(("keywords" "Keywords to describe the entry" "")
("file" "Link to document file." ":"))
bibtex-align-at-equal-sign t)
(setq bibtex-dialect 'biblatex)
https://github.com/jkitchin/org-ref/blob/master/org-ref.org
(use-package org-ref
:after org ;ivy-bibtex
:init
(require 'bibtex)
:bind
(:map org-mode-map
("s-[" . org-ref-insert-link-hydra/body)
("C-c ]" . org-ref-insert-link))
:hook
(org-export-before-parsing . org-ref-glossary-before-parsing)
(org-export-before-parsing . org-ref-acronyms-before-parsing)
:init
;(require 'org-ref-ivy)
;; (setq org-ref-insert-link-function 'org-ref-insert-link-hydra/body
;; org-ref-insert-cite-function 'org-ref-cite-insert-ivy
;; org-ref-default-citation-link 'parencite
;; org-ref-insert-label-function 'org-ref-insert-label-link
;; org-ref-insert-ref-function 'org-ref-insert-ref-link
;; org-ref-cite-onclick-function (lambda (_) (org-ref-citation-hydra/body))
;; )
;; (require 'org-ref-archiv)
;; (require 'org-ref-scopus)
;; (require 'org-ref-wos)
)
from the manual
(setq bibtex-completion-pdf-field "file")
(defun my/org-ref-open-pdf-at-point ()
"Open the pdf for bibtex key under point if it exists."
(interactive)
(let* ((results (org-ref-get-bibtex-key-and-file))
(key (car results))
(pdf-file (car (bibtex-completion-find-pdf-in-field key))))
(if (file-exists-p pdf-file)
(org-open-file pdf-file)
(message "No PDF found for %s" key))))
(setq org-ref-open-pdf-function 'my/org-ref-open-pdf-at-point)
;; (setq org-ref-get-pdf-filename-function 'bibtex-completion-find-pdf-in-field)
(global-set-key (kbd "<f8>") 'my/org-ref-open-pdf-at-point)
(use-package pdf-tools
:magic ("%PDF" . pdf-view-mode)
:load-path "/usr/share/emacs/site-lisp/pdf-tools"
:init
(pdf-tools-install)
:custom
;(pdf-loader-install)
(pdf-view-display-size 'fit-width)
:bind
;; swiper doesn't play nice with pdf-tools, so I disable it.
;(:map pdf-view-mode-map ("C-s" . isearch-forward))
)
https://github.com/weirdNox/org-noter
(use-package org-noter
:config
:bind (;(:map org-mode-map ("C-c o" . org-noter))
(:map org-noter-notes-mode-map
("C-c k" . org-noter-pdftools-create-skeleton)
("C-c q" . org-noter-kill-session)))
:custom
;; org-noter-notes-window-location 'horizontal-split
;; Please stop opening frames
(org-noter-always-create-frame nil)
(org-noter-kill-frame-at-session-end nil)
;; I want to see the whole file
(org-noter-hide-other nil)
;; Everything is relative to the main notes file
(org-noter-notes-search-path "~/SurfDrive/bibliography/notes/")
(require 'org-noter-pdftools))
(use-package org-pdftools
:hook (org-mode . org-pdftools-setup-link))
(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)))
docs here How to Take Smart Notes
(use-package org-roam
:demand ; do not defer
:commands (org-roam-buffer-toggle-display
org-roam-find-file
org-roam-graph
org-roam-insert
org-roam-switch-to-buffer
org-roam-dailies-date
org-roam-dailies-today
org-roam-dailies-tomorrow
org-roam-dailies-yesterday)
:bind (("C-c n f" . org-roam-node-find)
("C-c n d" . org-roam-dailies-capture-today)
:map org-roam-mode-map
("<mouse-1>" . org-roam-visit-thing)
:map org-mode-map
(("C-c n l" . org-roam-buffer-toggle)
("C-c n g" . org-roam-graph)
("C-c n i" . org-roam-node-insert)
:map evil-normal-state-map ;; is there an evil map within org-mode?
("g[" . org-roam-dailies-goto-previous-note)
("g]" . org-roam-dailies-goto-next-note)))
:custom
;; the file-truename part makes it follow symbolic links!
(org-roam-directory (file-truename "~/SurfDrive/bibliography/notes/"))
(org-roam-dailies-directory "daily/")
(org-id-link-to-org-use-id 'create-if-interactive)
;; (org-roam-completion-everywhere t) ;; this was a bit excessive
(org-roam-verbose nil) ; https://youtu.be/fn4jIlFwuLU
(org-roam-buffer-no-delete-other-windows t) ; make org-roam buffer sticky
(org-roam-capture-templates
'(("d" "default" plain
"%?"
:if-new (file+head "%<%Y%m%d%H%M%S>-${slug}.org"
"#+title: ${title}\n#+created: %U\n#+last_modified:\n")
:immediate-finish t
:unnarrowed t)
("p" "people" plain
"%?"
:if-new (file+head "%<%Y%m%d%H%M%S>-${slug}.org"
"#+title: ${title}\n#+created: %U\n#+last_modified:\n\n#+filetags: people")
:immediate-finish t
:unnarrowed t)
("r" "bibliography reference" plain
(file "/home/japhir/ArchConfigs/org-roam-bibtex-capture.org")
:if-new
(file+head "${citekey}.org" "#+title: ${citekey}: ${title}\n")
:add-created t
:unnarrowed t)))
(org-roam-capture-ref-templates
'(("r" "ref" plain
"%?"
:if-new (file+head "${citekey.org}"
"#+title: ${citekey}: ${title}\n")
:immediate-finish t
:add-created t
:unnarrowed t)))
(org-roam-dailies-capture-templates
'(("d" "default" entry
"* %?"
:if-new (file+head "%<%Y-%m-%d>.org"
"#+title: %<%Y-%m-%d>\n#+created: %U\n#+last_modified: %U\n")
:add-created t
:jump-to-captured t)))
:config
;; (org-roam-setup)
(add-to-list 'display-buffer-alist
'("\\*org-roam\\*"
(display-buffer-in-direction)
(direction . right)
;; (window-width . 0.33)
(window-height . fit-window-to-buffer)))
(org-roam-db-autosync-mode)
(require 'org-roam-protocol))
https://org-roam.discourse.group/t/creating-an-org-roam-note-from-an-existing-headline/978
(defun org-roam-create-note-from-headline ()
"Create an Org-roam note from the current headline and jump to it.
Normally, insert the headline’s title using the ’#title:’ file-level property
and delete the Org-mode headline. However, if the current headline has a
Org-mode properties drawer already, keep the headline and don’t insert
‘#+title:'. Org-roam can extract the title from both kinds of notes, but using
‘#+title:’ is a bit cleaner for a short note, which Org-roam encourages."
(interactive)
(let ((title (nth 4 (org-heading-components)))
(has-properties (org-get-property-block)))
(org-cut-subtree)
(org-roam-find-file title nil nil 'no-confirm)
(org-paste-subtree)
(unless has-properties
(kill-line)
(while (outline-next-heading)
(org-promote)))
(goto-char (point-min))
(when has-properties
(kill-line)
(kill-line))))
https://github.com/zaeph/.emacs.d/blob/master/lisp/zp-org.el#L140
(defvar zp/org-created-property-name "CREATED"
"The name of the org-mode property that stores the creation date of the entry")
(defun zp/org-set-created-property (&optional active name)
"Set a property on the entry giving the creation time.
By default the property is called CREATED. If given, the ‘NAME’
argument will be used instead. If the property already exists, it
will not be modified.
If the function sets CREATED, it returns its value."
(interactive)
(let* ((created (or name zp/org-created-property-name))
(fmt (if active "<%s>" "[%s]"))
(now (format fmt (format-time-string "%Y-%m-%d %a %H:%M"))))
(unless (org-entry-get (point) created nil)
(org-set-property created now)
now)))
(defun zp/org-capture-set-created-property ()
"Conditionally set the CREATED property on captured trees."
(let ((add-created (plist-get org-capture-plist :add-created))
(type (plist-get org-capture-current-plist :type)))
(when (and (not org-note-abort)
(eq type 'entry)
add-created)
(unless (buffer-narrowed-p)
(error "Cannot add CREATED when buffer is not narrowed"))
(save-excursion
(goto-char (point-min))
(zp/org-set-created-property)))))
(defun zp/org-set-time-file-property (property &optional anywhere pos)
"Set the time file PROPERTY in the preamble.
When ANYWHERE is non-nil, search beyond the preamble.
If the position of the file PROPERTY has already been computed,
it can be passed in POS."
(when-let ((pos (or pos
(zp/org-find-time-file-property property))))
(save-excursion
(goto-char pos)
(if (looking-at-p " ")
(forward-char)
(insert " "))
(delete-region (point) (line-end-position))
(let* ((now (format-time-string "[%Y-%m-%d %a %H:%M]")))
(insert now)))))
(defun zp/org-find-time-file-property (property &optional anywhere)
"Return the position of the time file PROPERTY if it exists.
When ANYWHERE is non-nil, search beyond the preamble."
(save-excursion
(goto-char (point-min))
(let ((first-heading
(save-excursion
(re-search-forward org-outline-regexp-bol nil t))))
(when (re-search-forward (format "^#\\+%s:" property)
(if anywhere nil first-heading)
t)
(point)))))
(defun zp/org-has-time-file-property-p (property &optional anywhere)
"Return the position of time file PROPERTY if it is defined.
As a special case, return -1 if the time file PROPERTY exists but
is not defined."
(when-let ((pos (zp/org-find-time-file-property property anywhere)))
(save-excursion
(goto-char pos)
(if (and (looking-at-p " ")
(progn (forward-char)
(org-at-timestamp-p 'lax)))
pos
-1))))
(defun zp/org-set-last-modified ()
"Update the LAST_MODIFIED file property in the preamble."
(when (derived-mode-p 'org-mode)
(zp/org-set-time-file-property "LAST_MODIFIED")))
- State “SOME” from [2024-09-20 Fri 18:32]
(use-package org-roam-ui
:after org-roam
;; :hook
;; normally we'd recommend hooking orui after org-roam, but since org-roam does not have
;; a hookable mode anymore, you're advised to pick something yourself
;; if you don't care about startup time, use
;; :hook (after-init . org-roam-ui-mode)
:config
(setq org-roam-ui-sync-theme t
org-roam-ui-follow t
org-roam-ui-update-on-save t
org-roam-ui-open-on-start t))
(use-package vertico
:custom
(vertico-cycle t)
(vertico-resize nil)
:init
(vertico-mode 1))
it also likes savehist-mode, which I already had enabled.
(use-package marginalia
:init
(marginalia-mode))
(use-package orderless
:ensure t
:custom
(completion-styles '(orderless basic))
(completion-category-defaults nil)
(completion-category-overrides '((file (styles partial-completion)))))
(use-package consult
:bind (;; A recursive grep
("C-c s" . consult-ripgrep) ;; previously counsel-rg
;; Search for files names recursively
("C-x f" . consult-find)
;; Search through the outline (headings) of the file
("C-c o" . consult-outline)
;; Search the current buffer
("C-s" . consult-line) ;; previously swiper
;; Switch to another buffer, or bookmarked file, or recently
;; opened file.
("C-x b" . consult-buffer)))
(use-package embark
:bind (("C-." . embark-act)
:map minibuffer-local-map
("C-c C-c" . embark-collect)
("C-c C-e" . embark-export)))
(use-package embark-consult)
(use-package wgrep
:bind ( :map grep-mode-map
("e" . wgrep-change-to-wgrep-mode)
("C-x C-q" . wgrep-change-to-wgrep-mode)
("C-c C-c" . wgrep-finish-edit)))
(use-package corfu
:init
(global-corfu-mode)
:config
(unless (display-graphic-p)
(when (require 'corfu-terminal nil :noerror)
(corfu-terminal-mode +1)))
;; Setup corfu for popup like completion
(customize-set-variable 'corfu-cycle t) ; Allows cycling through candidates
(customize-set-variable 'corfu-auto t) ; Enable auto completion
(customize-set-variable 'corfu-auto-prefix 2) ; Complete with less prefix keys
(when (require 'corfu-popupinfo nil :noerror)
(corfu-popupinfo-mode 1)
(eldoc-add-command #'corfu-insert)
(keymap-set corfu-map "M-p" #'corfu-popupinfo-scroll-down)
(keymap-set corfu-map "M-n" #'corfu-popupinfo-scroll-up)
(keymap-set corfu-map "M-d" #'corfu-popupinfo-toggle))
:custom
(text-mode-ispell-word-completion nil))
;; Use Dabbrev with Corfu!
(use-package dabbrev
;; Swap M-/ and C-M-/
:bind (("M-/" . dabbrev-completion)
("C-M-/" . dabbrev-expand))
:config
(add-to-list 'dabbrev-ignored-buffer-regexps "\\` ")
;; Since 29.1, use `dabbrev-ignored-buffer-regexps' on older.
(add-to-list 'dabbrev-ignored-buffer-modes 'doc-view-mode)
(add-to-list 'dabbrev-ignored-buffer-modes 'pdf-view-mode)
(add-to-list 'dabbrev-ignored-buffer-modes 'tags-table-mode))
(use-package cape
:bind ("M-+" . cape-prefix-map)
:init
;; Add useful defaults completion sources from cape
(add-hook 'completion-at-point-functions #'cape-dabbrev)
(add-hook 'completion-at-point-functions #'cape-dict)
(add-hook 'completion-at-point-functions #'cape-file)
(add-hook 'completion-at-point-functions #'cape-history)
:config
;; Silence the pcomplete capf, no errors or messages!
;; Important for corfu
(advice-add 'pcomplete-completions-at-point :around #'cape-wrap-silent)
;; Ensure that pcomplete does not write to the buffer
;; and behaves as a pure `completion-at-point-function'.
(advice-add 'pcomplete-completions-at-point :around #'cape-wrap-purify)
;; No auto-completion or completion-on-quit in eshell
(defun crafted-completion-corfu-eshell ()
"Special settings for when using corfu with eshell."
(setq-local corfu-quit-at-boundary t
corfu-quit-no-match t
corfu-auto nil)
(corfu-mode))
(add-hook 'eshell-mode-hook #'crafted-completion-corfu-eshell))
(use-package vterm)
;; (define-key vterm-mode-map (kbd "C-c C-l") #'vterm-clear)
(use-package systemd
:defer t)
(use-package dired-single)
(use-package dired
:ensure nil
:commands (dired dired-jump)
:bind (("C-x C-j" . dired-jump))
:custom ((dired-listing-switches "-agho --group-directories-first --time-style=iso"))
:config
(evil-collection-define-key 'normal 'dired-mode-map
"h" 'dired-single-up-directory
"l" 'dired-single-buffer))
(use-package dired-open
:config
(setq dired-open-extensions '(("png" . "imv")
("mkv" . "mpv")
("mp4" . "mpv"))))
(use-package dired-hide-dotfiles
:hook (dired-mode . dired-hide-dotfiles-mode)
:config
(evil-collection-define-key 'normal 'dired-mode-map
"H" 'dired-hide-dotfiles-mode))
Install it with Pacman
sudo pacman -S emacs-pkgbuild-mode
Then load it into emacs when opening a PKGBUILD file
(use-package pkgbuild-mode
:ensure nil
:defer t
:load-path "/usr/share/emacs/site-lisp/"
:mode "/PKGBUILD$")
(use-package smtpmail
:ensure nil
:custom
;; default config from https://www.djcbsoftware.nl/code/mu/mu4e/Gmail-configuration.html#Settings
(message-send-mail-function 'smtpmail-send-it)
(starttls-use-gnutls t)
(smtp-stream-type 'starttls))
https://github.com/harishkrupo/oauth2ms/blob/main/steps.org I have to use this repo to access my work’s office365 account through XOAUTH2
;;; Call the oauth2ms program to fetch the authentication token
(defun fetch-access-token ()
(with-temp-buffer
(call-process "/home/japhir/bin/oauth2ms" nil t nil "--encode-xoauth2")
(buffer-string)))
;;; Add new authentication method for xoauth2
(cl-defmethod smtpmail-try-auth-method
(process (_mech (eql xoauth2)) user password)
(let* ((access-token (fetch-access-token)))
(smtpmail-command-or-throw
process
(concat "AUTH XOAUTH2 " access-token)
235)))
;;; Register the method
(with-eval-after-load 'smtpmail
(add-to-list 'smtpmail-auth-supported 'xoauth2))
install it with pacman mu
(use-package mu4e
:ensure nil
:load-path "/usr/share/emacs/site-lisp/mu4e/"
:commands mu4e
:bind (("C-c m" . mu4e) ("C-c C-o" . shr-browse-url))
:hook ((mu4e-view-mode mu4e-compose-mode) . visual-line-mode)
:config
(require 'mu4e) ;; somehow this is needed, because otherwise calling org-store-link doesn't work
(require 'mu4e-org)
;; Use Ivy for mu4e completions (maildir folders, etc)
; (setq mu4e-completing-read-function #'ivy-completing-read)
;; send email using smtp
;; see https://www.djcbsoftware.nl/code/mu/mu4e/Gmail-configuration.html#Settings
;; see also the smtp heading
(require 'smtpmail)
(setq mail-user-agent 'mu4e-user-agent
message-send-mail-function 'smtpmail-send-it
send-mail-function 'smtpmail-send-it
;; this is the same for both mail clients
smtpmail-default-smtp-server "smtp.gmail.com"
smtpmail-smtp-service 587
smtpmail-stream-type 'starttls
starttls-use-gnutls t
starttls-gnutls-program "gnutls-cli"
starttls-extra-arguments nil
smtpmail-auth-credentials (expand-file-name "~/.authinfo")
smtpmail-debug-info t
smtpmail-debug-verb t)
(setq user-full-name "Ilja J. Kocken")
(setq mu4e-contexts
(list
;; University of Hawaii
(make-mu4e-context
:name "hawaii"
:enter-func (lambda () (mu4e-message "Switch to Hawaiʻi context"))
:match-func (lambda (msg)
(when msg
(string-prefix-p "/hawaii" (mu4e-message-field msg :maildir))))
:vars '((user-mail-address . "ikocken@hawaii.edu")
(message-user-organization . "University of Hawaiʻi at Mānoa")
;; sending email
(smtpmail-smtp-user . "ikocken@hawaii.edu")
(smtpmail-smtp-server . "smtp.gmail.com")
(smtpmail-smtp-service . 587)
;; (smtpmail-starttls-credentials . '(("smtp.gmail.com" 587 nil nil)))
;; (smtpmail-auth-credentials . '(("smtp.gmail.com" 587 "ikocken@hawaii.edu" nil)))
(mu4e-drafts-folder . "/hawaii/Drafts")
(mu4e-sent-folder . "/hawaii/Sent")
(mu4e-refile-folder . "/hawaii/Archive")
(mu4e-trash-folder . "/hawaii/Trash")
(mu4e-compose-signature .
(concat
"Dr. Ilja J. Kocken | Postdoc Researcher at SOEST |\n"
"University of Hawaii at Mānoa | 1000 Pope Road |\n"
"MSB 504 | Honolulu, HI 96822, USA\n"))
(mu4e-maildir-shortcuts .
(("/hawaii/Inbox" . ?i)
;; ("/hawaii/Drafts" . ?d) ; not synched!
("/hawaii/Trash" . ?t)
;; ("/hawaii/Sent Mail" . ?s) ; deleted!
;; ("/hawaii/Junk Email" . ?t)
("/hawaii/Archive" . ?r)))
;; delete gmail sent items because they're also stored in All Mail/Archive.
(mu4e-sent-messages-behavior . delete)))
;; Utrecht University
(make-mu4e-context
:name "solismail"
:match-func (lambda (msg)
(when msg
(string-prefix-p "/solismail" (mu4e-message-field msg :maildir))))
:vars '((user-mail-address . "i.j.kocken@uu.nl")
(message-user-organization . "Utrecht University")
;; sending email
(smtpmail-smtp-user . "i.j.kocken@uu.nl")
(smtpmail-smtp-server . "smtp.office365.com")
(smtpmail-smtp-service . 587)
(smtpmail-stream-type . starttls)
(smtpmail-starttls-credentials . (("outlook.office365.com" 587 "i.j.kocken@uu.nl" nil)))
(smtpmail-auth-credentials . (("outlook.office365.com" 587 "i.j.kocken@uu.nl" nil)))
(mu4e-drafts-folder . "/solismail/Drafts")
(mu4e-sent-folder . "/solismail/Sent")
(mu4e-refile-folder . "/solismail/Archive")
(mu4e-trash-folder . "/solismail/Trash")
(mu4e-compose-signature .
(concat
"Dr. Ilja Kocken\n"
"Utrecht University | Vening Meinesz Gebouw A |\n"
"Princetonlaan 8a, 3584 CB Utrecht, the Netherlands\n"))
(mu4e-maildir-shortcuts .
(("/solismail/Inbox" . ?i)
;;("/NEXT" . ?n)
;; ("/solismail/Waiting" . ?w)
;; ("/solismail/Drafts" . ?c)
("/solismail/Trash" . ?t)
("/solismail/news" . ?n)
("/solismail/Important backlog" . ?l)
("/solismail/Sent" . ?s)
;; ("/solismail/Spam" . ?t)
("/solismail/Archive" . ?r)))
))
(make-mu4e-context
:name "gmail"
:enter-func (lambda () (mu4e-message "Switch to Personal context"))
:match-func (lambda (msg)
(when msg
(string-prefix-p "/gmail" (mu4e-message-field msg :maildir))))
:vars '((user-mail-address . "iljakocken@gmail.com")
(message-user-organization . "Personal")
;; sending email
(smtpmail-stream-type . starttls)
(smtpmail-smtp-user . "iljakocken@gmail.com")
(smtpmail-smtp-server . "smtp.gmail.com")
(smtpmail-smtp-service . 587)
;; (smtpmail-starttls-credentials . '(("smtp.gmail.com" 587 nil nil)))
;; (smtpmail-auth-credentials . '(("smtp.gmail.com" 587 "iljakocken@gmail.com" nil)))
(mu4e-drafts-folder . "/gmail/Drafts")
(mu4e-sent-folder . "/gmail/Sent")
(mu4e-refile-folder . "/gmail/Archive")
(mu4e-trash-folder . "/gmail/Trash")
(mu4e-compose-signature .
(concat
"Ilja"))
(mu4e-maildir-shortcuts .
(("/gmail/Inbox" . ?i)
;; ("/gmail/Drafts" . ?d) ; not synched!
("/gmail/Trash" . ?t)
;; ("/gmail/Sent" . ?s) ; deleted!
;; ("/gmail/Junk Email" . ?t)
("/gmail/Archive" . ?r)))
;; delete gmail sent items because they're also stored in All Mail/Archive.
(mu4e-sent-messages-behavior . delete)))
))
(setq mu4e-context-policy 'pick-first) ;; default to hawaii gmail
(setq mu4e-change-filenames-when-moving t ; important for isync
mu4e-headers-date-format "%Y-%m-%d %H:%M"
mu4e-headers-fields
'((:date . 17)
(:flags . 5)
(:from . 22)
(:subject . nil))
mu4e-get-mail-command "env PATH=/usr/bin:/home/japhir/bin: mbsync -a"
mu4e-headers-include-related t
mu4e-compose-format-flowed t ; plain-text nice to read on phone
;; use-hard-newlines t ; above doesn't work for Outlooks, so disabled for colleagues
mu4e-confirm-quit nil
mu4e-view-show-images t)
;; if you press a V on an email you open it in the browser
(add-to-list 'mu4e-view-actions '("View in browser" . mu4e-action-view-in-browser) t)
;; use imagemagick, if available
;; (when (fboundp 'imagemagick-register-types)
;; (imagemagick-register-types))
(setq mu4e-org-link-query-in-headers-mode nil)
;; maybe I want this at some point? currently not working, mu must have changed it query syntax
(add-to-list 'mu4e-bookmarks
'(:name "All Inboxes"
:query "maildir:/hawaii/Inbox OR maildir:/solismail/inbox OR maildir:/gmail/Inbox"
:key ?i))
(add-to-list 'mu4e-bookmarks
'(:name "All sent mail"
:query "from:ikocken@hawaii.edu OR from:iljakocken@gmail.com OR from:i.j.kocken@uu.nl"
:key ?s))
)
https://ess.r-project.org/ emacs speaks statistics, work with R etc.
(defun japhir/insert-r-pipe ()
"Insert the pipe operator in R, |>"
(interactive)
(just-one-space 1)
(insert "|>")
(reindent-then-newline-and-indent))
(use-package ess
;; :load-path "/usr/share/emacs/site-lisp/ess"
:init (require 'ess-site) ;; seems like this is needed to load the minor modes as well keybindings don't work without it
:hook (
((ess-r-mode inferior-ess-r-mode) . electric-layout-mode)
;; (ess-r-post-run . (lambda ()
;; (ess-load-file (make-temp-file nil nil nil
;; "Sys.setenv(\"DISPLAY\"=\":0.0\")")))
)
:commands R
:bind (:map ess-r-mode-map
(";" . ess-insert-assign)
;; RStudio equivalents
("M--" . ess-insert-assign)
("C-S-m" . japhir/insert-r-pipe)
:map inferior-ess-r-mode-map
(";" . ess-insert-assign)
("M--" . ess-insert-assign)
("C-S-m" . japhir/insert-r-pipe))
:config
(defun my-org-confirm-babel-evaluate (lang body)
(not (or (string= lang "R")
(string= lang "python")
(string= lang "elisp")
(string= lang "emacs-lisp")
(string= lang "julia")
(string= lang "stan")
(string= lang "sh")
(string= lang "latex"))))
(setq ess-use-ido nil) ; disable ido, so that vertico etc. are used
(add-to-list 'display-buffer-alist
'(("\\*R:"
display-buffer-in-side-window
(inhibit-same-window . t)
(side . right)
;; (slot . 2)
;; (window-width . 0.5)
)))
:custom
;; display-buffer-alist
;; '(("*R Dired*"
;; (display-buffer-reuse-window display-buffer-in-side-window)
;; (side . right)
;; (slot . -1)
;; (window-width . 0.33))
;; ("*R:"
;; (display-buffer-reuse-window display-buffer-in-side-window)
;; (slot . 2)
;; (window-width . 0.5))
;; ("*Help*"
;; (display-buffer-reuse-window display-buffer-in-side-window)
;; (side . right)
;; (slot . 1)
;; (window-width . 0.33)))
;; ess-help-own-frame 'one
;; ess-auto-width 'window
(org-confirm-babel-evaluate 'my-org-confirm-babel-evaluate)
(ess-style 'RStudio)
;; (ess-use-auto-complete nil)
;; (ess-use-company t) ; I now use corfu!
(ess-indent-with-fancy-comments nil)
(ess-pdf-viewer-pref 'emacsclient)
(inferior-R-args "--no-restore-history --no-save")
(ess-ask-for-ess-directory nil)
(ess-R-font-lock-keywords
(quote
((ess-R-fl-keyword:modifiers)
(ess-R-fl-keyword:fun-defs . t)
(ess-R-fl-keyword:keywords . t)
(ess-R-fl-keyword:assign-ops . t)
(ess-R-fl-keyword:constants . t)
(ess-R-fl-keyword:fun-cals . t)
(ess-R-fl-keyword:numbers)
(ess-R-fl-keyword:operators . t)
(ess-R-fl-keyword:delimiters)
(ess-R-fl-keyword:=)
(ess-R-fl-keyword:F&T)))))
GioBo/ess-view: A small package to view dataframes within spreadsheet softwares allows you to quickly look at dataframes in a spreadsheet software (in my case LibreOffice)
(use-package ess-view
:after ess)
Put spaces around operators such as +, -, etc.
(use-package electric-operator
:hook ((R-mode ess-r-mode inferior-ess-r-mode) . electric-operator-mode)
:config
(electric-operator-add-rules-for-mode 'stan-mode
(cons "," ", ")
(cons "~" " ~ "))
(electric-operator-add-rules-for-mode 'ess-r-mode
(cons ".+" " . + ")
;; these should never have spacing around them
(cons ":" ":") ;; for ranges, should not add space
(cons "::" "::") ;; to call a function from a package
(cons ":::" ":::") ;; to call an internal function from a package
(cons ":=" " := ") ;; walrus operator
(cons "? " "?")
(cons "){" ") {")
(cons "}else{" "} else {")
(cons "for(" "for (")
(cons "if(" "if (")
(cons "while(" "while (")
(cons "{{" " {{ ") ;; curly-curly tidyverse
(cons "}}" " }} ")
(cons "!!" " !!")
(cons "!!!" " !!!")
(cons "^" "^") ;;
(cons "|>" " |> ") ;; r 4.0 built-in pipe
)
:custom
(electric-operator-R-named-argument-style 'spaced))
(setq compilation-window-height 15)
- Note taken on [2024-10-08 Tue 11:44]
this makes larger org-mode files very very slow
(use-package flycheck
;; :init (global-flycheck-mode)
)
(use-package julia-mode) ;; for syntax highlighting
(use-package julia-repl ;; for fancy REPL
:after vterm
:hook
(julia-mode . julia-repl-mode)
(julia-repl . #'julia-repl-use-emacsclient)
;; (add-hook 'julia-mode-hook 'julia-repl-mode)
:config
(setq julia-repl-switches "--threads 4")
(setq vterm-kill-buffer-on-exit nil)
;; after julia-repl but before using it
(julia-repl-set-terminal-backend 'vterm))
(use-package org-contrib
:init
(require 'ob-julia)
:commands org-babel-execute:julia
:config
;; (setq org-babel-julia-command-arguments
;; `("--sysimage"
;; ,(when-let ((img "~/.local/lib/julia.so")
;; (exists? (file-exists-p img)))
;; (expand-file-name img))
;; "--threads"
;; ,(number-to-string (- (doom-system-cpus) 2))
;; "--banner=no"))
)
https://mc-stan.org/ check out this worg entry on working inline with stan models! https://orgmode.org/worg/org-contrib/babel/languages/ob-doc-stan.html
(use-package stan-mode
:mode ("\\.stan\\'" . stan-mode)
:hook (stan-mode . stan-mode-setup)
:config
(setq stan-indentation-offset 2)
;; I've used cmdstanr to install cmdstan because it's not in my repositories
;; don't forget to update this after updating from within an R session!
(setq org-babel-stan-cmdstan-directory "/home/japhir/.cmdstan/cmdstan-2.32.2"))
;; (use-package company-stan
;; :hook (stan-mode . company-stan-setup))
(use-package eldoc-stan
:hook (stan-mode . eldoc-stan-setup))
(use-package flycheck-stan
:hook ((stan-mode . flycheck-stan-stanc2-setup)
(stan-mode . flycheck-stan-stanc3-setup))
:config
(setq flycheck-stanc-executable nil)
(setq flycheck-stanc3-executable nil))
;;; stan-snippets.el
(use-package stan-snippets
:hook (stan-mode . stan-snippets-initialize)
;;
:config
;; No configuration options as of now.
)
markdown mode for writing
(use-package markdown-mode :defer t)
for working with .Rmd files etc.
(use-package polymode :defer t)
(use-package poly-markdown :defer t)
(use-package poly-R)
(use-package ob-mermaid
:custom
(ob-mermaid-cli-path "/usr/bin/mmdc"))
for working with \LaTeX
;(load "auctex.el" nil t t)
;(load "preview-latex.el" nil t t)
(use-package tex
:load-path "/usr/share/emacs/site-lisp/auctex/"
:hook
(LaTeX-mode . turn-on-reftex)
;; (LaTeX-mode . turn-on-auto-fill) ;; I actually don't like this!
(LaTeX-mode . prettify-symbols-mode)
(LaTeX-mode . visual-fill-column-mode)
(LaTeX-mode . menu-bar--display-line-numbers-mode-relative)
:init
(setq TeX-auto-save t)
(setq TeX-parse-self t)
(setq-default TeX-master nil)
(setq reftex-plug-into-AUCTeX t))
These are all the settings that require secret directories, such as my org agenda files and google overwrite the settings with “<…>” syntax above.
;; (use-package emacsdirs)
(load "~/.emacs.d/secretdirs.el" t)
(use-package tree-sitter-langs)
(require 'treesit)
(global-tree-sitter-mode)
(add-hook 'ess-r-mode-hook #'tree-sitter-hl-mode)
(add-hook 'c-mode-hook #'tree-sitter-hl-mode)
(add-hook 'rust-mode-hook #'tree-sitter-hl-mode)
;; (add-hook 'ess-r-mode-hook #'tree-sitter-indent-mode)
(customize-set-variable 'treesit-font-lock-level 4)
;; (use-package tree-sitter-indent)
;; (use-package tree-sitter-ispell)
;; (use-package tree-sitter-ess-r
;; :hook (ess-r-mode-hook . tree-sitter-ess-r-mode-activate))
(setq major-mode-remap-alist
'((bash-mode . bash-ts-mode)
(c-mode . rust-c-mode)
(python-mode . python-ts-mode)
(rust-mode . rust-ts-mode)))
(use-package evil-textobj-tree-sitter
;; copied from https://github.com/meain/evil-textobj-tree-sitter README
:config
;; bind `function.outer`(entire function block) to `f` for use in things like `vaf`, `yaf`
(define-key evil-outer-text-objects-map "f" (evil-textobj-tree-sitter-get-textobj "function.outer"))
;; bind `function.inner`(function block without name and args) to `f` for use in things like `vif`, `yif`
(define-key evil-inner-text-objects-map "f" (evil-textobj-tree-sitter-get-textobj "function.inner"))
;; You can also bind multiple items and we will match the first one we can find
(define-key evil-outer-text-objects-map "a" (evil-textobj-tree-sitter-get-textobj ("conditional.outer" "loop.outer")))
;; The first arguemnt to `evil-textobj-tree-sitter-get-textobj' will be the capture group to use
;; and the second arg will be an alist mapping major-mode to the corresponding query to use.
(define-key evil-outer-text-objects-map "m" (evil-textobj-tree-sitter-get-textobj "import"
'((python-mode . [(import_statement) @import])
(c-mode . [(preproc_include) @import]))))
;; Goto start of next function
(define-key evil-normal-state-map (kbd "]f") (lambda ()
(interactive)
(evil-textobj-tree-sitter-goto-textobj "function.outer")))
;; Goto start of previous function
(define-key evil-normal-state-map (kbd "[f") (lambda ()
(interactive)
(evil-textobj-tree-sitter-goto-textobj "function.outer" t)))
;; Goto end of next function
(define-key evil-normal-state-map (kbd "]F") (lambda ()
(interactive)
(evil-textobj-tree-sitter-goto-textobj "function.outer" nil t)))
;; Goto end of previous function
(define-key evil-normal-state-map (kbd "[F") (lambda ()
(interactive)
(evil-textobj-tree-sitter-goto-textobj "function.outer" t t)))
)
(setq gc-cons-threshold 16777216
gc-cons-percentage 0.1)