summary refs log tree commit diff stats
path: root/lisp/+org.el
diff options
context:
space:
mode:
Diffstat (limited to 'lisp/+org.el')
-rw-r--r--lisp/+org.el167
1 files changed, 167 insertions, 0 deletions
diff --git a/lisp/+org.el b/lisp/+org.el index b17a1fa..70962d6 100644 --- a/lisp/+org.el +++ b/lisp/+org.el
@@ -1,5 +1,106 @@
1;;; +org.el --- -*- lexical-binding: t -*- 1;;; +org.el --- -*- lexical-binding: t -*-
2 2
3;;; Org Return DWIM
4;; [[https://github.com/alphapapa/unpackaged.el][unpackaged]] and [[http://kitchingroup.cheme.cmu.edu/blog/2017/04/09/A-better-return-in-org-mode/][kitchin]]
5
6(defun +org-element-descendant-of (type element)
7 "Return non-nil if ELEMENT is a descendant of TYPE.
8TYPE should be an element type, like `item' or `paragraph'.
9ELEMENT should be a list like that returned by `org-element-context'."
10 ;; MAYBE: Use `org-element-lineage'.
11 (when-let* ((parent (org-element-property :parent element)))
12 (or (eq type (car parent))
13 (+org-element-descendant-of type parent))))
14
15(defun +org-return-dwim (&optional prefix)
16 "A helpful replacement for `org-return'.
17With PREFIX, call `org-return'."
18 (interactive "P")
19 ;; Auto-fill if enabled
20 (when auto-fill-function
21 (dolist (func (ensure-list auto-fill-function))
22 (funcall func)))
23 (cond
24 (prefix ; Handle prefix
25 (pcase prefix
26 ('(4) (newline))
27 ('(16) (newline 2))
28 (_ (newline prefix))))
29 ((and org-return-follows-link ; Open link
30 (eq 'link (car (org-element-context))))
31 (org-open-at-point-global))
32 ((org-at-heading-p) ; Open a line after a heading
33 (let ((heading-start (org-entry-beginning-position)))
34 (goto-char (org-entry-end-position))
35 (cond ((and (org-at-heading-p)
36 (= heading-start (org-entry-beginning-position)))
37 ;; Entry ends on its heading, so add 2 newlines
38 (end-of-line)
39 (newline 2))
40 (t
41 ;; Entry ends after its heading, so back up
42 (forward-line -1)
43 (end-of-line)
44 (when (org-at-heading-p)
45 (forward-line)
46 (newline)
47 (forward-line -1))
48 (while (not (looking-back (rx (repeat 3 (seq (optional blank) "\n")))
49 nil))
50 (newline))
51 (forward-line -1)))))
52 ((org-at-item-checkbox-p) ; Insert a new checkbox item
53 (end-of-line)
54 (org-insert-todo-heading nil))
55 ((org-in-item-p) ; Insert a new list item
56 (let* ((context (org-element-context))
57 (first-item-p (eq 'plain-list (car context)))
58 (itemp (eq 'item (car context)))
59 (emptyp (or
60 ;; This (regular) list item is empty
61 (eq (org-element-property :contents-begin context)
62 (org-element-property :contents-end context))
63 ;; This (definition) list item is empty
64 (looking-at " *::")))
65 (item-child-p (+org-element-descendant-of 'item context)))
66 (cond ((and itemp emptyp)
67 (delete-region (line-beginning-position) (line-end-position))
68 (newline))
69 ((or first-item-p
70 (and itemp (not emptyp))
71 item-child-p)
72 (org-end-of-item)
73 (org-insert-item))
74 (t
75 (delete-region (line-beginning-position) (line-end-position))
76 (newline)))))
77 ((and (fboundp 'org-inlinetask-in-task-p) ; Don't insert a new heading with
78 (org-inlinetask-in-task-p)) ; inline tasks
79 (org-return))
80 ((org-at-table-p) ; Insert a new org-table row
81 (cond ((save-excursion
82 (beginning-of-line)
83 (cl-loop with end = (line-end-position)
84 for cell = (org-element-table-cell-parser)
85 always (equal (org-element-property :contents-begin cell)
86 (org-element-property :contents-end cell))
87 while (re-search-forward "|" end t)))
88 ;; Empty row: end the table
89 (delete-region (line-beginning-position) (line-end-position))
90 (org-return))
91 (t
92 ;; Non-empty row
93 (org-return))))
94 (t ; Otherwise---just call `org-return'.
95 (org-return))))
96
97(defun +org-table-copy-down|+org-return (&optional n)
98 "Call `org-table-copy-down' or `+org-return' depending on context."
99 (interactive "P")
100 (if (org-table-check-inside-data-field 'noerror)
101 (org-table-copy-down (or n 1))
102 (+org-return-dwim n)))
103
3;;; Copy org trees as HTML 104;;; Copy org trees as HTML
4 105
5;; Thanks to Oleh Krehel, via [[https://emacs.stackexchange.com/questions/54292/copy-results-of-org-export-directly-to-clipboard][this StackExchange question]]. 106;; Thanks to Oleh Krehel, via [[https://emacs.stackexchange.com/questions/54292/copy-results-of-org-export-directly-to-clipboard][this StackExchange question]].
@@ -41,4 +142,70 @@ and POST-PROCESS are passed to `org-export-to-file'."
41 ("—" "---")))) 142 ("—" "---"))))
42 (replace-match replace nil nil))))) 143 (replace-match replace nil nil)))))
43 144
145;;; A ... different ... `org-open-at-point-dwim'
146;; I honestly don't remember what the difference is between this and the
147;; O.G. one is.. hopefully this one fixes annoying stupid problems.
148
149(defun +org-open-at-point-dwim (&optional arg)
150 "Open thing at point, or if there isn't something, list things."
151 (interactive "P")
152 (save-excursion
153 (let* ((this-char-type (org-element-type (org-element-context)))
154 (prev-char-type (ignore-errors
155 (save-excursion
156 (backward-char)
157 (org-element-type (org-element-context)))))
158 (types '(citation citation-reference clock comment comment-block
159 footnote-definition footnote-reference headline
160 inline-src-block inlinetask keyword link
161 node-property planning src-block timestamp))
162 (type this-char-type))
163 (when (and (memq this-char-type types) (memq prev-char-type types))
164 (backward-char)
165 (setq type prev-char-type)) ; what the fuckckckckck
166 ;; Okay, so this ^ is pretty janky and doesn't /really/ work that well,
167 ;; especially on DEADLINE (and probably SCHEDULED) lines. However, since
168 ;; I really just want to open the list of URLs /most of the time/, I'm
169 ;; fixing it like this instead.
170 (unless (and (memq type types)
171 (ignore-errors (org-open-at-point arg)
172 t))
173 (while (not
174 (progn
175 (org-back-to-heading)
176 (car (org-offer-links-in-entry (current-buffer) (point) 1))))
177 (org-up-heading-all 1))
178 (org-open-at-point arg)))))
179
180;;; Skip invisible shit when moving around
181(defun +org-ignore-invisible (fn &rest r)
182 ":around ADVICE to ignore invisible text in `org-mode' buffers."
183 ;; TODO: generalize to all modes
184 (cond ((and (derived-mode-p #'org-mode)
185 (org-invisible-p))
186 (while (org-invisible-p)
187 (forward-char))
188 (apply fn r))
189 (t (apply fn r))))
190
191;;; Faces
192
193;;; Better org faces
194;; see `org-emphasis-alist'
195
196(defface org-bold '((t (:weight bold)))
197 "Bold face in `org-mode' documents.")
198
199(defface org-italic '((t (:slant italic)))
200 "Italic face in `org-mode' documents.")
201
202(defface org-underline '((t (:underline t)))
203 "Underline face in `org-mode' documents.")
204
205(defface org-strikethrough '((t (:strike-through t)))
206 "Strike-through face for `org-mode' documents.")
207
208;; `org-verbatim' and `org-code' are apparently already things, so we skip them
209;; here.
210
44(provide '+org) 211(provide '+org)