From b04e50f694be0e31d0cb2507f43a429ab8453d7a Mon Sep 17 00:00:00 2001 From: J S Date: Fri, 13 Oct 2023 21:48:58 -0400 Subject: [PATCH] feat[ALL] First commit --- config.el | 702 ++++++++++++++++++++ config.org | 953 +++++++++++++++++++++++++++ custom.el | 18 + emacs.png | Bin 0 -> 24692 bytes images/example.svg | 90 +++ init.el | 196 ++++++ packages.el | 79 +++ snippets/org-mode/" #'bash) + +(add-hook 'term-mode-hook 'hide-mode-line-mode) + +(use-package! sage-shell-mode + :defer) + +;; Ob-sagemath supports only evaluating with a session. +(setq org-babel-default-header-args:sage '((:session . t) + (:results . "output"))) + +;; C-c c for asynchronous evaluating (only for SageMath code blocks). +(with-eval-after-load "org" + (define-key org-mode-map (kbd "C-c c") 'ob-sagemath-execute-async)) + +(map! :leader + :desc "The Emacs Calculator" + "C" #'calc) + +(defun fava () + (interactive) + (async-shell-command "flatpak run org.gnome.gitlab.johannesjh.favagtk")) +(map! :leader + :desc "Start favagtk" + "r b" #'fava) + +(use-package! ob-mermaid) + +(use-package! ob-svgbob) +(setq org-svgbob-executable "svgbob_cli") + +(setq org-babel-svgbob--parameters + '(:background transparent + )) + +(defun current-date () (interactive) + (shell-command-to-string " bash -c 'echo -n $(date +%Y-%m-%d)'")) + (defun insert-current-date () (interactive) + (insert (current-date))) + +(map! :leader + :desc "Insert the current date into the buffer" + "i d" #'insert-current-date) + +(use-package! age + :ensure t + :demand t + :custom + (age-program "age") + (age-default-identity "~/.age/personal") + (age-default-recipient "~/.age/personal.pub") + :config + (age-file-enable)) + +(setq org-confirm-babel-evaluate t) +(setq org-link-shell-confirm-function t) +(setq org-link-elisp-confirm-function t) +(setq enable-local-variables t) +(setq enable-local-eval 'maybe) + +(after! org-roam +(defun vulpea-project-p () + "Return non-nil if current buffer has any todo entry. +TODO entries marked as done are ignored, meaning the this +function returns nil if current buffer contains only completed +tasks." + (seq-find ; (3) + (lambda (type) + (eq type 'todo)) + (org-element-map ; (2) + (org-element-parse-buffer 'headline) ; (1) + 'headline + (lambda (h) + (org-element-property :todo-type h))))) + +(defun vulpea-project-update-tag () + "Update PROJECT tag in the current buffer." + (when (and (not (active-minibuffer-window)) + (vulpea-buffer-p)) + (save-excursion + (goto-char (point-min)) + (let* ((tags (vulpea-buffer-tags-get)) + (original-tags tags)) + (if (vulpea-project-p) + (setq tags (cons "hastodos" tags)) + (setq tags (remove "hastodos" tags))) + + ;; cleanup duplicates + (setq tags (seq-uniq tags)) + + ;; update tags if changed + (when (or (seq-difference tags original-tags) + (seq-difference original-tags tags)) + (apply #'vulpea-buffer-tags-set tags)))))) + +(defun vulpea-buffer-p () + "Return non-nil if the currently visited buffer is a note." + (and buffer-file-name + (string-prefix-p + (expand-file-name (file-name-as-directory org-roam-directory)) + (file-name-directory buffer-file-name)))) + +(defun vulpea-project-files () + "Return a list of note files containing 'hastodos' tag." ; + (seq-uniq + (seq-map + #'car + (org-roam-db-query + [:select [nodes:file] + :from tags + :left-join nodes + :on (= tags:node-id nodes:id) + :where (like tag (quote "%\"hastodos\"%"))])))) + +(defun vulpea-agenda-files-update (&rest _) + "Update the value of `org-agenda-files'." + (setq org-agenda-files (vulpea-project-files))) + +(add-hook 'find-file-hook #'vulpea-project-update-tag) +(add-hook 'before-save-hook #'vulpea-project-update-tag) + +(advice-add 'org-agenda :before #'vulpea-agenda-files-update) +(advice-add 'org-todo-list :before #'vulpea-agenda-files-update) + +;; functions borrowed from `vulpea' library +;; https://github.com/d12frosted/vulpea/blob/6a735c34f1f64e1f70da77989e9ce8da7864e5ff/vulpea-buffer.el + +(defun vulpea-buffer-tags-get () + "Return filetags value in current buffer." + (vulpea-buffer-prop-get-list "filetags" "[ :]")) + +(defun vulpea-buffer-tags-set (&rest tags) + "Set TAGS in current buffer. +If filetags value is already set, replace it." + (if tags + (vulpea-buffer-prop-set + "filetags" (concat ":" (string-join tags ":") ":")) + (vulpea-buffer-prop-remove "filetags"))) + +(defun vulpea-buffer-tags-add (tag) + "Add a TAG to filetags in current buffer." + (let* ((tags (vulpea-buffer-tags-get)) + (tags (append tags (list tag)))) + (apply #'vulpea-buffer-tags-set tags))) + +(defun vulpea-buffer-tags-remove (tag) + "Remove a TAG from filetags in current buffer." + (let* ((tags (vulpea-buffer-tags-get)) + (tags (delete tag tags))) + (apply #'vulpea-buffer-tags-set tags))) + +(defun vulpea-buffer-prop-set (name value) + "Set a file property called NAME to VALUE in buffer file. +If the property is already set, replace its value." + (setq name (downcase name)) + (org-with-point-at 1 + (let ((case-fold-search t)) + (if (re-search-forward (concat "^#\\+" name ":\\(.*\\)") + (point-max) t) + (replace-match (concat "#+" name ": " value) 'fixedcase) + (while (and (not (eobp)) + (looking-at "^[#:]")) + (if (save-excursion (end-of-line) (eobp)) + (progn + (end-of-line) + (insert "\n")) + (forward-line) + (beginning-of-line))) + (insert "#+" name ": " value "\n"))))) + +(defun vulpea-buffer-prop-set-list (name values &optional separators) + "Set a file property called NAME to VALUES in current buffer. +VALUES are quoted and combined into single string using +`combine-and-quote-strings'. +If SEPARATORS is non-nil, it should be a regular expression +matching text that separates, but is not part of, the substrings. +If nil it defaults to `split-string-default-separators', normally +\"[ \f\t\n\r\v]+\", and OMIT-NULLS is forced to t. +If the property is already set, replace its value." + (vulpea-buffer-prop-set + name (combine-and-quote-strings values separators))) + +(defun vulpea-buffer-prop-get (name) + "Get a buffer property called NAME as a string." + (org-with-point-at 1 + (when (re-search-forward (concat "^#\\+" name ": \\(.*\\)") + (point-max) t) + (buffer-substring-no-properties + (match-beginning 1) + (match-end 1))))) + +(defun vulpea-buffer-prop-get-list (name &optional separators) + "Get a buffer property NAME as a list using SEPARATORS. +If SEPARATORS is non-nil, it should be a regular expression +matching text that separates, but is not part of, the substrings. +If nil it defaults to `split-string-default-separators', normally +\"[ \f\t\n\r\v]+\", and OMIT-NULLS is forced to t." + (let ((value (vulpea-buffer-prop-get name))) + (when (and value (not (string-empty-p value))) + (split-string-and-unquote value separators)))) + +(defun vulpea-buffer-prop-remove (name) + "Remove a buffer property called NAME." + (org-with-point-at 1 + (when (re-search-forward (concat "\\(^#\\+" name ":.*\n?\\)") + (point-max) t) + (replace-match "")))) + + (setq org-agenda-files (vulpea-project-files))) + +(setq org-log-done 'time) +(after! org-mode + (setq org-log-done 'time) + (setq org-archive-location "~/org/archive.org") + (add-to-list 'org-tags-exclude-from-inheritance 'hastodos) + (setq org-hide-emphasis-markers nil)) + +(setq org-directory "~/org/") +(setq org-roam-directory org-directory) +(setq org-archive-location (concat org-directory "/archive.org::")) + +(setq org-startup-with-inline-images t) + +;; Show images after evaluating code blocks. +(add-hook 'org-babel-after-execute-hook 'org-display-inline-images) + +(after! org + ;; Import ox-latex to get org-latex-classes and other funcitonality + ;; for exporting to LaTeX from org + (use-package! ox-latex + :init + ;; code here will run immediately + :config + ;; code here will run after the package is loaded + (setq org-latex-pdf-process + '("pdflatex -interaction nonstopmode -output-directory %o %f" + "bibtex %b" + "pdflatex -interaction nonstopmode -output-directory %o %f" + "pdflatex -interaction nonstopmode -output-directory %o %f")) + (setq org-latex-with-hyperref nil) ;; stop org adding hypersetup{author..} to latex export + ;; (setq org-latex-prefer-user-labels t) + + ;; deleted unwanted file extensions after latexMK + (setq org-latex-logfiles-extensions + (quote ("lof" "lot" "tex~" "aux" "idx" "log" "out" "toc" "nav" "snm" "vrb" "dvi" "fdb_latexmk" "blg" "brf" "fls" "entoc" "ps" "spl" "bbl" "xmpi" "run.xml" "bcf" "acn" "acr" "alg" "glg" "gls" "ist"))) + + (unless (boundp 'org-latex-classes) + (setq org-latex-classes nil)))) + +(setq org-latex-to-pdf-process + '("xelatex -interaction nonstopmode %f" + "xelatex -interaction nonstopmode %f")) ;; for multiple passes + +(setq-default org-html-with-latex `dvisvgm) +(setq org-latex-pdf-process + '("latexmk -pdflatex='pdflatex -interaction nonstopmode' -pdf -bibtex -f %f")) + + + +(unless (boundp 'org-latex-classes) + (setq org-latex-classes nil)) + +(add-to-list 'org-latex-classes + '("ethz" + "\\documentclass[a4paper,11pt,titlepage]{memoir} + \\usepackage[utf8]{inputenc} + \\usepackage[T1]{fontenc} + \\usepackage{fixltx2e} + \\usepackage{graphicx} + \\usepackage{longtable} + \\usepackage{float} + \\usepackage{wrapfig} + \\usepackage{rotating} + \\usepackage[normalem]{ulem} + \\usepackage{amsmath} + \\usepackage{textcomp} + \\usepackage{marvosym} + \\usepackage{wasysym} + \\usepackage{amssymb} + \\usepackage{hyperref} + \\usepackage{mathpazo} + \\usepackage{color} + \\usepackage{enumerate} + \\definecolor{bg}{rgb}{0.95,0.95,0.95} + \\tolerance=1000 + [NO-DEFAULT-PACKAGES] + [PACKAGES] + [EXTRA] + \\linespread{1.1} + \\hypersetup{pdfborder=0 0 0}" + ("\\chapter{%s}" . "\\chapter*{%s}") + ("\\section{%s}" . "\\section*{%s}") + ("\\subsection{%s}" . "\\subsection*{%s}") + ("\\subsubsection{%s}" . "\\subsubsection*{%s}") + ("\\paragraph{%s}" . "\\paragraph*{%s}") + ("\\subparagraph{%s}" . "\\subparagraph*{%s}"))) + + +(add-to-list 'org-latex-classes + '("article" + "\\documentclass[11pt,a4paper]{article} + \\usepackage[utf8]{inputenc} + \\usepackage[T1]{fontenc} + \\usepackage{fixltx2e} + \\usepackage{graphicx} + \\usepackage{longtable} + \\usepackage{float} + \\usepackage{wrapfig} + \\usepackage{rotating} + \\usepackage[normalem]{ulem} + \\usepackage{amsmath} + \\usepackage{textcomp} + \\usepackage{marvosym} + \\usepackage{wasysym} + \\usepackage{amssymb} + \\usepackage{hyperref} + \\usepackage{mathpazo} + \\usepackage{color} + \\usepackage{enumerate} + \\definecolor{bg}{rgb}{0.95,0.95,0.95} + \\tolerance=1000 + [NO-DEFAULT-PACKAGES] + [PACKAGES] + [EXTRA] + \\linespread{1.1} + \\hypersetup{pdfborder=0 0 0}" + ("\\section{%s}" . "\\section*{%s}") + ("\\subsection{%s}" . "\\subsection*{%s}") + ("\\subsubsection{%s}" . "\\subsubsection*{%s}") + ("\\paragraph{%s}" . "\\paragraph*{%s}"))) + + +(add-to-list 'org-latex-classes '("ebook" + "\\documentclass[11pt, oneside]{memoir} + \\setstocksize{9in}{6in} + \\settrimmedsize{\\stockheight}{\\stockwidth}{*} + \\setlrmarginsandblock{2cm}{2cm}{*} % Left and right margin + \\setulmarginsandblock{2cm}{2cm}{*} % Upper and lower margin + \\checkandfixthelayout + % Much more laTeX code omitted + " + ("\\chapter{%s}" . "\\chapter*{%s}") + ("\\section{%s}" . "\\section*{%s}") + ("\\subsection{%s}" . "\\subsection*{%s}"))) + +(defun +org-refresh-latex-images-previews-h () + (dolist (buffer (doom-buffers-in-mode 'org-mode (buffer-list))) + (with-current-buffer buffer + (+org--toggle-inline-images-in-subtree (point-min) (point-max) 'refresh) + (unless (eq org-latex-preview-default-process 'dvisvgm) + (org-clear-latex-preview (point-min) (point-max)) + (org--latex-preview-region (point-min) (point-max)))))) + +(add-hook 'doom-load-theme-hook #'+org-refresh-latex-images-previews-h) + +(defun eww-open-this-file () + (set 'directory (file-name-directory buffer-file-name)) + (set 'filename (file-name-sans-extension buffer-file-name)) + (set 'extension ".html") + (set 'filename (format "%s%s" filename extension)) + (eww-open-file filename) + (evil-window-left) +) + +(defun org-export-and-open-eww () + "Export current file to html and open in eww" + (interactive) + + (org-html-export-to-html) + (if (equal (file-name-extension buffer-file-name) "org") + (eww-open-this-file) + (message "Failed") + ) +) + +(map! :leader + :desc "Export to html and diplay with eww" + "r E" #'org-export-and-open-eww) + +(use-package! org-drill + :defer nil + ) + + (map! :leader + :desc "Start org-drill" + "d d" #'org-drill-directory) + + (map! :leader + :desc "Start org-drill in cram mode" + "d c" #'org-drill-cram) + +(use-package! ob-lilypond) +(setq ly-arrange-mode t) + +(use-package! org-edna) +(org-edna-mode) + +(use-package org-habit + :custom + (org-habit-graph-column 1) + (org-habit-preceding-days 10) + (org-habit-following-days 1) + (org-habit-show-habits-only-for-today nil)) + +(use-package! org-heatmap + :after (org) + :config + (org-heatmap-mode)) + +(setq org-hugo-base-dir "~/org/website/") + +(use-package! citar + :ensure t + :demand t + :custom + (citar-bibliography "~/org/references.bib") + (citar-file-note-extensions '(".org")) + (org-cite-global-bibliography '("~/org/references.bib")) + + + + (org-cite-csl-styles-dir + (expand-file-name "~/Zotero/styles/")) + (org-cite-export-processors + '((t . (csl "apa.csl")) )) + + :hook + (LaTeX-mode . citar-capf-setup) + (org-mode . citar-capf-setup)) +(after! org-mode + (org-cite-global-bibliography '("~/org/references.bib")) + ) + +(citar-org-roam-mode) + +(add-to-list 'org-latex-classes + '("student-apa7" + "\\documentclass[stu]{apa7}" + ("\\section{%s}" . "\\section*{%s}") + ("\\subsection{%s}" . "\\subsection*{%s}") + ("\\subsubsection{%s}" . "\\subsubsection*{%s}") + ("\\paragraph{%s}" . "\\paragraph*{%s}") + ("\\subparagraph{%s}" . "\\subparagraph*{%s}"))) + +(add-to-list 'org-latex-classes + '("student-turabian" + "\\documentclass{turabian-researchpaper}" + ("\\section{%s}" . "\\section*{%s}") + ("\\subsection{%s}" . "\\subsection*{%s}") + ("\\subsubsection{%s}" . "\\subsubsection*{%s}") + ("\\paragraph{%s}" . "\\paragraph*{%s}") + ("\\subparagraph{%s}" . "\\subparagraph*{%s}") + ("\\usepackage{biblatex-chicago}"))) + +(add-to-list 'org-latex-classes + '("student-mla" + "\\documentclass[stu]{mla}" + ("\\section{%s}" . "\\section*{%s}") + ("\\subsection{%s}" . "\\subsection*{%s}") + ("\\subsubsection{%s}" . "\\subsubsection*{%s}") + ("\\paragraph{%s}" . "\\paragraph*{%s}") + ("\\subparagraph{%s}" . "\\subparagraph*{%s}"))) + + ;; org-latex-compilers = ("pdflatex" "xelatex" "lualatex"), which are the possible values for %latex +(setq org-latex-pdf-process '("LC_ALL=en_US.UTF-8 latexmk -f -pdf -%latex -shell-escape -interaction=nonstopmode -output-directory=%o %f" )) + +(use-package! engrave-faces) +(setq org-latex-listings 'engraved) + +(use-package! org-roam + :after md-roam + :init (setq org-roam-directory "~/org/")) :custom + +(after! org-roam + :ensure t + :custom + (setq org-roam-capture-templates + '( + ("d" "default" plain "%?" + :target (file+head "%<%Y%m%d-%H%M%S>.org" + "#+TITLE: ${title}\n#+HTML_HEAD: \n") + :unnarrowed t) + + ("s" "school" plain "%?" + :target (file+head "%<%Y%m%d-%H%M%S>.org" +"#+TITLE: ${title} +#+LATEX_CLASS: student-apa7 +#+LATEX_OPTIONS: stu,hidelinks +#+LATEX_HEADER: \\course{} +#+LATEX_HEADER:\\authorsnames{Judah Sotomayor} +#+LATEX_HEADER: \\authorsaffiliations{} +#+LATEX_HEADER: \\professor{} +#+LATEX_HEADER: \\usepackage{times} +#+LATEX_HEADER: \\duedate{} +#+OPTIONS: toc:nil\n") + :unnarrowed t) + + ("c" "encrypted" plain "%?" + :target (file+head "%<%Y%m%d-%H%M%S>.sec.org.age" + "#+TITLE: ${title}\n#+FILETAGS: :secure:noexport:\n#+HTML_HEAD: \n\n\n* No Export Below This Line") + :unnarrowed t) + + ("w" "website" plain "%?" + :target (file+head "website/org/%<%Y%m%d-%H%M%S>.org" + "#+TITLE: ${title}\n") + :unnarrowed t)))) + +(after! org-roam (map! :leader (:prefix ("r" . "roam") + + :desc "Search for a node in org-roam files" + "f" #'org-roam-node-find + + :desc "Insert the link to a node from org-roam" + "i" #'org-roam-node-insert + + :desc "Rescan org-roam files and add new nodes to database" + "s" #'org-roam-db-sync + + :desc "Jump to a random node" + "r" #'org-roam-node-random + + :desc "Capture inside an existing or new node" + "c" #'org-roam-capture + + :desc "Go to or create a daily note" + "d" #'org-roam-dailies-goto-today + + :desc "Seek a daily note" + "D" #'org-roam-dailies-goto-date + + :desc "Extract a subtree to a new file" + "e" #'org-roam-extract-subtree)) + + (map! + :desc "Alternative keybind to insert a roam link while in insert mode" + :i "M-[" #'org-roam-node-insert)) + +(use-package! websocket + :after org-roam) + +(use-package! org-roam-ui + :after org-roam ;; or :after org +;; 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)) + +(after! org-roam-ui (map! :leader (:prefix ("r" . "roam") (:prefix ("u" . "roam-ui") + + :desc "Focus the current node in org-roam-ui view" + "f" #'org-roam-ui-node-zoom + + :desc "Focus the current node's local graph in org-roam-ui view" + "l" #'org-roam-ui-node-local + + :desc "Begin org-roam ui mode" + "u" #'open-org-roam-ui + + )))) + +(defun open-org-roam-ui () + (interactive) + (org-roam-ui-mode) + (async-shell-command "surf http://localhost:35901/")) + +(setq browse-url-browser-function 'browse-url-generic + browse-url-generic-program "surf") + + '(org-file-apps + (quote + ((auto-mode . emacs) + ("\\.mm\\'" . default) + ("\\.x?html?\\'" . "surf %s") + ("\\.pdf\\'" . default)))) + +(after! org-roam +(setq org-roam-dailies-capture-templates + `(("d" "default" entry + "* %?" + :target (file+head "%<%Y-%m-%d>.sec.org.age" + "#+title: %<%Y-%m-%d>\n"))))) + +(require 'cl-lib) + +(defun org-global-props-key-re (key) + "Construct a regular expression matching key and an optional plus and eating the spaces behind. +Test for existence of the plus: (match-beginning 1)" + (concat "^" (regexp-quote key) "\\(\\+\\)?[[:space:]]+")) + +(defun org-global-props (&optional buffer) + "Get the plists of global org properties of current buffer." + (with-current-buffer (or buffer (current-buffer)) + (org-element-map (org-element-parse-buffer) 'keyword (lambda (el) (when (string-equal (org-element-property :key el) "PROPERTY") (nth 1 el)))))) + +(defun org-global-prop-value (key) + "Get global org property KEY of current buffer. +Adding up values for one key is supported." + (let ((key-re (org-global-props-key-re key)) + (props (org-global-props)) + ret) + (cl-loop with val for prop in props + when (string-match key-re (setq val (plist-get prop :value))) do + (setq + val (substring val (match-end 0)) + ret (if (match-beginning 1) + (concat ret " " val) + val))) + ret)) + +(after! org + (use-package! ox-extra + :config + (ox-extras-activate '(latex-header-blocks ignore-headlines)))) + +(add-to-list 'org-latex-classes + '("altacv" "\\documentclass[10pt,a4paper,ragged2e,withhyper]{altacv} +\\usepackage[rm]{roboto} +\\usepackage[defaultsans]{lato} +\\usepackage{paracol} +[NO-DEFAULT-PACKAGES] +[NO-PACKAGES] +% Change the page layout if you need to +\\geometry{left=1.25cm,right=1.25cm,top=1.5cm,bottom=1.5cm,columnsep=1.2cm} + +% Use roboto and lato for fonts +\\renewcommand{\\familydefault}{\\sfdefault} + +% Change the colours if you want to +\\definecolor{SlateGrey}{HTML}{2E2E2E} +\\definecolor{LightGrey}{HTML}{666666} +\\definecolor{DarkPastelRed}{HTML}{450808} +\\definecolor{PastelRed}{HTML}{8F0D0D} +\\definecolor{GoldenEarth}{HTML}{E7D192} + +\\colorlet{name}{black} +\\colorlet{tagline}{black} +\\colorlet{heading}{black} +\\colorlet{headingrule}{black} +\\colorlet{subheading}{black} +\\colorlet{accent}{black} +\\colorlet{emphasis}{SlateGrey} +\\colorlet{body}{LightGrey} + +% Change some fonts, if necessary +\\renewcommand{\\namefont}{\\Huge\\rmfamily\\bfseries} +\\renewcommand{\\personalinfofont}{\\footnotesize} +\\renewcommand{\\cvsectionfont}{\\LARGE\\rmfamily\\bfseries} +\\renewcommand{\\cvsubsectionfont}{\\large\\bfseries} + +% Change the bullets for itemize and rating marker +% for \cvskill if you want to +\\renewcommand{\\itemmarker}{{\\small\\textbullet}} +\\renewcommand{\\ratingmarker}{\\faCircle} +" + + ("\\cvsection{%s}" . "\\cvsection*{%s}") + ("\\cvevent{%s}" . "\\cvevent*{%s}"))) + +(map! :n "g j" #'evil-next-visual-line) +(map! :n "g k" #'evil-previous-visual-line) + +(after! company-mode + (setq company-idle-delay nil)) +(setq company-idle-delay nil) + +(require 'zmq) + +(use-package! exec-path-from-shell) +(after! exec-path-from-shell + (dolist (var '("SSH_AUTH_SOCK" "SSH_AGENT_PID" "GPG_AGENT_INFO")) + (add-to-list 'exec-path-from-shell-variables var)) + (exec-path-from-shell-initialize) + ) diff --git a/config.org b/config.org new file mode 100644 index 0000000..60e3c0f --- /dev/null +++ b/config.org @@ -0,0 +1,953 @@ +#+TITLE: Doom-emacs config +#+AUTHOR: Judah Sotomayor +#+STARTUP: overview + + +Welcome to my configuration! +I hope you enjoy your time here :) +It's not all very well documented, but I have done my best to split everything into a logical order. +Perhaps in 10 years I will still be using it, but who knows. +* Task List +** TODO Reorganize into use-cases rather than packages +* Setting Basics +#+BEGIN_SRC emacs-lisp +(setq tab-always-indent t) +(setq org-roam-directory "~/org/") +#+END_SRC + +* Theme and Font +Set the theme. +/Use something dark/ ++I also prefer relative line numbers because of *evil* mode+ Relative line numbers don't work, because of foling in Org-mode. +#+BEGIN_SRC emacs-lisp +(setq doom-theme 'doom-dark+) +(setq doom-font (font-spec :family "Hack Nerd Font Mono" :size 16 :weight 'medium)) +(setq auto-save-default nil) +#+END_SRC + +** Doom splash screen +I really don't like the widgets, and I think it takes longer to load so I get rid of them +#+BEGIN_SRC emacs-lisp +(remove-hook '+doom-dashboard-functions #'doom-dashboard-widget-shortmenu) +(remove-hook '+doom-dashboard-functions #'doom-dashboard-widget-footer) +#+END_SRC + +Set a sweet splash image +#+BEGIN_SRC emacs-lisp +(setq fancy-splash-image (concat doom-private-dir "emacs.png")) +#+END_SRC + + +* User details +#+BEGIN_SRC emacs-lisp +(setq user-full-name "Judah Sotomayor" + user-mail-address "") +#+END_SRC + +* Evil configuration +I want a non-ESC way to get back to normal mode: +#+BEGIN_SRC emacs-lisp +(map! :desc "Switch to normal mode" "M-c" #'evil-normal-state) +#+END_SRC +#+BEGIN_SRC emacs-lisp + (setq org-pretty-entities 0) +#+END_SRC +* Terminal setup +I like to just use bash: +#+BEGIN_SRC emacs-lisp +(defun bash () + (interactive) + (term "/bin/bash")) +(map! + :desc "Start a bash shell" + "" #'bash) +#+END_SRC + +I don't like the modeline in the terminal. +#+BEGIN_SRC emacs-lisp +(add-hook 'term-mode-hook 'hide-mode-line-mode) +#+END_SRC +* Sage-math +#+BEGIN_SRC emacs-lisp +(use-package! sage-shell-mode + :defer) + +;; Ob-sagemath supports only evaluating with a session. +(setq org-babel-default-header-args:sage '((:session . t) + (:results . "output"))) + +;; C-c c for asynchronous evaluating (only for SageMath code blocks). +(with-eval-after-load "org" + (define-key org-mode-map (kbd "C-c c") 'ob-sagemath-execute-async)) +#+END_SRC +I like to have a shortcut for calc as well, for simpler calculations +#+BEGIN_SRC emacs-lisp +(map! :leader + :desc "The Emacs Calculator" + "C" #'calc) +#+END_SRC +* Beancount +I want to launch favagtk more easily. Let's do that here: +#+BEGIN_SRC emacs-lisp +(defun fava () + (interactive) + (async-shell-command "flatpak run org.gnome.gitlab.johannesjh.favagtk")) +(map! :leader + :desc "Start favagtk" + "r b" #'fava) +#+END_SRC +* Graphing Applications +** Mermaid.js +Mermaid.js requires the mmcli executable from npm. +Mermaid is a tool that allows you to graph many kinds of entities: +- Relationship diagrams +- Flowcharts +- Gantt diagrams +There's other kinds too. +The package on ELPA is perfect. Needs no config, fits right in with Babel. +#+BEGIN_SRC emacs-lisp +(use-package! ob-mermaid) +#+END_SRC + +** SVGBob +SVGBob is an ASCII art renderer. It can do all kinds of nifty things with just a few basic .------./\ +#+BEGIN_SRC emacs-lisp +(use-package! ob-svgbob) +(setq org-svgbob-executable "svgbob_cli") + +(setq org-babel-svgbob--parameters + '(:background transparent + )) +#+END_SRC +* Fun Stuff +* Useful Functions +** Get the date from the shell +I want to grab the current date and put it in the buffer. +Because I sometimes use Fish or another shell, it's good to make sure bash is running the command using the src_bash{`-c`} flag. +#+BEGIN_SRC emacs-lisp +(defun current-date () (interactive) + (shell-command-to-string " bash -c 'echo -n $(date +%Y-%m-%d)'")) + (defun insert-current-date () (interactive) + (insert (current-date))) + +(map! :leader + :desc "Insert the current date into the buffer" + "i d" #'insert-current-date) +#+END_SRC +* Creating Diagrams and graphs +** TODO set default values using org-babel's features for that. + +* Securing Sensitive Files +** Age.el +#+BEGIN_SRC emacs-lisp +(use-package! age + :ensure t + :demand t + :custom + (age-program "age") + (age-default-identity "~/.age/personal") + (age-default-recipient "~/.age/personal.pub") + :config + (age-file-enable)) +#+END_SRC + +** Org-mode security settings +These mostly concern limiting evaluation of code-blocks without confirmation. +The final two lines concern local variables, which may try to evaluate code. + +Emacs has better default values now, so it will ask to evaluate local variables. +#+BEGIN_SRC emacs-lisp +(setq org-confirm-babel-evaluate t) +(setq org-link-shell-confirm-function t) +(setq org-link-elisp-confirm-function t) +(setq enable-local-variables t) +(setq enable-local-eval 'maybe) +#+END_SRC +* Org-mode for a great todo list +** Making the Agenda features more efficient + +#+BEGIN_SRC emacs-lisp :tangle no +(dolist (file (org-roam-list-files)) + (message "processing %s" file) + (with-current-buffer (or (find-buffer-visiting file) + (find-file-noselect file)) + (vulpea-project-update-tag) + (save-buffer))) +#+END_SRC + +#+RESULTS: + + + +Only include files with the hastodos tag. +This section is contributed from [[https://gist.github.com/d12frosted/a60e8ccb9aceba031af243dff0d19b2e][d12frosted]] and use his vulpea.el package's functions. +I ripped out the essentials because I don't want all the other stuff in that package. + + +#+BEGIN_SRC emacs-lisp +(after! org-roam +(defun vulpea-project-p () + "Return non-nil if current buffer has any todo entry. +TODO entries marked as done are ignored, meaning the this +function returns nil if current buffer contains only completed +tasks." + (seq-find ; (3) + (lambda (type) + (eq type 'todo)) + (org-element-map ; (2) + (org-element-parse-buffer 'headline) ; (1) + 'headline + (lambda (h) + (org-element-property :todo-type h))))) + +(defun vulpea-project-update-tag () + "Update PROJECT tag in the current buffer." + (when (and (not (active-minibuffer-window)) + (vulpea-buffer-p)) + (save-excursion + (goto-char (point-min)) + (let* ((tags (vulpea-buffer-tags-get)) + (original-tags tags)) + (if (vulpea-project-p) + (setq tags (cons "hastodos" tags)) + (setq tags (remove "hastodos" tags))) + + ;; cleanup duplicates + (setq tags (seq-uniq tags)) + + ;; update tags if changed + (when (or (seq-difference tags original-tags) + (seq-difference original-tags tags)) + (apply #'vulpea-buffer-tags-set tags)))))) + +(defun vulpea-buffer-p () + "Return non-nil if the currently visited buffer is a note." + (and buffer-file-name + (string-prefix-p + (expand-file-name (file-name-as-directory org-roam-directory)) + (file-name-directory buffer-file-name)))) + +(defun vulpea-project-files () + "Return a list of note files containing 'hastodos' tag." ; + (seq-uniq + (seq-map + #'car + (org-roam-db-query + [:select [nodes:file] + :from tags + :left-join nodes + :on (= tags:node-id nodes:id) + :where (like tag (quote "%\"hastodos\"%"))])))) + +(defun vulpea-agenda-files-update (&rest _) + "Update the value of `org-agenda-files'." + (setq org-agenda-files (vulpea-project-files))) + +(add-hook 'find-file-hook #'vulpea-project-update-tag) +(add-hook 'before-save-hook #'vulpea-project-update-tag) + +(advice-add 'org-agenda :before #'vulpea-agenda-files-update) +(advice-add 'org-todo-list :before #'vulpea-agenda-files-update) + +;; functions borrowed from `vulpea' library +;; https://github.com/d12frosted/vulpea/blob/6a735c34f1f64e1f70da77989e9ce8da7864e5ff/vulpea-buffer.el + +(defun vulpea-buffer-tags-get () + "Return filetags value in current buffer." + (vulpea-buffer-prop-get-list "filetags" "[ :]")) + +(defun vulpea-buffer-tags-set (&rest tags) + "Set TAGS in current buffer. +If filetags value is already set, replace it." + (if tags + (vulpea-buffer-prop-set + "filetags" (concat ":" (string-join tags ":") ":")) + (vulpea-buffer-prop-remove "filetags"))) + +(defun vulpea-buffer-tags-add (tag) + "Add a TAG to filetags in current buffer." + (let* ((tags (vulpea-buffer-tags-get)) + (tags (append tags (list tag)))) + (apply #'vulpea-buffer-tags-set tags))) + +(defun vulpea-buffer-tags-remove (tag) + "Remove a TAG from filetags in current buffer." + (let* ((tags (vulpea-buffer-tags-get)) + (tags (delete tag tags))) + (apply #'vulpea-buffer-tags-set tags))) + +(defun vulpea-buffer-prop-set (name value) + "Set a file property called NAME to VALUE in buffer file. +If the property is already set, replace its value." + (setq name (downcase name)) + (org-with-point-at 1 + (let ((case-fold-search t)) + (if (re-search-forward (concat "^#\\+" name ":\\(.*\\)") + (point-max) t) + (replace-match (concat "#+" name ": " value) 'fixedcase) + (while (and (not (eobp)) + (looking-at "^[#:]")) + (if (save-excursion (end-of-line) (eobp)) + (progn + (end-of-line) + (insert "\n")) + (forward-line) + (beginning-of-line))) + (insert "#+" name ": " value "\n"))))) + +(defun vulpea-buffer-prop-set-list (name values &optional separators) + "Set a file property called NAME to VALUES in current buffer. +VALUES are quoted and combined into single string using +`combine-and-quote-strings'. +If SEPARATORS is non-nil, it should be a regular expression +matching text that separates, but is not part of, the substrings. +If nil it defaults to `split-string-default-separators', normally +\"[ \f\t\n\r\v]+\", and OMIT-NULLS is forced to t. +If the property is already set, replace its value." + (vulpea-buffer-prop-set + name (combine-and-quote-strings values separators))) + +(defun vulpea-buffer-prop-get (name) + "Get a buffer property called NAME as a string." + (org-with-point-at 1 + (when (re-search-forward (concat "^#\\+" name ": \\(.*\\)") + (point-max) t) + (buffer-substring-no-properties + (match-beginning 1) + (match-end 1))))) + +(defun vulpea-buffer-prop-get-list (name &optional separators) + "Get a buffer property NAME as a list using SEPARATORS. +If SEPARATORS is non-nil, it should be a regular expression +matching text that separates, but is not part of, the substrings. +If nil it defaults to `split-string-default-separators', normally +\"[ \f\t\n\r\v]+\", and OMIT-NULLS is forced to t." + (let ((value (vulpea-buffer-prop-get name))) + (when (and value (not (string-empty-p value))) + (split-string-and-unquote value separators)))) + +(defun vulpea-buffer-prop-remove (name) + "Remove a buffer property called NAME." + (org-with-point-at 1 + (when (re-search-forward (concat "\\(^#\\+" name ":.*\n?\\)") + (point-max) t) + (replace-match "")))) + + (setq org-agenda-files (vulpea-project-files))) + #+END_SRC + +** Basic settings +#+BEGIN_SRC emacs-lisp + (setq org-log-done 'time) + (after! org-mode + (setq org-log-done 'time) + (setq org-archive-location "~/org/archive.org") + (add-to-list 'org-tags-exclude-from-inheritance 'hastodos) + (setq org-hide-emphasis-markers nil)) + + (setq org-directory "~/org/") + (setq org-roam-directory org-directory) + (setq org-archive-location (concat org-directory "/archive.org::")) + +#+END_SRC + +** Appearances +*** Deprecated: TODO Keywords +I like to have a few different todo keywords for different sorts of activities. +Purchasing todos: +#+BEGIN_SRC emacs-lisp :tangle no + +(setq org-todo-keywords + '((sequence "PROJ(p)" "|" "COMPLETE") + (type "TICKLE") + (type "DELE") + (type "WAIT") + (sequence "TODO(t)" "|" "DONE") + (sequence "DELEGATED" "VERIFY" "|" "DONE") + (sequence "BUY(b)" "|" "BOUGHT") + )) +(setq org-todo-keyword-faces + '(("TODO" . "salmon1") + ("START" . "spring green" ) + ("DELE" . "gold") + ("TICKLE" . "magenta") + ("WAIT" . "gold") + ("PROJ" . "deep sky blue"))) +#+END_SRC + +These settings aren't very useful for me, as I like default colors and keywords. +*** Deprecated: Settings for org-modern + +#+BEGIN_SRC emacs-lisp :tangle no +(setq org-modern-todo-faces + '(("START" :background "spring green" :foreground "black") + ("DELE" :background "gold" :foreground "black") + ("WAIT" :background "gold" :foreground "black") + ("PROJ" :background "deep sky blue" :foreground "black") + ("TICKLE" :background "magenta" :foreground "black"))) + +(setq org-modern-priority-faces + '((?A :background "salmon1" :foreground "black") + (?B :background "gold" :foreground "black") + (?C :background "spring green" :foreground "black"))) +#+END_SRC + +I currently have org-modern stripped out of my config. +I probably won't need this again, but in case I do I want all my preferences to be there. +*** Images Preferences +We want to show images when loading a file, and also after evaluating code blocks. +#+BEGIN_SRC emacs-lisp +(setq org-startup-with-inline-images t) + +;; Show images after evaluating code blocks. +(add-hook 'org-babel-after-execute-hook 'org-display-inline-images) +#+END_SRC +** Export settings +#+BEGIN_SRC emacs-lisp +(after! org + ;; Import ox-latex to get org-latex-classes and other funcitonality + ;; for exporting to LaTeX from org + (use-package! ox-latex + :init + ;; code here will run immediately + :config + ;; code here will run after the package is loaded + (setq org-latex-pdf-process + '("pdflatex -interaction nonstopmode -output-directory %o %f" + "bibtex %b" + "pdflatex -interaction nonstopmode -output-directory %o %f" + "pdflatex -interaction nonstopmode -output-directory %o %f")) + (setq org-latex-with-hyperref nil) ;; stop org adding hypersetup{author..} to latex export + ;; (setq org-latex-prefer-user-labels t) + + ;; deleted unwanted file extensions after latexMK + (setq org-latex-logfiles-extensions + (quote ("lof" "lot" "tex~" "aux" "idx" "log" "out" "toc" "nav" "snm" "vrb" "dvi" "fdb_latexmk" "blg" "brf" "fls" "entoc" "ps" "spl" "bbl" "xmpi" "run.xml" "bcf" "acn" "acr" "alg" "glg" "gls" "ist"))) + + (unless (boundp 'org-latex-classes) + (setq org-latex-classes nil)))) +#+END_SRC + +#+BEGIN_SRC emacs-lisp +(setq org-latex-to-pdf-process + '("xelatex -interaction nonstopmode %f" + "xelatex -interaction nonstopmode %f")) ;; for multiple passes + +(setq-default org-html-with-latex `dvisvgm) +(setq org-latex-pdf-process + '("latexmk -pdflatex='pdflatex -interaction nonstopmode' -pdf -bibtex -f %f")) + + + +(unless (boundp 'org-latex-classes) + (setq org-latex-classes nil)) + +(add-to-list 'org-latex-classes + '("ethz" + "\\documentclass[a4paper,11pt,titlepage]{memoir} + \\usepackage[utf8]{inputenc} + \\usepackage[T1]{fontenc} + \\usepackage{fixltx2e} + \\usepackage{graphicx} + \\usepackage{longtable} + \\usepackage{float} + \\usepackage{wrapfig} + \\usepackage{rotating} + \\usepackage[normalem]{ulem} + \\usepackage{amsmath} + \\usepackage{textcomp} + \\usepackage{marvosym} + \\usepackage{wasysym} + \\usepackage{amssymb} + \\usepackage{hyperref} + \\usepackage{mathpazo} + \\usepackage{color} + \\usepackage{enumerate} + \\definecolor{bg}{rgb}{0.95,0.95,0.95} + \\tolerance=1000 + [NO-DEFAULT-PACKAGES] + [PACKAGES] + [EXTRA] + \\linespread{1.1} + \\hypersetup{pdfborder=0 0 0}" + ("\\chapter{%s}" . "\\chapter*{%s}") + ("\\section{%s}" . "\\section*{%s}") + ("\\subsection{%s}" . "\\subsection*{%s}") + ("\\subsubsection{%s}" . "\\subsubsection*{%s}") + ("\\paragraph{%s}" . "\\paragraph*{%s}") + ("\\subparagraph{%s}" . "\\subparagraph*{%s}"))) + + +(add-to-list 'org-latex-classes + '("article" + "\\documentclass[11pt,a4paper]{article} + \\usepackage[utf8]{inputenc} + \\usepackage[T1]{fontenc} + \\usepackage{fixltx2e} + \\usepackage{graphicx} + \\usepackage{longtable} + \\usepackage{float} + \\usepackage{wrapfig} + \\usepackage{rotating} + \\usepackage[normalem]{ulem} + \\usepackage{amsmath} + \\usepackage{textcomp} + \\usepackage{marvosym} + \\usepackage{wasysym} + \\usepackage{amssymb} + \\usepackage{hyperref} + \\usepackage{mathpazo} + \\usepackage{color} + \\usepackage{enumerate} + \\definecolor{bg}{rgb}{0.95,0.95,0.95} + \\tolerance=1000 + [NO-DEFAULT-PACKAGES] + [PACKAGES] + [EXTRA] + \\linespread{1.1} + \\hypersetup{pdfborder=0 0 0}" + ("\\section{%s}" . "\\section*{%s}") + ("\\subsection{%s}" . "\\subsection*{%s}") + ("\\subsubsection{%s}" . "\\subsubsection*{%s}") + ("\\paragraph{%s}" . "\\paragraph*{%s}"))) + + +(add-to-list 'org-latex-classes '("ebook" + "\\documentclass[11pt, oneside]{memoir} + \\setstocksize{9in}{6in} + \\settrimmedsize{\\stockheight}{\\stockwidth}{*} + \\setlrmarginsandblock{2cm}{2cm}{*} % Left and right margin + \\setulmarginsandblock{2cm}{2cm}{*} % Upper and lower margin + \\checkandfixthelayout + % Much more laTeX code omitted + " + ("\\chapter{%s}" . "\\chapter*{%s}") + ("\\section{%s}" . "\\section*{%s}") + ("\\subsection{%s}" . "\\subsection*{%s}"))) + +#+END_SRC +*** Fixing dvipng image handling +#+BEGIN_SRC emacs-lisp + +(defun +org-refresh-latex-images-previews-h () + (dolist (buffer (doom-buffers-in-mode 'org-mode (buffer-list))) + (with-current-buffer buffer + (+org--toggle-inline-images-in-subtree (point-min) (point-max) 'refresh) + (unless (eq org-latex-preview-default-process 'dvisvgm) + (org-clear-latex-preview (point-min) (point-max)) + (org--latex-preview-region (point-min) (point-max)))))) + +(add-hook 'doom-load-theme-hook #'+org-refresh-latex-images-previews-h) +#+END_SRC +*** Export Function +#+BEGIN_SRC emacs-lisp +(defun eww-open-this-file () + (set 'directory (file-name-directory buffer-file-name)) + (set 'filename (file-name-sans-extension buffer-file-name)) + (set 'extension ".html") + (set 'filename (format "%s%s" filename extension)) + (eww-open-file filename) + (evil-window-left) +) + +(defun org-export-and-open-eww () + "Export current file to html and open in eww" + (interactive) + + (org-html-export-to-html) + (if (equal (file-name-extension buffer-file-name) "org") + (eww-open-this-file) + (message "Failed") + ) +) +#+END_SRC + +We'll want a handy shortcut for this. +#+BEGIN_SRC emacs-lisp + (map! :leader + :desc "Export to html and diplay with eww" + "r E" #'org-export-and-open-eww) +#+END_SRC +#+RESULTS: +: /home/user/.config/doom/ + +** Org-drill +Set some good keybinds for quick access: +#+BEGIN_SRC emacs-lisp +(use-package! org-drill + :defer nil + ) + + (map! :leader + :desc "Start org-drill" + "d d" #'org-drill-directory) + + (map! :leader + :desc "Start org-drill in cram mode" + "d c" #'org-drill-cram) +#+END_SRC +** ob-lilypond +#+BEGIN_SRC emacs-lisp +(use-package! ob-lilypond) +(setq ly-arrange-mode t) +#+END_SRC +** org-edna +Edna allows better dependency handling for todos and the like. + +#+BEGIN_SRC emacs-lisp +(use-package! org-edna) +(org-edna-mode) +#+END_SRC +** Org-habit +#+BEGIN_SRC emacs-lisp + + (use-package org-habit + :custom + (org-habit-graph-column 1) + (org-habit-preceding-days 10) + (org-habit-following-days 1) + (org-habit-show-habits-only-for-today nil)) + + (use-package! org-heatmap + :after (org) + :config + (org-heatmap-mode)) +#+END_SRC + + + +* Ox-hugo +#+BEGIN_SRC emacs-lisp +(setq org-hugo-base-dir "~/org/website/") +#+END_SRC + +* Crafting a Writing Environment +For writing I like to automate as much as possible. +This means creating an environment that does citations and such /for/ me. +** Automatic Citations with *citar* and *org-cite* +Citar is a sweet little package for managing citations. Right here we'll set it up +We want a general bibliography file, a styles directory, and a default set of styles. +#+BEGIN_SRC emacs-lisp +(use-package! citar + :ensure t + :demand t + :custom + (citar-bibliography "~/org/references.bib") + (citar-file-note-extensions '(".org")) + (org-cite-global-bibliography '("~/org/references.bib")) + + + + (org-cite-csl-styles-dir + (expand-file-name "~/Zotero/styles/")) + (org-cite-export-processors + '((t . (csl "apa.csl")) )) + + :hook + (LaTeX-mode . citar-capf-setup) + (org-mode . citar-capf-setup)) +(after! org-mode + (org-cite-global-bibliography '("~/org/references.bib")) + ) + +(citar-org-roam-mode) +#+END_SRC + +** Scholarly Writing Environment with Org-mode +I like to keep formatting simple. +Let's use a package or two to set a decent document class: +#+BEGIN_SRC emacs-lisp +(add-to-list 'org-latex-classes + '("student-apa7" + "\\documentclass[stu]{apa7}" + ("\\section{%s}" . "\\section*{%s}") + ("\\subsection{%s}" . "\\subsection*{%s}") + ("\\subsubsection{%s}" . "\\subsubsection*{%s}") + ("\\paragraph{%s}" . "\\paragraph*{%s}") + ("\\subparagraph{%s}" . "\\subparagraph*{%s}"))) + +(add-to-list 'org-latex-classes + '("student-turabian" + "\\documentclass{turabian-researchpaper}" + ("\\section{%s}" . "\\section*{%s}") + ("\\subsection{%s}" . "\\subsection*{%s}") + ("\\subsubsection{%s}" . "\\subsubsection*{%s}") + ("\\paragraph{%s}" . "\\paragraph*{%s}") + ("\\subparagraph{%s}" . "\\subparagraph*{%s}") + ("\\usepackage{biblatex-chicago}"))) + +(add-to-list 'org-latex-classes + '("student-mla" + "\\documentclass[stu]{mla}" + ("\\section{%s}" . "\\section*{%s}") + ("\\subsection{%s}" . "\\subsection*{%s}") + ("\\subsubsection{%s}" . "\\subsubsection*{%s}") + ("\\paragraph{%s}" . "\\paragraph*{%s}") + ("\\subparagraph{%s}" . "\\subparagraph*{%s}"))) + + ;; org-latex-compilers = ("pdflatex" "xelatex" "lualatex"), which are the possible values for %latex +(setq org-latex-pdf-process '("LC_ALL=en_US.UTF-8 latexmk -f -pdf -%latex -shell-escape -interaction=nonstopmode -output-directory=%o %f" )) +#+END_SRC + +*** Engraving Faces +Ever wonder why code export sucks with \latex ? Me neither! Let's fix it! +#+BEGIN_SRC emacs-lisp +(use-package! engrave-faces) +(setq org-latex-listings 'engraved) +#+END_SRC +** Zettelkasten environment with org-roam +Org-roam enables features essential to a Zettelkasten such as inter-ID linking. +#+BEGIN_SRC emacs-lisp + (use-package! org-roam + :after md-roam + :init (setq org-roam-directory "~/org/")) :custom +#+END_SRC + +#+BEGIN_SRC emacs-lisp +(after! org-roam + :ensure t + :custom + (setq org-roam-capture-templates + '( + ("d" "default" plain "%?" + :target (file+head "%<%Y%m%d-%H%M%S>.org" + "#+TITLE: ${title}\n#+HTML_HEAD: \n") + :unnarrowed t) + + ("s" "school" plain "%?" + :target (file+head "%<%Y%m%d-%H%M%S>.org" +"#+TITLE: ${title} +#+LATEX_CLASS: student-apa7 +#+LATEX_OPTIONS: stu,hidelinks +#+LATEX_HEADER: \\course{} +#+LATEX_HEADER:\\authorsnames{Judah Sotomayor} +#+LATEX_HEADER: \\authorsaffiliations{} +#+LATEX_HEADER: \\professor{} +#+LATEX_HEADER: \\usepackage{times} +#+LATEX_HEADER: \\duedate{} +#+OPTIONS: toc:nil\n") + :unnarrowed t) + + ("c" "encrypted" plain "%?" + :target (file+head "%<%Y%m%d-%H%M%S>.sec.org.age" + "#+TITLE: ${title}\n#+FILETAGS: :secure:noexport:\n#+HTML_HEAD: \n\n\n* No Export Below This Line") + :unnarrowed t) + + ("w" "website" plain "%?" + :target (file+head "website/org/%<%Y%m%d-%H%M%S>.org" + "#+TITLE: ${title}\n") + :unnarrowed t)))) +#+END_SRC + +*** Keybinds +Org-roam has many commands, of which I have bound the most important below. +This entails creating a local leader. +I use =r= for this purpose. It is close and goes well with *roam*. +#+BEGIN_SRC emacs-lisp +(after! org-roam (map! :leader (:prefix ("r" . "roam") + + :desc "Search for a node in org-roam files" + "f" #'org-roam-node-find + + :desc "Insert the link to a node from org-roam" + "i" #'org-roam-node-insert + + :desc "Rescan org-roam files and add new nodes to database" + "s" #'org-roam-db-sync + + :desc "Jump to a random node" + "r" #'org-roam-node-random + + :desc "Capture inside an existing or new node" + "c" #'org-roam-capture + + :desc "Go to or create a daily note" + "d" #'org-roam-dailies-goto-today + + :desc "Seek a daily note" + "D" #'org-roam-dailies-goto-date + + :desc "Extract a subtree to a new file" + "e" #'org-roam-extract-subtree)) + + (map! + :desc "Alternative keybind to insert a roam link while in insert mode" + :i "M-[" #'org-roam-node-insert)) +#+END_SRC +*** Nice UI to access Zettelkasten notes with Org-roam ui +#+BEGIN_SRC emacs-lisp +(use-package! websocket + :after org-roam) + +(use-package! org-roam-ui + :after org-roam ;; or :after org +;; 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)) + +(after! org-roam-ui (map! :leader (:prefix ("r" . "roam") (:prefix ("u" . "roam-ui") + + :desc "Focus the current node in org-roam-ui view" + "f" #'org-roam-ui-node-zoom + + :desc "Focus the current node's local graph in org-roam-ui view" + "l" #'org-roam-ui-node-local + + :desc "Begin org-roam ui mode" + "u" #'open-org-roam-ui + + )))) +#+END_SRC +**** Function to pull up org-roam ui +#+BEGIN_SRC emacs-lisp +(defun open-org-roam-ui () + (interactive) + (org-roam-ui-mode) + (async-shell-command "surf http://localhost:35901/")) +#+END_SRC +*** Default Browser for Export +#+BEGIN_SRC emacs-lisp +(setq browse-url-browser-function 'browse-url-generic + browse-url-generic-program "surf") + + '(org-file-apps + (quote + ((auto-mode . emacs) + ("\\.mm\\'" . default) + ("\\.x?html?\\'" . "surf %s") + ("\\.pdf\\'" . default)))) + +#+END_SRC + +** Journal Environment with org-roam +#+BEGIN_SRC emacs-lisp +(after! org-roam +(setq org-roam-dailies-capture-templates + `(("d" "default" entry + "* %?" + :target (file+head "%<%Y-%m-%d>.sec.org.age" + "#+title: %<%Y-%m-%d>\n"))))) +#+END_SRC +*** Property getters and setters +These are to fulfill my need to get property values for generating my [[id:6672f401-32a1-49ef-8004-ac77ece67f5b][journal index]]. +#+BEGIN_SRC emacs-lisp +(require 'cl-lib) + +(defun org-global-props-key-re (key) + "Construct a regular expression matching key and an optional plus and eating the spaces behind. +Test for existence of the plus: (match-beginning 1)" + (concat "^" (regexp-quote key) "\\(\\+\\)?[[:space:]]+")) + +(defun org-global-props (&optional buffer) + "Get the plists of global org properties of current buffer." + (with-current-buffer (or buffer (current-buffer)) + (org-element-map (org-element-parse-buffer) 'keyword (lambda (el) (when (string-equal (org-element-property :key el) "PROPERTY") (nth 1 el)))))) + +(defun org-global-prop-value (key) + "Get global org property KEY of current buffer. +Adding up values for one key is supported." + (let ((key-re (org-global-props-key-re key)) + (props (org-global-props)) + ret) + (cl-loop with val for prop in props + when (string-match key-re (setq val (plist-get prop :value))) do + (setq + val (substring val (match-end 0)) + ret (if (match-beginning 1) + (concat ret " " val) + val))) + ret)) + +#+END_SRC +** Resume setup for a stellar CV +*** ox-extra for ":ignore:" tags +I want to be able to ignore headings on export. +#+BEGIN_SRC emacs-lisp +(after! org + (use-package! ox-extra + :config + (ox-extras-activate '(latex-header-blocks ignore-headlines)))) +#+END_SRC +*** Resume template +#+BEGIN_SRC emacs-lisp +(add-to-list 'org-latex-classes + '("altacv" "\\documentclass[10pt,a4paper,ragged2e,withhyper]{altacv} +\\usepackage[rm]{roboto} +\\usepackage[defaultsans]{lato} +\\usepackage{paracol} +[NO-DEFAULT-PACKAGES] +[NO-PACKAGES] +% Change the page layout if you need to +\\geometry{left=1.25cm,right=1.25cm,top=1.5cm,bottom=1.5cm,columnsep=1.2cm} + +% Use roboto and lato for fonts +\\renewcommand{\\familydefault}{\\sfdefault} + +% Change the colours if you want to +\\definecolor{SlateGrey}{HTML}{2E2E2E} +\\definecolor{LightGrey}{HTML}{666666} +\\definecolor{DarkPastelRed}{HTML}{450808} +\\definecolor{PastelRed}{HTML}{8F0D0D} +\\definecolor{GoldenEarth}{HTML}{E7D192} + +\\colorlet{name}{black} +\\colorlet{tagline}{black} +\\colorlet{heading}{black} +\\colorlet{headingrule}{black} +\\colorlet{subheading}{black} +\\colorlet{accent}{black} +\\colorlet{emphasis}{SlateGrey} +\\colorlet{body}{LightGrey} + +% Change some fonts, if necessary +\\renewcommand{\\namefont}{\\Huge\\rmfamily\\bfseries} +\\renewcommand{\\personalinfofont}{\\footnotesize} +\\renewcommand{\\cvsectionfont}{\\LARGE\\rmfamily\\bfseries} +\\renewcommand{\\cvsubsectionfont}{\\large\\bfseries} + +% Change the bullets for itemize and rating marker +% for \cvskill if you want to +\\renewcommand{\\itemmarker}{{\\small\\textbullet}} +\\renewcommand{\\ratingmarker}{\\faCircle} +" + + ("\\cvsection{%s}" . "\\cvsection*{%s}") + ("\\cvevent{%s}" . "\\cvevent*{%s}"))) +#+END_SRC +** Better EViL keybinds +*** Remapping =g-j/k= +#+BEGIN_SRC emacs-lisp +(map! :n "g j" #'evil-next-visual-line) +(map! :n "g k" #'evil-previous-visual-line) +#+END_SRC + +* Company-mode for great autocompletes +I don't really want company-mode to run on timeouts. +I want VIM-like autocompletion, where =C-x o= and friends gives me my autocompletion. +#+BEGIN_SRC emacs-lisp +(after! company-mode + (setq company-idle-delay nil)) +(setq company-idle-delay nil) +#+END_SRC + + + +* Test +#+BEGIN_SRC emacs-lisp +(require 'zmq) +#+END_SRC +* Initializing shell environment variables +#+BEGIN_SRC emacs-lisp +(use-package! exec-path-from-shell) +(after! exec-path-from-shell + (dolist (var '("SSH_AUTH_SOCK" "SSH_AGENT_PID" "GPG_AGENT_INFO")) + (add-to-list 'exec-path-from-shell-variables var)) + (exec-path-from-shell-initialize) + ) +#+END_SRC diff --git a/custom.el b/custom.el new file mode 100644 index 0000000..38a9c7d --- /dev/null +++ b/custom.el @@ -0,0 +1,18 @@ +(put 'narrow-to-region 'disabled nil) +(custom-set-variables + ;; custom-set-variables was added by Custom. + ;; If you edit it by hand, you could mess it up, so be careful. + ;; Your init file should contain only one such instance. + ;; If there is more than one, they won't work right. + '(magit-todos-insert-after '(bottom) nil nil "Changed by setter of obsolete option `magit-todos-insert-at'") + '(warning-suppress-types + '((org-element-cache) + (org-element-cache) + (org-element-cache) + (defvaralias)))) +(custom-set-faces + ;; custom-set-faces was added by Custom. + ;; If you edit it by hand, you could mess it up, so be careful. + ;; Your init file should contain only one such instance. + ;; If there is more than one, they won't work right. + ) diff --git a/emacs.png b/emacs.png new file mode 100644 index 0000000000000000000000000000000000000000..bd5650530c423eb98e42c71b30fbeea58cc8acd3 GIT binary patch literal 24692 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%0DGVh0b8 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 literal 0 HcmV?d00001 diff --git a/images/example.svg b/images/example.svg new file mode 100644 index 0000000..14115f5 --- /dev/null +++ b/images/example.svg @@ -0,0 +1,90 @@ + + + + + + + + + + + + + + + + + + + + + + + + + Like this one! + diff --git a/init.el b/init.el new file mode 100644 index 0000000..f7e2a85 --- /dev/null +++ b/init.el @@ -0,0 +1,196 @@ +;;; init.el -*- lexical-binding: t; -*- + +;; This file controls what Doom modules are enabled and what order they load +;; in. Remember to run 'doom sync' after modifying it! + +;; NOTE Press 'SPC h d h' (or 'C-h d h' for non-vim users) to access Doom's +;; documentation. There you'll find a link to Doom's Module Index where all +;; of our modules are listed, including what flags they support. + +;; NOTE Move your cursor over a module's name (or its flags) and press 'K' (or +;; 'C-c c k' for non-vim users) to view its documentation. This works on +;; flags as well (those symbols that start with a plus). +;; +;; Alternatively, press 'gd' (or 'C-c c d') on a module to browse its +;; directory (for easy access to its source code). + +(doom! :input + ;;bidi ; (tfel ot) thgir etirw uoy gnipleh + ;;chinese + ;;japanese + ;;layout ; auie,ctsrnm is the superior home row + + :completion + company ; the ultimate code completion backend + ;;helm + ;;ido + ;;ivy + vertico ; the search engine of the future + + :ui + ;;deft ; notational velocity for Emacs + doom ; what makes DOOM look the way it does + doom-dashboard ; a nifty splash screen for Emacs + ;;doom-quit ; DOOM quit-message prompts when you quit Emacs + ;;(emoji +unicode) ; 🙂 + hl-todo ; highlight TODO/FIXME/NOTE/DEPRECATED/HACK/REVIEW + ;;hydra + indent-guides ; highlighted indent columns + ;;ligatures ; ligatures and symbols to make your code pretty again + ;;minimap ; show a map of the code on the side + modeline ; snazzy, Atom-inspired modeline, plus API + nav-flash ; blink cursor line after big motions + ;;neotree ; a project drawer, like NERDTree for vim + ophints ; highlight the region an operation acts on + (popup +defaults) ; tame sudden yet inevitable temporary windows + ;;tabs ; a tab bar for Emacs + ;;treemacs ; a project drawer, like neotree but cooler + ;;unicode ; extended unicode support for various languages + (vc-gutter +pretty) ; vcs diff in the fringe + vi-tilde-fringe ; fringe tildes to mark beyond EOB + window-select ; visually switch windows + ;;workspaces ; tab emulation, persistence & separate workspaces + zen ; distraction-free coding or writing + + :editor + (evil +everywhere); come to the dark side, we have cookies + file-templates ; auto-snippets for empty files + fold ; (nigh) universal code folding + (format ) ; automated prettiness + ;;god ; run Emacs commands without modifier keys + ;;lispy ; vim for lisp, for people who don't like vim + ;;multiple-cursors ; editing in many places at once + ;;objed ; text object editing for the innocent + ;;parinfer ; turn lisp into python, sort of + ;;rotate-text ; cycle region at point between text candidates + snippets ; my elves. They type so I don't have to + word-wrap ; soft wrapping with language-aware indent + + :emacs + dired ; making dired pretty [functional] + electric ; smarter, keyword-based electric-indent + ibuffer ; interactive buffer management + undo ; persistent, smarter undo for your inevitable mistakes + vc ; version-control and Emacs, sitting in a tree + + :term + ;;eshell ; the elisp shell that works everywhere + ;;shell ; simple shell REPL for Emacs + term ; basic terminal emulator for Emacs + ;;vterm ; the best terminal emulation in Emacs + + :checkers + syntax ; tasing you for every semicolon you forget + (spell +flyspell +everywhere) ; tasing you for misspelling mispelling + grammar ; tasing grammar mistake every you make + + :tools + ;;ansible + biblio ; Writes a PhD for you (citation needed) + ;;debugger ; FIXME stepping through code, to help you add bugs + ;;direnv + ;;docker + editorconfig ; let someone else argue about tabs vs spaces + ;;ein ; tame Jupyter notebooks with emacs + (eval +overlay) ; run code, run (also, repls) + ;;gist ; interacting with github gists + (lookup +dictionary +offline) ; navigate your code and its documentation + lsp ; M-x vscode + magit ; a git porcelain for Emacs + ;;make ; run make tasks from Emacs + ;;pass ; password manager for nerds + pdf ; pdf enhancements + ;;prodigy ; FIXME managing external services & code builders + ;;rgb ; creating color strings + ;;taskrunner ; taskrunner for all your projects + ;;terraform ; infrastructure as code + ;;tmux ; an API for interacting with tmux + ;;tree-sitter ; syntax and parsing, sitting in a tree... + ;;upload ; map local to remote projects via ssh/ftp + + :os + ;;(:if IS-MAC macos) ; improve compatibility with macOS + ;;tty ; improve the terminal Emacs experience + + :lang + ;;agda ; types of types of types of types... + ( beancount +lsp) ; mind the GAAP + (cc +lsp) ; C > C++ == 1 + ;;clojure ; java with a lisp + ;;common-lisp ; if you've seen one lisp, you've seen them all + ;;coq ; proofs-as-programs + ;;crystal ; ruby at the speed of c + ;;csharp ; unity, .NET, and mono shenanigans + data ; config/data formats + ;;(dart +flutter) ; paint ui and not much else + ;;dhall + ;;elixir ; erlang done right + ;;elm ; care for a cup of TEA? + emacs-lisp ; drown in parentheses + ;;erlang ; an elegant language for a more civilized age + ;;ess ; emacs speaks statistics + ;;factor + ;;faust ; dsp, but you get to keep your soul + ;;fortran ; in FORTRAN, GOD is REAL (unless declared INTEGER) + ;;fsharp ; ML stands for Microsoft's Language + ;;fstar ; (dependent) types and (monadic) effects and Z3 + ;;gdscript ; the language you waited for + ;;(go +lsp) ; the hipster dialect + ;;(graphql +lsp) ; Give queries a REST + ;;(haskell +lsp) ; a language that's lazier than I am + ;;hy ; readability of scheme w/ speed of python + ;;idris ; a language you can depend on + ;;json ; At least it ain't XML + ;;(java +lsp) ; the poster child for carpal tunnel syndrome + ;;javascript ; all(hope(abandon(ye(who(enter(here)))))) + ;;julia ; a better, faster MATLAB + ;;kotlin ; a better, slicker Java(Script) + (latex +lsp +cdlatex +fold) ; writing papers in Emacs has never been so fun + ;;lean ; for folks with too much to prove + ;;ledger ; be audit you can be + ;;lua ; one-based indices? one-based indices + markdown ; writing docs for people to ignore + ;;nim ; python + lisp at the speed of c + ;;nix ; I hereby declare "nix geht mehr!" + ;;ocaml ; an objective camel + (org +roam2 +gnuplot +hugo +pomodoro +noter) ; organize your plain life in plain text + ;;php ; perl's insecure younger brother + ;;plantuml ; diagrams for confusing people more + ;;purescript ; javascript, but functional + python ; beautiful is better than ugly + ;;qt ; the 'cutest' gui framework ever + ;;racket ; a DSL for DSLs + ;;raku ; the artist formerly known as perl6 + ;;rest ; Emacs as a REST client + ;;rst ; ReST in peace + ;;(ruby +rails) ; 1.step {|i| p "Ruby is #{i.even? ? 'love' : 'life'}"} + (rust +lsp) ; Fe2O3.unwrap().unwrap().unwrap().unwrap() + ;;scala ; java, but good + ;;(scheme +guile) ; a fully conniving family of lisps + sh ; she sells {ba,z,fi}sh shells on the C xor + ;;sml + ;;solidity ; do you need a blockchain? No. + ;;swift ; who asked for emoji variables? + ;;terra ; Earth and Moon in alignment for performance. + web ; the tubes + ;;yaml ; JSON, but readable + ;zig ; C, but simpler + + :email + ;;(mu4e +org +gmail) + ;;notmuch + ;;(wanderlust +gmail) + + :app + calendar + ;;emmgs + ;;everywhere ; *leave* Emacs!? You must be joking + ;;irc ; how neckbeards socialize + ;;(rss +org) ; emacs as an RSS reader + ;;twitter ; twitter client https://twitter.com/vnought + + :config + literate + (default +bindings +smartparens) + +) diff --git a/packages.el b/packages.el new file mode 100644 index 0000000..a8f7448 --- /dev/null +++ b/packages.el @@ -0,0 +1,79 @@ +;; -*- no-byte-compile: t; -*- +;;; $DOOMDIR/packages.el + +;; To install a package with Doom you must declare them here and run 'doom sync' +;; on the command line, then restart Emacs for the changes to take effect -- or +;; use 'M-x doom/reload'. + + +;; To install SOME-PACKAGE from MELPA, ELPA or emacsmirror: +;(package! some-package) + +;; To install a package directly from a remote git repo, you must specify a +;; `:recipe'. You'll find documentation on what `:recipe' accepts here: +;; https://github.com/radian-software/straight.el#the-recipe-format +;(package! another-package +; :recipe (:host github :repo "username/repo")) + +;; If the package you are trying to install does not contain a PACKAGENAME.el +;; file, or is located in a subdirectory of the repo, you'll need to specify +;; `:files' in the `:recipe': +;(package! this-package +; :recipe (:host github :repo "username/repo" +; :files ("some-file.el" "src/lisp/*.el"))) + +;; If you'd like to disable a package included with Doom, you can do so here +;; with the `:disable' property: +;(package! builtin-package :disable t) + +;; You can override the recipe of a built in package without having to specify +;; all the properties for `:recipe'. These will inherit the rest of its recipe +;; from Doom or MELPA/ELPA/Emacsmirror: +;(package! builtin-package :recipe (:nonrecursive t)) +;(package! builtin-package-2 :recipe (:repo "myfork/package")) + +;; Specify a `:branch' to install a package from a particular branch or tag. +;; This is required for some packages whose default branch isn't 'master' (which +;; our package manager can't deal with; see radian-software/straight.el#279) +;(package! builtin-package :recipe (:branch "develop")) + +;; Use `:pin' to specify a particular commit to install. +;(package! builtin-package :pin "1a2b3c4d5e") + + +;; Doom's packages are pinned to a specific commit and updated from release to +;; release. The `unpin!' macro allows you to unpin single packages... +;(unpin! pinned-package) +;; ...or multiple packages +;(unpin! pinned-package another-pg-ql) +;; Org-mode + +;;(package! org-habit-plus + ; ; :recipe (:host github :type git :repo "myshevchuk/org-habit-plus")) + +(package! org-roam-ui) + + +(package! ob-lilypond + :recipe (:host github :type git :repo "mjago/ob-lilypond")) + + +;; Sagemath-related +;(package! sage-shell-mode) +;(package! ob-sagemath) + +(package! engrave-faces) +;; Graphing +(package! ob-mermaid) +(package! ob-svgbob + :recipe (:host nil :type git :repo "https://git.tecosaur.net/tec/ob-svgbob")) + +; Security-related +(package! age) + +(package! org-edna) + +(package! org-heatmap + :recipe (:host github :type git :repo "aspiers/org-heatmap")) + +(package! exec-path-from-shell) diff --git a/snippets/org-mode/