;;; init.el --- my emacs configuration -*- lexical-binding: t; -*- ;;; Commentary: ;; (profiler-start 'cpu+mem) ;; Things we have, or want to have, in this configuration: ;; - Make a nice interface ;; - Programming ;; - Offline web browsing ;; - Reading mail ;; - Sending mail ;; - Bibliography management ;; - Taking notes (add-to-list 'load-path (expand-file-name (concat user-emacs-directory "site-lisp"))) (add-to-list 'exec-path "/home/noa/.config/Scripts") (use-package use-package :custom (use-package-compute-statistics t) (use-package-enable-imenu-support t)) ;; Give me stats on garbage collection and startup time (add-hook 'emacs-startup-hook #'(lambda () (message (format "Initialised in %s seconds with %s garbage collections." (emacs-init-time) gcs-done)))) ;; keep the emacs directory clean (use-package no-littering) ;; It is often useful to be able to run a command while i am already in the process of running a command in the minibuffer. This is rarely two extended commands; usually it is completion. (use-package mb-depth :hook (after-init . minibuffer-depth-indicate-mode)) (use-package tubthumping-theme :disabled t :load-path "~/Documents/Projects/Tubthumping/" :config (load-theme 'tubthumping t)) ;;; Fonts ;; Using a proportional font is the right way to do things, but emacs is very old and comes from a time before the innovation of legibility. As a result, there are some things that require a monospaced font, so i set one here. (custom-set-faces '(default ((t (:family "Noto Sans Mono" :height 120)))) '(variable-pitch ((t (:family "Noto Sans" :height 120)))) '(fixed-pitch ((t (:family "Noto Sans Mono" :height 120)))) ) (use-package face-remap :hook ((text-mode . variable-pitch-mode) (prog-mode . variable-pitch-mode))) ;; Use simplified not korean hanzi (when (display-graphic-p) (dolist (charset '(han cjk-misc)) (set-fontset-font t charset (font-spec :family "Noto Serif CJK SC")))) ;; Prioritise fsd and noto emoji over coloured variants (when (and (display-graphic-p) (member "FSD Emoji" (font-family-list))) (set-fontset-font t 'emoji (font-spec :family "FSD Emoji") nil 'prepend)) (when (and (display-graphic-p) (member "Noto Emoji" (font-family-list))) (set-fontset-font t 'emoji (font-spec :family "Noto Emoji") nil 'append)) ;; While we're here, let's set up emoji input. (use-package emoji :bind ("C-." . emoji-search)) ;; Smooth-ish scrolling with the mouse, and smooth scrolling with C-v and M-v. Sadly it doesn't work with C-l. (use-package pixel-scroll :hook (after-init . pixel-scroll-precision-mode) :custom (pixel-scroll-precision-use-momentum t) (pixel-scroll-precision-interpolate-page t) :bind (([remap scroll-up-command] . pixel-scroll-interpolate-down) ([remap scroll-down-command] . pixel-scroll-interpolate-up))) ;; Update the calendar. We want weeks to start on a monday, the first day of the week. Holidays should be highlighted, and the date format should put the year first. (use-package calendar :defer t :custom (calendar-week-start-day 1) (calendar-date-style 'iso) :config ;; Ensure the calendar always displays at the bottom of the screen, rather than wrapping weirdly and looking bad when it shows up in a side window. (add-to-list 'display-buffer-alist '("\\*Calendar\\*" (display-buffer-in-side-window) (side . bottom)))) ;; Squeeze text into a more legible sliver. (use-package visual-fill-column :custom (visual-fill-column-enable-sensible-window-split t) (visual-fill-column-fringes-outside-margins nil) ; Keep fringes on the inside so relevant icons are in the right place (visual-fill-column-center-text t) :hook ((text-mode . visual-fill-column-mode) (eww-after-render . visual-line-fill-column-mode)) ) (use-package simple :hook ((text-mode . visual-line-mode) (after-init . auto-save-mode)) :custom (save-interprogram-paste-before-kill t) (kill-ring-max 25) ;; Hide commands in M-x which do not work in the current mode. (read-extended-command-predicate 'command-completion-default-include-p) ;; My brain is not ready for advanced emacs undo (undo-no-redo t) :bind (("C-z" . undo) ("C-S-z" . undo-redo))) ;; (advice-add 'text-scale-adjust :after #'visual-fill-column-adjust) ;; Doesn't indent nicely with proportional fonts ;; (use-package adaptive-wrap :ensure t) ;; (add-hook 'visual-fill-column-mode-hook #'visual-wrap-prefix-mode) ;; Make tooltip information appear consistently in the echo area (use-package tooltip :custom (tooltip-mode nil)) ;; startup.el does not provide itself, cannot be used with use-package (setopt inhibit-startup-screen t) (use-package mouse :custom (mouse-yank-at-point t) (mouse-drag-and-drop-region nil) (mouse-yank-at-point t) ;; Allow for slightly sloppier clicking. (mouse-prefer-closest-glyph t) ;; Emacs 30 ) ;; Shift click to select region with the mouse (https://christiantietze.de/posts/2022/07/shift-click-in-emacs-to-select/) (global-set-key (kbd "S-") #'mouse-set-mark) ;; Doesn't work great with a proportional font but could still be useful. (global-set-key (kbd "C-S-") #'mouse-drag-region-rectangle) ;; Markdown (use-package markdown-mode :mode ("\\.\\(?:md\\|markdown\\|mkd\\|mdown\\|mkdn\\|mdwn\\)\\'" . markdown-mode) :custom (markdown-disable-tooltip-prompt t) ; When inserting a link, only prompt for url and link text (markdown-enable-html nil) ; I don't believe markdown should have html (markdown-hide-urls t) ; Make inline urls look a bit neater (markdown-url-compose-char ?~) (markdown-max-image-size '(640 . 480)) ;; :hook ((markdown-mode . noa/set-buffer-name-to-markdown-title)) ) ;; Use abbrev as a simple autocorrect mode. M-x list-abbrevs for stats. ;; Check ~/.config/emacs/abbrev_defs to update any mistakes (use-package abbrev :hook (text-mode . abbrev-mode)) (use-package flyspell :hook (text-mode . flyspell-mode) :custom (flyspell-abbrev-p t)) (use-package writegood-mode :hook (text-mode . writegood-mode)) ;; A nicer package for spellchecking (use-package jinx :disabled t :hook (text-mode . jinx-mode) :commands (jinx-correct jinx-correct-all) :config (put 'jinx-overlay 'mouse-face '(jinx-misspelled highlight)) ;; Use standard mouse face for jinx overlays (add-to-list 'jinx-exclude-regexps '(t "\\cc")) ;; Don't check chinese characters ) ;; Automatically creates an abbrev for words i correct, so i don't make the same mistake twice (defun jinx--add-to-abbrev (overlay word) "Add abbreviation to `global-abbrev-table'. The misspelled word is taken from OVERLAY. WORD is the corrected word." (let ((abbrev (buffer-substring-no-properties (overlay-start overlay) (overlay-end overlay)))) (message "Abbrev: %s -> %s" abbrev word) (define-abbrev global-abbrev-table abbrev word))) (advice-add 'jinx--correct-replace :before #'jinx--add-to-abbrev) (use-package help :defer t :custom ;; When opening source files from a help window, use the same window (help-window-keep-selected t)) ;; Despite the name, eww is a delight to use for text-heavy websites. (use-package browse-url :defer t :custom (browse-url-browser-function 'noa/record-url) (browse-url-secondary-browser-function 'browse-url-default-browser)) ;; I've had no use for cookies in eww (use-package url-cookie :defer t :custom (url-cookie-trusted-urls '()) (url-cookie-untrusted-urls '(".*"))) (use-package shr :defer t :custom (shr-cookie-policy nil) (shr-use-colors nil) ;; I like the colours i already have set (shr-max-width nil) ;; Don't insert hard linebreaks to wrap paragraphs (shr-bullet " • ") (shr-discard-aria-hidden t)) (use-package eww :defer t :custom ;; Better buffer naming for eww buffers. See the help for a function which gives the page title and the url. (eww-auto-rename-buffer 'title)) ;; Goto address mode makes urls and email address in a buffer clickable. I want these clickable links to look like links, because that's what they are. The two mouse face variables are what face is used on hover, which at the moment i ignore. It might also be worth setting them to 'highlight. (use-package goto-addr :hook (after-init . global-goto-address-mode) :custom (goto-address-mail-face 'link) (goto-address-mail-mouse-face 'highlight) (goto-address-url-face 'link) (goto-address-url-mouse-face 'highlight)) (use-package flymake :hook (prog-mode . flymake-mode)) (use-package emacs :custom (window-combination-resize t) (window-resize-pixelwise t) (frame-resize-pixelwise t) (shell-file-name "/bin/sh") (completion-ignore-case t) (read-buffer-completion-ignore-case t) ;; yes-or-no-p uses y-or-no-p, and read-answer accepts single key press answers (use-short-answers t) (history-length 250) ;; Use a bar cursor and blink it and don't stop blinking it. (cursor-type 'bar) ;; Support opening new minibuffers from inside existing minibuffers. (enable-recursive-minibuffers t) ;; Whether to drop into the debugger on any error. This seems cool, but in practice is a bit annoying. (debug-on-error nil) (create-lockfiles nil) (auto-save-interval 6) ;; every six keystrokes (auto-save-timeout 5) ;; every 5 seconds (auto-save-no-message t) ;; Always give me a line of text when i'm near the edges of the screen (scroll-margin 2)) (use-package dired :defer t :custom (dired-recursive-deletes 'always) ;; Don't ask me things (dired-recursive-copies 'always) ;; Don't ask me things (dired-dwim-target t) ;; Synergy between two dired windows ;; I have quite a bit of storage and also make bad decisions regularly ;; People who have used computers in the last forty years or so will likely be familiar with this innovation. (delete-by-moving-to-trash t) ;; -l is required by dired ;; -a to also show dotfiles ;; -v to sort numbers properly ;; -F to visually distinguish different types of file ;; -h for human readable file sizes ;; I won't explain the meaning of the long flag. (dired-listing-switches "-alvFh --group-directories-first") ;; By default, don't show dired details :hook ((dired-mode . dired-hide-details-mode) (dired-mode . hl-line-mode)) ) ;; Show the recursive size of directories (use-package dired-du :disabled t :hook (dired-mode . dired-du-mode) :after dired :custom (dired-du-size-format t)) ;; Some tramp settings. (use-package files :custom (view-read-only t) (confirm-kill-emacs 'y-or-n-p) ;; We are on a unix system, so it makes sense to end files in the unix system way. I'm surprised this isn't the default. (require-final-newline t) ;; This behaviour changes how we visit symlinks. (find-file-visit-truename t) (remote-file-name-inhibit-locks t) (remote-file-name-inhibit-auto-save t) (remote-file-name-inhibit-auto-save-visited t) (backup-directory-alist '(("." . "~/.config/emacs/backups/"))) (make-backup-files nil) (backup-by-copying t) (version-control t) ;; this will auto save to the current file (auto-save-visited-mode t) (auto-save-visited-interval 0.1) (save-silently t) ;; don't message when saving ) (use-package tramp :defer t :custom (tramp-inline-compress-start-size 1000) (tramp-verbose 3)) ;; (add-to-list 'tramp-remote-path 'tramp-own-remote-path) ;; I only use git, and this apparently speeds up tramp. (use-package vc-hooks :after vc :custom (vc-handled-backends '(Git))) ;; It seems that tramp can also be made faster with these .ssh/config settings. ;; Host * ;; ControlMaster auto ;; ControlPath ~/.ssh/master-%h:%p ;; ControlPersist 10m ;; ForwardAgent yes ;; ServerAliveInterval 60 ;; Don't override display actions when i manually initiate a buffer switch. (use-package window :custom ;; My computer has a small screen, so i find that it's more beneficial for me to split the frame into columns, so i get more context. However, splitting in this way only gives me a (window-width) of 61, so emacs will always split into vertically stacked windows. By setting this to 80, the first split should always be vertical. (split-width-threshold 80) (switch-to-buffer-obey-display-actions t) ;; C-l from top to bottom (recenter-positions '(top middle bottom))) (use-package frame :hook (after-init . window-divider-mode) :custom (window-divider-default-right-width 1) (window-divider-default-bottom-width 1) (window-divider-default-places t)) ;; Taken from configuration for the vertico stack: ;; Add prompt indicator to `completing-read-multiple'. ;; We display [CRM], e.g., [CRM,] if the separator is a comma. (defun crm-indicator (args) (cons (format "[CRM%s] %s" (replace-regexp-in-string "\\`\\[.*?]\\*\\|\\[.*?]\\*\\'" "" crm-separator) (car args)) (cdr args))) (advice-add #'completing-read-multiple :filter-args #'crm-indicator) (use-package recentf :hook (after-init . recentf-mode) :custom (recentf-max-menu-items 25) (recentf-save-file "~/.config/emacs/recentf")) (use-package bookmark :defer t :custom (bookmark-default-file "~/.config/emacs/bookmarks")) ;; Unfill commands (defun unfill-paragraph () "Takes a multi-line paragraph and makes it into a single line of text." (interactive) (let ((fill-column (point-max))) (fill-paragraph nil))) (global-set-key (kbd "M-Q") #'unfill-paragraph) ;; Remember my position in files (use-package saveplace :hook (after-init . save-place-mode)) ;; Disable disabled commands (setq disabled-command-function nil) ;; Don't save changes in the customize interface (use-package cus-edit :custom (custom-file (make-temp-file "custom"))) ;; Scroll along with text in compilation mode, and stop scrolling at the first error. (use-package compile :defer t :custom (compilation-scroll-output 'first-error)) ;; Don't advertise gnu on startup (setq inhibit-startup-echo-area-message "noa") ;; #userfreedom ;; Better buffer naming (use-package uniquify :custom (uniquify-after-kill-buffer-p t) (uniquify-buffer-name-style 'forward) (uniquify-ignore-buffers-re "^\\*") (uniquify-separator "/")) ;; Emacs server ;; (unless (server-running-p) (server-start))) ;; Better support for long lines. (use-package so-long :hook (after-init . global-so-long-mode)) ;; Automatically revert buffers when they change on disk. This doesn't apply to tramp. (use-package autorevert :hook (after-init . global-auto-revert-mode) :custom (global-auto-revert-non-file-buffers t)) (use-package vc-hooks :custom (vc-follow-symlinks 'ask)) ;; Minibuffer candidate completion ;; Display completion candidates vertically (use-package vertico :hook (after-init . vertico-mode) :custom (vertico-resize nil) ;; don't shrink when there are less candidates ;; (vertico-group-format #("%s " 0 3 (face vertico-group-title))) ;; Don't put a vertical line across group titles ) ;; Interact with vertico with the mouse. (use-package vertico-mouse :after vertico :custom (vertico-mouse-mode t)) ;; More comfortable directory navigation (use-package vertico-directory :after vertico :bind (:map vertico-map ("RET" . vertico-directory-enter) ("" . vertico-directory-delete-char) ("C-" . vertico-directory-delete-word)) ;; If i type ~/ etc in a find-file prompt, get rid of the preceding directory names for a cleaner look. :hook (rfn-eshadow-update-overlay . vertico-directory-tidy)) ;; Prefix the current candidate with “» ”. From ;; https://github.com/minad/vertico/wiki#prefix-current-candidate-with-arrow (advice-add #'vertico--format-candidate :around (lambda (orig cand prefix suffix index _start) (setq cand (funcall orig cand prefix suffix index _start)) (concat (if (= vertico--index index) (propertize "» " 'face 'vertico-current) " ") cand))) ;; Annotations for completing-read (use-package marginalia :defer t :hook (after-init . marginalia-mode) ;; :custom ;; (marginalia-mode t) ) ;; Basic matches candidates with the same text before the point, and the text after the point as a substring. ;; Orderless takes any number of space separated components and displays candidates that much every component in any order. ;; I don't actually know if these make any difference when i've specified a different completion style. (use-package minibuffer :custom (read-file-name-completion-ignore-case t)) (use-package orderless :after minibuffer :custom (completion-styles '(orderless basic)) (completion-category-overrides '((file (styles basic partial-completion))))) ;; History (use-package savehist :custom (savehist-file "~/.config/emacs/savehist") (savehist-additional-variables '(kill-ring command-history set-variable-value-history custom-variable-history query-replace-history read-expression-history minibuffer-history read-char-history face-name-history bookmark-history file-name-history)) :hook (after-init . savehist-mode)) (use-package consult :defer t ;; :commands (consult-complete-in-region) :bind ( ;; ([remap switch-to-buffer] . consult-buffer) ([remap yank-pop] . consult-yank-pop) ([remap goto-line] . consult-goto-line) ;; ([remap imenu] . consult-imenu) ;; ([remap info] . consult-info) ([remap repeat-complex-command] . consult-complex-command) ([remap bookmark-jump] . consult-bookmark)) ;; :custom ;; Use consult for completion at point ;; (completion-in-region-function 'consult-completion-in-region) ) ;; Some settings for nicer completion with the default emacs completion buffer. I don't use this, because i use vertico. ;; (setopt completion-auto-help 'lazy ;; completion-auto-select 'second-tab ;; completion-show-help nil ;; completions-sort nil ;; completions-header-format nil) ;; Completion styles ;; When given a prompt to select from a list of candidates, there are quite a lot of things we can tweak to improve the experience. ;; Make leading whitespace a uniform width, so indentation still works with proportional fonts (use-package elastic-indent :disabled t :hook (prog-mode . elastic-indent-mode)) ;; Change the width of tab characters within lines to make subsequent lines form a table-like layout. (use-package elastic-table :disabled t :hook (prog-mode-hook . elastic-table-mode)) ;; Indenting lisp with tabs is horrible. H/t acdw (defvar space-indent-modes '(emacs-lisp-mode lisp-interaction-mode lisp-mode scheme-mode python-mode) "Modes to indent with spaces, not tabs.") (add-hook 'prog-mode-hook (defun indent-tabs-mode-maybe () (setq indent-tabs-mode (if (apply #'derived-mode-p space-indent-modes) nil t)))) ;; Make sentence navigation commands work for people who are wrong ;; NOTE: paragraphs does not provide itself (use-package paragraphs :disabled t :custom (sentence-end-double-space nil)) ;; If i write a script, i will always run chmod +x after saving it. This command means i don't have to do that. (add-hook 'after-save-hook #'executable-make-buffer-file-executable-if-script-p) ;; Zap up to char (global-set-key (kbd "M-z") 'zap-up-to-char) ;; Insert date and time at point ;; Sometimes it's useful to be able to add a timestamp. I use this for notes. Use the same binding as notepad.exe. (defun noa/insert-date (&optional time) "Insert the current date into the buffer. With prefix argument TIME, also add the current time." (interactive "P") (if time (insert (format-time-string "[%Y-%m-%d %H:%M]")) (insert (format-time-string "[%Y-%m-%d]")))) (defun noa/insert-datetime () (interactive) (noa/insert-date t)) (global-set-key (kbd "") 'noa/insert-date-time) ;; Improve incremental search (use-package isearch :bind (:map isearch-mode-map ("" . noa/isearch-done-goto-start) ; always put point at the beginning of the match ("C-g" . isearch-cancel) ; always quit on C-g ("C-o" . isearch-occur)) :init (defun noa/isearch-done-goto-start (&optional nopush edit) "End isearch at the start of the match." (interactive) (funcall #'isearch-done nopush edit) (when isearch-forward (goto-char isearch-other-end))) :custom (isearch-lax-whitespace t) (isearch-lazy-count t) (isearch-allow-motion t) (isearch-repeat-on-direction-change t) (isearch-wrap-pause 'no)) ;; Make window management commands easier to press (global-set-key (kbd "M-o") 'other-window) (global-set-key (kbd "M-1") 'delete-other-windows) (global-set-key (kbd "M-2") 'split-window-below) (global-set-key (kbd "M-3") 'split-window-right) (global-set-key (kbd "M-0") 'delete-window) (global-set-key (kbd "C-x k") 'kill-current-buffer) (defun snarf-song (url) (interactive "sYoutube url:") (async-shell-command (concat "yt-dlp -x --audio-format=mp3 -o " (shell-quote-argument "~/media/music/%(title)s [%(id)s].%(ext)s") " " (shell-quote-argument url)))) ;;; Email ;; I keep coming back to rmail, despite its many, many warts. ;; Currently i fetch mail into Spool.mbox with fdm, then rmail moves it into Inbox.mbox. (use-package rmail :commands (rmail) :custom (rmail-primary-inbox-list '("~/Documents/Library/Mail.new/Spool.mbox")) (rmail-file-name "~/Documents/Library/Mail.new/Inbox.mbox") (rmail-user-mail-address-regexp (rx "noa@noa.pub")) (rmail-mime-prefer-html nil) (rmail-mime-attachment-dirs-alist '(("" "~/media"))) (rmail-displayed-headers (rx bol (or "To" "Cc" "From" "Date" "Subject") ":")) (rmail-delete-after-output t) (rmail-default-file "~/Documents/Library/Mail/Archive.mbox") (mail-dont-reply-to-names rmail-user-mail-address-regexp) (rmail-display-summary nil) (rmail-redisplay-summary t) (rmail-summary-line-count-flag nil) ;; :hook ;; ((rmail-show-message . visual-line-fill-column-mode)) ) (use-package message :defer t :init (defun noa/message-default-headers () (format "Fcc: ~/Documents/Library/Mail/outbox/%s.mbox" (format-time-string "%Y-%m"))) :custom (message-default-headers #'noa/message-default-headers) (message-fill-column nil) ;; Don't enable auto-fill (user-full-name "noa") (user-mail-address "noa@noa.pub") (message-signature t) (message-signature-file "~/.config/signature") (message-send-mail-function 'message-send-mail-with-sendmail) (sendmail-program (executable-find "msmtpq")) (message-sendmail-extra-arguments '("--read-envelope-from")) (message-sendmail-envelope-from 'header) (message-kill-buffer-on-exit t) (message-sendmail-f-is-evil t) (message-forward-as-mime t) (message-interactive t) (message-auto-save-directory "~/Documents/Library/Mail/drafts")) ;; Environment variables (setenv "PAGER" "cat") (setenv "TERM" "dumb") (setenv "NO_COLOR") (setenv "GPG_AGENT_INFO" nil) ;; Dictionary ;; Emacs has built in support for interfacing with dictd. With dictd and some dictionaries installed on debian, this works fine out of the box. ;; Unfortunately, dictionaries in this format tend to be hard wrapped and there isn't a lot of coverage outside of english (use-package dictionary :defer t :custom (dictionary-search-interface nil)) ;;; Bibliography management ;; TODO: update this to fit with the new single org file notes system. This way should be easier than the previous method i think. (use-package ebib :defer t :custom (ebib-bibtex-dialect 'biblatex) (ebib-index-columns '(("Author/Editor" 40 t) ("Year" 6 t) ("Title" 50 t) ("Entry Key" 40 t))) ;; Put notes in my markdown notes directory. I still need to find a way to make ebib-notes-name-transform-function return the appropriate date-based filename format. (ebib-notes-storage 'one-file-per-note) (ebib-notes-directory "~/Documents/Notes/References") (ebib-notes-show-note-method 'all) (ebib-notes-file-extension "md") (ebib-notes-template "# %T\n\n%%?") (ebib-file-associations '(("pdf" . "xdg-open") ("ps" . "gv")))) (use-package citar :defer t :commands (citar-insert-citation citar-open-files citar-open-notes) :custom (citar-bibliography '("~/Documents/Library/References.bib")) (citar-library-paths '("~/Documents/Library/Papers")) (citar-notes-paths '("~/Documents/Notes")) ) (use-package citar-org :after oc :custom (org-cite-insert-processor 'citar) (org-cite-follow-processor 'citar) (org-cite-activate-processor 'citar)) (use-package bibtex :defer t :custom (bibtex-dialect 'biblatex) (bibtex-entry-format '(opts-or-alts page-dashes required-fields numerical-fields whitespace last-comma delimiters unify-case sort-fields)) (bibtex-field-delimiters 'braces) (bibtex-entry-delimiters 'braces) ;; Use one name, appending ETAL if there is more than one author ;; The name should be all caps (bibtex-autokey-names 1) (bibtex-autokey-name-case-convert-function 'upcase) (bibtex-autokey-additional-names "ETAL") ;; Follow this with the full year ;; Probably don't need more than two digits actually (bibtex-autokey-name-year-separator "-") (bibtex-autokey-year-length 4) ;; Follow this with initials of the title (bibtex-autokey-year-title-separator "-") (bibtex-autokey-titlewords t) (bibtex-autokey-titleword-length -1) ;; One character (bibtex-autokey-titleword-separator "") (bibtex-autokey-titleword-case-convert-function 'upcase)) (use-package biblio :disabled t :ensure t :defer t :custom (biblio-bibtex-use-autokey t) (biblio-download-directory "~/Documents/Library/Papers")) (defun noa/yank-buffer-file-name () (interactive) (when (buffer-file-name) (kill-new (file-name-nondirectory (buffer-file-name))))) (use-package org :defer t :init ;; Repurpose underline syntax for cloze deletion face (defface my-cloze '((t . (:box t))) "Cloze face for Inline-Anki") (setq org-emphasis-alist '(("*" bold) ("/" italic) ("_" my-cloze) ;; new ("=" org-verbatim verbatim) ("~" org-code verbatim) ("+" (:strike-through t)))) :custom (org-agenda-files '("~/Documents/Notes.org" "~/Documents/Notes/")) (org-replace-disputed-keys t) (org-support-shift-select 'always) ;; Still refuses to fix on timestamps :/ (org-log-done 'time) (org-pretty-entities t) (org-startup-with-inline-images t) (org-image-actual-width '(300)) (org-ellipsis " [+]") (org-insert-heading-respect-content t) (org-fontify-done-headline nil) (org-fontify-todo-headline nil) (org-fontify-whole-heading-line t) (org-src-fontify-natively t) (org-src-tab-acts-natively t) (org-edit-src-content-indentation 0) (org-use-sub-superscripts '{}) :hook ((org-mode . font-lock-mode)) ) (add-hook 'text-mode-hook (lambda () (setq-local line-spacing 0.1))) (use-package oc :after org :custom (org-cite-global-bibliography '("~/Documents/Library/References.bib")) (org-cite-export-processors '((beamer csl) (latex csl) (t csl)))) (use-package oc-csl :after oc :custom (org-cite-csl-styles-dir "~/Documents/Library/CSL/Styles") (org-cite-csl-locales-dir "~/Documents/Library/CSL/Locales")) ;; Not working how i want (use-package org-capture :bind ("C-c c" . org-capture) :custom (org-capture-templates '(("d" "Today's diary" entry (file+headline "~/Documents/Notes.org" "Diary") "** %u\n%?")))) ;; See https://llazarek.github.io/blog/2018/07/organization-with-org-mode.html ;; for configuring the org agenda (use-package inline-anki :defer t :after org :load-path "~/.config/emacs/site-lisp/inline-anki" :config (add-to-list 'org-structure-template-alist '("f" . "flashcard"))) (use-package ctrlj :load-path "~/Documents/Projects/2024-10-08 Ctrlj" :init (global-unset-key (kbd "C-j")) :bind* (("" . ctrlj/open-note) ("C-j C-j" . ctrlj/open-note) ;; ("C-j C-n" . ctrlj/new-note) ("C-j C-l" . ctrlj/insert-link-to-note) ("C-j C-d" . ctrlj/open-todays-diary) ("C-j C-a" . ctrlj/view-agenda) ("C-j C-o" . ctrlj/jump-to-other-related-note))) ;; Experimental website generator (use-package ox-hugo :disabled t :ensure t :after ox) (defun noa/consult-rg-notes () (interactive) (consult-ripgrep "~/Documents/Notes")) (global-set-key (kbd "C-j C-s") #'noa/consult-rg-notes) (use-package emms :disabled t :config (require 'emms-setup) (require 'emms-info-metaflac) (require 'emms-info-mp3info) (require 'emms-info-ogginfo) (emms-all) (emms-default-players) (setq emms-source-file-default-directory "~/Music/") (setq emms-browser-covers 'emms-browser-cache-thumbnail-async) (setq emms-playlist-default-major-mode 'emms-playlist-mode) (setq emms-track-description-function 'emacs-init/emms-track-description) (add-to-list 'emms-info-functions 'emms-info-libtag) (add-to-list 'emms-info-functions 'emms-info-mp3info) (add-to-list 'emms-info-functions 'emms-info-ogginfo) (global-set-key (kbd "C-c e p") 'emms-playlist-mode-go) (global-set-key (kbd "C-c e r") 'emms-toggle-repeat-playlist) (global-set-key (kbd "C-c e s") 'emms-toggle-random-playlist)) ;; Experiment with embark (use-package embark :bind (("s-SPC" . embark-act) ([remap describe-bindings] . embark-bindings)) :init (setq prefix-help-command #'embark-prefix-help-command)) (use-package embark-consult :after (embark consult) :hook (embark-collect-mode . consult-preview-at-point-mode)) (use-package pdf-tools :when (display-graphic-p) :magic ("%PDF" . pdf-view-mode) :config (pdf-tools-install :no-query)) ;; Common lisp development (use-package sly :disabled t :if (executable-find "sbcl") :ensure t :commands 'sly :custom ((inferior-lisp-program (executable-find "sbcl")) (common-lisp-hyperspec-root "file:///usr/share/doc/hyperspec/")) :mode ((rx (or ".lisp" ".cl") eos) . common-lisp-mode)) ;; Write url to text file (defvar noa/record-url-file "~/Documents/Library/urls") (defun noa/record-url (url &rest args) "An alternative browser function that appends the url to a file. We do not pay attention to any arguments." (write-region (concat url "\n") nil noa/record-url-file 'append)) (defvar note/directory "~/Documents/Notes" "The directory in which notes are stored.") (defvar note/file-ending "md" "The file ending for new notes.") (defun note/new (&optional other-window) (interactive "P") (let* ((uid (format-time-string "%Y-%m-%d-%H%M%S")) (note (concat note/directory "/" uid "." note/file-ending))) (if other-window (progn (insert "[[./" uid ".org]]") (find-file-other-window note)) (find-file note)) )) (use-package ediff :defer t :custom (ediff-window-setup-function 'ediff-setup-windows-plain) (ediff-split-window-function 'split-window-horizontally)) (use-package proced :defer t :custom (proced-auto-update-flag t) (proced-auto-update-interval 1) (proced-enable-color-flag nil) (proced-show-remote-processes t)) ;; (profiler-stop)