diff options
author | Case Duckworth | 2022-10-21 21:37:30 -0500 |
---|---|---|
committer | Case Duckworth | 2022-10-21 21:37:30 -0500 |
commit | 4cf60c3fea16b60eb18c9a7d8403b75c89aeffef (patch) | |
tree | 033b31cf848311659dc296793631f9e6e9983d58 /lisp/+org.el | |
parent | Add a bunch of other stuff or whatever (diff) | |
download | emacs-4cf60c3fea16b60eb18c9a7d8403b75c89aeffef.tar.gz emacs-4cf60c3fea16b60eb18c9a7d8403b75c89aeffef.zip |
blhe
Diffstat (limited to 'lisp/+org.el')
-rw-r--r-- | lisp/+org.el | 167 |
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. | ||
8 | TYPE should be an element type, like `item' or `paragraph'. | ||
9 | ELEMENT 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'. | ||
17 | With 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) |