]> git.donarmstrong.com Git - lib.git/blob - emacs_el/configuration/don-configuration.org
60f3c536bf3d40536761d963af0e11bd92987e80
[lib.git] / emacs_el / configuration / don-configuration.org
1 #+PROPERTY: header-args:emacs-lisp :tangle don-configuration.el
2 #+OPTIONS: auto-id:f
3
4 * General Notes
5
6 ** Delight
7 To look up options for symbols for delight, check out https://en.wikipedia.org/wiki/Emoji#Unicode_blocks
8
9 * Load debugger
10
11 # if for some reason, things get pear-shaped, we want to be able to
12 # enter the debugger by sending -USR2 to emacs
13
14 #+BEGIN_SRC emacs-lisp
15 (setq debug-on-event 'siguser2)
16 #+END_SRC
17 * Paths
18 ** Update PATH
19 #+BEGIN_SRC emacs-lisp
20 (add-to-list 'exec-path '"/usr/local/bin")
21 (add-to-list 'exec-path '"~/bin/")
22 #+END_SRC
23 ** Add library paths
24 #+BEGIN_SRC emacs-lisp
25 (let ((default-directory "~/lib/emacs_el/"))
26   (normal-top-level-add-subdirs-to-load-path))
27 ;; (eval-and-compile
28 ;;   (let ((default-directory "~/var/emacs/elpa"))
29 ;;     (normal-top-level-add-subdirs-to-load-path))
30 ;; )
31 (add-to-list 'load-path '"~/lib/emacs_el")
32 (setq package-user-dir "~/var/emacs/elpa")
33
34 #+END_SRC
35 * Initial startup stuff
36 ** Disable startup screen
37 #+BEGIN_SRC emacs-lisp
38 (setq inhibit-startup-screen t)
39 #+END_SRC
40 ** Disable cluter
41 #+BEGIN_SRC emacs-lisp
42 ; (if (fboundp 'menu-bar-mode) (menu-bar-mode -1))
43 (if (fboundp 'tool-bar-mode) (tool-bar-mode -1))
44 (if (fboundp 'scroll-bar-mode) (scroll-bar-mode -1))
45 #+END_SRC
46 ** Fullscreen
47 #+BEGIN_SRC emacs-lisp
48 (setq frame-resize-pixelwise t)
49 (add-to-list 'default-frame-alist '(fullscreen . maximixed))
50 #+END_SRC
51 * Package management
52 ** Bootstrap straight.el
53 #+BEGIN_SRC emacs-lisp
54 (defvar bootstrap-version)
55 (setq straight-base-dir '"~/var/emacs/")
56 (let ((bootstrap-file
57        (expand-file-name "straight/repos/straight.el/bootstrap.el" straight-base-dir))
58       (bootstrap-version 6))
59   (unless (file-exists-p bootstrap-file)
60     (with-current-buffer
61         (url-retrieve-synchronously
62          "https://raw.githubusercontent.com/radian-software/straight.el/develop/install.el"
63          'silent 'inhibit-cookies)
64       (goto-char (point-max))
65       (eval-print-last-sexp)))
66   (load bootstrap-file nil 'nomessage))
67 #+END_SRC
68 ** package repositories and package manager
69 #+BEGIN_SRC emacs-lisp
70 (straight-use-package 'use-package)
71 (setq straight-use-package-by-default t)
72 (setq use-package-verbose (not (bound-and-true-p byte-compile-current-file)))
73 (require 'gnutls)
74 (add-to-list 'gnutls-trustfiles "/etc/ssl/ca-global/ca-certificates.crt")
75 #+END_SRC
76 ** Paradox
77 #+BEGIN_SRC emacs-lisp
78 (use-package paradox
79   ;:ensure paradox
80   :commands (paradox-upgrade-packages paradox-list-packages)
81   :config
82   (setq paradox-execute-asynchronously t)
83   (setq paradox-github-token t) ; I don't want to be prompted about this integration
84   )
85 #+END_SRC
86 * Disable custom-vars
87 #+BEGIN_SRC emacs-lisp
88 ;; Set the custom file to /dev/null and don't bother to load it
89 (setq custom-file "/dev/null")
90 #+END_SRC
91 * Misc functions
92 ** with-library
93 #+BEGIN_SRC emacs-lisp
94 ;; From http://www.emacswiki.org/emacs/LoadingLispFiles
95 ;; execute conditional code when loading libraries
96 ; (defmacro with-library (symbol &rest body)
97 ;   `(when (require ,symbol nil t)
98 ;     ,@body))
99 ; (put 'with-library 'lisp-indent-function 1)
100 #+END_SRC
101
102 * Variables
103 ** Safe Local Variables
104 #+BEGIN_SRC emacs-lisp
105 (setq safe-local-variable-values
106       (quote ((auto-save-default)
107               (make-backup-files)
108               (cperl-indent-level . 4)
109               (indent-level . 4)
110               (indent-tabs-mode . f)
111               (vcl-indent-level . 4)
112               )))
113 #+END_SRC
114 * Memory
115 #+BEGIN_SRC emacs-lisp
116 (setq global-mark-ring-max 128
117       mark-ring-max 128
118       kill-ring-max 128)
119
120 (defun don/minibuffer-setup-hook ()
121   (setq gc-cons-threshold most-positive-fixnum))
122
123 (defun don/minibuffer-exit-hook ()
124   (setq gc-cons-threshold 1048576))
125
126 (add-hook 'minibuffer-setup-hook #'don/minibuffer-setup-hook)
127 (add-hook 'minibuffer-exit-hook #'don/minibuffer-exit-hook)
128 #+END_SRC
129 * Modules
130 ** Tree sitter
131 #+BEGIN_SRC emacs-lisp
132 (use-package tree-sitter
133   :defer t
134   :config
135   (global-tree-sitter-mode)
136   )
137 (use-package tree-sitter-langs
138   :ensure t
139   :defer 1
140   :after tree-sitter
141 ;   :config
142 ;   (defun dla/python-function-at-point ()
143 ;     "Return a list of function arguments
144
145 ; Borrowed from https://xenodium.com/emacs-generate-a-swift-initializer/
146 ; "
147 ;   (interactive)
148 ;   (cl-assert (seq-contains-p local-minor-modes 'tree-sitter-mode) "tree-sitter-mode not enabled")
149 ;   (let* ((node (tree-sitter-node-at-point 'function_definition)
150 ;                )
151 ;          (args)
152 ;          (arg)
153 ;          (ret))
154 ;     (unless node
155 ;       (error "Not in function"))
156 ;     (mapc
157 ;      (lambda (item)
158 ;        (cond ((eq 'func_name
159 ;                   (car item))
160 ;               ; (when arg
161 ;               ;   (setq args (append args (list arg)))
162 ;               ;   )
163 ;               (setq arg (list (cons 'function (tsc-node-text
164 ;                                            (cdr item))))))
165 ;              ((eq 'ident
166 ;                   (car item))
167 ;               (setq arg (map-insert arg 'ident (tsc-node-text
168 ;                                                (cdr item)))))
169 ;              ((eq 'ident_type
170 ;                   (car item))
171 ;               (setq arg (map-insert arg 'ident_type (tsc-node-text
172 ;                                                (cdr item)))))
173 ;              ((eq 'ret_type
174 ;                   (car item))
175 ;               (setq arg (map-insert arg 'ret_type (tsc-node-text
176 ;                                                (cdr item)))))
177 ;              ))
178 ;      (tsc-query-captures
179 ;       (tsc-make-query tree-sitter-language
180 ;                       "(function_definition (identifier) @func_name (parameters [(identifier) @ident (typed_parameter (identifier) @ident (type) @ident_type)]) (type)? @ret_type)")
181 ;       (tree-sitter-node-at-point 'function_definition) nil))
182 ;     (when arg
183 ;       (setq args (append args (list arg))))
184 ;     args))
185
186 )
187 #+END_SRC
188 ** Spacemacs theme
189 #+BEGIN_SRC emacs-lisp
190 (use-package spacemacs-theme
191   :config
192   (load-theme 'spacemacs-dark t)
193   )
194 #+END_SRC
195 ** Hippie Expand
196 #+BEGIN_SRC emacs-lisp
197 (use-package hippie-exp
198   :bind* (("M-<SPC>" . hippie-expand))
199   )
200 #+END_SRC
201 ** Flyspell 🐝 
202 #+BEGIN_SRC emacs-lisp
203 (use-package flyspell
204   ; :delight flyspell-mode 🐝
205   :config
206   (setq flyspell-mode-line-string " 🐝")
207   (add-hook 'text-mode-hook 'turn-on-flyspell)
208   (add-hook 'c-mode-common-hook 'flyspell-prog-mode)
209   (add-hook 'cperl-mode-hook 'flyspell-prog-mode)
210   (add-hook 'tcl-mode-hook 'flyspell-prog-mode)
211   :init
212   (setq ispell-program-name "ispell")
213   )
214 #+END_SRC
215
216 ** Flycheck
217 #+begin_src emacs-lisp :tangle yes
218 (use-package flycheck
219   :delight 🦋
220   :if (version<= "24.4" emacs-version)
221   :commands flycheck-mode
222   :hook ((prog-mode . flycheck-mode)
223          )
224 )
225 ;; Other pkgs
226 (use-package flycheck-tip
227   :commands 'flycheck-tip-cycle
228   :after flycheck
229   :bind (:map flycheck-mode-map
230               ("C-c C-n" . flycheck-tip-cycle)))
231
232 (use-package flycheck-package)
233
234 (use-package flycheck-checkpatch
235   :config (flycheck-checkpatch-setup)
236   :config (setq flycheck-checkers (delete 'checkpatch
237   flycheck-checkers))
238   :config (add-to-list 'flycheck-checkers 'checkpatch t))
239 #+end_src  
240
241 ** Flymake
242 #+BEGIN_SRC emacs-lisp
243   (use-package flymake
244     :delight "Φ")
245 #+END_SRC
246
247 ** Winnermode
248 #+BEGIN_SRC emacs-lisp
249   (winner-mode 1)
250 #+END_SRC
251 ** Eyebrowse
252
253 #+BEGIN_SRC emacs-lisp
254   (use-package eyebrowse
255     :ensure t
256     :delight eyebrowse-mode
257     :init (setq eyebrowse-keymap-prefix (kbd "C-c e"))
258     :config (progn
259               (setq eyebrowse-wrap-around t)
260               (eyebrowse-mode t)
261
262               (defun my/eyebrowse-new-window-config ()
263                 (interactive)
264                 (let ((done nil))
265                   (dotimes (i 10)
266                     ;; start at 1 run till 0
267                     (let ((j (mod (+ i 1) 10)))
268                       (when (and (not done)
269                                  (not (eyebrowse--window-config-present-p j)))
270                         (eyebrowse-switch-to-window-config j)
271                         (call-interactively 'eyebrowse-rename-window-config2 j)
272                         (setq done t)
273                         ))
274                     )))
275
276               ;; I don't use latex-preview-pane
277               ;; (require 'latex-preview-pane)
278               ;; (defun my/close-latex-preview-pane-before-eyebrowse-switch ()
279               ;;   ;; latex-preview-pane uses window-parameters which are
280               ;;   ;; not preserved by eyebrowse, so we close the preview
281               ;;   ;; pane before switching, it will be regenerated when we
282               ;;   ;; edit the TeX file.
283               ;;   (when (lpp/window-containing-preview)
284               ;;     (delete-window (lpp/window-containing-preview))))
285
286               ;; (add-to-list 'eyebrowse-pre-window-switch-hook
287               ;;              #'my/close-latex-preview-pane-before-eyebrowse-switch)
288
289               ;; (my/set-menu-key "["  #'my/eyebrowse-new-window-config)
290               ;; (my/set-menu-key ";"  #'eyebrowse-prev-window-config)
291               ;; (my/set-menu-key "'"  #'eyebrowse-next-window-config)
292               ;; (my/set-menu-key "]"  #'eyebrowse-close-window-config)
293               ;; (my/set-menu-key "\\" #'eyebrowse-rename-window-config)
294               )
295     )
296 #+END_SRC
297
298 ** Window handling
299
300 *** Splitting
301 #+BEGIN_SRC emacs-lisp
302   (defun my/vsplit-last-buffer ()
303     "Split the window vertically and display the previous buffer."
304     (interactive)
305     (split-window-vertically)
306     (other-window 1 nil)
307     (switch-to-next-buffer))
308
309   (defun my/hsplit-last-buffer ()
310     "Split the window horizontally and display the previous buffer."
311     (interactive)
312     (split-window-horizontally)
313     (other-window 1 nil)
314     (switch-to-next-buffer))
315
316   (bind-key "C-x 2" 'my/vsplit-last-buffer)
317   (bind-key "C-x 3" 'my/hsplit-last-buffer)
318
319   (setq split-width-threshold  100)
320   (setq split-height-threshold 60)
321
322   (defun my/split-window-prefer-vertically (window)
323     "If there's only one window (excluding any possibly active
324            minibuffer), then split the current window horizontally."
325     (if (and (one-window-p t)
326              (not (active-minibuffer-window))
327              ( < (frame-width) (frame-height))
328              )
329         (let ((split-width-threshold nil))
330           (split-window-sensibly window))
331       (split-window-sensibly window)))
332
333   (setq split-window-preferred-function #'my/split-window-prefer-vertically)
334   (setq window-combination-resize t)
335 #+END_SRC
336
337 *** Compilation window
338
339 If there is no compilation window, open one at the bottom, spanning
340 the complete width of the frame. Otherwise, reuse existing window. In
341 the former case, if there was no error the window closes
342 automatically.
343
344 #+BEGIN_SRC emacs-lisp
345   (add-to-list 'display-buffer-alist
346                `(,(rx bos "*compilation*" eos)
347                  (display-buffer-reuse-window
348                   display-buffer-in-side-window)
349                  (reusable-frames . visible)
350                  (side            . bottom)
351                  (window-height   . 0.4)))
352 #+END_SRC
353
354 #+BEGIN_SRC emacs-lisp
355   (defun my/compilation-exit-autoclose (status code msg)
356     ;; If M-x compile exists with a 0
357     (when (and (eq status 'exit) (zerop code))
358       ;; and delete the *compilation* window
359       (let ((compilation-window (get-buffer-window (get-buffer "*compilation*"))))
360         (when (and (not (window-at-side-p compilation-window 'top))
361                    (window-at-side-p compilation-window 'left)
362                    (window-at-side-p compilation-window 'right))
363           (delete-window compilation-window))))
364     ;; Always return the anticipated result of compilation-exit-message-function
365     (cons msg code))
366
367   ;; Specify my function (maybe I should have done a lambda function)
368   (setq compilation-exit-message-function #'my/compilation-exit-autoclose)
369 #+END_SRC
370
371 If you change the variable ~compilation-scroll-output~ to a ~non-nil~
372 value, the compilation buffer scrolls automatically to follow the
373 output. If the value is ~first-error~, scrolling stops when the first
374 error appears, leaving point at that error. For any other non-nil
375 value, scrolling continues until there is no more output.
376
377 #+BEGIN_SRC emacs-lisp
378   (setq compilation-scroll-output 'first-error)
379 #+END_SRC
380
381 ** Mode line cleaning
382 *** Delight 
383 #+BEGIN_SRC emacs-lisp
384 (use-package delight
385   :demand t)
386 #+END_SRC
387
388 ** Jumping
389 *** Avy
390 #+BEGIN_SRC emacs-lisp
391   (use-package avy
392     :if (>= emacs-major-version 25)
393     :ensure t
394     :bind (("C-c C-<SPC>" . avy-goto-word-or-subword-1)
395            ("C-c j j" . avy-goto-word-or-subword-1)
396            ("M-g g" . avy-goto-line))
397     :config (progn (setq avy-background t))
398     )
399 #+END_SRC
400 *** Ace-link (jumping to links)
401 #+BEGIN_SRC emacs-lisp
402   (use-package ace-link
403     :ensure t
404     ; bind o in most modes
405     :config (ace-link-setup-default))
406 #+END_SRC
407 *** Jumping through edit points (goto-chg)
408 #+BEGIN_SRC emacs-lisp
409   (use-package goto-chg
410     :ensure t
411     :bind (("C-c j ," . goto-last-change)
412            ("C-c j ." . goto-last-change-reverse))
413     )
414 #+END_SRC
415 *** Jumping to bookmarks (visible bookmarks, bm)
416 #+BEGIN_SRC emacs-lisp
417   (use-package bm
418     :ensure t
419     :bind (("C-c j b ." . bm-next)
420            ("C-c j b ," . bm-previous)
421            ("C-c j b SPC" . bm-toggle)))
422 #+END_SRC
423
424 ** Snippets
425 *** Yasnippet
426 #+BEGIN_SRC emacs-lisp
427 (use-package yasnippet
428   :ensure t
429   :delight yas-minor-mode
430   :config (progn
431             (yas-global-mode)
432             (setq yas-verbosity 1)
433             (define-key yas-minor-mode-map (kbd "<tab>") nil)
434             (define-key yas-minor-mode-map (kbd "TAB") nil)
435             (define-key yas-minor-mode-map (kbd "<backtab>") nil)
436             (setq yas-snippet-dirs '("~/lib/emacs_el/snippets/"
437                                      "~/lib/emacs_el/yasnippet-snippets/snippets/"))
438             (add-to-list 'hippie-expand-try-functions-list
439                              'yas-hippie-try-expand)
440             (yas-reload-all)
441             )
442   )
443 #+END_SRC
444 *** Auto-YASnippet
445 #+BEGIN_SRC emacs-lisp
446 (use-package auto-yasnippet
447   :ensure t
448   :bind (("H-w" . aya-create)
449          ("H-y" . aya-expand)
450          )
451   )
452 #+END_SRC
453 ** Treemacs: Tree file viewer
454 #+BEGIN_SRC emacs-lisp
455 ;; Provides workspaces with file browsing (tree file viewer)
456 ;; and project management when coupled with `projectile`.
457
458 ; (use-package treemacs
459 ;   :ensure t
460 ;   :defer t
461 ;   :config
462 ;   (setq treemacs-no-png-images t
463 ;         treemacs-width 24)
464 ;   :bind ("C-c t" . treemacs))
465 #+END_SRC
466 ** LSP mode
467 #+BEGIN_SRC emacs-lisp
468 (use-package lsp-mode
469   :defer t
470   :commands (lsp lsp-deferred)
471   :init (setq lsp-keymap-prefix "C-c l")
472   (defun my/orderless-dispatch-flex-first (_pattern index _total)
473     (and (eq index 0) 'orderless-flex))
474
475   (defun my/lsp-mode-setup-completion ()
476     (setf (alist-get 'styles (alist-get 'lsp-capf completion-category-defaults))
477           '(orderless)))
478
479   ;; Optionally configure the first word as flex filtered.
480   (add-hook 'orderless-style-dispatchers #'my/orderless-dispatch-flex-first nil 'local)
481
482   ;; Optionally configure the cape-capf-buster.
483   ; (setq-local completion-at-point-functions (list (cape-capf-buster #'lsp-completion-at-point)))
484
485   :hook (python-mode . lsp-deferred)
486         (cperl-mode . lsp-deferred)
487   (lsp-completion-mode . my/lsp-mode-setup-completion)
488   :custom
489   (lsp-completion-provider :none) ;; we use Corfu!
490   :config
491    (add-to-list 'lsp-file-watch-ignored-directories "[/\\\\]venv\\'")
492 )
493 #+END_SRC
494 ** LSP mode
495 #+BEGIN_SRC emacs-lisp
496 ;; provides visual help in the buffer 
497 ;; for example definitions on hover. 
498 ;; the `imenu` lets me browse definitions quickly.
499 (use-package lsp-ui
500   :defer t
501   :after lsp-mode
502   :config
503   (setq lsp-ui-sideline-enable t
504             lsp-ui-doc-delay 2)
505   :hook (lsp-mode . lsp-ui-mode)
506   :bind (:map lsp-ui-mode-map
507               ("C-c i" . lsp-ui-imenu)))
508 #+END_SRC
509 *** LSP Pyright -- Python language server
510 #+BEGIN_SRC emacs-lisp
511 ;; language server for python 
512 ;; read the docs for the different variables set in the config.
513 (use-package lsp-pyright
514   :defer t
515   :config
516   (setq lsp-clients-python-library-directories '("/usr/"))
517   (setq lsp-pyright-disable-language-service nil
518         lsp-pyright-disable-organize-imports nil
519         lsp-pyright-auto-import-completions t
520         lsp-pyright-use-library-code-for-types t
521         lsp-pyright-venv-path "venv")
522   :hook ((python-mode . (lambda () 
523                           (require 'lsp-pyright) (lsp-deferred)))))
524 #+END_SRC
525 ** Corfu
526 #+BEGIN_SRC emacs-lisp
527 (use-package corfu
528   ;; Optional customizations
529   :custom
530   (corfu-cycle t)                ;; Enable cycling for `corfu-next/previous'
531   (corfu-auto t)                 ;; Enable auto completion
532   (corfu-separator ?\s)          ;; Orderless field separator
533   (corfu-quit-at-boundary t)
534   (corfu-quit-no-match 'separator)
535   (corfu-preview-current nil)    ;; Disable current candidate preview
536   (corfu-preselect 'prompt)      ;; Preselect the prompt
537   (corfu-on-exact-match nil)     ;; Configure handling of exact matches
538   (corfu-scroll-margin 5)        ;; Use scroll margin
539
540   :bind (
541          :map corfu-map
542               ("M-m" . corfu-move-to-minibuffer)
543               )
544   :init
545   (global-corfu-mode)
546   (setq completion-cycle-threshold 3)
547   (setq tab-always-indent 'complete)
548   :config
549   (defun corfu-move-to-minibuffer ()
550     (interactive)
551     (when completion-in-region--data
552       (let ((completion-extra-properties corfu--extra)
553             completion-cycle-threshold completion-cycling)
554         (apply #'consult-completion-in-region completion-in-region--data))))
555   (add-to-list 'corfu-continue-commands #'corfu-move-to-minibuffer)
556   )
557 #+END_SRC
558 ** Dabbrv
559 #+BEGIN_SRC emacs-lisp
560 (use-package dabbrev
561   :ensure t
562   ;; Swap M-/ and C-M-/
563   :bind (("M-/" . dabbrev-completion)
564          ("C-M-/" . dabbrev-expand))
565   ;; Other useful Dabbrev configurations.
566   :custom
567   (dabbrev-ignored-buffer-regexps '("\\.\\(?:pdf\\|jpe?g\\|png\\)\\'")))
568 #+END_SRC
569 ** Tinyprocmail
570
571 #+BEGIN_SRC emacs-lisp
572 ;; load tinyprocmail
573 (use-package tinyprocmail
574   :straight (tinytools :type git :type git :host github :repo "jaalto/project--emacs-tiny-tools")
575   :mode (".procmailrc" . turn-on-tinyprocmail-mode)
576   )
577 #+END_SRC
578
579 ** Magit
580 #+BEGIN_SRC emacs-lisp
581 (use-package magit
582   :defer t
583   :bind (("C-x g" . magit-status)
584          ("C-x C-g" . magit-status))
585   :config
586   ;; refine diffs always (hilight words)
587   (setq magit-diff-refine-hunk nil)
588   )
589 (use-package magit-annex
590   :defer t
591   :after magit
592   )
593 (use-package magit-vcsh
594   :defer t
595   :after magit
596   )
597 #+END_SRC
598
599 *** Forge (github/gitlab)
600 #+BEGIN_SRC emacs-lisp
601 (use-package forge
602   :defer t
603   :after magit
604   )
605 #+END_SRC
606
607 ** Perl
608 #+BEGIN_SRC emacs-lisp
609 (use-package cperl-mode
610   :mode ("\\.pl'" . cperl-mode)
611   ("\\.perl5\\'" . cperl-mode)
612   ("\\.perl\\'" . cperl-mode)
613   ("\\.miniperl\\'" . cperl-mode)
614   ("\\.\\([Pp][Llm]\\|al\\)\\'" . cperl-mode)
615     ;; use c-mode for perl .xs files
616   ("\\.xs\\'" . c-mode)
617   :config
618        (setq cperl-hairy t
619           cperl-indent-level 4
620           cperl-auto-newline nil
621           cperl-auto-newline-after-colon nil
622           cperl-continued-statement-offset 4
623           cperl-brace-offset -1
624           cperl-continued-brace-offset 0
625           cperl-label-offset -4
626           cperl-highlight-variables-indiscriminately t
627           cperl-electric-lbrace-space nil
628           cperl-indent-parens-as-block nil
629           cperl-close-paren-offset -1
630           cperl-tab-always-indent t)
631     (setq cperl-lazy-help-time nil)
632     ;;(add-hook 'cperl-mode-hook (lambda () (cperl-set-style "PerlStyle")))
633 )
634 #+END_SRC
635
636 ** Markdown mode
637 #+BEGIN_SRC emacs-lisp
638 (use-package markdown-mode
639   :defer t
640   :mode (("\\.md\\'" . markdown-mode)
641          ("\\.mdwn\\'" . markdown-mode)
642          ("README\\.md\\'" . gfm-mode)
643          )
644   :config
645   (setq markdown-enable-math t)
646   (setq markdown-follow-wiki-link-on-enter nil)
647   (bind-key "M-." #'markdown-jump markdown-mode-map)
648   (add-hook 'markdown-mode-hook #'flyspell-mode)
649   (add-hook 'markdown-mode-hook #'outline-minor-mode)
650   (bind-key "C-<tab>" #'outline-cycle markdown-mode-map)
651 )
652
653 #+END_SRC
654 ** SQL mode
655 #+BEGIN_SRC emacs-lisp
656 ; load sql-indent when sql is loaded
657 (use-package sql-indent
658   :after sql
659   :hook sql-mode
660   )
661 (use-package sql
662   :commands (sql-mode)
663   :mode (("\\.sql\\'" . sql-mode))
664   )
665 #+END_SRC
666 ** Ediff
667 #+BEGIN_SRC emacs-lisp
668 (use-package ediff
669   :commands ediff ediff3
670   :config
671   ;; ediff configuration
672   ;; don't use the multi-window configuration
673   (setq ediff-window-setup-function 'ediff-setup-windows-plain)
674 )
675 #+END_SRC
676 ** Do the Right Thing Indenting
677 Attempts to automatically identify the right indentation for a file
678 #+BEGIN_SRC emacs-lisp
679 (use-package dtrt-indent
680 )  
681 #+END_SRC
682 ** VCL --editing varnish configuration files
683 #+BEGIN_SRC emacs-lisp
684 (use-package vcl-mode
685   :mode "\\.vcl\\'"
686   )
687 #+END_SRC
688 ** Vertico
689 #+BEGIN_SRC emacs-lisp
690 (use-package vertico
691   :demand t
692   :config
693   (vertico-mode)
694   ; (define-key vertico-map "\r" #'vertico-directory-enter)
695   ; (define-key vertico-map "\d" #'vertico-directory-delete-char)
696   ; (define-key vertico-map "\M-\d" #'vertico-directory-delete-word)
697   ; (add-hook 'rfn-eshadow-update-overlay-hook #'vertico-directory-tidy)
698
699   ;; Different scroll margin
700   ;; (setq vertico-scroll-margin 0)
701
702   ;; Show more candidates
703   ;; (setq vertico-count 20)
704
705   ;; Grow and shrink the Vertico minibuffer
706   ;; (setq vertico-resize t)
707
708   ;; Optionally enable cycling for `vertico-next' and `vertico-previous'.
709   ;; (setq vertico-cycle t)
710   :custom
711   (vertico-grid-separator "       ")
712   (vertico-grid-lookahead 50)
713 )
714 (use-package vertico-multiform
715   :straight nil
716   :load-path "~/var/emacs/straight/build/vertico/extensions/"
717   :after vertico
718   :config
719   (setq vertico-multiform-categories
720      '((file reverse)
721        (consult-grep buffer)
722        (consult-location)
723        (imenu buffer)
724        (library reverse indexed)
725        (org-roam-node reverse indexed)
726        ; (t reverse)
727        )
728      )
729   (setq vertico-multiform-commands
730         '(("flyspell-correct-*" grid reverse)
731           (org-refile grid reverse indexed)
732           (consult-yank-pop indexed)
733           (consult-flycheck)
734           (consult-lsp-diagnostics)
735           )
736         )
737   (vertico-multiform-mode)
738   )
739
740 (use-package vertico-grid
741   :straight nil
742   :after vertico
743   )
744 (use-package vertico-reverse
745   :straight nil
746   :after vertico
747   )
748 (use-package vertico-indexed
749   :straight nil
750   :after vertico
751   )
752 (use-package vertico-buffer
753   :straight nil
754   :after vertico
755   )
756
757
758 ;; Persist history over Emacs restarts. Vertico sorts by history position.
759 (use-package savehist
760   :demand t
761   :config
762   (savehist-mode))
763
764 #+END_SRC
765 ** Orderless: advanced completion style
766 #+begin_src emacs-lisp
767 (use-package orderless
768   :init
769   ;; Configure a custom style dispatcher (see the Consult wiki)
770   ;; (setq orderless-style-dispatchers '(+orderless-dispatch)
771   ;;       orderless-component-separator #'orderless-escapable-split-on-space)
772   (setq completion-styles '(orderless basic)
773         completion-category-defaults nil
774         completion-category-overrides '((file (styles partial-completion)))))
775 #+end_src
776 ** Marginalia: Rich annotations in the minibuffer
777 #+begin_src emacs-lisp
778 (use-package marginalia
779   :demand t
780   :bind (:map minibuffer-local-map
781          ("M-A" . marginalia-cycle))
782   :config
783   (marginalia-mode)
784   )
785 #+end_src
786 ** Embark: Minibuffer actions and context menu
787 #+begin_src emacs-lisp
788 (use-package embark
789   :bind
790   (("C-." . embark-act)         ;; pick some comfortable binding
791    ("C-;" . embark-dwim)        ;; good alternative: M-.
792    ("C-h B" . embark-bindings)) ;; alternative for `describe-bindings'
793
794   :init
795
796   ;; Optionally replace the key help with a completing-read interface
797   (setq prefix-help-command #'embark-prefix-help-command)
798
799   :config
800
801   ;; Hide the mode line of the Embark live/completions buffers
802   (add-to-list 'display-buffer-alist
803                '("\\`\\*Embark Collect \\(Live\\|Completions\\)\\*"
804                  nil
805                  (window-parameters (mode-line-format . none)))))
806
807 (use-package embark-consult
808   :hook
809   (embark-collect-mode . consult-preview-at-point-mode))
810 #+end_src
811 ** which-key (show possible completions of a key combination)
812 #+BEGIN_SRC emacs-lisp
813 (use-package which-key
814   :demand t
815   )
816 #+END_SRC
817 ** Consult
818 #+begin_src emacs-lisp
819 (use-package consult
820   ;; Replace bindings. Lazily loaded due by `use-package'.
821   :bind (;; C-c bindings in `mode-specific-map'
822          ("C-c M-x" . consult-mode-command)
823          ("C-c h" . consult-history)
824          ("C-c k" . consult-kmacro)
825          ("C-c m" . consult-man)
826          ("C-c i" . consult-info)
827          ([remap Info-search] . consult-info)
828          ;; C-x bindings in `ctl-x-map'
829          ("C-x M-:" . consult-complex-command)     ;; orig. repeat-complex-command
830          ("C-x b" . consult-buffer)                ;; orig. switch-to-buffer
831          ("C-x 4 b" . consult-buffer-other-window) ;; orig. switch-to-buffer-other-window
832          ("C-x 5 b" . consult-buffer-other-frame)  ;; orig. switch-to-buffer-other-frame
833          ("C-x r b" . consult-bookmark)            ;; orig. bookmark-jump
834          ("C-x p b" . consult-project-buffer)      ;; orig. project-switch-to-buffer
835          ;; Custom M-# bindings for fast register access
836          ("M-#" . consult-register-load)
837          ("M-'" . consult-register-store)          ;; orig. abbrev-prefix-mark (unrelated)
838          ("C-M-#" . consult-register)
839          ;; Other custom bindings
840          ("M-y" . consult-yank-pop)                ;; orig. yank-pop
841          ;; M-g bindings in `goto-map'
842          ("M-g e" . consult-compile-error)
843          ("M-g f" . consult-flymake)               ;; Alternative: consult-flycheck
844          ("M-g g" . consult-goto-line)             ;; orig. goto-line
845          ("M-g M-g" . consult-goto-line)           ;; orig. goto-line
846          ("M-g o" . consult-outline)               ;; Alternative: consult-org-heading
847          ("M-g m" . consult-mark)
848          ("M-g k" . consult-global-mark)
849          ("M-g i" . consult-imenu)
850          ("M-g I" . consult-imenu-multi)
851          ;; M-s bindings in `search-map'
852          ("M-s d" . consult-find)
853          ("M-s D" . consult-locate)
854          ("M-s g" . consult-grep)
855          ("M-s G" . consult-git-grep)
856          ("M-s r" . consult-ripgrep)
857          ("M-s l" . consult-line)
858          ("M-s L" . consult-line-multi)
859          ("M-s k" . consult-keep-lines)
860          ("M-s u" . consult-focus-lines)
861          ;; Isearch integration
862          ("M-s e" . consult-isearch-history)
863          :map isearch-mode-map
864          ("M-e" . consult-isearch-history)         ;; orig. isearch-edit-string
865          ("M-s e" . consult-isearch-history)       ;; orig. isearch-edit-string
866          ("M-s l" . consult-line)                  ;; needed by consult-line to detect isearch
867          ("M-s L" . consult-line-multi)            ;; needed by consult-line to detect isearch
868          ;; Minibuffer history
869          :map minibuffer-local-map
870          ("M-s" . consult-history)                 ;; orig. next-matching-history-element
871          ("M-r" . consult-history))                ;; orig. previous-matching-history-element
872
873   ;; Enable automatic preview at point in the *Completions* buffer. This is
874   ;; relevant when you use the default completion UI.
875   :hook (completion-list-mode . consult-preview-at-point-mode)
876
877   :commands (consult-xref)
878
879   ;; The :init configuration is always executed (Not lazy)
880   :init
881
882   ;; Optionally configure the register formatting. This improves the register
883   ;; preview for `consult-register', `consult-register-load',
884   ;; `consult-register-store' and the Emacs built-ins.
885   (setq register-preview-delay 0.5
886         register-preview-function #'consult-register-format)
887
888   ;; Optionally tweak the register preview window.
889   ;; This adds thin lines, sorting and hides the mode line of the window.
890   (advice-add #'register-preview :override #'consult-register-window)
891
892   ;; Use Consult to select xref locations with preview
893   (setq xref-show-xrefs-function #'consult-xref
894         xref-show-definitions-function #'consult-xref)
895
896   ;; Configure other variables and modes in the :config section,
897   ;; after lazily loading the package.
898   :config
899   ;; Optionally configure preview. The default value
900   ;; is 'any, such that any key triggers the preview.
901   ;; (setq consult-preview-key 'any)
902   ;; (setq consult-preview-key "M-.")
903   ;; (setq consult-preview-key '("S-<down>" "S-<up>"))
904   ;; For some commands and buffer sources it is useful to configure the
905   ;; :preview-key on a per-command basis using the `consult-customize' macro.
906   (consult-customize
907    consult-theme :preview-key '(:debounce 0.2 any)
908    consult-ripgrep consult-git-grep consult-grep
909    consult-bookmark consult-recent-file consult-xref
910    consult--source-bookmark consult--source-file-register
911    consult--source-recent-file consult--source-project-recent-file
912    ;; :preview-key "M-."
913    :preview-key '(:debounce 0.4 any))
914
915   ;; Optionally configure the narrowing key.
916   ;; Both < and C-+ work reasonably well.
917   (setq consult-narrow-key "<") ;; "C-+"
918
919   ;; Optionally make narrowing help available in the minibuffer.
920   ;; You may want to use `embark-prefix-help-command' or which-key instead.
921   ;; (define-key consult-narrow-map (vconcat consult-narrow-key "?") #'consult-narrow-help)
922
923   ;; By default `consult-project-function' uses `project-root' from project.el.
924   ;; Optionally configure a different project root function.
925   ;;;; 1. project.el (the default)
926   ;; (setq consult-project-function #'consult--default-project--function)
927   ;;;; 2. vc.el (vc-root-dir)
928   ;; (setq consult-project-function (lambda (_) (vc-root-dir)))
929   ;;;; 3. locate-dominating-file
930   ;; (setq consult-project-function (lambda (_) (locate-dominating-file "." ".git")))
931   ;;;; 4. projectile.el (projectile-project-root)
932   ;; (autoload 'projectile-project-root "projectile")
933   ;; (setq consult-project-function (lambda (_) (projectile-project-root)))
934   ;;;; 5. No project support
935   ;; (setq consult-project-function nil)
936 )
937 #+end_src
938 ** Projectile -- Project management
939 #+begin_src emacs-lisp
940 (use-package projectile
941   :bind (("<f5>" . projectile-compile-project)
942          ("<f6>" . next-error))
943   :config (projectile-global-mode))
944 #+end_src
945
946 ** Zap to char
947 #+BEGIN_SRC emacs-lisp
948 (use-package avy-zap
949   :bind ("M-z" . avy-zap-up-to-char-dwim))
950 #+END_SRC
951 ** Hydra
952 #+BEGIN_SRC emacs-lisp
953 (use-package hydra
954   :bind (("C-c 2" . my/hydra-orgmodes/body)
955          ("C-c @" . my/hydra-orgmodes/body)
956          ("C-c #" . my/hydra-outline/body)
957          ("C-c 3" . my/hydra-outline/body)
958          )
959   :config
960   (defhydra my/hydra-orgmodes (:color blue :hint nil)
961   "
962 _n_: notes _c_: chaim _w_: wildman _o_: ool
963 _u_: uddin _s_: steve _r_: refile  _f_: fh    
964 _p_: read papers      _R_: paper notes
965 _h_: hpcbio
966 _q_: quit
967 _z_: quit
968 "
969   ("n" (find-file "~/projects/org-notes/notes.org"))
970   ("c" (find-file "~/projects/org-notes/chaim.org"))
971   ("w" (find-file "~/projects/org-notes/wildman.org"))
972   ("u" (find-file "~/projects/org-notes/uddin.org"))
973   ("o" (find-file "~/projects/org-notes/ool.org"))
974   ("f" (find-file "~/projects/org-notes/fh.org"))
975   ("s" (find-file "~/projects/org-notes/sndservers.org"))
976   ("r" (find-file my/org-refile-file))
977   ("p" (find-file "~/projects/research/papers_to_read.org"))
978   ("R" (find-file "~/projects/research/paper_notes.org"))
979   ("h" (find-file "~/projects/org-notes/hpcbio.org"))
980   ("q" nil "quit")
981   ("z" nil "quit")
982   )
983
984   ;; from https://github.com/abo-abo/hydra/wiki/Emacs
985   (defhydra my/hydra-outline (:color pink :hint nil)
986   "
987 ^Hide^             ^Show^           ^Move
988 ^^^^^^------------------------------------------------------
989 _q_: sublevels     _a_: all         _u_: up
990 _t_: body          _e_: entry       _n_: next visible
991 _o_: other         _i_: children    _p_: previous visible
992 _c_: entry         _k_: branches    _f_: forward same level
993 _l_: leaves        _s_: subtree     _b_: backward same level
994 _d_: subtree
995
996 "
997   ;; Hide
998   ("q" outline-hide-sublevels)    ; Hide everything but the top-level headings
999   ("t" outline-hide-body)         ; Hide everything but headings (all body lines)
1000   ("o" outline-hide-other)        ; Hide other branches
1001   ("c" outline-hide-entry)        ; Hide this entry's body
1002   ("l" outline-hide-leaves)       ; Hide body lines in this entry and sub-entries
1003   ("d" outline-hide-subtree)      ; Hide everything in this entry and sub-entries
1004   ;; Show
1005   ("a" outline-show-all)          ; Show (expand) everything
1006   ("e" outline-show-entry)        ; Show this heading's body
1007   ("i" outline-show-children)     ; Show this heading's immediate child sub-headings
1008   ("k" outline-show-branches)     ; Show all sub-headings under this heading
1009   ("s" outline-show-subtree)      ; Show (expand) everything in this heading & below
1010   ;; Move
1011   ("u" outline-up-heading)                ; Up
1012   ("n" outline-next-visible-heading)      ; Next
1013   ("p" outline-previous-visible-heading)  ; Previous
1014   ("f" outline-forward-same-level)        ; Forward - same level
1015   ("b" outline-backward-same-level)       ; Backward - same level
1016   ("z" nil "leave"))
1017 )
1018 #+END_SRC
1019
1020 ** Tramp
1021 #+BEGIN_SRC emacs-lisp
1022 (use-package tramp
1023   :demand t
1024   ; use the built in tramp
1025   :straight nil
1026   :config
1027   (setq tramp-use-ssh-controlmaster-options nil)
1028   (add-to-list 'tramp-methods '("vcsh"
1029                                 (tramp-login-program "vcsh")
1030                                 (tramp-login-args
1031                                  (("enter")
1032                                   ("%h")))
1033                                 (tramp-remote-shell "/bin/sh")
1034                                 (tramp-remote-shell-args
1035                                  ("-c")))))
1036 #+END_SRC
1037 ** Reftex
1038 #+BEGIN_SRC emacs-lisp
1039 (use-package reftex
1040   :hook ((LaTeX-mode latex-mode) . reftex-mode)
1041   :config
1042   (setq-default reftex-default-bibliography
1043                   '("~/projects/research/references.bib"))
1044   (setq-default reftex-plug-into-AUCTeX t)
1045   )
1046 #+END_SRC
1047 ** BibTex
1048 #+BEGIN_SRC emacs-lisp
1049 (use-package bibtex
1050   :mode "\\.bib\\'"
1051   :config (setq bibtex-user-optional-fields
1052                 (quote (("annote" "Personal annotation (ignored)")
1053                         ("abstract" "")
1054                 ("pmid" "")
1055                 ("doi" ""))))
1056   )
1057
1058 #+END_SRC
1059 ** LaTeX
1060 #+BEGIN_SRC emacs-lisp
1061 (use-package tex
1062   :straight auctex
1063   :mode ("\\.tex\\'" . LaTeX-mode)
1064   :config
1065   ; (add-to-list 'TeX-style-path '"/home/don/lib/emacs_el/auctex/style")
1066   (add-hook 'LaTeX-mode-hook 'outline-minor-mode)   ; with AUCTeX LaTeX mode
1067   (add-hook 'latex-mode-hook 'outline-minor-mode)   ; with Emacs latex mode
1068
1069   ;; support fake section headers
1070   (setq TeX-outline-extra
1071         '(("%chapter" 1)
1072           ("%section" 2)
1073           ("%subsection" 3)
1074           ("%subsubsection" 4)
1075           ("%paragraph" 5)))
1076   ;; add font locking to the headers
1077   (font-lock-add-keywords
1078    'latex-mode
1079    '(("^%\\(chapter\\|\\(sub\\|subsub\\)?section\\|paragraph\\)"
1080       0 'font-lock-keyword-face t)
1081      ("^%chapter{\\(.*\\)}"       1 'font-latex-sectioning-1-face t)
1082      ("^%section{\\(.*\\)}"       1 'font-latex-sectioning-2-face t)
1083      ("^%subsection{\\(.*\\)}"    1 'font-latex-sectioning-3-face t)
1084      ("^%subsubsection{\\(.*\\)}" 1 'font-latex-sectioning-4-face t)
1085      ("^%paragraph{\\(.*\\)}"     1 'font-latex-sectioning-5-face t)))
1086
1087   ;; use smart quotes by default instead of `` and ''
1088   ;; taken from http://kieranhealy.org/esk/kjhealy.html
1089   (setq TeX-open-quote "“")
1090   (setq TeX-close-quote "”")
1091
1092   ;; (TeX-add-style-hook
1093   ;;  "latex"
1094   ;;  (lambda ()
1095   ;;    (TeX-add-symbols
1096   ;;     '("DLA" 1))))
1097   ;; (custom-set-variables
1098   ;;  '(font-latex-user-keyword-classes 
1099   ;;    '(("fixme" 
1100   ;;       ("DLA" "RZ")
1101   ;;       font-lock-function-name-face 2 (command 1 t))))
1102   ;; ) 
1103   (setq-default TeX-parse-self t)
1104   (setq-default TeX-auto-save t)
1105   (setq-default TeX-master nil)
1106   (add-to-list 'LaTeX-font-list
1107                '(?\C-a "\\alert{","}"))
1108   (eval-after-load
1109       "latex"
1110     '(TeX-add-style-hook
1111       "cleveref"
1112       (lambda ()
1113         (if (boundp 'reftex-ref-style-alist)
1114             (add-to-list
1115              'reftex-ref-style-alist
1116              '("Cleveref" "cleveref"
1117                (("\\cref" ?c) ("\\Cref" ?C) ("\\cpageref" ?d) ("\\Cpageref" ?D)))))
1118         (reftex-ref-style-activate "Cleveref")
1119         (TeX-add-symbols
1120          '("cref" TeX-arg-ref)
1121          '("Cref" TeX-arg-ref)
1122          '("cpageref" TeX-arg-ref)
1123          '("Cpageref" TeX-arg-ref)))))
1124   (eval-after-load
1125       "latex"
1126     '(add-to-list 'LaTeX-fill-excluded-macros
1127                   '("Sexpr")))
1128   
1129   (setq font-latex-match-reference-keywords
1130         '(
1131           ("fref" "{")
1132           ("Fref" "{")
1133           ("citep" "{")
1134           ("citet" "{")
1135           ("acs" "{")
1136           ("acsp" "{")
1137           ("ac" "{")
1138           ("acp" "{")
1139           ("acl" "{")
1140           ("aclp" "{")
1141           ("acsu" "{")
1142           ("aclu" "{")
1143           ("acused" "{")
1144           ("DLA" "{")
1145           ("RZ" "{")
1146           ("OM" "{")
1147           ("DL" "{")
1148           ("fixme" "{"))
1149         )
1150   (setq font-latex-fontify-script nil)
1151   (setq font-latex-fontify-sectioning (quote color))
1152   (setq font-latex-script-display (quote (nil)))
1153 )
1154
1155 #+END_SRC
1156 ** ESS
1157 #+BEGIN_SRC emacs-lisp
1158 (use-package ess
1159   :commands R
1160   :mode ("\\.R\\'" . ess-r-mode)
1161   :bind (:map ess-mode-map
1162               ("C-c C-R" . dla/ess-region-remote-eval))
1163   :init
1164   (autoload 'ess-r-mode "ess-site" nil t)
1165   (autoload 'R "ess-site" nil t)
1166   :config
1167   ; actually load the rest of ess
1168   (require 'ess-site)
1169   (defun ess-change-directory (path)
1170     "Set the current working directory to PATH for both *R* and Emacs."
1171     (interactive "Directory to change to: ")
1172
1173     (when (file-exists-p path)
1174       (ess-command (concat "setwd(\"" path "\")\n"))
1175       ;; use file-name-as-directory to ensure it has trailing /
1176       (setq default-directory (file-name-as-directory path))))
1177   (add-hook 'ess-mode-hook 'flyspell-prog-mode)
1178   ;; outlining support for ess modes
1179   (add-hook
1180    'ess-mode-hook
1181    '(lambda ()
1182       (outline-minor-mode)
1183       (setq outline-regexp "\\(^#\\{4,5\\} \\)\\|\\(^[a-zA-Z0-9_\.]+ ?<- ?function\\)")
1184       (defun outline-level ()
1185         (cond ((looking-at "^##### ") 1)
1186               ((looking-at "^#### ") 2)
1187               ((looking-at "^[a-zA-Z0-9_\.]+ ?<- ?function(.*{") 3)
1188               (t 1000)))
1189       ))
1190   (defun dla/ess-region-remote-eval (start end)
1191     "Evaluate region in a remote ESS instance"
1192     (interactive "r")
1193     (shell-command-on-region start end "eval_r" (get-buffer-create "***essregionremoteeval***") nil nil nil)
1194     (kill-buffer "***essregionremoteeval***"))
1195   ;; Don't restore history or save workspace image
1196   '(inferior-R-args "--no-restore-history --no-save")
1197   )
1198 #+END_SRC
1199
1200 ** Rainbowmode
1201 From http://julien.danjou.info/projects/emacs-packages#rainbow-mode, this colorizes color strings
1202
1203 #+BEGIN_SRC emacs-lisp
1204 (use-package rainbow-mode
1205   :hook ((LaTeX-mode ess-mode python-mode cperl-mode) . rainbow-mode)
1206   :delight 🌈
1207   ;; add ess to the x major mode
1208   :config (add-to-list 'rainbow-x-colors-major-mode-list 'ESS[S])
1209   (add-to-list 'rainbow-x-colors-major-mode-list 'ESS[R])
1210 )
1211 #+END_SRC
1212
1213 ** YAML Mode
1214 #+BEGIN_SRC emacs-lisp
1215 (use-package yaml-mode
1216   ;; add ess to the x major mode
1217   :mode ("\\.\\(yaml|yml\\)\\'" . yaml-mode)
1218 )
1219 #+END_SRC
1220
1221 ** Polymode
1222 #+BEGIN_SRC emacs-lisp
1223 (use-package poly-noweb
1224   :after polymode
1225
1226   )
1227 (use-package poly-markdown
1228   :after polymode
1229   )
1230 (use-package poly-R
1231   :after (:all polymode poly-markdown poly-noweb)
1232   :mode ("\\.Snw" . poly-noweb+r-mode)
1233   :mode ("\\.Rnw" . poly-noweb+r-mode)
1234   :mode ("\\.Rmd" . poly-markdown+r-mode)
1235   )
1236 (use-package polymode
1237   :defer t
1238   )
1239
1240 #+END_SRC
1241
1242 ** Outlining
1243 *** outline minor mode
1244 #+BEGIN_SRC emacs-lisp
1245 (use-package outline
1246    :straight nil
1247    :delight
1248    :init
1249    ; (setq outline-minor-mode-prefix nil)
1250    :config
1251    (define-prefix-command 'cm-map nil "Outline-")
1252    (global-set-key "\M-o" cm-map)
1253    ; Outline-minor-mode key map
1254 ; HIDE
1255 (define-key cm-map "q" 'outline-hide-sublevels)    ; Hide everything but the top-level headings
1256 (define-key cm-map "t" 'outline-hide-body)         ; Hide everything but headings (all body lines)
1257 (define-key cm-map "o" 'outline-hide-other)        ; Hide other branches
1258 (define-key cm-map "c" 'outline-hide-entry)        ; Hide this entry's body
1259 (define-key cm-map "l" 'outline-hide-leaves)       ; Hide body lines in this entry and sub-entries
1260 (define-key cm-map "d" 'outline-hide-subtree)      ; Hide everything in this entry and sub-entries
1261 ; SHOW
1262 (define-key cm-map "a" 'outline-show-all)          ; Show (expand) everything
1263 (define-key cm-map "e" 'outline-show-entry)        ; Show this heading's body
1264 (define-key cm-map "i" 'outline-show-children)     ; Show this heading's immediate child sub-headings
1265 (define-key cm-map "k" 'outline-show-branches)     ; Show all sub-headings under this heading
1266 (define-key cm-map "s" 'outline-show-subtree)      ; Show (expand) everything in this heading & below
1267 ; MOVE
1268 (define-key cm-map "u" 'outline-up-heading)                ; Up
1269 (define-key cm-map "n" 'outline-next-visible-heading)      ; Next
1270 (define-key cm-map "p" 'outline-previous-visible-heading)  ; Previous
1271 (define-key cm-map "f" 'outline-forward-same-level)        ; Forward - same level
1272 (define-key cm-map "b" 'outline-backward-same-level)       ; Backward - same level
1273
1274 )
1275 #+END_SRC
1276 *** outshine (outlining) integration
1277 #+BEGIN_SRC emacs-lisp
1278 ; (use-package outshine
1279 ;   :after outline
1280 ;   :hook (outline-minor-mode . outshine-mode)
1281 ; )
1282 #+END_SRC
1283 ** Writeroom Mode
1284 #+BEGIN_SRC emacs-lisp
1285 (use-package writeroom-mode
1286   :commands (writeroom-mode)
1287   :config
1288   (defun my/writing-mode ()
1289     "Start my writing mode; enable visual-line-mode and auto-fill-mode"
1290     (interactive)
1291     (if writeroom-mode
1292         (progn
1293           (writeroom-mode -1)
1294           (visual-line-mode -1)
1295           (auto-fill-mode -1)
1296           (visual-fill-column-mode -1)
1297           )
1298       (visual-line-mode 1)
1299       (auto-fill-mode 1)
1300       (visual-fill-column-mode 1)
1301       (writeroom-mode 1))
1302     )
1303   )
1304 #+END_SRC
1305 ** GhostText/Atomic Chrome
1306 #+BEGIN_SRC emacs-lisp
1307 (use-package atomic-chrome
1308   :config
1309   (ignore-errors (atomic-chrome-start-server))
1310   (setq atomic-chrome-buffer-open-style 'full)
1311   )
1312 #+END_SRC
1313 ** Edit Server
1314 #+BEGIN_SRC emacs-lisp
1315 (use-package edit-server
1316   :commands edit-server-start
1317   :init (if after-init-time
1318             (edit-server-start)
1319           (add-hook 'after-init-hook
1320                     #'(lambda() (edit-server-start))))
1321   :config (setq edit-server-new-frame-alist
1322                 '((name . "Edit with Emacs FRAME")
1323                   (top . 200)
1324                   (left . 200)
1325                   (width . 80)
1326                   (height . 25)
1327                   (minibuffer . t)
1328                   (menu-bar-lines . t)
1329                   (window-system . x)))
1330   )
1331 #+END_SRC
1332 ** Multiple Cursors
1333 [[https://github.com/magnars/multiple-cursors.el][Multiple Cursors]]
1334 #+BEGIN_SRC emacs-lisp
1335 (use-package multiple-cursors
1336   :bind* (("C-;" . mc/mark-all-dwim)
1337           ("C-<" . mc/mark-previous-like-this)
1338           ("C->" . mc/mark-next-like-this)
1339           ("C-S-c C-S-c" . mc/edit-lines))
1340   )
1341 #+END_SRC
1342 ** Web Mode
1343 #+BEGIN_SRC emacs-lisp
1344 (use-package web-mode
1345   :mode ("\\.\\(tx|tmpl\\)\\'" . web-mode)
1346   :config
1347   (add-to-list 'auto-mode-alist '("\\.tmpl\\'" . web-mode))
1348   (setq web-mode-enable-engine-detection t)
1349   (setq web-mode-engines-alist
1350         '(("template-toolkit" . "\\.tmpl\\'")))
1351   )
1352 #+END_SRC
1353 ** Spamassassin Mode
1354 #+BEGIN_SRC emacs-lisp
1355 (use-package spamassassin-mode
1356   :straight nil
1357   :load-path "~/lib/emacs_el"
1358   :commands spamassassin-mode
1359   )
1360 #+END_SRC
1361 ** Password Store
1362 #+BEGIN_SRC emacs-lisp
1363 (use-package password-store
1364   :commands password-store-edit password-store-generate
1365   :config
1366   (defun dla/password-store-edit (entry)
1367     "Edit password for ENTRY which doesn't require it to already exist"
1368     (interactive (list (password-store--completing-read nil)))
1369     (password-store--run-edit entry))
1370   (advice-add 'password-store-edit :override #'dla/password-store-edit)
1371   )
1372 #+END_SRC
1373 ** CSS mode
1374 #+BEGIN_SRC emacs-lisp
1375 (use-package css
1376   :straight css-mode
1377   :mode "\\.css'"
1378   :config
1379   ;; fix up css mode to not be silly
1380   ;; from http://www.stokebloke.com/wordpress/2008/03/21/css-mode-indent-buffer-fix/
1381   (setq cssm-indent-level 4)
1382   (setq cssm-newline-before-closing-bracket t)
1383   (setq cssm-indent-function #'cssm-c-style-indenter)
1384   (setq cssm-mirror-mode nil))
1385 #+END_SRC
1386 ** Abbrev Mode
1387 #+BEGIN_SRC emacs-lisp
1388 (use-package abbrev
1389   :straight nil
1390   :delight abbrev-mode
1391   :config
1392   ;; load abbreviations from 
1393   (setq abbrev-file-name       
1394         "~/.emacs_abbrev_def")
1395
1396   ;; read the abbrev file if it exists
1397   (if (file-exists-p abbrev-file-name)
1398       (quietly-read-abbrev-file))
1399
1400   ;; for now, use abbrev mode everywhere
1401   :init 
1402   (setq default-abbrev-mode t))
1403 #+END_SRC
1404
1405 ** Debugging (realgud)
1406 #+BEGIN_SRC emacs-lisp
1407 (use-package realgud
1408   :commands (realgud:pdb realgud:gdb)
1409   )
1410 #+END_SRC
1411 ** Python Programming
1412 #+BEGIN_SRC emacs-lisp
1413 (use-package python-mode
1414   :delight Py 🐍
1415   :hook
1416   (python-mode . pyvenv-mode)
1417   (python-mode . flycheck-mode)
1418   (python-mode . blacken-mode)
1419   (python-mode . yas-minor-mode)
1420   (python-mode . anaconda-mode)
1421   )
1422 (use-package pyvenv
1423   :delight
1424   :after python-mode
1425   )
1426 (use-package blacken
1427   :delight
1428   :after python-mode
1429   :commands (blacken-buffer)
1430   :config
1431   (setq-default blacken-fast-unsafe t)
1432 )
1433 #+END_SRC
1434 *** Black
1435 #+begin_src emacs-lisp :tangle yes
1436 (use-package python-black
1437   :delight
1438   :commands (python-black-buffer python-black-statement)
1439   :after python)
1440 #+end_src
1441 *** Sphinx Documentation
1442 #+begin_src emacs-lisp :tangle yes
1443 (use-package numpydoc
1444   :after python
1445   :bind (:map python-mode-map
1446               ("C-c C-n" . numpydoc-generate)))
1447 (use-package sphinx-doc
1448   :delight 🐈
1449   :config
1450   (setq sphinx-doc-include-types t)
1451   :after python
1452   :hook (python-mode . sphinx-doc-mode)
1453   )
1454 (use-package python-docstring
1455   :delight 
1456   :after python
1457   :hook (python-mode . python-docstring-mode)
1458   )
1459 #+end_src
1460 *** Anaconda Mode (Documentation lookup and completion)
1461 #+BEGIN_SRC emacs-lisp
1462 (use-package anaconda-mode
1463   :delight
1464   :after python
1465 )
1466 #+END_SRC
1467 ** Go language
1468 #+BEGIN_SRC emacs-lisp
1469 (use-package go-mode
1470              :delight "go"
1471              :mode "\\.go"
1472              )
1473 #+END_SRC
1474
1475 ** Expand region
1476 #+BEGIN_SRC emacs-lisp
1477 (use-package expand-region
1478   :bind (("C-=" . 'er/expand-region))
1479   )
1480 #+END_SRC
1481
1482 ** Dockerfile
1483 #+BEGIN_SRC emacs-lisp
1484 (use-package dockerfile-mode
1485   :mode "Dockerfile"
1486   )
1487 #+END_SRC
1488
1489 ** Beancount
1490 #+BEGIN_SRC emacs-lisp
1491 (use-package beancount
1492   :straight (beancount
1493              :type git
1494              :host github
1495              :repo "cnsunyour/beancount.el")
1496   :load-path "~/lib/emacs_el/beancount-mode/"
1497   :mode "\\.bean\\(?:count\\)?\\'"
1498   
1499   )
1500 #+END_SRC
1501 ** Apache
1502 #+BEGIN_SRC emacs-lisp
1503 (use-package apache-mode
1504   :delight 🪶
1505   :mode "apache\\.conf\\'"
1506   )
1507 #+END_SRC
1508 ** ELDoc
1509 #+BEGIN_SRC emacs-lisp
1510 (use-package eldoc
1511   :delight
1512   :commands eldoc-mode
1513   :straight nil
1514   )
1515 #+END_SRC
1516
1517 * Email
1518 ** Mutt
1519 *** Message-mode
1520 #+BEGIN_SRC emacs-lisp
1521 (use-package message
1522   :straight nil
1523   :delight (message "✉")
1524   :delight (message-mode "✉")
1525   :mode ("muttng-[a-z0-9]+-[0-9]+-" . message-mode)
1526   :mode ("mutt-[a-z0-9]+-[0-9]+-" . message-mode)
1527   :hook 'my/message-mode-settings
1528   :hook 'turn-on-flyspell
1529   :bind (:map message-mode-map
1530       ("C-c C-a" . my/post-attach-file)
1531       ("C-x p" . my/message-kill-buffer)
1532       )
1533   :config
1534   (defun my/message-mode-settings ()
1535     (font-lock-add-keywords nil
1536                 '(("^[ \t]*>[ \t]*>[ \t]*>.*$"
1537                (0 'message-multiply-quoted-text-face))
1538               ("^[ \t]*>[ \t]*>.*$"
1539                (0 'message-double-quoted-text-face))))
1540     )
1541   (defun my/message-kill-buffer ()
1542     (interactive)
1543     (kill-buffer nil)
1544     )
1545   (defun my/post-attach-file ()
1546     "Prompt for an attachment."
1547     (interactive)
1548     (let ((file (read-file-name "Attach file: " nil nil t nil)))
1549       (my/header-attach-file file "")))
1550
1551   (defun my/header-attach-file (file description)
1552     "Attach a FILE to the current message (works with Mutt).
1553   Argument DESCRIPTION MIME description."
1554     (interactive "fAttach file: \nsDescription: ")
1555     (when (> (length file) 0)
1556   (save-excursion
1557     (save-match-data
1558       (save-restriction
1559         (widen)
1560         (goto-char (point-min))
1561         (search-forward-regexp "^$")
1562         (insert (concat "Attach: " (replace-regexp-in-string "\\([[:space:]\\]\\)" "\\\\\\1" (file-truename file)) " "
1563                 description "\n"))
1564         (message (concat "Attached '" file "'."))
1565         (setq post-has-attachment t))))))
1566
1567   (setq mail-yank-prefix "> ")
1568   (setq mail-header-separator "") ; fix broken header detection
1569 )
1570 #+END_SRC
1571 *** Muttrc mode
1572 #+BEGIN_SRC emacs-lisp
1573 (use-package mutt-mode
1574   :mode "muttngrc"
1575   :mode "muttrc"
1576   :config
1577   (setq mutt-alias-file-list (quote ("~/.mutt/aliases" "~/.mail_aliases")))
1578 )
1579 #+END_SRC
1580 *** Set mail User agent
1581 #+BEGIN_SRC emacs-lisp
1582 (setq mail-user-agent (quote sendmail-user-agent))
1583 #+END_SRC
1584 * Base emacs
1585 ** Reverting buffers
1586 #+BEGIN_SRC emacs-lisp
1587 (use-package autorevert
1588   :delight auto-revert-mode
1589   :demand t
1590   :config
1591   (setq global-auto-revert-non-file-buffers t
1592         global-auto-revert-ignore-modes '(pdf-view-mode)
1593         auto-revert-verbose nil)
1594   (global-auto-revert-mode 1))
1595 #+END_SRC
1596 * Org Mode
1597 ** Use-package and load things
1598 #+BEGIN_SRC emacs-lisp
1599
1600 (use-package org
1601   :delight (org-mode "ø")
1602   :mode ("\\.\\(org\\|org_archive\\|txt\\)\\'" . org-mode)
1603   :bind (("C-c l l" . org-store-link)
1604          ("C-c a"  . org-agenda)
1605          ("C-c b"  . org-iswitchb))
1606 #+END_SRC
1607 ** Agenda Configuration
1608 #+BEGIN_SRC emacs-lisp
1609   :config
1610   (setq-default org-log-done 'time)
1611   (setq-default org-agenda-ndays 5)
1612
1613   (setq org-agenda-sticky t)
1614   (defun dla/show-org-agenda ()
1615     (interactive)
1616     (let (agendabuffer
1617           '(delq nil 
1618                 (mapcar (lambda (x)
1619                           (and (string-match-p
1620                                 "\*Org Agenda.*\*"
1621                                 (buffer-name x))
1622                                x)
1623                           )
1624                         (buffer-list))))
1625       (if agendabuffer
1626           (switch-to-buffer
1627            (buffer-name agendabuffer))
1628         (org-agenda-list)))
1629       (delete-other-windows))
1630
1631   ;; agenda configuration
1632   ;; Do not dim blocked tasks
1633   (setq org-agenda-dim-blocked-tasks nil)
1634   (setq org-agenda-inhibit-startup t)
1635   (setq org-agenda-use-tag-inheritance nil)
1636
1637   ;; Compact the block agenda view
1638   (setq org-agenda-compact-blocks t)
1639
1640   ;; Custom agenda command definitions
1641   (setq org-agenda-custom-commands
1642         (quote (("N" "Notes" tags "NOTE"
1643                  ((org-agenda-overriding-header "Notes")
1644                   (org-tags-match-list-sublevels t)))
1645                 ("h" "Habits" tags-todo "STYLE=\"habit\""
1646                  ((org-agenda-overriding-header "Habits")
1647                   (org-agenda-sorting-strategy
1648                    '(todo-state-down effort-up category-keep))))
1649                 (" " "Agenda"
1650                  ((agenda "" nil)
1651                   (tags "REFILE"
1652                         ((org-agenda-overriding-header "Tasks to Refile")
1653                          (org-tags-match-list-sublevels nil)))
1654                   (tags-todo "-CANCELLED/!"
1655                              ((org-agenda-overriding-header "Stuck Projects")
1656                               (org-agenda-skip-function 'bh/skip-non-stuck-projects)
1657                               (org-agenda-sorting-strategy
1658                                '(category-keep))))
1659                   (tags-todo "-HOLD-CANCELLED/!"
1660                              ((org-agenda-overriding-header "Projects")
1661                               (org-agenda-skip-function 'bh/skip-non-projects)
1662                               (org-tags-match-list-sublevels 'indented)
1663                               (org-agenda-sorting-strategy
1664                                '(category-keep))))
1665                   (tags-todo "-CANCELLED/!NEXT"
1666                              ((org-agenda-overriding-header (concat "Project Next Tasks"
1667                                                                     (if bh/hide-scheduled-and-waiting-next-tasks
1668                                                                         ""
1669                                                                       " (including WAITING and SCHEDULED tasks)")))
1670                               (org-agenda-skip-function 'bh/skip-projects-and-habits-and-single-tasks)
1671                               (org-tags-match-list-sublevels t)
1672                               (org-agenda-todo-ignore-scheduled bh/hide-scheduled-and-waiting-next-tasks)
1673                               (org-agenda-todo-ignore-deadlines bh/hide-scheduled-and-waiting-next-tasks)
1674                               (org-agenda-todo-ignore-with-date bh/hide-scheduled-and-waiting-next-tasks)
1675                               (org-agenda-sorting-strategy
1676                                '(todo-state-down effort-up category-keep))))
1677                   (tags-todo "-REFILE-CANCELLED-WAITING-HOLD/!"
1678                              ((org-agenda-overriding-header (concat "Project Subtasks"
1679                                                                     (if bh/hide-scheduled-and-waiting-next-tasks
1680                                                                         ""
1681                                                                       " (including WAITING and SCHEDULED tasks)")))
1682                               (org-agenda-skip-function 'bh/skip-non-project-tasks)
1683                               (org-agenda-todo-ignore-scheduled bh/hide-scheduled-and-waiting-next-tasks)
1684                               (org-agenda-todo-ignore-deadlines bh/hide-scheduled-and-waiting-next-tasks)
1685                               (org-agenda-todo-ignore-with-date bh/hide-scheduled-and-waiting-next-tasks)
1686                               (org-agenda-sorting-strategy
1687                                '(category-keep))))
1688                   (tags-todo "-REFILE-CANCELLED-WAITING-HOLD/!"
1689                              ((org-agenda-overriding-header (concat "Standalone Tasks"
1690                                                                     (if bh/hide-scheduled-and-waiting-next-tasks
1691                                                                         ""
1692                                                                       " (including WAITING and SCHEDULED tasks)")))
1693                               (org-agenda-skip-function 'bh/skip-project-tasks)
1694                               (org-agenda-todo-ignore-scheduled bh/hide-scheduled-and-waiting-next-tasks)
1695                               (org-agenda-todo-ignore-deadlines bh/hide-scheduled-and-waiting-next-tasks)
1696                               (org-agenda-todo-ignore-with-date bh/hide-scheduled-and-waiting-next-tasks)
1697                               (org-agenda-sorting-strategy
1698                                '(category-keep))))
1699                   (tags-todo "-CANCELLED+WAITING|HOLD/!"
1700                              ((org-agenda-overriding-header "Waiting and Postponed Tasks")
1701                               (org-agenda-skip-function 'bh/skip-stuck-projects)
1702                               (org-tags-match-list-sublevels nil)
1703                               (org-agenda-todo-ignore-scheduled t)
1704                               (org-agenda-todo-ignore-deadlines t)))
1705                   (tags "-REFILE/"
1706                         ((org-agenda-overriding-header "Tasks to Archive")
1707                          (org-agenda-skip-function 'bh/skip-non-archivable-tasks)
1708                          (org-tags-match-list-sublevels nil))))
1709                  nil))))
1710
1711   ; org mode agenda files
1712   (setq org-agenda-files
1713         (append
1714         (file-expand-wildcards "~/projects/org-notes/*.org")
1715         (file-expand-wildcards "~/org-mode/from-mobile.org")
1716         (file-expand-wildcards "~/org-notes-*/*.org")
1717         )
1718   )
1719   (setq my/org-refile-file
1720         (car (seq-filter
1721               (lambda (file) (string-match-p (regexp-quote "/refile.org") file))
1722               org-agenda-files)))
1723
1724   (set-register ?n (cons 'file "~/projects/org-notes/notes.org"))
1725   (set-register ?r (cons 'file my/org-refile-file))
1726   (set-register ?o (cons 'file "~/projects/org-notes/ool.org"))
1727   (set-register ?s (cons 'file "~/projects/org-notes/sndservers.org"))
1728   (set-register ?c (cons 'file "~/projects/org-notes/chaim.org"))
1729   (set-register ?w (cons 'file "~/projects/org-notes/wildman.org"))
1730   (set-register ?u (cons 'file "~/projects/org-notes/uddin.org"))
1731   (set-register ?R (cons 'file "~/projects/reviews/reviews.org"))
1732   (set-register ?d (cons 'file "~/projects/org-notes/diary.org"))
1733   ; from https://emacs.stackexchange.com/questions/909/how-can-i-have-an-agenda-timeline-view-of-multiple-files
1734   ; (defun org-agenda-timeline-all (&optional arg)
1735   ;   (interactive "P")
1736   ;   (with-temp-buffer
1737   ;     (dolist (org-agenda-file org-agenda-files)
1738   ;       (insert-file-contents org-agenda-file nil)
1739   ;       (goto-char (point-max))
1740   ;       (newline))
1741   ;     (write-file "/tmp/timeline.org")
1742   ;     (org-agenda arg "L")))
1743   ; (define-key org-mode-map (kbd "C-c t") 'org-agenda-timeline-all)
1744
1745 #+END_SRC
1746 ** General config
1747 #+BEGIN_SRC emacs-lisp
1748   (setq org-global-properties '(("Effort_ALL 0 0:10 0:30 1:00 2:00 3:00 4:00 5:00 6:00 7:00")))
1749   (setq org-columns-default-format "%40ITEM(Task) %6Effort{:} %CLOCKSUM %PRIORITY %TODO %13SCHEDULED %13DEADLINE %TAGS")
1750
1751   (setq org-default-notes-file "~/projects/org-notes/notes.org")
1752   (setq org-id-link-to-org-use-id 'use-existing)
1753 #+END_SRC
1754 ** Capture Templates
1755 #+BEGIN_SRC emacs-lisp
1756   (setq org-capture-templates  ;; mail-specific note template, identified by "m"
1757         `(("m" "Mail" entry (file my/org-refile-file)
1758            "* %?\n\n  Source: %u, [[%:link][%:description]]\n  %:initial")
1759           ("t" "todo" entry (file my/org-refile-file)
1760            "* TODO %?\n  :PROPERTIES:\n  :END:\n  :LOGBOOK:\n  :END:\n%U\n%a\n" :clock-in t :clock-resume t)
1761           ("r" "respond" entry (file my/org-refile-file)
1762            "* NEXT Respond to %:from on %:subject\nSCHEDULED: %t\n%U\n%a\n" :clock-in t :clock-resume t :immediate-finish t)
1763           ("n" "note" entry (file my/org-refile-file)
1764            "* %? :NOTE:\n%U\n%a\n" :clock-in t :clock-resume t)
1765           ("s" "schedule" entry (file my/org-refile-file)
1766            "* %? :cal:\n%^{scheduled:}t\n%U\n%a\n" :clock-in t :clock-resume t)
1767           ("j" "Journal" entry (file+datetree "~/projects/org-notes/diary.org")
1768            "* %?\n%U\n" :clock-in t :clock-resume t)
1769           ("w" "org-protocol" entry (file my/org-refile-file)
1770            "* TODO Review %c\n%U\n" :immediate-finish t)
1771           ("M" "Meeting" entry (file my/org-refile-file)
1772            "* MEETING with %? :MEETING:\n%U" :clock-in t :clock-resume t)
1773           ("S" "Seminar" entry (file my/org-refile-file)
1774            "* SEMINAR notes %? :SEMINAR:\n%U" :clock-in t :clock-resume t)
1775           ("P" "Paper to read" entry (file+headline "~/projects/research/papers_to_read.org" "Refile")
1776            "* TODO Get/Read %? \n%U" :clock-in t :clock-resume t)
1777           ("p" "Phone call" entry (file my/org-refile-file)
1778            "* PHONE %? :PHONE:\n%U" :clock-in t :clock-resume t)
1779            ("J" "job" entry (file+olp "~/projects/org-notes/notes.org"
1780                                        "Jobs"
1781                                        ,(format-time-string "Positions %Y"))
1782            "* TODO Apply for %? :job:\nSCHEDULED: <%<%Y-%m-%d>>\n%U\n%x\n" :clock-in t :clock-resume t)
1783           ("h" "Habit" entry (file my/org-refile-file)
1784            "* NEXT %?\n%U\n%a\nSCHEDULED: %(format-time-string \"<%Y-%m-%d .+1d/3d>\")\n:PROPERTIES:\n:STYLE: habit\n:REPEAT_TO_STATE: NEXT\n:END:\n%a\n")
1785           )
1786         )
1787
1788   ;; Remove empty LOGBOOK drawers on clock out
1789   (defun bh/remove-empty-drawer-on-clock-out ()
1790     (interactive)
1791     (save-excursion
1792       (beginning-of-line 0)
1793       (org-remove-empty-drawer-at (point))))
1794
1795   (defun my/org-add-id ()
1796     (interactive)
1797     (save-excursion
1798       (if (org-current-level)
1799           ()
1800         (forward-char 1)
1801         )
1802       (org-id-get-create)
1803       )
1804   )
1805
1806 #+END_SRC
1807 ** Org mode key bindings
1808 #+BEGIN_SRC emacs-lisp
1809   ;; org mode configuration from http://doc.norang.ca/org-mode.html
1810   ;; Custom Key Bindings
1811   :bind* (("<f9> a" . org-agenda)
1812           ("<f9> I" . bh/punch-in)
1813           ("<f9> O" . bh/punch-out)
1814           ("<f9> SPC" . bh/clock-in-last-task)
1815           ("<f12>" . dla/show-org-agenda)
1816           ;; ("<f5>" . bh/org-todo)
1817           ("<S-f5>" . bh/widen)
1818           ("<f7>" . bh/set-truncate-lines)
1819           ("<f8>" . org-cycle-agenda-files)
1820           ("<f9> <f9>" . dla/show-org-agenda)
1821           ("<f9> b" . bbdb)
1822           ("<f9> c" . calendar)
1823           ("<f9> f" . boxquote-insert-file)
1824           ("<f9> h" . bh/hide-other)
1825           ("<f9> n" . bh/toggle-next-task-display)
1826           ("<f9> w" . widen)
1827
1828           ("<f9> r" . boxquote-region)
1829           ("<f9> s" . bh/switch-to-scratch)
1830
1831           ("<f9> t" . bh/insert-inactive-timestamp)
1832           ("<f9> T" . bh/toggle-insert-inactive-timestamp)
1833
1834           ("<f9> v" . visible-mode)
1835           ("<f9> l" . org-toggle-link-display)
1836           ("<f9> SPC" . bh/clock-in-last-task)
1837           ("C-<f9>" . previous-buffer)
1838           ("M-<f9>" . org-toggle-inline-images)
1839           ("C-x n r" . narrow-to-region)
1840           ("C-<f10>" . next-buffer)
1841           ("<f11>" . org-clock-goto)
1842           ("C-<f11>" . org-clock-in)
1843           ("C-s-<f12>" . bh/save-then-publish)
1844           ("C-c c" . org-capture))
1845   :config
1846 #+END_SRC
1847 ** Utility Functions
1848 #+BEGIN_SRC emacs-lisp
1849 (defun bh/hide-other ()
1850   (interactive)
1851   (save-excursion
1852     (org-back-to-heading 'invisible-ok)
1853     (outline-hide-other)
1854     (org-cycle)
1855     (org-cycle)
1856     (org-cycle)))
1857
1858 (defun bh/set-truncate-lines ()
1859   "Toggle value of truncate-lines and refresh window display."
1860   (interactive)
1861   (setq truncate-lines (not truncate-lines))
1862   ;; now refresh window display (an idiom from simple.el):
1863   (save-excursion
1864     (set-window-start (selected-window)
1865                       (window-start (selected-window)))))
1866
1867 (defun bh/switch-to-scratch ()
1868   (interactive)
1869   (switch-to-buffer "*scratch*"))
1870
1871 (setq org-use-fast-todo-selection t)
1872 (setq org-treat-S-cursor-todo-selection-as-state-change nil)
1873
1874 ; create function to create headlines in file. This comes from
1875 ; http://stackoverflow.com/questions/13340616/assign-ids-to-every-entry-in-org-mode
1876 (defun my/org-add-ids-to-headlines-in-file ()
1877   "Add ID properties to all headlines in the current file which
1878 do not already have one."
1879   (interactive)
1880   (save-excursion
1881     (widen)
1882     (goto-char (point-min))
1883     (when (not (re-search-forward "^#\\+OPTIONS:.*auto-id:f" (point-max) t))
1884       (org-map-entries 'org-id-get-create))))
1885 (defun dla/org-update-ids-to-headlines-in-file ()
1886   "Add or replace ID properties to all headlines in the current file 
1887 (or narrowed region)."
1888   (interactive)
1889
1890   (org-map-entries '(lambda () (org-id-get-create t))))
1891 ; if we wanted to do this to every buffer, do the following:
1892 (add-hook 'org-mode-hook
1893           (lambda ()
1894             (add-hook 'before-save-hook 'my/org-add-ids-to-headlines-in-file nil 'local)))
1895 #+END_SRC
1896 ** Org ID locations
1897 #+BEGIN_SRC emacs-lisp
1898 (use-package find-lisp
1899   :demand t)
1900 (setq org-agenda-text-search-extra-files
1901       (append '(agenda-archives)
1902               (find-lisp-find-files "~/projects/org-notes" "\.org$")
1903               (find-lisp-find-files "~/projects/org-notes" "\.org_archive$")
1904               ))
1905 #+END_SRC
1906 ** Keywords (TODO)
1907 #+BEGIN_SRC emacs-lisp
1908 (setq org-todo-keywords
1909       (quote ((sequence "TODO(t)" "NEXT(n)" "|" "DONE(d)")
1910               (sequence "WAITING(w@/!)" "HOLD(h@/!)" "|" "CANCELLED(c@/!)" "PHONE" "MEETING"))))
1911
1912 (setq org-todo-keyword-faces
1913       (quote (("TODO" :foreground "red" :weight bold)
1914               ("NEXT" :foreground "blue" :weight bold)
1915               ("DONE" :foreground "forest green" :weight bold)
1916               ("WAITING" :foreground "orange" :weight bold)
1917               ("HOLD" :foreground "magenta" :weight bold)
1918               ("CANCELLED" :foreground "forest green" :weight bold)
1919               ("MEETING" :foreground "forest green" :weight bold)
1920               ("PHONE" :foreground "forest green" :weight bold))))
1921
1922 (setq org-todo-state-tags-triggers
1923       (quote (("CANCELLED" ("CANCELLED" . t))
1924               ("WAITING" ("WAITING" . t))
1925               ("HOLD" ("WAITING") ("HOLD" . t))
1926               (done ("WAITING") ("HOLD"))
1927               ("TODO" ("WAITING") ("CANCELLED") ("HOLD"))
1928               ("NEXT" ("WAITING") ("CANCELLED") ("HOLD"))
1929               ("DONE" ("WAITING") ("CANCELLED") ("HOLD")))))
1930
1931
1932
1933 ; (add-hook 'org-clock-out-hook 'bh/remove-empty-drawer-on-clock-out 'append)
1934 ; add ids on creation of nodes
1935 (add-hook 'org-capture-prepare-finalize-hook 'my/org-add-id)
1936
1937
1938 ; resolve clocks after 10 minutes of idle; use xprintidle
1939 ; (setq org-clock-idle-time 10)
1940 ; (setq org-clock-x11idle-program-name "xprintidle")
1941
1942 ; this is from http://doc.norang.ca/org-mode.html#Capture
1943 ; use C-M-r for org mode capture
1944 (global-set-key (kbd "C-M-r") 'org-capture)
1945
1946 ; Targets include this file and any file contributing to the agenda - up to 9 levels deep
1947 (setq org-refile-targets (quote ((nil :maxlevel . 9)
1948                                  (org-agenda-files :maxlevel . 9))))
1949
1950 ; Use full outline paths for refile targets - we file directly with IDO
1951 (setq org-refile-use-outline-path t)
1952
1953 ; Targets complete directly with IDO
1954 (setq org-outline-path-complete-in-steps nil)
1955
1956 ; Allow refile to create parent tasks with confirmation
1957 (setq org-refile-allow-creating-parent-nodes (quote confirm))
1958
1959 ; ; Use IDO for both buffer and file completion and ido-everywhere to t
1960 ; (setq org-completion-use-ido t)
1961 ; (setq ido-everywhere t)
1962 ; (setq ido-max-directory-size 100000)
1963 ; (ido-mode (quote both))
1964 ; ; Use the current window when visiting files and buffers with ido
1965 ; (setq ido-default-file-method 'selected-window)
1966 ; (setq ido-default-buffer-method 'selected-window)
1967 ; ; Use the current window for indirect buffer display
1968 ; (setq org-indirect-buffer-display 'current-window)
1969
1970
1971 ;;;; Refile settings
1972 ; Exclude DONE state tasks from refile targets
1973 (defun bh/verify-refile-target ()
1974   "Exclude todo keywords with a done state from refile targets"
1975   (not (member (nth 2 (org-heading-components)) org-done-keywords)))
1976
1977 (setq org-refile-target-verify-function 'bh/verify-refile-target)
1978
1979 ;; ensure that emacsclient will show just the note to be edited when invoked
1980 ;; from Mutt, and that it will shut down emacsclient once finished;
1981 ;; fallback to legacy behavior when not invoked via org-protocol.
1982 (require 'org-protocol)
1983 ; (add-hook 'org-capture-mode-hook 'delete-other-windows)
1984 (setq my-org-protocol-flag nil)
1985 (defadvice org-capture-finalize (after delete-frame-at-end activate)
1986   "Delete frame at remember finalization"
1987   (progn (if my-org-protocol-flag (delete-frame))
1988          (setq my-org-protocol-flag nil)))
1989 (defadvice org-capture-refile (around delete-frame-after-refile activate)
1990   "Delete frame at remember refile"
1991   (if my-org-protocol-flag
1992       (progn
1993         (setq my-org-protocol-flag nil)
1994         ad-do-it
1995         (delete-frame))
1996     ad-do-it)
1997   )
1998 (defadvice org-capture-kill (after delete-frame-at-end activate)
1999   "Delete frame at remember abort"
2000   (progn (if my-org-protocol-flag (delete-frame))
2001          (setq my-org-protocol-flag nil)))
2002 (defadvice org-protocol-capture (before set-org-protocol-flag activate)
2003   (setq my-org-protocol-flag t))
2004
2005 (defadvice org-insert-todo-heading (after dla/create-id activate)
2006   (unless (org-in-item-p)
2007     (org-id-get-create)
2008     )
2009   )
2010
2011 ;; org modules
2012 (add-to-list 'org-modules 'org-habit)
2013
2014 ; this comes from http://upsilon.cc/~zack/blog/posts/2010/02/integrating_Mutt_with_Org-mode/
2015 (defun open-mail-in-mutt (message)
2016   "Open a mail message in Mutt, using an external terminal.
2017
2018 Message can be specified either by a path pointing inside a
2019 Maildir, or by Message-ID."
2020   (interactive "MPath or Message-ID: ")
2021   (shell-command
2022    (format "faf xterm -e \"%s %s\""
2023        (substitute-in-file-name "$HOME/bin/mutt_open") message)))
2024
2025 ;; add support for "mutt:ID" links
2026 (org-add-link-type "mutt" 'open-mail-in-mutt)
2027
2028 (defun my-org-mode-setup ()
2029   ; (load-library "reftex")
2030   (and (buffer-file-name)
2031        (file-exists-p (buffer-file-name))
2032        (progn
2033          ; (reftex-parse-all)
2034          (reftex-set-cite-format
2035           '((?b . "[[bib:%l][%l-bib]]")
2036             (?n . "[[notes:%l][%l-notes]]")
2037             (?c . "\\cite{%l}")
2038             (?h . "*** %t\n:PROPERTIES:\n:Custom_ID: %l\n:END:\n[[papers:%l][%l xoj]] [[papers-pdf:%l][pdf]]")))
2039          ))
2040   (define-key org-mode-map (kbd "C-c )") 'reftex-citation)
2041   (define-key org-mode-map (kbd "C-c [") 'reftex-citation)
2042   (define-key org-mode-map (kbd "C-c (") 'org-mode-reftex-search)
2043   (define-key org-mode-map (kbd "C-c 0") 'reftex-view-crossref)
2044   )
2045 (add-hook 'org-mode-hook 'my-org-mode-setup)
2046
2047 (defun org-mode-reftex-search ()
2048   (interactive)
2049   (org-open-link-from-string (format "[[notes:%s]]" (first (reftex-citation t)))))
2050
2051 (defun open-research-paper (bibtexkey)
2052   "Open a paper by bibtex key"
2053   (interactive "bibtex key: ")
2054   (shell-command
2055    (format "%s %s"
2056        (substitute-in-file-name "$HOME/bin/bibtex_to_paper") bibtexkey)))
2057 (org-add-link-type "papers" 'open-research-paper)
2058 (defun open-research-paper-pdf (bibtexkey)
2059   "Open a paper pdf by bibtex key"
2060   (interactive "bibtex key: ")
2061   (shell-command
2062    (format "%s -p evince_annot %s"
2063        (substitute-in-file-name "$HOME/bin/bibtex_to_paper") bibtexkey)))
2064 (org-add-link-type "papers-pdf" 'open-research-paper-pdf)
2065
2066 (add-to-list 'org-link-abbrev-alist
2067              '("notes" .
2068                "~/projects/research/paper_notes.org::#%s"))
2069
2070 ; I pretty much always want hiearchical checkboxes
2071 (setq org-hierachical-checkbox-statistics nil)
2072
2073 ;; Add \begin{equation}\end{equation} templates to the org mode easy templates
2074 (add-to-list 'org-structure-template-alist
2075              '("E" "\\begin{equation}\n?\n\\end{equation}"))
2076
2077  ;; stolen from
2078 ;; http://www-public.it-sudparis.eu/~berger_o/weblog/2012/03/23/how-to-manage-and-export-bibliographic-notesrefs-in-org-mode/
2079 (defun my-rtcite-export-handler (path desc format)
2080   (message "my-rtcite-export-handler is called : path = %s, desc = %s, format = %s" path desc format)
2081   (let* ((search (when (string-match "::#?\\(.+\\)\\'" path)
2082                    (match-string 1 path)))
2083          (path (substring path 0 (match-beginning 0))))
2084     (cond ((eq format 'latex)
2085            (if (or (not desc) 
2086                    (equal 0 (search "rtcite:" desc)))
2087                (format "\\cite{%s}" search)
2088              (format "\\cite[%s]{%s}" desc search))))))
2089
2090 (org-add-link-type "rtcite" 
2091                    'org-bibtex-open
2092                    'my-rtcite-export-handler)
2093
2094
2095 #+END_SRC
2096 ** Org Mobile Configuration
2097 #+BEGIN_SRC emacs-lisp
2098   (setq-default org-mobile-directory "/linnode.donarmstrong.com:/sites/dav.donarmstrong.com/root/org/")
2099   (when (string= system-name "linnode")
2100     (setq-default org-mobile-directory "/sites/dav.donarmstrong.com/root/org/"))
2101   (setq-default org-directory "/home/don/org-mode/")
2102   (setq-default org-mobile-inbox-for-pull "/home/don/org-mode/from-mobile.org")
2103
2104 #+END_SRC
2105 ** Org iCal Support
2106 #+BEGIN_SRC emacs-lisp
2107   ;; org mode ical export
2108   (setq org-icalendar-timezone "America/Los_Angeles")
2109   (setq org-icalendar-use-scheduled '(todo-start event-if-todo))
2110   ;; we already add the id manually
2111   (setq org-icalendar-store-UID t)
2112
2113 #+END_SRC
2114 ** General Org Babel Configuration
2115 #+BEGIN_SRC emacs-lisp
2116 ;; org babel support
2117 (org-babel-do-load-languages
2118  'org-babel-load-languages
2119  '((emacs-lisp . t )
2120    (R . t)
2121    (latex . t)
2122    (ditaa . t)
2123    (dot . t)
2124    ))
2125 ;; set the right path to ditaa.jar
2126 (setq org-ditaa-jar-path "/usr/share/ditaa/ditaa.jar")
2127 ;; use graphviz-dot for dot things
2128 (add-to-list 'org-src-lang-modes '("dot" . graphviz-dot))
2129 ;; do not indent begin_src blocks
2130 (setq org-edit-src-content-indentation 0)
2131 ;; org-babel-by-backend
2132 (defmacro org-babel-by-backend (&rest body)
2133    `(case (if (boundp 'backend) 
2134               (org-export-backend-name backend)
2135             nil) ,@body))
2136
2137 (defun my/fix-inline-images ()
2138   (when org-inline-image-overlays
2139     (org-redisplay-inline-images)))
2140
2141 (add-hook 'org-babel-after-execute-hook
2142            'my/fix-inline-images)
2143
2144 #+END_SRC
2145 ** LaTeX configuration
2146 #+BEGIN_SRC emacs-lisp
2147 (use-package org-contrib
2148   :no-require t
2149   :after org
2150   :config
2151   (require 'ox-extra)
2152   (ox-extras-activate '(latex-header-blocks ignore-headlines))
2153   (require 'ox-latex)
2154 (add-to-list 'org-latex-classes
2155          '("memarticle"
2156        "\\documentclass[11pt,oneside,article]{memoir}\n"
2157        ("\\section{%s}" . "\\section*{%s}")
2158        ("\\subsection{%s}" . "\\subsection*{%s}")
2159        ("\\subsubsection{%s}" . "\\subsubsection*{%s}")
2160        ("\\paragraph{%s}" . "\\paragraph*{%s}")
2161        ("\\subparagraph{%s}" . "\\subparagraph*{%s}")))
2162
2163 (setq org-beamer-outline-frame-options "")
2164 (add-to-list 'org-latex-classes
2165          '("beamer"
2166        "\\documentclass[ignorenonframetext]{beamer}
2167 [NO-DEFAULT-PACKAGES]
2168 [PACKAGES]
2169 [EXTRA]"
2170        ("\\section{%s}" . "\\section*{%s}")
2171        ("\\subsection{%s}" . "\\subsection*{%s}")
2172        ("\\subsubsection{%s}" . "\\subsubsection*{%s}")
2173        ("\\paragraph{%s}" . "\\paragraph*{%s}")
2174        ("\\subparagraph{%s}" . "\\subparagraph*{%s}")))
2175
2176 (add-to-list 'org-latex-classes
2177          '("membook"
2178        "\\documentclass[11pt,oneside]{memoir}\n"
2179        ("\\chapter{%s}" . "\\chapter*{%s}")
2180        ("\\section{%s}" . "\\section*{%s}")
2181        ("\\subsection{%s}" . "\\subsection*{%s}")
2182        ("\\subsubsection{%s}" . "\\subsubsection*{%s}")))
2183
2184 (add-to-list 'org-latex-classes
2185          '("letter"
2186        "\\documentclass[11pt]{letter}
2187 [NO-DEFAULT-PACKAGES]
2188 [PACKAGES]
2189 [EXTRA]"
2190    ("\\section{%s}" . "\\section*{%s}")
2191        ("\\subsection{%s}" . "\\subsection*{%s}")
2192        ("\\subsubsection{%s}" . "\\subsubsection*{%s}")
2193        ("\\paragraph{%s}" . "\\paragraph*{%s}")
2194        ("\\subparagraph{%s}" . "\\subparagraph*{%s}")))
2195
2196 (add-to-list 'org-latex-classes
2197          '("dlacv"
2198        "\\documentclass{dlacv}
2199 [NO-DEFAULT-PACKAGES]
2200 [NO-PACKAGES]
2201 [NO-EXTRA]"
2202        ("\\section{%s}" . "\\section*{%s}")
2203        ("\\subsection{%s}" . "\\subsection*{%s}")
2204        ("\\subsubsection{%s}" . "\\subsubsection*{%s}")
2205        ("\\paragraph{%s}" . "\\paragraph*{%s}")
2206        ("\\subparagraph{%s}" . "\\subparagraph*{%s}")))
2207
2208
2209 (add-to-list 'org-latex-classes
2210          '("dlaresume"
2211        "\\documentclass{dlaresume}
2212 [NO-DEFAULT-PACKAGES]
2213 [NO-PACKAGES]
2214 [NO-EXTRA]"
2215        ("\\section{%s}" . "\\section*{%s}")
2216        ("\\subsection{%s}" . "\\subsection*{%s}")
2217        ("\\subsubsection{%s}" . "\\subsubsection*{%s}")
2218        ("\\paragraph{%s}" . "\\paragraph*{%s}")
2219        ("\\subparagraph{%s}" . "\\subparagraph*{%s}")))
2220
2221
2222 ;; Originally taken from Bruno Tavernier: http://thread.gmane.org/gmane.emacs.orgmode/31150/focus=31432
2223 ;; but adapted to use latexmk 4.22 or higher.  
2224 (setq org-latex-pdf-process '("latexmk -f -pdflatex=xelatex -bibtex -use-make -pdf %f"))
2225
2226 ;; Default packages included in /every/ tex file, latex, pdflatex or xelatex
2227 (setq org-latex-default-packages-alist
2228   '(("" "amsmath" t)
2229     ("" "unicode-math" t)
2230     ))
2231 (setq org-latex-packages-alist
2232   '(("" "graphicx" t)
2233     ("" "fontspec" t)
2234     ("" "xunicode" t)
2235     ("" "hyperref" t)
2236     ("" "url" t)
2237     ("" "rotating" t)
2238     ("" "longtable" nil)
2239     ("" "float" )))
2240
2241 ;; make equations larger
2242 (setq org-format-latex-options (plist-put org-format-latex-options :scale 2.0))
2243
2244 (defun org-create-formula--latex-header ()
2245   "Return LaTeX header appropriate for previewing a LaTeX snippet."
2246   (let ((info (org-combine-plists (org-export--get-global-options
2247            (org-export-get-backend 'latex))
2248           (org-export--get-inbuffer-options
2249            (org-export-get-backend 'latex)))))
2250     (org-latex-guess-babel-language
2251      (org-latex-guess-inputenc
2252   (org-splice-latex-header
2253    org-format-latex-header
2254    org-latex-default-packages-alist
2255    nil t
2256    (plist-get info :latex-header)))
2257      info)))
2258
2259
2260 ; support ignoring headers in org mode export to latex
2261 ; from http://article.gmane.org/gmane.emacs.orgmode/67692
2262 (defadvice org-latex-headline (around my-latex-skip-headlines
2263                   (headline contents info) activate)
2264   (if (member "ignoreheading" (org-element-property :tags headline))
2265   (setq ad-return-value contents)
2266     ad-do-it))
2267
2268 ;; keep latex logfiles
2269
2270 (setq org-latex-remove-logfiles nil)
2271 )
2272
2273 ;; Resume clocking task when emacs is restarted
2274 (org-clock-persistence-insinuate)
2275 ;;
2276 ;; Show lot of clocking history so it's easy to pick items off the C-F11 list
2277 (setq org-clock-history-length 23)
2278 ;; Resume clocking task on clock-in if the clock is open
2279 (setq org-clock-in-resume t)
2280 ;; Change tasks to NEXT when clocking in; this avoids clocking in when
2281 ;; there are things like PHONE calls
2282 (setq org-clock-in-switch-to-state 'bh/clock-in-to-next)
2283 ;; Separate drawers for clocking and logs
2284 (setq org-drawers (quote ("PROPERTIES" "LOGBOOK")))
2285 ;; Save clock data and state changes and notes in the LOGBOOK drawer
2286 (setq org-clock-into-drawer t)
2287 (setq org-log-into-drawer t)
2288 ;; Sometimes I change tasks I'm clocking quickly - this removes clocked tasks with 0:00 duration
2289 (setq org-clock-out-remove-zero-time-clocks t)
2290 ;; Clock out when moving task to a done state
2291 (setq org-clock-out-when-done t)
2292 ;; Save the running clock and all clock history when exiting Emacs, load it on startup
2293 (setq org-clock-persist t)
2294 ;; Do not prompt to resume an active clock
2295 (setq org-clock-persist-query-resume nil)
2296 ;; Enable auto clock resolution for finding open clocks
2297 (setq org-clock-auto-clock-resolution (quote when-no-clock-is-running))
2298 ;; Include current clocking task in clock reports
2299 (setq org-clock-report-include-clocking-task t)
2300
2301 ;; the cache seems to be broken
2302 (setq org-element-use-cache nil)
2303
2304 (defvar bh/keep-clock-running nil)
2305
2306 (defun bh/is-task-p ()
2307   "Any task with a todo keyword and no subtask"
2308   (save-restriction
2309     (widen)
2310     (let ((has-subtask)
2311           (subtree-end (save-excursion (org-end-of-subtree t)))
2312           (is-a-task (member (nth 2 (org-heading-components)) org-todo-keywords-1)))
2313       (save-excursion
2314         (forward-line 1)
2315         (while (and (not has-subtask)
2316                     (< (point) subtree-end)
2317                     (re-search-forward "^\*+ " subtree-end t))
2318           (when (member (org-get-todo-state) org-todo-keywords-1)
2319             (setq has-subtask t))))
2320       (and is-a-task (not has-subtask)))))
2321 (defun bh/is-project-p ()
2322   "Any task with a todo keyword subtask"
2323   (save-restriction
2324     (widen)
2325     (let ((has-subtask)
2326           (subtree-end (save-excursion (org-end-of-subtree t)))
2327           (is-a-task (member (nth 2 (org-heading-components)) org-todo-keywords-1)))
2328       (save-excursion
2329         (forward-line 1)
2330         (while (and (not has-subtask)
2331                     (< (point) subtree-end)
2332                     (re-search-forward "^\*+ " subtree-end t))
2333           (when (member (org-get-todo-state) org-todo-keywords-1)
2334             (setq has-subtask t))))
2335       (and is-a-task has-subtask))))
2336
2337 (defun bh/is-subproject-p ()
2338   "Any task which is a subtask of another project"
2339   (let ((is-subproject)
2340         (is-a-task (member (nth 2 (org-heading-components)) org-todo-keywords-1)))
2341     (save-excursion
2342       (while (and (not is-subproject) (org-up-heading-safe))
2343         (when (member (nth 2 (org-heading-components)) org-todo-keywords-1)
2344           (setq is-subproject t))))
2345     (and is-a-task is-subproject)))
2346
2347
2348 (defun bh/clock-in-to-next (kw)
2349   "Switch a task from TODO to NEXT when clocking in.
2350 Skips capture tasks, projects, and subprojects.
2351 Switch projects and subprojects from NEXT back to TODO"
2352   (when (not (and (boundp 'org-capture-mode) org-capture-mode))
2353     (cond
2354      ((and (member (org-get-todo-state) (list "TODO"))
2355        (bh/is-task-p))
2356   "NEXT")
2357      ((and (member (org-get-todo-state) (list "NEXT"))
2358        (bh/is-project-p))
2359   "TODO"))))
2360
2361 (defun bh/punch-in (arg)
2362   "Start continuous clocking and set the default task to the
2363 selected task.  If no task is selected set the Organization task
2364 as the default task."
2365   (interactive "p")
2366   (setq bh/keep-clock-running t)
2367   (if (equal major-mode 'org-agenda-mode)
2368   ;;
2369   ;; We're in the agenda
2370   ;;
2371   (let* ((marker (org-get-at-bol 'org-hd-marker))
2372          (tags (org-with-point-at marker (org-get-tags))))
2373     (if (and (eq arg 4) tags)
2374         (org-agenda-clock-in '(16))
2375       (bh/clock-in-organization-task-as-default)))
2376     ;;
2377     ;; We are not in the agenda
2378     ;;
2379     (save-restriction
2380   (widen)
2381   ; Find the tags on the current task
2382   (if (and (equal major-mode 'org-mode) (not (org-before-first-heading-p)) (eq arg 4))
2383       (org-clock-in '(16))
2384     (bh/clock-in-organization-task-as-default)))))
2385
2386 (defun bh/punch-out ()
2387   (interactive)
2388   (setq bh/keep-clock-running nil)
2389   (when (org-clock-is-active)
2390     (org-clock-out))
2391   (org-agenda-remove-restriction-lock))
2392
2393 (defun bh/clock-in-default-task ()
2394   (save-excursion
2395     (org-with-point-at org-clock-default-task
2396   (org-clock-in))))
2397
2398 (defun bh/clock-in-parent-task ()
2399   "Move point to the parent (project) task if any and clock in"
2400   (let ((parent-task))
2401     (save-excursion
2402   (save-restriction
2403     (widen)
2404     (while (and (not parent-task) (org-up-heading-safe))
2405       (when (member (nth 2 (org-heading-components)) org-todo-keywords-1)
2406         (setq parent-task (point))))
2407     (if parent-task
2408         (org-with-point-at parent-task
2409       (org-clock-in))
2410       (when bh/keep-clock-running
2411         (bh/clock-in-default-task)))))))
2412
2413 (defvar bh/organization-task-id "e22cb8bf-07c7-408b-8f60-ff3aadac95e4")
2414
2415 (defun bh/clock-in-organization-task-as-default ()
2416   (interactive)
2417   (org-with-point-at (org-id-find bh/organization-task-id 'marker)
2418     (org-clock-in '(16))))
2419
2420 (defun bh/clock-out-maybe ()
2421   (when (and bh/keep-clock-running
2422          (not org-clock-clocking-in)
2423          (marker-buffer org-clock-default-task)
2424          (not org-clock-resolving-clocks-due-to-idleness))
2425     (bh/clock-in-parent-task)))
2426
2427 ; (add-hook 'org-clock-out-hook 'bh/clock-out-maybe 'append)
2428
2429 (require 'org-id)
2430 (defun bh/clock-in-task-by-id (id)
2431   "Clock in a task by id"
2432   (org-with-point-at (org-id-find id 'marker)
2433     (org-clock-in nil)))
2434
2435 (defun bh/clock-in-last-task (arg)
2436   "Clock in the interrupted task if there is one
2437 Skip the default task and get the next one.
2438 A prefix arg forces clock in of the default task."
2439   (interactive "p")
2440   (let ((clock-in-to-task
2441      (cond
2442       ((eq arg 4) org-clock-default-task)
2443       ((and (org-clock-is-active)
2444         (equal org-clock-default-task (cadr org-clock-history)))
2445        (caddr org-clock-history))
2446       ((org-clock-is-active) (cadr org-clock-history))
2447       ((equal org-clock-default-task (car org-clock-history)) (cadr org-clock-history))
2448       (t (car org-clock-history)))))
2449     (widen)
2450     (org-with-point-at clock-in-to-task
2451   (org-clock-in nil))))
2452
2453
2454 (defun org-export-to-ods ()
2455   (interactive)
2456   (let ((csv-file "data.csv"))
2457     (org-table-export csv-file "orgtbl-to-csv")
2458     (org-odt-convert csv-file "ods" 'open)))
2459
2460 ; allow for zero-width-space to be a break in regexp too
2461 ; (setcar org-emphasis-regexp-components "​ [:space:] \t('\"{")
2462 ; (setcar (nthcdr 1 org-emphasis-regexp-components) "​ [:space:]- \t.,:!?;'\")}\\")
2463 ; (org-set-emph-re 'org-emphasis-regexp-components org-emphasis-regexp-components)
2464
2465 ;; support inserting screen shots
2466 (defun my/org-insert-screenshot ()
2467   "Take a screenshot into a time stamped unique-named file in the
2468 same directory as the org-buffer and insert a link to this file."
2469   (interactive)
2470   (defvar my/org-insert-screenshot/filename)
2471   (setq my/org-insert-screenshot/filename
2472     (read-file-name
2473      "Screenshot to insert: "
2474      nil
2475      (concat (buffer-file-name) "_" (format-time-string "%Y%m%d_%H%M%S") ".png")
2476      )
2477     )
2478   (call-process "import" nil nil nil my/org-insert-screenshot/filename)
2479   (insert (concat "[[" my/org-insert-screenshot/filename "]]"))
2480   (org-display-inline-images))
2481
2482 (defun my/fix-inline-images ()
2483   (when org-inline-image-overlays
2484     (org-redisplay-inline-images)))
2485
2486 (add-hook 'org-babel-after-execute-hook 'my/fix-inline-images)
2487
2488 ;; use xelatex to preview with imagemagick
2489 (add-to-list 'org-preview-latex-process-alist
2490          '(xelateximagemagick
2491       :programs ("xelatex" "convert")
2492       :description "pdf > png"
2493       :message "you need to install xelatex and imagemagick"
2494       :use-xcolor t
2495       :image-input-type "pdf"
2496       :image-output-type "png"
2497       :image-size-adjust (1.0 . 1.0)
2498       :latex-compiler ("xelatex -interaction nonstopmode -output-directory %o %f")
2499       :image-converter ("convert -density %D -trim -antialias %f -quality 100 %O"))
2500          )
2501 ;; use xelatex by default
2502 (setq org-preview-latex-default-process 'xelateximagemagick)
2503
2504 ; from http://orgmode.org/Changes.html
2505 (defun my/org-repair-property-drawers ()
2506   "Fix properties drawers in current buffer.
2507  Ignore non Org buffers."
2508   (interactive)
2509   (when (eq major-mode 'org-mode)
2510     (org-with-wide-buffer
2511      (goto-char (point-min))
2512      (let ((case-fold-search t)
2513        (inline-re (and (featurep 'org-inlinetask)
2514                (concat (org-inlinetask-outline-regexp)
2515                    "END[ \t]*$"))))
2516    (org-map-entries
2517     (lambda ()
2518       (unless (and inline-re (org-looking-at-p inline-re))
2519         (save-excursion
2520       (let ((end (save-excursion (outline-next-heading) (point))))
2521         (forward-line)
2522         (when (org-looking-at-p org-planning-line-re) (forward-line))
2523         (when (and (< (point) end)
2524                (not (org-looking-at-p org-property-drawer-re))
2525                (save-excursion
2526                  (and (re-search-forward org-property-drawer-re end t)
2527                   (eq (org-element-type
2528                    (save-match-data (org-element-at-point)))
2529                   'drawer))))
2530           (insert (delete-and-extract-region
2531                (match-beginning 0)
2532                (min (1+ (match-end 0)) end)))
2533           (unless (bolp) (insert "\n"))))))))))))
2534
2535 #+END_SRC
2536 ** Org-Gcal
2537 #+BEGIN_SRC emacs-lisp
2538 (use-package calfw
2539   :ensure f
2540   )
2541 (use-package calfw-org
2542   :ensure f
2543   )
2544 (use-package org-gcal
2545   :if (file-readable-p "~/.hide/org_gcal.el")
2546   :ensure f
2547   :config '((if (file-readable-p "~/.hide/org_gcal.el")
2548                 (load-file "~/.hide/org_gcal.el"))
2549             )
2550   )
2551 #+END_SRC
2552 ** appt integration
2553 #+BEGIN_SRC emacs-lisp
2554 (use-package appt
2555   :straight nil
2556   :config
2557   ;; Show notification 10 minutes before event
2558   (setq appt-message-warning-time 10)
2559   ;; Disable multiple reminders
2560   (setq appt-display-interval appt-message-warning-time)
2561   (setq appt-display-mode-line nil)
2562
2563   ;; add automatic reminders for appointments
2564   (defun my/org-agenda-to-appt ()
2565     (interactive)
2566     (setq appt-time-msg-list nil)
2567     (org-agenda-to-appt))
2568   ;; add reminders when starting emacs
2569   (my/org-agenda-to-appt)
2570   ;; when rebuilding the agenda
2571   (defadvice  org-agenda-redo (after org-agenda-redo-add-appts)
2572     "Pressing `r' on the agenda will also add appointments."
2573     (my/org-agenda-to-appt)
2574     )
2575   ;; when saving all org buffers
2576   (defadvice org-save-all-org-buffers (after org-save-all-org-buffers-add-appts)
2577     "Re-add appts after saving all org buffers"
2578     (my/org-agenda-to-appt))
2579   ;; Display appointments as a window manager notification
2580   (setq appt-disp-window-function 'my/appt-display)
2581   (setq appt-delete-window-function (lambda () t))
2582
2583   (setq my/appt-notification-app (concat (getenv "HOME") "/bin/appt_notification"))
2584
2585   (defun my/appt-display (min-to-app new-time msg)
2586     (if (atom min-to-app)
2587     (start-process "my/appt-notification-app" nil my/appt-notification-app min-to-app msg)
2588   (dolist (i (number-sequence 0 (1- (length min-to-app))))
2589     (start-process "my/appt-notification-app" nil my/appt-notification-app
2590              (nth i min-to-app) (nth i msg))))
2591     )
2592   )
2593
2594
2595 #+END_SRC
2596 ** End use-package
2597 #+BEGIN_SRC emacs-lisp
2598   )
2599 #+END_SRC
2600 * Keybindings
2601 ** Home/End Begining/End of line
2602 #+BEGIN_SRC emacs-lisp
2603   (global-set-key [home] 'move-beginning-of-line)
2604   (global-set-key [end] 'move-end-of-line)
2605 #+END_SRC
2606 ** Goto line
2607 #+BEGIN_SRC emacs-lisp
2608   ; (global-unset-key "\M-g")
2609   ; (global-set-key (kbd "M-g l") 'goto-line)
2610 #+END_SRC
2611 * Debian
2612 ** debian-changelog
2613 #+BEGIN_SRC emacs-lisp
2614 (use-package debian-changelog-mode
2615   :mode "debian/changelog"
2616   :ensure debian-el
2617   :config
2618   (setq debian-changelog-mailing-address "don@debian.org")
2619   (setq debian-changelog-full-name "Don Armstrong"))
2620 #+END_SRC
2621 * Misc (uncharacterized)
2622 #+BEGIN_SRC emacs-lisp
2623   (setq calendar-latitude 38.6)
2624   (setq calendar-longitude -121.5)
2625   (setq case-fold-search t)
2626   (setq confirm-kill-emacs (quote y-or-n-p))
2627
2628 #+END_SRC
2629 ** Turn on fontlock
2630 #+BEGIN_SRC emacs-lisp
2631   (global-font-lock-mode 1)
2632 #+END_SRC
2633 ** PS Printing
2634 #+BEGIN_SRC emacs-lisp
2635   (setq ps-footer-font-size (quote (8 . 10)))
2636   (setq ps-header-font-size (quote (8 . 10)))
2637   (setq ps-header-title-font-size (quote (10 . 10)))
2638   (setq ps-line-number-color "blue")
2639   (setq ps-print-footer t)
2640   (setq ps-print-footer-frame nil)
2641   (setq ps-print-only-one-header t)
2642 #+END_SRC
2643 ** Only single spacing on sentences
2644 #+BEGIN_SRC emacs-lisp
2645   (setq sentence-end "[.?!][]\"')]*\\($\\|   \\| \\)[    
2646   ]*")
2647   (setq sentence-end-double-space nil)
2648   ; enable matching parenthesis
2649 #+END_SRC
2650 ** Display paren mode
2651 #+BEGIN_SRC emacs-lisp
2652   (show-paren-mode 1)
2653   (setq show-paren-delay 0.2)
2654
2655 #+END_SRC
2656 ** My Username
2657 #+BEGIN_SRC emacs-lisp
2658   (setq user-mail-address "don@donarmstrong.com")
2659
2660 #+END_SRC
2661 ** Use primary selection on unix machines
2662 #+BEGIN_SRC emacs-lisp
2663 ;; switch back to the old primary selection method
2664 (if (or (string-equal system-type "darwin")
2665         (string-equal system-type "windows")
2666         )
2667     (progn
2668       (setq select-enable-clipboard t)
2669       (setq select-enable-primary nil)
2670       )
2671   (progn
2672     (setq select-enable-clipboard nil)
2673     (setq select-enable-primary t)
2674     ))
2675 ; (setq mouse-drag-copy-region t)
2676
2677 (setq-default c-indent-level 4)
2678 (setq-default c-brace-imaginary-offset 0)
2679 (setq-default c-brace-offset -4)
2680 (setq-default c-argdecl-indent 4)
2681 (setq-default c-label-offset -4)
2682 (setq-default c-continued-statement-offset 4)
2683 ; tabs are annoying
2684 (setq-default indent-tabs-mode nil)
2685 (setq-default tab-width 4)
2686
2687 (defun insert-date ()
2688   "Insert date at point."
2689   (interactive)
2690   (insert (format-time-string "%A, %B %e, %Y %k:%M:%S %Z")))
2691 (global-set-key "\C-[d" 'insert-date)
2692
2693 (defun unfill-paragraph (arg)
2694   "Pull this whole paragraph up onto one line."
2695   (interactive "*p")
2696   (let ((fill-column 10000))
2697     (fill-paragraph arg))
2698   )
2699
2700 (column-number-mode t)
2701
2702 #+END_SRC
2703 ** Desktop-save-mode
2704 If the envvar EMACS_SERVER_NAME is set, consider this a separate
2705 emacs, and use a different desktop file to restore history
2706 #+BEGIN_SRC emacs-lisp
2707 (use-package desktop
2708   :demand
2709   :config
2710   (setq desktop-base-file-name
2711         (convert-standard-filename
2712          (concat ".emacs"
2713                  (or (getenv "EMACS_SERVER_NAME")
2714                      "")
2715                  ".desktop")
2716          ))
2717   (setq desktop-base-lock-name
2718         (convert-standard-filename
2719          (concat desktop-base-file-name
2720                  ".lock")))
2721   (setq desktop-auto-save-timeout 60)
2722   (setq desktop-restore-eager 5)
2723   (setq desktop-lazy-verbose nil)
2724   (desktop-save-mode 1)
2725   ; (desktop-read)
2726 )
2727 #+END_SRC
2728 ** Misc (Uncharacterized)
2729 #+BEGIN_SRC emacs-lisp
2730
2731 (put 'upcase-region 'disabled nil)
2732 (put 'downcase-region 'disabled nil)
2733 (put 'narrow-to-region 'disabled nil)
2734
2735 ; fix up tmux xterm keys
2736 ; stolen from http://unix.stackexchange.com/questions/24414/shift-arrow-not-working-in-emacs-within-tmux
2737 (defun fix-up-tmux-keys ()
2738     "Fix up tmux xterm keys"
2739     (if (getenv "TMUX")
2740         (progn
2741           (let ((x 2) (tkey ""))
2742             (while (<= x 8)
2743               ;; shift
2744               (if (= x 2)
2745                   (setq tkey "S-"))
2746               ;; alt
2747               (if (= x 3)
2748                   (setq tkey "M-"))
2749               ;; alt + shift
2750               (if (= x 4)
2751                   (setq tkey "M-S-"))
2752               ;; ctrl
2753               (if (= x 5)
2754                   (setq tkey "C-"))
2755               ;; ctrl + shift
2756               (if (= x 6)
2757                   (setq tkey "C-S-"))
2758               ;; ctrl + alt
2759               (if (= x 7)
2760                   (setq tkey "C-M-"))
2761               ;; ctrl + alt + shift
2762               (if (= x 8)
2763                   (setq tkey "C-M-S-"))
2764
2765               ;; arrows
2766               (define-key key-translation-map (kbd (format "M-[ 1 ; %d A" x)) (kbd (format "%s<up>" tkey)))
2767               (define-key key-translation-map (kbd (format "M-[ 1 ; %d B" x)) (kbd (format "%s<down>" tkey)))
2768               (define-key key-translation-map (kbd (format "M-[ 1 ; %d C" x)) (kbd (format "%s<right>" tkey)))
2769               (define-key key-translation-map (kbd (format "M-[ 1 ; %d D" x)) (kbd (format "%s<left>" tkey)))
2770               ;; home
2771               (define-key key-translation-map (kbd (format "M-[ 1 ; %d H" x)) (kbd (format "%s<home>" tkey)))
2772               ;; end
2773               (define-key key-translation-map (kbd (format "M-[ 1 ; %d F" x)) (kbd (format "%s<end>" tkey)))
2774               ;; page up
2775               (define-key key-translation-map (kbd (format "M-[ 5 ; %d ~" x)) (kbd (format "%s<prior>" tkey)))
2776               ;; page down
2777               (define-key key-translation-map (kbd (format "M-[ 6 ; %d ~" x)) (kbd (format "%s<next>" tkey)))
2778               ;; insert
2779               (define-key key-translation-map (kbd (format "M-[ 2 ; %d ~" x)) (kbd (format "%s<delete>" tkey)))
2780               ;; delete
2781               (define-key key-translation-map (kbd (format "M-[ 3 ; %d ~" x)) (kbd (format "%s<delete>" tkey)))
2782               ;; f1
2783               (define-key key-translation-map (kbd (format "M-[ 1 ; %d P" x)) (kbd (format "%s<f1>" tkey)))
2784               ;; f2
2785               (define-key key-translation-map (kbd (format "M-[ 1 ; %d Q" x)) (kbd (format "%s<f2>" tkey)))
2786               ;; f3
2787               (define-key key-translation-map (kbd (format "M-[ 1 ; %d R" x)) (kbd (format "%s<f3>" tkey)))
2788               ;; f4
2789               (define-key key-translation-map (kbd (format "M-[ 1 ; %d S" x)) (kbd (format "%s<f4>" tkey)))
2790               ;; f5
2791               (define-key key-translation-map (kbd (format "M-[ 15 ; %d ~" x)) (kbd (format "%s<f5>" tkey)))
2792               ;; f6
2793               (define-key key-translation-map (kbd (format "M-[ 17 ; %d ~" x)) (kbd (format "%s<f6>" tkey)))
2794               ;; f7
2795               (define-key key-translation-map (kbd (format "M-[ 18 ; %d ~" x)) (kbd (format "%s<f7>" tkey)))
2796               ;; f8
2797               (define-key key-translation-map (kbd (format "M-[ 19 ; %d ~" x)) (kbd (format "%s<f8>" tkey)))
2798               ;; f9
2799               (define-key key-translation-map (kbd (format "M-[ 20 ; %d ~" x)) (kbd (format "%s<f9>" tkey)))
2800               ;; f10
2801               (define-key key-translation-map (kbd (format "M-[ 21 ; %d ~" x)) (kbd (format "%s<f10>" tkey)))
2802               ;; f11
2803               (define-key key-translation-map (kbd (format "M-[ 23 ; %d ~" x)) (kbd (format "%s<f11>" tkey)))
2804               ;; f12
2805               (define-key key-translation-map (kbd (format "M-[ 24 ; %d ~" x)) (kbd (format "%s<f12>" tkey)))
2806               ;; f13
2807               (define-key key-translation-map (kbd (format "M-[ 25 ; %d ~" x)) (kbd (format "%s<f13>" tkey)))
2808               ;; f14
2809               (define-key key-translation-map (kbd (format "M-[ 26 ; %d ~" x)) (kbd (format "%s<f14>" tkey)))
2810               ;; f15
2811               (define-key key-translation-map (kbd (format "M-[ 28 ; %d ~" x)) (kbd (format "%s<f15>" tkey)))
2812               ;; f16
2813               (define-key key-translation-map (kbd (format "M-[ 29 ; %d ~" x)) (kbd (format "%s<f16>" tkey)))
2814               ;; f17
2815               (define-key key-translation-map (kbd (format "M-[ 31 ; %d ~" x)) (kbd (format "%s<f17>" tkey)))
2816               ;; f18
2817               (define-key key-translation-map (kbd (format "M-[ 32 ; %d ~" x)) (kbd (format "%s<f18>" tkey)))
2818               ;; f19
2819               (define-key key-translation-map (kbd (format "M-[ 33 ; %d ~" x)) (kbd (format "%s<f19>" tkey)))
2820               ;; f20
2821               (define-key key-translation-map (kbd (format "M-[ 34 ; %d ~" x)) (kbd (format "%s<f20>" tkey)))
2822
2823               (setq x (+ x 1))
2824               ))
2825           )
2826       )
2827     )
2828 ; (add-hook 'tty-setup-hook 'fix-up-tmux-keys)
2829
2830 (defadvice ask-user-about-supersession-threat (around ask-user-about-supersession-threat-if-necessary)
2831   "Call ask-user-about-supersession-threat only if the buffer is actually obsolete."
2832   (if (or (buffer-modified-p)
2833           (verify-visited-file-modtime)
2834           (< (* 8 1024 1024) (buffer-size))
2835           (/= 0 (call-process-region 1 (+ 1 (buffer-size)) "diff" nil nil nil "-q" (buffer-file-name) "-")))
2836       ad-do-it
2837     (clear-visited-file-modtime)
2838     (not-modified)))
2839 (ad-activate 'ask-user-about-supersession-threat)
2840 #+END_SRC
2841
2842 * Start Server
2843 #+BEGIN_SRC emacs-lisp
2844   (use-package server
2845     :config
2846     (setq server-name
2847           (or (getenv "EMACS_SERVER_NAME")
2848               "server"))
2849     (unless (server-running-p)
2850       ; (global-set-key "\C-xp" 'server-edit)
2851       (server-start)))
2852 #+END_SRC
2853
2854 * END
2855 #+BEGIN_SRC emacs-lisp
2856 (provide 'don-configuration)
2857 #+END_SRC