(setq tab-always-indent t) (setq org-roam-directory "~/org/") (setq doom-theme 'doom-dark+) (setq doom-font (font-spec :family "Hack Nerd Font Mono" :size 16 :weight 'medium)) (setq auto-save-default nil) (remove-hook '+doom-dashboard-functions #'doom-dashboard-widget-shortmenu) (remove-hook '+doom-dashboard-functions #'doom-dashboard-widget-footer) (setq fancy-splash-image (concat doom-private-dir "emacs.png")) (setq user-full-name "Judah Sotomayor" user-mail-address "") (map! :desc "Switch to normal mode" "M-c" #'evil-normal-state) (setq org-pretty-entities 0) (defun bash () (interactive) (term "/bin/bash")) (map! :desc "Start a bash shell" "" #'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) (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 templates/post-capture-props "#+date: [%<%Y-%m-%d %a>]\n#+lastmod:\n#+categories[]:\n#+tags[]:\n#+images[]: ") (setq templates/post-capture-title "#+TITLE: ${title}\n") (setq templates/post-capture-template (concat templates/post-capture-title templates/post-capture-props)) (setq org-preview-latex-image-directory (concat org-directory (file-name-as-directory "images/latexsnip"))) (setq org-hugo-base-dir (concat org-directory (file-name-as-directory "website"))) (setq org-hugo-default-section-directory "posts") (after! org ;; Import ox-latex to get org-latex-classes and other funcitonality ;; for exporting to LaTeX from org (use-package! ox-latex :init :config (setq org-latex-with-hyperref nil) ;; stop org adding hypersetup{author..} to latex export ;; (setq org-latex-prefer-user-labels t) (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)))) (after! ox-latex (setq org-latex-pdf-process '("lualatex --output-directory=/home/user/Documents -shell-escape -interaction nonstopmode %f" "lualatex --output-directory=/home/user/Documents -shell-escape -interaction nonstopmode %f")) ) (setq-default org-html-with-latex `dvisvgm) (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[hidelinks]{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[hidelinks]{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! 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} [NO-DEFAULT-PACKAGES] [NO-PACKAGES]" ("\\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 (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 post" plain "%?" :target (file+head "~/org/website/content/posts/${title}.org" ,templates/post-capture-template) :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}"))) (add-to-list 'org-latex-classes '("mcdowellcv" "\\documentclass[]{mcdowellcv} \\usepackage{amsmath} \\usepackage[]{multicol} [NO-DEFAULT-PACKAGES] [NO-PACKAGES]" ("\\section{%s}" . "\\section*{%s}") ("\\subsection{%s}" . "\\subsection*{%s}") ("\\subsubsection{%s}" . "\\subsubsection*{%s}") ("\\paragraph{%s}" . "\\paragraph*{%s}") ("\\subparagraph{%s}" . "\\subparagraph*{%s}") ("\\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) (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) )