Update org config

This commit is contained in:
Henrik Lissner 2016-02-13 00:46:58 -05:00
parent 3cc18ac674
commit a670dad95f
8 changed files with 474 additions and 332 deletions

2
Cask
View file

@ -219,7 +219,7 @@
(depends-on "org-download")
(depends-on "ox-opml" :git "https://github.com/edavis/org-opml")
(depends-on "ox-pandoc")
; (depends-on "org-plus-contrib")
(depends-on "org-plus-contrib")
;; Writing -- modules/lib-writing.el
(depends-on "helm-bibtex")

View file

@ -93,8 +93,7 @@ buffers."
(interactive)
(in! org-directory
(let ((helm-ff-skip-boring-files t))
(helm-find-files-1 org-directory))))
(helm-find-files-1 (concat org-directory "/")))))
(provide 'defuns-helm)
;;; defuns-helm.el ends here

View file

@ -1,8 +1,8 @@
;;; helm-deft.el --- helm module for grepping note files over directories
;; Copyright (C) 2014 Derek Feichtinger
;; Author: Derek Feichtinger <derek.feichtinger@psi.ch>
;; Author: Derek Feichtinger <dfeich@gmail.com>
;; Keywords: convenience
;; Homepage: https://github.com/dfeich/helm-deft
;; Version: TODO
@ -23,6 +23,18 @@
;; You should have received a copy of the GNU General Public License
;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>.
;;; Commentary:
;; Helm command to find files fast based on contents and filename. Inspired
;; by the great emacs deft package. It allows defining a list of input directories
;; that can be defined and that are searched recursively.
;;
;; helm-deft is composed of three search sources
;; - file names: simple match of pattern vs. file name
;; - file match: shows file names of files where all of the individual patterns
;; match anywhere in the file
;; - file contents: show the lines where the last word in the search patterns
;; matches
;;; Code:
(require 'helm)
@ -30,45 +42,64 @@
(require 'helm-files)
(require 'f)
(require 'cl-lib)
(require 'subr-x)
(defgroup helm-deft nil
"customization group for the helm-deft utility" :group 'helm :version 24.3)
(defcustom helm-deft-dir-list
'("~/Documents")
"list of directories in which to search recursively for candidate files"
"List of directories in which to search recursively for candidate files."
:group 'helm-deft
)
(defcustom helm-deft-extension "org"
"defines file extension for identifying candidate files to be searched for")
"Defines file extension for identifying candidate files to be searched for.")
(defvar helm-deft-file-list ""
"variable to store the list of candidate files")
(defvar helm-deft-file-list nil
"Variable to store the list of candidate files.
This is constant over the invocation of one helm-deft.")
(defvar helm-deft-matching-files '()
"Used for building the list of filenames that the grep matched.")
(defvar helm-source-deft-fn
'((name . "File Names")
(header-line . "C-r: rotate pattern C-s/C-d: set/delete (marked) candidates from list")
(init . (lambda ()
(progn (setq helm-deft-file-list (helm-deft-fname-search))
(progn (unless helm-deft-file-list
(setq helm-deft-file-list (helm-deft-fname-search)))
(with-current-buffer (helm-candidate-buffer 'local)
(insert (mapconcat 'identity
helm-deft-file-list "\n"))))))
(insert (mapconcat 'identity
helm-deft-file-list "\n"))))))
(candidates-in-buffer)
;; matching is done in the buffer when candidates-in-buffer is used
;; We only want against the basename and not the full path
(match-part . (lambda (c) (helm-basename c)))
(type . file)
;; Note: We override the transformer that the file type brings. We
;; want the file list sorted
;;(type . file)
(action . helm-find-files-actions)
;; We want the file list sorted. helm-highlight-files also will
;; transform a filename to a (basename . filename) cons
(candidate-transformer . (lambda (c) (sort (helm-highlight-files c)
(lambda (a b)
(string< (downcase (car a))
(downcase (car b)))))))
;; (action . (("open file" . (lambda (candidate)
;; (find-file candidate)))))
;;(persistent-help . "show name")
(cleanup . (lambda () (setq helm-deft-file-list nil)))
)
"Source definition for matching filenames of the `helm-deft' utility")
"Source definition for matching filenames of the `helm-deft' utility.")
(defun helm-deft-fname-search ()
"Search all preconfigured directories for matching files.
Returns the filenames as a list."
(assert helm-deft-extension nil "No file extension defined for helm-deft")
(assert helm-deft-dir-list nil "No directories defined for helm-deft")
(cl-loop for dir in helm-deft-dir-list
do (assert (file-exists-p dir) nil
(format "Directory %s does not exist. Check helm-deft-dir-list" dir))
collect (f--files dir (equal (f-ext it) helm-deft-extension) t)
into reslst
finally (return (apply #'append reslst)))
)
(defvar helm-source-deft-filegrep
'((name . "File Contents")
@ -76,16 +107,142 @@
;; We use the action from the helm-grep module
(action . helm-grep-action)
(requires-pattern)
(filter-one-by-one . helm-grep-filter-one-by-one)
(pattern-transformer . (lambda (pattern)
(cl-loop for ptr in (split-string pattern " *" t)
if (string-prefix-p "w:" ptr)
collect (string-remove-prefix "w:" ptr) into cptr
else collect ptr into cptr
finally return (mapconcat 'identity cptr " "))))
(filter-one-by-one . (lambda (candidate)
;; we abuse the filter-one-by-one function
;; for building the candidates list for the
;; matching-files source
(helm-deft-matching-files-search candidate)
;; we borrow the helm-grep filter function
(helm-grep-filter-one-by-one candidate)))
(cleanup . (lambda () (when (get-buffer "*helm-deft-proc*")
(let ((kill-buffer-query-functions nil))
(kill-buffer "*helm-deft-proc*")))))
)
"Source definition for matching against file contents for the
`helm-deft' utility")
"Source definition for matching against file contents for the `helm-deft' utility.")
(defun helm-deft-build-cmd (ptrnstr filelst)
"Builds a grep command based on the patterns and file list.
PTRNSTR may contain multiple search patterns separated by
spaces. The first pattern will be used to retrieve matching
lines. All other patterns will be used to pre-select files with
matching lines. FILELST is a list of file paths"
(let* ((ptrnlst (reverse (split-string ptrnstr " *" t)))
(firstp (pop ptrnlst))
(firstaddflag (if (string-prefix-p "w:" firstp)
(progn
(setq firstp (string-remove-prefix "w:" firstp))
"-w")
""))
(filelst (mapconcat 'identity filelst " "))
(innercmd (if ptrnlst
(cl-labels ((build-inner-cmd
(ptrnlst filelst)
(let* ((pattern (pop ptrnlst))
(addflags
(if (string-prefix-p "w:" pattern)
(progn
(setq pattern
(string-remove-prefix
"w:" pattern))
"-w")
"")))
(if ptrnlst
(format "$(grep %s -Elie '%s' %s)"
addflags pattern
(build-inner-cmd ptrnlst filelst))
(format "$(grep %s -Elie '%s' %s)"
addflags pattern filelst)))))
(build-inner-cmd ptrnlst filelst))
filelst)))
(format "grep %s -EHine '%s' %s" firstaddflag firstp innercmd))
)
(defun helm-deft-fgrep-search ()
"Greps for the helm search pattern in the configuration defined file list."
(setq helm-deft-matching-files '())
;; need to pass helm-input (the real input line) to the build
;; function since helm-pattern is already cleaned by the
;; pattern-transformer function of helm-source-deft-filegrep
(let* ((shcmd (helm-deft-build-cmd helm-input helm-deft-file-list)))
(helm-log "grep command: %s" shcmd)
;; the function must return the process object
(prog1
(start-process-shell-command "helm-deft-proc" "*helm-deft-proc*"
shcmd)
(set-process-sentinel
(get-process "helm-deft-proc")
(lambda (process event)
(cond
((string= event "finished\n")
(with-helm-window
(setq mode-line-format
'(" " mode-line-buffer-identification " "
(:eval (format "L%s" (helm-candidate-number-at-point))) " "
(:eval (propertize
;; TODO: The count is wrong since it counts all sources
(format
"[Grep process finished - (%s results)] "
(max (1- (count-lines
(point-min)
(point-max)))
0))
'face 'helm-grep-finish))))
(force-mode-line-update))
;; must NOT DO a targeted update here. Seems to call also this source
;; and we end in an infinite loop
;; (helm-update nil helm-source-deft-matching-files)
)
;; Catch error output in log.
(t (helm-log
"Error: Grep %s"
(replace-regexp-in-string "\n" "" event))))
))
)
))
(defvar helm-source-deft-matching-files
'((name . "Matching Files")
(candidates . helm-deft-matching-files)
;;(type . file)
;; introducing the delayed value to always have it scheduled after
;; the async grep process that produces the basis for this source
(delayed . 0.5)
(action . helm-find-files-actions)
;; need to override the file type's match settings
(match . (lambda (candidate) t))
(candidate-transformer . (lambda (c) (sort (helm-highlight-files c)
(lambda (a b)
(string< (downcase (car a))
(downcase (car b)))))))
(requires-pattern)
(volatile)
)
"Source definition for showing matching files from the grep buffer of the `helm-deft' utility.")
(defun helm-deft-matching-files-search (candidate)
"Add entry to helm-deft-matching-files list from a grep CANDIDATE."
(when (string-match "\\([^:]+\\):[0-9]+:" candidate)
(pushnew (match-string 1 candidate) helm-deft-matching-files :test #'equal)))
;; (defun helm-deft-matching-files-search ()
;; (when (get-buffer "*helm-deft-proc*")
;; (with-current-buffer "*helm-deft-proc*"
;; (beginning-of-buffer)
;; (while (and
;; (looking-at "^\\([^:]+\\):[0-9]+:")
;; (not (equal (forward-line) 1)))
;; (push (match-string 1) helm-deft-matching-files)))
;; (cl-remove-duplicates helm-deft-matching-files :test #'equal))
;; )
(defun helm-deft-rotate-searchkeys ()
"rotate the words of the search pattern in the helm minibuffer"
"Rotate the words of the search pattern in the helm minibuffer."
(interactive)
(helm-log "Executing helm-deft-rotate-searchkeys")
(let ((patlst (split-string helm-pattern " *")))
@ -98,64 +255,42 @@
(helm-update)))
)
(defun helm-deft-remove-candidate-file ()
"Remove the file under point from the list of candidates."
(interactive)
;; helm-get-selection returns current item under point
;; helm-marked-candidates returns all marked candidates or the item under point
(dolist (selection (helm-marked-candidates))
(when (string-match "\\([^:]+\\):[0-9]+:" selection)
(setq selection (match-string 1 selection)))
(setq helm-deft-file-list (delete selection helm-deft-file-list)))
(helm-unmark-all)
(helm-force-update))
(defun helm-deft-set-to-marked ()
"Set the filelist to the marked files."
(interactive)
(setq helm-deft-file-list (helm-marked-candidates))
(helm-unmark-all)
(helm-force-update))
(defvar helm-deft-map
(let ((map (make-sparse-keymap)))
(set-keymap-parent map helm-map)
(define-key map (kbd "C-r") 'helm-deft-rotate-searchkeys)
(define-key map (kbd "C-d") 'helm-deft-remove-candidate-file)
(define-key map (kbd "C-s") 'helm-deft-set-to-marked)
(delq nil map))
"helm keymap used for helm deft sources")
(defun helm-deft-fname-search ()
"search all preconfigured directories for matching files and return the
filenames as a list"
(cl-assert helm-deft-extension nil "No file extension defined for helm-deft")
(cl-assert helm-deft-dir-list nil "No directories defined for helm-deft")
(cl-loop for dir in helm-deft-dir-list
do (cl-assert (file-exists-p dir) nil
(format "Directory %s does not exist. Check helm-deft-dir-list" dir))
collect (f--files dir (equal (f-ext it) helm-deft-extension) t)
into reslst
finally (return (apply #'append reslst)))
)
(defun helm-deft-build-cmd (ptrnstr filelst)
"Builds a grep command where PTRNSTR may contain multiple search patterns
separated by spaces. The first pattern will be used to retrieve matching lines.
All other patterns will be used to pre-select files with matching lines.
FILELST is a list of file paths"
(let* ((ptrnlst (remove "" (reverse (split-string ptrnstr " *"))))
(firstp (pop ptrnlst))
(filelst (mapconcat 'identity filelst " "))
(innercmd (if ptrnlst
(cl-labels ((build-inner-cmd
(ptrnlst filelst)
(let ((pattern (pop ptrnlst)))
(if ptrnlst
(format "$(grep -Elie \"%s\" %s)" pattern
(build-inner-cmd ptrnlst filelst))
(format "$(grep -Elie \"%s\" %s)"
pattern filelst)))))
(build-inner-cmd ptrnlst filelst))
filelst)))
(format "grep -EHine \"%s\" %s" firstp innercmd))
)
(defun helm-deft-fgrep-search ()
"greps for the helm search pattern in the configuration defined
file list"
(let* ((shcmd (helm-deft-build-cmd helm-pattern helm-deft-file-list)))
(helm-log "grep command: %s" shcmd)
(start-process-shell-command "helm-deft-proc" "*helm-deft-proc*"
shcmd))
)
"Helm keymap used for helm deft sources.")
;;;###autoload
(defun helm-deft ()
"Preconfigured `helm' module for locating note files where either the
filename or the file contents match the query string. Inspired by the
emacs `deft' extension"
"Preconfigured `helm' module for locating matching files.
Either the filename or the file contents must match the query
string. Inspired by the Emacs `deft' extension"
(interactive)
(helm :sources '(helm-source-deft-fn helm-source-deft-filegrep)
(helm :sources '(helm-source-deft-fn helm-source-deft-matching-files
helm-source-deft-filegrep)
:keymap helm-deft-map))
(provide 'helm-deft)

View file

@ -1,5 +1,7 @@
;;; defuns-org-crm.el --- for my custom org-based CRM
(require 'helm-deft)
(defun narf--helm-org (&optional directory)
(let ((helm-deft-dir-list `(,(or directory default-directory))))
(helm-deft)))
@ -30,33 +32,7 @@
(let ((narf--helm-org-params '()))
(narf--helm-org (expand-file-name "writing/" org-directory))))
;;;###autoload
(defun narf/org-crm-link-contact (id)
(org-open-file (narf--org-crm-id-to-path id 'contact) t))
;;;###autoload
(defun narf/org-crm-link-project (id)
(org-open-file (narf--org-crm-id-to-path id 'project) t))
;;;###autoload
(defun narf/org-crm-link-invoice (id)
(org-open-file (narf--org-crm-id-to-path id 'invoice) t))
(defun narf--org-complete (type)
(let ((default-directory (symbol-value (intern (format "org-directory-%ss" type)))))
(let* ((file (org-iread-file-name ">>> "))
(match (s-match "^\\([0-9]+\\)[-.]" (f-filename file))))
(unless (file-exists-p file)
(message "Created %s" file)
(write-region "" nil file))
(unless match
(user-error "Invalid file ID"))
(format "%s:%s" type (cadr match)))))
;;;###autoload
(defun org-contact-complete-link () (narf--org-complete 'contact))
;;;###autoload
(defun org-project-complete-link () (narf--org-complete 'project))
;;;###autoload
(defun org-invoice-complete-link () (narf--org-complete 'invoice))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(defun narf--org-crm-assert-type (type)
(unless (memq type '(project contact invoice))
@ -67,7 +43,7 @@
(let* ((prefix
(replace-regexp-in-string
"/+$" "" (symbol-value (intern (format "org-directory-%ss" type)))))
(last-file (car-safe (sort (f-glob "*.org" prefix) 'string>))))
(last-file (car-safe (sort (f-glob "*.org" prefix) 'org-string>))))
(when last-file
(let* ((old-id (narf--org-crm-path-to-id last-file type))
(new-id (format "%04X" (1+ old-id))))
@ -91,7 +67,12 @@
(replace-regexp-in-string
"/+$" "" (symbol-value (intern (format "org-directory-%ss" type))))))
(car-safe
(f-glob (format (if (eq type 'invoice) "*-%04X.org" "%04X*.org")
(f-glob (format (cond ((eq type 'invoice)
"*-%04X.org")
((eq type 'courses)
"%s*.org")
(t
"%04X*.org"))
(string-to-number id 16))
prefix))))

View file

@ -1,5 +1,13 @@
;;; defuns-org.el
;;;###autoload
(defun narf/org-get-property (name)
(interactive)
(save-excursion
(goto-char 1)
(re-search-forward (format "^#\\+%s:[ \t]*\\([^\n]+\\)" (upcase name)) nil t)
(buffer-substring-no-properties (match-beginning 1) (match-end 1))))
;;;###autoload
(defun narf/org-open-notes ()
(interactive)

View file

@ -0,0 +1,45 @@
;;; macros-org.el
;;;###autoload
(defmacro define-org-link! (type directory &optional id-func)
(setq directory (f-slash directory))
(let* ((type-str (symbol-name type))
(link-sym (intern (format "narf/org-link-%s" type-str)))
(dir-var (intern (format "org-directory-%s" type-str))))
`(progn
(defvar ,dir-var ,(expand-file-name directory org-directory))
(defun ,(intern (format "narf/helm-org-%s" type-str)) ()
(interactive)
(let ((default-directory ,directory))
(helm-deft)))
(defun ,link-sym (id)
(let ((path (f-glob (format "%s*.org" id) ,directory)))
(unless path
(error "ID not found: %s" id))
(org-open-file (car path) t)))
(org-add-link-type ,type-str ',link-sym)
(defun ,(intern (format "narf/org-%s-at-pt" type-str)) ()
(interactive)
(let* ((id (or (narf/org-get-property ,type-str)
(thing-at-point 'word t)))
(path (f-glob (format "%s*.org" id) ,dir-var)))
(unless path
(user-error "Couldn't find anything with %s (%s in %s)" id path ,directory))
(org-open-file (car path) t)))
(defun ,(intern (format "org-%s-complete-link" type-str)) ()
(let* ((default-directory (f-slash ,dir-var))
(file (org-iread-file-name ">>> "))
(relpath (f-relative file ,dir-var)))
(when (and (not (file-exists-p file))
(y-or-n-p (format "Create %s?" relpath)))
(write-region "" nil file)
(message "Created %s" file))
(format "%s:%s" ,type-str ,(if id-func `(funcall ,id-func relpath) 'relpath))
)))))
(provide 'macros-org)
;;; macros-org.el ends here

View file

@ -58,7 +58,7 @@
"add-hook" "associate" "open-with" "define-repl"
"define-builder" "narf-space-setup" "define-env-command"
"define-text-object" "add-yas-minor-mode"
"define-company-backend"))
"define-org-link!" "define-company-backend"))
"!\\)")
(1 font-lock-keyword-face append))))

View file

@ -7,13 +7,13 @@
:keymap (make-sparse-keymap) ; defines evil-org-mode-map
:group 'evil-org)
(defvar org-directory (expand-file-name "org/" narf-dropbox-dir))
(defvar org-directory-contacts (expand-file-name "work/contacts/" org-directory))
(defvar org-directory-projects (expand-file-name "work/projects/" org-directory))
(defvar org-directory-invoices (expand-file-name "work/invoices/" org-directory))
(defvar org-directory (expand-file-name write-mode-dir))
(defvar org-directory-contacts (expand-file-name "Work/Contacts/" org-directory))
(defvar org-directory-projects (expand-file-name "Work/Projects/" org-directory))
(defvar org-directory-invoices (expand-file-name "Work/Invoices/" org-directory))
(defvar org-directory-courses (expand-file-name "Courses/" org-directory))
(defvar org-default-notes-file (concat org-directory "notes.org"))
(defvar org-default-todo-file (concat org-directory "todo.org"))
(defvar org-default-notes-file (concat org-directory "/Notes.org"))
(add-hook! org-load 'narf|org-init)
@ -21,7 +21,7 @@
(defun narf@org-vars ()
(setq org-agenda-files
(f-entries org-directory (lambda (path) (string-suffix-p ".org" path)) t)
(f-entries org-directory (lambda (path) (string-suffix-p ".org" path)))
org-archive-location (concat org-directory "/archive/%s::")
org-attach-directory ".attach/"
@ -46,7 +46,7 @@
org-log-done t
org-agenda-window-setup 'other-window
org-agenda-skip-unavailable-files t
org-startup-folded 'content
org-startup-folded t
org-todo-keywords '((sequence "TODO(t)" "|" "DONE(d)")
(sequence "IDEA(i)" "NEXT(n)" "ACTIVE(a)" "WAITING(w)" "LATER(l)" "|" "CANCELLED(c)")
(sequence "UNSENT(u)" "UNPAID(U)" "|" "PAID(p)"))
@ -58,33 +58,18 @@
("@projects" . ?r))
org-capture-templates
'(("t" "TODO" entry
(file+headline org-default-todo-file "Inbox")
"*** TODO %? %u")
;; TODO Select file from org files
;; ("T" "Specific TODO" entry
;; (function narf/-org-capture-choose)
;; "** TODO %?\n%i" :prepend t)
;; ("c" "Changelog" entry
;; (function narf/-org-capture-changelog)
;; "** %<%H:%M>: %? :unsorted:\n%i" :prepend t)
'(("c" "Changelog" entry
(file+headline (concat (narf/project-root) "CHANGELOG.org") "Unreleased")
"* %?")
("j" "Journal" entry
(file+datetree (concat org-directory "journal.org"))
"** %<%H:%M>: %?\n%i" :prepend t)
;; TODO Select file from notes folder
("n" "Notes" entry
(file+headline org-default-notes-file "Inbox")
"* %u %?\n%i" :prepend t)
("s" "Writing Scraps" entry
(file+headline (concat org-directory "writing/scraps.org") "Unsorted")
"* %t %?\n%i" :prepend t)
;; TODO Sort word under correct header
("v" "Vocab" entry
(file+headline (concat org-directory "topics/vocab.org") "Unsorted")
"** %i%?\n")
@ -117,7 +102,11 @@
(defun narf@org-export ()
(defvar narf-org-export-directory (concat org-directory ".export"))
(require 'ox-pandoc)
(unless (featurep 'ox-opml)
(load-library "org-opml"))
(use-package ox-pandoc)
(setq org-export-backends '(ascii html latex md opml)
org-export-with-toc nil)
@ -135,20 +124,21 @@
org-src-preserve-indentation t
org-src-tab-acts-natively t)
(defun narf-refresh-babel-lob ()
(let ((files (f-entries org-directory (lambda (path) (f-ext? path "org")) t)))
(async-start
`(lambda ()
,(async-inject-variables "\\`\\(org-directory\\|load-path$\\)")
(require 'org)
(setq org-babel-library-of-babel nil)
(mapc (lambda (f) (org-babel-lob-ingest f)) (list ,@files))
org-babel-library-of-babel)
(lambda (lib)
;; (persistent-soft-store 'org-babel-library lib "org")
(message "Library of babel updated!")
(setq org-babel-library-of-babel lib)))))
(setq org-babel-library-of-babel (narf-refresh-babel-lob))
;; (defun narf-refresh-babel-lob ()
;; (let ((files (f-entries org-directory (lambda (path) (f-ext? path "org")) t)))
;; (async-start
;; `(lambda ()
;; ,(async-inject-variables "\\`\\(org-directory\\|load-path$\\)")
;; (require 'org)
;; (setq org-babel-library-of-babel nil)
;; (mapc (lambda (f) (org-babel-lob-ingest f)) (list ,@files))
;; org-babel-library-of-babel)
;; (lambda (lib)
;; ;; (persistent-soft-store 'org-babel-library lib "org")
;; (message "Library of babel updated!")
;; (setq org-babel-library-of-babel lib)))))
;; (setq org-babel-library-of-babel (narf-refresh-babel-lob))
(add-hook! org-mode
(add-hook 'after-save-hook
(lambda ()
@ -163,7 +153,9 @@
'((python . t) (ruby . t) (sh . t) (js . t) (css . t)
(plantuml . t) (emacs-lisp . t) (matlab . t)
(latex . t) (calc . t) (lisp . t) (lilypond . t)
(http . t) (rust . t) (go . t)))
(go . t)
(rust . t)))
;; (http . t)
(setq org-babel-lilypond-gen-png t)
;; Ensure lilypond doesn't print out entire pages for previews
@ -207,117 +199,94 @@ will function properly."
(defun narf@org-latex ()
(setq-default
org-latex-preview-ltxpng-directory (concat narf-temp-dir "ltxpng/")
org-latex-remove-logfiles t
org-latex-remove-logfiles nil
org-latex-create-formula-image-program 'dvipng
org-startup-with-latex-preview nil
org-highlight-latex-and-related '(latex)
org-format-latex-options (plist-put org-format-latex-options :scale 1.4)
org-format-latex-options (plist-put org-format-latex-options :scale 1.2)
org-latex-image-default-width nil
org-latex-packages-alist
'(("" "gauss" t)
'(;; ("" "gauss" t)
;; ("" "physics" t) TODO Install this
)))
(defun narf@org-looks ()
(setq org-image-actual-width nil
org-startup-with-inline-images nil
org-startup-indented t
org-pretty-entities t
org-pretty-entities-include-sub-superscripts t
org-use-sub-superscripts '{}
org-fontify-whole-heading-line nil
org-fontify-done-headline t
org-fontify-quote-and-verse-blocks t
org-ellipsis 'hs-face
org-indent-indentation-per-level 2
org-cycle-separator-lines 2
org-hide-emphasis-markers t
org-hide-leading-stars t
org-bullets-bullet-list '("" "" "" "" "" "")
org-entities-user
'(("flat" "\\flat" nil "" "" "266D" "")
("sharp" "\\sharp" nil "" "" "266F" ""))
org-priority-faces
'((?A . org-todo-vhigh)
(?B . org-todo-high)
(?C . org-todo)))
(setq-default
org-image-actual-width nil
org-startup-with-inline-images nil
org-startup-indented t
org-pretty-entities nil
org-pretty-entities-include-sub-superscripts t
org-use-sub-superscripts '{}
org-fontify-whole-heading-line nil
org-fontify-done-headline t
org-fontify-quote-and-verse-blocks t
org-ellipsis 'hs-face
org-indent-indentation-per-level 2
org-cycle-separator-lines 2
org-hide-emphasis-markers t
org-hide-leading-stars t
org-bullets-bullet-list '("" "" "" "" "" "")
org-entities-user
'(("flat" "\\flat" nil "" "" "266D" "")
("sharp" "\\sharp" nil "" "" "266F" "")))
(add-hook! org-mode
(highlight-regexp org-any-link-re 'org-link))
;; Restore org-block-background face (removed in official org)
(defface org-block-background '((t ()))
"Face used for the source block background.")
(defun narf--adjoin-to-list-or-symbol (element list-or-symbol)
(let ((list (if (not (listp list-or-symbol))
(list list-or-symbol)
list-or-symbol)))
(require 'cl-lib)
(cl-adjoin element list)))
(set-face-attribute 'org-block-background nil :inherit
(narf--adjoin-to-list-or-symbol
'fixed-pitch
(face-attribute 'org-block-background :inherit)))
;; (defface org-block-background '((t ())) "Face used for the source block background.")
;; (defun narf--adjoin-to-list-or-symbol (element list-or-symbol)
;; (let ((list (if (not (listp list-or-symbol))
;; (list list-or-symbol)
;; list-or-symbol)))
;; (require 'cl-lib)
;; (cl-adjoin element list)))
;; (set-face-attribute 'org-block-background nil :inherit
;; (narf--adjoin-to-list-or-symbol
;; 'fixed-pitch
;; (face-attribute 'org-block-background :inherit)))
;; Prettify symbols, blocks and TODOs
(defface org-headline-todo '((t ())) "Face for todo headlines")
(defface org-headline-done '((t ())) "Face for todo headlines")
(defface org-todo-high '((t ())) "Face for high-priority todo")
(defface org-todo-vhigh '((t ())) "Face for very high-priority todo")
;; (defface org-whitespace '((t ())) "Face for spaces")
(defface org-list-bullet '((t ())) "Face for list bullets")
(defface org-todo-checkbox '((t ())) "Face for list bullets")
(font-lock-add-keywords
'org-mode `(("^ *\\(#\\+begin_src\\>\\)"
(1 (narf/show-as ?#)))
("^ *\\(#\\+end_src\\>\\)"
(1 (narf/show-as ?#)))
("^ *\\(#\\+begin_quote\\>\\)"
(1 (narf/show-as ?>)))
("^ *\\(#\\+end_quote\\>\\)"
(1 (narf/show-as ?>)))
;; Hide TODO tags
("^\\**\\(\\* DONE\\) \\([^$\n\r]+\\)"
(1 (narf/show-as ?☑))
(2 'org-headline-done))
("^\\**\\(\\* \\(?:TODO\\|PAID\\)\\) "
(1 (narf/show-as ?☐)))
("[-+*] \\[X\\] \\([^$\n\r]+\\)"
(1 'org-headline-done))
;; Show checkbox for other todo states (but don't hide the label)
(,(concat
"\\(\\*\\) "
(regexp-opt '("IDEA" "NEXT" "ACTIVE" "WAITING" "LATER" "CANCELLED" "UNPAID" "UNSENT") t)
" ")
(1 (narf/show-as ?☐)))
("^ *\\([-+]\\|[0-9]+[).]\\)\\( \\)+[^$\n\r]"
(1 'org-list-bullet))
)))
(defvar narf-org-font-lock-keywords
'(("^ *\\([-+]\\|[0-9]+[).]\\)[^$\n\r]"
(1 'org-list-bullet))
;; Crossed out finished items
("\\* \\(?:DONE\\|PAID\\) \\([^$\n\r]+\\)"
(1 'org-headline-done))
("^ *\\(?:[-+]\\|[0-9]+[).]\\) \\[X\\] \\([^$\n\r]+\\)"
(1 'org-headline-done))))
(font-lock-add-keywords 'org-mode narf-org-font-lock-keywords))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(defun narf|org-hook ()
(evil-org-mode +1)
(org-bullets-mode +1)
(org-indent-mode +1)
;; (text-scale-set 1)
(setq line-spacing '1)
(setq header-line-format mode-line-format
mode-line-format '("%e"))
(visual-line-mode +1)
(visual-fill-column-mode +1)
(when write-mode
(org-bullets-mode +1))
;;; OS-Specific
(cond (IS-MAC (narf-org-init-for-osx))
(IS-LINUX nil)
(IS-WINDOWS nil))
;; Org-specific font. See `narf-writing-font'
(setq buffer-face-mode-face `(:family ,(symbol-name (font-get narf-writing-font :family))))
(buffer-face-mode +1)
(setq truncate-lines nil)
(setq line-spacing '2)
(defun narf|org-update-statistics-cookies ()
(when (file-exists-p buffer-file-name)
(org-update-statistics-cookies t)))
@ -365,9 +334,12 @@ will function properly."
(setq epa-file-encrypt-to user-mail-address)
;; Custom links
(org-add-link-type "contact" 'narf/org-crm-link-contact)
(org-add-link-type "project" 'narf/org-crm-link-project)
(org-add-link-type "invoice" 'narf/org-crm-link-invoice)
(define-org-link! project "Work/Projects" 'f-no-ext)
(define-org-link! invoice "Work/Invoices" 'f-no-ext)
(define-org-link! contact "Work/Contacts" 'f-no-ext)
(define-org-link! dev "Personal/Dev")
(define-org-link! course "Courses"
(lambda (path) (substring path 0 (s-index-of " " path))))
(after! helm
(mapc (lambda (r) (add-to-list 'helm-boring-file-regexp-list r))
@ -411,6 +383,8 @@ will function properly."
(f-relative path (f-dirname (buffer-file-name))))
(advice-add 'org-download--fullname :filter-return 'narf*org-download--fullname)
;; Let org-download also handle PDFs
;;; Auto-completion
(after! company
(require 'company-math)
@ -472,9 +446,8 @@ will function properly."
:v "M-`" "S+"
(:leader
:n ";" 'helm-org-in-buffer-headings
:n "oa" 'narf/org-attachment-reveal
)
:n ";" 'helm-org-in-buffer-headings
:n "oa" 'narf/org-attachment-reveal)
(:localleader
:n "/" 'org-sparse-tree
@ -486,7 +459,7 @@ will function properly."
:nv "l" 'org-insert-link
:n "L" 'org-store-link
:n "x" 'narf/org-remove-link
:n "w" 'writing-mode
;; :n "w" 'writing-mode
:n "v" 'variable-pitch-mode
:n "SPC" 'narf/org-toggle-checkbox
:n "RET" 'org-archive-subtree
@ -558,111 +531,112 @@ will function properly."
:e "C-n" 'org-agenda-next-item
:e "C-p" 'org-agenda-previous-item)))
(progn ;; Org hacks
(defun org-fontify-meta-lines-and-blocks-1 (limit)
"Fontify #+ lines and blocks."
(let ((case-fold-search t))
(if (re-search-forward
"^\\([ \t]*#\\(\\(\\+[a-zA-Z]+:?\\| \\|$\\)\\(_\\([a-zA-Z]+\\)\\)?\\)[ \t]*\\(\\([^ \t\n]*\\)[ \t]*\\(.*\\)\\)\\)"
limit t)
(let ((beg (match-beginning 0))
(block-start (match-end 0))
(block-end nil)
(lang (match-string 7))
(beg1 (line-beginning-position 2))
(dc1 (downcase (match-string 2)))
(dc3 (downcase (match-string 3)))
end end1 quoting block-type ovl)
(cond
((and (match-end 4) (equal dc3 "+begin"))
;; Truly a block
(setq block-type (downcase (match-string 5))
quoting (member block-type org-protecting-blocks))
(when (re-search-forward
(concat "^[ \t]*#\\+end" (match-string 4) "\\>.*")
nil t) ;; on purpose, we look further than LIMIT
(setq end (min (point-max) (match-end 0))
end1 (min (point-max) (1- (match-beginning 0))))
(setq block-end (match-beginning 0))
(when quoting
(org-remove-flyspell-overlays-in beg1 end1)
(remove-text-properties beg end
'(display t invisible t intangible t)))
(add-text-properties
beg end '(font-lock-fontified t font-lock-multiline t))
(add-text-properties beg beg1 '(face org-meta-line))
(org-remove-flyspell-overlays-in beg beg1)
(add-text-properties ; For end_src
end1 (min (point-max) (1+ end)) '(face org-meta-line))
(org-remove-flyspell-overlays-in end1 end)
(cond
((and lang (not (string= lang "")) org-src-fontify-natively)
(org-src-font-lock-fontify-block lang block-start block-end)
;;;;;;; EDIT
;; remove old background overlays
(mapc (lambda (ov)
(if (eq (overlay-get ov 'face) 'org-block-background)
(delete-overlay ov)))
(overlays-at (/ (+ beg1 block-end) 2)))
;; add a background overlay
(setq ovl (make-overlay beg1 block-end))
(overlay-put ovl 'face 'org-block-background)
(overlay-put ovl 'evaporate t)) ; make it go away when empty
;; (add-text-properties beg1 block-end '(src-block t)))
;;;;;;; /EDIT
(quoting
(add-text-properties beg1 (min (point-max) (1+ end1))
'(face org-block))) ; end of source block
((not org-fontify-quote-and-verse-blocks))
((string= block-type "quote")
(add-text-properties beg1 (min (point-max) (1+ end1)) '(face org-quote)))
((string= block-type "verse")
(add-text-properties beg1 (min (point-max) (1+ end1)) '(face org-verse))))
(add-text-properties beg beg1 '(face org-block-begin-line))
(add-text-properties (min (point-max) (1+ end)) (min (point-max) (1+ end1))
'(face org-block-end-line))
t))
((string-match-p
(format "^\\+%s+:$"
(regexp-opt '("title" "author" "email" "date" "address" "location" "contact"
"project" "country" "city" "created" "issued" "paid" "currency")))
dc1)
;; (member dc1 '("+title:" "+author:" "+email:" "+date:" "+address:" "+location:" "+contact:" "+project:"))
(org-remove-flyspell-overlays-in
(match-beginning 0)
(if (equal "+title:" dc1) (match-end 2) (match-end 0)))
(add-text-properties
beg (match-end 3)
(if (member (intern (substring dc1 1 -1)) org-hidden-keywords)
'(font-lock-fontified t invisible t)
'(font-lock-fontified t face org-document-info-keyword)))
(add-text-properties
(match-beginning 6) (min (point-max) (1+ (match-end 6)))
(if (string-equal dc1 "+title:")
'(font-lock-fontified t face org-document-title)
'(font-lock-fontified t face org-document-info))))
((equal dc1 "+caption:")
(org-remove-flyspell-overlays-in (match-end 2) (match-end 0))
(remove-text-properties (match-beginning 0) (match-end 0)
'(display t invisible t intangible t))
(add-text-properties (match-beginning 1) (match-end 3)
'(font-lock-fontified t face org-meta-line))
(add-text-properties (match-beginning 6) (+ (match-end 6) 1)
'(font-lock-fontified t face org-block))
t)
((member dc3 '(" " ""))
(org-remove-flyspell-overlays-in beg (match-end 0))
(add-text-properties
beg (match-end 0)
'(font-lock-fontified t face font-lock-comment-face)))
(t ;; just any other in-buffer setting, but not indented
(org-remove-flyspell-overlays-in (match-beginning 0) (match-end 0))
(remove-text-properties (match-beginning 0) (match-end 0)
'(display t invisible t intangible t))
(add-text-properties beg (match-end 0)
'(font-lock-fontified t face org-meta-line))
t))))))
))
(progn ;; Org hacks
(defun org-fontify-meta-lines-and-blocks-1 (limit)
"Fontify #+ lines and blocks."
(let ((case-fold-search t))
(if (re-search-forward
"^\\([ \t]*#\\(\\(\\+[a-zA-Z]+:?\\| \\|$\\)\\(_\\([a-zA-Z]+\\)\\)?\\)[ \t]*\\(\\([^ \t\n]*\\)[ \t]*\\(.*\\)\\)\\)"
limit t)
(let ((beg (match-beginning 0))
(block-start (match-end 0))
(block-end nil)
(lang (match-string 7))
(beg1 (line-beginning-position 2))
(dc1 (downcase (match-string 2)))
(dc3 (downcase (match-string 3)))
end end1 quoting block-type ovl)
(cond
((and (match-end 4) (equal dc3 "+begin"))
;; Truly a block
(setq block-type (downcase (match-string 5))
quoting (member block-type org-protecting-blocks))
(when (re-search-forward
(concat "^[ \t]*#\\+end" (match-string 4) "\\>.*")
nil t) ;; on purpose, we look further than LIMIT
(setq end (min (point-max) (match-end 0))
end1 (min (point-max) (1- (match-beginning 0))))
(setq block-end (match-beginning 0))
(when quoting
(org-remove-flyspell-overlays-in beg1 end1)
(remove-text-properties beg end
'(display t invisible t intangible t)))
(add-text-properties
beg end '(font-lock-fontified t font-lock-multiline t))
(add-text-properties beg beg1 '(face org-meta-line))
(org-remove-flyspell-overlays-in beg beg1)
(add-text-properties ; For end_src
end1 (min (point-max) (1+ end)) '(face org-meta-line))
(org-remove-flyspell-overlays-in end1 end)
(cond
((and lang (not (string= lang "")) org-src-fontify-natively)
(org-src-font-lock-fontify-block lang block-start block-end)
;;;;;;; EDIT
;; remove old background overlays
(mapc (lambda (ov)
(if (eq (overlay-get ov 'face) 'org-block-background)
(delete-overlay ov)))
(overlays-at (/ (+ beg1 block-end) 2)))
;; add a background overlay
(setq ovl (make-overlay beg1 block-end))
(overlay-put ovl 'face 'org-block-background)
(overlay-put ovl 'evaporate t)) ; make it go away when empty
;; (add-text-properties beg1 block-end '(src-block t)))
;;;;;;; /EDIT
(quoting
(add-text-properties beg1 (min (point-max) (1+ end1))
'(face org-block))) ; end of source block
((not org-fontify-quote-and-verse-blocks))
((string= block-type "quote")
(add-text-properties beg1 (min (point-max) (1+ end1)) '(face org-quote)))
((string= block-type "verse")
(add-text-properties beg1 (min (point-max) (1+ end1)) '(face org-verse))))
(add-text-properties beg beg1 '(face org-block-begin-line))
(add-text-properties (min (point-max) (1+ end)) (min (point-max) (1+ end1))
'(face org-block-end-line))
t))
((string-match-p
(format "^\\+%s+:$"
(regexp-opt '("title" "author" "email" "date" "address" "location" "contact"
"project" "country" "city" "created" "issued" "paid" "currency")))
dc1)
;; (member dc1 '("+title:" "+author:" "+email:" "+date:" "+address:" "+location:" "+contact:" "+project:"))
(org-remove-flyspell-overlays-in
(match-beginning 0)
(if (equal "+title:" dc1) (match-end 2) (match-end 0)))
(add-text-properties
beg (match-end 3)
(if (member (intern (substring dc1 1 -1)) org-hidden-keywords)
'(font-lock-fontified t invisible t)
'(font-lock-fontified t face org-document-info-keyword)))
(add-text-properties
(match-beginning 6) (min (point-max) (1+ (match-end 6)))
(if (string-equal dc1 "+title:")
'(font-lock-fontified t face org-document-title)
'(font-lock-fontified t face org-document-info))))
((equal dc1 "+caption:")
(org-remove-flyspell-overlays-in (match-end 2) (match-end 0))
(remove-text-properties (match-beginning 0) (match-end 0)
'(display t invisible t intangible t))
(add-text-properties (match-beginning 1) (match-end 3)
'(font-lock-fontified t face org-meta-line))
(add-text-properties (match-beginning 6) (+ (match-end 6) 1)
'(font-lock-fontified t face org-block))
t)
((member dc3 '(" " ""))
(org-remove-flyspell-overlays-in beg (match-end 0))
(add-text-properties
beg (match-end 0)
'(font-lock-fontified t face font-lock-comment-face)))
(t ;; just any other in-buffer setting, but not indented
(org-remove-flyspell-overlays-in (match-beginning 0) (match-end 0))
(remove-text-properties (match-beginning 0) (match-end 0)
'(display t invisible t intangible t))
(add-text-properties beg (match-end 0)
'(font-lock-fontified t face org-meta-line))
t))))))
)
)
(provide 'module-org)
;;; module-org.el ends here