440 lines
16 KiB
Nix
440 lines
16 KiB
Nix
{
|
|
config,
|
|
lib,
|
|
pkgs,
|
|
...
|
|
}:
|
|
with lib;
|
|
mkIf (elem "emacs::org" config.machine.pkgs) {
|
|
programs.emacs.init.usePackage.org = {
|
|
enable = true;
|
|
package = epkgs: [epkgs.org];
|
|
mode = [''("\\.org\\'" . org-mode)''];
|
|
command = ["org-mode"];
|
|
hook =
|
|
[
|
|
"(org-mode . (lambda () (org-indent-mode)))"
|
|
''
|
|
(org-mode
|
|
. (lambda ()
|
|
;; Automatic line-wrapping in org-mode
|
|
;;(auto-fill-mode 1)
|
|
|
|
(setq completion-at-point-functions
|
|
'(org-completion-symbols
|
|
ora-cap-filesystem))))
|
|
''
|
|
''
|
|
(org-mode
|
|
. (lambda ()
|
|
"Beautify Org Checkbox Symbol"
|
|
(push '("[ ]" . "☐" ) prettify-symbols-alist)
|
|
(push '("[X]" . "☑" ) prettify-symbols-alist)
|
|
(push '("[-]" . "❍" ) prettify-symbols-alist)
|
|
(prettify-symbols-mode)))
|
|
''
|
|
]
|
|
++ optional (elem "emacs::flyspell" config.machine.pkgs) "(org-mode . (lambda () (flyspell-mode)))";
|
|
bind = {
|
|
"C-c a" = "org-agenda";
|
|
};
|
|
bindLocal = {
|
|
org-mode-map =
|
|
{
|
|
"M-<up>" = "org-metaup";
|
|
"M-<down>" = "org-metadown";
|
|
"M-." = "org-open-at-point";
|
|
"M-," = "org-mark-ring-goto";
|
|
"M-S-<return>" = "org-insert-todo-heading-respect-content";
|
|
"M-<return>" = "org-meta-return";
|
|
"M-p" = "org-previous-visible-heading";
|
|
"M-n" = "org-next-visible-heading";
|
|
}
|
|
// (optionalAttrs (elem "emacs::company" config.machine.pkgs) {
|
|
"<M-tab>" = "company-pcomplete";
|
|
});
|
|
};
|
|
config = ''
|
|
;; Insead of "..." show "…" when there's hidden folded content
|
|
|
|
;; org-prettify
|
|
(defface org-checkbox-done-text
|
|
'((t (:foreground "#71696A" :strike-through t)))
|
|
"Face for the text part of a checked org-mode checkbox.")
|
|
|
|
(font-lock-add-keywords
|
|
'org-mode
|
|
`(("^[ \t]*\\(?:[-+*]\\|[0-9]+[).]\\)[ \t]+\\(\\(?:\\[@\\(?:start:\\)?[0-9]+\\][ \t]*\\)?\\[\\(?:X\\|\\([0-9]+\\)/\\2\\)\\][^\n]*\n\\)"
|
|
1 'org-checkbox-done-text prepend))
|
|
'append)
|
|
|
|
;; Some characters to choose from: …, ⤵, ▼, ↴, ⬎, ⤷, and ⋱
|
|
(setq org-ellipsis " ▼")
|
|
;; get nice looking tables (only for non org-tables; rarely used)
|
|
(setq table-cell-horizontal-chars "\u2501")
|
|
(setq table-cell-vertical-char ?\u2503)
|
|
(setq table-cell-intersection-char ?\u254B)
|
|
|
|
(setq org-directory "~/Documents/org/")
|
|
|
|
;; Show headings up to level 2 by default when opening an org files
|
|
(setq org-startup-folded 'content)
|
|
|
|
;; Show inline images by default
|
|
(setq org-startup-with-inline-images t)
|
|
|
|
;; Add more levels to headlines that get displayed with imenu
|
|
(setq org-imenu-depth 5)
|
|
|
|
;; Enter key follows links (= C-c C-o)
|
|
(setq org-return-follows-link t)
|
|
|
|
;; Don't remove links after inserting
|
|
(setq org-keep-stored-link-after-insertion t)
|
|
|
|
(setq org-tag-alist (quote ((:startgroup)
|
|
("WAITING" . ?w)
|
|
("HOLD" . ?h)
|
|
("CANCELLED" . ?c)
|
|
("NOTE" . ?n)
|
|
(:endgroup)
|
|
("PERSONAL" . ?P)
|
|
("WORK" . ?W)
|
|
("ATOMX" . ?A)
|
|
("E5" . ?E)
|
|
("HOGASO" . ?H)
|
|
("ORG" . ?o)
|
|
("crypt" . ?C)
|
|
("FLAGGED" . ??))))
|
|
|
|
;; Allow setting single tags without the menu
|
|
(setq org-fast-tag-selection-single-key (quote expert))
|
|
|
|
(setq org-archive-mark-done nil)
|
|
(setq org-archive-location "%s_archive::* Archived Tasks")
|
|
|
|
;; C-RET, C-S-RET insert new heading after current task content
|
|
(setq org-insert-heading-respect-content nil)
|
|
|
|
;; Show a little bit more when using sparse-trees
|
|
(setq org-show-following-heading t)
|
|
(setq org-show-hierarchy-above t)
|
|
(setq org-show-siblings (quote ((default))))
|
|
|
|
;; don't show * / = etc
|
|
(setq org-hide-emphasis-markers t)
|
|
|
|
;; leave highlights in sparse tree after edit. C-c C-c removes highlights
|
|
(setq org-remove-highlights-with-change nil)
|
|
|
|
;; M-RET should not split the lines
|
|
(setq org-M-RET-may-split-line '((default . nil)))
|
|
|
|
(setq org-special-ctrl-a/e t)
|
|
(setq org-special-ctrl-k t)
|
|
(setq org-yank-adjusted-subtrees t)
|
|
|
|
;; Show org entities as UTF-8 characters (e.g. \sum as ∑)
|
|
(setq org-pretty-entities t)
|
|
;; But Don't print "bar" as subscript in "foo_bar"
|
|
(setq org-pretty-entities-include-sub-superscripts nil)
|
|
;; And also don't display ^ or _ as super/subscripts
|
|
(setq org-use-sub-superscripts nil)
|
|
;; undone TODO entries will block switching the parent to DONE
|
|
(setq org-enforce-todo-dependencies t)
|
|
|
|
(setq org-use-fast-todo-selection t)
|
|
|
|
(setq org-todo-keywords
|
|
(quote ((sequence "TODO(t)" "NEXT(n)" "|" "DONE(d)")
|
|
(sequence "WAITING(w@/!)" "HOLD(h@/!)" "|" "CANCELLED(c@/!)" "PHONE" "MEETING"))))
|
|
|
|
(setq org-todo-keyword-faces
|
|
(quote (("TODO" :foreground "red" :weight bold)
|
|
("NEXT" :foreground "blue" :weight bold)
|
|
("DONE" :foreground "forest green" :weight bold)
|
|
("WAITING" :foreground "orange" :weight bold)
|
|
("HOLD" :foreground "magenta" :weight bold)
|
|
("CANCELLED" :foreground "forest green" :weight bold)
|
|
("MEETING" :foreground "forest green" :weight bold)
|
|
("PHONE" :foreground "forest green" :weight bold))))
|
|
|
|
;; Auto completion for symbols in org-mode
|
|
;; https://oremacs.com/2017/10/04/completion-at-point/
|
|
(defun org-completion-symbols ()
|
|
(when (looking-back "[`~=][a-zA-Z]+" nil)
|
|
(let (cands)
|
|
(save-match-data
|
|
(save-excursion
|
|
(goto-char (point-min))
|
|
(while (re-search-forward "[`~=]\\([a-zA-Z.\\-_]+\\)[`~=]" nil t)
|
|
(cl-pushnew
|
|
(match-string-no-properties 0) cands :test 'equal))
|
|
cands))
|
|
(when cands
|
|
(list (match-beginning 0) (match-end 0) cands)))))
|
|
|
|
(defun ora-cap-filesystem ()
|
|
(let (path)
|
|
(when (setq path (ffap-string-at-point))
|
|
(when (string-match "\\`file:\\(.*\\)\\'" path)
|
|
(setq path (match-string 1 path)))
|
|
(let ((compl (all-completions path #'read-file-name-internal)))
|
|
(when compl
|
|
(let* ((str (car compl))
|
|
(offset
|
|
(let ((i 0)
|
|
(len (length str)))
|
|
(while (and (< i len)
|
|
(equal (get-text-property i 'face str)
|
|
'completions-common-part))
|
|
(cl-incf i))
|
|
i)))
|
|
(list (- (point) offset) (point) compl)))))))
|
|
|
|
'';
|
|
};
|
|
|
|
programs.emacs.init.usePackage.ob = {
|
|
enable = true;
|
|
package = epkgs: [epkgs.ob-ipython epkgs.ob-rust epkgs.ob-diagrams];
|
|
defer = true;
|
|
init = ''
|
|
(add-hook 'org-babel-after-execute-hook 'org-display-inline-images 'append)
|
|
'';
|
|
config = ''
|
|
(setq org-confirm-babel-evaluate nil) ; don't prompt me to confirm everytime I want to evaluate a block
|
|
|
|
(defun org-babel-restart-session-to-point (&optional arg)
|
|
"Restart session up to the src-block in the current point.
|
|
Goes to beginning of buffer and executes each code block with
|
|
`org-babel-execute-src-block' that has the same language and
|
|
session as the current block. ARG has same meaning as in
|
|
`org-babel-execute-src-block'."
|
|
(interactive "P")
|
|
(unless (org-in-src-block-p)
|
|
(error "You must be in a src-block to run this command"))
|
|
(let* ((current-point (point-marker))
|
|
(info (org-babel-get-src-block-info))
|
|
(lang (nth 0 info))
|
|
(params (nth 2 info))
|
|
(session (cdr (assoc :session params))))
|
|
(save-excursion
|
|
(goto-char (point-min))
|
|
(while (re-search-forward org-babel-src-block-regexp nil t)
|
|
;; goto start of block
|
|
(goto-char (match-beginning 0))
|
|
(let* ((this-info (org-babel-get-src-block-info))
|
|
(this-lang (nth 0 this-info))
|
|
(this-params (nth 2 this-info))
|
|
(this-session (cdr (assoc :session this-params))))
|
|
(when
|
|
(and
|
|
(< (point) (marker-position current-point))
|
|
(string= lang this-lang)
|
|
(src-block-in-session-p session))
|
|
(org-babel-execute-src-block arg)))
|
|
;; move forward so we can find the next block
|
|
(forward-line)))))
|
|
|
|
(defun org-babel-kill-session ()
|
|
"Kill session for current code block."
|
|
(interactive)
|
|
(unless (org-in-src-block-p)
|
|
(error "You must be in a src-block to run this command"))
|
|
(save-window-excursion
|
|
(org-babel-switch-to-session)
|
|
(kill-buffer)))
|
|
|
|
(defun org-babel-remove-result-buffer ()
|
|
"Remove results from every code block in buffer."
|
|
(interactive)
|
|
(save-excursion
|
|
(goto-char (point-min))
|
|
(while (re-search-forward org-babel-src-block-regexp nil t)
|
|
(org-babel-remove-result))))
|
|
|
|
|
|
;; this adds a "new language" in babel that gets exported as js in html
|
|
;; https://www.reddit.com/r/orgmode/comments/5bi6ku/tip_for_exporting_javascript_source_block_to/
|
|
(add-to-list 'org-src-lang-modes '("inline-js" . javascript))
|
|
(defvar org-babel-default-header-args:inline-js
|
|
'((:results . "html")
|
|
(:exports . "results")))
|
|
(defun org-babel-execute:inline-js (body _params)
|
|
(format "<script type=\"text/javascript\">\n%s\n</script>" body))
|
|
|
|
;; Path when plantuml is installed from AUR (package `plantuml')
|
|
(setq org-plantuml-jar-path "/opt/plantuml/plantuml.jar")
|
|
|
|
;; add all languages to org mode
|
|
(org-babel-do-load-languages
|
|
'org-babel-load-languages
|
|
'((C . t)
|
|
;;(R . t)
|
|
(asymptote)
|
|
(awk)
|
|
(calc . t)
|
|
(clojure . t)
|
|
(comint)
|
|
(css)
|
|
(ditaa . t)
|
|
(dot . t)
|
|
(emacs-lisp . t)
|
|
(fortran)
|
|
(gnuplot . t)
|
|
(haskell)
|
|
(io)
|
|
(java)
|
|
(js . t)
|
|
(latex)
|
|
(lilypond)
|
|
(lisp)
|
|
(lua . t)
|
|
(matlab)
|
|
(maxima)
|
|
(mscgen)
|
|
(ocaml)
|
|
(octave . t)
|
|
(org . t)
|
|
(perl)
|
|
(picolisp)
|
|
(plantuml . t)
|
|
(python . t)
|
|
;; (ipython . t)
|
|
;; (restclient . t)
|
|
(ref)
|
|
(ruby)
|
|
(sass)
|
|
(scala)
|
|
(scheme)
|
|
(screen)
|
|
(shell . t)
|
|
(shen)
|
|
(snippet)
|
|
(sql . t)
|
|
(sqlite . t)))
|
|
'';
|
|
};
|
|
|
|
programs.emacs.init.usePackage.org-src = {
|
|
enable = true;
|
|
package = epkgs: null;
|
|
defer = true;
|
|
init = ''(put 'org-src-preserve-indentation 'safe-local-variable 'booleanp)'';
|
|
config = ''
|
|
(setq org-src-window-setup 'current-window)
|
|
|
|
(setq org-src-fontify-natively t) ; syntax highlighting for source code blocks
|
|
|
|
;; Tab should do indent in code blocks
|
|
;; I think I hate this function (causes scroll on TAB
|
|
(setq org-src-tab-acts-natively t)
|
|
;; ?Fix weird scrolling
|
|
|
|
;; Don't remove (or add) any extra whitespace
|
|
(setq org-src-preserve-indentation nil)
|
|
(setq org-edit-src-content-indentation 0)
|
|
|
|
;;; Some helper function to manage org-babel sessions
|
|
|
|
(defun src-block-in-session-p (&optional name)
|
|
"Return if src-block is in a session of NAME.
|
|
NAME may be nil for unnamed sessions."
|
|
(let* ((info (org-babel-get-src-block-info))
|
|
;;(lang (nth 0 info))
|
|
;;(body (nth 1 info))
|
|
(params (nth 2 info))
|
|
(session (cdr (assoc :session params))))
|
|
|
|
(cond
|
|
;; unnamed session, both name and session are nil
|
|
((and (null session)
|
|
(null name))
|
|
t)
|
|
;; Matching name and session
|
|
((and
|
|
(stringp name)
|
|
(stringp session)
|
|
(string= name session))
|
|
t)
|
|
;; no match
|
|
(t nil))))
|
|
|
|
;; dot == graphviz-dot
|
|
(add-to-list 'org-src-lang-modes '("dot" . graphviz-dot))
|
|
|
|
;; Add 'conf-mode' to org-babel
|
|
(add-to-list 'org-src-lang-modes '("ini" . conf))
|
|
(add-to-list 'org-src-lang-modes '("conf" . conf))
|
|
'';
|
|
};
|
|
|
|
programs.emacs.init.usePackage.org-tempo = {
|
|
enable = true;
|
|
package = epkgs: null;
|
|
};
|
|
|
|
programs.emacs.init.usePackage.ox = {
|
|
enable = true;
|
|
package = epkgs: null;
|
|
defer = true;
|
|
command = [];
|
|
config = ''
|
|
;; Use html5 as org export and use new tags
|
|
(setq org-html-doctype "html5")
|
|
(setq org-html-html5-fancy t)
|
|
;; Don't add html footer to export
|
|
(setq org-html-postamble nil)
|
|
;; Don't export ^ or _ as super/subscripts
|
|
(setq org-export-with-sub-superscripts nil)
|
|
'';
|
|
};
|
|
|
|
programs.emacs.init.usePackage.ox-gfm = {
|
|
enable = true;
|
|
after = ["ox"];
|
|
};
|
|
|
|
programs.emacs.init.usePackage.ox-rst = {
|
|
enable = true;
|
|
after = ["ox"];
|
|
};
|
|
|
|
programs.emacs.init.usePackage.ox-md = {
|
|
enable = true;
|
|
package = epkgs: null;
|
|
after = ["ox"];
|
|
};
|
|
|
|
programs.emacs.init.usePackage.org-bullets = {
|
|
enable = true;
|
|
hook = ["(org-mode . org-bullets-mode)"];
|
|
};
|
|
|
|
programs.emacs.init.usePackage.org-crypt = {
|
|
enable = true;
|
|
package = epkgs: null;
|
|
after = ["org"];
|
|
hook = ["(org-mode . (lambda () (add-hook 'before-save-hook 'org-encrypt-entries nil t)))"];
|
|
command = ["org-decrypt-entry" "org-encrypt-entry"];
|
|
bindLocal = {
|
|
org-mode-map = {
|
|
"C-c d" = "org-decrypt-entry";
|
|
"C-c e" = "org-encrypt-entry";
|
|
};
|
|
};
|
|
config = ''
|
|
(setq org-tags-exclude-from-inheritance (quote ("crypt")))
|
|
;; GPG key to use for encryption
|
|
(load-file "~/.emacs.d/org-crypt-key.el")
|
|
|
|
;; don't ask to disable auto-save
|
|
(setq org-crypt-disable-auto-save "encrypt")
|
|
'';
|
|
};
|
|
|
|
programs.emacs.init.usePackage.org-drill = {
|
|
enable = true;
|
|
};
|
|
}
|