changelog shortlog graph tags branches changeset files revisions annotate raw help

Mercurial > core / emacs/default.el

changeset 182: 0e972410eb3e
parent: 2d1fe1d7b738
child: a962648ad6d5
author: Richard Westhaver <ellis@rwest.io>
date: Tue, 30 Jan 2024 20:21:58 -0500
permissions: -rw-r--r--
description: nu invasion
1 ;;; default.el --- default config -*- lexical-binding: t -*-
2 
3 ;;; Code:
4 ;;; Settings
5 (put 'upcase-region 'disabled nil)
6 (put 'list-threads 'disabled nil)
7 (put 'list-timers 'disabled nil)
8 (setq show-paren-context-when-offscreen 'overlay)
9 (setopt
10  ;; tabs = bad
11  indent-tabs-mode nil
12  make-backup-files nil
13  auto-save-list-file-prefix (expand-file-name "auto-save/." user-emacs-directory)
14  tramp-auto-save-directory (expand-file-name "auto-save/tramp/" user-emacs-directory)
15  dired-free-space nil
16  mml-attach-file-at-the-end t
17  dired-mouse-drag-files t
18  confirm-kill-emacs nil
19  confirm-kill-processes nil
20  use-short-answers t
21  display-time-format "%Y-%m-%d %H:%M"
22  ring-bell-function 'ignore
23  completion-ignore-case t
24  ;; NOTE 2023-11-04: you need to add the following lines to ~/.gnupg/gpg-agent.conf:
25  ;; allow-emacs-pinentry
26  ;; allow-loopback-pinentry
27  epg-pinentry-mode 'loopback
28  shr-use-colors nil
29  shr-use-fonts nil
30  shr-max-image-proportion 0.6
31  shr-image-animate nil
32  shr-discard-aria-hidden t
33  bookmark-default-file (expand-file-name "bookmarks" user-emacs-directory)
34  project-list-file (expand-file-name "projects" user-emacs-directory)
35  project-mode-line t
36  project-file-history-behavior 'relativize
37  emms-directory (expand-file-name "emms" user-emacs-directory)
38  gnus-cache-directory (expand-file-name "gnus" user-emacs-directory)
39  url-cache-directory (expand-file-name "url" user-emacs-directory)
40  tab-always-indent 'complete
41  shr-cookie-policy nil
42  ;; NOTE 2023-11-04: EXPERIMENTAL
43  ediff-floating-control-frame t
44  register-use-preview nil
45  shr-use-xwidgets-for-media t
46  browse-url-browser-function 'browse-url-default-browser
47  eww-auto-rename-buffer 'title
48  eww-search-prefix "https://duckduckgo.com/html?q="
49  view-read-only t)
50 
51 ;;; Variables
52 (defvar user-custom-file (expand-file-name (format "%s.el" user-login-name) user-emacs-directory))
53 (defvar user-home-directory (expand-file-name "~"))
54 (defvar user-lab-directory (expand-file-name "lab" user-home-directory))
55 (defvar user-stash-directory (expand-file-name "stash" user-home-directory))
56 (defvar user-store-directory (expand-file-name "store" user-home-directory))
57 (defvar user-shed-directory (expand-file-name "shed" user-home-directory))
58 (defvar user-mail-directory (expand-file-name "mail" user-home-directory))
59 (defvar user-media-directory (expand-file-name "media" user-home-directory))
60 
61 (defvar default-theme 'leuven-dark)
62 (defvar company-source-directory (join-paths user-lab-directory "comp"))
63 (defvar company-domain "compiler.company")
64 (defvar company-name "The Compiler Company, LLC")
65 (defvar company-vc-domain "vc.compiler.company")
66 (defvar company-home "the.compiler.company")
67 
68 ;;; Theme
69 (defun load-default-theme () (interactive) (load-theme default-theme))
70 
71 (add-hook 'after-init-hook #'load-default-theme)
72 
73 ;;; Packages
74 (package-initialize)
75 
76 (with-eval-after-load 'package
77  (setq package-archives
78  '(("gnu" . "https://elpa.gnu.org/packages/")
79  ("nongnu" . "https://elpa.nongnu.org/nongnu/")
80  ("melpa" . "https://melpa.org/packages/"))
81  use-package-always-ensure t
82  use-package-expand-minimally t)
83  (add-packages
84  org-web-tools ;; web parsing
85  citeproc ;; citations
86  all-the-icons all-the-icons-dired all-the-icons-ibuffer ;; icons
87  corfu orderless cape ;; completion
88  slime ;; common lisp server
89  bbdb
90  slime-company
91  which-key ;; key helper
92  ;; langs
93  rust-mode)
94  (package-install-selected-packages t))
95 
96 ;;; Env
97 (require 'exec-path-from-shell)
98 (exec-path-from-shell-copy-env "SSH_AGENT_PID")
99 (exec-path-from-shell-copy-env "SSH_AUTH_SOCK")
100 (exec-path-from-shell-copy-env "PATH")
101 (add-to-list 'exec-path (expand-file-name "~/.cargo/bin/"))
102 (add-to-list 'exec-path (expand-file-name "~/.local/bin/"))
103 (add-to-list 'exec-path "/bin/")
104 (add-to-list 'exec-path "/usr/local/sbin/")
105 
106 ;;; Completions
107 (use-package corfu
108  :init (global-corfu-mode))
109 
110 (use-package cape
111  ;; Bind dedicated completion commands
112  ;; Alternative prefix keys: C-c p, M-p, M-+, ...
113  :bind (("C-c p p" . completion-at-point) ;; capf
114  ("C-c p t" . complete-tag) ;; etags
115  ("C-c p d" . cape-dabbrev) ;; or dabbrev-completion
116  ("C-c p h" . cape-history)
117  ("C-c p f" . cape-file)
118  ("C-c p k" . cape-keyword)
119  ("C-c p s" . cape-elisp-symbol)
120  ("C-c p e" . cape-elisp-block)
121  ("C-c p a" . cape-abbrev)
122  ("C-c p l" . cape-line)
123  ("C-c p w" . cape-dict)
124  ("C-c p :" . cape-emoji)
125  ("C-c p \\" . cape-tex)
126  ("C-c p _" . cape-tex)
127  ("C-c p ^" . cape-tex)
128  ("C-c p &" . cape-sgml)
129  ("C-c p r" . cape-rfc1345))
130  :init
131  ;; Add to the global default value of `completion-at-point-functions' which is
132  ;; used by `completion-at-point'. The order of the functions matters, the
133  ;; first function returning a result wins. Note that the list of buffer-local
134  ;; completion functions takes precedence over the global list.
135  (add-to-list 'completion-at-point-functions #'cape-dabbrev)
136  (add-to-list 'completion-at-point-functions #'cape-abbrev)
137  ;; (add-to-list 'completion-at-point-functions #'cape-history)
138  ;; (add-to-list 'completion-at-point-functions #'cape-keyword)
139  (add-to-list 'completion-at-point-functions #'cape-file)
140  ;; (add-to-list 'completion-at-point-functions #'cape-line)
141  ;; (add-to-list 'completion-at-point-functions #'cape-elisp-block)
142  ;; (add-to-list 'completion-at-point-functions #'cape-tex)
143  ;; (add-to-list 'completion-at-point-functions #'cape-sgml)
144  ;; (add-to-list 'completion-at-point-functions #'cape-rfc1345)
145  ;; (add-to-list 'completion-at-point-functions #'cape-dict)
146  ;; (add-to-list 'completion-at-point-functions #'cape-elisp-symbol)
147  ;; (add-to-list 'completion-at-point-functions #'cape-emoji)
148  )
149 
150 (use-package orderless
151  :custom
152  (completion-styles '(orderless basic))
153  (completion-category-overrides '((file (styles basic partial-completion)))))
154 
155 ;;; Desktop
156 (setopt desktop-dirname (expand-file-name "sessions" user-emacs-directory))
157 
158 ;;; Multisession
159 (setq multisession-storage 'sqlite)
160 
161 ;;; Kill Ring
162 (kill-ring-deindent-mode)
163 
164 ;;; VC
165 ;; use rhg, fallback to hg. see hgrc
166 (if (file-exists-p "~/.local/bin/rhg")
167  (setq hg-binary "~/.local/bin/rhg"))
168 
169 ;;; Dired
170 (add-hook 'dired-mode-hook #'all-the-icons-dired-mode)
171 (add-hook 'ibuffer-mode-hook #'all-the-icons-ibuffer-mode)
172 
173 ;;; Lisp
174 (use-package lisp-mode
175  :ensure nil
176  :custom
177  inferior-lisp-program "sbcl --dynamic-space-size=8G"
178  scheme-program-name "gsi"
179  guile-program "guile"
180  cmulisp-program "lisp"
181  scsh-program "scsh")
182 
183 (use-package slime
184  :ensure t
185  :config
186  (setq slime-contribs '(slime-fancy slime-quicklisp))
187 
188  (put 'make-instance 'common-lisp-indent-function 1)
189  (put 'reinitialize-instance 'common-lisp-indent-function 1)
190 
191  (defvar slime-toggle nil)
192  (defun slime-toggle ()
193  "toggle between lisp file and slime-repl"
194  (interactive)
195  (if (eq major-mode 'slime-repl-mode)
196  (setq slime-toggle (pop-to-buffer (or slime-toggle (read-buffer "lisp file: "))))
197  (progn
198  (setq slime-toggle (current-buffer))
199  (slime-repl))))
200 
201  (defun clouseau-inspect (string)
202  "Inspect a lisp value with Clouseau. make sure to load clouseau
203 with a custom core or in your init file before using this
204 function: '(ql:quickload :clouseau)'."
205  (interactive
206  (list (slime-read-from-minibuffer
207  "Inspect value (evaluated): "
208  (slime-sexp-at-point))))
209  (let ((inspector 'cl-user::*clouseau-inspector*))
210  (slime-eval-async
211  `(cl:progn
212  (cl:defvar ,inspector nil)
213  ;; (Re)start the inspector if necessary.
214  (cl:unless (cl:and (clim:application-frame-p ,inspector)
215  (clim-internals::frame-process ,inspector))
216  (cl:setf ,inspector (cl:nth-value 1 (clouseau:inspect nil :new-process t))))
217  ;; Tell the inspector to visualize the correct datum.
218  (cl:setf (clouseau:root-object ,inspector :run-hook-p t)
219  (cl:eval (cl:read-from-string ,string)))
220  ;; Return nothing.
221  (cl:values)))))
222 
223  (define-key slime-prefix-map (kbd "i") 'clouseau-inspect)
224  (setq slime-threads-update-interval 1))
225 
226 ;;; Rust
227 (add-hook 'rust-mode-hook 'eglot-ensure)
228 (setq rust-rustfmt-switches nil
229  rust-indent-offset 2)
230 
231 (with-eval-after-load 'eglot
232  (add-to-list 'eglot-server-programs '(rust-mode . ("rust-analyzer"))))
233 
234 ;;; Python
235 (setq python-indent-offset 2)
236 (add-hook 'python-mode-hook 'eglot-ensure)
237 
238 ;;; Bash
239 (setq sh-basic-offset 2)
240 
241 ;;; Comments
242 (defcustom prog-comment-keywords
243  '("TODO" "REVIEW" "FIX" "HACK" "RESEARCH")
244  "List of strings with comment keywords."
245  :group 'default)
246 
247 (defcustom prog-comment-timestamp-format-concise "%F"
248  "Specifier for date in `prog-comment-timestamp-keyword'.
249 Refer to the doc string of `format-time-string' for the available
250 options."
251  :group 'default)
252 
253 (defcustom prog-comment-timestamp-format-verbose "%F %T %z"
254  "Like `prog-comment-timestamp-format-concise', but longer."
255  :group 'default)
256 
257 ;;;###autoload
258 (defun prog-comment-dwim (arg)
259  "Flexible, do-what-I-mean commenting.
260 
261 If region is active and ARG is either a numeric argument greater
262 than one or a universal prefix (\\[universal-argument]), then
263 apply `comment-kill' on all comments in the region.
264 
265 If the region is active and no ARG is supplied, or is equal to a
266 numeric prefix of 1, then toggle the comment status of the region.
267 
268 Else toggle the comment status of the line at point. With a
269 numeric prefix ARG, do so for ARGth lines (negative prefix
270 operates on the lines before point)."
271  (interactive "p")
272  (cond
273  ((and (> arg 1) (use-region-p))
274  (let* ((beg (region-beginning))
275  (end (region-end))
276  (num (count-lines beg end)))
277  (save-excursion
278  (goto-char beg)
279  (comment-kill num))))
280  ((use-region-p)
281  (comment-or-uncomment-region (region-beginning) (region-end)))
282  (t
283  (save-excursion (comment-line (or arg 1))))))
284 
285 (defvar prog-comment--keyword-hist '()
286  "Input history of selected comment keywords.")
287 
288 (defun prog-comment--keyword-prompt (keywords)
289  "Prompt for candidate among KEYWORDS."
290  (let ((def (car prog-comment--keyword-hist)))
291  (completing-read
292  (format "Select keyword [%s]: " def)
293  keywords nil nil nil 'prog-comment--keyword-hist def)))
294 
295 
296 ;;;###autoload
297 (defun prog-comment-timestamp-keyword (keyword &optional verbose)
298  "Add timestamped comment with KEYWORD.
299 
300 When called interactively, the list of possible keywords is that
301 of `prog-comment-keywords', though it is possible to
302 input arbitrary text.
303 
304 If point is at the beginning of the line or if line is empty (no
305 characters at all or just indentation), the comment is started
306 there in accordance with `comment-style'. Any existing text
307 after the point will be pushed to a new line and will not be
308 turned into a comment.
309 
310 If point is anywhere else on the line, the comment is indented
311 with `comment-indent'.
312 
313 The comment is always formatted as 'DELIMITER KEYWORD DATE:',
314 with the date format being controlled by the variable
315 `prog-comment-timestamp-format-concise'.
316 
317 With optional VERBOSE argument (such as a prefix argument
318 `\\[universal-argument]'), use an alternative date format, as
319 specified by `prog-comment-timestamp-format-verbose'."
320  (interactive
321  (list
322  (prog-comment--keyword-prompt prog-comment-keywords)
323  current-prefix-arg))
324  (let* ((date (if verbose
325  comment-timestamp-format-verbose
326  prog-comment-timestamp-format-concise))
327  (string (format "%s %s: " keyword (format-time-string date)))
328  (beg (point)))
329  (cond
330  ((or (eq beg (point-at-bol))
331  (default-line-regexp-p 'empty))
332  (let* ((maybe-newline (unless (default-line-regexp-p 'empty 1) "\n")))
333  ;; NOTE 2021-07-24: we use this `insert' instead of
334  ;; `comment-region' because of a yet-to-be-determined bug that
335  ;; traps `undo' to the two states between the insertion of the
336  ;; string and its transformation into a comment.
337  (insert
338  (concat comment-start
339  ;; NOTE 2021-07-24: See function `comment-add' for
340  ;; why we need this.
341  (make-string
342  (comment-add nil)
343  (string-to-char comment-start))
344  comment-padding
345  string
346  comment-end))
347  (indent-region beg (point))
348  (when maybe-newline
349  (save-excursion (insert maybe-newline)))))
350  (t
351  (comment-indent t)
352  (insert (concat " " string))))))
353 
354 (setq hexl-bits 8)
355 (setq tab-width 4)
356 
357 ;;; Keyboard Macros
358 (defun toggle-macro-recording ()
359  (interactive)
360  (if defining-kbd-macro
361  (end-kbd-macro)
362  (start-kbd-macro nil)))
363 
364 (defun play-macro-if-not-playing ()
365  (interactive)
366  (if defining-kbd-macro
367  (end-kbd-macro)
368  (call-last-kbd-macro)))
369 
370 ;;; Registers
371 ;; - additional register vtypes: buffer
372 (defun decrement-register (number register)
373  "Subtract NUMBER from the contents of register REGISTER.
374 Interactively, NUMBER is the prefix arg."
375  (interactive "p\ncDecrement register: ")
376  (increment-register (- number) register))
377 
378 (defun copy-register (a b)
379  "Copy register A to B."
380  (interactive
381  (list (register-read-with-preview "From register: ")
382  (register-read-with-preview "To register: ")))
383  (set-register b (get-register a)))
384 
385 (defun buffer-to-register (register &optional delete)
386  "Put current buffer in register - this would also work for
387  just buffers, as switch-to-buffer can use both, but it
388  facilitates for easier saving/restoring of registers."
389  (interactive "cPut current buffername in register: \nP.")
390  (set-register register (cons 'buffer (buffer-name (current-buffer)))))
391 
392 (defun file-to-register (register &optional delete)
393  "This is better than put-buffer-in-register for file-buffers, because a closed
394  file can be opened again, but does not work for no-file-buffers."
395  (interactive "cPut the filename of current buffer in register: \nP")
396  (set-register register (cons 'file (buffer-file-name (current-buffer)))))
397 
398 (defun file-query-to-register (register &optional delete)
399  (interactive
400  (list
401  (register-read-with-preview "File query to register: ")))
402  (set-register register (list 'file-query (buffer-file-name (current-buffer)) (point))))
403 
404 ;; additional register-val handlers
405 ;; (cl-defmethod register-val-jump-to :around ((val cons) delete)
406 ;; (cond
407 ;; (t (cl-call-next-method val delete))))
408 
409 ;;; Outlines
410 (defun outline-hook (&optional rx)
411  "Enable `outline-minor-mode' and set `outline-regexp'."
412  (when rx (setq-local outline-regexp rx))
413  (outline-minor-mode 1))
414 
415 (setq outline-minor-mode-use-buttons nil)
416 
417 (defun add-outline-hook (mode &optional rx)
418  (let ((sym (symb mode "-hook")))
419  (add-hook sym (lambda () (outline-hook rx)))))
420 
421 (defmacro outline-hooks (&rest pairs)
422  `(mapc (lambda (x) (add-outline-hook (car x) (cadr x))) ',pairs))
423 
424 (outline-hooks (asm-mode ";;;+")
425  (nasm-mode ";;;+")
426  (rust-mode "\\(//!\\|////+\\)")
427  (sh-mode "###+")
428  (sh-script-mode "###+")
429  (makefile-mode "###+")
430  (conf-mode "###+")
431  (common-lisp-mode)
432  (emacs-lisp-mode)
433  (lisp-data-mode)
434  (org-mode)
435  (css-mode)
436  (html-mode)
437  (skel-mode))
438 
439 ;;; Scratch
440 (defcustom default-scratch-buffer-mode 'lisp-interaction-mode
441  "Default major mode for new scratch buffers"
442  :group 'default)
443 
444 ;; Adapted from the `scratch.el' package by Ian Eure.
445 (defun default-scratch-list-modes ()
446  "List known major modes."
447  (cl-loop for sym the symbols of obarray
448  for name = (symbol-name sym)
449  when (and (functionp sym)
450  (not (member sym minor-mode-list))
451  (string-match "-mode$" name)
452  (not (string-match "--" name)))
453  collect name))
454 
455 (defun default-scratch-buffer-setup (region &optional mode)
456  "Add contents to `scratch' buffer and name it accordingly.
457 
458 REGION is added to the contents to the new buffer.
459 
460 Use the current buffer's major mode by default. With optional
461 MODE use that major mode instead."
462  (let* ((major (or mode major-mode))
463  (string (format "Scratch buffer for: %s\n\n" major))
464  (text (concat string region))
465  (buf (format "*Scratch for %s*" major)))
466  (with-current-buffer (get-buffer-create buf)
467  (funcall major)
468  (save-excursion
469  (insert text)
470  (goto-char (point-min))
471  (comment-region (point-at-bol) (point-at-eol)))
472  (vertical-motion 2))
473  (pop-to-buffer buf)))
474 
475 ;;;###autoload
476 (defun default-scratch-buffer (&optional arg)
477  "Produce a bespoke scratch buffer matching current major mode.
478 
479 With optional ARG as a prefix argument (\\[universal-argument]),
480 use `default-scratch-buffer-mode'.
481 
482 With ARG as a double prefix argument, prompt for a major mode
483 with completion.
484 
485 If region is active, copy its contents to the new scratch
486 buffer."
487  (interactive "P")
488  (let* ((default-mode default-scratch-buffer-mode)
489  (modes (default-scratch-list-modes))
490  (region (with-current-buffer (current-buffer)
491  (if (region-active-p)
492  (buffer-substring-no-properties
493  (region-beginning)
494  (region-end))
495  "")))
496  (m))
497  (pcase (prefix-numeric-value arg)
498  (16 (progn
499  (setq m (intern (completing-read "Select major mode: " modes nil t)))
500  (default-scratch-buffer-setup region m)))
501  (4 (default-scratch-buffer-setup region default-mode))
502  (_ (default-scratch-buffer-setup region)))))
503 
504 ;;;###autoload
505 (defun scratch-new ()
506  "create a new scratch buffer. (could be *scratch* - *scratchN*)"
507  (interactive)
508  (let ((n 0)
509  bufname)
510  (while (progn
511  (setq bufname
512  (concat "*scratch"
513  (if (= n 0) "" (int-to-string n))
514  "*"))
515  (setq n (1+ n))
516  (get-buffer bufname)))
517  (switch-to-buffer (get-buffer-create bufname))
518  (insert initial-scratch-message)
519  (lisp-interaction-mode)))
520 
521 ;;; Shell
522 (defun set-no-process-query-on-exit ()
523  (let ((proc (get-buffer-process (current-buffer))))
524  (when (processp proc)
525  (set-process-query-on-exit-flag proc nil))))
526 
527 (add-hook 'shell-mode-hook 'set-no-process-query-on-exit)
528 (add-hook 'term-exec-hook 'set-no-process-query-on-exit)
529 
530 ;;; Eshell
531 (defun eshell-new()
532  "Open a new instance of eshell."
533  (interactive)
534  (eshell 'Z))
535 
536 (setq eshell-highlight-prompt t
537  eshell-hist-ignoredups t
538  eshell-save-history-on-exit t
539  eshell-prefer-lisp-functions nil
540  eshell-destroy-buffer-when-process-dies t)
541 
542 (add-hook 'eshell-mode-hook
543  (lambda ()
544  (eshell/alias "d" "dired $1")
545  (eshell/alias "ff" "find-file $1")
546  (eshell/alias "hgfe" "hg-fast-export.sh")))
547 
548 (defun eshell/clear ()
549  "Clear the eshell buffer."
550  (let ((inhibit-read-only t))
551  (erase-buffer)
552  (eshell-send-input)))
553 
554 (defun eshell-quit-or-delete-char (arg)
555  (interactive "p")
556  (if (and (eolp) (looking-back eshell-prompt-regexp))
557  (progn
558  (eshell-life-is-too-much) ; Why not? (eshell/exit)
559  (ignore-errors
560  (delete-window)))
561  (delete-forward-char arg)))
562 
563 (add-hook 'eshell-mode-hook
564  (lambda ()
565  (bind-keys :map eshell-mode-map
566  ("C-d" . eshell-quit-or-delete-char))))
567 
568 (defun eshell-next-prompt (n)
569  "Move to end of Nth next prompt in the buffer. See `eshell-prompt-regexp'."
570  (interactive "p")
571  (re-search-forward eshell-prompt-regexp nil t n)
572  (when eshell-highlight-prompt
573  (while (not (get-text-property (line-beginning-position) 'read-only) )
574  (re-search-forward eshell-prompt-regexp nil t n)))
575  (eshell-skip-prompt))
576 
577 (defun eshell-previous-prompt (n)
578  "Move to end of Nth previous prompt in the buffer. See `eshell-prompt-regexp'."
579  (interactive "p")
580  (backward-char)
581  (eshell-next-prompt (- n)))
582 
583 (defun eshell-insert-history ()
584  "Displays the eshell history to select and insert back into your eshell."
585  (interactive)
586  (insert (ido-completing-read "Eshell history: "
587  (delete-dups
588  (ring-elements eshell-history-ring)))))
589 ;;; Tramp
590 
591 (setopt tramp-default-method "ssh"
592  tramp-default-user user-login-name
593  tramp-default-host "localhost")
594 ;;; Org
595 ;; todos
596 (setq org-todo-keywords
597  '((type "TBD(0!)" "TODO(t!)" "|")
598  (type "WIP(w!)" "|")
599  (sequence "FIND(q!)" "READ(r@!)" "WATCH(W@!)" "|")
600  (sequence "RESEARCH(s!)" "RECORD(e!)" "|")
601  (sequence "OUTLINE(O!)" "RESEARCH(A!)" "DRAFT(M!)" "REVIEW(R!)" "|")
602  (sequence "FIX(i!)" "TEST(t!)" "|")
603  (type "GOTO(g!)" "HACK(h!)" "NOTE(n!)" "CODE(c!)" "LINK(l!)" "|")
604  (type "KLUDGE(k@!)" "|")
605  (sequence "|" "DONE(d!)" "NOPE(x@!)" "FOUND(f@!)")))
606 ;; captures
607 (setq org-capture-templates
608  '(("t" "task" entry (file "inbox.org") "* %^{title}\n- %?" :prepend t)
609  ("1" "current-task-item" item (clock) "%i%?")
610  ("2" "current-task-checkbox" checkitem (clock) "%i%?")
611  ("3" "current-task-region" plain (clock) "%i" :immediate-finish t :empty-lines 1)
612  ("4" "current-task-kill" plain (clock) "%c" :immediate-finish t :empty-lines 1)
613  ("l" "log" item (file+headline "log.org" "log") "%U %?" :prepend t)
614  ("s" "secret" table-line (file+function "krypt" org-ask-location) "| %^{key} | %^{val} |" :immediate-finish t :kill-buffer t)
615  ("n" "note" plain (file+function "notes.org" org-ask-location) "%?")
616  ("i" "idea" entry (file "inbox.org") "* OUTLINE %?\n:notes:\n:end:\n- _outline_ [/]\n - [ ] \n - [ ] \n- _refs_" :prepend t)
617  ("b" "bug" entry (file "inbox.org") "* FIX %?\n- _review_\n- _fix_\n- _test_" :prepend t)
618  ("r" "research" entry (file "inbox.org") "* RESEARCH %?\n:notes:\n:end:\n- _refs_" :prepend t)))
619 (setq org-html-htmlize-output-type 'css
620  org-html-head-include-default-style nil
621  ;; comp2 default
622  org-ascii-text-width 80)
623 
624 (org-crypt-use-before-save-magic)
625 
626 (setq org-structure-template-alist
627  '(("s" . "src")
628  ("e" . "src emacs-lisp")
629  ("x" . "src shell")
630  ("l" . "src lisp")
631  ("h" . "export html")
632  ("p" . "src python")
633  ("r" . "src rust")
634  ("E" . "example")
635  ("q" . "quote")
636  ("c" . "center")
637  ("C" . "comment")
638  ("v" . "verse")))
639 
640 (setopt org-preview-latex-image-directory "~/.emacs.d/.cache/ltximg"
641  org-latex-image-default-width "8cm"
642  org-refile-use-cache t
643  org-refile-allow-creating-parent-nodes 'confirm
644 
645  org-refile-targets '((nil :maxlevel . 3)
646  (org-agenda-files :maxlevel . 3))
647  org-confirm-babel-evaluate nil
648  org-src-fontify-natively t
649  org-src-tabs-act-natively t
650  org-footnote-section nil
651  org-log-into-drawer t
652  org-log-states-order-reversed nil
653  org-clock-persist 'history)
654 
655 (add-hook 'after-init-hook #'org-clock-persistence-insinuate)
656 
657 (defun org-todo-at-date (date)
658  "create a todo entry for a given date."
659  (interactive (list (org-time-string-to-time (org-read-date))))
660  (cl-flet ((org-current-effective-time (&rest r) date)
661  (org-today (&rest r) (time-to-days date)))
662  (cond ((eq major-mode 'org-mode) (org-todo))
663  ((eq major-mode 'org-agenda-mode) (org-agenda-todo)))))
664 
665 (defun org-ask-location ()
666  "prompt for a location\"\""
667  (let* ((org-refile-targets '((nil :maxlevel . 9)))
668  (hd (condition-case nil
669  (car (org-refile-get-location))
670  (error (car org-refile-history)))))
671  (goto-char (point-min))
672  (outline-next-heading)
673  (if (re-search-forward
674  (format org-complex-heading-regexp-format (regexp-quote hd))
675  nil t)
676  (goto-char (point-at-bol))
677  (goto-char (point-max))
678  (or (bolp) (insert "\n"))
679  (insert "* " hd "\n")))
680  (end-of-line))
681 
682 (defun org-capture-fileref-snippet (f type headers func-name)
683  (let* ((code-snippet
684  (buffer-substring-no-properties (mark) (- (point) 1)))
685  (file-name (buffer-file-name))
686  (file-base (file-name-nondirectory file-name))
687  (line-number (line-number-at-pos (region-beginning)))
688  (initial-txt (if (null func-name)
689  (format "From [[file:%s::%s][%s]]:"
690  file-name line-number file-base)
691  (format "From ~%s~ (in [[file:%s::%s][%s]]):"
692  func-name file-name line-number
693  file-base))))
694  (format "
695  %s
696  #+BEGIN_%s %s
697  %s
698  #+END_%s" initial-txt type headers code-snippet type)))
699 
700 (defun org-capture-clip-snippet (f)
701  "Given a file, F, this captures the currently selected text
702  within an Org EXAMPLE block and a backlink to the file."
703  (with-current-buffer (find-buffer-visiting f)
704  (org-capture-fileref-snippet f "EXAMPLE" "" nil)))
705 
706 (defun org-capture-code-snippet (f)
707  "Given a file, F, this captures the currently selected text
708  within an Org SRC block with a language based on the current mode
709  and a backlink to the function and the file."
710  (with-current-buffer (find-buffer-visiting f)
711  (let ((org-src-mode (replace-regexp-in-string "-mode" "" (format "%s" major-mode)))
712  (func-name (which-function)))
713  (org-capture-fileref-snippet f "SRC" org-src-mode func-name))))
714 
715 (defun region-to-clocked-task (start end)
716  "Copies the selected text to the currently clocked in org-mode task."
717  (interactive "r")
718  (org-capture-string (buffer-substring-no-properties start end) "3"))
719 
720 (setq org-global-properties
721  '(quote (("EFFORT_ALL" . "0:15 0:30 0:45 1:00 2:00 3:00 4:00 5:00 6:00 0:00")
722  ("STYLE_ALL" . "habit"))))
723 
724 (defun org-mode-ask-effort ()
725  "Ask for an effort estimate when clocking in."
726  (unless (org-entry-get (point) "Effort")
727  (let ((effort
728  (completing-read
729  "Effort: "
730  (org-entry-get-multivalued-property (point) "Effort"))))
731  (unless (equal effort "")
732  (org-set-property "Effort" effort)))))
733 
734 (add-hook 'org-clock-in-prepare-hook
735  'org-mode-ask-effort)
736 
737 ;;;###autoload
738 (defun org-adjust-tags-column-reset-tags ()
739  "In org-mode buffers it will reset tag position according to
740 `org-tags-column'."
741  (when (and
742  (not (string= (buffer-name) "*Remember*"))
743  (eql major-mode 'org-mode))
744  (let ((b-m-p (buffer-modified-p)))
745  (condition-case nil
746  (save-excursion
747  (goto-char (point-min))
748  (command-execute 'outline-next-visible-heading)
749  ;; disable (message) that org-set-tags generates
750  (flet ((message (&rest ignored) nil))
751  (org-set-tags 1 t))
752  (set-buffer-modified-p b-m-p))
753  (error nil)))))
754 
755 ;;;###autoload
756 (defun org-align-all-tables ()
757  "align all tables in current buffer"
758  (interactive)
759  (org-table-map-tables 'org-table-align 'quietly))
760 
761 (defun org-remove-redundant-tags ()
762  "Remove redundant tags of headlines in current buffer.
763 
764 A tag is considered redundant if it is local to a headline and
765 inherited by a parent headline."
766  (interactive)
767  (when (eq major-mode 'org-mode)
768  (save-excursion
769  (org-map-entries
770  (lambda ()
771  (let ((alltags (split-string (or (org-entry-get (point) "ALLTAGS") "") ":"))
772  local inherited tag)
773  (dolist (tag alltags)
774  (if (get-text-property 0 'inherited tag)
775  (push tag inherited) (push tag local)))
776  (dolist (tag local)
777  (if (member tag inherited) (org-toggle-tag tag 'off)))))
778  t nil))))
779 ;;;; Agenda
780 (defvar org-agenda-overriding-header)
781 (defvar org-agenda-sorting-strategy)
782 (defvar org-agenda-restrict)
783 (defvar org-agenda-restrict-begin)
784 (defvar org-agenda-restrict-end)
785 
786 ;;;###autoload
787 (defun org-agenda-reschedule-to-today ()
788  (interactive)
789  (flet ((org-read-date (&rest rest) (current-time)))
790  (call-interactively 'org-agenda-schedule)))
791 
792 ;; Patch org-mode to use vertical splitting
793 (defadvice org-prepare-agenda (after org-fix-split)
794  (toggle-window-split))
795 (ad-activate 'org-prepare-agenda)
796 
797 (add-hook 'org-agenda-mode-hook (lambda () (hl-line-mode 1)))
798 
799 (defun org-agenda-log-mode-colorize-block ()
800  "Set different line spacing based on clock time duration."
801  (save-excursion
802  (let* ((colors (cl-case (alist-get 'background-mode (frame-parameters))
803  (light
804  (list "#F6B1C3" "#FFFF9D" "#BEEB9F" "#ADD5F7"))
805  (dark
806  (list "#aa557f" "DarkGreen" "DarkSlateGray" "DarkSlateBlue"))))
807  pos
808  duration)
809  (nconc colors colors)
810  (goto-char (point-min))
811  (while (setq pos (next-single-property-change (point) 'duration))
812  (goto-char pos)
813  (when (and (not (equal pos (point-at-eol)))
814  (setq duration (org-get-at-bol 'duration)))
815  ;; larger duration bar height
816  (let ((line-height (if (< duration 15) 1.0 (+ 0.5 (/ duration 30))))
817  (ov (make-overlay (point-at-bol) (1+ (point-at-eol)))))
818  (overlay-put ov 'face `(:background ,(car colors) :foreground "black"))
819  (setq colors (cdr colors))
820  (overlay-put ov 'line-height line-height)
821  (overlay-put ov 'line-spacing (1- line-height))))))))
822 
823 (add-hook 'org-agenda-finalize-hook #'org-agenda-log-mode-colorize-block)
824 
825 ;;;###autoload
826 (defun org-agenda-current-subtree-or-region (only-todos)
827  "Display an agenda view for the current subtree or region.
828  With prefix, display only TODO-keyword items."
829  (interactive "P")
830  (let ((starting-point (point))
831  header)
832  (with-current-buffer (or (buffer-base-buffer (current-buffer))
833  (current-buffer))
834  (if (use-region-p)
835  (progn
836  (setq header "Region")
837  (put 'org-agenda-files 'org-restrict (list (buffer-file-name (current-buffer))))
838  (setq org-agenda-restrict (current-buffer))
839  (move-marker org-agenda-restrict-begin (region-beginning))
840  (move-marker org-agenda-restrict-end
841  (save-excursion
842  ;; If point is at beginning of line, include
843  ;; heading on that line by moving forward 1.
844  (goto-char (1+ (region-end)))
845  (org-end-of-subtree))))
846  ;; No region; restrict to subtree.
847  (save-excursion
848  (save-restriction
849  ;; In case the command was called from an indirect buffer, set point
850  ;; in the base buffer to the same position while setting restriction.
851  (widen)
852  (goto-char starting-point)
853  (setq header "Subtree")
854  (org-agenda-set-restriction-lock))))
855  ;; NOTE: Unlike other agenda commands, binding `org-agenda-sorting-strategy'
856  ;; around `org-search-view' seems to have no effect.
857  (let ((org-agenda-sorting-strategy '(priority-down timestamp-up))
858  (org-agenda-overriding-header header))
859  (org-search-view (if only-todos t nil) "*"))
860  (org-agenda-remove-restriction-lock t)
861  (message nil))))
862 
863 ;;; Tempo
864 (setq tempo-interactive t)
865 
866 (provide 'default)
867 ;; default.el ends here