Table of Contents
- 1. Overview
- 2. Information
- 3. Constants
- 4. Init
- 5. Start
- 6. Package Manager
- 7. Environment
- 8. Key Bindings
- 9. Org Mode
- 9.1. Configuration
- 9.2. Outline
- 9.3. Agenda
- 9.4. Capture
- 9.5.
Alerts - 9.6. Appear
- 9.7. LaTeX
- 9.8.
ACUTeX - 9.9.
Remember - 9.10.
TOC - 9.11.
PDF - 9.12. Modules
- 9.13. Functions
- 9.13.1. org-get-property-list
- 9.13.2. org-get-element-tree
- 9.13.3. org-get-file-data
- 9.13.4. org-get-buffer-data
- 9.13.5. org-get-buffer-tags-statistics
- 9.13.6. org-safe-meta
- 9.13.7. org-sort-multi
- 9.13.8. org-sort-current
- 9.13.9. org-fill-element–adapt-indentation
- 9.13.10. org-copy-to-clipboard
- 9.13.11. org-fix-custom-ids
- 9.13.12. org-update-last-modified-property
- 9.13.13. org-export-to-json
- 9.13.14. org-toggle-headline-checkbox
- 9.13.15. org-table-remove-commas
- 9.13.16. org-days-between-dates
- 9.13.17. org-copy-tangled-sections
- 9.13.18. org-screenshot
- 9.13.19. org-convert-headings-from-odd-indented-to-oddeven-unindented
- 9.13.20. org-convert-headings-from-oddeven-unindented-to-odd-indented
- 9.13.21. org-insert-header
- 9.13.22. org-insert-table
- 9.13.23. org-insert-toc-header
- 9.14. Hook
- 9.15. Babel
- 9.15.1. Configuration
- 9.15.2. Structure Templates
- 9.15.3. Edit Source
- 9.15.4. Tangle Case-Sensitive
- 9.15.5. Tangle Update Timestamps
- 9.15.6. Tangle Delete Trailing Whitespace
- 9.15.7.
Tangle Makefile Tabs - 9.15.8. Tangle Generate PDF from TEX
- 9.15.9. Racket
- 9.15.10. Java
- 9.15.11. Kotlin
- 9.15.12.
Python (iPython Version) - 9.15.13. Python
- 9.15.14. Rust
- 9.15.15. V
- 9.15.16. Basic (Commander X16)
- 9.15.17. Assembly Language (Commander X16)
- 9.15.18. PlantUML
- 9.15.19. Load Languages
- 9.16. Babel Functions
- 9.16.1.
org-babel-send-region-to-process - 9.16.2. org-babel-tangle-block
- 9.16.3. org-babel-tangle-file-async
- 9.16.4. org-generate-custom-id-from-title
- 9.16.5. org-fix-literate-programming-heading
- 9.16.6. org-fix-literate-programming-heading-region
- 9.16.7. org-toggle-literate-programming-code-block
- 9.16.8. org-insert-literate-programming-statics
- 9.16.9. org-insert-literate-programming-block
- 9.16.10. org-insert-literate-programming-init-emacs-block
- 9.16.11. org-insert-literate-programming-code-block
- 9.16.12. org-insert-literate-programming-project-euler-problem-block
- 9.16.1.
- 9.17. Visibility
- 9.18.
Contacts - 9.19. Present
- 9.20.
Reveal - 9.21.
Jira - 9.22. Bookmarks
- 9.23. Finances
- 9.24. Magic the Gathering
- 9.25. MechWarrior Online
- 9.26. Dungeons and Dragons Online
- 10. Org Website
- 10.1. Configuration
- 10.2. Functions
- 10.2.1.
Get Content Property List - 10.2.2. Get Property List
- 10.2.3. Get Property Element
- 10.2.4.
Get Data - 10.2.5. Get URL
- 10.2.6. Blog URL
- 10.2.7. Is Blog Post
- 10.2.8. Get Level
- 10.2.9. Format Headline
- 10.2.10. Get Gopher Selector Hostname Port
- 10.2.11. Convert URL to Gopher Selector Hostname Port
- 10.2.12. Gopher Justify Lines
- 10.2.1.
- 10.3. Publish HTML
- 10.4. Publish RSS
- 10.5. Publish Gopher
- 10.6. Helper Functions
- 10.7. Generate Website Emacs Initialization File
- 10.8. Tangle and Publish Script
- 10.9. Remote Synchronization
- 10.10. Deployment
- 11. Functions
- 11.1. Initialization Functions
- 11.2. General Functions
- 11.2.1. list-to-string
- 11.2.2. string-to-list
- 11.2.3. join-strings
- 11.2.4. file-to-string
- 11.2.5. safe-substring
- 11.2.6.
chomp - 11.2.7.
trim - 11.2.8. set-nth
- 11.2.9. delete-nth
- 11.2.10. for-each
- 11.2.11. is-single
- 11.2.12. append-element
- 11.2.13. map-integer
- 11.2.14. filter
- 11.2.15. most
- 11.2.16.
queue - 11.2.17. quicksort
- 11.2.18. hash-table-dump
- 11.2.19. password
- 11.2.20. password-phrase
- 11.3. Emacs Functions
- 11.3.1. inside-string
- 11.3.2. inside-comment
- 11.3.3. try-finally
- 11.3.4. save-buffer-always
- 11.3.5. save-buffer-always-maybe
- 11.3.6. describe-function-or-variable-at-point
- 11.3.7. mode-line-add
- 11.3.8. insert-line-below
- 11.3.9. insert-line-above
- 11.3.10. move-line-down
- 11.3.11. move-line-up
- 11.3.12.
kill-word-enhanced - 11.3.13. kill-region-or-word
- 11.3.14. kill-duplicate-lines
- 11.3.15. indent-or-expand
- 11.3.16. swap-windows
- 11.3.17. toggle-window-split
- 11.3.18. window-enlarge-vertically
- 11.3.19. window-shrink-vertically
- 11.3.20. window-enlarge-horizontally
- 11.3.21. window-shrink-horizontally
- 11.3.22. compile-elisp
- 11.3.23. join-next-line
- 11.3.24. sort-all-lines
- 11.3.25. sort-lines-removing-duplicates
- 11.3.26. delete-word
- 11.3.27. backward-delete-word
- 11.3.28. copy-line
- 11.3.29. cut-line
- 11.3.30. delete-line
- 11.3.31. delete-to-end-of-line
- 11.3.32. duplicate-line
- 11.3.33. duplicate-line-inc
- 11.3.34.
duplicate-sexp - 11.3.35. yank-as-rectangle
- 11.3.36. display-line-numbers-type-toggle
- 11.3.37.
goto-line-query - 11.3.38. goto-line-enhanced
- 11.3.39.
forward-word-enhanced - 11.3.40.
backword-word-enhanced - 11.3.41. forward-sexp-enhanced
- 11.3.42. backward-sexp-enhanced
- 11.3.43. scroll-up-enhanced
- 11.3.44. scroll-down-enhanced
- 11.3.45. scroll-up-command-enhanced
- 11.3.46. scroll-down-command-enhanced
- 11.3.47. downcase-region-enhanced
- 11.3.48. upcase-region-enhanced
- 11.3.49. downcase-word-enhanced
- 11.3.50. upcase-word-enhanced
- 11.3.51. capitalize-word-enhanced
- 11.3.52. toggle-word-case
- 11.3.53. eval-current-sexp
- 11.3.54. eval-sexp-buffer
- 11.3.55. eval-and-replace-last-sexp
- 11.3.56. eval-and-replace-current-sexp
- 11.3.57. macroexpand-and-replace
- 11.3.58. calc-eval-and-replace-region
- 11.3.59. calc-eval-and-replace-line
- 11.3.60. indent-current-sexp
- 11.3.61. indent-sexp-buffer
- 11.3.62. comment-or-uncomment-sexp
- 11.3.63. rename-buffer-and-file
- 11.3.64. move-buffer-and-file
- 11.3.65. delete-buffer-and-file
- 11.3.66. expand-relative-file-name
- 11.3.67. remove-trailing-blanks
- 11.3.68. remove-tabs
- 11.3.69. indent-down
- 11.3.70. server-start-maybe
- 11.3.71. load-bookmarks
- 11.3.72. find-file-updir
- 11.3.73. find-file-eof
- 11.3.74. mark-full-word
- 11.3.75. term-buffer
- 11.3.76. term-ansi
- 11.3.77. pop-up-shell
- 11.3.78. pop-up-shell-toggle
- 11.3.79. switch-to-scratch
- 11.3.80. switch-to-scratch-for-current-mode
- 11.3.81. new-scratch
- 11.3.82. new-emacs-lisp-scratch
- 11.3.83. new-org-scratch
- 11.3.84. recreate-scratch-when-killed
- 11.3.85. switch-to-messages
- 11.3.86. diff-current-buffer
- 11.3.87. get-char-property-here
- 11.3.88. comments-in-buffer
- 11.3.89. count-words
- 11.3.90. count-words-paragraph
- 11.3.91. count-lines-of-code
- 11.3.92. date-offset
- 11.3.93.
match-paren - 11.3.94. memory-use-counts-pretty
- 11.3.95. git-paste-cleanup
- 11.3.96. execute-buffer
- 11.3.97. file-in-exec-path
- 11.3.98.
resolve-file-link - 11.3.99. unicode-shell
- 11.3.100. async-spinner
- 11.3.101. with-time
- 11.3.102. package-desc-summary-to-kill-ring
- 11.3.103. toggle-case-fold-search
- 11.3.104. derived-modes
- 11.3.105. list-charset-unicode
- 11.3.106.
keybindings-table - 11.3.107. url-refresh
- 11.3.108. url-test
- 11.4. Emacs Grouped Functions
- 11.5. Text Conversion Functions
- 11.6. Text Inserting Functions
- 11.6.1. insert-timestamp
- 11.6.2. insert-path
- 11.6.3. uuid
- 11.6.4. insert-uuid
- 11.6.5. uuid-decimal
- 11.6.6. uuid-string
- 11.6.7. uuid-xml
- 11.6.8. insert-uuid-xml
- 11.6.9. insert-incrementing-vertical-numbers
- 11.6.10. insert-column-position-ruler
- 11.6.11. append-char-to-column
- 11.6.12. append-equal-to-column-80
- 11.6.13. append-dash-to-column-80
- 11.6.14. append-asterisk-to-column-80
- 11.6.15. insert-lisp-comment-block-equal
- 11.6.16. insert-lisp-comment-block-dash
- 11.6.17. insert-center-lisp-comment
- 11.6.18. insert-c-comment-block
- 11.6.19. insert-c-comment-stub
- 11.6.20. insert-db-change-log-template-line
- 11.6.21. insert-db-change-log-template-line-legacy
- 11.6.22. insert-xml-header
- 11.6.23. insert-lexical-binding
- 11.6.24. insert-figlet
- 11.6.25. insert-password
- 11.6.26. insert-password-phrase
- 11.6.27. insert-license-gpl
- 11.6.28. insert-license-mit
- 11.6.29. insert-license-apache
- 11.7. External Program Functions
- 11.7.1. insert-date
- 11.7.2. insert-datetime
- 11.7.3. insert-time
- 11.7.4. insert-date-stamp
- 11.7.5. insert-fortune
- 11.7.6. insert-quote
- 11.7.7. insert-arch-package-description
- 11.7.8. set-arch-package-description
- 11.7.9. insert-nix-package-description
- 11.7.10. set-nix-package-description
- 11.7.11. define-word
- 11.7.12. run-command
- 11.8. Newer Emacs Functionality Functions
- 11.9. Grep Search Functions
- 11.10. TAGS File Functions
- 11.11. Code Formatting Functions
- 11.11.1. indent-region-or-thing
- 11.11.2. indent-buffer
- 11.11.3. find-code-block
- 11.11.4. align-assignment-commands
- 11.11.5. align-assignment-commands-indent
- 11.11.6. align-declaration-commands
- 11.11.7. align-declaration-commands-indent
- 11.11.8. align-comments
- 11.11.9.
align-whitespace - 11.11.10. java-toggle-comment-type
- 11.11.11. java-remove-comments
- 11.11.12.
java-remove-comments-old - 11.11.13. lisp-to-camel-case
- 11.11.14. camel-case-to-lisp
- 11.11.15. c-pretty-print
- 11.11.16. ruby-pretty-print
- 11.11.17. java-pretty-print
- 11.11.18.
json-pretty-print - 11.11.19.
json-to-csv - 11.11.20. xml-pretty-print
- 11.12. Code Inserting Functions
- 11.13. Esoteric Functions
- 11.14. Table Generators
- 11.15. Programs
- 11.16. Games
- 12. Completions
- 13. Packages
- 13.1.
2048 - 13.2.
abook - 13.3. abbrev-mode
- 13.4.
ace-jump-mode - 13.5.
ace-window - 13.6. ag
- 13.7.
aggressive-indent - 13.8. alert
- 13.9. analog-clock
- 13.10. any-ini-mode
- 13.11.
anzu - 13.12. async
- 13.13. auto-compile
- 13.14.
auto-dictionary - 13.15. avy
- 13.16. bash-completion
- 13.17.
bbdb - 13.18. beacon
- 13.19. boxquote
- 13.20. browse-kill-ring
- 13.21. bs
- 13.22. calc
- 13.23. casual
- 13.24. casual-calc
- 13.25. casual-dired
- 13.26. cedet/semantic
- 13.27.
centered-cursor-mode - 13.28. cheat-sh
- 13.29.
codeium - 13.30.
color-theme - 13.31. command-log
- 13.32. compile
- 13.33. cycle-buffer
- 13.34.
cua - 13.35. decide
- 13.36.
decimation - 13.37.
define-word - 13.38. demo-it
- 13.39.
diff-hl - 13.40. doom-modeline
- 13.41. easy-kill
- 13.42. eat
- 13.43. editorconfig
- 13.44. eldoc
- 13.45. elfeed
- 13.46. elfeed-tube
- 13.47. ellama
- 13.48. elnode
- 13.49. elpher
- 13.50.
elscreen - 13.51. emacs-everywhere
- 13.52.
ement - 13.53. epaint
- 13.54. eperiodic
- 13.55. epg/epa
- 13.56. epoch
- 13.57. ert
- 13.58.
eterm-256color - 13.59. exec-path-from-shell
- 13.60. expand-region
- 13.61.
explain-pause-mode - 13.62. flycheck
- 13.63. flymake-cursor
- 13.64. flyspell
- 13.65. fuzzy
- 13.66. game-master-assistant
- 13.67. gcmh
- 13.68.
git-gutter - 13.69.
git-gutter+ - 13.70.
git-timemachine - 13.71.
golden-ratio - 13.72.
GPTel - 13.73. guix
- 13.74.
helpful - 13.75. hide-mode-line
- 13.76. hippie-exp
- 13.77. htmlize
- 13.78. hungry-delete
- 13.79.
hyperbole - 13.80. ibuffer
- 13.81.
identica - 13.82. isearch
- 13.83. iedit
- 13.84.
igrep - 13.85.
imdb - 13.86.
info-look - 13.87. ini
- 13.88. ispell
- 13.89.
jinx - 13.90. json
- 13.91.
keats - 13.92. key-chord
- 13.93. keyfreq
- 13.94. langtool
- 13.95.
longlines - 13.96. lorem-ipsum
- 13.97. lorem-ipsum-overlay
- 13.98.
lusty-explorer - 13.99. magit
- 13.100.
magpie - 13.101. mastodon
- 13.102. mingus
- 13.103. minions
- 13.104. multiple-cursors
- 13.105. mwim
- 13.106. neotree
- 13.107. nov
- 13.108. occur
- 13.109.
openwith - 13.110.
org-ai - 13.111. org-tree-slide
- 13.112.
outline - 13.113. olivetti
- 13.114.
pabbrev - 13.115.
package-lint - 13.116.
paredit - 13.117.
pdf-tools - 13.118. persistent-scratch
- 13.119.
pivotal-tracker - 13.120.
planner - 13.121. pocket-reader
- 13.122.
popper - 13.123.
powerline - 13.124. proced
- 13.125.
project - 13.126. projectile
- 13.127.
psvn - 13.128. rainbow-mode
- 13.129. recentf
- 13.130.
rect-mark - 13.131. regex-tool
- 13.132.
remind-bindings - 13.133. replacer
- 13.134. s
- 13.135. saveplace
- 13.136.
selected - 13.137.
session - 13.138.
simple-mpc - 13.139.
slack - 13.140. smerge
- 13.141.
smex - 13.142. sokoban
- 13.143. split-move
- 13.144. spinner
- 13.145. sudoku
- 13.146. svg-2048
- 13.147. svg-clock
- 13.148. switch-window
- 13.149.
sunrise - 13.150.
table - 13.151. telnet
- 13.152.
template - 13.153. timeclock
- 13.154. time-stamp
- 13.155.
totd - 13.156. tramp
- 13.157.
treemacs - 13.158.
tree-sitter - 13.159.
twit - 13.160. undo-tree
- 13.161.
uniquify - 13.162.
units-mode - 13.163. vimish-fold
- 13.164. visual-fill-column
- 13.165. w3m
- 13.166.
wanderlust - 13.167. web-query
- 13.168. webjump
- 13.169. weblogger
- 13.170. wgrep
- 13.171. which-key
- 13.172. wtf
- 13.173. wttrin
- 13.174.
yascroll
- 13.1.
- 14. Modes
- 14.1. Configuration
- 14.2. ASM
- 14.3.
Auto-Indent Mode - 14.4. Brainfuck
- 14.5. BASIC
- 14.6. C Mode
- 14.7. Calendar
- 14.8.
Clojure Mode - 14.9. CSS Mode
- 14.10. Dired
- 14.11. Ediff
- 14.12.
Ergoemacs Mode - 14.13. Erlang Mode
- 14.14. Fundamental Mode
- 14.15. Geiser (Racket Scheme REPL)
- 14.16. GNU Plot
- 14.17.
Go Mode - 14.18.
GPG Mode - 14.19. Graphviz Dot Mode
- 14.20.
HTML Mode - 14.21. INI Mode
- 14.22.
Java Mode - 14.23.
Java: JDE Mode - 14.24.
Java: Flymake Mode for JDE - 14.25.
Java: JDEE Mode - 14.26.
Java: Meghanada Mode - 14.27.
Java: Android Mode - 14.28.
Javascript Mode - 14.29. Javascript: js2 Mode
- 14.30.
Javascript: js3 Mode - 14.31. JSON Mode
- 14.32.
Kotlin Mode - 14.33. LaTeX
- 14.34. Ledger Mode
- 14.35. Lisp Mode
- 14.36.
LSP Mode - 14.37. LUA Mode
- 14.38. Makefile Mode
- 14.39. Markdown Mode
- 14.40.
Muse Mode - 14.41. Nix Mode
- 14.42. Perl Mode
- 14.43. PlantUML Mode
- 14.44.
Prolog Mode - 14.45.
Python Mode (iPython Version) - 14.46. Python Mode
- 14.47. Racket Mode
- 14.48. Ruby Mode
- 14.49. Rust Mode
- 14.50. SH Script
- 14.51. Shell Mode
- 14.52. Slime Mode (Common Lisp)
- 14.53. SQL Mode
- 14.54. Text Mode
- 14.55. TypeScript Mode
- 14.56. V Mode
- 14.57. Vimrc Mode
- 14.58.
Workgroups Mode - 14.59.
XML/SGML Mode - 14.60. XML Mode
- 14.61. YAML Mode
- 14.62.
Yuck Mode - 14.63.
Global Mode
- 15. Menus
- 15.1. Configuration
- 15.2. Buffer-Switch Menu
- 15.3. Dired Menu
- 15.4. Load Menu
- 15.5. Application Menu
- 15.6. Run-File Menu
- 15.7. Website Menu
- 15.8. Package Manager Menu
- 15.9. Miscellaneous Menu
- 15.10. Manuals Menu
- 15.11. Web Menu
- 15.12. Insert Menu
- 15.13.
Yank Menu - 15.14. Weather Menu
- 15.15. Games Menu
- 16. Snippets
- 17. Hydras
- 18. Windows OS
- 19. Gnus
- 20. ERC
- 21. Work
- 22. Other
- 23. Aliases
- 24. Final
- 24.1. Set Key Bindings
- 24.2.
Turn on CUA Mode - 24.3.
Turn on Menu-Bar - 24.4. Compile Personal Modules
- 24.5.
Upgrade Quelpa Asynchronously - 24.6. Start Emacs Server
- 24.7.
Move to Current Desktop - 24.8.
Restore Open Buffers - 24.9. Remove Logging Buffers
- 24.10. Fix Info-Directory-List
- 24.11. Turn off Scroll Bar
- 24.12.
Clear Mark - 24.13. Reset Emacs Lisp Garbage Collection Threshold
- 24.14.
Turn off Debugging - 24.15.
Open Messages Buffer on Error
- 25. End
Overview
This Emacs configuration is in Org/Babel 'literate' programming style.
This file, init-emacs.org, is converted (automatically on save) into
init-emacs.el, which is then compiled into init-emacs.elc using
org-babel-generate-elisp
, which is a custom generator that runs a lot faster
than org-babel-tangle
.
The 4.2 section tangles init.el which contains the bootstrap code that
defines key methods like org-babel-generate-elisp
and runs init-emacs.el.
It was inspired and influenced by the Emacs Starter Kit and Grant Rettke's Creation and Conservation of Computer Files (C3F) Emacs setup. Grant's post on reddit motivated me to convert my (over 10 years old and over 10K lines long) Emacs configuration system to an Org/Babel based one.
Emacs outshines all other editing software in approximately the same way that the noonday sun does the stars. It is not just bigger and brighter; it simply makes everything else vanish.
– Neal Stephenson, "In the Beginning was the Command Line"
Information
Font-Lock Faces
Faces that May be Set with Font-Lock |
---|
font-lock-builtin-face |
font-lock-comment-delimiter-face |
font-lock-comment-face |
font-lock-constant-face |
font-lock-doc-face |
font-lock-doc-string-face |
font-lock-function-name-face |
font-lock-keyword-face |
font-lock-negation-char-face |
font-lock-preprocessor-face |
font-lock-string-face |
font-lock-type-face |
font-lock-variable-name-face |
font-lock-warning-face |
Constants
Colors
Use list-coding-systems
to display common colors.
Color | Name | Symbol | Hex Code |
---|---|---|---|
Adwaita Dark Background (Original) | #29353b | ||
Adwaita Dark Background (Darker) | #19252b | ||
Adwaita Dark Background (Darkest) | color-background | #09151b | |
White Foreground | color-foreground | #bbc2cf | |
White Foreground Accent | #798188 | ||
Yellow Cursor | color-cursor | #eeee22 | |
Bright Yellow Highlight | color-paren | #ffff33 | |
White Mouse | color-mouse | #ffffff | |
Outline Level 1 | goldenrod | color-1 | #daa520 |
Outline Level 2 | light goldenrod | color-2 | #eedd82 |
Outline Level 3 | yellow green | color-3 | #9acd32 |
Outline Level 4 | light salmon | color-4 | #ffa07a |
Outline Level 5 | tan | color-5 | #d2b48c |
Outline Level 6 | light green | color-6 | #90ee90 |
Outline Level 7 | coral | color-7 | #ff7f50 |
Outline Level 8 | wheat | color-8 | #f5deb3 |
;;------------------------------------------------------------------------------ ;;; Constants: Colors ;;------------------------------------------------------------------------------ (mapc (lambda (x) (let ((color (caddr x)) (value (cadddr x))) (when (> (length color) 0) (set (intern color) value)))) (cdr data))
Init
Early Init
Tangle early-init.el file.
;; -*- mode: emacs-lisp; lexical-binding: t; no-byte-compile: t -*- ;;============================================================================== ;;; early-init.el ;; ;;; Early Emacs Initialization File ;; ;; Author: Kyle W T Sherman ;; ;; This file was generated from init-emacs.org and should not be edited ;; manually. ;; ;; init-emacs.org => early-init.el ;;============================================================================== ;; macro combining `setq' and `setq-default' ;; FIXME ;;(defmacro setq-customize ( ;; disable default emacs package handling (needed for straight) (setq package-enable-at-startup nil) ;; do not shrink frame to match font size (setq frame-resize-pixelwise t) ;; suppress display compilation warnings (setq warning-suppress-types '((comp))) ;;============================================================================== ;;; early-init.el ends here ;;==============================================================================
Init
Tangle init.el bootstrap file.
;; -*- mode: emacs-lisp; lexical-binding: t; no-byte-compile: t -*- ;;============================================================================== ;;; init.el ;; ;;; Bootstrap Emacs Initialization File ;; ;; Author: Kyle W T Sherman ;; ;; This file was generated from init-emacs.org and should not be edited ;; manually. ;; ;; init-emacs.org => init.el ;;============================================================================== ;;------------------------------------------------------------------------------ ;;; Org/Babel Bootstrap: Custom Tangle ;;------------------------------------------------------------------------------ ;; (defun org-babel-generate-elisp-file (file &optional byte-compile force) ;; "Generate an emacs-lisp file from an org-babel FILE. ;; Additionally, byte compile the file if BYTE-COMPILE is ;; non-nil. ;; Process file even if timestamp is not newer than target if FORCE ;; is non-nil." ;; (let* ((case-fold-search t) ;; (file-base (concat (file-name-directory user-init-file) "init-emacs")) ;; (file-org (file-truename (concat file-base ".org"))) ;; (file-elisp (file-truename (concat file-base ".el"))) ;; (file-comp (file-truename (concat file-base ".elc"))) ;; (heading-regexp "^\*+ ") ;; (heading-comment-regexp "^\*+ COMMENT ") ;; (begin-regexp "^[ \t]*#\\+BEGIN_SRC emacs-lisp") ;; (begin-tangle-regexp "^[ \t]*#\\+BEGIN_SRC .*:tangle ") ;; (end-regexp "^[ \t]*#\\+END_SRC") ;; (indent-regexp "^ ")) ;; ;; generate elisp file if needed ;; (when (or force ;; (not (file-exists-p file-elisp)) ;; (file-newer-than-file-p file-org file-elisp)) ;; (message "Writing %s..." file-elisp) ;; (with-temp-file file-elisp ;; (insert-file-contents file) ;; (goto-char (point-min)) ;; (let (code ;; headings-counts ;; (level 1) ;; (comment-level 0) ;; (end-comment "")) ;; (while (not (eobp)) ;; (cond ;; ;; comment heading ;; ((let ((case-fold-search nil)) ;; (looking-at heading-comment-regexp)) ;; (setq level (/ (- (match-end 0) (line-beginning-position) 8) 2)) ;; (when (or (zerop comment-level) ;; (< level comment-level)) ;; (setq comment-level level)) ;; (delete-region (line-beginning-position) (progn (forward-line 1) (point)))) ;; ;; normal heading ;; ((looking-at heading-regexp) ;; (setq level (/ (- (match-end 0) (line-beginning-position)) 2)) ;; (when (or (zerop comment-level) ;; (<= level comment-level)) ;; (setq comment-level 0) ;; (if (assoc level headings-counts) ;; (setf (cdr (assoc level headings-counts)) ;; (cons (buffer-substring-no-properties (match-end 0) (line-end-position)) 1)) ;; (setq headings-counts (append headings-counts (list (cons level (cons "No heading" 1))))))) ;; (delete-region (line-beginning-position) (progn (forward-line 1) (point)))) ;; ;; start of tangled source block ;; ((and (looking-at begin-regexp) ;; (zerop comment-level) ;; (not (looking-at begin-tangle-regexp))) ; skip blocks with their own tangle directive ;; (let* ((heading-count (cdr (assoc level headings-counts))) ;; (heading (car heading-count)) ;; (count (cdr heading-count))) ;; (delete-region (line-beginning-position) (progn (forward-line 1) (point))) ;; (unless (bobp) ;; (newline)) ;; (when (fboundp 'org-link-escape) ;; (insert (format ";; [[file:%s::*%s][%s:%s]]\n" file-org (org-link-escape heading) heading count)) ;; (setq end-comment (format ";; %s:%s ends here\n" heading count)) ;; (cl-incf (cddr (assoc level headings-counts)))) ;; (setq code t))) ;; ;; end of tangled source block ;; ((and code ;; (looking-at end-regexp)) ;; (delete-region (line-beginning-position) (progn (forward-line 1) (point))) ;; (insert end-comment) ;; (setq code nil ;; end-comment "")) ;; ;; inside tangled source block ;; (code ;; (when (looking-at indent-regexp) ;; (delete-char (if (boundp 'org-edit-src-content-indentation) ;; org-edit-src-content-indentation ;; 2))) ;; (forward-line 1)) ;; ;; outside tangled source block ;; (t ;; (delete-region (line-beginning-position) (progn (forward-line 1) (point)))))) ;; (time-stamp)) ;; (message "Wrote %s..." file-elisp))) ;; ;; byte compile elisp file if needed ;; (when (and byte-compile ;; (or (not (file-exists-p file-comp)) ;; (file-newer-than-file-p file-elisp file-comp))) ;; (byte-compile-file file-elisp)))) ;; ;; generate and load main init file ;; (let* ((file-base (concat (file-name-directory user-init-file) "init-emacs")) ;; (file-org (file-truename (concat file-base ".org"))) ;; (file-elisp (file-truename (concat file-base ".el"))) ;; (file-comp (file-truename (concat file-base ".elc")))) ;; ;; do not try to byte compile the generated file as it will fail since our environment is not setup ;; (org-babel-generate-elisp-file file-org) ;; ;; delete any existing byte compiled init file to prevent an outdated version from loading ;; (when (file-exists-p file-comp) ;; (delete-file file-comp)) ;; (if (file-exists-p file-elisp) ;; (load file-elisp) ;; (message "Error loading %s" file-elisp))) ;;------------------------------------------------------------------------------ ;;; Org/Babel Bootstrap: Normal Tangle ;;------------------------------------------------------------------------------ (require 'ob-tangle) (setq vc-follow-symlinks t) ;; generate (if needed) and load main init file (let* ((file-base (concat (file-name-directory user-init-file) "init-emacs")) (file-org (file-truename (concat file-base ".org"))) (file-elisp (file-truename (concat file-base ".el"))) (file-comp (file-truename (concat file-base ".elc")))) ;; do not try to byte compile the generated file as it will fail since our environment is not setup (when (file-newer-than-file-p file-org file-elisp) (org-babel-tangle-file file-org)) ;; delete any existing byte compiled init file to prevent an outdated version from loading (when (file-exists-p file-comp) (delete-file file-comp)) (if (file-exists-p file-elisp) (load file-elisp) (message "Error loading %s" file-elisp))) ;;============================================================================== ;;; init.el ends here ;;==============================================================================
Windows Init
Special init file for Windows machines where I run the MinGW version of Emacs.
;; -*- mode: emacs-lisp; lexical-binding: t; no-byte-compile: t -*- ;;============================================================================== ;;; init-windows.el ;; ;;; Bootstrap Emacs Initialization File for Windows ;; ;; Author: Kyle W T Sherman ;; ;; This file was generated from init-emacs.org and should not be edited ;; manually. ;; ;; init-emacs.org => init-windows.el ;; ;; On Windows machines copy this file to: %APPDATA%\init.el ;;============================================================================== ;;------------------------------------------------------------------------------ ;;; Load Real Init File ;;------------------------------------------------------------------------------ (let ((home "C:\\msys64\\home\\kyle.sherman")) (setenv "HOME" home) (load (expand-file-name ".emacs.d\\init.el" home))) ;;============================================================================== ;;; init-windows.el ends here ;;==============================================================================
Start
Starting point of tangled init-emacs.el file.
Header
;; -*- mode: emacs-lisp; lexical-binding: t; no-byte-compile: t -*- ;;============================================================================== ;;; init-emacs.el ;; ;;; Main Emacs Settings File ;; ;; Author: Kyle W T Sherman ;; ;; This file was generated from init-emacs.org and should not be edited ;; manually. ;; ;; init-emacs.org => init-emacs.el ;;============================================================================== ;;============================================================================== ;;; Start ;;==============================================================================
Status messages are written to the \*Messages\* buffer throughout the initialization process to help debug loading errors.
Status Messages
;;------------------------------------------------------------------------------ ;;; Start: Status Messages ;;------------------------------------------------------------------------------ ;; add timestamps to *Messages* buffer (defun message--with-timestamp (format-string &rest args) "Add timestamps to `*Messages*' buffer." (when (and (> (length format-string) 0) (not (string= format-string " "))) (let ((deactivate-mark nil)) (save-mark-and-excursion (with-current-buffer "*Messages*" (let ((inhibit-read-only t)) (goto-char (point-max)) (unless (bolp) (newline)) (insert (format-time-string "[%T] " (current-time))))))))) ;; advise `message' (advice-add 'message :before #'message--with-timestamp) ;; keep track of load times (defvar init-message-timestamp nil "Timestamp used to track time between `init-message' calls.") (setq init-message-timestamp (current-time)) ;; load time message (defun init-message (level format-string &rest args) "Custom version of `message' to log messages during Emacs initialization. LEVEL is the indentation level." (let ((file (file-name-sans-extension (file-name-nondirectory (or load-file-name buffer-file-name (buffer-name))))) (time (* (float-time (time-subtract (current-time) init-message-timestamp)) 1000.0))) (message (concat (format "[%4d] " time) file " " (make-string (* 2 level) ?-) "> " (format format-string args) " ")) (setq init-message-timestamp (current-time)))) (init-message 2 "Start: Status Messages") ;; display load time after startup (defun emacs-startup-hook--message-startup-time () "Message the Emacs startup time and number of garbage collections." (message "Emacs startup time: %.2f seconds" (float-time (time-subtract after-init-time before-init-time))) (message "Emacs startup garbage collections: %d" gcs-done)) (add-hook 'emacs-startup-hook #'emacs-startup-hook--message-startup-time)
Set Emacs Lisp Garbage Collection Threshold
Increase the Emacs Lisp garbage collection threshold to reduce the frequency of garbage collections.
;;------------------------------------------------------------------------------ ;;; Start: Set Emacs Lisp Garbage Collection Threshold ;;------------------------------------------------------------------------------ ;; reduce frequency of garbage collections (setq gc-cons-threshold (* 8 1024 1024)) ; default: 800000
Ignore Errors Advice Wrapper
Generic advice wrapper function to ignore errors.
;;------------------------------------------------------------------------------ ;;; Start: Ignore Errors Advice Wrapper ;;------------------------------------------------------------------------------ ;; generic advice wrapper function to ignore all errors (defun advice--ignore-all-errors (orig-fun &rest args) "Ignore errors when calling ORIG-FUN with ARGS." (ignore-errors (apply orig-fun args))) ;; generic advice wrapper function to ignore interactive errors (defun advice--ignore-interactive-errors (orig-fun &rest args) "Ignore errors when interactively calling ORIG-FUN with ARGS." (condition-case err (apply orig-fun args) ('error (if (called-interactively-p 'any) (message "%s" err) (error err)))))
Lock-File Macro Wrapper
Lock-file wrapper macro to evaluate code blocks only once per emacs session.
Source: https://www.reddit.com/user/7890yuiop/
;;------------------------------------------------------------------------------ ;;; Start: Lock-File Macro Wrapper ;;------------------------------------------------------------------------------ ;; lock-file wrapper macro to evaluate code blocks only once per emacs session (defmacro when-lock-file-acquired (lock-file &rest body) "Evaluate BODY unless another running Emacs instance has done so. LOCK-FILE is a file name to be used as a lock for this BODY code. Skips checks if run on Windows or Mac." (declare (indent 1)) (let ((procdir (gensym "procdir"))) `(let ((,procdir (format "/proc/%d" (emacs-pid)))) (unless (or (string= system-type "windows-nt") (string= system-type "darwin") (file-exists-p ,lock-file)) (make-symbolic-link ,procdir ,lock-file t)) (when (or (string= system-type "windows-nt") (string= system-type "darwin") (file-equal-p ,lock-file ,procdir)) ,@body))))
Package Manager
Package managers.
;;============================================================================== ;;; Package Manager ;;============================================================================== (init-message 1 "Package Manager")
Straight
Build and install Emacs Lisp packages on-the-fly and directly from source.
;;------------------------------------------------------------------------------ ;;; Package Manager: Straight ;;------------------------------------------------------------------------------ (init-message 2 "Package Manager: Straight") ;; initialize package system (require 'package) ;; (setq package-archives '(("melpa" . "https://melpa.org/packages/") ;; ("elpa" . "https://elpa.gnu.org/packages/")) (setq package-archives '(("elpa" . "https://elpa.gnu.org/packages/") ("nongnu" . "https://elpa.nongnu.org/nongnu/")) native-comp-async-report-warnings-errors nil) ;; bootstrap (defvar bootstrap-version) (let ((bootstrap-file (expand-file-name "straight/repos/straight.el/bootstrap.el" user-emacs-directory)) (bootstrap-version 5)) (unless (file-exists-p bootstrap-file) (with-current-buffer (url-retrieve-synchronously "https://raw.githubusercontent.com/raxod502/straight.el/develop/install.el" 'silent 'inhibit-cookies) (goto-char (point-max)) (eval-print-last-sexp))) (load bootstrap-file nil 'nomessage)) ;; use straight with `use-package' (straight-use-package 'use-package) ;; ;; configure `use-package' to use straight by default ;; (use-package straight ;; :custom ;; (straight-use-package-by-default t)) ;; turn off package file modification check at startup (setq straight-check-for-modifications '(find-when-checking check-on-save)) ;; update recipe repositories ;;(straight-pull-recipe-repositories)
Quelpa
Build and install Emacs Lisp packages on-the-fly and directly from source.
;; ;;------------------------------------------------------------------------------ ;; ;;; Package Manager: Quelpa ;; ;;------------------------------------------------------------------------------ ;; (init-message 2 "Package Manager: Quelpa") ;; ;; set package archives (no ELPA) ;; (setq package-archives '(("gnu" . "http://elpa.gnu.org/packages/") ;; ("melpa" . "http://melpa.org/packages/"))) ;; ;; initialize package ;; (package-initialize) ;; ;; load package archive, if needed ;; (unless package-archive-contents ;; (package-refresh-contents)) ;; ;; initialize `quelpa' to fetch and build packages ;; (unless (package-installed-p 'quelpa) ;; (with-temp-buffer ;; (url-insert-file-contents "https://github.com/quelpa/quelpa/raw/master/quelpa.el") ;; (eval-buffer) ;; (quelpa-self-upgrade))) ;; ;; do not update Quelpa or MELPA repo on initialization as it slows down launch time ;; (setq quelpa-upgrade-p nil ;; quelpa-update-melpa-p nil) ;; ;; install quelpa version of `use-package' to install and load packages ;; (quelpa '(quelpa-use-package :fetcher github :repo "quelpa/quelpa-use-package")) ;; (setq use-package-expand-minimally t) ;; (require 'quelpa-use-package) ;; (setq use-package-always-ensure t) ; always fetch missing packages
ELPA (Emacs Lisp Package Archive)
ELPA (Emacs Lisp Package Archive) configuration.
;; ;;------------------------------------------------------------------------------ ;; ;;; Package Manager: ELPA (Emacs Lisp Package Archive) ;; ;;------------------------------------------------------------------------------ ;; (init-message 2 "Package Manager: ELPA (Emacs Lisp Package Archive)") ;; ;; elpa (emacs lisp package archive) ;; (defconst emacs-package-dir ;; (file-truename (expand-file-name "elpa" user-emacs-directory)) ;; "ELPA (Emacs Lisp Package Archive) packages directory.") ;; (add-to-list 'load-path emacs-package-dir t) ;; ;; if package is not installed, install it ;; (unless (require 'package nil :no-error) ;; (let ((buffer (url-retrieve-synchronously "http://tromey.com/elpa/package-install.el"))) ;; (with-current-buffer buffer ;; (goto-char (point-min)) ;; (re-search-forward "^$" nil 'move) ;; (eval-region (point) (point-max)) ;; (kill-buffer (current-buffer)))) ;; ;; remove code that gets added to ~/.emacs.d/init.el ;; (let ((buffer (find-file-noselect (file-truename (expand-file-name "~/.emacs.d/init.el"))))) ;; (with-current-buffer buffer ;; (when (re-search-forward ";;; init.el ends here" nil :noerror) ;; (forward-line 0) ;; (forward-line 1) ;; (kill-region (point) (point-max)) ;; (save-buffer) ;; (kill-buffer (current-buffer)))))) ;; ;; initialize package system ;; (require 'package) ;; (setq package-enable-at-startup nil ;; ;; package-archives '(("org" . "http://orgmode.org/elpa/") ;; ;; ("gnu" . "http://elpa.gnu.org/packages/") ;; ;; ("melpa" . "http://melpa.org/packages/")) ;; package-archives '(("gnu" . "http://elpa.gnu.org/packages/") ;; ("melpa" . "http://melpa.org/packages/")) ;; package-user-dir emacs-package-dir) ;; (package-initialize) ;; ;; refresh package archive contents if empty ;; (unless package-archive-contents ;; (package-refresh-contents)) ;; ;; install `use-package' to load packages ;; (unless (package-installed-p 'use-package) ;; (package-refresh-contents) ;; (package-install 'use-package)) ;; (setq use-package-expand-minimally t) ;; ;; install `bind-key' to help with binding keys in `use-package' blocks ;; (unless (package-installed-p 'bind-key) ;; (package-install 'bind-key)) ;; ;; install `diminish' to diminish package names on the mode-line in `use-package' blocks ;; (unless (package-installed-p 'diminish) ;; (package-install 'diminish)) ;; ;; require above packages ;; (require 'use-package) ;; (use-package diminish) ;; (use-package bind-key) ;; ;; verbose `use-package' reporting when byte compiling ;; (eval-when-compile ;; (setq use-package-verbose t))
Paradox
Paradox Package Menu.
A modern Packages Menu. Colored, with package ratings, and customizable.
;; ;;------------------------------------------------------------------------------ ;; ;;; Package Manager: Paradox ;; ;;------------------------------------------------------------------------------ ;; (init-message 2 "Package Manager: Paradox") ;; (use-package paradox ;; :commands (paradox-enable) ;; :config ;; ;; always run package commands asynchronously ;; (setq paradox-execute-asynchronously t) ;; ;; enable paradox ;; (paradox-enable))
Environment
Configuration of default Emacs settings.
;;============================================================================== ;;; Environment ;;============================================================================== (init-message 1 "Environment")
Debugging
;; ;;------------------------------------------------------------------------------ ;; ;;; Environment Settings: Debugging ;; ;;------------------------------------------------------------------------------ ;; (init-message 2 "Environment: Debugging")
Turn debugging on when errors occur. This will also trap normal (expected) errors, so it should not normally be on.
;; ;; turn debugging on when errors occur ;; (setq debug-on-error t) ;; ;; (defun after-init-hook--debug-on-error () ;; ;; "Hook to turn debugging on after init completes." ;; ;; (setq debug-on-error t)) ;; ;; (add-hook 'after-init-hook #'after-init-hook--debug-on-error)
Init Packages
Load packages that are used for initialization.
;;------------------------------------------------------------------------------ ;;; Environment: Init Packages ;;------------------------------------------------------------------------------ (init-message 2 "Environment: Init Packages") ;; load packages that are used for initialization (use-package async :straight t) (use-package bind-key :straight t :custom ;; extract docstrings from lambdas, closures and keymaps if possible (bind-key-describe-special-forms t)) (use-package cl-generic :straight (:type built-in)) (use-package cl-macs :straight (:type built-in)) (use-package dash :straight t :demand t) (use-package diminish :straight (diminish :type git :host github :repo "myrjola/diminish.el")) (use-package f :straight t :demand t) (use-package s :straight t :demand t) (use-package seq :straight (:type built-in)) (use-package subr-x :straight (:type built-in)) (use-package org :straight (:type built-in)) (use-package org-table :straight (:type built-in)) (use-package ob-tangle :straight (:type built-in)) (use-package ox :straight (:type built-in))
Environment
;;------------------------------------------------------------------------------ ;;; Environment: Environment ;;------------------------------------------------------------------------------ (init-message 2 "Environment: Environment")
Set coding system to UTF-8.
;; set coding system to UTF-8 (prefer-coding-system 'utf-8) (set-language-environment 'utf-8) (set-default-coding-systems 'utf-8) (set-terminal-coding-system 'utf-8) (set-selection-coding-system 'utf-8) (set-keyboard-coding-system 'utf-8)
Set timezone to CST.
;; set timezone to CST ;;(setenv "TZ" "CDT+6") (setenv "TZ" "America/Chicago")
Determine if running on a MS-Windows display.
;; determine if running on a MS-Windows display (defconst window-system-windows ;;(memq system-type '(emx win32 w32 mswindows ms-dos windows-nt)) (string= window-system "w32") "Non-nil if running on a MS-Windows display.")
Determine if running on a Macintosh GNUstep or Cocoa display.
;; determine if running on a macintosh gnustep or cocoa display (defconst window-system-mac (string= window-system "ns") "Non-nil if running on a Macintosh GNUstep or Cocoa display.")
Determine if running on a Linux X display.
;; determine if running on a Linux X display (defconst window-system-linux (string= window-system "x") "Non-nil if running on a Linux X display.")
Determine if running on a work computer.
;; determine if running on a work system (defconst work-system (file-exists-p "~/.work") "Non-nil if running on a work system.")
Make the user's home directory the default directory.
;; cd to home (cd "~")
Configure shell environment.
;; shell environment (setq shell-file-name (or (getenv "SHELL") "/bin/bash") shell-command-switch "-c" explicit-shell-file-name shell-file-name explicit-sh-args '("-login" "-i")) ;; quote arguments on windows (when window-system-windows (defvar w32-quote-process-args ?\" "Windows quote arguments.")) ;; add /usr/local to path on mac (when window-system-mac (add-to-list 'exec-path "/usr/local/sbin") (add-to-list 'exec-path "/usr/local/bin"))
Set print settings.
;; set object print depth (do not abbreviate printed objects) (setq print-length nil print-level nil eval-expression-print-length nil eval-expression-print-level nil) ;; ;; turn off print header ;; (setq ps-print-header nil)
Global Variables
;;------------------------------------------------------------------------------ ;;; Environment: Global Variables ;;------------------------------------------------------------------------------ (init-message 2 "Environment: Global Variables")
Set Emacs home directory.
;; set emacs home directory (defconst emacs-home-dir (file-truename (expand-file-name "~/.emacs.d")) "Emacs configuration home directory.")
Macro for setting emacs-home-dir
sub-directories.
(defmacro emacs-home-sub-dir (dir) "Return expanded directory name of DIR if found as a sub-directory of `emacs-home-dir', or just `emacs-home-dir' otherwise." `(let ((file (expand-file-name ,dir emacs-home-dir))) (if (file-exists-p file) (file-truename file) emacs-home-dir)))
Set Emacs modules directory. This is used for non-ELPA modules that are manually installed.
;; set emacs modules directory (defconst emacs-modules-dir (emacs-home-sub-dir "modules") "Emacs modules directory.")
Set local initialization directory. This is not currently used.
;; ;; set local init directory ;; (defconst local-init-dir ;; (emacs-home-sub-dir "local-init") ;; "Emacs local initialization directory.")
Set local modules directory. This is used for custom modules that I've written.
;; set local modules directory (defconst local-modules-dir (emacs-home-sub-dir "local-modules") "Emacs local modules directory.")
Set local work modules directory. This is used for custom modules that I use for work.
;; set local work modules directory (defconst local-work-modules-dir (emacs-home-sub-dir "local-work-modules") "Emacs local work modules directory.")
Set Emacs customizations file. Used to save customizations made with the customize command. This file is not loaded and is stored in a system temporary directory so it does not persist. Any desired customizations should be moved into this init file instead of the temporary customization file.
;; set customization file (defconst customization-file (file-truename (expand-file-name "customization.el" emacs-home-dir)) "Emacs customization file.") (setq custom-file customization-file)
Set init-emacs.org true file name.
;; set init-emacs.org true file name (defconst init-emacs-true-file-name (file-truename (expand-file-name "init-emacs.org" emacs-home-dir)) "The true file name of this buffer.")
Set various versions of user's name.
;; set user name (defconst user-name "kyle") (defconst user-full-name "Kyle W T Sherman") (defconst user-short-name "Kyle Sherman") (defconst user-first-name "Kyle") (defconst user-last-name "Sherman")
Set user email addresses.
;; set email address (defconst user-mail-address (if (getenv "EMAIL") (getenv "EMAIL") (concat "kyle" "w" "sherman" "@" "gmail" "." "com")) "User email address.")
;; set no-spam email address (defconst user-mail-address-nospam (replace-regexp-in-string "\\." " dot " (replace-regexp-in-string "@" " at " user-mail-address)) "Slightly obfuscated user email address.")
Function that returns an email signature in the form of NAME <MAIL> with an optional fortune added.
(defun signature (&optional fortune) "Return a signature. A fortune is added if FORTUNE is non-nil." (let ((name (or user-short-name user-full-name)) (mail user-mail-address)) (let ((sig (if (and name mail) (concat name " <" mail ">") (if name name mail)))) (concat (if sig sig "") (if (and sig fortune) "\n\n" "") (if fortune (shell-command-to-string (concat "fortune -a " (shell-quote-argument (expand-file-name "~/quotes")) " | xargs echo -n")) "")))))
Load Path
Add other configuration directories to load-path.
(init-message 2 "Environment: Load Path") ;; add paths to the head of `load-path' in reverse order. ;; personal elisp projects (when (file-exists-p local-modules-dir) (add-to-list 'load-path local-modules-dir)) ;; ;; personal emacs initialization scripts ;; (when (file-exists-p local-init-dir) ;; (add-to-list 'load-path local-init-dir)) ;; ;; emacs home directory ;; (when (file-exists-p emacs-home-dir) ;; (add-to-list 'load-path emacs-home-dir)) ;; emacs modules directory (when (file-exists-p emacs-modules-dir) (add-to-list 'load-path emacs-modules-dir)) ;; ;; org-mode directory ;; (when (file-exists-p (expand-file-name "org-mode/contrib/lisp" emacs-modules-dir)) ;; (add-to-list 'load-path (file-truename (expand-file-name "org-mode/contrib/lisp" emacs-modules-dir)))) ;; (when (file-exists-p (expand-file-name "org-mode/lisp" emacs-modules-dir)) ;; (add-to-list 'load-path (file-truename (expand-file-name "org-mode/lisp" emacs-modules-dir))))
GUI
Header
(when window-system
General
;;------------------------------------------------------------------------------ ;;;; Environment: GUI: General ;;------------------------------------------------------------------------------ (init-message 3 "Environment: GUI: General") ;; support for emacs version < 25.1 (unless (fboundp 'gui-selection-value) (defalias 'gui-selection-value 'x-cut-buffer-or-selection-value)) ;; clipboard (when (string= window-system "x") (setq select-enable-clipboard t ; cutting and pasting uses clipboard select-enable-primary t ; cutting and pasting uses primary selection x-select-request-type '(UTF8_STRING COMPOUND_TEXT TEXT STRING) ; data-type request for X selection save-interprogram-paste-before-kill t ; save clipboard strings into kill ring before replacing them mouse-yank-at-point t ; mouse yank commands yank at point interprogram-paste-function 'gui-selection-value) ; function to call to get text cut from other programs (setq-default select-enable-clipboard select-enable-clipboard select-enable-primary select-enable-primary x-select-request-type x-select-request-type save-interprogram-paste-before-kill save-interprogram-paste-before-kill mouse-yank-at-point mouse-yank-at-point)) ;; inverse video on (setq inverse-video t) (setq-default inverse-video inverse-video) ;; visible bell (setq visible-bell t) (setq-default visible-bell visible-bell) ;; turn off bell (setq ring-bell-function 'ignore) ;; turn off cursor blinking (blink-cursor-mode 0) ;; stretch cursor to glyph width (setq x-stretch-cursor t) ;; ;; scroll bar on right ;; (setq scroll-bar-mode 'right) ;; (scroll-bar-mode -1) ;; (scroll-bar-mode 1) ;; turn off scroll bar (when (fboundp 'scroll-bar-mode) (scroll-bar-mode -1)) ;; turn off toolbar (when (and (fboundp 'tool-bar-mode) tool-bar-mode) (tool-bar-mode -1)) ;; make default frame size fullscreen ;;(add-to-list 'default-frame-alist '(fullscreen . maximized)) ;; do not shrink frame to match font size (setq frame-resize-pixelwise t) ;; put current buffer name in title bar (setq frame-title-format "%b") ;; mouse button one drags the scroll bar (bind-keys* ([vertical-scroll-bar down-mouse-1] . scroll-bar-drag)) ;; scroll mouse settings (setq mouse-wheel-scroll-amount '(1 ((shift) . 1)) mouse-wheel-progressive-speed t)
Font
;;------------------------------------------------------------------------------ ;;;; Environment: GUI: Font ;;------------------------------------------------------------------------------ (init-message 3 "Environment: GUI: Font") ;; set default font (cl-labels ((set-font (font) (set-face-attribute 'default nil :font font) (set-face-attribute 'fixed-pitch nil :font font) (set-face-attribute 'variable-pitch nil :font font))) (cl-case window-system (x (condition-case nil (set-font (cond ;; "8x13" ;; "9x15" ;; "Ubuntu Mono-13" ;; "Inconsolata-15" ;; "BitstreamVeraSansMono Nerd Font Mono-14" ((x-list-fonts "MesloLGS Nerd Font") "MesloLGS Nerd Font Mono-14") ((x-list-fonts "Dejavu Sans") "Dejavu Sans Mono-14") ((x-list-fonts "Hack Nerd Font") "Hack Nerd Font Mono-14") ((x-list-fonts "DroidSansMono Nerd Font") "DroidSansMono Nerd Font Mono-14") ((x-list-fonts "Fira Code") "Fira Code Mono-14") (t "9x15" nil))) ('error (set-font "9x15")))) (w32 (condition-case nil (set-font "Hack Nerd Font Mono-14") ('error nil))) (ns (condition-case nil ;;(set-font "BitstreamVeraSansMono Nerd Font Mono-14") ;;(set-font "DroidSansMono Nerd Font Mono-14") (set-font "Hack Nerd Font Mono-14") ('error (set-font "Menlo"))))))
Faces
;;------------------------------------------------------------------------------ ;;;; Environment: GUI: Faces ;;------------------------------------------------------------------------------ (init-message 3 "Environment: GUI: Faces") ;; ;; set faces ;; ;; white foreground on black background with yellow cursor ;; (custom-set-faces ;; `(default ((t (:foreground ,color-foreground :background ,color-background)))) ;; `(cursor ((t (:foreground ,color-background :background ,color-cursor))))) ;; ;; set faces ;; ;; green foreground on black background with yellow cursor ;; (custom-set-faces ;; `(default ((t (:foreground ,color-foreground :background ,color-background)))) ; green ;; `(cursor ((t (:foreground ,color-background :background ,color-cursor))))) ; yellow ;; transparant background (not on Macs) (defvar background-alpha 100 "Background transparency alpha percentage. Common values: 100 = none 90 = 10% transparency 85 = 15% transparency 80 = 20% transparency") (setq background-alpha (if (or window-system-mac window-system-windows) 100 ; 0% transparency 85)) ; 10% transparency (set-frame-parameter (selected-frame) 'alpha background-alpha) (add-to-list 'default-frame-alist (cons 'alpha background-alpha)) ;; set mouse color (set-mouse-color color-mouse)
Theme
;; ;;------------------------------------------------------------------------------ ;; ;;;; Environment Settings: GUI: Theme ;; ;;------------------------------------------------------------------------------ ;; (init-message 3 "Environment: GUI: Theme") ;; ;; flatland theme ;; ;; https://github.com/gchp/flatland-emacs ;; (use-package flatland-theme ;; :straight t ;; :init (load-theme 'flatland :no-error)) ;; ;; ;; darcula theme ;; ;; ;; https://github.com/ianyepan/jetbrains-darcula-emacs-theme ;; ;; (use-package jetbrains-darcula-theme ;; ;; :straight t ;; ;; :init (load-theme 'jetbrains-darcula :no-error)) ;; ;; ;; gruber-darker theme ;; ;; ;; https://github.com/rexim/gruber-darker-theme ;; ;; (use-package gruber-darker-theme ;; ;; :straight t ;; ;; :init (load-theme 'gruber-darker :no-error)) ;; ;; ;; dracula theme ;; ;; ;; https://draculatheme.com/emacs/ ;; ;; (use-package dracula-theme ;; ;; :straight t ;; ;; :init (load-theme 'dracula :no-error)) ;; ;; ;; material theme ;; ;; ;; https://github.com/cpaulik/emacs-material-theme ;; ;; (use-package material-theme ;; ;; :straight t ;; ;; :init (load-theme 'material :no-error)) ;; ;; material theme ;; ;; https://github.com/cpaulik/emacs-material-theme ;; ;; (use-package material-theme ;; ;; :load-path (lambda () (file-truename (expand-file-name "material-theme.el" local-modules-dir))) ;; ;; :init (load-theme 'material :no-error)) ;; ;; ;; zenburn theme ;; ;; ;; https://github.com/bbatsov/zenburn-emacs ;; ;; (use-package zenburn-theme ;; ;; :straight t ;; ;; :init ;; ;; (setq zenburn-override-colors-alist ; default values ;; ;; '(("zenburn-bg+05" . "#181818") ; #383838 ;; ;; ("zenburn-bg+1" . "#1f1f1f") ; #4f4f4f ;; ;; ("zenburn-bg+2" . "#2f2f2f") ; #5f5f5f ;; ;; ("zenburn-bg+3" . "#3f3f3f"))) ; #6f6f6f ;; ;; (load-theme 'zenburn :no-error)) ;; ;; ;; color-theme-sanityinc-tomorrow theme ;; ;; ;; https://github.com/purcell/color-theme-sanityinc-tomorrow ;; ;; (use-package color-theme-sanityinc-tomorrow ;; ;; :straight t ;; ;; :init (load-theme 'sanityinc-tomorrow-night :no-error)) ;; ;; ;; spacemacs-theme ;; ;; ;; https://github.com/nashamri/spacemacs-theme ;; ;; (use-package spacemacs-theme ;; ;; :straight t ;; ;; :init (load-theme 'spacemacs-dark :no-error)) ;; ;; ;; solarized theme ;; ;; ;; https://github.com/bbatsov/solarized-emacs ;; ;; (use-package solarized-theme ;; ;; :straight t ;; ;; :init ;; ;; ;; make the fringe stand out from the background ;; ;; ;;(setq solarized-distinct-fringe-background t) ;; ;; ;; do not change the font for some headings and titles ;; ;; (setq solarized-use-variable-pitch nil) ;; ;; ;; make the modeline high contrast ;; ;; ;;(setq solarized-high-contrast-mode-line t) ;; ;; ;; use less bolding ;; ;; (setq solarized-use-less-bold t) ;; ;; ;; use more italics ;; ;; ;;(setq solarized-use-more-italic t) ;; ;; ;; use less colors for indicators such as git:gutter, flycheck and similar ;; ;; ;;(setq solarized-emphasize-indicators nil) ;; ;; ;; do not change size of org-mode headlines (but keep other size-changes) ;; ;; (setq solarized-scale-org-headlines nil) ;; ;; ;; avoid all font-size changes ;; ;; (setq solarized-height-minus-1 1.0) ;; ;; (setq solarized-height-plus-1 1.0) ;; ;; (setq solarized-height-plus-2 1.0) ;; ;; (setq solarized-height-plus-3 1.0) ;; ;; (setq solarized-height-plus-4 1.0) ;; ;; ;; load theme ;; ;; (load-theme 'solarized-dark :no-error)) ;; ;; ;; doom themes ;; ;; (use-package doom-themes ;; ;; :straight t ;; ;; :custom ;; ;; (doom-themes-enable-bold t) ; if nil, bold is universally disabled ;; ;; (doom-themes-enable-italic t) ; if nil, italics is universally disabled ;; ;; (doom-themes-treemacs-theme "doom-atom") ; use "doom-colors" for less minimal icon theme ;; ;; :config ;; ;; (load-theme 'doom-one :no-error) ;; ;; ;;(load-theme 'doom-dracula :no-error) ;; ;; ;; enable flashing mode-line on errors ;; ;; (doom-themes-visual-bell-config) ;; ;; ;; enable custom neotree theme (all-the-icons must be installed) ;; ;; (doom-themes-neotree-config) ;; ;; ;; or for treemacs users ;; ;; (doom-themes-treemacs-config) ;; ;; ;; correct (and improve) org-mode's native fontification ;; ;; (doom-themes-org-config))
Modus Themes
Use dark Modus Theme, Vivendi. Color values are found in
modus-themes-vivendi-colors
.
;;------------------------------------------------------------------------------ ;;;; Environment: GUI: Modus Themes ;;------------------------------------------------------------------------------ (init-message 3 "Environment: GUI: Modus Themes") ;; modus themes ;; https://github.com/protesilaos/modus-themes/ (use-package modus-themes :straight (:type built-in) :demand t :bind ("<f2>" . modus-themes-toggle) :init ;; add customizations before loading (setq modus-themes-italic-constructs t modus-themes-bold-constructs nil modus-themes-mixed-fonts nil modus-themes-subtle-line-numbers nil modus-themes-intense-mouseovers nil modus-themes-deuteranopia t modus-themes-tabs-accented t modus-themes-variable-pitch-ui nil modus-themes-inhibit-reload t ; only applies to `customize-set-variable' and related modus-themes-fringes nil ; {nil,'subtle,'intense} ;; Options for `modus-themes-lang-checkers' are either nil (the ;; default), or a list of properties that may include any of those ;; symbols: `straight-underline', `text-also', `background', ;; `intense' OR `faint'. modus-themes-lang-checkers nil ;; Options for `modus-themes-mode-line' are either nil, or a list ;; that can combine any of `3d' OR `moody', `borderless', ;; `accented', a natural number for extra padding (or a cons cell ;; of padding and NATNUM), and a floating point for the height of ;; the text relative to the base font size (or a cons cell of ;; height and FLOAT) modus-themes-mode-line '(accented borderless (padding . 4) (height . 0.9)) ;; Same as above: ;; modus-themes-mode-line '(accented borderless 4 0.9) ;; Options for `modus-themes-markup' are either nil, or a list ;; that can combine any of `bold', `italic', `background', ;; `intense'. modus-themes-markup '(background italic) ;; Options for `modus-themes-syntax' are either nil (the default), ;; or a list of properties that may include any of those symbols: ;; `faint', `yellow-comments', `green-strings', `alt-syntax' ;;modus-themes-syntax nil modus-themes-syntax '(alt-syntax faint green-strings yellow-comments) ;; Options for `modus-themes-hl-line' are either nil (the default), ;; or a list of properties that may include any of those symbols: ;; `accented', `underline', `intense' ;;modus-themes-hl-line '(underline accented) modus-themes-hl-line '(intense) ;; Options for `modus-themes-paren-match' are either nil (the ;; default), or a list of properties that may include any of those ;; symbols: `bold', `intense', `underline' modus-themes-paren-match '(bold intense) ;; Options for `modus-themes-links' are either nil (the default), ;; or a list of properties that may include any of those symbols: ;; `neutral-underline' OR `no-underline', `faint' OR `no-color', ;; `bold', `italic', `background' modus-themes-links '(neutral-underline background) ;; Options for `modus-themes-box-buttons' are either nil (the ;; default), or a list that can combine any of `flat', `accented', ;; `faint', `variable-pitch', `underline', `all-buttons', the ;; symbol of any font weight as listed in `modus-themes-weights', ;; and a floating point number (e.g. 0.9) for the height of the ;; button's text. modus-themes-box-buttons '(variable-pitch flat faint 0.9) ;; Options for `modus-themes-prompts' are either nil (the ;; default), or a list of properties that may include any of those ;; symbols: `background', `bold', `gray', `intense', `italic' modus-themes-prompts '(intense bold) ;; The `modus-themes-completions' is an alist that reads three ;; keys: `matches', `selection', `popup'. Each accepts a nil ;; value (or empty list) or a list of properties that can include ;; any of the following (for WEIGHT read further below): ;; ;; `matches' - `background', `intense', `underline', `italic', WEIGHT ;; `selection' - `accented', `intense', `underline', `italic', `text-also' WEIGHT ;; `popup' - same as `selected' ;; `t' - applies to any key not explicitly referenced (check docs) ;; ;; WEIGHT is a symbol such as `semibold', `light', or anything ;; covered in `modus-themes-weights'. Bold is used in the absence ;; of an explicit WEIGHT. modus-themes-completions '((matches . (extrabold)) (selection . (semibold accented)) (popup . (accented intense))) modus-themes-mail-citations nil ; {nil,'intense,'faint,'monochrome} ;; Options for `modus-themes-region' are either nil (the default), ;; or a list of properties that may include any of those symbols: ;; `no-extend', `bg-only', `accented' ;;modus-themes-region '(bg-only no-extend) modus-themes-region nil ;; Options for `modus-themes-diffs': nil, 'desaturated, 'bg-only modus-themes-diffs 'desaturated ;;modus-themes-org-blocks 'gray-background ; {nil,'gray-background,'tinted-background} modus-themes-org-blocks nil ; {nil,'gray-background,'tinted-background} modus-themes-org-agenda ; this is an alist: read the manual or its doc string '((header-block . (variable-pitch 1.3)) (header-date . (grayscale workaholic bold-today 1.1)) (event . (accented varied)) (scheduled . uniform) (habit . traffic-light)) modus-themes-headings ; this is an alist: read the manual or its doc string ;; '((1 . (overline background variable-pitch 1.3)) ;; (2 . (rainbow overline 1.1)) ;; (t . (semibold))) ;;'((t . (rainbow))) '((t . ())) modus-themes-vivendi-color-overrides ; override some main colors `((bg-main . ,color-background) (fg-main . ,color-foreground))) ;; load theme files before enabling ;;(modus-themes-load-themes) ;;(load-theme 'modus-operandi :no-error) (load-theme 'modus-vivendi :no-error) :config ;;(modus-themes-load-operandi) (modus-themes-load-vivendi))
Footer
)
General
;;------------------------------------------------------------------------------ ;;; Environment: General ;;------------------------------------------------------------------------------ (init-message 2 "Environment: General")
Do not show the startup splash screen.
;; disable splash screen (setq inhibit-startup-screen t)
Load el files if newer than elc versions.
;; prefer newer el files over elc (setq load-prefer-newer t)
Hide the menu-bar. Use C-M-z to activate it.
;; hide menu-bar (use C-M-z to activate) (when (and (fboundp 'menu-bar-mode) menu-bar-mode) (menu-bar-mode -1))
Set default buffer mode to `text-mode'.
;; ;; set default buffer mode to `text-mode' ;; (setq initial-major-mode 'text-mode)
Set default buffer mode to `org-mode'.
;; set default buffer mode to `org-mode' (setq initial-major-mode 'org-mode)
Start with an empty \*scratch\* buffer.
;; clear scratch buffer (setq initial-scratch-message nil)
Set \*scratch\* buffer mode to `emacs-lisp-mode'.
;; ;; set scratch buffer mode to `emacs-lisp-mode' ;; (setq initial-major-mode 'emacs-lisp-mode)
Make backspace key work correctly.
;; make baskspace key work (normal-erase-is-backspace-mode 1)
Add some characters to word boundaries.
;; add underscore to word boundaries (modify-syntax-entry ?_ "w") ;; add dash to word boundaries (modify-syntax-entry ?- "w")
Add camel-case words to word boundaries.
;; add camel-case words to word boundaries (global-subword-mode 1)
Find open-paren at outermost level when searching for beginning of defuns.
See beginning-of-defun
for more information.
;; beginning of defun is outermost level open-paren (setq open-paren-in-column-0-is-defun-start nil defun-prompt-regexp nil)
Ignore comments when parsing s-expressions.
;; do not parse comments in sexp's (setq parse-sexp-ignore-comments t) (setq-default parse-sexp-ignore-comments parse-sexp-ignore-comments)
Wrap lines by default.
;; ;; wrap lines ;; (setq truncate-lines nil)
Do not wrap lines by default.
;; turn off line wrapping (setq truncate-lines t) (setq-default truncate-lines truncate-lines) (toggle-truncate-lines 1)
Auto-wrap longlines and show hard newlines.
;; ;; longlines (auto-wrap and show hard newlines) ;; (setq longlines-auto-wrap t ;; longlines-show-hard-newlines t)
Turn off auto-fill-mode
.
;; do not automatically break lines by inserting newlines (turn-off-auto-fill)
Turn on
visual-line-mode
as the default behavior.
;; ;; visually break lines that are longer than the screen width ;; (global-visual-line-mode 1) ;; ;; (defun buffer-menu-mode-hook--visual-line-mode() ;; ;; "Hook to turn on `visual-line-mode' in most buffers." ;; ;; (unless (string= (substring (buffer-name) 0 1) "*") ;; ;; (visual-line-mode 1))) ;; ;; (add-hook 'buffer-menu-mode-hook #'buffer-menu-mode-hook--visual-line-mode) ;; ;; use curly arrows to indicate a visual line wrap ;; (setq visual-line-fringe-indicators '(left-curly-arrow right-curly-arrow))
Turn off visual-line-mode
as the default behavior.
;; do not visually break lines that are longer than the screen width (global-visual-line-mode -1) ;; (defun buffer-menu-mode-hook--visual-line-mode() ;; "Hook to turn off `visual-line-mode' in most buffers." ;; (unless (string= (substring (buffer-name) 0 1) "*") ;; (visual-line-mode -1))) ;; (add-hook 'buffer-menu-mode-hook #'buffer-menu-mode-hook--visual-line-mode) ;; use curly arrows to indicate a visual line wrap (setq visual-line-fringe-indicators '(left-curly-arrow right-curly-arrow))
Set line number mode to relative as the default behavior.
;; when `display-line-numbers-mode' is on use relative numbering (setq display-line-numbers-type 'relative)
Prevent next-line
from inserting newlines. (This stops the cursor at the end
of the file.)
;; stop cursor at the end of the file (setq next-line-add-newlines nil)
Keep the cursor in the same column when using page-up and page-down.
;; keep screen position when using page-up and page-down (setq scroll-preserve-screen-position 'keep)
Only scroll one line at a time when moving past the edge of a window.
;; scroll one line at a time (setq scroll-step 1) ;; scroll fewer lines (setq scroll-conservatively 101) ;; scroll before reaching window edge (setq scroll-margin 2) ;; turn off vertical auto-scroll (setq auto-window-vscroll nil)
Searches and matches should ignore case.
;; make searches case-insensitive (setq case-fold-search t)
Highlight search matches.
;; ;; highlight search matches ;; (setq search-highlight t ;; query-replace-highlight t)
Do not Highlight search matches due to poor performance.
;; highlight search matches (setq search-highlight nil query-replace-highlight nil)
Highlight marked regions.
;; make current selection visible (transient-mark-mode 1) (setq-default transient-mark-mode transient-mark-mode)
Set default tab indentation and width to 4. Turn on auto-complete.
;; set tab indentation, width, and convert tabs to spaces (setq indent-tabs-mode nil ; do not insert tab characters tab-width 4 ; default tab width is four spaces standard-indent 4 ; default margin-changing functions indent tab-always-indent 'complete ; tab key will try to auto-complete after auto-tabbing line tab-stop-list (number-sequence 4 180 4)) ; tab stops set to every 4 spaces (setq-default indent-tabs-mode indent-tabs-mode tab-width tab-width standard-indent standard-indent tab-always-indent tab-always-indent tab-stop-list tab-stop-list)
Set default automatic line-wrapping column to 78. This is used with
auto-fill-mode
and the fill-paragraph
command.
;; custom fill-column value (defconst custom-fill-column 78 "Custom `fill-column' value.") ;; set default fill column for `auto-fill-mode' mode and `fill-paragraph' (setq fill-column custom-fill-column) (setq-default fill-column fill-column)
Display fill column indictator in programming modes.
;; display fill column indictator in programming modes (add-hook 'prog-mode-hook #'display-fill-column-indicator-mode)
Set default right-margin comment indent column to 40. Have
comment-fill-column
use the value of fill-column
.
;; set default comment column for in-line comments (setq comment-column 40) (setq-default comment-column comment-column) ;; set default comment fill column for in-line comments (setq comment-fill-column nil) (setq-default comment-fill-column comment-fill-column)
Have up and down cursor movements attempt to keep point on the original column.
;; turn on goal column support (put 'set-goal-column 'disabled nil)
Sentences and colons should have one space after them.
;; insert one space after a sentence when filling text (setq sentence-end-double-space nil) ;; insert one space after a colon when filling text (setq colon-double-space nil)
Sentences and colons should have two spaces after them.
;; ;; insert two spaces after a sentence when filling text ;; (setq sentence-end-double-space t) ;; ;; insert two spaces after a colon when filling text ;; (setq colon-double-space t)
Highlight matching parenthesis when the cursor is on one of them.
;; highlight matching parenthesis (show-paren-mode 1) (set-face-foreground 'show-paren-match color-paren) (set-face-attribute 'show-paren-match nil :weight 'extra-bold)
Highlight tabs.
;; highlight tabs (setq highlight-tabs t) (setq-default highlight-tabs highlight-tabs)
Highlight tabs and trailing whitespace.
(Can be anoying in buffers that have them on purpose.)
;; ;; highlight trailing white spaces ;; (setq show-trailing-whitespace t) ;; (setq-default show-trailing-whitespace show-trailing-whitespace) ;; highlight tabs and trailing white spaces (setq whitespace-style '(face trailing tab-mark)) (custom-set-faces `(whitespace-tab ((t (:foreground ,color-foreground :background ,color-background))))) (setq whitespace-display-mappings '((space-mark 32 [183] [46]) ; 32 space ' ', 183 middle dot '·', 46 full stop '.' (newline-mark 10 [182 10]) ; 10 linefeed '\n', 182 ??? '¶' (tab-mark 9 [9655 9] [92 9]))) ; 9 tab '\t', 9655 '▷', 92 backslash '\' (global-whitespace-mode 1) ; enable whitespace mode everywhere
Highlight current line.
;; highlight current line (hl-line-mode 1) (global-hl-line-mode 1)
Turn on syntax highlighting.
;; turn on global font lock mode and syntax highlighting (global-font-lock-mode 1) (setq font-lock-maximum-decoration t)
When text is highlighted, typing will replace the highlighted text.
;; replace highlighted text with typed text (delete-selection-mode 1)
Set commenting style to indent.
;; ;; set comment start (default) and padding ;; (setq comment-start "#" ;; comment-padding " ") ;; set comment style (setq comment-style 'indent)
Allow minibuffer commands to work in the minibuffer.
(setq enable-recursive-minibuffers t)
(minibuffer-depth-indicate-mode 1)
Set title bar to current buffer's file name.
;; ;; set current buffer's file name, and full path in title bar ;; (setq frame-title-format '("%b" (buffer-file-name ": %f")))
Have the apropos
command search all symbols and order by relevance.
;; make apropos command search all symbols (setq apropos-do-all t) ;; make apropos command list results by relevance (setq apropos-sort-by-scores t apropos-documentation-sort-by-scores t)
Display customize menu entries and tag names as symbols.
;; display customize menu entries and tag names as symbols (setq custom-unlispify-menu-entries nil custom-unlispify-tag-names nil) (setq-default custom-unlispify-menu-entries custom-unlispify-menu-entries custom-unlispify-tag-names custom-unlispify-tag-names)
Set default grep
command.
;; set grep command (setq grep-command "grep -n -H -i -r -e ")
Set email sources.
;; email settings (setq mail-sources `((pop :server "pop.gmail.com" :port 995 :user ,user-mail-address :connection ssl :leave t)))
Set default browser.
;; set default browser ;;(setq browse-url-browser-function #'browse-url-default-browser) ;;(setq browse-url-generic-program "x-www-browser") ;;(setq browse-url-generic-program "w3m") ;;(setq browse-url-generic-program "mozilla") ;;(setq browse-url-browser-function #'browse-url-generic) ;;(setq browse-url-browser-function #'eww-browse-url) ;;(setq browse-url-browser-function #'w3m-browse-url) (setq browse-url-browser-function #'browse-url-firefox browse-url-new-window-flag t browse-url-firefox-new-window-is-tab t) ;; set secondary browser (setq browse-url-secondary-browser-function #'browse-url-default-browser)
Make single character deletion commands (delete and backspace) delete an active region without saving to the kill ring.
;; when deleting an active region via single character deletion command, ;; do not save to kill ring (setq delete-active-region t)
Select help window on creation.
;; ;; select help window on creation ;; (setq help-window-select t)
Always recenter after
next-error
is called.
;; ;; recenter window after `next-error' ;; (setq next-error-recenter '(4)) ;; ;;(add-hook 'next-error-hook #'recenter :append)
Always recenter after occur-mode-goto-occurrence
is called.
;; always recenter after `occur-mode-goto-occurrence' (defun occur-mode-goto-occurrence--recenter (&optional arg) "Recenter when an `occur' result is selected." (recenter)) ;; advise `occur-mode-goto-occurrence' (advice-add 'occur-mode-goto-occurrence :after #'occur-mode-goto-occurrence--recenter)
Set time zones to use for display-time-world
.
;; set display-time-world time zones (setq display-time-world-list '(("Etc/UTC" "UTC") ("America/Los_Angeles" "San Diego") ("America/Chicago" "Minneapolis") ("America/New_York" "New York") ("Etc/GMT" "GMT") ("Europe/London" "London") ("Europe/Paris" "Paris") ("Asia/Tokyo" "Tokyo")))
System
;;------------------------------------------------------------------------------ ;;; Environment: System ;;------------------------------------------------------------------------------ (init-message 2 "Environment: System")
Optimize garbage collections.
;; reduce frequency of garbage collections ;; this is handled in the Start section so it can take effect earlier ;; (setq gc-cons-threshold (* 8 1024 1024)) ; default: 800000 ;; run garbage collections when Emacs is backgrounded (defun garbage-collect-maybe () "Run `garbage-collect' if Emacs does not have focus." (unless (frame-focus-state) (garbage-collect))) ;; advise `after-focus-change-function' (advice-add 'after-focus-change-function :after #'garbage-collect-maybe) ;; ;; run garbage collections when Emacs is idle ;; (cancel-function-timers #'garbage-collect) ;; (run-with-idle-timer 20 :refresh #'garbage-collect)
Allow Emacs to use a larger number of variable bindings and unwind protects.
;; set max variable bindings (setq max-specpdl-size 10000) ; default: 1300
Allow Emacs to use a larger number of recursions (depth) with eval
, apply
,
funcall
functions.
;; set max eval depth (setq max-lisp-eval-depth 10000) ; default: 600
Prevent the message log from getting too large.
;; set max message log size (setq message-log-max 10000) ; default: 1000
Increase the maximum size of history lists and remove duplicate entries.
;; set max history list size (setq history-length 250) ; default: 30 ;; remove duplicates from history lists (setq history-delete-duplicates t) ; default: nil
Increase the maximum size of the kill and mark rings.
;; set max kill ring size (setq kill-ring-max 100) ; default: 60 ;; set max mark ring size (setq mark-ring-max 32) ; default: 16
Make all calls to yes-or-no-p
use y-or-n-p
instead.
;; change all calls to `yes-or-no-p' to `y-or-n-p' ;; (fset 'yes-or-no-p 'y-or-n-p) (setq use-short-answers t)
Enable some functions that are disabled by default.
;; enable upercase region (C-x C-u) (put 'upcase-region 'disabled nil) ;; enable lowercase region (C-x C-l) (put 'downcase-region 'disabled nil) ;; enable narrow to region (put 'narrow-to-region 'disabled nil) ;; turn off the disabling of certain commands (setq disabled-command-function nil)
Turn off support for bidirectional languages to speed up screen drawing times.
Note: This breaks support for Arabic, Farsi, and Hebrew languages.
;; turn off bidirectional paragraph formatting (setq bidi-paragraph-direction 'left-to-right) (setq-default bidi-paragraph-direction bidi-paragraph-direction) ;; turn off bidirectional parentheses matching (when (version<= "27.1" emacs-version) (setq bidi-inhibit-bpa t)) ;; turn on `so-long-mode' for files with long lines to help with performance (when (version<= "27.1" emacs-version) (global-so-long-mode 1))
Silence advice redefinition warnings.
;; silence advice redefinition warnings (setq ad-redefinition-action 'accept) (setq-default ad-redefinition-action ad-redefinition-action)
Files
;;------------------------------------------------------------------------------ ;;; Environment: Files ;;------------------------------------------------------------------------------ (init-message 2 "Environment: Files")
General
;;------------------------------------------------------------------------------ ;;;; Environment: Files: General ;;------------------------------------------------------------------------------ (init-message 3 "Environment: Files: General") (use-package files :straight (:type built-in) :custom ;; do not make backup files (make-backup-files nil) (backup-inhibited t) ;; reuse existing buffers, following file links (find-file-existing-other-name t) ;; end files with a newline (require-final-newline t) ;; do not make auto-save files (auto-save-default nil) ;; disable auto-save list (auto-save-list-file-prefix nil) ;; delete auto-save files (delete-auto-save-files t) ;; enable file local variables (enable-local-variables t) ;; enable directory local variables (enable-dir-local-variables t) ;; ask user before evaluating local variables (enable-local-eval 'maybe) ;; increase maximum file size (in bytes) to open before confirmation is requested (large-file-warning-threshold (* 50 1000 1000)) ;; all backup files should go into the system temp directory (backup-directory-alist `(("." . ,temporary-file-directory))) ;; ask before closing emacs (kill-emacs-query-functions (cons (lambda () (yes-or-no-p "Really kill Emacs? ")) kill-emacs-query-functions)))
Prevent local variable prompt for some safe local variable values.
;; org-babel noweb start and end patterns are considered safe (add-to-list 'safe-local-variable-values '(org-babel-noweb-wrap-start . "{{")) (add-to-list 'safe-local-variable-values '(org-babel-noweb-wrap-end . "}}"))
Create directories in file path on file save.
(defun create-buffer-file-name-directory-if-needed () "Create `buffer-file-name' directory if it does not already exist." (when (and buffer-file-name (not (file-exists-p (file-name-directory buffer-file-name)))) (make-directory (file-name-directory buffer-file-name) t))) ;; create directories if needed on file save (add-hook 'before-save-hook #'create-buffer-file-name-directory-if-needed)
Delete trailing whitespace and newlines on file save.
;; delete trailing lines on call to `delete-trailing-whitespace' (setq delete-trailing-lines t) (defun delete-trailing-whitespace-if-not-read-only (&optional beg end) "Call `delete-trailing-whitespace' if current buffer is not read-only." (interactive (if (use-region-p) (list (region-beginning) (region-end)) (list nil nil))) (unless buffer-read-only (delete-trailing-whitespace beg end))) ;; delete trailing whitespace on save (add-hook 'before-save-hook #'delete-trailing-whitespace-if-not-read-only)
Make shell scripts executable when saving (and reset the buffer mode).
;; make shell scripts executable when saving (and reset the buffer mode) (when (fboundp 'executable-make-buffer-file-executable-if-script-p) (add-hook 'after-save-hook #'executable-make-buffer-file-executable-if-script-p))
File extensions for files that should save as DOS files.
;; set DOS file extensions (add-to-list 'file-coding-system-alist '("\\.ASM\\'" . dos)) (add-to-list 'file-coding-system-alist '("\\.BAT\\'" . dos)) (add-to-list 'file-coding-system-alist '("\\.DO\\'" . dos)) (add-to-list 'file-coding-system-alist '("\\.SYS\\'" . dos))
Version Control
;;------------------------------------------------------------------------------ ;;;; Environment: Files: Version Control ;;------------------------------------------------------------------------------ (init-message 3 "Environment: Files: Version Control") (use-package vc-hooks :straight (:type built-in) :custom ;; follow symlinks to version control files without asking or warning (vc-follow-symlinks t) ;; disable vc-git as it throws debugger errors when revert-buffer is called (vc-handled-backends nil))
Compression
;;------------------------------------------------------------------------------ ;;;; Environment: Files: Compression ;;------------------------------------------------------------------------------ (init-message 3 "Environment: Files: Compression") (use-package jka-cmpr-hook :straight (:type built-in) :custom ;; automatically uncompress and compress gzip/zip/jar/tar files (auto-compression-mode t))
Auto-Revert
Automatically revert buffers when the file they are visiting changes.
;;------------------------------------------------------------------------------ ;;;; Environment: Files: Auto-Revert ;;------------------------------------------------------------------------------ (init-message 3 "Environment: Files: Auto-Revert") (use-package autorevert :straight (:type built-in) :custom ;; turn on auto buffer revert mode (global-auto-revert-mode 1))
Bookmark
;;------------------------------------------------------------------------------ ;;;; Environment: Files: Bookmark ;;------------------------------------------------------------------------------ (init-message 3 "Environment: Files: Bookmark") (use-package bookmark :straight (:type built-in) :custom ;; auto-save bookmarks every time they change (bookmark-save-flag 1))
Desktop
Restore open buffers when Emacs is launched.
;;------------------------------------------------------------------------------ ;;;; Environment: Files: Desktop ;;------------------------------------------------------------------------------ (init-message 3 "Environment: Files: Desktop") (use-package desktop :straight (:type built-in) :custom (desktop-dirname user-emacs-directory) (desktop-save 'ask-if-new) (desktop-load-locked-desktop 'check-pid) (desktop-restore-eager 0) ; do not restore any buffers until all modules and modes have loaded (desktop-buffers-not-to-save (concat "\\(" "\\.log\\|(ftp)\\|^tags\\|^TAGS" "\\.diary\\|\\diary\\|\\.bbdb" "\\)$")) :init ;; desktop history ;; (when-lock-file-acquired (expand-file-name "emacs-desktop-history-lock-file" ;; temporary-file-directory) ;; (desktop-save-mode 1) ;; (add-to-list 'desktop-globals-to-save 'file-name-history t) ;; (add-to-list 'desktop-modes-not-to-save 'Info-mode t) ;; (add-to-list 'desktop-modes-not-to-save 'info-lookup-mode t) ;; ;;(add-to-list 'desktop-modes-not-to-save 'dired-mode t) ;; ;;(add-to-list 'desktop-modes-not-to-save 'fundamental-mode t) ;; )) (desktop-save-mode 1) (add-to-list 'desktop-globals-to-save 'file-name-history t) (add-to-list 'desktop-modes-not-to-save 'Info-mode t) (add-to-list 'desktop-modes-not-to-save 'info-lookup-mode t))
Minibuffer History
Save minibuffer history.
;;------------------------------------------------------------------------------ ;;;; Environment: Files: Minibuffer History ;;------------------------------------------------------------------------------ (init-message 3 "Environment: Files: Minibuffer History") (use-package savehist :straight (:type built-in) :custom (savehist-save-minibuffer-history 1) (savehist-additional-variables '(search-ring regexp-search-ring)) :init ;; save minibuffer history (when (fboundp 'savehist-mode) (when-lock-file-acquired (expand-file-name "emacs-minibuffer-history-lock-file" temporary-file-directory) (savehist-mode 1))))
Buffers and Windows
;;------------------------------------------------------------------------------ ;;; Environment: Buffers and Windows ;;------------------------------------------------------------------------------ (init-message 2 "Environment: Buffers and Windows")
Use C-<left> and C-<right> to undo/redo window changes.
;; allow undo/redo of window settings (when (fboundp 'winner-mode) (winner-mode 1))
Turn on
imenu
indexes. This parses the current buffer and adds an Index
menu item that has links to sections based on the buffer type.
TODO: This needs to be added to major mode hooks for modes where we want this feature. However, this can cause a loading delay.
;; ;; turn on imenu bar index ;; (imenu-add-menubar-index)
Delay buffer fontification to increase scroll speed.
;; delay buffer fontification to increase scroll speed (setq jit-lock-defer-time 0.05)
Preserve buffer point for each window.
;; preserve buffer point for each window (setq switch-to-buffer-preserve-window-point t)
Make mouse movement smoother.
;; smoother mouse movement (setq mouse-wheel-scroll-amount '(1 ((shift) . 5) ((control))))
Increase maximum mini-window height.
;; increase maximum mini-window height (setq max-mini-window-height 0.50)
Tabs
;;------------------------------------------------------------------------------ ;;; Environment: Tabs ;;------------------------------------------------------------------------------ (init-message 2 "Environment: Tabs") ;; regular tab width (defvar custom-tab-width 4 "Regular tab width.") ;; short tab width used for certain modes (defvar custom-short-tab-width 2 "Short tab width used for certain modes.") ;; set tabs (defun set-tabs (enable &optional width) "Set default tab settings. If ENABLED is non-nil, enable TAB characters. Otherwise, disable TAB characters. If WIDTH is given, it is used to set the TAB width. Otherwise, `custom-tab-width' is used." (let ((width (or width custom-tab-width))) (setq indent-tabs-mode enable ; whether to insert tab characters tab-width width ; set tab width standard-indent width ; set margin-changing functions indent tab-always-indent 'complete ; tab key will try to auto-complete after auto-tabbing line tab-stop-list (number-sequence width 180 width) ; set tab stops backward-delete-char-untabify-method nil))) ; backspace will just delete one character ;; backward-delete-char-untabify-method 'untabify))) ; backspace will turn a tab to many spaces, then delete one space ;; backward-delete-char-untabify-method 'hungry))) ; backspace will delete all whitespace, both tabs and spaces ;; disable tabs (defun disable-tabs (&optional width) "Disable TAB character usage, using WIDTH if given." (set-tabs nil width)) ;; enable tabs (defun enable-tabs (&optional width) "Enable TAB character usage, using WIDTH if given." (set-tabs t width)) ;; enable tabs 4 (defun enable-tabs-4 () "Enable TAB character usage with a width of 4 spaces." (set-tabs t 4)) ;; enable tabs 8 (defun enable-tabs-8 () "Enable TAB character usage with a width of 8 spaces." (set-tabs t 8))
Mode Line
Custom mode line mode. Replaced by doom-modeline
.
;; ;;------------------------------------------------------------------------------ ;; ;;; General Settings: Mode Line ;; ;;------------------------------------------------------------------------------ ;; (init-message 2 "Environment: Mode Line")
Show the day, date, and time in the mode line.
;; ;; turn on date and time in mode line ;; (setq display-time-day-and-date t) ;; (if (< emacs-major-version 26) ;; (setq display-time-string-forms ;; '(" " (format-time-string "%a %Y-%m-%d %H:%M") " ")) ;; (setq display-time-string-forms ;; '(" " (format-time-string "%a %Y-%m-%d %H:%M" nil (current-time-zone)) " "))) ;; (display-time-mode 1) ;; ;; ;; right-align date and time ;; ;; (display-time-mode 0) ;; ;; (setq global-mode-string (remove 'display-time-string global-mode-string)) ;; ;; (setq mode-line-end-spaces ;; ;; (list (propertize " " 'display '(space :align-to (- right 12))) ;; ;; 'display-time-string))
Show line number in the mode line.
;; ;; show line number in mode line ;; (line-number-mode 1)
Show column number in the mode line.
;; ;; show column number in mode line ;; (column-number-mode 1)
Set mode line format.
;; ;; set `mode-line-format' ;; (setq mode-line-format ;; '("%e" ;; mode-line-front-space ;; #("-" 0 1 (help-echo "mouse-1: select (drag to resize), mouse-2 = C-x 1, mouse-3 = C-x 0")) ;; mode-line-mule-info ; coding system, eol style, read-only status ;; mode-line-modified ; buffer modified status ;; mode-line-frame-identification ; frame name ;; mode-line-buffer-identification ; buffer name ;; #(" " 0 2 (help-echo "mouse-1: select (drag to resize), mouse-2 = C-x 1, mouse-3 = C-x 0")) ;; mode-line-position ; position in buffer as a percentage, line number, column number ;; ;; #(" w:" 0 3 (help-echo "mouse-1: select (drag to resize), mouse-2 = C-x 1, mouse-3 = C-x 0")) ;; ;; (count-words-paragraph count-words-paragraph) ; words in current paragraph ;; mode-line-projectile ; project information ;; (vc-mode vc-mode) ; version control information ;; #(" " 0 2 (help-echo "mouse-1: select (drag to resize), mouse-2 = C-x 1, mouse-3 = C-x 0")) ;; mode-line-modes ; major and minor modes ;; ;; (which-func-mode ;; ;; ("" which-func-format ;; ;; #("--" 0 2 (help-echo "mouse-1: select (drag to resize), mouse-2 = C-x 1, mouse-3 = C-x 0")))) ;; ;; (global-mode-string ;; ;; (#("--" 0 2 (help-echo "mouse-1: select (drag to resize), mouse-2 = C-x 1, mouse-3 = C-x 0")) ;; ;; global-mode-string)) ;; (global-mode-string ;; (#(" " 0 1 (help-echo "mouse-1: select (drag to resize), mouse-2 = C-x 1, mouse-3 = C-x 0")) ;; global-mode-string)) ; day, date, time ;; #("-%-" 0 3 (help-echo "mouse-1: select (drag to resize), mouse-2 = C-x 1, mouse-3 = C-x 0")) ;; mode-line-end-spaces)) ;; (set-default 'mode-line-format mode-line-format)
Set mode line for projectile-mode
.
;; (defvar mode-line-projectile ;; '(:eval (when (ignore-errors (projectile-project-root)) ;; (concat " " (projectile-project-name)))) ;; "Mode line format for `projectile'.") ;; ;; set mode line for `projectile-mode' ;; (put 'mode-line-projectile 'risky-local-variable t)
Set mode line for vc-mode
.
;; ;; strip backend name from the version control status information ;; (defvar mode-line-vc-mode ;; '(" " (:eval (let ((backend (symbol-name (vc-backend (or buffer-file-name (buffer-name)))))) ;; (substring vc-mode (+ (length backend) 2))))) ;; "Mode line format for `vc-mode'.") ;; ;; set mode line for `vc-mode' ;; (put 'mode-line-vc-mode 'risky-local-variable t)
Set mode line modes.
;; ;; set `mode-line-modes' ;; (setq mode-line-modes ;; '((#("%[(" 0 3 (help-echo "mouse-1: select (drag to resize), mouse-2 = C-x 1, mouse-3 = C-x 0")) ;; (:propertize ;; ("" mode-name) ;; help-echo "mouse-1: major mode, mouse-2: major mode help, mouse-3: toggle minor modes" ;; mouse-face mode-line-highlight local-map ;; (keymap ;; (mode-line keymap ;; (down-mouse-3 . mode-line-mode-menu-1) ;; (mouse-2 . describe-mode) ;; (down-mouse-1 . mouse-major-mode-menu)))) ;; ("" mode-line-process) ;; (:propertize ;; ("" minor-mode-alist) ;; mouse-face mode-line-highlight ;; help-echo "mouse-2: minor mode help, mouse-3: toggle minor modes" ;; local-map ;; (keymap ;; (header-line keymap ;; (down-mouse-3 . mode-line-mode-menu-1)) ;; (mode-line keymap ;; (down-mouse-3 . mode-line-mode-menu-1) ;; (mouse-2 . mode-line-minor-mode-help)))) ;; #("%n" 0 2 ;; (help-echo "mouse-2: widen" mouse-face mode-line-highlight local-map ;; (keymap ;; (mode-line keymap ;; (mouse-2 . mode-line-widen))))) ;; #(")%]" 0 3 ;; (help-echo "mouse-1: select (drag to resize), mouse-2 = C-x 1, mouse-3 = C-x 0"))))) ;; (set-default 'mode-line-modes mode-line-modes) ;; ;; (setcar (last (car mode-line-modes)) ;; ;; '#(")%]" 0 3 (help-echo "mouse-1: select (drag to resize), mouse-2 = C-x 1, mouse-3 = C-x 0")))
Add count words paragraph to mode line.
;; ;; ;;------------------------------------------------------------------------------ ;; ;; ;;;; Add Count Words Paragraph To Mode Line ;; ;; ;;------------------------------------------------------------------------------ ;; ;; (init-message 3 "Count Words") ;; ;; ;; store count in variable ;; ;; (defvar count-words-paragraph nil ;; ;; "*Current value returned from `count-words-paragraph' function.") ;; ;; ;; only setup timer once ;; ;; (unless count-words-paragraph ;; ;; ;; seed count-words-paragraph ;; ;; (setq count-words-paragraph "0 ") ;; ;; ;; create timer to keep count-words-paragraph updated ;; ;; (run-with-idle-timer 0.5 :refresh ;; ;; (lambda () ;; ;; (let ((count (number-to-string (count-words-paragraph)))) ;; ;; (while (< (length count) 3) ;; ;; (setq count (concat count " "))) ;; ;; (setq count-words-paragraph count))))) ;; ;; ;; add count words paragraph the mode line ;; ;; (unless (and (listp (nth 8 mode-line-format)) ;; ;; (memq 'count-words-paragraph (nth 8 mode-line-format))) ;; ;; (push (cons '#(" w:" 0 3 (help-echo "mouse-1: select (drag to resize), mouse-2 = C-x 1, mouse-3 = C-x 0")) ;; ;; '(count-words-paragraph)) ;; ;; (nthcdr 8 mode-line-format))) ;; ;; ;; set mode line ;; ;; (set-default 'mode-line-format mode-line-format)
Terminals
Customizations for the various terminal modes in Emacs.
;;------------------------------------------------------------------------------ ;;; Environment: Terminals ;;------------------------------------------------------------------------------ (init-message 2 "Environment: Terminals")
Configuration
;;------------------------------------------------------------------------------ ;;;; Environment: Terminals: Configuration ;;------------------------------------------------------------------------------ (init-message 3 "Environment: Terminals: Configuration") (setq custom-terminal-history-size 10000 custom-terminal-maximum-lines 10000)
eshell
;;------------------------------------------------------------------------------ ;;;; Environment: Terminals: eshell ;;------------------------------------------------------------------------------ (init-message 3 "Environment: Terminals: eshell") (defun custom-eshell-first-time-mode-hook () ;; save command history (add-hook 'eshell-pre-command-hook #'eshell-save-some-history) ;; truncate history for performance (add-to-list 'eshell-output-filter-functions #'eshell-truncate-buffer)) (use-package eshell :straight (:type built-in) :hook (eshell-first-time-mode . custom-eshell-first-time-mode-hook) ;; :bind (:map eshell-mode-map ;; ([remap beginning-of-line] . eshell-bol) ;; ([remap move-beginning-of-line] . eshell-bol) ;; ("C-r" . counsel-esh-history)) :custom (eshell-history-size custom-terminal-history-size) (eshell-buffer-maximum-lines custom-terminal-maximum-lines) (eshell-hist-ignoredups t) (eshell-scroll-to-bottom-on-input t) :config (setenv "PAGER" "cat") ; less does not work well inside Emacs (with-eval-after-load "esh-opt" (setq eshell-destroy-buffer-when-process-dies t eshell-visual-commands '("htop" "ssh" "vim" "zsh")))) (use-package eshell-git-prompt :straight t :after (eshell) :config (eshell-git-prompt-use-theme 'powerline))
term-bash
;;------------------------------------------------------------------------------ ;;;; Environment: Terminals: term-bash ;;------------------------------------------------------------------------------ (init-message 3 "Environment: Terminals: term-bash") (defun term-bash () "Start a BASH terminal-emulator in a new buffer." (interactive) (term "/bin/bash"))
term-zsh
;;------------------------------------------------------------------------------ ;;;; Environment: Terminals: term-zsh ;;------------------------------------------------------------------------------ (init-message 3 "Environment: Terminals: term-zsh") (defun term-zsh () "Start a ZSH terminal-emulator in a new buffer." (interactive) (term "/bin/zsh"))
vterm
Loading this causes features.h, cdefs.h, and c++config.h files to load into buffers.
;; ;;------------------------------------------------------------------------------ ;; ;;;; Environment: Terminals: vterm ;; ;;------------------------------------------------------------------------------ ;; (init-message 3 "Environment: Terminals: vterm") ;; (use-package vterm ;; :straight t ;; :commands (vterm) ;; :custom ;; (vterm-max-scrollback custom-terminal-maximum-lines) ;; (vterm-kill-buffer-on-exit nil))
Bookmarks
Emacs Bookmarks
;;------------------------------------------------------------------------------ ;;; Environment: Bookmarks ;;------------------------------------------------------------------------------ (init-message 2 "Environment: Bookmarks")
;;;; Emacs Bookmark Format Version 1;;;; -*- coding: utf-8-emacs; mode: lisp-data -*- ;;; -*- End Of Bookmark File Format Version Stamp -*- ( ;; Gopher: Search ("Gopherpedia" (location . "gopher://gopherpedia.com/1") (handler . elpher-bookmark-jump)) ;; Gopher: News ("Gopher Project" (location . "gopher://gopherproject.org/1") (handler . elpher-bookmark-jump)) ("Hacker News" (location . "gopher://hngopher.com/1") (handler . elpher-bookmark-jump)) ("Weather Forecasts" (location . "gopher://gopher.floodgap.com/1/groundhog") (handler . elpher-bookmark-jump)) ;; Gopher: Repositories ("Floodgap Systems" (location . "gopher://gopher.floodgap.com/1") (handler . elpher-bookmark-jump)) ("Quux" (location . "gopher://quux.org/1") (handler . elpher-bookmark-jump)) ("TEXTFILES" (location . "gopher://0x1bi.net/1/textfiles") (handler . elpher-bookmark-jump)) ;; Gopher: Popular ("SDF Public Access UNIX System" (location . "gopher://sdf.org/1") (handler . elpher-bookmark-jump)) ("Gopher Club" (location . "gopher://gopher.club/1/phlogs/") (handler . elpher-bookmark-jump)) ("Zaibatsu" (location . "gopher://zaibatsu.circumlunar.space/1") (handler . elpher-bookmark-jump)) ("Baud Baby" (location . "gopher://baud.baby/1") (handler . elpher-bookmark-jump)) ("EyeBlea" (location . "gopher://eyeblea.ch/1") (handler . elpher-bookmark-jump)) ("Final Zone" (location . "gopher://finalzone.ddns.net/1") (handler . elpher-bookmark-jump)) ("20 For Beers" (location . "gopher://20ForBeers.com/1") (handler . elpher-bookmark-jump)) ("Bitreich" (location . "gopher://bitreich.org/1") (handler . elpher-bookmark-jump)) ;; Gopher: Esoteric ("Gopherus Author" (location . "gopher://gopher.viste.fr/1") (handler . elpher-bookmark-jump)) ("Elpher" (location . "gopher://thelambdalab.xyz/1/projects/elpher/") (handler . elpher-bookmark-jump)) ("Klondike Solitaire" (location . "gopher://worldofsolitaire.com/") (handler . elpher-bookmark-jump)) ("Plan9 Project (jrsharp, L29)" (location . "gopher://frstcomputer.com/") (handler . elpher-bookmark-jump)) ;; Gopher: Personal ("Nullman" (location . "gopher://nullman.net/1") (handler . elpher-bookmark-jump)) ("kurisu (L29)" (location . "gopher://eyeblea.ch/1/~kurisu") (handler . elpher-bookmark-jump)) ;;("fluxcap (L29) ???" (location . "gopher://fluxcap.synchro.net:5070/1") (handler . elpher-bookmark-jump)) ("nkeck72 (L29)" (location . "gopher://gopher.nkeck72.xyz/1") (handler . elpher-bookmark-jump)) ("MeatLoTioN (Lunduke)" (location . "gopher://gopher.erb.pw/1") (handler . elpher-bookmark-jump)) ;;("fputs (Lunduke) ???" (location . "gopher://fputs.com/1") (handler . elpher-bookmark-jump)) ("Nepsis (Lunduke)" (location . "gopher://bpfh.space") (handler . elpher-bookmark-jump)) ;; Gemini ("Haiku" (location . "gemini://lofi.haiku-os.org/") (handler . elpher-bookmark-jump)) ("Project Gemini" (location . "gemini://gemini.circumlunar.space/") (handler . elpher-bookmark-jump)) ("Planet m68k" (location . "gemini://m68k.info/") (handler . elpher-bookmark-jump)) ;;("System Crafters" (location . "gemini://systemcrafters.cc") (handler . elpher-bookmark-jump)) ;;("Writing a Gemini Server" (location . "gemini://bcalderon.io/writing-a-gemini-server") (handler . elpher-bookmark-jump)) ("Zerock (L29)" (location . "gemini://retro.inetcc.org/~zerock/") (handler . elpher-bookmark-jump)) )
Key Bindings
;;============================================================================== ;;; Key Bindings ;;============================================================================== (init-message 1 "Key Bindings")
System Keys
;;------------------------------------------------------------------------------ ;;; Key Bindings: System Keys ;;------------------------------------------------------------------------------ (init-message 2 "Key Bindings: System Keys") (defun custom-key-bindings-system-keys () "Set custom system key bindings." (cond ;; most of these are already set correctly for MacOS (window-system-mac ;; new buffer (when (fboundp 'new-scratch) (bind-keys* ("s-t" . new-scratch)))) ((or window-system-linux window-system-windows) ;; cut (if (fboundp 'kill-region-or-word) (bind-keys* ("s-x" . kill-region-or-word)) (bind-keys* ("s-x" . kill-region))) ;; copy (bind-keys* ("s-c" . kill-ring-save)) ;; paste (bind-keys* ("s-v" . yank)) ;; undo (bind-keys* ("s-z" . undo)) ;; redo (when (fboundp 'undo-tree-redo) (bind-keys* ("s-y" . undo-tree-redo))) ;; select all (bind-keys* ("s-a" . mark-whole-buffer)) ;; find (bind-keys* ("s-f" . isearch-forward)) ;; find next (bind-keys* ("s-g" . isearch-forward)) ;; find previous (bind-keys* ("s-r" . isearch-backward)) ;; open file (bind-keys* ("s-o" . find-file)) ;; print (bind-keys* ("s-p" . print-buffer)) ;; save buffer (if (fboundp 'save-buffer-always) (bind-keys* ("s-s" . save-buffer-always)) (bind-keys* ("s-s" . save-buffer))) ;; new buffer (when (fboundp 'new-scratch) (bind-keys* ("s-t" . new-scratch))) ;; close buffer (bind-keys* ("s-w" . kill-current-buffer)) ;; set mark (bind-keys* ("s-SPC" . set-mark-command))))) (init-message 3 "custom-key-bindings-system-keys") (custom-key-bindings-system-keys)
Function Keys
;;------------------------------------------------------------------------------ ;;; Key Bindings: Function Keys ;;------------------------------------------------------------------------------ (init-message 2 "Key Bindings: Function Keys") (defun custom-key-bindings-function-keys () "Set custom function key bindings." (when (fboundp 'help-for-help) (bind-keys ("<f1>" . help-for-help))) (when (fboundp 'help-command) (bind-keys ("S-<f1>" . help-command))) (when (fboundp 'kmacro-start-macro-or-insert-counter) (bind-keys ("<f3>" . kmacro-start-macro-or-insert-counter))) ; default: `kmacro-start-macro-or-insert-counter' (when (fboundp 'kmacro-end-or-call-macro) (bind-keys ("<f4>" . kmacro-end-or-call-macro))) ; default: `kmacro-end-or-call-macro' (when (fboundp 'define-word-at-point-after-spell-check) (bind-keys ("<f5>" . define-word-at-point-after-spell-check))) (when (fboundp 'define-word-after-spell-check) (bind-keys ("S-<f5>" . define-word-after-spell-check))) ;; (when (fboundp 'ispell-word) ;; (bind-keys ("<f6>" . ispell-word))) ;; (when (fboundp 'ispell) ;; (bind-keys ("<S-f6>" . ispell))) (when (fboundp 'web-query-symbol-by-mode-at-point) (bind-keys ("<f7>" . web-query-symbol-by-mode-at-point))) ;; (when (fboundp 'web-query-word-at-point) ;; (bind-keys ("<f7>" . web-query-word-at-point))) (when (fboundp 'web-query) (bind-keys ("<S-f7>" . web-query))) (when (fboundp 'neotree) (bind-keys ("<f8>" . neotree))) (when (fboundp 'cycle-buffer-backward) (bind-keys ("<f9>" . cycle-buffer-backward))) (when (fboundp 'cycle-buffer-backward-permissive) (bind-keys ("S-<f9>" . cycle-buffer-backward-permissive))) (when (fboundp 'cycle-buffer) (bind-keys ("<f10>" . cycle-buffer))) ; default: `tmm-menubar' (when (fboundp 'cycle-buffer-permissive) (bind-keys ("S-<f10>" . cycle-buffer-permissive))) ;; normally f11 and f12 are left for screen to use (unbind-key "<f11>") ; default: `toggle-frame-fullscreen' (unbind-key "<f12>")) (init-message 3 "custom-key-bindings-function-keys") (custom-key-bindings-function-keys)
Extended Keys
;;------------------------------------------------------------------------------ ;;; Key Bindings: Extended Keys ;;------------------------------------------------------------------------------ (init-message 2 "Key Bindings: Extended Keys") (defun custom-key-bindings-extended-keys () "Set custom extended key bindings." ;; ;; turn off insert key ;; (unbind-key "<insert>") ; default: `overwrite-mode' ;; ;; window move ;; (when (fboundp 'windmove-left) ;; ;; shift arrow keys ;; (bind-keys ("S-<left>" . windmove-left) ;; ("S-<right>" . windmove-right) ;; ("S-<up>" . windmove-up) ;; ("S-<down>" . windmove-down))) ;; beginning of line (bind-keys* ("<home>" . beginning-of-line)) ; default: `move-beginning-of-line' ;; end of line (bind-keys* ("<end>" . end-of-line)) ; default: `move-end-of-line' ;; beginning of buffer (bind-keys* ("C-<home>" . beginning-of-buffer)) ;; end of buffer (bind-keys* ("C-<end>" . end-of-buffer))) (init-message 3 "custom-key-bindings-extended-keys") (custom-key-bindings-extended-keys)
Movement Keys
;;------------------------------------------------------------------------------ ;;; Key Bindings: Movement Keys ;;------------------------------------------------------------------------------ (init-message 2 "Key Bindings: Movement Keys") (defun custom-key-bindings-movement-keys (&optional keymap) "Set custom movement key bindings on KEYMAP. KEYMAP defaults to `override-global-map'." (let ((keymap (or keymap override-global-map))) ;; cursor movement keys (short, single character) (bind-keys* :map keymap ;;("<up>" . previous-line) ; default: `previous-line' ;;("<down>" . next-line) ; default: `next-line' ;;("<left>" . left-char) ; default: `left-char' ;;("<right>" . right-char) ; default: `right-char' ("M-i" . previous-line) ; default: `tab-to-tab-stop' ("C-p") ("M-k" . next-line) ; default: `kill-sentence' ("C-n") ("M-j" . left-char) ; default: `indent-new-comment-line' ("C-f") ("M-l" . right-char)) ; default: `downcase-word' ("C-b") ;; cursor movement keys (medium, multi-character) (bind-keys* :map keymap ("C-<up>" . backward-paragraph) ; default: `backward-paragraph' ("C-<down>" . forward-paragraph) ; default: `forward-paragraph' ("C-<left>" . left-word) ; default: `left-word' ("C-<right>" . right-word) ; default: `right-word' ("C-M-u" . backward-paragraph) ; default: `backward-up-list' ("C-M-o" . forward-paragraph) ; default: `split-line' ("M-u" . left-word) ; default: `upcase-word' ("M-o" . right-word)) ; default: `facemenu-keymap' ;; cursor movement keys (long, multi-character) (bind-keys* :map keymap ("C-M-<up>" . scroll-down-command) ; default: `scroll-down-command' ("C-M-<down>" . scroll-up-command) ; default: `scroll-up-command' ("C-M-<left>" . move-beginning-of-line) ; default: `move-beginning-of-line' ("C-M-<right>" . move-end-of-line) ; default: `move-end-of-line' ("C-M-i" . scroll-down-command) ; default: `completion-at-point' ("<prior>") ("C-M-k" . scroll-up-command) ; default: `kill-whole-line' ("<next>") ("C-M-j" . move-beginning-of-line) ; default: `default-indent-new-line' ("C-a") ("C-M-l" . move-end-of-line)) ; default: `reposition-window' ("C-e") ;; window movement keys (bind-keys* :map keymap ("C-x <up>" . windmove-up) ("C-x <down>" . windmove-down) ("C-x <left>" . windmove-left) ; default: `previous-buffer' ("C-x <right>" . windmove-right) ; default: `next-buffer' ("C-x C-<up>" . windmove-up) ("C-x C-<down>" . windmove-down) ("C-x C-<left>" . windmove-left) ; default: `previous-buffer' ("C-x C-<right>" . windmove-right) ; default: `next-buffer' ("C-x M-i" . windmove-up) ("C-x M-k" . windmove-down) ("C-x M-j" . windmove-left) ("C-x M-l" . windmove-right)) ;; window resize keys (when (fboundp 'window-shrink-vertically) (bind-keys :map keymap ("C-M-S-i" . window-shrink-vertically))) (when (fboundp 'window-enlarge-vertically) (bind-keys :map keymap ("C-M-S-k" . window-enlarge-vertically))) (when (fboundp 'window-shrink-horizontally) (bind-keys :map keymap ("C-M-S-j" . window-shrink-horizontally))) (when (fboundp 'window-enlarge-horizontally) (bind-keys :map keymap ("C-M-S-l" . window-enlarge-horizontally))) ;; move line up (when (fboundp 'move-line-up) (bind-keys* :map keymap ("M-[" . move-line-up))) ;; move line down (when (fboundp 'move-line-down) (bind-keys* :map keymap ("M-]" . move-line-down))))) (init-message 3 "custom-key-bindings-movement-keys") (custom-key-bindings-movement-keys)
Standard Keys
;;------------------------------------------------------------------------------ ;;; Key Bindings: Standard Keys ;;------------------------------------------------------------------------------ (init-message 2 "Key Bindings: Standard Keys") (defun custom-key-bindings-standard-keys () "Set custom standard key bindings." ;; newline (when (fboundp 'insert-line-below) (bind-keys ("C-M-<return>" . insert-line-below))) ;; set mark (bind-keys ("C-SPC" . set-mark-command)) ; default: `set-mark-command' ;; set rectangle mark (when (fboundp 'cua-set-rectangle-mark) (bind-keys ("C-x rm" . cua-set-rectangle-mark) ("C-M-SPC" . cua-set-rectangle-mark))) ; default: `mark-sexp' ;; yank as rectangle (when (fboundp 'yank-as-rectangle) (bind-keys ("C-x r C-y" . yank-as-rectangle))) ;; (bind-keys ("C-x r C-y" . yank-as-rectangle) ;; ("C-M-y" . yank-as-rectangle))) ;; just one space (when (fboundp 'just-one-space) (bind-keys ("C-x C-SPC" . just-one-space))) ; default: `pop-global-mark' ;; help (bind-keys ("C-x C-h" . help-command) ("C-x ?" . help)) ;; describe function or variable at point (when (fboundp 'describe-function-or-variable-at-point) (bind-keys ("C-h z" . describe-function-or-variable-at-point) ("C-x C-h z" . describe-function-or-variable-at-point))) ;; shortdoc (when (fboundp 'shortdoc-display-group) (bind-keys ("C-h D" . shortdoc-display-group) ("C-x C-h D" . shortdoc-display-group))) ;; ;; smart M-x ;; (when (fboundp 'smex) ;; (bind-keys ("M-x" . smex))) ; default: `execute-extended-command' ;; (when (fboundp 'smex-major-mode-commands) ;; (bind-keys ("M-X" . smex-major-mode-commands))) ; default: `execute-extended-command' ;; ;; alternates for M-x ;; (bind-keys ("C-x C-m" . execute-extended-command)) ; default: Prefix Command ;; menubar (when (fboundp 'tmm-menubar) (bind-keys ("C-M-z" . tmm-menubar))) ;; force save maybe (when (fboundp 'save-buffer-always-maybe) (bind-keys ("C-x C-s" . save-buffer-always-maybe))) ; default: `save-buffer' ;; ;; bs-show (buffer select) ;; (when (fboundp 'bs-show) ;; (bind-keys ("C-x C-b" . bs-show))) ; default: `list-buffers' ;; cycle to previous buffer (bind-keys ("C-`" . mode-line-other-buffer)) ;; bury buffer (bind-keys ("C-c y" . bury-buffer)) (bind-keys ("C-c C-y" . bury-buffer)) ; default: `org-evaluate-time-range' ;; revert buffer (bind-keys ("C-c r" . revert-buffer)) (bind-keys ("C-c C-r" . revert-buffer)) ;; diff buffer (bind-keys ("C-c d" . diff-current-buffer)) ;; mark full word (when (fboundp 'mark-full-word) (bind-keys ("M-@" . mark-full-word))) ; default: `mark-word' ;; ;; expand region ;; (when (fboundp 'er/expand-region) ;; (bind-keys ("C-=" . er/expand-region) ; default: `count-lines-region' ;; ("C-+" . er/contract-region) ; default: `count-lines-region' ;; ("C-M-SPC" . er/expand-region) ; default: `mark-sexp' ;; ("C-M-S-SPC" . er/contract-region))) ;; regexp replace (bind-keys ("M-&" . replace-regexp)) ; default: `async-shell-command' ;; insert menu prompt (when (fboundp 'insert-menu-prompt) (bind-keys ("C-x i" . insert-menu-prompt))) ; default: `insert-file' ;; split windows (bind-keys ("M-1" . delete-other-windows)) ; default: `digit-argument' (bind-keys ("M-2" . split-window-horizontally)) ; default: `digit-argument' (bind-keys ("M-3" . split-window-vertically)) ; default: `digit-argument' (unbind-key "M-4") ; default: `digit-argument' (if (fboundp 'swap-windows) (bind-keys ("M-4" . swap-windows))) ; default: `digit-argument' (unbind-key "M-5") ; default: `digit-argument' (when (fboundp 'toggle-window-split) (bind-keys ("M-5" . toggle-window-split))) ; default: `split-line' (bind-keys ("M-6" . switch-to-buffer-other-window)) ; default: `digit-argument' (unbind-key "M-7") ; default: `digit-argument' (unbind-key "M-8") ; default: `digit-argument' (unbind-key "M-8") ; default: `digit-argument' (when (fboundp 'kill-other-window-buffer) (bind-keys ("M-8" . kill-other-window-buffer))) ; default: `digit-argument' (unbind-key "M-9") ; default: `digit-argument' (when (fboundp 'kill-other-window-buffer-and-delete-window) (bind-keys ("M-9" . kill-other-window-buffer-and-delete-window))) ; default: `digit-argument' (bind-keys ("M-0" . delete-window)) ; default: `digit-argument' ;; switch windows ;; (bind-keys ("M-o" . other-window)) ; default: `facemenu-keymap' (when (fboundp 'ace-window) (bind-keys ("C-x o" . ace-window))) ; default: `other-window' ;; swap windows (when (fboundp 'swap-windows) (bind-keys ("C-x C-o" . swap-windows))) ; default: `delete-blank-lines' ;; toggle window split (when (fboundp 'toggle-window-split) (bind-keys ("C-x M-o" . toggle-window-split))) ; default: `split-line' ;; toggle truncate lines (bind-keys ("C-$" . toggle-truncate-lines)) ;; kill current buffer (bind-keys ("C-x C-k" . kill-current-buffer)) ; default: `kmacro-keymap' ;; delete to end of line (when (fboundp 'delete-to-end-of-line) (bind-keys ("C-k" . delete-to-end-of-line))) ; default: `kill-line' ;; delete line (when (fboundp 'delete-line) (bind-keys ("C-M-d" . delete-line))) ; default: `down-list' ;; delete word (when (fboundp 'delete-word) (bind-keys ("M-d" . delete-word))) ; default: `kill-word' (when (fboundp 'backward-delete-word) (bind-keys ("C-<backspace>" . backward-delete-word))) ; default: `backward-kill-word' ;; copy line (when (fboundp 'copy-line) (bind-keys ("C-x C-y" . copy-line))) ;; cut line (when (fboundp 'cut-line) (bind-keys ("C-x M-y" . cut-line))) ;; duplicate line (when (fboundp 'duplicate-line) (bind-keys ("C-x C-d" . duplicate-line))) ; default: `list-directory' ;; ;; kill ring browser ;; (when (fboundp 'browse-kill-ring) ;; (bind-keys ("C-M-y" . browse-kill-ring))) ;; join line ;;(bind-keys ("C-M-j" . join-line)) ; default: `comment-indent-new-line' (bind-keys ("C-x C-j" . join-line)) ;; join next line (when (fboundp 'join-next-line) ;;(bind-keys ("M-j" . join-next-line))) ; default: `indent-new-comment-line' (bind-keys ("C-x j" . join-next-line))) ; also: `dired-jump' ;; enhanced titleize-word (when (fboundp 'titleize-word-enhanced) (bind-keys ("M-t" . titleize-word-enhanced)) ; default: `transpose-words' (bind-keys ("M-T" . titleize-line-or-region))) ;; describe text properties (bind-keys ("C-x M-p" . describe-text-properties)) ;; undo (bind-keys ("C-_" . undo)) ;; undo-redo (bind-keys ("M-_" . undo-redo)) ;; goto last change (undo) (when (fboundp 'goto-last-change) (bind-keys ("C-x C-_" . goto-last-change))) ;; jump to matching parenthesis (when (fboundp 'match-paren) (bind-keys ("M-(" . match-paren))) ;; evaluate current sexp (bind-keys ("C-x C-e" . eval-current-sexp)) ; default: `eval-last-sexp' ;; \C-\M-x defaults to `eval-defun' ;; evaluate all sexp's in current buffer (when (fboundp 'eval-sexp-buffer) (bind-keys ("C-x M-e" . eval-sexp-buffer))) ;; ;; indent current sexp ;; (bind-keys ("C-M-q" . indent-current-sexp)) ; default: `indent-sexp' or `indent-pp-sexp' ;; ;; indent all sexp's in current buffer ;; (when (fboundp 'indent-sexp-buffer) ;; (bind-keys ("C-x M-q" . indent-sexp-buffer))) ;; comment and uncomment sexp's (when (fboundp 'comment-or-uncomment-sexp) (define-key emacs-lisp-mode-map (kbd "C-M-;") 'comment-or-uncomment-sexp)) ;; indent region or thing (when (fboundp 'indent-region-or-thing) (bind-keys ("C-M-\\" . indent-region-or-thing))) ; default: `indent-region' ;; append equal characters up to column 80 (when (fboundp 'append-equal-to-column-80) (bind-keys ("C-c =" . append-equal-to-column-80))) ;; append dash characters up to column 80 (when (fboundp 'append-dash-to-column-80) (bind-keys ("C-c -" . append-dash-to-column-80))) ;; append asterisk characters up to column 80 (when (fboundp 'append-asterisk-to-column-80) (bind-keys ("C-c 8" . append-asterisk-to-column-80)) (bind-keys ("C-c *" . append-asterisk-to-column-80))) ;; add lisp comment block (equal) (when (fboundp 'insert-lisp-comment-block-equal) (bind-keys ("C-c C-=" . insert-lisp-comment-block-equal))) ;; add lisp comment block (dash) (when (fboundp 'insert-lisp-comment-block-dash) (bind-keys ("C-c C--" . insert-lisp-comment-block-dash))) ;; align commands (bind-keys ("C-c |" . align-current)) ;; ;; hippie expand ;; (when (fboundp 'hippie-expand) ;; (bind-keys ("M-/" . hippie-expand))) ; default: `dabbrev-expand' ;; ;; complete tag ;; (when (fboundp 'complete-tag) ;; (bind-keys ("C-M-/" . complete-tag))) ;; unset set-fill-column (unbind-key "C-x f") ; default: `set-fill-column' ;; compare windows (when (fboundp 'compare-windows) (bind-keys ("C-c C-w" . compare-windows))) ;; unfill paragraph (when (fboundp 'unfill-paragraph) (bind-keys ("M-Q" . unfill-paragraph))) ; default: `fill-paragraph' ;; ;; double-space punctuation ;; (when (fboundp 'double-space-punctuation) ;; (bind-keys ("C-M-q" . double-space-punctuation))) ;; toggle pop-up shell (when (and (fboundp 'pop-up-shell) (fboundp 'pop-up-shell-toggle)) (bind-keys ("C-x C-]" . pop-up-shell-toggle))) ;; describe character under cursor (bind-keys ("C-x _" . describe-char))) (init-message 3 "custom-key-bindings-standard-keys") (custom-key-bindings-standard-keys)
Modes and Module Keys
;;------------------------------------------------------------------------------ ;;; Key Bindings: Modes and Module Keys ;;------------------------------------------------------------------------------ (init-message 2 "Key Bindings: Modes and Module Keys") (defun custom-key-bindings-modes-and-modules-keys () "Set custom modes and modules key bindings." ;; diary (when (fboundp 'diary) (bind-keys ("C-x y" . diary))) ;; imenu (bind-keys ("C-M-'" . imenu)) ;; isearch ;; ;; regular expression searches ;; (when (fboundp 'isearch-forward-regexp) ;; (bind-keys ("C-S" . isearch-forward-regexp))) ;; (when (fboundp 'isearch-backward-regexp) ;; (bind-keys ("C-R" . isearch-backward-regexp))) ;; activate `occur' from isearch (define-key isearch-mode-map (kbd "C-o") (lambda () (interactive) (let ((case-fold-search isearch-case-fold-search)) (occur (if isearch-regexp isearch-string (regexp-quote isearch-string)))))) ;; line number mode (bind-keys ("C-x M-n" . display-line-numbers-mode)) (when (fboundp 'display-line-numbers-type-toggle) (bind-keys ("C-x M-N" . display-line-numbers-type-toggle))) ;; occur (when (fboundp 'occur) ;;(bind-keys ("C-x u" . occur)) ; default: `undo' (bind-keys ("C-c o" . occur))) ;; shell (bind-keys ("C-x !" . shell))) (init-message 3 "custom-key-bindings-modes-and-modules-keys") (custom-key-bindings-modes-and-modules-keys)
Grouped Prefix Keys
;;------------------------------------------------------------------------------ ;;; Key Bindings: Grouped Prefix Keys ;;------------------------------------------------------------------------------ (init-message 2 "Key Bindings: Grouped Prefix Keys") (defun custom-key-bindings-grouped-prefix-keys () "Set custom grouped prefix key bindings." ;; help find commands ;; "C-h e" defaults to `view-echo-area-messages' (unbind-key "C-h e") (define-prefix-command 'help-find-map nil "Help Find Commands") (bind-keys :prefix "C-h e" :prefix-map help-find-map :menu-name "Help Find Commands" ("e" . view-echo-area-messages) ("f" . find-function) ("k" . find-function-on-key) ("l" . find-library) ("v" . find-variable) ("V" . apropos-value)) ;; custom prefix launching point (M-space) (unbind-key "M-SPC") (define-prefix-command 'space-map nil "Space Prefix Launching Point") (bind-keys :prefix "M-SPC" :prefix-map space-map :menu-name "Space Prefix Launching Point") (bind-keys ("C-." . space-map)) ; in case the OS consumes M-SPC ;; menu (bind-keys :map space-map ("M-SPC" . tmm-menubar)) ;; buffer commands (bind-keys :map space-map :prefix "b" :prefix-map space-buffer-map :menu-name "Buffer Commands") (when (fboundp 'switch-to-messages) (bind-keys :map space-buffer-map ("m" . switch-to-messages))) (when (fboundp 'new-scratch) (bind-keys :map space-buffer-map ("n" . new-scratch))) (when (fboundp 'new-emacs-lisp-scratch) (bind-keys :map space-buffer-map ("e" . new-emacs-lisp-scratch))) (when (fboundp 'new-org-scratch) (bind-keys :map space-buffer-map ("o" . new-org-scratch))) (when (fboundp 'switch-to-scratch) (bind-keys :map space-buffer-map ("s" . switch-to-scratch))) (when (fboundp 'switch-to-scratch-for-current-mode) (bind-keys :map space-buffer-map ("c" . switch-to-scratch-for-current-mode))) ;; command log commands (bind-keys :map space-map :prefix "c" :prefix-map space-command-log-map :menu-name "Command Log Commands" ("c" . command-log-mode-on) ("k" . command-log-mode-off) ("l" . clm/command-log-clear)) ;; git commands (bind-keys :map space-map :prefix "g" :prefix-map space-git-map :menu-name "Git Commands" ("b" . magit-branch) ("c" . magit-branch-or-checkout) ("d" . magit-diff-unstaged) ("f" . magit-fetch) ("F" . magit-fetch-all) ("p" . magit-pull-branch) ("P" . magit-push-current) ("r" . magit-rebase) ("s" . magit-status)) ;; git log commands (bind-keys :map space-git-map :prefix "l" :prefix-map space-git-log-map :menu-name "Git Log Commands" ("l" . magit-log-current) ("f" . magit-log-buffer-file)) ;; grep commands (bind-keys :map space-map :prefix "G" :prefix-map space-grep-map :menu-name "Grep Commands") (when (fboundp 'grep-bin) (bind-keys :map space-grep-map ("b" . grep-bin))) (when (fboundp 'grep-clojure) (bind-keys :map space-grep-map ("c" . grep-clojure))) (when (fboundp 'grep-clisp) (bind-keys :map space-grep-map ("l" . grep-clisp))) (when (fboundp 'grep-elisp) (bind-keys :map space-grep-map ("e" . grep-elisp))) (when (fboundp 'grep-elisp-extended) (bind-keys :map space-grep-map ("E" . grep-elisp-extended))) (when (fboundp 'grep-emacs-init) (bind-keys :map space-grep-map ("i" . grep-emacs-init))) (when (fboundp 'grep-home-init) (bind-keys :map space-grep-map ("h" . grep-home-init))) (when (fboundp 'grep-org) (bind-keys :map space-grep-map ("o" . grep-org))) (when (fboundp 'grep-python) (bind-keys :map space-grep-map ("p" . grep-python))) (when (fboundp 'grep-racket) (bind-keys :map space-grep-map ("r" . grep-racket))) (when (fboundp 'grep-web) (bind-keys :map space-grep-map ("w" . grep-web))) ;; insert commands (bind-keys :map space-map :prefix "i" :prefix-map space-insert-map :menu-name "Insert Commands" ("d" . insert-date) ("t" . insert-datetime) ("u" . insert-uuid)) ;; insert org-mode commands (bind-keys :map space-insert-map :prefix "o" :prefix-map space-insert-org-map :menu-name "Insert Org-Mode Commands" ("b" . org-insert-literate-programming-src) ("c" . org-insert-literate-programming-code-block) ("e" . org-insert-literate-programming-src-emacs-lisp) ("h" . org-insert-header) ("i" . org-insert-literate-programming-init-emacs-block) ("k" . org-insert-literate-programming-src-kotlin) ("n" . org-insert-literate-programming-name) ("p" . org-insert-literate-programming-project-euler-problem-block) ("r" . org-insert-literate-programming-src-racket) ("s" . org-insert-literate-programming-src-sh) ("t" . org-insert-table)) ;; insert password commands (bind-keys :map space-insert-map :prefix "p" :prefix-map space-insert-password-map :menu-name "Insert Password Commands" ("p" . insert-password) ("h" . insert-password-phrase) ("2" . insert-password-20) ("3" . insert-password-phrase-3-space) ("6" . insert-password-phrase-6-space) ("-" . insert-password-phrase-6-hyphen-capitalize) ("!" . insert-password-phrase-6-symbol-capitalize)) ;; miscellaneous commands (bind-keys :map space-map :prefix "m" :prefix-map space-miscellaneous-map :menu-name "Miscellaneous Commands" ("b" . emacs-lisp-byte-compile) ("c" . customize-group) ("g" . magit-status) ("m" . macrostep-mode) ("s" . server-start-maybe) ("w" . webjump) ("x" . regexp-builder)) ;; miscellaneous display commands (bind-keys :map space-miscellaneous-map :prefix "d" :prefix-map space-miscellaneous-display-map :menu-name "Display Commands" ("c" . list-colors-display) ("f" . list-faces-display) ("s" . list-character-sets) ("w" . display-time-world)) (when (fboundp 'term-bash) (bind-keys :map space-miscellaneous-display-map ("u" . list-charset-unicode))) ;; miscellaneous eval commands (bind-keys :map space-miscellaneous-map :prefix "e" :prefix-map space-miscellaneous-eval-map :menu-name "Eval Commands" ("b" . eval-buffer) ("i" . ielm) ("r" . eval-region)) ;; miscellaneous format commands (bind-keys :map space-miscellaneous-map :prefix "f" :prefix-map space-miscellaneous-format-map :menu-name "Format Commands" ("j" . json-pretty-print) ("x" . xml-pretty-print)) ;; miscellaneous toggle commands (bind-keys :map space-miscellaneous-map :prefix "t" :prefix-map space-miscellaneous-toggle-map :menu-name "Toggle Commands" ("d" . toggle-debug-on-error) ("q" . toggle-debug-on-quit) ("s" . toggle-case-fold-search) ("t" . toggle-truncate-lines) ("v" . visual-line-mode)) ;; package commands (bind-keys :map space-map :prefix "p" :prefix-map space-package-map :menu-name "Package Commands" ("i" . package-install) ("l" . package-list-packages-no-fetch) ("L" . package-list-packages) ("R" . straight-pull-recipe-repositories) ("P" . straight-pull-all) ("F" . straight-fetch-all)) ;; run commands (bind-keys :map space-map :prefix "r" :prefix-map space-run-map :menu-name "Run Commands") (when (and (fboundp 'safe-load) (boundp 'emacs-home-dir)) (defun safe-load-init-elisp () (safe-load (file-truename (expand-file-name "init.el" emacs-home-dir)))) (bind-keys :map space-run-map ("i" . safe-load-init-elisp))) ;; terminal commands (bind-keys :map space-map :prefix "t" :prefix-map space-terminal-map :menu-name "Terminal Commands" ("a" . ansi-term) ("e" . eshell) ("s" . shell) ("t" . term)) (when (fboundp 'term-bash) (bind-keys :map space-terminal-map ("b" . term-bash))) (when (fboundp 'term-zsh) (bind-keys :map space-terminal-map ("z" . term-zsh))) (when (fboundp 'vterm) (bind-keys :map space-terminal-map ("v" . vterm))) ;; ;; window resize commands ;; (bind-keys :map space-map ;; :prefix "w" ;; :prefix-map space-window-resize-map ;; :menu-name "Window Resize") ;; (when (fboundp 'window-shrink-vertically) ;; (bind-keys :map space-window-resize-map ("i" . window-shrink-vertically))) ;; (when (fboundp 'window-enlarge-vertically) ;; (bind-keys :map space-window-resize-map ("k" . window-enlarge-vertically))) ;; (when (fboundp 'window-shrink-horizontally) ;; (bind-keys :map space-window-resize-map ("j" . window-shrink-horizontally))) ;; (when (fboundp 'window-enlarge-horizontally) ;; (bind-keys :map space-window-resize-map ("l" . window-enlarge-horizontally))) ;; browse-url commands (bind-keys :map space-map :prefix "z" :prefix-map space-browse-url-map :menu-name "Browse URL Commands" ("." . browse-url-at-point) ("b" . browse-url-of-buffer) ("r" . browse-url-of-region) ("u" . browse-url) ("v" . browse-url-of-file))) (init-message 3 "custom-key-bindings-grouped-prefix-keys") (custom-key-bindings-grouped-prefix-keys)
Set All Custom Key Bindings
;;------------------------------------------------------------------------------ ;;; Key Bindings: Set All Custom Key Bindings ;;------------------------------------------------------------------------------ (init-message 2 "Key Bindings: Set All Custom Key Bindings") (defun custom-key-bindings-set-all () "Set all custom key bindings." ;; Turned off in order to reserve the Super keybindings for the OS. ;; (init-message 3 "custom-key-bindings-system-keys") ;; (custom-key-bindings-system-keys) (init-message 3 "custom-key-bindings-function-keys") (custom-key-bindings-function-keys) (init-message 3 "custom-key-bindings-extended-keys") (custom-key-bindings-extended-keys) (init-message 3 "custom-key-bindings-movement-keys") (custom-key-bindings-movement-keys) (init-message 3 "custom-key-bindings-standard-keys") (custom-key-bindings-standard-keys) (init-message 3 "custom-key-bindings-modes-and-modules-keys") (custom-key-bindings-modes-and-modules-keys) (init-message 3 "custom-key-bindings-grouped-prefix-keys") (custom-key-bindings-grouped-prefix-keys))
Org Mode
Org Mode (advanced outline mode) configuration.
https://orgmode.org/ https://orgmode.org/manual/ https://www.emacswiki.org/emacs/OrgMode http://doc.norang.ca/org-mode.html https://emacsclub.github.io/html/org_tutorial.html
;;============================================================================== ;;; Org Mode ;;============================================================================== (init-message 1 "Org Mode")
Configuration
Main Org Mode configuration.
;;------------------------------------------------------------------------------ ;;; Org Mode: Configuration ;;------------------------------------------------------------------------------ (init-message 2 "Org Mode: Configuration") (use-package org :straight (:type built-in) :demand t :mode (("\\.org\\'" . org-mode) ("\\.org_archive\\'" . org-mode)) :bind* (("C-c a" . org-agenda) ("C-c c" . org-capture) ;;("C-c l" . org-store-link) ("C-c j" . org-babel-tangle-jump-to-org)) :custom ;; org directory (org-directory (file-truename (expand-file-name "~/org"))) ;; ;; use org indent mode ;; (org-indent-mode 1) ;; indent blocks to outline node level (org-adapt-indentation t) ;; ;; do not indent blocks to outline node level ;; (org-adapt-indentation nil) ;; odd level headings only (org-odd-levels-only t) ;; ;; odd and even level headings ;; (org-odd-levels-only nil) ;; hide leading stars on headings (org-hide-leading-stars t) ;; startup in "overview" (folded) by default (org-startup-folded 'overview) ;; remap disputed keys (see `org-disputed-keys') (org-replace-disputed-keys t) ;; shift-cursor commands select text when possible (org-support-shift-select 'always) ;; display inline images (org-startup-with-inline-images t) ;; do not insert empty lines around headings (org-blank-before-new-entry '((heading . nil) (plain-list-item . nil))) ;; use a different ellipsis indicator (than '...') ;;(org-ellipsis "…") ;;(org-ellipsis " ⤵") ;;(org-ellipsis " ") ;;(org-ellipsis " ") ;;(org-ellipsis " ") (org-ellipsis " ▼") ;; return follows links ;;(org-return-follows-link t) ;; reverse `org-beginning-of-line' and `org-end-of-line' toggle order ;; HOME toggles between line start and headline start ;; END toggles between end of tags and headline end (org-special-ctrl-a/e 'reversed) ;; show and error on invisible edits (org-catch-invisible-edits 'show-and-error) ;; use todo key selection (org-use-fast-todo-selection t) ;; use shift-left/right to change todo status without a state change (org-treat-S-cursor-todo-selection-as-state-change nil) ;; time stamp settings (org-display-custom-times t) (org-time-stamp-custom-formats '("<%Y-%m-%d %a>" . "<%Y-%m-%d %a %H:%M>")) ;; always show lineage (org-show-context-detail '((default . lineage) (agenda . local))) ;; todo keywords ;;(org-todo-keywords '("TODO(t)" "NEXT(n)" "|" "DONE(d!)")) ;; log note settings (org-log-note-headings '((done . "CLOSING NOTE %t") ;;(state . "State %-12s from %-12S %t") (state . "State %-12s %t") (note . "Note taken on %t") (reschedule . "Rescheduled from %S on %t") (delschedule . "Not scheduled, was %S on %t") (redeadline . "New deadline from %S on %t") (deldeadline . "Removed deadline, was %S on %t") (refile . "Refiled on %t") (clock-out . ""))) :config ;; faces (custom-set-faces `(org-ellipsis ((t (:underline nil)))) `(org-block ((t (:inherit shadow :foreground ,color-foreground))))) ;; `(org-level-1 ((t (:foreground ,color-1)))) ;; `(org-level-2 ((t (:foreground ,color-2)))) ;; `(org-level-3 ((t (:foreground ,color-3)))) ;; `(org-level-4 ((t (:foreground ,color-4)))) ;; `(org-level-5 ((t (:foreground ,color-5)))) ;; `(org-level-6 ((t (:foreground ,color-6)))) ;; `(org-level-7 ((t (:foreground ,color-7)))) ;; `(org-level-8 ((t (:foreground ,color-8))))) ;; set file apps (when window-system (setq org-file-apps (quote ((auto-mode . emacs) ("\\.mm\\'" . default) ("\\.x?html?\\'" . default) ("\\.pdf\\'" . emacs))))) ; use internal PDF viewer ;; remember settings ;;(setq remember-handler-functions '(org-remember-handler) ;; remember-annotation-functions '(org-remember-annotation)) ;;(add-hook 'remember-mode-hook #'org-remember-apply-template) ;; todo keywords ;; (org-todo-keywords ;; '((sequence "TODO(t)" "NEXT(n)" "|" "DONE(d!)") ;; (sequence "BACKLOG(b)" "PLAN(p)" "READY(r)" "ACTIVE(a)" "REVIEW(v)" "WAIT(w@/!)" "HOLD(h)" "|" "COMPLETED(c)" "CANCELED(k@)")) ;; ;; add todo state map ;; (define-prefix-command 'org-todo-state-map) ;; (define-key org-mode-map (kbd "C-c x") 'org-todo-state-map) ;; (define-key org-todo-state-map (kbd "s") (lambda () (interactive) (org-todo "STARTED"))) ;; (define-key org-todo-state-map (kbd "w") (lambda () (interactive) (org-todo "WAITING"))) ;; ;;(define-key org-todo-state-map (kbd "f") (lambda () (interactive) (org-todo "DEFERRED"))) ;; ;;(define-key org-todo-state-map (kbd "l") (lambda () (interactive) (org-todo "DELEGATED"))) ;; (define-key org-todo-state-map (kbd "d") (lambda () (interactive) (org-todo "DONE"))) ;; (define-key org-todo-state-map (kbd "c") (lambda () (interactive) (org-todo "CANCELED"))) ;; save buffers after refile (advice-add 'org-refile :after #'org-save-all-org-buffers) (defun pabbrev-global-mode--org-disable (orig-fun &rest args) "Turn off pabbrev mode (it interferes with org mode)." (unless (eq major-mode 'org-mode) (apply orig-fun args))) ;; advise `pabbrev-global-mode' (advice-add 'pabbrev-global-mode :around #'pabbrev-global-mode--org-disable) ;; make windmove work in org-mode (add-hook 'org-shiftup-final-hook #'windmove-up) (add-hook 'org-shiftleft-final-hook #'windmove-left) (add-hook 'org-shiftdown-final-hook #'windmove-down) (add-hook 'org-shiftright-final-hook #'windmove-right) ;; mobile org settings (setq org-mobile-directory (file-truename (expand-file-name "~/Dropbox/MobileOrg"))) (setq org-mobile-inbox-for-pull (file-truename (expand-file-name "index.org" org-mobile-directory))) (defun org-update-parent-cookie () "Update parent TODO cookies when children entries are killed." (when (eq major-mode 'org-mode) (save-mark-and-excursion (ignore-errors (org-back-to-heading) (org-update-parent-todo-statistics))))) ;; ;; too slow ;; (defun org-kill-line--fix-cookies (&optional arg) ;; "Update parent todo cookies after `org-kill-line'." ;; (org-update-parent-cookie)) ;; ;; advise `org-kill-line' ;; (advice-add 'org-kill-line :after #'org-kill-line--fix-cookies) ;; ;; too slow ;; (defun kill-whole-line--fix-cookies (&optional arg) ;; "Update parent todo cookies after `kill-whole-line'." ;; (org-update-parent-cookie)) ;; ;; advise `kill-whole-line' ;; (advice-add 'kill-whole-line :after #'kill-whole-line--fix-cookies) (defun org-kill-src-buffers (&rest args) "Kill temporary buffers created by `org-src-font-lock-fontify-block'." (dolist (buffer (buffer-list)) (let ((buffer-name (buffer-name buffer))) (when (string-prefix-p " org-src-fontification:" buffer-name) (kill-buffer buffer))))) (defun org-src-font-lock-fontify-block--kill-src-buffers (lang start end) "Kill temporary buffers created by `org-src-font-lock-fontify-block'." (org-kill-src-buffers)) ;; advise `org-src-font-lock-fontify-block' (advice-add 'org-src-font-lock-fontify-block :after #'org-src-font-lock-fontify-block--kill-src-buffers) (defun before-save-hook--update-last-modified-property () "Hook to update last modified property on save." (when (and buffer-file-name (string= (file-name-extension buffer-file-name) "org")) (org-update-last-modified-property))) (add-hook 'before-save-hook #'before-save-hook--update-last-modified-property) (defun after-save-hook--generate-init-emacs-elisp-file () "Hook to generate init-emacs.el file on save." (when (and buffer-file-name (string= (file-truename buffer-file-name) init-emacs-true-file-name)) ;;(org-babel-generate-elisp-file init-emacs-true-file-name nil t) (if (fboundp 'org-babel-tangle-file-async) (org-babel-tangle-file-async init-emacs-true-file-name) (org-babel-tangle-file init-emacs-true-file-name)))) (add-hook 'after-save-hook #'after-save-hook--generate-init-emacs-elisp-file :append) ;; (defun org-insert-heading--fix-newline-bug (orig-fun &rest args) ;; "Fix extra newline bug in org." ;; ;; make sure empty lines above new headline are not removed ;; (if (= (point) (line-beginning-position)) ;; (let ((start (point))) ;; (apply orig-fun args) ;; (forward-line 0) ;; (while (< (point) start) ;; (newline)) ;; (goto-char (line-end-position))) ;; (apply orig-fun args))) ;; ;; advise `org-insert-heading' to fix extra newline bug ;; (advice-add 'org-insert-heading :around #'org-insert-heading--fix-newline-bug) ;; (defun org-fixup-indentation--unindent (diff) ;; "Unindent org begin/end blocks, keywords, and paragraphs." ;; (save-window-excursion ;; (save-mark-and-excursion ;; (save-match-data ;; (when (org-with-limited-levels (org-at-heading-p)) ;; (org-with-wide-buffer ;; (narrow-to-region (line-beginning-position) ;; (save-mark-and-excursion ;; (org-with-limited-levels (outline-next-heading)) ;; (point))) ;; (forward-line 0) ;; (org-beginning-of-line) ;; (let* ((case-fold-search t) ;; (indentation (- (point) (line-beginning-position))) ;; (spacing (make-string (abs diff) ? )) ;; (indented-regexp (concat "^" spacing "[ \t]*")) ;; (text-indent t)) ;; (forward-line 1) ;; (while (not (eobp)) ;; (when (re-search-forward indented-regexp (line-end-position) :noerror) ;; (let ((line-indentation (- (point) (line-beginning-position)))) ;; (forward-line 0) ;; (cl-case (org-element-type (org-element-at-point)) ;; ('src-block ;; (when (> diff 0) ;; (delete-char diff))) ;; ((paragraph table table-row) ;; (if (> diff 0) ;; (when (or (not text-indent) ;; (< line-indentation indentation)) ;; (delete-char diff) ;; (setq text-indent nil)) ;; (if (and text-indent ;; (>= line-indentation (- indentation diff))) ;; (delete-char (abs diff)) ;; (setq text-indent nil))))))) ;; (forward-line 1))))))))) ;; ;; advise `org-fixup-indentation' to unindent as needed ;; (advice-add 'org-fixup-indentation :after #'org-fixup-indentation--unindent) ;;---------------------------------------------------------------------------- ;; define some deprecated functions that are needed ;;---------------------------------------------------------------------------- (unless (fboundp 'org-outline-overlay-data) (defun org-outline-overlay-data (&optional use-markers) "Return a list of the locations of all outline overlays. These are overlays with the `invisible' property value `outline'. The return value is a list of cons cells, with start and stop positions for each overlay. If USE-MARKERS is set, return the positions as markers." (let (beg end) (org-with-wide-buffer (delq nil (mapcar (lambda (x) (when (eq (overlay-get x 'invisible) 'outline) (setq beg (overlay-start x) end (overlay-end x)) (and beg end (> end beg) (if use-markers (cons (copy-marker beg) (copy-marker end t)) (cons beg end))))) (overlays-in (point-min) (point-max)))))))) (unless (fboundp 'org-set-outline-overlay-data) (defun org-set-outline-overlay-data (data) "Create visibility overlays for all positions in DATA. DATA should have been made by `org-outline-overlay-data'." (org-with-wide-buffer (org-show-all) (dolist (c data) (org-flag-region (car c) (cdr c) t 'outline))))))
Outline
;;------------------------------------------------------------------------------ ;;; Org Mode: Outline ;;------------------------------------------------------------------------------ (init-message 2 "Org Mode: Outline") (use-package outline :straight (:type built-in) :after (org) :commands (outline-up-heading outline-forward-same-level outline-show-subtree) :config ;; ;; faces ;; (custom-set-faces ;; `(outline-1 ((t (:foreground ,color-1)))) ;; `(outline-2 ((t (:foreground ,color-2)))) ;; `(outline-3 ((t (:foreground ,color-3)))) ;; `(outline-4 ((t (:foreground ,color-4)))) ;; `(outline-5 ((t (:foreground ,color-5)))) ;; `(outline-6 ((t (:foreground ,color-6)))) ;; `(outline-7 ((t (:foreground ,color-7)))) ;; `(outline-8 ((t (:foreground ,color-8))))) ;; advise `outline-up-heading' to suppress errors (advice-add 'outline-up-heading :around #'advice--ignore-interactive-errors))
Agenda
Org Agenda configuration.
;;------------------------------------------------------------------------------ ;;; Org Mode: Agenda ;;------------------------------------------------------------------------------ (init-message 2 "Org Mode: Agenda") (use-package org-agenda :when (file-exists-p org-directory) :straight (:type built-in) :after (org) :config ;; agenda key bindings ;;(define-key org-agenda-mode-map (kbd "C-n") 'next-line) ;;(define-key org-agenda-keymap (kbd "C-n") 'next-line) ;;(define-key org-agenda-mode-map (kbd "C-p") 'previous-line) ;;(define-key org-agenda-keymap (kbd "C-p") 'previous-line) ;; record time when todo's are marked done (setq org-log-done 'time) ;; agenda files (setq org-agenda-file-regexp "agenda-.*\\.org\\'" org-agenda-files (mapcar (lambda (x) (expand-file-name x (file-name-as-directory org-directory))) (cl-remove-if-not (lambda (x) (string-match org-agenda-file-regexp x)) (directory-files org-directory)))) ;; default notes file (setq org-default-notes-file (car org-agenda-files)) ;; show 7 days in agenda view (setq org-agenda-span 7) ;; show deadlines within 14 days (setq org-deadline-warning-days 14) ;; show all dates (even empty ones) (setq org-agenda-show-all-dates t) ;; do not show entries marked done (setq org-agenda-skip-deadline-if-done t) (setq org-agenda-skip-scheduled-if-done t) ;; start agenda view on current day (setq org-agenda-start-on-weekday nil) ;; store new notes at the beginning of files (setq org-reverse-note-order t) ;; quick tag selection (setq org-fast-tag-selection-single-key 'expert) ;; quick tag keys (setq org-agenda-custom-commands (quote (("d" todo "DONE" nil) ;;("d" todo "DONE|DEFERRED|CANCELLED" nil) ("w" todo "WAITING" nil) ;;("l" todo "DELEGATED" nil) ("W" agenda "" ((org-agenda-ndays 21))) ("A" agenda "" ((org-agenda-skip-function (lambda () (org-agenda-skip-entry-if 'notregexp "\\=.*\\[#A\\]"))) (org-agenda-ndays 1) (org-agenda-overriding-header "Today's Priority #A tasks: "))) ("u" alltodo "" ((org-agenda-skip-function (lambda () (org-agenda-skip-entry-if 'scheduled 'deadline 'regexp "<[^>\n]+>"))) (org-agenda-overriding-header "Unscheduled TODO entries: ")))))) ;; fix bug (unless (boundp 'org-called-interactively-p) (defalias 'org-called-interactively-p 'called-interactively-p)) ;; archive done tasks (defun org-agenda-archive-done-tasks () "Archive DONE tasks." (interactive) (org-map-entries #'org-archive-subtree "/DONE" 'file)) ;; auto-save archive files (when (boundp 'org-archive-subtree-save-file-p) (setq org-archive-subtree-save-file-p t)))
Capture
Org Capture configuration.
;;------------------------------------------------------------------------------ ;;; Org Mode: Capture ;;------------------------------------------------------------------------------ (init-message 2 "Org Mode: Capture") (use-package org-capture :when (file-exists-p org-directory) :straight (:type built-in) :after (org org-agenda) :config (let ((capture-file (car org-agenda-files)) (capture-headline "Inbox")) (setq org-capture-templates `(("i" "Inbox" entry (file+headline ,capture-file ,capture-headline) "* TODO %?\nOPENED: %U" :prepend t) ("@" "Inbox [mu4e]" entry (file+headline ,capture-file ,capture-headline) "* TODO Email: \"%a\" %?\nOPENED: %U" :prepend t)))))
Alerts
;; ;;------------------------------------------------------------------------------ ;; ;;; Org Mode: Alerts ;; ;;------------------------------------------------------------------------------ ;; (init-message 2 "Org Mode: Alerts") ;; ;; (use-package org-alert ;; ;; :straight t ;; ;; :after (org) ;; ;; :custom ;; ;; (alert-default-style 'notifications) ;; ;; :config ;; ;; (setq org-alert-interval 300 ;; ;; org-alert-notification-title "Org Reminder")) ;; ;; ;; throws error: void-function -orfn ;; ;; (use-package org-wild-notifier ;; ;; :straight t ;; ;; :after (org) ;; ;; :custom ;; ;; (alert-default-style 'notifications) ;; ;; (org-wild-notifier-alert-time '(1 10 30)) ;; ;; (org-wild-notifier-keyword-whitelist '("TODO" "NEXT")) ;; ;; (org-wild-notifier-notification-title "Org Reminder") ;; ;; :init (org-wild-notifier-mode 1)) ;; ;; (use-package org-notify ;; ;; :straight t ;; ;; :after (org) ;; ;; :init (org-notify-start))
Appear
;;------------------------------------------------------------------------------ ;;; Org Mode: Appear ;;------------------------------------------------------------------------------ (init-message 2 "Org Mode: Appear") (use-package org-appear :straight t :hook (org-mode . org-appear-mode) :custom (org-appear-autolinks t) (org-appear-autosubmarkers t) (org-appear-autoentities t) (org-appear-autokeywords t) (org-appear-inside-latex t) (org-appear-delay 0.5) (org-appear-trigger #'always))
LaTeX
LaTeX support for Org files.
;;------------------------------------------------------------------------------ ;;; Org Mode: LaTeX ;;------------------------------------------------------------------------------ (init-message 2 "Org Mode: LaTeX")
ox-latex
;;------------------------------------------------------------------------------ ;;;; Org Mode: LaTeX: ox-latex ;;------------------------------------------------------------------------------ (init-message 3 "Org Mode: LaTeX: ox-latex") (use-package ox-latex :straight (:type built-in) :custom (org-latex-listings t) :init (add-to-list 'org-latex-classes `("org-latex-plain" ,(concat "\\documentclass{article}\n" "[NO-DEFAULT-PACKAGES]\n" "[PACKAGES]\n" "[EXTRA]") ("\\section{%s}" . "\\section*{%s}") ("\\subsection{%s}" . "\\subsection*{%s}") ("\\subsubsection{%s}" . "\\subsubsection*{%s}") ("\\paragraph{%s}" . "\\paragraph*{%s}") ("\\subparagraph{%s}" . "\\subparagraph*{%s}"))))
ob-latex-as-png
An Org-babel "language" whose execution produces PNGs from LaTeX snippets; useful for shipping arbitrary LaTeX results in HTML.
The pdflatex command needs to be installed for this to work.
# install texlive-bin on Arch system sudo pacman -S --noconfirm texlive-bin # nixos package: texlive.combined.scheme-full
;;------------------------------------------------------------------------------ ;;;; Org Mode: LaTeX: ob-latex-as-png ;;------------------------------------------------------------------------------ (init-message 3 "Org Mode: LaTeX: ob-latex-as-png") (use-package ob-latex-as-png :straight t)
org-latex-plain.org
Tangle manually when modified.
%============================================================================== %% org-latex-plain.org % %% A simple LaTeX configuration for Org files. % % To use, add this line to an Org file: % % #+SETUPFILE: ~/org/org-latex-plain.org % % Author: Jake Box <jakebox0@protonmail.com> % Source: https://github.com/jakebox/jake-emacs/ %============================================================================== % Colorized Links % Page Geometry % Line Spacing % Page Numbering Disabled % Spacing, Titling, Text Setting % Title Customization % Move Title Up % Section/Subsection Headings: % Section % Subsection % Subsubsection % Lists: % List Spacing % Ordered List Bullets % Unordered List Bullets %============================================================================== %% End of File %==============================================================================
ACUTeX
;; ;;------------------------------------------------------------------------------ ;; ;;; Org Mode: ACUTeX ;; ;;------------------------------------------------------------------------------ ;; (init-message 2 "Org Mode: ACUTeX") ;; (use-package auctex ;; :straight t ;; :after (tex))
Remember
Remember configuration (for quickly jotting down things to remember).
;; ;;------------------------------------------------------------------------------ ;; ;;; Org Mode: Remember ;; ;;------------------------------------------------------------------------------ ;; (init-message 2 "Org Mode: Remember") ;; (use-package remember ;; :straight (:type built-in) ;; :commands (remember remember-region) ;; :config ;; ;; key bindings ;; (bind-keys ("C-x C-r" . remember)) ; default: `find-file-read-only' ;; ;; remember todo file ;; (setq org-default-todo-file (file-truename (expand-file-name "agenda-personal.org" (file-name-as-directory org-directory)))) ;; ;; remember notes file ;; ;;(setq org-default-notes-file (file-truename (expand-file-name "remember-notes.org" (file-name-as-directory org-directory)))) ;; (setq org-default-notes-file (file-truename (expand-file-name "agenda-personal.org" (file-name-as-directory org-directory)))) ;; ;; quick remember save ;; (setq org-remember-store-without-prompt t) ;; ;; templates ;; (setq org-remember-templates ;; (quote ((116 "* TODO %?" org-default-todo-file "Tasks") ;; ;;(116 "* TODO %?\n %u" org-default-todo-file "Tasks") ;; (110 "* %u %?" org-default-notes-file "Notes")))) ;; ;; use template ;; (add-hook 'remember-mode-hook #'org-remember-apply-template) ;; ;; annotation functions hook ;; (setq remember-annotation-functions 'org-remember-annotation) ;; ;; function(s) to process remember data ;; (setq remember-handler-functions 'org-remember-handler)) ;; ;;------------------------------------------------------------------------------ ;; ;;;; remember-planner ;; ;;------------------------------------------------------------------------------ ;; (init-message 3 "remember-planner") ;; (use-package remember-planner ;; :straight (:type built-in) ;; :after (remember) ;; :config ;; (setq remember-handler-functions '(remember-planner-append) ;; remember-annotation-functions planner-annotation-functions))
TOC
Automatic table of contents for Org files.
;; ;;------------------------------------------------------------------------------ ;; ;;; Org Mode: TOC ;; ;;------------------------------------------------------------------------------ ;; (init-message 2 "Org Mode: TOC") ;; (use-package org-make-toc ;; ;; original author is not maintaining the code ;; ;; :straight (org-make-toc :type git :host github :repo "alphapapa/org-make-toc") ;; ;; forked branch fixes a bug ;; :straight (org-make-toc ;; :type git ;; :host github ;; :repo "nullman/org-make-toc" ;; :branch "fix/no-auto-save-temp-file") ;; :hook (org-mode . org-make-toc-mode) ;; :custom ;; (org-make-toc-link-type-fn #'org-make-toc--link-entry-custom) ;; :config ;; ;; custom link entry generator ;; (defun org-make-toc--link-entry-custom () ;; "Return text for ENTRY converted to ID link." ;; (or (when-let* ((id (cdr (assoc "CUSTOM_ID" (org-entry-properties)))) ;; (title (cdr (assoc "ITEM" (org-entry-properties)))) ;; (filename (if org-make-toc-filename-prefix ;; (file-name-nondirectory (buffer-file-name)) ;; ""))) ;; (org-link-make-string (concat filename "#" id) ;; (org-make-toc--visible-text title))) ;; (org-make-toc--link-entry-github))))
PDF
;; ;;------------------------------------------------------------------------------ ;; ;;; Org Mode: PDF ;; ;;------------------------------------------------------------------------------ ;; (init-message 3 "org-pdfview") ;; needs pdftools, which annoyingly recompiles on every boot ;; (use-package org-pdfview ;; :straight t ;; :after (org))
Modules
Org Mode modules.
;;------------------------------------------------------------------------------ ;;; Org Mode: Modules ;;------------------------------------------------------------------------------ (init-message 2 "Org Mode: Modules") (org-load-modules-maybe t)
Functions
Org Mode supporting functions.
;;------------------------------------------------------------------------------ ;;; Org Mode: Functions ;;------------------------------------------------------------------------------ (init-message 2 "Org Mode: Functions")
org-get-property-list
Return a list of requested org properties.
;;------------------------------------------------------------------------------ ;;;; Org Mode: Functions: org-get-property-list ;;------------------------------------------------------------------------------ (init-message 3 "Org Mode: Functions: org-get-property-list") (defun org-get-property-list (&optional property buffer) "Return an association list of org properties matching PROPERTY in BUFFER. PROPERTY is used to `string-match' for properties to return (defaults to \"PROPERTY\"). Multiple properties can be queried in one call by using a regular expression. (E.g. \"\\(AUTHOR\\|EMAIL\\|TITLE\\)\") If BUFFER is nil, current buffer is used." (let ((property (or property "PROPERTY"))) (with-current-buffer (or buffer (current-buffer)) (org-element-map (org-element-parse-buffer) 'keyword (lambda (x) (let ((key (org-element-property :key x))) (when (string-match property key) (cons key (org-element-property :value x)))))))))
org-get-element-tree
Return a tree structure representing the org buffer for requested types.
;;------------------------------------------------------------------------------ ;;;; Org Mode: Functions: org-get-element-tree ;;------------------------------------------------------------------------------ (init-message 3 "Org Mode: Functions: org-get-element-tree") (defun org-get-element-tree (types &optional buffer) "Return a tree structure representing the org levels found in BUFFER for given TYPES. TYPES is the same symbol or list of symbols used with `org-element-map'. If BUFFER is nil, current buffer is used." (with-current-buffer (or buffer (current-buffer)) (org-element-map (org-element-parse-buffer) types (lambda (x) (cons (org-element-property :level x) (org-element-property :raw-value x))))))
org-get-file-data
Return a tree structure of org data found in the given file.
;;------------------------------------------------------------------------------ ;;;; Org Mode: Functions: org-get-file-data ;;------------------------------------------------------------------------------ (init-message 3 "Org Mode: Functions: org-get-file-data") (defun org-get-file-data (file &optional path) "Return tree structure version of given Org FILE. PATH is an optional list of headlines to match starting from the top level. Output format: (((\"KEY1\" . VALUE1) (\"KEY2\" . VALUE2) (\"KEY3\" . VALUE3)) ((HEADLINE1) (HEADLINE2 (HEADLINE21 . BODY21)) (HEADLINE3 (HEADLINE31 (HEADLINE311 . BODY311) (HEADLINE312 . BODY312)) (HEADLINE32 (HEADLINE321 . BODY321) (HEADLINE322 . BODY322)))))" (let* ((property-headline-regexp "^[ \t]*\\** Org\\([ \t]*:noexport:\\)?$") (property-regexp "^[ \t]*#\\+\\(.*\\): \\(.*\\)$") (property-drawer-regexp "[ \t]*:PROPERTIES:.*:END:[ \t]*") (headline-regexp "^\\(\*+ \\)\\(.*\\)$") (property-alist nil) (property-section t) (level 0) (tree (cons nil nil)) (start tree) (stack nil) (matches path) (path-level (length path)) (parse-error "Error parsing at headline: %s")) (with-temp-buffer (insert-file-contents file) (goto-char (point-min)) (while (not (eobp)) ;;(message "%S" tree) (cond ;; ignore property folder ((and (bobp) (looking-at property-headline-regexp)) nil) ;; add properties ((and property-section (looking-at property-regexp)) (let ((key (match-string-no-properties 1)) (value (match-string-no-properties 2))) (push (cons key value) property-alist))) ;; add folders ((looking-at headline-regexp) (setq property-section nil) (let ((headline-level (/ (length (match-string-no-properties 1)) (if org-odd-levels-only 2 1))) (headline-value (match-string-no-properties 2)) (segment (car path))) (when (and path (not matches) (>= path-level headline-level)) (setq matches path)) (when (or (and (not matches) (> headline-level path-level)) (string= headline-value (car matches))) (when (string= headline-value (car matches)) (setq matches (cdr matches))) (cond ((> headline-level level) (unless tree (user-error parse-error headline-value)) (setcdr tree (cons (cons headline-value nil) nil)) (setq tree (cdr tree)) (push tree stack) (setq tree (car tree)) (setq level headline-level)) ((= headline-level level) (setq tree (pop stack)) (unless tree (user-error parse-error headline-value)) (setcdr tree (cons (cons headline-value nil) nil)) (setq tree (cdr tree)) (push tree stack) (setq tree (car tree))) ((< headline-level level) (while (< headline-level level) (setq tree (pop stack)) (setq level (1- level))) (setq tree (pop stack)) (unless tree (user-error parse-error headline-value)) (setcdr tree (cons (cons headline-value nil) nil)) (setq tree (cdr tree)) (push tree stack) (setq tree (car tree)) (setq level headline-level)))))) ;; add body sections ((and (not matches) (>= level path-level)) (setq property-section nil) (when (> (length start) 1) (let ((body "") (point (point))) (while (and (not (eobp)) (not (looking-at property-regexp)) (not (looking-at headline-regexp))) (when (> (length body) 0) (setq body (concat body "\n"))) (setq body (concat body (replace-regexp-in-string "^[ \t\n]*" "" (buffer-substring-no-properties (line-beginning-position) (line-end-position))))) (forward-line 1)) ;; add unless body is drawer properties (when (> (length (replace-regexp-in-string property-drawer-regexp "" (replace-regexp-in-string "\n" "" body))) 0) (setcdr tree (cons (replace-regexp-in-string "[ \t]*$" "" body) nil)) (setq tree (cdr tree))) (forward-line 0) (when (> (point) point) (forward-line -1))))) (t (setq property-section nil))) (forward-line 1)) (cons property-alist (cdr start)))))
org-get-buffer-data
Return a tree structure of org data found in the given buffer.
;;------------------------------------------------------------------------------ ;;;; Org Mode: Functions: org-get-buffer-data ;;------------------------------------------------------------------------------ (init-message 3 "Org Mode: Functions: org-get-buffer-data") (defun org-get-buffer-data (buffer &optional path with-markers) "Return tree structure version of given Org BUFFER. PATH is an optional list of headlines to match starting from the top level. If WITH-MARKERS is non-nil, include `point-marker' after HEADLINE values in output. Output format: (((\"KEY1\" . VALUE1) (\"KEY2\" . VALUE2) (\"KEY3\" . VALUE3)) ((HEADLINE1) (HEADLINE2 (HEADLINE21 . BODY21)) (HEADLINE3 (HEADLINE31 (HEADLINE311 . BODY311) (HEADLINE312 . BODY312)) (HEADLINE32 (HEADLINE321 . BODY321) (HEADLINE322 . BODY322))))) Output format if WITH-MARKERS is non-nil: (((\"KEY1\" . VALUE1) (\"KEY2\" . VALUE2) (\"KEY3\" . VALUE3)) ((HEADLINE1 . MARKER1) (HEADLINE2 . MARKER2 (HEADLINE21 . MARKER21 . BODY21)) (HEADLINE3 . MARKER3 (HEADLINE31 . MARKER31 (HEADLINE311 . MARKER311 . BODY311) (HEADLINE312 . MARKER312 . BODY312)) (HEADLINE32 . MARKER32 (HEADLINE321 . MARKER321 . BODY321) (HEADLINE322 . MARKER322 . BODY322)))))" (let* ((property-headline-regexp "^[ \t]*\\** Org\\([ \t]*:noexport:\\)?$") (property-regexp "^[ \t]*#\\+\\(.*\\): \\(.*\\)$") (property-drawer-regexp "[ \t]*:PROPERTIES:.*:END:[ \t]*") (headline-regexp "^\\(\*+ \\)\\(.*\\)$") (property-alist nil) (property-section t) (level 0) (tree (cons nil nil)) (start tree) (stack nil) (matches path) (path-level (length path))) (with-current-buffer buffer (goto-char (point-min)) (while (not (eobp)) ;;(message "%S" tree) (cond ;; ignore property folder ((and (bobp) (looking-at property-headline-regexp)) nil) ;; add properties ((and property-section (looking-at property-regexp)) (let ((key (match-string-no-properties 1)) (value (match-string-no-properties 2))) (push (cons key value) property-alist))) ;; add headlines ((looking-at headline-regexp) (setq property-section nil) (let ((headline-level (/ (length (match-string-no-properties 1)) (if org-odd-levels-only 2 1))) (headline-value (match-string-no-properties 2)) (segment (car path))) (when (and path (not matches) (>= path-level headline-level)) (setq matches path)) (when (or (and (not matches) (> headline-level path-level)) (string= headline-value (car matches))) (when (string= headline-value (car matches)) (setq matches (cdr matches))) (cond ((> headline-level level) (if with-markers (setcdr tree (cons (cons (cons headline-value (point-marker)) nil) nil)) (setcdr tree (cons (cons headline-value nil) nil))) (setq tree (cdr tree)) (push tree stack) (setq tree (car tree)) (setq level headline-level)) ((= headline-level level) (setq tree (pop stack)) (if with-markers (setcdr tree (cons (cons (cons headline-value (point-marker)) nil) nil)) (setcdr tree (cons (cons headline-value nil) nil))) (setq tree (cdr tree)) (push tree stack) (setq tree (car tree))) ((< headline-level level) (while (< headline-level level) (setq tree (pop stack)) (setq level (1- level))) (setq tree (pop stack)) (if with-markers (setcdr tree (cons (cons (cons headline-value (point-marker)) nil) nil)) (setcdr tree (cons (cons headline-value nil) nil))) (setq tree (cdr tree)) (push tree stack) (setq tree (car tree)) (setq level headline-level)))))) ;; add body sections ((and (not matches) (>= level path-level)) (setq property-section nil) (when (> (length start) 1) (let ((body "") (point (point))) (while (and (not (eobp)) (not (looking-at property-regexp)) (not (looking-at headline-regexp))) (when (> (length body) 0) (setq body (concat body "\n"))) (setq body (concat body (replace-regexp-in-string "^[ \t\n]*" "" (buffer-substring-no-properties (line-beginning-position) (line-end-position))))) (forward-line 1)) ;; add unless body is drawer properties (when (> (length (replace-regexp-in-string property-drawer-regexp "" (replace-regexp-in-string "\n" "" body))) 0) (setcdr tree (cons (replace-regexp-in-string "[ \t]*$" "" body) nil)) (setq tree (cdr tree))) (forward-line 0) (when (> (point) point) (forward-line -1))))) (t (setq property-section nil))) (forward-line 1)) (cons property-alist (cdr start)))))
org-get-buffer-tags-statistics
Return an association list of tags and their counts in the given files.
;;------------------------------------------------------------------------------ ;;;; Org Mode: Functions: org-get-buffer-tags-statistics ;;------------------------------------------------------------------------------ (init-message 3 "Org Mode: Functions: org-get-buffer-tags-statistics") (defun org-get-buffer-tags-statistics (&optional files) "Return an alist of tags and counts for all tags in FILES. FILES can be nil, a single file, or a list of files. If FILES is nil, the current buffer is used instead." (let ((files (mapcar #'file-truename (cond ((not files) (list (buffer-file-name))) ((stringp files) (list files)) ((listp files) files) (t (user-error "Invalid value for FILES: %S" files))))) (loaded-files (cl-remove-if #'null (mapcar #'buffer-file-name (buffer-list)))) stats) (save-mark-and-excursion (dolist (file files) (find-file file) (org-with-point-at 1 (let (tags) (while (re-search-forward org-tag-line-re nil t) (push (split-string (match-string-no-properties 2) ":") tags)) (dolist (tag (flatten-list tags)) (let ((node (assoc tag stats))) (if node (setcdr node (1+ (cdr node))) (push (cons tag 1) stats)))))) (unless (member file loaded-files) (kill-buffer)))) (sort stats (lambda (a b) (< (cdr a) (cdr b))))))
org-safe-meta
Macros to create "safe meta" functions for org-mode
. They wrap the meta
calls with error checking and ignore any errors thrown.
;;------------------------------------------------------------------------------ ;;;; Org Mode: Functions: org-safe-meta ;;------------------------------------------------------------------------------ (init-message 3 "Org Mode: Functions: org-safe-meta") (defmacro org-safe-meta-function (org-meta-function safe-function) "Return SAFE-FUNCTION version of ORG-META-FUNCTION." `(defun ,(intern safe-function) (&optional arg) ,(concat "Call `" org-meta-function "' ignoring any errors.") (interactive) (let ((pos (point))) (condition-case nil (,(intern org-meta-function) arg) ('error (goto-char pos)))))) (defmacro org-safe-shiftmeta-function (org-shiftmeta-function safe-function) "Return SAFE-FUNCTION version of ORG-SHIFTMETA-FUNCTION." `(defun ,(intern safe-function) () ,(concat "Call `" org-shiftmeta-function "' ignoring any errors.") (interactive) (let ((pos (point))) (condition-case nil (,(intern org-shiftmeta-function)) ('error (goto-char pos)))))) ;; safe versions of org-meta functions (org-safe-meta-function "org-metaleft" "org-safe-metaleft") (org-safe-meta-function "org-metaright" "org-safe-metaright") (org-safe-meta-function "org-metadown" "org-safe-metadown") (org-safe-meta-function "org-metaup" "org-safe-metaup") ;; safe versions of org-shiftmeta functions (org-safe-shiftmeta-function "org-shiftmetaleft" "org-safe-shiftmetaleft") (org-safe-shiftmeta-function "org-shiftmetaright" "org-safe-shiftmetaright") (org-safe-shiftmeta-function "org-shiftmetadown" "org-safe-shiftmetadown") (org-safe-shiftmeta-function "org-shiftmetaup" "org-safe-shiftmetaup")
org-sort-multi
Multiple sorts on a certain level of an outline tree, or plain list items.
;;------------------------------------------------------------------------------ ;;;; Org Mode: Functions: org-sort-multi ;;------------------------------------------------------------------------------ (init-message 3 "Org Mode: Functions: org-sort-multi") (defun org-sort-multi (sort-types) "Multiple sorts on a certain level of an outline tree, list items, or plan text. SORT-TYPES is a list where each entry is either a character or a list of parmeters to be passed to `org-sort-entries'. If COMPARE-FUNC is provided, but GETKEY-FUNC is nil, then the header string will be used. Example: To sort first by TODO status, then by priority, then by date, then alphabetically (case-sensitive) use the following call: (org-sort-multi '(?o ?p ?t (t ?a)) Example: To sort using `string<' use the following call: (org-sort-multi '((nil ?f nil #'string<)))" (save-mark-and-excursion (forward-line 0) (let ((type (car (org-element-at-point)))) (dolist (x (nreverse sort-types)) (when (characterp x) (setq x (list nil x))) (when (and (listp x) (> (length x) 3) (not (nth 2 x))) (setq x `(,(car x) ,(cadr x) (lambda () (replace-regexp-in-string "^[\*]*[ \t]*" "" (buffer-substring-no-properties (line-beginning-position) (line-end-position)))) (lambda (a b) (funcall ,(cadddr x) a b)) ,@(cddddr x)))) (cl-case type ('headline (condition-case nil (outline-up-heading 1) ('error (forward-line 0))) (let ((beg (point))) (while (and (not (bobp)) (not (eobp)) (<= (point) beg)) (condition-case nil (outline-forward-same-level 1) ('error (condition-case nil (outline-up-heading 1) ('error (goto-char (point-max))))))) (unless (> (point) beg) (goto-char (point-max))) (let ((end (point))) (goto-char beg) (ignore-errors (apply #'org-sort-entries x)) (goto-char end) (when (eobp) (forward-line -1)) (when (looking-at "^\\s-*$") (delete-line)) (goto-char beg) (dotimes (_ 2) (org-cycle))))) ('paragraph (let* ((plist (cadr (org-element-at-point))) (beg (plist-get plist :contents-begin)) (end (plist-get plist :contents-end))) (sort-lines nil beg end))) (t (ignore-errors (apply #'org-sort-list x))))))))
org-sort-current
Sort the current org level.
;;------------------------------------------------------------------------------ ;;;; Org Mode: Functions: org-sort-current ;;------------------------------------------------------------------------------ (init-message 3 "Org Mode: Functions: org-sort-current") (defun org-sort-current (&optional sort-types) "Sort the current org level. SORT-TYPES is a list where each entry is either a character or a list of parmeters to be passed to `org-sort-entries'. If COMPARE-FUNC is provided, but GETKEY-FUNC is nil, then the header string will be used. Entries are applied in back to front order. If entry at point has TODO and PRIORITY tags, then default SORT-TYPE is \"?o ?p ?t (nil ?f nil #'string<)\" which is to sort by TODO status, then by priority, then by timestamp, and finally by ASCII code. Otherwise, default SORT-TYPE is \"(nil ?f nil #'string<)\" which is to sort by ASCII code." (interactive) (when (derived-mode-p 'org-mode) (let ((sort-types (or sort-types (if (and (eq (car (org-element-at-point)) 'headline) (org-entry-get nil "TODO") (org-entry-get nil "PRIORITY")) '(?o ?p ?t (nil ?f nil #'string<)) '((nil ?f nil #'string<)))))) (org-sort-multi sort-types))))
org-fill-element–adapt-indentation
(defun org-fill-element--adapt-indentation (orig-fun &rest args) "Modify `fill-column' based on current org block indentation." (with-syntax-table org-mode-transpose-word-syntax-table (let* ((element (save-excursion (end-of-line) (org-element-at-point))) (type (org-element-type element))) (if (or (eq type 'paragraph) (eq type 'comment-block) (eq type 'comment)) (let ((indent-min fill-column) (fc fill-column) (point (point))) ;; goto start of element block (while (and (not (bobp)) (eq type (org-element-type (org-element-at-point))) (forward-line -1))) (unless (eq type (org-element-type (org-element-at-point))) (forward-line 1)) ;; find minimum indent of entire element block (while (and (not (eobp)) (eq type (org-element-type (org-element-at-point)))) (when (and (not (= (line-beginning-position) (line-end-position))) (re-search-forward "^ *" (line-end-position) :noerror) (< (current-column) indent-min)) (setq indent-min (current-column))) (forward-line 1)) (goto-char point) ;; set temporary `fill-column' (let ((fill-column (+ fill-column indent-min))) (apply orig-fun args))) (apply orig-fun args))))) ;; advise `org-fill-element' to set `fill-column' correctly (advice-add 'org-fill-element :around #'org-fill-element--adapt-indentation)
org-copy-to-clipboard
Copy `org-mode' region (or entire buffer) to the `kill-ring' and X clipboard, indenting and cleaning up links.
;;------------------------------------------------------------------------------ ;;;; Org Mode: Functions: org-copy-to-clipboard ;;------------------------------------------------------------------------------ (init-message 3 "Org Mode: Functions: org-copy-to-clipboard") (defun org-copy-to-clipboard (&optional beg end) "Copy `org-mode' region (or entire buffer) to the `kill-ring' and X clipboard, indenting and cleaning up links." (interactive) (let ((beg (or beg (if (use-region-p) (region-beginning) (point-min)))) (end (or end (if (use-region-p) (region-end) (point-max)))) (buffer (current-buffer))) (deactivate-mark) (with-temp-buffer (insert-buffer-substring buffer beg end) (untabify (point-min) (point-max)) (let ((indent-min fill-column)) ;; replace asterisks with spaces and determine minimum indent (goto-char (point-min)) (while (re-search-forward "^\\(*+ \\| *- \\)" nil :noerror) (replace-match (concat (make-string (- (match-end 0) (match-beginning 0) 2) ? ) "- ")) (when (< (- (current-column) 2) indent-min) (setq indent-min (- (current-column) 2))) (goto-char (line-end-position))) ;; if there are no headings in block, find minimum indent (when (= indent-min fill-column) (goto-char (point-min)) (while (not (eobp)) (when (and (not (= (line-beginning-position) (line-end-position))) (re-search-forward "^ *" (line-end-position) :noerror) (< (current-column) indent-min)) (setq indent-min (current-column))) (forward-line 1))) ;; indent to minimum indent (when (> indent-min 0) (goto-char (point-min)) (while (re-search-forward (concat "^" (make-string indent-min ? )) nil :noerror) (replace-match "") (goto-char (line-end-position)))) ;; replace links (goto-char (point-min)) (while (re-search-forward "\\[\\[\\(.*?\\)\\]\\[.*?\\]\\]" nil :noerror) (replace-match (match-string 1))) (clipboard-kill-region (point-min) (point-max))))))
org-fix-custom-ids
Fix all CUSTOMID tags in buffer by lower casing them and replacing spaces with dashes.
;;------------------------------------------------------------------------------ ;;;; Org Mode: Functions: org-fix-custom-ids ;;------------------------------------------------------------------------------ (init-message 3 "Org Mode: Functions: org-fix-custom-ids") (defun org-fix-custom-ids (&optional beg end) "Fix CUSTOM_ID tags in region (or entire buffer), by lower casing them and replacing spaces with dashes." (interactive) (let ((case-fold-search t) (beg (or beg (if (use-region-p) (region-beginning) (point-min)))) (end (or end (if (use-region-p) (region-end) (point-max)))) (buffer (current-buffer))) (deactivate-mark) (save-mark-and-excursion (save-restriction (save-match-data (narrow-to-region beg end) (goto-char (point-min)) (while (re-search-forward "^[ \t]*:PROPERTIES:$" nil :noerror) (forward-line 0) (forward-char 1) (while (and (not (looking-at "^[ \t]*:END:$")) (re-search-forward "^[ \t]*:CUSTOM_ID: " (line-end-position) :noerror)) (let ((pos (point))) (downcase-region pos (line-end-position)) (while (re-search-forward " " (line-end-position) :noerror) (replace-match "-")) (goto-char pos) (while (re-search-forward ":" (line-end-position) :noerror) (replace-match "-")) (forward-line 0) (forward-line 1)))))))))
org-update-last-modified-property
;;------------------------------------------------------------------------------ ;;;; Org Mode: Functions: org-update-last-modified-property ;;------------------------------------------------------------------------------ (init-message 3 "Org Mode: Functions: org-update-last-modified-property") (defun org-update-last-modified-property () "Update value of LAST-PROPERTY property to current timestamp, if found and buffer has been modified." (when (buffer-modified-p) (save-mark-and-excursion (save-match-data (let ((case-fold-search t)) (goto-char (point-min)) (when (re-search-forward "^[ \t]*#\\+LAST_MODIFIED: \\(.*\\)$" nil :noerror) (replace-match (format-time-string "%Y-%m-%d %H:%M" nil t) t t nil 1)))))))
org-export-to-json
;;------------------------------------------------------------------------------ ;;;; Org Mode: Functions: org-export-to-json ;;------------------------------------------------------------------------------ (init-message 3 "Org Mode: Functions: org-export-to-json") ;; adapted from https://github.com/mattduck/org-toggl-py/blob/master/org-export-json.el (use-package json :straight (:type built-in) :commands (json-encode) :config (defun org-export-to-json (&optional output beg end) "Export the outline as JSON. IF OUTPUT is nil, a default output buffer will be created and exported into. If OUTPUT is non-nil, create a buffer with that name and export to it. If OUTPUT is the symbol 'string, exported data is returned as a string. If BEG and END are given, only that region is exported." (interactive) (let ((beg (or beg (if (use-region-p) (region-beginning) (point-min)))) (end (or end (if (use-region-p) (region-end) (point-max))))) (deactivate-mark) (save-mark-and-excursion (save-restriction (narrow-to-region beg end) (let ((tree (org-element-parse-buffer))) (org-element-map tree (append org-element-all-elements org-element-all-objects '(plain-text)) (lambda (x) (when (org-element-property :parent x) (org-element-put-property x :parent "none")) (when (org-element-property :structure x) (org-element-put-property x :structure "none")))) (if (eq output 'string) (json-encode tree) (let ((buffer (generate-new-buffer (or output (concat buffer-file-name ".json"))))) (set-buffer buffer) (insert (json-encode tree)) (switch-to-buffer buffer)))))))))
org-toggle-headline-checkbox
Toggle between an Org headline and checkbox on current line.
;;------------------------------------------------------------------------------ ;;;; Org Mode: Functions: org-toggle-headline-checkbox ;;------------------------------------------------------------------------------ (init-message 3 "Org Mode: Functions: org-toggle-headline-checkbox") (defun org-toggle-headline-checkbox (&optional beg end) "Toggle between an Org headline and checkbox on current line or region." (interactive) (let ((beg (or beg (if (use-region-p) (region-beginning) (line-beginning-position)))) (end (or end (if (use-region-p) (region-end) (line-end-position))))) (deactivate-mark) (save-mark-and-excursion (save-restriction (save-match-data (narrow-to-region beg end) (goto-char (point-min)) (while (not (eobp)) (forward-line 0) (if (re-search-forward "^\\*+ " (line-end-position) :noerror) (replace-match (concat (make-string (- (point) (line-beginning-position) 2) ? ) "- [ ] ")) (forward-line 0) (when (re-search-forward "^[ \t]*- \\[[ X]\\] " (line-end-position) :noerror) (replace-match (concat (make-string (- (point) (line-beginning-position) 5) ?*) " ")))) (forward-line 1)))))))
org-table-remove-commas
Remove all commas in current Org table.
;;------------------------------------------------------------------------------ ;;;; Org Mode: Functions: org-table-remove-commas ;;------------------------------------------------------------------------------ (init-message 3 "Org Mode: Functions: org-table-remove-commas") (defun org-table-remove-commas () "Remove all commas in current Org table." (interactive) (save-mark-and-excursion (save-match-data (goto-char (org-table-begin)) (while (re-search-forward "," (org-table-end) :noerror) (replace-match "")))))
org-days-between-dates
Calculate the number of days (inclusive) between two given dates.
;;------------------------------------------------------------------------------ ;;;; Org Mode: Functions: org-days-between-dates ;;------------------------------------------------------------------------------ (init-message 3 "Org Mode: Functions: org-days-between-dates") (defun org-days-between-dates (beg end) "Return the number of days between BEG (inclusive) and END (exclusive). Where BEG and END dates are in one of these formats: YYYY YYYYMM YYYYMMDD YYYY-MM YYYY-MM-DD" (cl-labels ((convert-date (date) (calendar-absolute-from-gregorian (org-date-to-gregorian date))) (pad-date (date) (let ((date (if (stringp date) date (number-to-string date)))) (cl-case (length date) (4 (concat date "-01-01")) (6 (concat (substring date 0 4) "-" (substring date 4) "-01")) (7 (concat date "-01")) (8 (concat (substring date 0 4) "-" (substring date 4 6) "-" (substring date 6))) (10 date))))) (let ((beg (convert-date (pad-date beg))) (end (convert-date (pad-date end))) x) (when (> beg end) (setq x beg beg end end x)) (- end beg))))
org-copy-tangled-sections
Copy section blocks from a tangled file to another generated file. This is used to generate Emacs initialization files consisting of only the needed configurations for specific batch processing tasks.
;;------------------------------------------------------------------------------ ;;;; Org Mode: Functions: org-copy-tangled-sections ;;------------------------------------------------------------------------------ (init-message 3 "Org Mode: Functions: org-copy-tangled-sections") (defun org-copy-tangled-sections (source-file target-file sections &optional prefix) "Copy section blocks from tangled SOURCE-FILE to TARGET-FILE that match the names in SECTIONS. If PREFIX is non-nil, insert it verbatim at the top of the TARGET-FILE." ;; create buffer for target-file (let ((buffer (find-file-noselect target-file))) (set-buffer buffer) (erase-buffer) ;; insert header (insert ";; -*- mode: emacs-lisp; lexical-binding: t; no-byte-compile: t -*-\n") (insert ";;==============================================================================\n") (insert ";;; " (file-name-nondirectory target-file) "\n") (insert ";;\n") (insert ";; This file was generated from " (file-name-nondirectory source-file) ".\n") (insert ";;==============================================================================\n\n") ;; insert optional prefix (when prefix (insert (concat prefix "\n"))) ;; insert section blocks (with-temp-buffer (insert-file-contents source-file) (dolist (section sections) (goto-char (point-min)) (re-search-forward (concat "^[ \t]*" section "$")) (forward-line 0) (forward-line -1) (unless (looking-at "^[ \t]*;;--") (forward-line 1)) (let ((beg (point)) (end (progn (re-search-forward (concat "^[ \t]*;; .* ends here$")) (forward-line 0) (forward-line 1) (point)))) (append-to-buffer buffer beg end)))) ;; remove all `init-message' calls (goto-char (point-min)) (while (re-search-forward "^[ \t]*(init-message [0-9] \"\\(.*\\)\")$" nil :noerror) (delete-region (1- (line-beginning-position)) (1+ (line-end-position)))) ;; remove all ';; ... ends here' lines (goto-char (point-min)) (while (re-search-forward "^[ \t]*;; .* ends here$" nil :noerror) (forward-line 0) (delete-region (line-beginning-position) (line-end-position))) (goto-char (point-max)) ;; insert footer (insert ";;==============================================================================\n") (insert ";;; " (file-name-nondirectory target-file) " ends here\n") (insert ";;==============================================================================\n") ;; save and close buffer (save-buffer) (kill-buffer buffer)))
org-screenshot
;;------------------------------------------------------------------------------ ;;;; Org Mode: Functions: org-screenshot ;;------------------------------------------------------------------------------ (init-message 3 "Org Mode: Functions: org-screenshot") ;; take a screenshot and insert org link (defun org-screenshot () "Take a screenshot into a time stamped unique-named file in the same directory as the org-buffer and insert a link to this file." (interactive) ;; (let ((file (concat ;; (make-temp-name ;; (concat (buffer-file-name) ;; "_" ;; (format-time-string "%Y%m%d_%H%M%S_"))) ;; ".png"))) (let ((file (concat (buffer-file-name) "_" (format-time-string "%Y%m%d_%H%M%S") ".png"))) (call-process "import" nil nil nil file) (insert (concat "[[" file "]]\n"))))
org-convert-headings-from-odd-indented-to-oddeven-unindented
;;------------------------------------------------------------------------------ ;;;; Org Mode: Functions: org-convert-headings-from-odd-indented-to-oddeven-unindented ;;------------------------------------------------------------------------------ (init-message 3 "Org Mode: Functions: org-convert-headings-from-odd-indented-to-oddeven-unindented") (defun org-convert-headings-from-odd-indented-to-oddeven-unindented (&optional buffer) "Convert Org BUFFER from having only odd heading levels and indented body data (`org-odd-levels-only' and `org-adapt-indentation') to having odd and even heading levels and non-indented body data (`org-indent-mode'). If BUFFER is nil, current buffer is used." (unless (derived-mode-p 'org-mode) (user-error "Not an Org buffer")) (with-current-buffer (or buffer (current-buffer)) (save-mark-and-excursion (goto-char (point-min)) (while (re-search-forward "^\\(\\*+\\) " nil :noerror) (when (evenp (length (match-string 1))) (user-error "Even headings found"))) (goto-char (point-min)) (let ((spaces 0)) (while (not (eobp)) (cond ((looking-at "^\\(\\*+\\) ") (let ((level (/ (1+ (length (match-string 1))) 2))) (replace-match (make-string level ?*) nil nil nil 1) (setq spaces (* level 2)))) ((looking-at (concat "^" (make-string spaces ? ) "\\*")) (replace-match ",*")) ((looking-at (concat "^" (make-string spaces ? ))) (replace-match ""))) (forward-line 1))))))
org-convert-headings-from-oddeven-unindented-to-odd-indented
;;------------------------------------------------------------------------------ ;;;; Org Mode: Functions: org-convert-headings-from-oddeven-unindented-to-odd-indented ;;------------------------------------------------------------------------------ (init-message 3 "Org Mode: Functions: org-convert-headings-from-oddeven-unindented-to-odd-indented") (defun org-convert-headings-from-oddeven-unindented-to-odd-indented (&optional buffer) "Convert Org BUFFER from having odd and even heading levels and non-indented body data (`org-indent-mode') to having only odd heading levels and intended body data (`org-odd-levels-only' and `org-adapt-indentation'). If BUFFER is nil, current buffer is used." (unless (derived-mode-p 'org-mode) (user-error "Not an Org buffer")) (with-current-buffer (or buffer (current-buffer)) (save-mark-and-excursion (goto-char (point-min)) (let (even subheading) (while (re-search-forward "^\\(\\*+\\) " nil :noerror) (when (evenp (length (match-string 1))) (setq even t)) (when (> (length (match-string 1)) 2) (setq subheading t))) (when (and subheading (not even)) (user-error "Only odd headings found"))) (goto-char (point-min)) (let ((spaces 0)) (while (not (eobp)) (cond ((looking-at "^\\(\\*+\\) ") (let ((level (length (match-string 1)))) (replace-match (make-string (1- (* level 2)) ?*) nil nil nil 1) (setq spaces (* level 2)))) ((looking-at "^,\\*") (replace-match (concat (make-string spaces ? ) "*"))) ((not (looking-at "^$")) (insert (make-string spaces ? )))) (forward-line 1))))))
org-insert-header
;;------------------------------------------------------------------------------ ;;;; Functions: Text Inserting Functions: org-insert-header ;;------------------------------------------------------------------------------ (init-message 3 "Functions: Text Inserting Functions: org-insert-header") (defun org-insert-header () "Insert literate programming header." (interactive "*") (let ((text `("* Org :noexport:" "#+TITLE: TITLE" "#+AUTHOR: Kyle W. T. Sherman" ,(concat "#+EMAIL: " user-mail-address) "#+FILENAME: FILENAME.org" "#+DESCRIPTION: DESCRIPTION" "#+KEYWORDS: KEYWORD, emacs, org-mode, babel, literate programming, reproducible research" "#+LANGUAGE: en" "#+PROPERTY: header-args :noweb yes :padline yes :comments no :results silent output :mkdirp yes :cache yes" "#+OPTIONS: num:nil toc:nil d:(HIDE) tags:not-in-toc html-preamble:nil html-postamble:nil" "#+STARTUP: noindent odd overview" "#+TIMESTAMP: <>" ""))) (dolist (x text) (insert x) (newline))))
org-insert-table
;;------------------------------------------------------------------------------ ;;;; Functions: Text Inserting Functions: org-insert-table ;;------------------------------------------------------------------------------ (init-message 3 "Functions: Text Inserting Functions: org-insert-table") (defun org-insert-table () "Insert table template." (interactive "*") (let ((text '("|---|" "| |" "|---|" "| |" "|---|"))) (dolist (x text) (insert x) (newline))))
org-insert-toc-header
;;------------------------------------------------------------------------------ ;;;; Functions: Text Inserting Functions: org-insert-toc-header ;;------------------------------------------------------------------------------ (init-message 3 "Functions: Text Inserting Functions: org-insert-toc-header") (defun org-insert-toc-header () "Insert table of contents (TOC) header." (interactive "*") (let ((text `("* Table of Contents" " :PROPERTIES:" " :CUSTOM_ID: table-of-contents" " :TOC: :include all" " :END:" "" " :CONTENTS:" " :END:" ""))) (dolist (x text) (insert x) (newline))))
Hook
Org Mode hook configuration.
;;------------------------------------------------------------------------------ ;;; Org Mode: Hook ;;------------------------------------------------------------------------------ (init-message 2 "Org Mode: Hook") (defun custom-org-mode-hook () "Custom `org-mode' hook." ;; remappings (bind-keys :map org-mode-map ([remap org-metaleft] . org-safe-metaleft) ([remap org-metaright] . org-safe-metaright) ([remap org-metadown] . org-safe-metadown) ([remap org-metaup] . org-safe-metaup) ([remap org-shiftmetaleft] . org-safe-shiftmetaleft) ([remap org-shiftmetaright] . org-safe-shiftmetaright) ([remap org-shiftmetadown] . org-safe-shiftmetadown) ([remap org-shiftmetaup] . org-safe-shiftmetaup)) ;; local key bindings (bind-keys :map org-mode-map ("M-n" . scroll-up) ("M-p" . scroll-down) ("M-W" . org-copy-to-clipboard) ("C-M-b" . org-metaleft) ("C-M-f" . org-metaright) ("C-M-n" . org-metadown) ("C-M-p" . org-metaup) ("C-M-B" . org-shiftmetaleft) ("C-M-F" . org-shiftmetaright) ("C-M-N" . org-shiftmetadown) ("C-M-P" . org-shiftmetaup) ;;("C-c C-<return>" . org-insert-heading) ("C-c a" . org-agenda) ("C-c l" . org-store-link) ("C-c m" . org-insert-todo-heading) ("C-c p" . org-priority) ; "C-c ," gets overridden by `semantic-complete-analyze-inline' ("C-c s" . org-sort-current) ; sort current level ("C-c z" . org-agenda-archive-done-tasks) ; archive done tasks ;;("C-c C-j" . counsel-org-goto) ; default: `org-goto' ("C-c C-j" . consult-org-heading) ; default: `org-goto' ;;("C-c C-z" . switch-to-lisp) ; default: `org-add-note' ("C-c C-z" . geiser-mode-switch-to-repl) ; default: `org-add-note' ("C-c C-x C-l" . org-toggle-link-display) ; toggle showing or hiding links ("C-c C-x t" . org-toggle-headline-checkbox) ; toggle between headline and checkbox ("C-c C-x T" . org-toggle-literate-programming-code-block) ; toggle literate programming code block on/off ("C-c C-x F" . org-fix-literate-programming-heading) ; fix literate programming heading of current org section ("C-c C-v q" . org-babel-tangle-block) ; tangle current source block ("C-c C-v C-q" . org-babel-tangle-block)) ; tangle current source block ;; custom movement keys (custom-key-bindings-movement-keys org-mode-map) ;; ;; work functions ;; (when (fboundp 'work-linkify-jira-card) ;; (bind-keys :map org-mode-map ("C-c C-x L" . work-linkify-jira-card))) ;; make sure tabs are not inserted (setq indent-tabs-mode nil) ;; turn off auto-fill (turn-off-auto-fill) ;; turn off auto-save (auto-save-mode nil) ;; turn off flyspell ;; (when (fboundp 'flyspell-mode-off) ;; (flyspell-mode-off)) ) (use-package org :straight (:type built-in) :hook (org-mode . custom-org-mode-hook))
Babel
Org/Babel customizations and supporting functions.
;;------------------------------------------------------------------------------ ;;; Org Mode: Babel ;;------------------------------------------------------------------------------ (init-message 2 "Org Mode: Babel")
Configuration
Configure org-babel
.
;;------------------------------------------------------------------------------ ;;;; Org Mode: Babel: Configuration ;;------------------------------------------------------------------------------ (init-message 3 "Org Mode: Babel: Configuration") ;; load ob-shell (use-package org :straight (:type built-in) :config (require 'ob-shell nil :no-error)) ;; load ob-async (use-package ob-async :straight t :after (org)) ;; babel settings ;; do not set `org-src-fontify-natively' to true as this breaks org-table-align->font-lock-fontify-region ;; `org-src-fontify-natively' also creates temp files that are not always cleaned up (setq org-use-property-inheritance t org-babel-use-quick-and-dirty-noweb-expansion t org-src-tab-acts-natively t org-src-preserve-indentation nil org-src-fontify-natively t org-src-ask-before-returning-to-edit-buffer nil org-src-strip-leading-and-trailing-blank-lines t org-src-window-setup 'current-window org-confirm-babel-evaluate nil org-confirm-shell-link-function nil org-confirm-elisp-link-function nil) ;; exportable file types (set-default 'org-export-backends '(ascii html icalendar latex md odt org)) ;; ;; delete trailing white space on tangle ;; (add-hook 'org-babel-post-tangle-hook #'delete-trailing-whitespace) ;; (add-hook 'org-babel-post-tangle-hook #'save-buffer :append) ;; update images in buffer after evaluation (add-hook 'org-babel-after-execute-hook #'org-display-inline-images :append) ;; org-eldoc is just too buggy with org-babel ;; Examples: ;; ":tangle-mode (identity #o600)" throws ;; "#+BEGIN_SRC org" goes into an infinite loop ;; (use-package org-eldoc ;; :straight (:type built-in) ;; :commands (global-eldoc-mode) ;; :config (progn ;; ;; turn off eldoc mode ;; (global-eldoc-mode -1))) ;; ;; FIXME: temporary fix for org-eldoc-documentation-function ;; (use-package org-eldoc ;; :straight (:type built-in) ;; :commands (org-eldoc-get-breadcrumb ;; org-eldoc-get-mode-local-documentation-function ;; org-eldoc-get-src-header ;; org-eldoc-get-src-lang) ;; :functions (c-eldoc-print-current-symbol-info ;; css-eldoc-function ;; eldoc-print-current-symbol-info ;; go-eldoc--documentation-function ;; org-eldoc-documentation-function ;; php-eldoc-function) ;; :config ;; ;; fix `org-eldoc-documentation-function' so it does not recursively call in org lang babel blocks ;; (defun org-eldoc-documentation-function () ;; "Return breadcrumbs when on a headline, args for src block header-line, ;; calls other documentation functions depending on lang when inside src body. ;; [Custom fix for recursive bug]" ;; (or ;; (org-eldoc-get-breadcrumb) ;; (org-eldoc-get-src-header) ;; (let ((lang (org-eldoc-get-src-lang))) ;; (cond ((or ;; (string= lang "emacs-lisp") ;; (string= lang "elisp")) (if (fboundp 'elisp-eldoc-documentation-function) ;; (elisp-eldoc-documentation-function) ;; (let (eldoc-documentation-function) ;; (eldoc-print-current-symbol-info)))) ;; ((or ;; (string= lang "c") ;; http://github.com/nflath/c-eldoc ;; (string= lang "C")) (when (require 'c-eldoc nil :no-error) ;; (c-eldoc-print-current-symbol-info))) ;; ;; https://github.com/zenozeng/css-eldoc ;; ((string= lang "css") (when (require 'css-eldoc nil :no-error) ;; (css-eldoc-function))) ;; ;; https://github.com/zenozeng/php-eldoc ;; ((string= lang "php") (when (require 'php-eldoc nil :no-error) ;; (php-eldoc-function))) ;; ((or ;; (string= lang "go") ;; (string= lang "golang")) (when (require 'go-eldoc nil :no-error) ;; (go-eldoc--documentation-function))) ;; (t (let ((doc-fun (org-eldoc-get-mode-local-documentation-function lang))) ;; (when (and (functionp doc-fun) (not (string= doc-fun "org-eldoc-documentation-function"))) ;; (funcall doc-fun)))))))))
Structure Templates
Add templates to org-structure-template-alist
and
org-tempo-keywords-alist
. Customize org-tempo
so headers are in uppercase.
;;------------------------------------------------------------------------------ ;;;; Org Mode: Babel: Structure Templates ;;------------------------------------------------------------------------------ (init-message 3 "Org Mode: Babel: Structure Templates") (use-package org-tempo :straight (:type built-in) :custom ;; set keyword completion elements (org-tempo-keywords-alist '(("A" . "ascii") ;;("c" . "call") ("H" . "html") ("i" . "index") ("L" . "latex") ("n" . "name"))) ;; set block types (org-structure-template-alist '(("c" . "center") ("C" . "comment") ("e" . "example") ("E" . "export") ("ea" . "export ascii") ("eh" . "export html") ("el" . "export latex") ("o" . "src org") ("q" . "quote") ("s" . "src") ("sel" . "src emacs-lisp") ("sk" . "src kotlin") ("sl" . "src latex") ("spy" . "src python") ("sql" . "src sql") ("sr" . "src racket") ("ssh" . "src sh") ("ssu" . "src sh :dir /sudo::") ("t" . "src text") ("v" . "verse"))) :config ;; custom `org-tempo-add-block' with upcase headers (defun org-tempo-add-block (entry) "Add block entry from `org-structure-template-alist'." (let* ((key (format "<%s" (car entry))) (name (cdr entry)) (name-parts (split-string name " ")) (upcase-type (upcase (car name-parts))) (upcase-name (mapconcat 'identity (cons upcase-type (cdr name-parts)) " ")) (special (member name '("src" "export")))) (tempo-define-template (format "org-%s" (replace-regexp-in-string " " "-" name)) `(,(format "#+BEGIN_%s%s" upcase-name (if special " " "")) ,(when special 'p) '> n '> ,(unless special 'p) n ,(format "#+END_%s" upcase-type) >) key (format "Insert a %s block" upcase-name) 'org-tempo-tags))) ;; custom `org-tempo-add-keyword' with upcase headers (defun org-tempo-add-keyword (entry) "Add keyword entry from `org-tempo-keywords-alist'." (let* ((key (format "<%s" (car entry))) (name (cdr entry)) (upcase-name (upcase name))) (tempo-define-template (format "org-%s" (replace-regexp-in-string " " "-" name)) `(,(format "#+%s: " upcase-name) p '>) key (format "Insert a %s keyword" upcase-name) 'org-tempo-tags))) ;; custom `org-tempo--include-file' with upcase header (defun org-tempo--include-file () "Add #+INCLUDE: and a file name." (let ((inhibit-quit t)) (unless (with-local-quit (prog1 t (insert (format "#+INCLUDE: %S " (file-relative-name (read-file-name "Include file: ")))))) (insert "<I") (setq quit-flag nil)))) ;; update templates (org-tempo-add-templates) ;; disable `org-src-tab-acts-natively' during template indentation (defun tempo-insert--disable-org-src-tab-acts-natively (orig-fun &rest args) "Disable `org-src-tab-acts-natively' during template indentation." (let ((org-src-tab-acts-natively nil)) (apply orig-fun args))) ;; advise `tempo-insert' (advice-add 'tempo-insert :around #'tempo-insert--disable-org-src-tab-acts-natively)) ;; ;; upcase begin_src and end_src block headers ;; (defun org-insert-structure-template--upcase (type) ;; "Upcase #+begin_src and #+end_src block headers." ;; (save-mark-and-excursion ;; (let ((case-fold-search nil)) ; case sensitive search ;; (forward-line -1) ;; (when (re-search-forward "^[ \t]*#\\+begin_[a-z]*" (line-end-position) :noerror) ;; (replace-match (upcase (match-string 0))) ;; (forward-line 2) ;; (when (re-search-forward "^[ \t]*#\\+end_[a-z]*" (line-end-position) :noerror) ;; (replace-match (upcase (match-string 0)))))))) ;; ;; advise `org-insert-structure-template' ;; (advice-add 'org-insert-structure-template :after #'org-insert-structure-template--upcase) ;; ;; upcase include header ;; (defun org-tempo--include-file--upcase () ;; "Upcase #+include: header." ;; (save-mark-and-excursion ;; (let ((case-fold-search nil)) ; case sensitive search ;; (forward-line 0) ;; (when (re-search-forward "^[ \t]*#\\+include: " (line-end-position) :noerror) ;; (replace-match (upcase (match-string 0))))))) ;; ;; advise `org-tempo--include-file' ;; (advice-add 'org-tempo--include-file :after #'org-tempo--include-file--upcase))
Edit Source
Customize Org/Babel org-edit-src-exit
.
- It will update LASTMODIFIED property timestamp on source update.
- It will
recenter
when going in/out of edit mode.
;;------------------------------------------------------------------------------ ;;;; Org Mode: Babel: Edit Source ;;------------------------------------------------------------------------------ (init-message 3 "Org Mode: Babel: Edit Source") (use-package org :straight (:type built-in) :commands (org-edit-src-code org-edit-src-exit) :config (require 'org-src) ;; make sure custom key bindings are set in `org-src-mode' (add-hook 'org-src-mode-hook #'custom-key-bindings-set-all) (defun org-edit-src-exit--update-last-modified () "Update LAST_MODIFIED property timestamp on source update." (org-update-last-modified-property)) ;; advise `org-edit-src-exit' (advice-add 'org-edit-src-exit :before #'org-edit-src-exit--update-last-modified) (defun org-edit-src--recenter (&optional arg) "Recenter when entering/exiting special editors." (recenter)) ;; advise `org-edit-special' (advice-add 'org-edit-special :after #'org-edit-src--recenter) ;; advise `org-edit-src-exit' (advice-add 'org-edit-src-exit :after #'org-edit-src--recenter))
Tangle Case-Sensitive
Customize Org/Babel org-babel-tangle-collect-blocks
so it will use
case-sensitive string matches. (This is to insure that headlines starting with
"Comment" do not act like "COMMENT".)
;;------------------------------------------------------------------------------ ;;;; Org Mode: Babel: Tangle Case-Sensitive ;;------------------------------------------------------------------------------ (init-message 3 "Org Mode: Babel: Tangle Case-Sensitive") (defun org-babel-tangle-collect-blocks--case-sensitive (orig-fun &rest args) "Set `case-fold-search' to nil so `string-match' calls are case-sensitive." (let ((case-fold-search nil)) (apply orig-fun args))) ;; advise `org-babel-tangle-collect-blocks' making it case-sensitive (advice-add 'org-babel-tangle-collect-blocks :around #'org-babel-tangle-collect-blocks--case-sensitive)
Tangle Update Timestamps
Update timestamps using time-stamp
in tangled files.
;;------------------------------------------------------------------------------ ;;;; Org Mode: Babel: Tangle Update Timestamps ;;------------------------------------------------------------------------------ (init-message 3 "Org Mode: Babel: Tangle Update Timestamps") (defun org-babel-post-tangle-hook--time-stamp () "Update timestamps in tangled files." (time-stamp) (save-buffer)) (add-hook 'org-babel-post-tangle-hook #'org-babel-post-tangle-hook--time-stamp)
Tangle Delete Trailing Whitespace
Delete trailing whitespace in tangled files.
;;------------------------------------------------------------------------------ ;;;; Org Mode: Babel: Tangle Delete Trailing Whitespace ;;------------------------------------------------------------------------------ (init-message 3 "Org Mode: Babel: Tangle Delete Trailing Whitespace") (defun org-babel-post-tangle-hook--delete-trailing-whitespace () "Delete trailing whitespace in tangled files." (delete-trailing-whitespace (point-min) (point-max)) (save-buffer)) (add-hook 'org-babel-post-tangle-hook #'org-babel-post-tangle-hook--delete-trailing-whitespace)
Tangle Makefile Tabs
Convert spaces to tabs when tanging =Makefile=s.
;; ;;------------------------------------------------------------------------------ ;; ;;;; Org Mode: Babel: Tangle Makefile Tabs ;; ;;------------------------------------------------------------------------------ ;; (init-message 3 "Org Mode: Babel: Tangle Makefile Tabs") ;; (defun org-babel-post-tangle-hook--makefile-tabs () ;; "Convert spaces to tabs when tanging Makefiles." ;; (when (eq major-mode 'makefile-mode) ;; (goto-char (point-min)) ;; (while (re-search-forward " " nil :noerror) ;; (replace-match " ")))) ;; (add-hook 'org-babel-post-tangle-hook #'org-babel-post-tangle-hook--makefile-tabs)
Tangle Generate PDF from TEX
If a TEX file was generated, attempt to also generate a PDF.
;;------------------------------------------------------------------------------ ;;;; Org Mode: Babel: Tangle Generate PDF from TEX ;;------------------------------------------------------------------------------ (init-message 3 "Org Mode: Babel: Tangle Generate PDF from TEX") (defun org-babel-post-tangle-hook--generate-pdf-from-tex () "Generate PDF from tangled TEX file." (let ((case-fold-search t) (filename (expand-file-name (buffer-file-name))) (output "*PDFLaTeX Output*")) (when (string= (file-name-extension filename) "tex") (shell-command (concat "pdflatex -output-directory=" temporary-file-directory " -halt-on-error \"" filename "\" && " "cp \"" temporary-file-directory (file-name-sans-extension (file-name-nondirectory filename)) ".pdf" "\" " "\"" (file-name-sans-extension filename) ".pdf" "\"") output)))) (add-hook 'org-babel-post-tangle-hook #'org-babel-post-tangle-hook--generate-pdf-from-tex)
Racket
Customize Org/Babel for Racket so it works.
;;------------------------------------------------------------------------------ ;;;; Org Mode: Babel: Racket ;;------------------------------------------------------------------------------ (init-message 3 "Org Mode: Babel: Racket") (use-package ob-racket :straight (ob-racket :type git :host github :repo "hasu/emacs-ob-racket" :files ("*.el" "*.rkt")) :after (org) :config (add-hook 'ob-racket-pre-runtime-library-load-hook #'ob-racket-raco-make-runtime-library) ;; ;; default to racket-mode for racket files ;; (defvar org-babel-tangle-lang-exts) ;; (add-to-list 'org-babel-tangle-lang-exts '("racket" . "rkt")) (defvar org-babel-racket-command "racket") (defvar org-babel-default-header-args:racket '()) (defvar org-babel-header-args:racket '((package . :any))) (defun org-babel-execute:racket (body params) "Execute a block of Racket Scheme code with Babel. BODY is the contents of the block, as a string. PARAMS is a property list containing the parameters of the block. This function is called by `org-babel-execute-src-block'." (let ((result ;; if there is a #lang line then geiser racket session wont work (if (with-temp-buffer (insert (org-babel-expand-body:lisp body params)) (goto-char (point-min)) (re-search-forward "^[ \t]*#lang +\\([^ ]+\\)" nil :noerror)) ;; create temporary racket file and execute it for result (let ((src-file (org-babel-src-file "racket-" ".rkt"))) (with-temp-file src-file (insert (org-babel-expand-body:lisp body params))) (org-babel-eval (concat org-babel-racket-command " " src-file) "")) ;; otherwise, eval body in geiser racket session for result (funcall (if (member "output" (cdr (assq :result-params params))) (lambda (x) (cdr (assq (intern "output") x))) (lambda (x) (cdr (assq (intern "result") x)))) (with-temp-buffer (insert (org-babel-expand-body:lisp body params)) (racket-mode) ;; check for non-comment lines (goto-char (point-min)) (while (and (not (eobp)) (looking-at "^[ \t]*\\(;\\|$\\)")) (forward-line 1)) ;; only continue if there are non-comment lines ;; (otherwise geiser eval commands hang) (unless (eobp) (if (fboundp 'geiser-eval-region) (geiser-eval-region (point-min) (point-max) nil :raw) (error "geiser-eval-region not defined")))))))) (org-babel-reassemble-table (org-babel-result-cond (cdr (assq :result-params params)) result (condition-case nil (read (org-babel-lisp-vector-to-list result)) (error result))) (org-babel-pick-name (cdr (assq :colname-names params)) (cdr (assq :colnames params))) (org-babel-pick-name (cdr (assq :rowname-names params)) (cdr (assq :rownames params))))))) ;; (use-package ob-scheme ;; :straight (:type built-in) ;; :config (progn ;; ;; customize org/babel for scheme/racket so it works ;; (defcustom org-babel-scheme-command "racket -f" ;; "Name of the scheme command. ;; May be either a command in the path, like scheme ;; or an absolute path name, like /usr/local/bin/scheme ;; parameters may be used, like scheme -verbose" ;; :group 'org-babel ;; :type 'string) ;; (defcustom org-babel-scheme-compiler "racket" ;; "Name of the scheme compiler. ;; May be either a command in the path, like schemec ;; or an absolute path name, like /usr/local/bin/schemec ;; parameters may be used, like schemec -verbose" ;; :group 'org-babel ;; :type 'string) ;; ;; default to scheme-mode for racket files ;; (add-to-list 'org-babel-tangle-lang-exts '("scheme" . "rkt")) ;; ;; redefine `org-babel-scheme-make-session-name' to use ;; ;; implementation name if no session name is given ;; (defun org-babel-scheme-make-session-name (buffer name impl) ;; "Generate a name for the session buffer. ;; For a named session, the buffer name will be the session name. ;; If the session is unnamed (nil), generate a name. ;; If the session is `none', use an existing IMPL session if one exists, ;; otherwise use nil for the session name, and ;; org-babel-scheme-execute-with-geiser will use a temporary session." ;; (cond ;; ((not name) ;; (concat buffer " " (symbol-name impl) " REPL")) ;; ((string= name "none") ;; (and (org-babel-scheme-get-session-buffer impl) impl)) ;; (t ;; name))) ;; ;; redefine `org-babel-scheme-get-session-buffer' to add default ;; ;; racket geiser repl to `org-babel-scheme-repl-map' if running ;; (defun org-babel-scheme-get-session-buffer (session-name) ;; "Look up the scheme buffer for a session; return nil if it doesn't exist." ;; (org-babel-scheme-cleanse-repl-map) ; prune dead sessions ;; (let* ((impl (intern "racket")) ;; (buffer (get-buffer "* Racket REPL *"))) ;; (when (and buffer ;; (not (gethash impl org-babel-scheme-repl-map))) ;; (puthash impl buffer org-babel-scheme-repl-map))) ;; (gethash session-name org-babel-scheme-repl-map)))) ;; ;; (defun org-babel-scheme-get-session-buffer--add-geiser-repl (session-name) ;; ;; "Add default racket geiser repl to `org-babel-scheme-repl-map' if running." ;; ;; (let* ((impl (intern "racket")) ;; ;; (buffer (get-buffer "* Racket REPL *"))) ;; ;; (when (and buffer ;; ;; (not (gethash impl org-babel-scheme-repl-map))) ;; ;; (puthash impl buffer org-babel-scheme-repl-map)))) ;; ;; ;; advise `org-babel-scheme-get-session-buffer' ;; ;; (advice-add 'org-babel-scheme-get-session-buffer :before #'org-babel-scheme-get-session-buffer--add-geiser-repl)))
Java
Customize Org/Babel for Java so it will handle packages correctly.
;;------------------------------------------------------------------------------ ;;;; Org Mode: Babel: Java ;;------------------------------------------------------------------------------ (init-message 3 "Org Mode: Babel: Java") (use-package org :straight (:type built-in) :commands (org-babel-execute:java) :config (when (require 'ob-java nil :no-error) ;; customize org/babel for java so it will handle packages correctly (defun org-babel-execute:java (body params) "Execute a block of Java code with Babel. BODY is the contents of the block, as a string. PARAMS is a property list containing the parameters of the block." (let* ((classname (or (cdr (assoc :classname params)) (user-error ":classname parameter is required"))) (packagename (file-name-directory classname)) (src-file (concat classname ".java")) (javacflags (or (cdr (assoc :javacflags params)) "")) (javaflags (or (cdr (assoc :javaflags params)) "")) (full-body (org-babel-expand-body:generic body params))) ;; created package-name directories if missing (unless (or (not packagename) (file-exists-p packagename)) (make-directory packagename 'parents)) ;; compile java source file (with-temp-file src-file (insert full-body) (org-babel-eval (concat org-babel-java-compiler " " javacflags " " src-file) "")) ;; run java code (let ((result (org-babel-eval (concat org-babel-java-command " " javaflags " " classname) ""))) (org-babel-reassemble-table (org-babel-result-cond (cdr (assoc :result-params params)) (org-babel-read result) (let ((temp-file (org-babel-temp-file "java-"))) (with-temp-file temp-file (insert result) (org-babel-import-elisp-from-file temp-file)))) (org-babel-pick-name (cdr (assoc :colname-names params)) (cdr (assoc :colnames params))) (org-babel-pick-name (cdr (assoc :rowname-names params)) (cdr (assoc :rownames params)))))))))
Kotlin
Customize Org/Babel for Kotlin so it works. Specifically, if main function
exists, then compile code and run jar otherwise, run code in kotlin-repl
.
;;------------------------------------------------------------------------------ ;;;; Org Mode: Babel: Kotlin ;;------------------------------------------------------------------------------ (init-message 3 "Org Mode: Babel: Kotlin") (use-package ob-kotlin :straight t :after (org kotlin-mode) :commands (org-babel-execute:kotlin) :functions (flycheck-mode kotlin-send-buffer org-babel-kotlin-command) :defines (org-babel-kotlin-compiler) :config ;; customize org/babel for kotlin so it works (defcustom org-babel-kotlin-command "kotlin" "Name of the kotlin command. May be either a command in the path, like kotlin or an absolute path name, like /usr/local/bin/kotlin parameters may be used, like kotlin -verbose" :group 'org-babel :type 'string) (defcustom org-babel-kotlin-compiler "kotlinc" "Name of the kotlin compiler. May be either a command in the path, like kotlinc or an absolute path name, like /usr/local/bin/kotlinc parameters may be used, like kotlinc -verbose" :group 'org-babel :type 'string) (defun org-babel-execute:kotlin (body params) "If main function exists, then compile code and run jar otherwise, run code in `kotlin-repl'." (let* ((classname (or (cdr (assq :classname params)) "main")) ;;(packagename (file-name-directory classname)) (src-file (org-babel-temp-file classname ".kt")) (jar-file (concat (file-name-sans-extension src-file) ".jar")) (cmpflag (or (cdr (assq :cmpflag params)) "")) (cmdline (or (cdr (assq :cmdline params)) "")) (full-body (org-babel-expand-body:generic body params))) (if (or (string-match "fun main(args: Array<String>)" full-body) (string-match "fun main()" full-body)) (progn (with-temp-file src-file (insert full-body)) (org-babel-eval (concat org-babel-kotlin-compiler " " cmpflag " " src-file " -include-runtime -d " jar-file) "") (message (org-babel-eval (concat org-babel-java-command " " cmdline " -jar " jar-file) ""))) (with-temp-buffer (insert body) (kotlin-send-buffer))))))
Python (iPython Version)
Customize Org/Babel for Python so it works.
;; ;;------------------------------------------------------------------------------ ;; ;;;; Org Mode: Babel: Python ;; ;;------------------------------------------------------------------------------ ;; (init-message 3 "Org Mode: Babel: Python (iPython Version)") ;; (use-package ob-python ;; :straight (:type built-in) ;; :after (org python-mode) ;; :commands (org-babel-execute:python) ;; :config ;; (defun org-babel-execute:python (body params) ;; "Execute a block of Python code with Babel. ;; BODY is the contents of the block, as a string. PARAMS is ;; a property list containing the parameters of the block. ;; This function is called by `org-babel-execute-src-block'. ;; Note: This function only works with an iPython shell if it has ;; the autoindent feature turned off. Add '--no-autoindent' to ;; `py-ipython-command-args' to set this when an iPython process is ;; created." ;; (let* ((org-babel-python-command (or (cdr (assq :python params)) ;; org-babel-python-command)) ;; (session-name (cdr (assq :session params))) ;; (session (when (and session-name (not (string= session-name "none"))) ;; (org-babel-python-initiate-session session))) ;; (result-params (cdr (assq :result-params params))) ;; (result-type (cdr (assq :result-type params))) ;; (return-val (when (and (eq result-type 'value) (not session)) ;; (cdr (assq :return params)))) ;; (preamble (cdr (assq :preamble params))) ;; (process (get-process "ipython")) ;; (full-body ;; (org-babel-expand-body:generic ;; (concat body (if return-val (format "\nreturn %s" return-val) "")) ;; params (org-babel-variable-assignments:python params))) ;; (result (cond ;; (session ;; (org-babel-python-evaluate-session ;; session full-body result-type result-params)) ;; ;; (process ;; ;; (org-babel-python-evaluate-session ;; ;; (process-buffer process) full-body result-type result-params)) ;; (process ;; (process-send-string process (concat full-body "\n\n")) ;; ;; (process-send-string process (concat "%cpaste\n" full-body "\n--\n")) ;; (display-buffer (process-buffer process) t)) ;; ;; (process ;; ;; (let ((buffer (process-buffer process))) ;; ;; (display-buffer buffer t) ;; ;; (with-current-buffer buffer ;; ;; (goto-char (point-max)) ;; ;; (insert (concat "%cpaste\n" full-body "\n--\n"))))) ;; ;; (process ;; ;; (with-temp-buffer ;; ;; (insert full-body) ;; ;; (py-send-region (point-min) (point-max)))) ;; (t ;; (org-babel-python-evaluate-external-process ;; full-body result-type result-params preamble))))) ;; (org-babel-reassemble-table ;; result ;; (org-babel-pick-name (cdr (assq :colname-names params)) ;; (cdr (assq :colnames params))) ;; (org-babel-pick-name (cdr (assq :rowname-names params)) ;; (cdr (assq :rownames params))))))) ;; ;; (use-package ob-ipython ;; ;; :straight t ;; ;; :after (ob-python))
Python
Customize Org/Babel for Python so it works.
;;------------------------------------------------------------------------------ ;;;; Org Mode: Babel: Python ;;------------------------------------------------------------------------------ (init-message 3 "Org Mode: Babel: Python") (use-package org :straight (:type built-in) :after (python-mode) :commands (org-babel-execute:python) :config (when (require 'ob-python nil :no-error) (defun org-babel-execute:python (body params) "Execute a block of Python code with Babel. BODY is the contents of the block, as a string. PARAMS is a property list containing the parameters of the block. This function is called by `org-babel-execute-src-block'. Note: This function only works with an iPython shell if it has the autoindent feature turned off. Add '--no-autoindent' to `py-ipython-command-args' to set this when an iPython process is created." (let* ((org-babel-python-command (or (cdr (assq :python params)) org-babel-python-command)) (session-name (cdr (assq :session params))) (session (when (and session-name (not (string= session-name "none"))) (org-babel-python-initiate-session session))) (result-params (cdr (assq :result-params params))) (result-type (cdr (assq :result-type params))) (return-val (when (and (eq result-type 'value) (not session)) (cdr (assq :return params)))) (preamble (cdr (assq :preamble params))) (process (get-process python-shell-buffer-name)) (full-body (org-babel-expand-body:generic (concat body (if return-val (format "\nreturn %s" return-val) "")) params (org-babel-variable-assignments:python params))) (result (cond (session (org-babel-python-evaluate-session session full-body result-type result-params)) (process (process-send-string process (concat full-body "\n\n")) (display-buffer (process-buffer process) t)) (t (org-babel-python-evaluate-external-process full-body result-type result-params preamble))))) (org-babel-reassemble-table result (org-babel-pick-name (cdr (assq :colname-names params)) (cdr (assq :colnames params))) (org-babel-pick-name (cdr (assq :rowname-names params)) (cdr (assq :rownames params))))))))
Rust
Customize Org/Babel for Rust so it works.
;;------------------------------------------------------------------------------ ;;;; Org Mode: Babel: Rust ;;------------------------------------------------------------------------------ (init-message 3 "Org Mode: Babel: Rust") (use-package ob-rust :straight t :after (org rust-mode) :commands (org-babel-execute:rust) :functions (flycheck-mode rust-send-buffer org-babel-rust-command) :config (when (require 'ob-rust nil :no-error) (defun org-babel-execute:rust (body params) "Execute a block of Rust code with Babel. BODY is the contents of the block, as a string. PARAMS is a property list containing the parameters of the block. This function is called by `org-babel-execute-src-block'." (let* ((tmp-src-file (org-babel-temp-file "rust-src-" ".rs")) (tmp-run-file (org-babel-temp-file "rust-run-")) (processed-params (org-babel-process-params params)) (_flags (cdr (assoc :flags processed-params))) (_args (cdr (assoc :args processed-params))) (coding-system-for-read 'utf-8) ;; use utf-8 with subprocesses (coding-system-for-write 'utf-8) (wrapped-body (save-match-data (if (string-match "fn main()" body) body (if (string-match "fn \\(.*_test\\)()" body) (concat body "\n\nfn main() {\n" (match-string 1 body) "();\n}") (concat "fn main() {\n" body "\n}")))))) (with-temp-file tmp-src-file (insert wrapped-body)) (let ((result (org-babel-eval (format "rustc -o %s %s && %s" tmp-run-file tmp-src-file tmp-run-file) ""))) (when result (org-babel-reassemble-table (if (or (member "table" (cdr (assoc :result-params processed-params))) (member "vector" (cdr (assoc :result-params processed-params)))) (let ((tmp-file (org-babel-temp-file "rust-"))) (with-temp-file tmp-file (insert (org-babel-trim result))) (org-babel-import-elisp-from-file tmp-file)) (org-babel-read (org-babel-trim result) t)) (org-babel-pick-name (cdr (assoc :colname-names params)) (cdr (assoc :colnames params))) (org-babel-pick-name (cdr (assoc :rowname-names params)) (cdr (assoc :rownames params))))))))))
V
Customize Org/Babel for V so it works.
;;------------------------------------------------------------------------------ ;;;; Org Mode: Babel: V ;;------------------------------------------------------------------------------ (init-message 3 "Org Mode: Babel: V") ;; default to v-mode for v files (defvar org-babel-tangle-lang-exts) (add-to-list 'org-babel-tangle-lang-exts '("v" . "v")) (defvar org-babel-v-command "v") (defvar org-babel-default-header-args:v '()) (defvar org-babel-header-args:v '((package . :any))) (defun org-babel-execute:v (body params) "Execute a block of V code with Babel. BODY is the contents of the block, as a string. PARAMS is a property list containing the parameters of the block. This function is called by `org-babel-execute-src-block'." (let* ((tmp-src-file (org-babel-temp-file "v-src-" ".v")) (tmp-run-file (org-babel-temp-file "v-run-")) (processed-params (org-babel-process-params params)) (_flags (cdr (assoc :flags processed-params))) (_args (cdr (assoc :args processed-params))) (coding-system-for-read 'utf-8) ;; use utf-8 with subprocesses (coding-system-for-write 'utf-8) (wrapped-body (save-match-data (if (string-match "fn main()" body) body (if (string-match "fn \\(test_.*\\)()" body) (let ((start 0) tests) (while (string-match "fn \\(test_.*\\)()" body start) (push (match-string 1 body) tests) (setq start (match-end 0))) (concat body "\n\nfn main() {\n" (apply #'concat (nreverse tests)) "()\n}")) body))))) (with-temp-file tmp-src-file (insert wrapped-body)) (let ((result (org-babel-eval (format "v -o %s %s && %s" tmp-run-file tmp-src-file tmp-run-file) ""))) (when result (org-babel-reassemble-table (if (or (member "table" (cdr (assoc :result-params processed-params))) (member "vector" (cdr (assoc :result-params processed-params)))) (let ((tmp-file (org-babel-temp-file "v-"))) (with-temp-file tmp-file (insert (org-babel-trim result))) (org-babel-import-elisp-from-file tmp-file)) (org-babel-read (org-babel-trim result) t)) (org-babel-pick-name (cdr (assoc :colname-names params)) (cdr (assoc :colnames params))) (org-babel-pick-name (cdr (assoc :rowname-names params)) (cdr (assoc :rownames params))))))))
Basic (Commander X16)
Customize Org/Babel for BASIC so it works.
;;------------------------------------------------------------------------------ ;;;; Org Mode: Babel: Basic (Commander X16) ;;------------------------------------------------------------------------------ (init-message 3 "Org Mode: Babel: Basic (Commander X16)") ;; default to basic-mode for basic files (require 'basic) (defvar org-babel-tangle-lang-exts) (add-to-list 'org-babel-tangle-lang-exts '("basic" . "bas")) ;;(defvar org-babel-basic-command "~/x16emu/x16emu") (defvar org-babel-basic-command "x16emu -rom /usr/share/x16-rom/rom.bin") (defun org-babel-execute:basic (body params) "Execute a block of BASIC code with Babel. BODY is the contents of the block, as a string. PARAMS is a property list containing the parameters of the block." (let ((src-file (org-babel-temp-file "basic-" ".bas"))) (with-temp-file src-file (insert (org-babel-expand-body:generic body params))) (org-babel-eval (concat org-babel-basic-command " -bas " src-file " -run &") "")))
Assembly Language (Commander X16)
Customize Org/Babel for Assembly Language so it works.
;;------------------------------------------------------------------------------ ;;;; Org Mode: Babel: Assembly Language (Commander X16) ;;------------------------------------------------------------------------------ (init-message 3 "Org Mode: Babel: Assembly Language (Commander X16)") ;; default to asm-mode for assembly language files (defvar org-babel-tangle-lang-exts) (add-to-list 'org-babel-tangle-lang-exts '("asm" . "asm")) ;; ;; vasm version ;; defvar org-babel-asm-compiler "vasm6502_oldstyle") ;; defvar org-babel-asm-compiler-params "-c02 -cbm-prg -chklabels -nocase -Dvasm=1 -DBuildC64=1 -Fbin") ;; defvar org-babel-asm-command "x16emu -keymap en-us") ;; (defun org-babel-execute:asm (body params) ;; "Execute a block of Assembly Language code with Babel. ;; BODY is the contents of the block, as a string. PARAMS is ;; a property list containing the parameters of the block." ;; (let* ((base-file (org-babel-temp-file "asm-")) ;; (src-file (concat base-file ".asm")) ;; (list-file (concat base-file ".lst")) ;; (output-file (concat base-file ".prg")) ;; (defines (cdr (assoc :defines params)))) ;; (with-temp-file src-file ;; (insert (org-babel-expand-body:generic body params))) ;; (org-babel-eval (concat org-babel-asm-compiler ;; " " org-babel-asm-compiler-params ;; (if defines (concat " -D " defines) "") ;; " -L " list-file ;; " -o " output-file ;; " " src-file) "") ;; (org-babel-eval (concat org-babel-asm-command " -prg " output-file " -run &") ""))) ;; acme version (defun org-babel-execute:asm (body params) "Execute a block of Assembly Language code with Babel. BODY is the contents of the block, as a string. PARAMS is a property list containing the parameters of the block." (let* ((base-file (org-babel-temp-file "asm-")) (src-file (concat base-file ".asm")) (list-file (concat base-file ".lst")) (output-file (concat base-file ".prg")) (defines (cdr (assoc :defines params))) (cmpflag (or (cdr (assq :cmpflag params)) "")) (cmdline (or (cdr (assq :cmdline params)) "")) (x16emu (string= (cdr (assq :x16emu params)) "yes")) (compile-command (concat "acme" (if cmpflag (concat " " cmpflag) "") (if defines (concat " -D " defines) "") " --symbollist " list-file " --outfile " output-file " " src-file)) (run-command (when x16emu (concat "x16emu -keymap en-us" (if cmdline (concat " " cmdline) "") " -prg " output-file " -run &")))) (with-temp-file src-file (insert (org-babel-expand-body:generic body params))) (message "Compiling: %s" compile-command) (org-babel-eval compile-command "") (when x16emu (message "Running: %s" run-command) (org-babel-eval run-command "")))) ;; ;; 64tass version ;; defvar org-babel-asm-compiler "64tass") ;; defvar org-babel-asm-compiler-params "-a -B -C") ;; defvar org-babel-asm-command "x16emu -keymap en-us") ;; (defun org-babel-execute:asm (body params) ;; "Execute a block of Assembly Language code with Babel. ;; BODY is the contents of the block, as a string. PARAMS is ;; a property list containing the parameters of the block." ;; (let* ((base-file (org-babel-temp-file "asm-")) ;; (src-file (concat base-file ".asm")) ;; (list-file (concat base-file ".lst")) ;; (output-file (concat base-file ".prg")) ;; (defines (cdr (assoc :defines params)))) ;; (with-temp-file src-file ;; (insert (org-babel-expand-body:generic body params))) ;; (org-babel-eval (concat org-babel-asm-compiler ;; " " org-babel-asm-compiler-params ;; (if defines (concat " -D " defines) "") ;; " -L " list-file ;; " -o " output-file ;; " " src-file) "") ;; (org-babel-eval (concat org-babel-asm-command " -prg " output-file " -run &") "")))
PlantUML
Customize Org/Babel for PlantUML so it works.
;;------------------------------------------------------------------------------ ;;;; Org Mode: Babel: PlantUML ;;------------------------------------------------------------------------------ (init-message 3 "Org Mode: Babel: PlantUML") ;; set plantuml.jar location (setq org-plantuml-jar-path "~/dev/java/lib/plantuml.jar")
Load Languages
Load org-babel
languages.
This must evaluate after the ob-LANG packages have been loaded.
;;------------------------------------------------------------------------------ ;;;; Org Mode: Babel: Load Languages ;;------------------------------------------------------------------------------ (init-message 3 "Org Mode: Babel: Load Languages") ;; babel languages (usable in source blocks) (org-babel-do-load-languages 'org-babel-load-languages '((C . t) (clojure . t) (css . t) (ditaa . t) (dot . t) (emacs-lisp . t) (gnuplot . t) ;;(ipython . t) (java . t) (js . t) ;;(json . t) (kotlin . t) (latex . t) (lilypond . t) (lisp . t) (lua . t) (makefile . t) (org . t) (perl . t) (plantuml . t) (python . t) (racket . t) (ruby . t) (rust . t) (scheme . t) (shell . t) (sql . t))) ;; major modes for languages ;; (only needed if the mode name is not LANG-mode) ;;(add-to-list 'org-src-lang-modes '("java" . jdee)) (add-to-list 'org-src-lang-modes '("dot" . graphviz-dot)) (add-to-list 'org-src-lang-modes '("racket" . scheme))
Babel Functions
Org Mode Babel supporting functions.
;;------------------------------------------------------------------------------ ;;; Org Mode: Babel Functions ;;------------------------------------------------------------------------------ (init-message 2 "Org Mode: Babel Functions")
org-babel-send-region-to-process
Send region to a running shell process.
;; ;;------------------------------------------------------------------------------ ;; ;;;; Org Mode: Functions: org-babel-send-region-to-process ;; ;;------------------------------------------------------------------------------ ;; (init-message 3 "Org Mode: Functions: org-babel-send-region-to-process") ;; (defun org-babel-send-line-or-region (process-name &optional beg end step) ;; "Send line or region to a running shell process." ;; (interactive) ;; (let* ((beg (or beg (if (use-region-p) (region-beginning) (line-beginning-position)))) ;; (end (or end (if (use-region-p) (region-end) (line-end-position)))) ;; (process (get-process process-name)) ;; (buffer (process-buffer process)) ;; (data (concat (buffer-substring-no-properties beg end) "\n"))) ;; (deactivate-mark) ;; (with-current-buffer buffer ;; (goto-char (process-mark process)) ;; (insert data) ;; (move-marker (process-mark process) (point))) ;; (process-send-string process data) ;; (display-buffer buffer t) ;; (when step ;; (goto-char end) ;; (forward-line 1) ;; (forward-line 0))))
org-babel-tangle-block
Tangle blocks for the tangle file of the block at point.
;;------------------------------------------------------------------------------ ;;;; Org Mode: Functions: org-babel-tangle-block ;;------------------------------------------------------------------------------ (init-message 3 "Org Mode: Functions: org-babel-tangle-block") (defun org-babel-tangle-block (&optional file) "Tangle blocks for the tangle file of the block at point. If FILE is non-nil, then search the buffer for blocks that tangle to FILE and tangle them." (interactive) (if file (save-excursion (goto-char (point-min)) (when (re-search-forward (concat "#\\+BEGIN_SRC .* :tangle " file)) (org-babel-tangle '(16)))) (org-babel-tangle '(16))))
org-babel-tangle-file-async
;;------------------------------------------------------------------------------ ;;;; Org Mode: Functions: org-babel-tangle-file-async ;;------------------------------------------------------------------------------ (init-message 3 "Org Mode: Functions: org-babel-tangle-file-async") (defun org-babel-tangle-file-async (file &optional target-file lang-re) "Asynchronous version of `org-babel-tangle-file'." (interactive) (let* ((file-hash (secure-hash 'md5 file)) (lock-file (expand-file-name (concat "emacs-tangle-file-async-lock-file-" file-hash) temporary-file-directory)) (run-file (expand-file-name (concat "emacs-tangle-file-async-run-file-" file-hash) temporary-file-directory))) (if (file-exists-p lock-file) (progn (message "Tangle running: %s" file) (unless (file-exists-p run-file) (make-empty-file run-file))) (message "Tangle started: %s" file) (make-empty-file lock-file) (eval `(async-spinner (lambda () (require 'ob-tangle) (unless (file-exists-p ,run-file) (make-empty-file ,run-file)) (while (file-exists-p ,run-file) (delete-file ,run-file) (org-babel-tangle-file ,file ,target-file ,lang-re))) (lambda (result) (message "Tangle finished: %s" ,file) (delete-file ,lock-file))))))) ;; delete any existing lock/run files in case they were not cleaned up (mapc (lambda (x) (mapc (lambda (f) (delete-file f)) x)) (mapcar (lambda (x) (file-expand-wildcards (expand-file-name x temporary-file-directory) :full)) '("emacs-tangle-file-async-lock-file-*" "emacs-tangle-file-async-run-file-*")))
org-generate-custom-id-from-title
;;------------------------------------------------------------------------------ ;;;; Org Mode: Babel Functions: org-generate-custom-id-from-title ;;------------------------------------------------------------------------------ (init-message 3 "Org Mode: Babel Functions: org-generate-custom-id-from-title") (defun org-generate-custom-id-from-title (title) "Generate a proper `org-mode' CUSTOM_ID property from a given TITLE." (replace-regexp-in-string (rx (seq "-" "-")) "-" (replace-regexp-in-string (rx (seq "-" eol)) "" (replace-regexp-in-string (rx (seq bol "-")) "" (replace-regexp-in-string (rx (any ".")) "-dot-" (replace-regexp-in-string (rx (any " " "_" "/")) "-" (replace-regexp-in-string (rx (not (any alnum space "-" "_" "." "/"))) "" (downcase title))))))))
org-fix-literate-programming-heading
;;------------------------------------------------------------------------------ ;;;; Org Mode: Babel Functions: org-fix-literate-programming-heading ;;------------------------------------------------------------------------------ (init-message 3 "Org Mode: Babel Functions: org-fix-literate-programming-heading") (defun org-fix-literate-programming-heading () "Fix 'literate programming' heading of current org section. Reset the CUSTOM_ID property, title comment, and `init-message'." (interactive "*") (save-window-excursion (save-mark-and-excursion (save-match-data (org-with-wide-buffer ;; find heading of current position (forward-line 0) (while (not (looking-at "^\*+ ")) (forward-line -1)) (let* ((case-fold-search t) (start (point)) (count (length (progn (re-search-forward "^\\(\*+\\) " (line-end-position)) (match-string-no-properties 1)))) (level (/ (1+ count) (if org-odd-levels-only 2 1))) headings) ;; get parent headings (goto-char start) (while (and (not (bobp)) (> count 0)) (let ((regexp (concat "^\*\\{" (number-to-string count) "\\} \\(.*\\)$"))) (while (and (not (bobp)) (not (looking-at regexp))) (forward-line -1)) (when (re-search-forward regexp (line-end-position)) (push (replace-regexp-in-string "+" "" (match-string-no-properties 1)) headings) (setq count (- count (if org-odd-levels-only 2 1)))))) (let ((id (mapconcat (lambda (x) (org-generate-custom-id-from-title x)) headings "-")) (title (mapconcat #'(lambda (x) x) headings ": "))) (goto-char start) ;; set CUSTOM_ID (org-set-property "CUSTOM_ID" id) (forward-line 1) (indent-region (point) (re-search-forward "^[ \t]*:END:$")) ;; set comment (let ((end (if (re-search-forward "^\*+ " nil :noerror) (point) (point-max)))) (goto-char start) (when (re-search-forward "^[ \t]*#\\+BEGIN_SRC" end :noerror) (org-babel-do-in-edit-buffer (let* ((comment-1 (substring comment-start -1)) (comment-2 (if (= (length comment-start) 1) (concat comment-start comment-start) comment-start)) (comment-3 (concat comment-2 comment-1)) (comment-4 (concat comment-3 comment-1))) (when (looking-at (concat comment-2 "[=-]+\n" comment-2 "+ .*\n")) (replace-match (concat comment-2 (make-string 78 (if (> level 1) ?- ?=)) "\n" (if (> level 2) comment-4 comment-3) " " title "\n")) (forward-line 0) (while (looking-at comment-2) (when (looking-at (concat comment-2 "[=-]+\n")) (replace-match (concat comment-2 (make-string 78 (if (> level 1) ?- ?=)) "\n"))) (forward-line 1)))) ;; set `init-message' text (when (re-search-forward "(init-message .*$" nil :noerror) (replace-match (concat "(init-message " (number-to-string level) " \"" title "\")")))))))))))))
org-fix-literate-programming-heading-region
;;------------------------------------------------------------------------------ ;;;; Org Mode: Babel Functions: org-fix-literate-programming-heading-region ;;------------------------------------------------------------------------------ (init-message 3 "Org Mode: Babel Functions: org-fix-literate-programming-heading-region") (defun org-fix-literate-programming-heading-region (&optional beg end) "Fix 'literate programming' headings contained with given region. Reset the CUSTOM_ID property, title comment, and `init-message'." (interactive "*") (let ((case-fold-search t) (beg (or beg (if (use-region-p) (region-beginning) (progn (beginning-of-line-text) (point))))) (end (or end (if (use-region-p) (region-end) (line-end-position))))) (deactivate-mark) (save-mark-and-excursion (save-restriction (save-match-data (org-with-wide-buffer (narrow-to-region beg end) (goto-char (point-min)) (while (and (re-search-forward "^[ \t]*:CUSTOM_ID:" nil :noerror) (< (line-end-position) end)) (org-fix-literate-programming-heading) (forward-line 1))))))))
org-toggle-literate-programming-code-block
;;------------------------------------------------------------------------------ ;;;; Org Mode: Babel Functions: org-toggle-literate-programming-code-block ;;------------------------------------------------------------------------------ (init-message 3 "Org Mode: Babel Functions: org-toggle-literate-programming-code-block") (defun org-toggle-literate-programming-code-block () "Toggle 'literate programming' heading and code block on/off." (interactive) (save-window-excursion (save-mark-and-excursion (save-match-data (org-with-wide-buffer (org-back-to-heading t) (let ((case-fold-search t) (beg (point)) (end (progn (forward-line 1) (re-search-forward "^\*" nil 'move) (1- (point))))) (goto-char beg) (re-search-forward " " (line-end-position)) (let ((toggle-on (looking-at "\+"))) ; whether toggling on or off ;; toggle source blocks (in reverse as END will move) (goto-char end) (while (re-search-backward "^[ \t]*#\\+BEGIN_" beg :noerror) (if toggle-on (when (re-search-forward " :tangle no" (line-end-position) :noerror) (replace-match "")) (progn (goto-char (line-end-position)) (insert " :tangle no"))) (forward-line 1) (org-babel-do-in-edit-buffer (if toggle-on (uncomment-region (point-min) (point-max)) (comment-region (point-min) (point-max)))) (forward-line -2)) ;; toggle header text (goto-char beg) (re-search-forward " " (line-end-position)) (if toggle-on (dotimes (_ 2) (when (re-search-forward "\+" (line-end-position)) (replace-match ""))) (progn (insert "+") (goto-char (line-end-position)) (insert "+"))))))))))
org-insert-literate-programming-statics
Various org-babel
related static inserts.
;;------------------------------------------------------------------------------ ;;;; Org Mode: Babel Functions: org-insert-literate-programming-statics ;;------------------------------------------------------------------------------ (init-message 3 "Org Mode: Babel Functions: org-insert-literate-programming-statics") (defun org-insert-literate-programming-name () "Insert `org-babel' block NAME" (interactive "*") (org-indent-line) (insert "#+NAME: ")) (defmacro org-insert-literate-programming-src-function (name &optional lang) "Return org babel insert function from NAME and optional LANG. LANG is only needed if the language section of the block is different from NAME." (let* ((lang (or lang name)) (funct (intern (concat "org-insert-literate-programming-src" (if name (concat "-" name) "")))) (doc (concat "Insert `org-babel'" (if lang (concat " " name) "") " source block")) (block (concat "#+BEGIN_SRC" (if lang (concat " " lang) "") "\n\n#+END_SRC\n"))) `(defun ,funct () ,doc (interactive "*") (let ((point (point))) (insert ,block) (indent-region point (point)) (forward-line -2))))) ;; org-insert-literate-programming-src (org-insert-literate-programming-src-function nil) ;; org-insert-literate-programming-src-sh (org-insert-literate-programming-src-function "sh") ;; org-insert-literate-programming-src-sh-sudo (org-insert-literate-programming-src-function "sh-sudo" "sh :dir /sudo::") ;; org-insert-literate-programming-src-emacs-lisp (org-insert-literate-programming-src-function "emacs-lisp") ;; org-insert-literate-programming-src-racket (org-insert-literate-programming-src-function "racket") ;; org-insert-literate-programming-src-kotlin (org-insert-literate-programming-src-function "kotlin")
org-insert-literate-programming-block
Insert a new block consisting of a heading, properties, and source block.
;;------------------------------------------------------------------------------ ;;;; Org Mode: Babel Functions: org-insert-literate-programming-block ;;------------------------------------------------------------------------------ (init-message 3 "Org Mode: Babel Functions: org-insert-literate-programming-block") (defun org-insert-literate-programming-block (&optional title) "Insert 'literate programming' block consisting of a heading, properties, and source block." (interactive "*") (let* ((case-fold-search t) (point (point)) (title (or title (read-string "Block title: "))) (tag (org-generate-custom-id-from-title title))) (org-insert-heading) (insert title) (org-set-property "CUSTOM_ID" tag) (re-search-forward "^[ \t]*:END:$") (newline) (newline) (insert "#+BEGIN_SRC conf-unix\n") (insert "#+END_SRC\n") (indent-region point (point)) (org-previous-visible-heading 1) (goto-char (line-end-position)) (org-fix-literate-programming-heading) (forward-line 12)))
org-insert-literate-programming-init-emacs-block
;;------------------------------------------------------------------------------ ;;;; Org Mode: Babel Functions: org-insert-literate-programming-init-emacs-block ;;------------------------------------------------------------------------------ (init-message 3 "Org Mode: Babel Functions: org-insert-literate-programming-init-emacs-block") (defun org-insert-literate-programming-init-emacs-block (&optional title) "Insert 'literate programming' init-emacs block consisting of a heading, properties, source block, title comment, and `init-message'." (interactive "*") (let* ((case-fold-search t) (point (point)) (title (or title (read-string "Block title: "))) (tag (org-generate-custom-id-from-title title))) (org-insert-heading) (insert title) (org-set-property "CUSTOM_ID" tag) (re-search-forward "^[ \t]*:END:$") (newline) (newline) (insert "#+BEGIN_SRC emacs-lisp\n") (insert " ;;------------------------------------------------------------------------------\n") (insert " ;;;; " title "\n") (insert " ;;------------------------------------------------------------------------------\n") (newline) (insert " (init-message 2 \"" title "\")\n") (newline) (newline) (insert "#+END_SRC\n") (indent-region point (point)) (org-previous-visible-heading 1) (goto-char (line-end-position)) (org-fix-literate-programming-heading) (forward-line 12)))
org-insert-literate-programming-code-block
;;------------------------------------------------------------------------------ ;;;; Org Mode: Babel Functions: org-insert-literate-programming-code-block ;;------------------------------------------------------------------------------ (init-message 3 "Org Mode: Babel Functions: org-insert-literate-programming-code-block") (defun org-insert-literate-programming-code-block () "Insert 'literate programming' code block consisting of a heading, properties, source block, and title comment." (interactive "*") (let* ((case-fold-search t) (point (point)) (title (read-string "Block title: ")) (funct (org-generate-custom-id-from-title title)) (lang (save-mark-and-excursion (if (re-search-backward "^[ \t]*#\\+BEGIN_SRC \\([^ \t\n]*\\)" nil :noerror) (match-string 1) "emacs-lisp")))) (org-previous-visible-heading 1) (org-insert-heading-respect-content) (insert title) (org-set-property "CUSTOM_ID" funct) (re-search-forward "^[ \t]*:END:$") (newline) (newline) (insert "#+BEGIN_SRC " lang "\n") (insert " ;;------------------------------------------------------------------------------\n") (insert " ;;;; " title "\n") (insert " ;;------------------------------------------------------------------------------\n") (newline) (insert " (define (" funct " num)\n") (insert " )\n") (insert "#+END_SRC\n") (newline) (insert "#+BEGIN_SRC " lang " :tangle no\n") (insert " (define (" funct "-test)\n") (insert " (check-equal? (" funct " ) )\n") (insert " )\n") (insert "#+END_SRC\n") (indent-region point (point)) (org-previous-visible-heading 1) (goto-char (line-end-position)) (org-fix-literate-programming-heading) (forward-line 10)))
org-insert-literate-programming-project-euler-problem-block
;;------------------------------------------------------------------------------ ;;;; Org Mode: Babel Functions: org-insert-literate-programming-project-euler-problem-block ;;------------------------------------------------------------------------------ (init-message 3 "Org Mode: Babel Functions: org-insert-literate-programming-project-euler-problem-block") (defun org-insert-literate-programming-project-euler-problem-block () "Insert 'literate programming' project euler problem block consisting of a heading, properties, source block with title comment, and test block." (interactive "*") (let* ((case-fold-search t) (point (point)) (num (read-string "Problem number: ")) (title (concat "Problem " num)) (funct (format "project-euler-%03d" (string-to-number num))) (lang (save-mark-and-excursion (if (re-search-backward "^[ \t]*#\\+BEGIN_SRC \\([^ \t\n]*\\)" nil :noerror) (match-string 1) "emacs-lisp")))) (org-previous-visible-heading 1) (org-insert-heading-respect-content) (insert title) (org-set-property "CUSTOM_ID" funct) (re-search-forward "^[ \t]*:END:$") (newline) (newline) (insert "#+BEGIN_SRC " lang "\n") (insert " ;;------------------------------------------------------------------------------\n") (insert " ;;;; " title "\n") (insert " ;;\n") (insert " ;;\n") (insert " ;;\n") (insert " ;; The correct answer is: \n") (insert " ;;------------------------------------------------------------------------------\n") (newline) (insert " (define (" funct " [num 1000])\n") (insert " )\n") (insert "#+END_SRC\n") (newline) (insert "#+BEGIN_SRC " lang " :tangle no\n") (insert " (define (" funct "-test)\n") (insert " (check-equal? (" funct " ) )\n") (insert " )\n") (insert "#+END_SRC\n") (indent-region point (point)) (org-previous-visible-heading 1) (goto-char (line-end-position)) (org-fix-literate-programming-heading) (forward-line 9)))
Visibility
Persist visibility snapshot of org files.
;;------------------------------------------------------------------------------ ;;; Org Mode: Visibility ;;------------------------------------------------------------------------------ (init-message 2 "Org Mode: Visibility") (use-package org-visibility :straight t ;;:load-path (lambda () (file-truename (expand-file-name "~/code/github-nullman/emacs-org-visibility"))) :after (org) :demand t :bind* (:map org-visibility-mode-map ("C-x C-v" . org-visibility-force-save) ; default: `find-alternative-file' ("C-x M-v" . org-visibility-remove)) ; default: undefined :custom ;; list of directories and files to automatically persist and restore visibility state of (org-visibility-include-paths `(,(file-truename "~/.emacs.d/init-emacs.org") ,(file-truename "~/code/github-nullman") ,(file-truename "~/dev") ,(file-truename "~/doc/bbs") ,(file-truename "~/org") ,(file-truename "~/web/org"))) ;; list of directories and files to not persist and restore visibility state of (org-visibility-exclude-paths `(,(file-truename "~/org/old") ,(file-truename "~/org/test"))) :init (org-visibility-mode 1))
Contacts
;; ;;------------------------------------------------------------------------------ ;; ;;; Org Mode: Contacts ;; ;;------------------------------------------------------------------------------ ;; (init-message 2 "Org Mode: Contacts") ;; (use-package org-contacts ;; :straight t ;; :after (org) ;; :custom ;; (org-contacts-files ;; (list (file-truename (expand-file-name "~/org/contacts.org"))))) ;; ;; ;;------------------------------------------------------------------------------ ;; ;; ;;; Org Mode: VCARD ;; ;; ;;------------------------------------------------------------------------------ ;; ;; (init-message 3 "Org Mode: VCARD") ;; ;; buggy; needs a maintainer ;; ;; (use-package org-vcard ;; ;; :straight t ;; ;; :custom ;; ;; (org-vcard-default-version "3.0") ;; ;; (org-vcard-default-language "en") ;; ;; (org-vcard-default-style "flat") ;; ;; (org-vcard-include-import-unknowns t))
Present
;;------------------------------------------------------------------------------ ;;; Org Mode: Present ;;------------------------------------------------------------------------------ (init-message 2 "Org Mode: Present") (use-package org-present :straight t :config ;; custom `org-present-read-only' function to fix cursor bug (defun org-present-read-only () "Make buffer read-only." (interactive) (setq buffer-read-only t) (define-key org-present-mode-keymap (kbd "SPC") #'org-present-next)) (defun custom-org-present-mode-hook () "Customizations for entering `org-present-mode'." ;;(org-present-big) (setq-local face-remapping-alist '((default (:height 1.5) variable-pitch) (header-line (:height 4.0) variable-pitch) (org-document-title (:height 1.75) org-document-title) (org-code (:height 1.55) org-code) (org-verbatim (:height 1.55) org-verbatim) (org-block (:height 1.25) org-block) (org-block-begin-line (:height 0.7) org-block))) (setq-local header-line-format " ") (org-display-inline-images) (org-present-hide-cursor) (org-present-read-only) (when (fboundp 'visual-fill-column-mode) (visual-fill-column-mode 1)) (visual-line-mode 1)) (add-hook 'org-present-mode-hook #'custom-org-present-mode-hook) (defun custom-org-present-mode-quit-hook () "Customizations for exiting `org-present-mode'." ;;(org-present-small) (setq-local face-remapping-alist '((default variable-pitch default))) (setq-local header-line-format nil) (org-remove-inline-images) (org-present-show-cursor) (org-present-read-write) (when (fboundp 'visual-fill-column-mode) (visual-fill-column-mode 0)) (visual-line-mode 0)) (add-hook 'org-present-mode-quit-hook #'custom-org-present-mode-quit-hook) (defun custom-org-present-after-navigate-functions (buffer-name heading) "Customizations for navigating in `org-present-mode'." ;; collapse headlines (org-overview) ;; show top entry (org-show-entry) ;; show direct subheadlines, but do not expand them (org-show-children)) (add-hook 'org-present-after-navigate-functions #'custom-org-present-after-navigate-functions))
Reveal
Reveal Presentation Mode configuration.
;; ;;------------------------------------------------------------------------------ ;; ;;; Org Mode: Reveal ;; ;;------------------------------------------------------------------------------ ;; (init-message 2 "Org Mode: Reveal") ;; (use-package ox-reveal ;; :straight t ;; :after (org) ;; :load-path (lambda () (file-truename (expand-file-name "org-reveal" emacs-modules-dir))) ;; :config ;; (setq org-reveal-root "../reveal.js"))
Jira
Jira Mode issue tracking configuration.
;; ;;------------------------------------------------------------------------------ ;; ;;; Org Mode: Jira ;; ;;------------------------------------------------------------------------------ ;; (init-message 2 "Org Mode: Jira") ;; (use-package org-jira ;; :straight (:type built-in) ;; :after (org soap-client) ;; :commands (org-jira org-jira-mode org-jira-get-projects) ;; :config ;; ;; BuzzFeed Jira Server ;; (setq jiralib-url "https://buzzfeed.atlassian.net")) ;; ;; requires soap client ;; (use-package soap-client ;; :straight (:type built-in))
Bookmarks
Bookmark parsing and exporting functions.
These functions work on a very simple bookmark format where org headlines are folders unless they have a URI below them, in which case they represent a bookmark.
* Org * Folder 1 *** Folder 2 ***** Bookmark 1 URI1 ***** Bookmark 2 [bm2] URI2 *** Folder 3
Where "Folder 1" and "Folder 2" represent folders, "Bookmark 1" and "Bookmark 2" represent bookmarks, and "Bookmark 2" has a keyword (for Firefox) of "bm2".
If the first headline is "Org", it is ignored.
org-bookmarks-guid
Return a twelve character GUID.
;;------------------------------------------------------------------------------ ;;;; Org Mode: Bookmarks: org-bookmarks-guid ;;------------------------------------------------------------------------------ (init-message 3 "Org Mode: Bookmarks: org-bookmarks-guid") (defun org-bookmarks-guid () "Return a twelve character GUID." (cl-labels ((random-char () (let ((num (random 62))) (cond ((< num 10) (byte-to-string (+ num 48))) ((< num 36) (byte-to-string (+ num 55))) (t (byte-to-string (+ num 61))))))) (cl-loop repeat 12 concat (random-char))))
org-bookmarks-timestamp
Return time since the epoch in microseconds.
;;------------------------------------------------------------------------------ ;;;; Org Mode: Bookmarks: org-bookmarks-timestamp ;;------------------------------------------------------------------------------ (init-message 3 "Org Mode: Bookmarks: org-bookmarks-timestamp") (defun org-bookmarks-timestamp () "Return time since the epoch in microseconds." (floor (* (float-time (current-time)) 1000000)))
org-bookmarks-parse
Return a tree structure representing the bookmarks.
;;------------------------------------------------------------------------------ ;;;; Org Mode: Bookmarks: org-bookmarks-parse ;;------------------------------------------------------------------------------ (init-message 3 "Org Mode: Bookmarks: org-bookmarks-parse") (defun org-bookmarks-parse (file) "Return a tree structure representing the org folders and bookmarks found in FILE. Example input: * Folder 1 ** Folder 2 *** Bookmark 1 URI1 *** Bookmark 2 [bm2] URI2 ** Folder 3 Example output: ((:type \"folder\" :title \"Folder 1\" :children [(:type \"folder\" :title \"Folder 2\" :children [(:type \"bookmark\" :title \"Bookmark 1\" :uri \"URI1\") (:type \"bookmark\" :title \"Bookmark 2\" :uri \"URI2\" :keyword \"bm2\")]) (:type \"folder\" :title \"Folder 3\")]))" (cl-labels ((parse (bm tree) (cond ;; end of branch ((not bm) nil) ;; bookmark ((and (stringp (car bm)) (stringp (cadr bm))) (let* ((title (car x)) (uri (cadr x)) (keyword (if (string-match " \\[\\(.*\\)\\]$" title) (match-string-no-properties 1 title) nil)) (title (replace-regexp-in-string " \\[.*\\]$" "" title)) (entry (list :type "bookmark" :title title :uri uri))) (when keyword (setq entry (append entry (list :keyword keyword)))) entry)) ;; nested folder ((stringp (car bm)) (let* ((title (car bm)) (entry (list :type "folder" :title title))) (if (cdr bm) (append entry (list :children (map 'vector (lambda (x) (parse x tree)) (cdr bm)))) entry)))))) (let ((bm (org-get-file-data file))) (map 'vector (lambda (x) (parse x nil)) (cdr bm)))))
org-bookmarks-export-to-json
Export from an Org Bookmarks file to a Mozilla/Firefox Bookmarks JSON file.
;;------------------------------------------------------------------------------ ;;;; Org Mode: Bookmarks: org-bookmarks-export-to-json ;;------------------------------------------------------------------------------ (init-message 3 "Org Mode: Bookmarks: org-bookmarks-export-to-json") (defun org-bookmarks-export-to-json (org-file &optional json-file) "Export from an Org Bookmarks file, ORG-FILE, to a Mozilla/Firefox Bookmarks JSON file, JSON-FILE. If JSON-FILE is nil, then output is returned." (let* ((type-code-list '(("bookmark" . 1) ("folder" . 2))) (type-value-list '(("bookmark" . "text/x-moz-place") ("folder" . "text/x-moz-place-container"))) (title-guid-list '(("Bookmarks Toolbar" . "toolbar_____") ("Bookmarks Menu" . "menu________") ("Other Bookmarks" . "unfiled_____") ("Mobile Bookmarks" . "mobile______"))) (title-root-list '(("Bookmarks Toolbar" . "toolbarFolder") ("Bookmarks Menu" . "bookmarksMenuFolder") ("Other Bookmarks" . "unfiledBookmarksFolder") ("Mobile Bookmarks" . "mobileFolder"))) (global-id 0) (timestamp (org-bookmarks-timestamp))) (cl-labels ((gen-id () (cl-incf global-id)) (parse (bm tree index) (let* ((type (plist-get bm :type)) (type-value (cdr (assoc type type-value-list))) (type-code (cdr (assoc type type-code-list))) (title (plist-get bm :title)) (uri (plist-get bm :uri)) (keyword (plist-get bm :keyword)) (children (plist-get bm :children)) (guid (org-bookmarks-guid)) (id (gen-id)) (root (cdr (assoc title title-root-list))) (custom-guid (cdr (assoc title title-guid-list))) (entry (list :guid (or custom-guid guid) :title title :index index :dateAdded timestamp :lastModified timestamp :id id :typeCode type-code :type type-value))) (when uri (setq entry (append entry (list :uri uri)))) (when keyword (setq entry (append entry (list :keyword keyword)))) (when root (setq entry (append entry (list :root root)))) (when children (let ((idx -1)) (setq entry (append entry (list :children (map 'vector (lambda (x) (parse x tree (cl-incf idx))) children)))))) (append tree entry)))) (let ((json-object-type 'plist) (json-array-type 'vector) (json-key-type 'string) (bookmarks (org-bookmarks-parse org-file))) (with-temp-buffer (insert (json-encode (list :guid "root________" :title "" :index 0 :dateAdded timestamp :lastModified timestamp :id (gen-id) :typeCode 2 :type (cdr (assoc "folder" type-value-list)) :root "placesRoot" :children (map 'vector (lambda (x) (parse x nil 0)) bookmarks)))) (newline) (json-pretty-print (point-min) (point-max)) (if json-file (write-region (point-min) (point-max) json-file) (buffer-substring-no-properties (point-min) (point-max))))))))
org-bookmarks-export-to-text
Export from an Org Bookmarks file to a text file with one bookmark per line.
;;------------------------------------------------------------------------------ ;;;; Org Mode: Bookmarks: org-bookmarks-export-to-text ;;------------------------------------------------------------------------------ (init-message 3 "Org Mode: Bookmarks: org-bookmarks-export-to-text") (defun org-bookmarks-export-to-text (org-file &optional text-file) "Export from an Org Bookmarks file, ORG-FILE, to a text file, TEXT-FILE. If TEXT-FILE is nil, then output is returned." (let ((title-root-list '(("Bookmarks Toolbar" . "Toolbar") ("Bookmarks Menu" . "Menu") ("Other Bookmarks" . "Other") ("Mobile Bookmarks" . "Mobile")))) (cl-labels ((folder? (type) (string= type "folder")) (path-string (path) (string-join (reverse path) " > ")) (parse (bm path) (let* ((type (plist-get bm :type)) (folder? (folder? type)) (title (plist-get bm :title)) (uri (plist-get bm :uri)) (keyword (plist-get bm :keyword)) (children (plist-get bm :children)) (root? (cdr (assoc title title-root-list))) (path path)) (unless folder? (insert (if keyword (format "%s > %s [%s]: %s\n" (path-string path) title keyword uri) (format "%s > %s: %s\n" (path-string path) title uri)))) (when children (let ((path (if root? (list root?) (cons title path)))) (map 'vector (lambda (x) (parse x path)) children)))))) (let ((bookmarks (org-bookmarks-parse org-file))) (with-temp-buffer (map 'vector (lambda (x) (parse x '())) bookmarks) (if text-file (write-region (point-min) (point-max) text-file) (buffer-substring-no-properties (point-min) (point-max))))))))
org-bookmarks-export-to-html
Export from an Org Bookmarks file to a Mozilla/Firefox Bookmarks HTML file.
;;------------------------------------------------------------------------------ ;;;; Org Mode: Bookmarks: org-bookmarks-export-to-html ;;------------------------------------------------------------------------------ (init-message 3 "Org Mode: Bookmarks: org-bookmarks-export-to-html") (defun org-bookmarks-export-to-html (org-file &optional html-file) "Export from an Org Bookmarks file, ORG-FILE, to a Mozilla/Firefox Bookmarks HTML file, HTML-FILE. If HTML-FILE is nil, then output is returned." (let* ((type-code-list '(("bookmark" . 1) ("folder" . 2))) (title-code-list '(("Bookmarks Toolbar" . "PERSONAL_TOOLBAR_FOLDER") ("Other Bookmarks" . "UNFILED_BOOKMARKS_FOLDER"))) (timestamp (number-to-string (truncate (org-bookmarks-timestamp) 1000000)))) (cl-labels ((indent (idt str) (concat (spaces-string idt) str)) (parse (bm str idt) (let* ((type (plist-get bm :type)) (type-code (cdr (assoc type type-code-list))) (title (plist-get bm :title)) (title-code (cdr (assoc title title-code-list))) (uri (url-encode-url (plist-get bm :uri))) (keyword (plist-get bm :keyword)) (children (plist-get bm :children)) (entry (cl-case type-code (2 (concat (indent idt "<DT><H3") " ADD_DATE=\"" timestamp "\"" " LAST_MODIFIED=\"" timestamp "\"" (if title-code (concat " " title-code "=\"true\"") "") ">" title "</H3>")) (1 (concat (indent idt "<DT>") "<A HREF=\"" uri "\"" " ADD_DATE=\"" timestamp "\"" " LAST_MODIFIED=\"" timestamp "\"" (if keyword (concat " SHORTCUTURL=\"" keyword "\"") "") ">" title "</A>"))))) (when children (setq entry (concat entry "\n" (indent idt "<DL><p>\n") (mapconcat (lambda (x) (parse x str (+ idt 4))) children "\n") "\n" (indent idt "</DL><p>\n")))) entry))) (let ((bookmarks (org-bookmarks-parse org-file))) (with-temp-buffer (insert (concat "<!DOCTYPE NETSCAPE-Bookmark-file-1> <META HTTP-EQUIV=\"Content-Type\" CONTENT=\"text/html; charset=UTF-8\"> <TITLE>Bookmarks</TITLE> <H1>Bookmarks Menu</H1> <DL><p>\n" (mapconcat (lambda (x) (parse x "" 4)) bookmarks "\n")) "</DL><p>\n") (if html-file (write-region (point-min) (point-max) html-file) (buffer-substring-no-properties (point-min) (point-max))))))))
org-bookmarks-export-to-nyxt
Export from an Org Bookmarks file to an NYXT Bookmarks JSON file.
;;------------------------------------------------------------------------------ ;;;; Org Mode: Bookmarks: org-bookmarks-export-to-nyxt ;;------------------------------------------------------------------------------ (init-message 3 "Org Mode: Bookmarks: org-bookmarks-export-to-nyxt") (defun org-bookmarks-export-to-nyxt (org-file &optional nyxt-file) "Export from an Org Bookmarks file, ORG-FILE, to an NYXT Bookmarks Lisp file, NYXT-FILE. If NYXT-FILE is nil, then output is returned." (let ((timestamp (format-time-string "%FT%T.%6NZ")) (title-root-list '(("Bookmarks Toolbar" . "toolbarFolder") ("Bookmarks Menu" . "bookmarksMenuFolder") ("Other Bookmarks" . "unfiledBookmarksFolder") ("Mobile Bookmarks" . "mobileFolder")))) (cl-labels ((folder? (type) (string= type "folder")) (tags (name) (split-string name " " :omit-nulls)) (parse (bm tags) (let* ((type (plist-get bm :type)) (folder? (folder? type)) (title (plist-get bm :title)) (uri (plist-get bm :uri)) (keyword (plist-get bm :keyword)) (children (plist-get bm :children)) (root? (cdr (assoc title title-root-list))) (tags tags)) (when (and folder? (not root?)) (setq tags (append tags (tags title)))) (when keyword (setq tags (append tags (list keyword)))) (unless folder? (insert (format "%S\n" (list :url uri :title title :date timestamp :tags tags)))) (when children (map 'vector (lambda (x) (parse x tags)) children))))) (let ((bookmarks (org-bookmarks-parse org-file))) (with-temp-buffer (insert "(\n") (map 'vector (lambda (x) (parse x '())) bookmarks) (insert ")\n") (if nyxt-file (write-region (point-min) (point-max) nyxt-file) (buffer-substring-no-properties (point-min) (point-max))))))))
org-bookmarks-export-to-chrome-html
Export from an Org Bookmarks file to a Chrome/Chromium Bookmarks HTML file.
;;------------------------------------------------------------------------------ ;;;; Org Mode: Bookmarks: org-bookmarks-export-to-chrome-html ;;------------------------------------------------------------------------------ (init-message 3 "Org Mode: Bookmarks: org-bookmarks-export-to-chrome-html") (defun org-bookmarks-export-to-chrome-html (org-file &optional html-file) "Export from an Org Bookmarks file, ORG-FILE, to a Chrome/Chromium Bookmarks HTML file, HTML-FILE. If HTML-FILE is nil, then output is returned." (let* ((type-code-list '(("bookmark" . 1) ("folder" . 2))) (title-code-list '(("Bookmarks Toolbar" . "PERSONAL_TOOLBAR_FOLDER") ("Other Bookmarks" . "UNFILED_BOOKMARKS_FOLDER"))) (title-rename-list '(("Bookmarks Toolbar" . "Bookmarks bar") ("Bookmarks Menu" . :none) ("Other Bookmarks" . :none))) (timestamp (number-to-string (truncate (org-bookmarks-timestamp) 1000000)))) (cl-labels ((indent (idt str) (concat (spaces-string idt) str)) (parse (bm str idt) (let* ((type (plist-get bm :type)) (type-code (cdr (assoc type type-code-list))) (title (plist-get bm :title)) (title-code (cdr (assoc title title-code-list))) (title-rename (cdr (assoc title title-rename-list))) (skip (eq title-rename :none)) (uri (url-encode-url (plist-get bm :uri))) (keyword (plist-get bm :keyword)) (children (plist-get bm :children)) (entry (cl-case type-code (2 (if skip "" (concat (indent idt "<DT><H3") " ADD_DATE=\"" timestamp "\"" " LAST_MODIFIED=\"" timestamp "\"" (if title-code (concat " " title-code "=\"true\"") "") ">" (or title-rename title) "</H3>"))) (1 (concat (indent idt "<DT>") "<A HREF=\"" uri "\"" " ADD_DATE=\"" timestamp "\"" " LAST_MODIFIED=\"" timestamp "\"" (if keyword (concat " SHORTCUTURL=\"" keyword "\"") "") ">" title "</A>"))))) (when children (setq entry (concat entry (if skip "" (concat "\n" (indent idt "<DL><p>\n"))) (mapconcat (lambda (x) (parse x str (+ idt 4))) children "\n") (if skip "" (concat "\n" (indent idt "</DL><p>\n")))))) entry))) (let ((bookmarks (org-bookmarks-parse org-file))) (with-temp-buffer (insert (concat "<!DOCTYPE NETSCAPE-Bookmark-file-1> <META HTTP-EQUIV=\"Content-Type\" CONTENT=\"text/html; charset=UTF-8\"> <TITLE>Bookmarks</TITLE> <H1>Bookmarks</H1> <DL><p>\n" (mapconcat (lambda (x) (parse x "" 4)) bookmarks "\n")) "</DL><p>\n") (if html-file (write-region (point-min) (point-max) html-file) (buffer-substring-no-properties (point-min) (point-max))))))))
Finances
Finance related functions.
;;------------------------------------------------------------------------------ ;;; Org Mode: Finances ;;------------------------------------------------------------------------------ (init-message 2 "Org Mode: Finances")
export-taxes
Export yearly tax report.
;;------------------------------------------------------------------------------ ;;;; Org Mode: Finances: export-taxes ;;------------------------------------------------------------------------------ (init-message 3 "Org Mode: Finances: export-taxes") (defun export-taxes () "Export tax information found at current org subtree." (interactive) (let* ((title (concat "Sherman Taxes " (save-mark-and-excursion (save-match-data (forward-line 0) (re-search-forward "^\*+ " (line-end-position)) (buffer-substring-no-properties (point) (line-end-position)))))) (target-buffer (generate-new-buffer-name (concat "*" title "*")))) (org-cycle 8) (org-copy-subtree) (set-buffer (get-buffer-create target-buffer)) (org-mode) (buffer-disable-undo) (org-paste-subtree) (goto-char (point-min)) (kill-region (line-beginning-position) (line-end-position)) (insert title) (newline) (insert "------------------") (while (re-search-forward "^\*\\{3\\} " nil :noerror) (kill-region (line-beginning-position) (point)) (insert "\n\n") (capitalize-region (line-beginning-position) (line-end-position)) (goto-char (line-end-position))) (goto-char (point-min)) (while (re-search-forward "^\*\\{5\\} " nil :noerror) (kill-region (line-beginning-position) (point)) (insert "\n- ") (capitalize-region (line-beginning-position) (line-end-position))) (goto-char (point-min)) (while (re-search-forward "^\*\\{7\\} " nil :noerror) (kill-region (line-beginning-position) (point)) (insert " - ") (capitalize-region (line-beginning-position) (line-end-position))) (goto-char (point-min)) (while (re-search-forward "^\|-" nil :noerror) (forward-line 0) (when (save-mark-and-excursion (forward-line -1) (not (looking-at "^$"))) (newline)) (goto-char (org-table-end))) (goto-char (point-min)) (while (re-search-forward "^[ \t]*#\\+TBLFM:.*$" nil :noerror) (kill-region (line-beginning-position) (1+ (point)))) (goto-char (point-min)) (switch-to-buffer target-buffer)))
duluth-hotel-invoiced-expense
Fill in Duluth Hotel invoiced expense based on the balance.
;; ;;------------------------------------------------------------------------------ ;; ;;;; Org Mode: Finances: duluth-hotel-invoiced-expense ;; ;;------------------------------------------------------------------------------ ;; (init-message 3 "Org Mode: Finances: duluth-hotel-invoiced-expense") ;; (defun duluth-hotel-invoiced-expense (balance) ;; "Insert Duluth Hotel Invoiced Expense." ;; (interactive "*sTotal Balance: ") ;; (org-table-goto-column 5) ;; (org-table-blank-field) ;; (org-table-recalculate) ;; (org-table-goto-column 7) ;; (let* ((invoice (/ (round (* (- (string-to-number (org-table-get-field)) ;; (string-to-number balance)) ;; 100)) 100.0))) ;; (org-table-goto-column 5) ;; (insert (format "%.2f" invoice)) ;; (org-table-recalculate)))
nwm-add-monthly-account-data
;;------------------------------------------------------------------------------ ;;;; Org Mode: Finances: nwm-add-monthly-account-data ;;------------------------------------------------------------------------------ (init-message 3 "Org Mode: Finances: nwm-add-monthly-account-data") (defun nwm-add-monthly-account-data (data) "Add Northwestern Mutual monthly entries for all accounts found in DATA." (interactive "*sNorthwestern Mutual Account Summary: ") (cl-labels ((date-to-year-month (date) (concat (substring date 6 10) (substring date 0 2)))) (let ((buffer (get-buffer "personal-encrypted.org.gpg")) (tables '("NWM_A40_344433" "NWM_A40_344458" "NWM_A40_345190" "NWM_B40_300756" "NWM_B40_300798" "NWM_PX1_012685" "NWM_PX1_012692")) date balances) (with-temp-buffer (insert data) (goto-char (point-min)) (re-search-forward "^Period Ending: ") (setq date (date-to-year-month (buffer-substring-no-properties (point) (line-end-position)))) (mapcar (lambda (x) (re-search-forward "%\\([0-9,]*\.[0-9][0-9]\\)[0-9.]*%") (push (replace-regexp-in-string "," "" (match-string 1)) balances)) tables)) (with-current-buffer buffer (do ((tables tables (cdr tables)) (balances (nreverse balances) (cdr balances))) ((null tables)) (goto-char (point-min)) (re-search-forward (concat "^[ \t]*#\\+NAME: " (car tables) "$")) (goto-char (org-table-end)) (forward-line -4) (org-table-insert-row) (org-table-goto-column 1) (insert "#") (org-table-goto-column 2) (insert date) (org-table-goto-column 4) (insert (car balances)) (org-table-recalculate) (re-search-forward (concat "^[ \t]*#\\+NAME: " (car tables) "_STATS$")) (forward-line 1) (org-table-recalculate) (org-table-recalculate))))))
Magic the Gathering
Magic the Gathering related functions.
;;------------------------------------------------------------------------------ ;;; Org Mode: Magic the Gathering ;;------------------------------------------------------------------------------ (init-message 2 "Org Mode: Magic the Gathering")
mtg-cards-owned-file-name
Magic the Gathering cards owned file name.
(defconst mtg-cards-owned-file-name (file-truename (expand-file-name "~/org/magic-the-gathering-cards-owned.org")))
mtg-card-list
;;------------------------------------------------------------------------------ ;;;; Org Mode: Magic the Gathering: mtg-card-list ;;------------------------------------------------------------------------------ (init-message 3 "Org Mode: Magic the Gathering: mtg-card-list") (defun mtg-card-list () "Create a list of Magic The Gathering cards in inventory." (interactive) (unless (string= (buffer-name) (file-name-nondirectory mtg-cards-owned-file-name)) (find-file mtg-cards-owned-file-name)) ;; create a copy of the org buffer to work with (let ((source-buffer (current-buffer)) (target-buffer (generate-new-buffer-name "*mtg*"))) (set-buffer (get-buffer-create target-buffer)) (buffer-disable-undo) (insert-buffer-substring source-buffer) (goto-char (point-min)) (search-forward "* mtg cards owned") (forward-line 0) (kill-region (point-min) (point)) (unless (search-forward "* mtg card sets" nil :noerror) (goto-char (point-max))) (forward-line 0) (kill-region (point) (point-max)) (org-mode) (goto-char (point-min)) (outline-show-subtree) (while (re-search-forward "^| +|.*\n" nil :noerror) (replace-match "")) (goto-char (point-min)) (while (re-search-forward "| +Artist" nil :noerror) (org-table-delete-column)) (goto-char (point-min)) (switch-to-buffer target-buffer)))
mtg-deck-search
;;------------------------------------------------------------------------------ ;;;; Org Mode: Magic the Gathering: mtg-deck-search ;;------------------------------------------------------------------------------ (init-message 3 "Org Mode: Magic the Gathering: mtg-deck-search") (defun mtg-deck-search () "Show cards owned from a deck list. LIST must have one card per line with the number of cards followed by the card name." (interactive) (let ((buffer (current-buffer)) cards (ignored '("Plains" "Island" "Swamp" "Mountain" "Forest"))) (save-mark-and-excursion (save-match-data (goto-char (point-min)) (while (re-search-forward "^\s*\\([0-9]+\\)\s*\\(.*\\)\s*$" nil :noerror) (let ((name (buffer-substring-no-properties (match-beginning 2) (match-end 2))) (count (buffer-substring-no-properties (match-beginning 1) (match-end 1)))) (setq name (replace-regexp-in-string "\s*\\[.*\\]\s*" "" name)) (unless (member name ignored) (push (list name count) cards)))))) (setq cards (sort cards (lambda (a b) (string< (car a) (car b))))) ;;(message "%S" cards) (find-file mtg-cards-owned-file-name) (occur (concat "\\(" (substring (apply #'concat (mapcar (lambda (x) (concat "\\|" (car x))) cards)) 2) "\\)")) (switch-to-buffer buffer)))
mtg-set-to-table
;;------------------------------------------------------------------------------ ;;;; Org Mode: Magic the Gathering: mtg-set-to-table ;;------------------------------------------------------------------------------ (init-message 3 "Org Mode: Magic the Gathering: mtg-set-to-table") (defun mtg-set-to-table (&optional owned) "Convert `http://gatherer.wizards.com/' set checklist list to table. If OWNED is non-nil, add an Owned column to the table." (interactive "P") (goto-char (point-min)) (let ((source-buffer (current-buffer)) (target-buffer (generate-new-buffer-name "*mtg-set-table*"))) (set-buffer (get-buffer-create target-buffer)) (buffer-disable-undo) (insert-buffer-substring source-buffer) (goto-char (point-min)) (delete-non-matching-lines "<tr class=\"cardItem\">" (point-min) (point-max)) (goto-char (point-min)) (while (re-search-forward "</tr><tr" nil :noerror) (replace-match "</tr>\n<tr")) (goto-char (point-min)) (while (re-search-forward "<td[^>]*>" nil :noerror) (replace-match "| ")) (goto-char (point-min)) (while (re-search-forward "</td>" nil :noerror) (replace-match " ")) (goto-char (point-min)) (while (re-search-forward "^\s*<tr[^>]*>" nil :noerror) (replace-match "")) (goto-char (point-min)) (while (re-search-forward "</tr>" nil :noerror) (replace-match "|")) (goto-char (point-min)) (while (re-search-forward "<a[^>]*>" nil :noerror) (replace-match "")) (goto-char (point-min)) (while (re-search-forward "</a>" nil :noerror) (replace-match "")) (goto-char (point-min)) (goto-char (point-min)) (insert (concat "|-+-+-+-+-+-|")) (newline) (insert (concat "| # | Name | Artist | Color | Rarity | Set |")) (newline) (insert (concat "|-+-+-+-+-+-|")) (newline) (goto-char (point-max)) (insert (concat "|-+-+-+-+-+-|")) (goto-char (point-min)) (org-mode) (org-table-align) (when owned (org-table-insert-column) (insert "Owned") (org-table-align)) (switch-to-buffer target-buffer)))
mtg-modify-owned-count
;; ;;------------------------------------------------------------------------------ ;; ;;;; Org Mode: Magic the Gathering: mtg-modify-owned-count ;; ;;------------------------------------------------------------------------------ ;; (init-message 3 "Org Mode: Magic the Gathering: mtg-modify-owned-count") ;; (defun mtg-modify-owned-count (&optional amount) ;; "Increment or decrement owned column card count by AMOUNT." ;; (interactive "p") ;; (save-mark-and-excursion ;; (save-match-data ;; (forward-line 0) ;; (when (re-search-forward "^| *\\([^| ]*\\) *|" (line-end-position) :noerror) ;; (let ((num (+ (string-to-number (match-string 1)) (or amount 1)))) ;; (replace-match (number-to-string num) nil nil nil 1) ;; (org-table-align)))))) ;; (defun mtg-modify-owned-count-increment () ;; "Increment owned column card count by one." ;; (interactive) ;; (mtg-modify-owned-count 1)) ;; (defun mtg-modify-owned-count-decrement () ;; "Decrement owned column card count by one." ;; (interactive) ;; (mtg-modify-owned-count -1)) ;; (with-eval-after-load "org" ;; (bind-keys :map org-mode-map ;; ("C-c ]" . mtg-modify-owned-count-increment) ;; ("C-c [" . mtg-modify-owned-count-decrement)))
MechWarrior Online
MechWarrior Online related functions.
;;------------------------------------------------------------------------------ ;;; Org Mode: MechWarrior Online ;;------------------------------------------------------------------------------ (init-message 2 "Org Mode: MechWarrior Online")
mwo-export-mech
;;------------------------------------------------------------------------------ ;;;; Org Mode: MechWarrior Online: mwo-export-mech ;;------------------------------------------------------------------------------ (init-message 3 "Org Mode: MechWarrior Online: mwo-export-mech") (defun mwo-export-mech () "Export mech found at current org subtree." (interactive) (let ((target-buffer (generate-new-buffer-name "*mwo-mech*"))) (org-cycle 8) (org-copy-subtree) (set-buffer (get-buffer-create target-buffer)) (buffer-disable-undo) (org-paste-subtree) (goto-char (point-min)) (while (re-search-forward "^\*+ " (line-end-position) :noerror) (replace-match "")) (while (re-search-forward "^\*+ " nil :noerror) (kill-region (line-beginning-position) (point)) (newline) (capitalize-region (line-beginning-position) (line-end-position)) (goto-char (line-end-position)) (newline)) (switch-to-buffer target-buffer) (goto-char (point-min))))
Dungeons and Dragons Online
Dungeons and Dragons Online related functions.
;;------------------------------------------------------------------------------ ;;; Org Mode: Dungeons and Dragons Online ;;------------------------------------------------------------------------------ (init-message 2 "Org Mode: Dungeons and Dragons Online")
ddo-get-item-info
;;------------------------------------------------------------------------------ ;;;; Org Mode: Dungeons and Dragons Online: ddo-get-item-info ;;------------------------------------------------------------------------------ (init-message 3 "Org Mode: Dungeons and Dragons Online: ddo-get-item-info") (defun ddo-get-item-info (&optional item) "Look up ITEM in the DDO Wiki and return information about it." (interactive "sDDO Item Name: ") (save-current-buffer (let* ((url (url-encode-url (concat "http://ddowiki.com/index.php?search=" item))) (buffer (url-retrieve-synchronously url)) (enchantments "")) (when buffer (set-buffer buffer) (goto-char (point-min)) (when (re-search-forward "Enchantments" nil :noerror) (let ((start (point))) (when (re-search-forward "</td>" nil :noerror) (let ((end (point))) (goto-char start) (while (re-search-forward "<a .*>\\([^<]*\\)</a>" end :noerror) (setq enchantments (concat enchantments (if (zerop (length enchantments)) "" ", ") (buffer-substring-no-properties (match-beginning 1) (match-end 1)))) (when (re-search-forward "</span>\\([^<]*\\)</li>" end :noerror) (setq enchantments (concat enchantments (buffer-substring-no-properties (match-beginning 1) (match-end 1)))))))))) (concat item " (" enchantments ")\n" url)))))
ddo-fix-wiki-description
;;------------------------------------------------------------------------------ ;;;; Org Mode: Dungeons and Dragons Online: ddo-fix-wiki-description ;;------------------------------------------------------------------------------ (init-message 3 "Org Mode: Dungeons and Dragons Online: ddo-fix-wiki-description") (defun ddo-fix-wiki-description () "Fix wiki description around point." (interactive) (forward-line 0) (while (not (looking-at "\\*")) (insert ", ") (forward-line 0) (delete-char -1) (forward-line 0)) (while (re-search-forward "Icon tooltip\.png" (line-end-position) :noerror) (replace-match "")) (forward-line 0) (while (re-search-forward " +," (line-end-position) :noerror) (replace-match ",")) (forward-line 0) (while (re-search-forward ",," (line-end-position) :noerror) (replace-match ",")) (forward-line 0) (while (re-search-forward " +" (line-end-position) :noerror) (replace-match " ")) (forward-line 0) (while (re-search-forward " +$" (line-end-position) :noerror) (replace-match "")) (goto-char (line-end-position)) (insert ")"))
Org Website
Org Website is a collection of my customization's to org-babel
to generate
my website from org-mode
files.
Required OS binaries:
- libxslt
;;============================================================================== ;;; Org Website ;;============================================================================== (init-message 1 "Org Website")
Configuration
Org Website configuration of org-publish
.
;;------------------------------------------------------------------------------ ;;; Org Website: Configuration ;;------------------------------------------------------------------------------ (init-message 2 "Org Website: Configuration")
Publish Configuration
;;------------------------------------------------------------------------------ ;;;; Org Website: Configuration: Publish Configuration ;;------------------------------------------------------------------------------ (init-message 3 "Org Website: Configuration: Publish Configuration") (use-package org :straight (:type built-in) :commands (org-export-as org-export-to-buffer org-export-to-file) :functions (org-export-collect-footnote-definitions org-export-data org-export-define-derived-backend org-export-footnote-first-reference-p org-export-get-footnote-number org-export-get-previous-element org-export-get-relative-level org-website-convert-url-to-gopher-selector-hostname-port) :config (when (require 'ox nil :no-error) ;; add gopher link support (i.e. [[gopher:LINK]]) (defun org-link-gopher-export-link (link desc format) "Create export version of LINK and DESC to FORMAT." (let ((link (concat "gopher:" link))) (cond ((eq format 'html) (format "<a href=\"%s\">%s</a>" link desc)) ((eq format 'latex) (format "\\href{%s}{%s}" link desc)) ((eq format 'gopher) (format "1\t%s\t%s" desc (org-website-convert-url-to-gopher-selector-hostname-port link))) (t (format "[%s](%s)" desc link))))) (org-link-set-parameters "gopher" :export #'org-link-gopher-export-link)) (require 'ox-publish nil :no-error) (require 'ox-ascii nil :no-error) (when (require 'ox-html nil :no-error) (let* ((site-extension "org") (shared-extension "css") (statics-extension (concat "html\\|css\\|js\\|sh\\|" "txt\\|rss\\|" "ico\\|gif\\|png\\|jpg\\|" "mp4\\|webm\\|" "eot\\|ttf\\|woff\\|" "pdf\\|odt\\|doc\\|docx\\|" "tgz\\|zip\\|" "xml\\|xsd\\|xsl")) (assets-extension (concat "org\\|" statics-extension))) ;; website publishing instructions (setq org-publish-project-alist `(;; nullman site ("nullman" :components ("nullman-shared" "nullman-assets" "nullman-site" "nullman-site-statics" "nullman-site-gopher" "rsync")) ("nullman-shared" :base-directory "~/web/sites/shared" :base-extension ,shared-extension :publishing-directory "~/web/sites/nullman/site" :publishing-function org-publish-attachment :recursive t) ("nullman-assets" :base-directory "~/web/sites/nullman/assets" :base-extension ,assets-extension :publishing-directory "~/web/sites/nullman/site" :publishing-function org-publish-attachment :recursive t) ("nullman-site" :base-directory "~/web/sites/nullman/site" :base-extension ,site-extension :publishing-directory "~/public_html/sites/nullman" :publishing-function org-website-html-publish-to-html :recursive t) ("nullman-site-statics" :base-directory "~/web/sites/nullman/site" :base-extension ,statics-extension :publishing-directory "~/public_html/sites/nullman" :publishing-function org-publish-attachment :recursive t) ("nullman-site-gopher" :base-directory "~/web/sites/nullman/site" :base-extension ,site-extension :publishing-directory "~/public_gopher/sites/nullman" :publishing-function org-website-gopher-publish-to-gopher :recursive t) ;; blog site ("blog" :components ("blog-shared" "blog-assets" "blog-site" "blog-site-statics" ;;"blog-site-rss" "rsync")) ("blog-shared" :base-directory "~/web/sites/shared" :base-extension ,shared-extension :publishing-directory "~/web/sites/blog/site" :publishing-function org-publish-attachment :recursive t) ("blog-assets" :base-directory "~/web/sites/blog/assets" :base-extension ,assets-extension :publishing-directory "~/web/sites/blog/site" :publishing-function org-publish-attachment :recursive t) ("blog-site" :base-directory "~/web/sites/blog/site" :base-extension ,site-extension :publishing-directory "~/public_html/sites/blog" :publishing-function org-website-html-publish-to-html :recursive t) ("blog-site-statics" :base-directory "~/web/sites/blog/site" :base-extension ,statics-extension :publishing-directory "~/public_html/sites/blog" :publishing-function org-publish-attachment :recursive t) ;; blog-site-rss is no longer used as the rss feed is generated from a tangle block in blog.org ;; ("blog-site-rss" ;; :base-directory "~/web/sites/blog/site" ;; :base-extension ,site-extension ;; :rss-extension "rss" ;; :rss-feed-url "http://blog.nullman.net/" ;; :rss-image-url "http://blog.nullman.net/img/image.png" ;; :publishing-directory "~/public_html/sites/blog" ;; :publishing-function org-website-rss-publish-to-rss ;; :exclude "." ;; :include ("index.org")) ;; nullware site ("nullware" :components ("nullware-shared" "nullware-assets" "nullware-site" "nullware-site-statics" "rsync")) ("nullware-shared" :base-directory "~/web/sites/shared" :base-extension ,shared-extension :publishing-directory "~/web/sites/nullware/site" :publishing-function org-publish-attachment :recursive t) ("nullware-assets" :base-directory "~/web/sites/nullware/assets" :base-extension ,assets-extension :publishing-directory "~/web/sites/nullware/site" :publishing-function org-publish-attachment :recursive t) ("nullware-site" :base-directory "~/web/sites/nullware/site" :base-extension ,site-extension :publishing-directory "~/public_html/sites/nullware" :publishing-function org-website-html-publish-to-html :recursive t) ("nullware-site-statics" :base-directory "~/web/sites/nullware/site" :base-extension ,statics-extension :publishing-directory "~/public_html/sites/nullware" :publishing-function org-publish-attachment :recursive t) ;; kylesherman site ("kylesherman" :components ("kylesherman-shared" "kylesherman-assets" "kylesherman-site" "kylesherman-site-statics" "rsync")) ("kylesherman-shared" :base-directory "~/web/sites/shared" :base-extension ,shared-extension :publishing-directory "~/web/sites/kylesherman/site" :publishing-function org-publish-attachment :recursive t) ("kylesherman-assets" :base-directory "~/web/sites/kylesherman/assets" :base-extension ,assets-extension :publishing-directory "~/web/sites/kylesherman/site" :publishing-function org-publish-attachment :recursive t) ("kylesherman-site" :base-directory "~/web/sites/kylesherman/site" :base-extension ,site-extension :publishing-directory "~/public_html/sites/kylesherman" :publishing-function org-website-html-publish-to-html :recursive t) ("kylesherman-site-statics" :base-directory "~/web/sites/kylesherman/site" :base-extension ,statics-extension :publishing-directory "~/public_html/sites/kylesherman" :publishing-function org-publish-attachment :recursive t) ;; shermanwest site ("shermanwest" :components ("shermanwest-shared" "shermanwest-assets" "shermanwest-site" "shermanwest-site-statics" "rsync")) ("shermanwest-shared" :base-directory "~/web/sites/shared" :base-extension ,shared-extension :publishing-directory "~/web/sites/shermanwest/site" :publishing-function org-publish-attachment :recursive t) ("shermanwest-assets" :base-directory "~/web/sites/shermanwest/assets" :base-extension ,assets-extension :publishing-directory "~/web/sites/shermanwest/site" :publishing-function org-publish-attachment :recursive t) ("shermanwest-site" :base-directory "~/web/sites/shermanwest/site" :base-extension ,site-extension :publishing-directory "~/public_html/sites/shermanwest" :publishing-function org-website-html-publish-to-html :recursive t) ("shermanwest-site-statics" :base-directory "~/web/sites/shermanwest/site" :base-extension ,statics-extension :publishing-directory "~/public_html/sites/shermanwest" :publishing-function org-publish-attachment :recursive t) ;; rsync ("rsync" :base-directory "~/web" :base-extension "none" :publishing-directory "~/public_html") ;;:completion-function org-website-rsync-to-localhost-morpheus) )) ;; links (setq org-link-abbrev-alist (append ;; internal links '(("about" . "http://nullman.net/about/") ("blog" . "http://blog.nullman.net/") ("blog-post" . "%(org-website-blog-url)") ("emacs" . "http://nullman.net/emacs/") ("nullman" . "http://nullman.net/") ("pet-peeves" . "http://nullman.net/rants/pet-peeves.html") ("powerhouse" . "http://powerhouse.nullware.com/") ("projects" . "http://nullman.net/projects/") ("rants" . "http://nullman.net/rants/") ("tutorials" . "http://nullman.net/tutorials/")) ;; external links '(("cowiki" . "http://www.champions-online-wiki.com/wiki/") ("google" . "http://www.google.com/search?q=%h") ("urban" . "http://www.urbandictionary.com/define.php?term=") ("wiki" . "http://en.wikipedia.org/wiki/Special:Search?search=") ("word" . "http://en.wiktionary.org/wiki/") ("youtube" . "https://www.youtube.com/watch?v=")))) ;; use h1 tags for top level headlines (instead of h2) (setq org-html-toplevel-hlevel 1) ;; remove table attributes (setq org-html-table-default-attributes nil) ;;(setq org-html-table-default-attributes '(:class "org-table")) )))
Menu Lists
;;------------------------------------------------------------------------------ ;;;; Org Website: Configuration: Menu Lists ;;------------------------------------------------------------------------------ (init-message 3 "Org Website: Configuration: Menu Lists") ;; standard menu list (defconst org-website-menu-list '((:home . (:name "Home" :title "Home Page" :url "http://nullman.net/")) (:blog . (:name "Blog" :title "Personal Blog" :url "http://blog.nullman.net/")) (:applications . (:name "Applications" :title "Nullware Applications" :url "http://nullware.com/")) (:emacs . (:name "Emacs" :title "Emacs Customizations" :url "http://nullman.net/emacs/")) (:projects . (:name "Projects" :title "Computer Programming Projects" :url "http://nullman.net/projects/")) (:tutorials . (:name "Tutorials" :title "Computer Tutorials" :url "http://nullman.net/tutorials/")) (:presentations . (:name "Presentations" :title "Presentations I've Given" :url "http://nullman.net/presentations/")) (:interesting . (:name "Interesting" :title "Things of Interest" :url "http://nullman.net/interesting/")) (:games . (:name "Games" :title "Computer Games" :url "http://nullman.net/games/")) (:quotes . (:name "Quotes" :title "Collected Quotes" :url "http://nullman.net/quotes/")) (:rants . (:name "Rants" :title "Random Ramblings and Rants" :url "http://nullman.net/rants/")) (:social . (:name "Social" :title "Social Links" :url "http://nullman.net/social/")) ;;(:twitter . (:name "Twitter" :title "Nullman Twitter Feed" :url "http://nullman.net/social/twitter.html")) (:photos . (:name "Photos" :title "Personal Photographs" :url "http://nullman.net/photos/")) (:bookmarks . (:name "Bookmarks" :title "Personal Bookmarks" :url "http://nullman.net/bookmarks/")) (:about . (:name "About" :title "About This Site and Its Author" :url "http://nullman.net/about/"))) "Website standard menu list. Format: ((TAG . (:name NAME :title TITLE :url URL)) ... )") ;; shermanwest menu list (defconst org-website-shermanwest-menu-list '((:home . (:name "Home" :title "Home Page" :url "http://shermanwest.com/")) (:pictures . (:name "Pictures" :title "Condo Pictures" :url "http://www.flickr.com/photos/nullman/sets/72157603365914146/show/")) (:directions . (:name "Directions" :title "Sherman West Directions" :url "http://shermanwest.com/directions.html")) (:restaurants . (:name "Restaurants" :title "San Diego Restaurants" :url "http://shermanwest.com/restaurants.html")) (:bars . (:name "Bars" :title "San Diego Bars" :url "http://shermanwest.com/bars.html")) (:attractions . (:name "Attractions" :title "San Diego Attractions" :url "http://shermanwest.com/attractions.html")) (:shopping . (:name "Shopping" :title "San Diego Shopping" :url "http://shermanwest.com/shopping.html")) (:rules . (:name "Rules" :title "House Rules" :url "http://shermanwest.com/rules.html")) (:guestbook . (:name "Guestbook" :title "Guestbook" :url "http://shermanwest.com/guestbook.html"))) "Website Sherman West menu list. Format: ((TAG . (:name NAME :title TITLE :url URL)) ... )") ;; gopher menu list (defconst org-website-gopher-menu-list '((:home . (:name "Home" :title "Home Page" :selector "/nullman/index.gopher")) (:blog . (:name "Blog" :title "Personal Blog" :selector "/blog/index.gopher")) (:applications . (:name "Applications" :title "Nullware Applications" :selector "/nullware/index.gopher")) (:emacs . (:name "Emacs" :title "Emacs Customizations" :selector "/nullman/emacs/index.gopher")) (:projects . (:name "Projects" :title "Computer Programming Projects" :selector "/nullman/projects/index.gopher")) (:tutorials . (:name "Tutorials" :title "Computer Tutorials" :selector "/nullman/tutorials/index.gopher")) (:presentations . (:name "Presentations" :title "Presentations I've Given" :selector "/nullman/presentations/index.gopher")) (:interesting . (:name "Interesting" :title "Things of Interest" :selector "/nullman/interesting/index.gopher")) (:games . (:name "Games" :title "Computer Games" :selector "/nullman/games/index.gopher")) (:quotes . (:name "Quotes" :title "Collected Quotes" :selector "/nullman/quotes/index.gopher")) (:rants . (:name "Rants" :title "Random Ramblings and Rants" :selector "/nullman/rants/index.gopher")) (:social . (:name "Social" :title "Social Links" :selector "/nullman/social/index.gopher")) ;;(:twitter . (:name "Twitter" :title "Nullman Twitter Feed" :selector "/nullman/social/twitter.gopher")) (:photos . (:name "Photos" :title "Personal Photographs" :selector "/nullman/photos/index.gopher")) (:bookmarks . (:name "Bookmarks" :title "Personal Bookmarks" :selector "/nullman/bookmarks/index.gopher")) (:about . (:name "About" :title "About This Site and Its Author" :selector "/nullman/about/index.gopher"))) "Website Gopher menu list. Format: ((TAG . (:name NAME :title TITLE :selector SELECTOR)) ... )")
Gopher Configuration
;;------------------------------------------------------------------------------ ;;;; Org Website: Configuration: Gopher Configuration ;;------------------------------------------------------------------------------ (init-message 3 "Org Website: Configuration: Gopher Configuration") ;; gopher server port (defconst gopher-port 70 "Port used by Gopher server.") ;; gopher max text width before word wrapping (defconst gopher-text-width org-ascii-text-width "Maximum width of Gopher text before word wrapping.") ;; gopher item types ;; INFO https://en.wikipedia.org/wiki/Gopher_(protocol) (defconst gopher-type-text-file "0") (defconst gopher-type-submenu "1") (defconst gopher-type-binary-file "9") (defconst gopher-type-gif-file "g") (defconst gopher-type-image-file "i") (defconst gopher-type-html-file "h") (defconst gopher-type-sound-file "s")
Functions
Org Website supporting functions.
;;------------------------------------------------------------------------------ ;;; Org Website: Functions ;;------------------------------------------------------------------------------ (init-message 2 "Org Website: Functions")
Get Content Property List
;; ;;------------------------------------------------------------------------------ ;; ;;;; Org Website: Functions: Get Content Property List ;; ;;------------------------------------------------------------------------------ ;; (init-message 3 "Org Website: Functions: Get Content Property List") ;; (defun org-website-get-contents-property-list (contents) ;; "Return property list for CONTENTS." ;; (let (property-list) ;; (with-temp-buffer ;; (insert contents) ;; (goto-char (point-min)) ;; (while (re-search-forward "^[ \t]*#\\+\\(.*\\): \\(.*\\)$" (line-end-position) :noerror) ;; (push (cons ;; (intern (concat ":" (downcase (replace-regexp-in-string "_" "-" (match-string 1))))) ;; (match-string 2)) ;; property-list) ;; (forward-char 1))) ;; (nreverse property-list)))
Get Property List
;;------------------------------------------------------------------------------ ;;;; Org Website: Functions: Get Property List ;;------------------------------------------------------------------------------ (init-message 3 "Org Website: Functions: Get Property List") (defun org-website-get-property-list (info) "Return an association list of org properties in INFO." (org-element-map (plist-get info :parse-tree) 'keyword (lambda (x) (let ((key (intern (concat ":" (replace-regexp-in-string "_" "-" (downcase (org-element-property :key x))))))) (cons key (org-element-property :value x))))))
Get Property Element
;;------------------------------------------------------------------------------ ;;;; Org Website: Functions: Get Property Element ;;------------------------------------------------------------------------------ (init-message 3 "Org Website: Functions: Get Property Element") (defun org-website-get-property-element (property-list element) "Return ELEMENT from PROPERTY-LIST returned from `org-website-get-property-list', or empty string if element was not found." (or (cdr (assoc element property-list)) ""))
Get Data
;; ;;------------------------------------------------------------------------------ ;; ;;;; Org Website: Functions: Get Data ;; ;;------------------------------------------------------------------------------ ;; (init-message 3 "Org Website: Functions: Get Data") ;; (defun org-website-get-data (file) ;; "Return tree structure version of given Org FILE. ;; Format: ;; (((\"TIMESTAMP\" . TIMESTAMP) ;; (\"DESCRIPTION\" . DESCRIPTION) ;; (\"TITLE\" . TITLE)) ;; ((HEADLINE1) ;; (HEADLINE2 ;; (HEADLINE21 . BODY21)) ;; (HEADLINE3 ;; (HEADLINE31 ;; (HEADLINE311 . BODY311) ;; (HEADLINE312 . BODY312)) ;; (HEADLINE32 ;; (HEADLINE321 . BODY321) ;; (HEADLINE322 . BODY322)))))" ;; (let* ((property-regexp "^[ \t]*#\\+\\(.*\\): \\(.*\\)$") ;; (property-names '("TITLE" "DESCRIPTION" "TIMESTAMP")) ;; (headline-regexp "^\\(\*+ \\)\\(.*\\)$") ;; (property-alist nil) ;; (level 0) ;; (tree (cons nil nil)) ;; (start tree) ;; (stack nil)) ;; (with-temp-buffer ;; (insert-file-contents file) ;; (goto-char (point-min)) ;; (while (not (eobp)) ;; ;;(message "%S" tree) ;; (cond ;; ;; add properties ;; ((looking-at property-regexp) ;; (let ((key (match-string-no-properties 1)) ;; (value (match-string-no-properties 2))) ;; (when (member key property-names) ;; (push (cons key value) property-alist)))) ;; ;; add folders ;; ((looking-at headline-regexp) ;; (let ((headline-level (/ (length (match-string-no-properties 1)) ;; (if org-odd-levels-only 2 1))) ;; (headline-value (match-string-no-properties 2))) ;; (cond ;; ((> headline-level level) ;; (setcdr tree (cons (cons headline-value nil) nil)) ;; (setq tree (cdr tree)) ;; (push tree stack) ;; (setq tree (car tree)) ;; (setq level headline-level)) ;; ((= headline-level level) ;; (setq tree (pop stack)) ;; (setcdr tree (cons (cons headline-value nil) nil)) ;; (setq tree (cdr tree)) ;; (push tree stack) ;; (setq tree (car tree))) ;; ((< headline-level level) ;; (while (< headline-level level) ;; (setq tree (pop stack)) ;; (setq level (1- level))) ;; (setq tree (pop stack)) ;; (setcdr tree (cons (cons headline-value nil) nil)) ;; (setq tree (cdr tree)) ;; (push tree stack) ;; (setq tree (car tree)) ;; (setq level headline-level))))) ;; ;; add body sections ;; (t ;; (when (> (length start) 1) ;; (let ((body "")) ;; (while (and (not (eobp)) ;; (not (looking-at property-regexp)) ;; (not (looking-at headline-regexp))) ;; (when (> (length body) 0) ;; (setq body (concat body "\n"))) ;; (setq body (concat body ;; (replace-regexp-in-string "^[ \t\n]*" "" ;; (buffer-substring-no-properties ;; (line-beginning-position) ;; (line-end-position))))) ;; (forward-line 1)) ;; (setcdr tree (cons (replace-regexp-in-string "[ \t\n]*$" "" body) nil)) ;; (setq tree (cdr tree)) ;; (forward-line 0) ;; (forward-line -1))))) ;; (forward-line 1)) ;; (cons property-alist (cdr start)))))
Get URL
;;------------------------------------------------------------------------------ ;;;; Org Website: Functions: Get URL ;;------------------------------------------------------------------------------ (init-message 3 "Org Website: Functions: Get URL") (defun org-website-get-url (property-list) "Return target URL for current buffer being exported." (concat (org-website-get-property-element property-list :link-home) (replace-regexp-in-string "^.*/site/" "" (replace-regexp-in-string "\.[^\.]*$" "" buffer-file-name)) ".html"))
Blog URL
;;------------------------------------------------------------------------------ ;;;; Org Website: Functions: Blog URL ;;------------------------------------------------------------------------------ (init-message 3 "Org Website: Functions: Blog URL") (defun org-website-blog-url (&optional name) "Return URL of given blog NAME. If NAME is non-nil, return base URL." (let ((parts (split-string name "[.]"))) (concat "http://blog.nullman.net/" (nth 0 parts) "/" (nth 1 parts) "/" name ".html"))) (put #'org-website-blog-url 'org-link-abbrev-safe t)
Is Blog Post
;;------------------------------------------------------------------------------ ;;;; Org Website: Functions: Is Blog Post ;;------------------------------------------------------------------------------ (init-message 3 "Org Website: Functions: Is Blog Post") (defun org-website-is-blog-post (property-list) "Return non-nil if current page is a blog entry." (zerop (length (replace-regexp-in-string "^.*/[0-9]\\{4\\}.[0-9]\\{2\\}.[0-9]\\{2\\}.[0-9]\\{4\\}-.*$" "" buffer-file-name))))
Get Level
;;------------------------------------------------------------------------------ ;;;; Org Website: Functions: Get Level ;;------------------------------------------------------------------------------ (init-message 3 "Org Website: Functions: Get Level") (defun org-website-get-level (property-list) "Return level of current project file." (- (length (split-string (org-website-get-url property-list) "/")) 3))
Format Headline
;;------------------------------------------------------------------------------ ;;;; Org Website: Functions: Format Headline ;;------------------------------------------------------------------------------ (init-message 3 "Org Website: Functions: Format Headline") (defun org-website-format-headline (headline &optional char col) "Return HEADLINE surrounded by CHAR ending at COL length." (let* ((char (or char ?=)) (col (or col org-ascii-text-width)) (text-width (- col 12)) ;; if headline is too long, split it into multiple lines (headline (if (> (length headline) text-width) (let ((fill-column text-width)) (with-temp-buffer (insert headline) (fill-region (point-min) (point-max)) (buffer-string))) headline))) (mapconcat (lambda (line) (let ((str (concat (make-string 5 char) " " (upcase line) " " (make-string 5 char)))) (while (< (length str) col) (setq str (concat str (string char)))) str)) (split-string headline "\n") "\n")))
Get Gopher Selector Hostname Port
;;------------------------------------------------------------------------------ ;;;; Org Website: Functions: Get Gopher Selector Hostname Port ;;------------------------------------------------------------------------------ (init-message 3 "Org Website: Functions: Get Gopher Selector Hostname Port") (defun org-website-get-gopher-selector-hostname-port (selector) "Return Gopher selector, hostname, and port from given SELECTOR." (let* ((hostname "nullman.net") (port (if (boundp 'gopher-port) gopher-port 70))) (concat selector "\t" hostname "\t" (int-to-string port))))
Convert URL to Gopher Selector Hostname Port
;;------------------------------------------------------------------------------ ;;;; Org Website: Functions: Convert URL to Gopher Selector Hostname Port ;;------------------------------------------------------------------------------ (init-message 3 "Org Website: Functions: Convert URL to Gopher Selector Hostname Port") (defun org-website-convert-url-to-gopher-selector-hostname-port (url) "Return Gopher selector, hostname, and port from given URL." (let* ((suffix (replace-regexp-in-string "^.*://" "" url)) (hostname (replace-regexp-in-string "/.*$" "" suffix)) (selector (replace-regexp-in-string "^.*?/" "/" suffix)) (port (if (boundp 'gopher-port) gopher-port 70))) (concat selector "\t" hostname "\t" (int-to-string port))))
Gopher Justify Lines
;;------------------------------------------------------------------------------ ;;;; Org Website: Functions: Gopher Justify Lines ;;------------------------------------------------------------------------------ (init-message 3 "Org Website: Functions: Gopher Justify Lines") (defun org-website-gopher-justify-lines (str &optional indent width justify) "Return STR after justifying all lines. INDENT is the amount to indent the final text (defaults to 0). WIDTH is an integer specifying maximum length of a line (defaults to `gopher-text-width' or `org-ascii-text-width'). JUSTIFY determines the type of justification: `left', `right', `full', `center', or `none' (defaults to `none')." (with-temp-buffer (let ((indent (or indent 0)) (fill-column (or width (and (boundp 'gopher-text-width) gopher-text-width) org-ascii-text-width))) (insert str) ;; replace all newlines with doubles to prevent their removal when justifying (goto-char (point-min)) (while (search-forward "\n" nil :noerror) (replace-match "\n\n")) ;; justify string (fill-region (point-min) (point-max) justify :nosqueeze :to-eop) ;; replace double newlines with single to return to original format (goto-char (point-min)) (while (search-forward "\n\n" nil :noerror) (replace-match "\n")) ;; indent (when (> indent 0) (let ((spc (make-string indent ? ))) (goto-char (point-min)) (while (not (eobp)) (insert spc) (forward-line 0) (forward-line 1)))) ;; return justified string (buffer-string))))
Publish HTML
;;------------------------------------------------------------------------------ ;;; Org Website: Publish HTML ;;------------------------------------------------------------------------------ (init-message 2 "Org Website: Publish HTML")
Derived Backend
;;------------------------------------------------------------------------------ ;;;; Org Website: Publish HTML: Derived Backend ;;------------------------------------------------------------------------------ (init-message 3 "Org Website: Publish HTML: Derived Backend") ;; create derived backend with customizations to html backend (org-export-define-derived-backend 'org-website-html 'html :translate-alist '((template . org-website-html-template) (inner-template . org-website-html-inner-template) (headline . org-website-html-headline) (section . org-website-html-section)))
Publish to HTML
;;------------------------------------------------------------------------------ ;;;; Org Website: Publish HTML: Publish to HTML ;;------------------------------------------------------------------------------ (init-message 3 "Org Website: Publish HTML: Publish to HTML") (defun org-website-html-publish-to-html (plist file-name pub-dir) "Publish a Website org file to HTML and return output file name. FILE-NAME is the file name of the Org file to be published. PLIST is the property list for the given project. PUB-DIR is the publishing directory." (org-publish-org-to 'org-website-html file-name (concat "." (or (plist-get plist :html-extension) org-html-extension "html")) plist pub-dir))
Template
;;------------------------------------------------------------------------------ ;;;; Org Website: Publish HTML: Template ;;------------------------------------------------------------------------------ (init-message 3 "Org Website: Publish HTML: Template") ;; custom html template ;; INFO reference: http://orgmode.org/worg/dev/org-export-reference.html (defun org-website-html-template (contents info) "Return complete document string after HTML conversion. CONTENTS is the transcoded contents string. INFO is a plist holding export options." (let* ((property-list (org-website-get-property-list info)) (site (org-website-get-property-element property-list :site)) (title (org-website-get-property-element property-list :title))) ;;(message "%S" info) ;;(message "%S" property-list) (concat ;; "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n" ;; "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Strict//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd\">\n" "<!DOCTYPE html>\n" (format "<html xmlns=\"http://www.w3.org/1999/xhtml\" lang=\"%s\">\n" (org-website-get-property-element property-list :language)) "\n" "<head>\n" "\n" (format " <title>%s</title>\n" title) "\n" (format " <meta http-equiv=\"Content-Type\" content=\"text/html; charset=%s\" />\n" (or (coding-system-get org-html-coding-system 'mime-charset) "utf-8")) " <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\" />\n" (format " <meta name=\"author\" content=\"%s\" />\n" (org-website-get-property-element property-list :author)) (format " <meta name=\"keywords\" content=\"%s\" />\n" (org-website-get-property-element property-list :keywords)) (format " <meta name=\"description\" content=\"%s\" />\n" (org-website-get-property-element property-list :description)) " <meta name=\"generator\" content=\"org-mode\" />\n" " <meta name=\"robots\" content=\"all\" />\n" " <meta name=\"google-site-verification\" content=\"" (org-website-get-property-element property-list :google-site-verification) "\" />\n" "\n" " <link rel=\"alternate\" type=\"application/rss+xml\" title=\"RSS Feed\" href=\"http://blog.nullman.net/index.rss\" />\n" " <link rel=\"author\" href=\"http://nullman.net/about.html\" />\n" " <link rel=\"home\" href=\"/\" />\n" (cond ((and (string= site "kylesherman") (string= title "Resume")) " <link rel=\"stylesheet\" type=\"text/css\" media=\"all\" href=\"/styles/resume.css\" />\n") (t " <link rel=\"stylesheet\" type=\"text/css\" media=\"all\" href=\"/styles/default.css\" />\n")) " <link rel=\"stylesheet\" type=\"text/css\" media=\"print\" href=\"/styles/print.css\" />\n" "\n" " <!-- Google Analytics -->\n" " <script><!--\n" " var _gaq = _gaq || [];\n" " _gaq.push(['_setAccount', '" (org-website-get-property-element property-list :google_analytics) "']);\n" " _gaq.push(['_trackPageview']);\n" " (function() {\n" " var ga = document.createElement('script'); ga.async = true;\n" " ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';\n" " var s = document.getElementsByTagName('script')[0];\n" " s.parentNode.insertBefore(ga, s);\n" " })();\n" " // --></script>\n" "\n" (concat (org-element-normalize-string (plist-get info :html-head)) (org-element-normalize-string (plist-get info :html-head-extra))) "\n" "</head>\n" "\n" "<body>\n" "\n" " <div id=\"container\">\n" "\n" ;; header (cond ((and (string= site "kylesherman") (string= title "Resume")) "") (t (concat " <!-- header start -->\n" "\n" " <div id=\"header\">\n" " <h1 class=\"title\">\n" (format " <span>%s</span>\n" title) " </h1>\n" " </div>\n" "\n" " <!-- header end -->\n" "\n"))) ;; left menu (if (> (length (org-website-get-property-element property-list :menu)) 0) (concat " <!-- menu start -->\n" "\n" " <div id=\"menu\">\n" "\n" (mapconcat (lambda (x) (let* ((plist (cdr x)) (name (plist-get plist :name)) (title (plist-get plist :title)) (url (plist-get plist :url)) (current (string= (org-website-get-property-element property-list :menu) name))) (concat " <div class=\"" (if current "menu-item-current" "menu-item") "\">\n" " <a title=\"" title "\" href=\"" url "\">" name "</a>\n" " </div>\n"))) (if (string= site "shermanwest") org-website-shermanwest-menu-list org-website-menu-list) "") "\n" " <!-- search start -->\n" "\n" " <div class=\"search\">\n" " <form method=\"get\" action=\"http://www.google.com/search\">\n" " <fieldset>\n" " <input type=\"hidden\" name=\"q\" value=\"site:http://blog.nullman.net/ OR site:http://nullman.net/ OR site:http://nullware.com/\" />\n" " <input type=\"hidden\" name=\"hl\" value=\"en\" />\n" " <input type=\"text\" name=\"q\" maxlength=\"2048\" value=\"\" title=\"Search\" style=\"width: 5.5em\" />\n" " <input type=\"image\" name=\"btnG\" src=\"/img/search.png\" alt=\"Search\" style=\"height: 100%; vertical-align: middle\" />\n" " </fieldset>\n" " </form>\n" " </div>\n" "\n" " <!-- search end -->\n" "\n" " </div>\n" "\n" " <!-- menu end -->\n" "\n") "") ;; main content (cond ((string= site "blog") (org-website-html-blog-contents-template contents info property-list)) ((string= site "kylesherman") (concat " <!-- content start -->\n" "\n" (if (string= title "Resume") contents (concat " <div id=\"content-generic\">\n" "\n" contents "\n" " </div>\n")) "\n" " <!-- content end -->\n" "\n")) (t (concat " <!-- content start -->\n" "\n" " <div id=\"content\">\n" "\n" contents "\n" " </div>\n" "\n" " <!-- content end -->\n" "\n"))) ;; footer (cond ((string= site "kylesherman") "") (t (concat " <!-- footer start -->\n" "\n" " <div id=\"footer\">\n" "\n" " <div class=\"validator\">\n" " <a title=\"Check the validity of this page using W3C's unified validator\"\n" (format " href=\"http://validator.w3.org/unicorn/check?ucn_task=conformance&ucn_uri=%s\">unicorn</a>\n" (org-website-get-property-element property-list :link-home)) " </div>\n" "\n" " <div class=\"validator\">\n" " <a title=\"Check the validity of this page's XHTML\"\n" " href=\"http://validator.w3.org/check?uri=referer\">xhtml</a>\n" " </div>\n" "\n" " <div class=\"validator\">\n" " <a title=\"Check the validity of this page's CSS\"\n" " href=\"http://jigsaw.w3.org/css-validator/check/referer\">css</a>\n" " </div>\n" "\n" " <div class=\"validator\">\n" " <a title=\"Check the performance this page\"\n" (format " href=\"https://developers.google.com/speed/pagespeed/insights/?url=%s\">pagespeed</a>\n" (org-website-get-url property-list)) " </div>\n" "\n" " <!--\n" " <div class=\"validator\">\n" " <a title=\"Check the accessibility of this page according to U.S. Section 508\"\n" (format " href=\"http://www.contentquality.com/mynewtester/cynthia.exe?Url1=%s\">508</a>\n" (org-website-get-property-element property-list :link-home)) " </div>\n" " -->\n" "\n" " <div class=\"license\">\n" " <span>Last Modified: " (org-website-get-property-element property-list :last-modified) "<br />\n" " " (org-website-get-property-element property-list :copyright) "<br />\n" " <span class=\"license\">Creative Commons\n" " <a title=\"View details of the license of this site\"\n" " href=\"http://creativecommons.org/licenses/by-nc-sa/3.0/\">\n" " Attribution-NonCommercial-ShareAlike\n" " </a> license</span></span>\n" " </div>\n" "\n" " </div>\n" "\n" " <!-- footer end -->\n" "\n"))) " </div>\n" "\n" "</body>\n" "\n" "</html>\n")))
Blog Contents Template
;;------------------------------------------------------------------------------ ;;;; Org Website: Publish HTML: Blog Contents Template ;;------------------------------------------------------------------------------ (init-message 3 "Org Website: Publish HTML: Blog Contents Template") ;; custom blog contents html template ;; INFO reference: http://orgmode.org/worg/dev/org-export-reference.html (defun org-website-html-blog-contents-template (contents info property-list) "Return blog contents string after HTML conversion. CONTENTS is the transcoded contents string. INFO is a plist holding export options. PROPERTY-LIST is the list of org properties found in INFO." ;; if the POSTED property exists and level is 2, then assume current file is a blog post (let ((post (org-website-is-blog-post property-list)) (site-url (org-website-get-property-element property-list :link-home))) (concat ;; menu-index (right blog menu) (with-temp-buffer (insert-file-contents "~/web/sites/blog/site/menu-index.html-nopub") (goto-char (point-min)) (while (re-search-forward "^" nil :noerror) (replace-match " ")) (buffer-string)) "\n" " <!-- content-index start -->\n" "\n" " <div id=\"content-index\">\n" "\n" (if post (concat ;; posted date " <div class=\"timestamp\">" (substring (org-website-get-property-element property-list :posted) 0 10) "</div>\n" ;; description and link headline (concat " <h2><a href=\"" (org-website-get-url property-list) "\">" (org-website-get-property-element property-list :description) "</a></h2>\n")) "") contents (if post (concat "\n" ;; tags " <div class=\"tags\">Tags: " (org-website-get-property-element property-list :tags) "</div>\n" "\n") "") "\n" " </div>\n" "\n" " <!-- content-index end -->\n" "\n")))
Inner Template
;;------------------------------------------------------------------------------ ;;;; Org Website: Publish HTML: Inner Template ;;------------------------------------------------------------------------------ (init-message 3 "Org Website: Publish HTML: Inner Template") ;; custom html inner template (defun org-website-html-inner-template (contents info) "Return body of document string after HTML conversion. CONTENTS is the transcoded contents string. INFO is a plist holding export options." (require 'ox-html) (concat ;; table of contents (let ((depth (plist-get info :with-toc))) (when depth (org-html-toc depth info))) ;; document contents contents ;; footnotes section (org-website-html-footnote-section info)))
Headline
;;------------------------------------------------------------------------------ ;;;; Org Website: Publish HTML: Headline ;;------------------------------------------------------------------------------ (init-message 3 "Org Website: Publish HTML: Headline") ;; custom html headline (defun org-website-html-headline (headline contents info) "Transcode a HEADLINE element from Org to HTML. CONTENTS holds the contents of the headline. INFO is a plist holding contextual information." (let ((level (+ (org-export-get-relative-level headline info) (1- (or (plist-get info :html-toplevel-hlevel) 1)))) (id (org-export-data (org-element-property :CUSTOM_ID headline) info)) (title (org-export-data (org-element-property :title headline) info)) (contents (or contents ""))) (concat (if id (format "\n<h%d id=\"%s\">%s</h%d>\n" level id title level) (format "\n<h%d>%s</h%d>\n" level title level)) contents)))
Section
;;------------------------------------------------------------------------------ ;;;; Org Website: Publish HTML: Section ;;------------------------------------------------------------------------------ (init-message 3 "Org Website: Publish HTML: Section") ;; custom html section (defun org-website-html-section (section contents info) "Transcode a SECTION element from Org to HTML. CONTENTS holds the contents of the section. INFO is a plist holding contextual information." (or contents ""))
Footnote Reference
;;------------------------------------------------------------------------------ ;;;; Org Website: Publish HTML: Footnote Reference ;;------------------------------------------------------------------------------ (init-message 3 "Org Website: Publish HTML: Footnote Reference") (defun org-website-html-footnote-reference (footnote-reference _contents info) "Transcode a FOOTNOTE-REFERENCE element from Org to HTML. CONTENTS is nil. INFO is a plist holding contextual information." (require 'ox-html) (concat ;; insert separator between two footnotes in a row (let ((prev (org-export-get-previous-element footnote-reference info))) (when (eq (org-element-type prev) 'footnote-reference) (plist-get info :html-footnote-separator))) (let* ((n (org-export-get-footnote-number footnote-reference info)) (id (format "fnr.%d%s" n (if (org-export-footnote-first-reference-p footnote-reference info) "" ".100")))) (format (plist-get info :html-footnote-format) (org-html--anchor id n (format " class=\"footnote-reference\" href=\"#fn.%d\"" n) info)))))
Footnote Section
;;------------------------------------------------------------------------------ ;;;; Org Website: Publish HTML: Footnote Section ;;------------------------------------------------------------------------------ (init-message 3 "Org Website: Publish HTML: Footnote Section") ;; custom html footnote section (defun org-website-html-footnote-section (info) "Format the footnote section. INFO is a plist used as a communication channel." (let* ((fn-alist (org-export-collect-footnote-definitions info)) (fn-alist (cl-loop for (n type raw) in fn-alist collect (cons n (if (eq (org-element-type raw) 'org-data) (org-trim (org-export-data raw info)) (format "<p>%s</p>" (org-trim (org-export-data raw info)))))))) (when fn-alist (format "<div class=\"footnotes\">\n%s</div>" (mapconcat (lambda (fn) (let ((n (car fn)) (def (cdr fn))) (format "<div class=\"footnote\">\n%s\n%s\n</div>\n" (format org-html-footnote-format (org-html--anchor (format "fn.%s" n) n (format " class=\"footnote-number\" href=\"#fnr.%s\"" n) info)) def))) fn-alist "\n")))))
Publish RSS
;;------------------------------------------------------------------------------ ;;; Org Website: Publish RSS ;;------------------------------------------------------------------------------ (init-message 2 "Org Website: Publish RSS")
Derived Backend
;;------------------------------------------------------------------------------ ;;;; Org Website: Publish RSS: Derived Backend ;;------------------------------------------------------------------------------ (init-message 3 "Org Website: Publish RSS: Derived Backend") ;; create derived backend with customizations to html backend (org-export-define-derived-backend 'org-website-rss 'html :translate-alist '((template . org-website-rss-template) (inner-template . org-website-rss-inner-template)))
Publish to RSS
;;------------------------------------------------------------------------------ ;;;; Org Website: Publish RSS: Publish to RSS ;;------------------------------------------------------------------------------ (init-message 3 "Org Website: Publish RSS: Publish to RSS") (defun org-website-rss-publish-to-rss (plist file-name pub-dir) "Publish a Website org file to RSS and return output file name. FILE-NAME is the file name of the Org file to be published. PLIST is the property list for the given project. PUB-DIR is the publishing directory." (org-publish-org-to 'org-website-rss file-name ".rss" plist pub-dir))
Template
;;------------------------------------------------------------------------------ ;;;; Org Website: Publish RSS: Template ;;------------------------------------------------------------------------------ (init-message 3 "Org Website: Publish RSS: Template") ;; custom rss template ;; INFO reference: http://orgmode.org/worg/dev/org-export-reference.html (defun org-website-rss-template (contents info) "Return complete document string after RSS conversion. CONTENTS is the transcoded contents string. INFO is a plist holding export options." (let* ((property-list (org-website-get-property-list info)) (link-home (org-website-get-property-element property-list :link-home)) (title (org-website-get-property-element property-list :title))) ;;(message "%S" info) ;;(message "%S" property-list) (concat "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" "<rdf:RDF xmlns:rdf=\"http://www.w3.org/1999/02/22-rdf-syntax-ns#\"\n" " xmlns=\"http://purl.org/rss/1.0/\"\n" " xmlns:slash=\"http://purl.org/rss/1.0/modules/slash/\"\n" " xmlns:taxo=\"http://purl.org/rss/1.0/modules/taxonomy/\"\n" " xmlns:dc=\"http://purl.org/dc/elements/1.1/\"\n" " xmlns:syn=\"http://purl.org/rss/1.0/modules/syndication/\"\n" " xmlns:admin=\"http://webns.net/mvcb/\"\n" " xmlns:feedburner=\"http://rssnamespace.org/feedburner/ext/1.0\">\n\n" " <channel rdf:about=\"" link-home "\">\n" " <title>" title "</title>\n" " <link>" link-home "</link>\n" " <description>" (org-website-get-property-element property-list :description) "</description>\n" " <dc:language>en-us</dc:language>\n" " <dc:rights>" (org-website-get-property-element property-list :copyright) "</dc:rights>\n" " <dc:date>" (format-time-string "%FT%TZ" nil t) "</dc:date>\n" " <dc:publisher>" (org-website-get-property-element property-list :author) "</dc:publisher>\n" " <dc:creator>" (org-website-get-property-element property-list :author) "</dc:creator>\n" " <dc:subject>Software Engineering</dc:subject>\n" " <syn:updatePeriod>daily</syn:updatePeriod>\n" " <syn:updateFrequency>1</syn:updateFrequency>\n" " <syn:updateBase>2007-06-04T00:00:00Z</syn:updateBase>\n" " <items>\n" " <rdf:Seq>\n" ;; (mapconcat ;; (lambda (x) ;; (let ((file (substring (car x) 1)) ;; (date (cadr x)) ;; (desc (caddr x))) ;; (concat " <rdf:li rdf:resource=\"" link-home file ".html\" />"))) ;; indexes "\n") " </rdf:Seq>\n" " </items>\n" " <image rdf:resource=\"" link-home "img/image.jpg\" />\n" " </channel>\n\n" " <image rdf:about=\"" link-home "img/image.jpg\">\n" " <title>" title "</title>\n" " <url>" link-home "img/image.jpg</url>\n" " <link>" link-home "</link>\n" " </image>\n" contents "\n" " <textinput rdf:about=\"" link-home "search.html\">\n" " <title>Search " title "</title>\n" " <description>Search " title " entries</description>\n" " <name>query</name>\n" " <link>" link-home "search.html</link>\n" " </textinput>\n\n" "</rdf:RDF>\n")))
Inner Template
;;------------------------------------------------------------------------------ ;;;; Org Website: Publish RSS: Inner Template ;;------------------------------------------------------------------------------ (init-message 3 "Org Website: Publish RSS: Inner Template") ;; custom rss inner template (defun org-website-rss-inner-template (contents info) "Return body of document string after RSS conversion. CONTENTS is the transcoded contents string. INFO is a plist holding export options." (let ((property-list (org-website-get-property-list info))) (concat ;; table of contents ;; (let ((depth (plist-get info :with-toc))) ;; (when depth (org-html-toc depth info))) ;; document contents "\n" " <item rdf:about=\"" (org-website-get-url property-list) "\">\n" " <title>" (org-website-get-property-element property-list :description) "</title>\n" " <link>" (org-website-get-url property-list) "</link>\n" " <description>\n" " <![CDATA[\n" contents " ]]>\n" " </description>\n" " </item>\n" ;; footnotes section (org-website-html-footnote-section info))))
Publish Gopher
;;------------------------------------------------------------------------------ ;;; Org Website: Publish Gopher ;;------------------------------------------------------------------------------ (init-message 2 "Org Website: Publish Gopher")
Derived Backend
;;------------------------------------------------------------------------------ ;;;; Org Website: Publish Gopher: Derived Backend ;;------------------------------------------------------------------------------ (init-message 3 "Org Website: Publish Gopher: Derived Backend") ;; create derived backend with customizations to ascii backend (org-export-define-derived-backend 'gopher 'ascii ;;:options-alist '((:ascii-text-width nil nil gopher-text-width)) :translate-alist '((template . org-website-gopher-template) (inner-template . org-website-gopher-inner-template) ;;(inner-template . org-ascii-inner-template) (headline . org-website-gopher-headline) (section . org-website-gopher-section))) ;;(link . org-website-gopher-link)))
Publish to Gopher
;;------------------------------------------------------------------------------ ;;;; Org Website: Publish Gopher: Publish to Gopher ;;------------------------------------------------------------------------------ (init-message 3 "Org Website: Publish Gopher: Publish to Gopher") (defun org-website-gopher-publish-to-gopher (plist file-name pub-dir) "Publish a Website org file to Gopher and return output file name. FILE-NAME is the file name of the Org file to be published. PLIST is the property list for the given project. PUB-DIR is the publishing directory." (org-publish-org-to 'gopher file-name ".gopher" plist pub-dir))
Template
;;------------------------------------------------------------------------------ ;;;; Org Website: Publish Gopher: Template ;;------------------------------------------------------------------------------ (init-message 3 "Org Website: Publish Gopher: Template") ;; custom gopher template ;; INFO reference: http://orgmode.org/worg/dev/org-export-reference.html (defun org-website-gopher-template (contents info) "Return complete document string after Gopher conversion. CONTENTS is the transcoded contents string. INFO is a plist holding export options." (let* ((property-list (org-website-get-property-list info)) (site (org-website-get-property-element property-list :site)) (title (org-website-get-property-element property-list :title))) ;;(message "%S" info) ;;(message "%S" property-list) (concat (format "%s\n\n" (org-website-format-headline title)) ;; menu (only display on home page) (if (string= (downcase title) "nullman") (concat (format "%s\n\n" (org-website-format-headline "menu")) (mapconcat (lambda (x) (let* ((plist (cdr x)) (name (plist-get plist :name)) (title (plist-get plist :title)) (selector (plist-get plist :selector))) (format "%s\t%s\t%s\n" gopher-type-submenu title (org-website-get-gopher-selector-hostname-port selector)))) (if (string= site "shermanwest") org-website-shermanwest-menu-list org-website-menu-list) "") "\n") "") ;; main content (cond ((string= site "blog") (org-website-gopher-blog-contents-template contents info property-list)) (t (concat contents "\n"))) ;; footer (cond ((string= site "kylesherman") "") (t (concat (format "%s\n\n" (make-string gopher-text-width ?=)) (format "Last Modified: %s\n" (org-website-get-property-element property-list :last-modified)) (format "%s\n" (org-website-get-property-element property-list :copyright)) (format "%s\t%s\t%s\t%s\n" gopher-type-html-file "Creative Commons Attribution-NonCommercial-ShareAlike license" "http://creativecommons.org/licenses/by-nc-sa/3.0/" gopher-port)))) )))
Inner Template
;;------------------------------------------------------------------------------ ;;;; Org Website: Publish Gopher: Inner Template ;;------------------------------------------------------------------------------ (init-message 3 "Org Website: Publish Gopher: Inner Template") ;; custom gopher inner template (defun org-website-gopher-inner-template (contents info) "Return body of document string after Gopher conversion. CONTENTS is the transcoded contents string. INFO is a plist holding export options." (require 'ox-ascii) (concat ;; ;; table of contents ;; (let ((depth (plist-get info :with-toc))) ;; (when depth ;; (org-ascii--build-toc info depth))) ;; document contents (replace-regexp-in-string "^ " "" contents) ; remove indentation ;; footnotes section (org-website-gopher-footnote-section info)))
Headline
;;------------------------------------------------------------------------------ ;;;; Org Website: Publish Gopher: Headline ;;------------------------------------------------------------------------------ (init-message 3 "Org Website: Publish Gopher: Headline") ;; custom gopher headline (defun org-website-gopher-headline (headline contents info) "Transcode a HEADLINE element from Org to Gopher. CONTENTS holds the contents of the headline. INFO is a plist holding contextual information." (let ((level (+ (org-export-get-relative-level headline info) (1- (or (plist-get info :gopher-toplevel-hlevel) 1)))) (text (org-export-data (org-element-property :title headline) info)) (contents (or contents ""))) (concat (format "\n%s\n" (if (< level 3) (org-website-format-headline text ?= gopher-text-width) (org-website-format-headline text ?- gopher-text-width))) contents)))
Section
;;------------------------------------------------------------------------------ ;;;; Org Website: Publish Gopher: Section ;;------------------------------------------------------------------------------ (init-message 3 "Org Website: Publish Gopher: Section") ;; custom gopher section (defun org-website-gopher-section (section contents info) "Transcode a SECTION element from Org to Gopher. CONTENTS holds the contents of the section. INFO is a plist holding contextual information." (or contents ""))
Footnote Reference
;;------------------------------------------------------------------------------ ;;;; Org Website: Publish Gopher: Footnote Reference ;;------------------------------------------------------------------------------ (init-message 3 "Org Website: Publish Gopher: Footnote Reference") (defun org-website-gopher-footnote-reference (footnote-reference _contents info) "Transcode a FOOTNOTE-REFERENCE element from Org to Gopher. CONTENTS is nil. INFO is a plist holding contextual information." (require 'ox-ascii) (concat ;; insert separator between two footnotes in a row (let ((prev (org-export-get-previous-element footnote-reference info))) (when (eq (org-element-type prev) 'footnote-reference) (plist-get info :ascii-footnote-separator))) (let ((n (org-export-get-footnote-number footnote-reference info))) (format (plist-get info :ascii-footnote-format) (format "%d" n)))))
Footnote Section
;;------------------------------------------------------------------------------ ;;;; Org Website: Publish Gopher: Footnote Section ;;------------------------------------------------------------------------------ (init-message 3 "Org Website: Publish Gopher: Footnote Section") ;; custom gopher footnote section (defun org-website-gopher-footnote-section (info) "Format the footnote section. INFO is a plist used as a communication channel." (let* ((fn-alist (org-export-collect-footnote-definitions info)) (fn-alist (cl-loop for (n type raw) in fn-alist collect (cons n (if (eq (org-element-type raw) 'org-data) (org-trim (org-export-data raw info)) (format "%s" (org-trim (org-export-data raw info)))))))) (when fn-alist (format "%s" (mapconcat (lambda (fn) (let ((n (car fn)) (def (cdr fn))) (format "%s\n%s\n" (format org-ascii-footnote-format (format "%s" n)) def))) fn-alist "\n")))))
Helper Functions
;;------------------------------------------------------------------------------ ;;; Org Website: Helper Functions ;;------------------------------------------------------------------------------ (init-message 2 "Org Website: Helper Functions")
Publish
Publish all or some Org Website projects. Optionally force a full re-publish.
;;------------------------------------------------------------------------------ ;;;; Org Website: Helper Functions: Publish ;;------------------------------------------------------------------------------ (init-message 3 "Org Website: Helper Functions: Publish") (defun org-website-publish (&optional project force) "Publish org-website projects. If PROJECT is non-nil, only publish that project. If FORCE is non-nil, force publish all files in project." (interactive) (let ((files (directory-files "~/web/org/" nil "\.org\\'"))) (when (member "styles.org" files) (setq files (append "styles.org" (remove "styles.org" files)))) (dolist (file files) (let ((site (file-name-sans-extension file))) (when (or (not project) (string= project site)) ;; publish site (org-publish site force)))))) (defun org-website-publish-async (&optional project force) "Asynchronous version of `org-website-publish'." (interactive) (eval `(async-spinner (lambda () (load "~/web/bin/init-emacs-website.el") (org-website-publish ,project ,force)) (lambda (result) (message "Website publish finished")))))
Tangle Publish
Tangle and publish all or some Org Website projects. Optionally force a full re-publish.
;;------------------------------------------------------------------------------ ;;;; Org Website: Helper Functions: Tangle Publish ;;------------------------------------------------------------------------------ (init-message 3 "Org Website: Helper Functions: Tangle Publish") (defun org-website-tangle-publish (&optional project force) "Tangle and publish org-website projects. If PROJECT is non-nil, only tangle/publish that project. If FORCE is non-nil, force publish all files in project." (interactive) (let ((files (directory-files "~/web/org/" nil "\.org\\'")) (org-html-htmlize-output-type 'css)) (when (member "styles.org" files) (setq files (append "styles.org" (remove "styles.org" files)))) (dolist (file files) (let ((site (file-name-sans-extension file))) (when (or (not project) (string= project site)) ;; tangle site file (org-babel-tangle-file (concat "~/web/org/" file)) ;; publish site (org-publish site force)))))) (defun org-website-tangle-publish-async (&optional project force) "Asynchronous version of `org-website-tangle-publish'." (interactive) (eval `(async-spinner (lambda () (load "~/web/bin/init-emacs-website.el") (org-website-tangle-publish ,project ,force)) (lambda (result) (message "Website tangle/publish finished")))))
Tangle Publish Asynchronously
;; ;;------------------------------------------------------------------------------ ;; ;;;; Org Website: Helper Functions: Tangle Publish Asynchronously ;; ;;------------------------------------------------------------------------------ ;; (init-message 3 "Org Website: Helper Functions: Tangle Publish Asynchronously") ;; (defun org-website-tangle-publish-async (&optional project force) ;; "Tangle and publish org-website projects asynchronously. ;; \nIf PROJECT is non-nil, only tangle/publish that project. ;; If FORCE is non-nil, force publish all files in project." ;; (interactive) ;; (message (concat "~/web/bin/website-tangle-publish" ;; (if project (concat " --site " project) "") ;; (if force " --force" ""))) ;; ;; (let ((args (cl-remove-if #'null ;; ;; (append ;; ;; (when project (append '("--site") (list project))) ;; ;; (when force '("--force")))))) ;; (eval ;; `(async-spinner ;; (lambda () ;; (shell-command ;; (concat "~/web/bin/website-tangle-publish" ;; (if ,project (concat " --site " ,project) "") ;; (if ,force " --force" "")))) ;; (lambda (result) ;; (message "Website tangle/publish finished"))))) ;; ;; (eval `(start-process ;; ;; "org-website-tangle-publish-async-process-name" ;; ;; "*org-website-tangle-publish-async*" ;; ;; "~/web/bin/website-tangle-publish" ;; ;; ,@args)))))
Blog Post Create
;;------------------------------------------------------------------------------ ;;;; Org Website: Helper Functions: Blog Post Create ;;------------------------------------------------------------------------------ (init-message 3 "Org Website: Helper Functions: Blog Post Create") (defun org-website-blog-post-create (&optional title) "Create empty blog post entry with TITLE. If TITLE is nil, caller is prompted for one." (interactive "sTitle: ") (save-match-data (setq title (titleize title)) (find-file "~/web/org/blog.org") (goto-char (point-min)) (re-search-forward "^\*\*\* Blog Posts$") (org-forward-heading-same-level 1 t) (forward-line -1) (newline) (let* ((ts (current-time)) (time (format-time-string "%Y.%m.%d.%H%M" ts)) (name (concat time "-" (org-generate-custom-id-from-title title))) (path (format-time-string "%Y/%m" ts)) (file (concat "~/web/sites/blog/site/" path "/" name ".org")) (posted (format-time-string "%Y-%m-%d %H:%M" ts))) (insert (concat "******* " time " " title "\n" " :PROPERTIES:\n" " :CUSTOM_ID: site-blog-posts-" time "\n" " :END:\n" "\n" "#+NAME: blog-" time "\n" "#+BEGIN_SRC org :tangle " file "\n" " <<level-2>>\n" " ,#+TITLE: " title "\n" " ,#+DESCRIPTION: \n" " ,#+POSTED: " posted "\n" " ,#+LAST_MODIFIED: " posted "\n" " ,#+UUID: " (uuid) "\n" " ,#+TAGS: \n" "\n" " ,#+ATTR_HTML: :class blog-img :title " title "\n" " [[][<<site-url>>/" path "/img/]]\n" "\n" "\n" "\n" " ,#+BEGIN_QUOTE\n" " ,#+END_QUOTE\n" "#+END_SRC\n")) (forward-line -14) (goto-char (line-end-position)))))
Blog Post Update Posted
;;------------------------------------------------------------------------------ ;;;; Org Website: Helper Functions: Blog Post Update Posted ;;------------------------------------------------------------------------------ (init-message 3 "Org Website: Helper Functions: Blog Post Update Posted") (defun org-website-blog-post-update-posted (&optional date) "Update posted time of current blog post entry. Set blog timestamp to `current-time' or DATE, if non-nil." (interactive) (when (string= (expand-file-name "~/web/org/blog.org") buffer-file-name) (save-mark-and-excursion (save-match-data (let* ((case-fold-search t) (start (progn (org-previous-visible-heading 1) (point))) (end (progn (org-next-visible-heading 1) (point))) (title (progn (goto-char start) (re-search-forward "#\\+TITLE: \\(.*\\)" end) (match-string 1))) (ts (if date (date-to-time date) (current-time))) (time (format-time-string "%Y.%m.%d.%H%M" ts)) (name (concat time "-" (org-generate-custom-id-from-title title))) (path (format-time-string "%Y/%m" ts)) (file (concat "~/web/sites/blog/site/" path "/" name ".org")) (posted (format-time-string "%Y-%m-%d %H:%M" ts))) (goto-char start) ;; heading (re-search-forward "^\*+ \\(.*\\)" (line-end-position)) (replace-match (concat time " " title) nil nil nil 1) ;; custom_id (re-search-forward "^[ \t]*:CUSTOM_ID: site-blog-posts-\\(.*\\)" end) (replace-match time nil nil nil 1) ;; name (re-search-forward "^[ \t]*#\\+NAME: blog-\\(.*\\)" end) (replace-match time nil nil nil 1) ;; file (re-search-forward "^[ \t]*#\\+BEGIN_SRC org :tangle \\(.*\\)" end) (let ((old-file (match-string 1))) (when (file-exists-p old-file) (delete-file old-file))) (replace-match file nil nil nil 1) ;; posted (re-search-forward "^[ \t]*#\\+POSTED: \\(.*\\)" end) (replace-match posted nil nil nil 1) ;; last_modified (re-search-forward "^[ \t]*#\\+LAST_MODIFIED: \\(.*\\)" end) (replace-match posted nil nil nil 1))))))
Unflatten
Un-flatten a list into a tree.
Author: http://emacs.stackexchange.com/users/2462/bburns-km Source: http://emacs.stackexchange.com/a/18914
;;------------------------------------------------------------------------------ ;;;; Org Website: Helper Functions: Unflatten ;;------------------------------------------------------------------------------ (init-message 3 "Org Website: Helper Functions: Unflatten") (defun unflatten (xs &optional fn-value fn-level) "Unflatten a list XS into a tree, e.g. (1 2 3 1) => (1 (2 (3)) 1). FN-VALUE specifies how to extract the values from each element, which are included in the output tree, FN-LEVEL tells how to extract the level of each element. By default these are the `identity' function so it will work on a list of numbers." (let* ((level 1) (tree (cons nil nil)) (start tree) (stack nil) (fn-value (or fn-value #'identity)) (fn-level (or fn-level #'identity))) (dolist (x xs) (let ((x-value (funcall fn-value x)) (x-level (funcall fn-level x))) (cond ((> x-level level) (setcdr tree (cons (cons x-value nil) nil)) (setq tree (cdr tree)) (push tree stack) (setq tree (car tree)) (setq level x-level)) ((= x-level level) (setcdr tree (cons x-value nil)) (setq tree (cdr tree))) ((< x-level level) (while (< x-level level) (setq tree (pop stack)) (setq level (- level 1))) (setcdr tree (cons x-value nil)) (setq tree (cdr tree)) (setq level x-level))))) (cdr start)))
Generate Website Emacs Initialization File
Generate minimal version of init-emacs.el
called init-emacs-website.el
to
be used with batch commands.
;;------------------------------------------------------------------------------ ;;; Org Website: Generate Website Emacs Initialization File ;;------------------------------------------------------------------------------ (init-message 2 "Org Website: Generate Website Emacs Initialization File") (defun org-website-generate-website-emacs-initialization-file () "Generate minimal version of init-emacs.el called init-emacs-website.el to be used with batch commands." (save-mark-and-excursion (save-match-data (let ((source-file (expand-file-name "init-emacs.el" emacs-home-dir)) (target-file (expand-file-name "init-emacs-website.el" "~/web/bin")) (sections (append '(;;";;; Package Manager: Quelpa" ";;; Package Manager: Straight" ";; set emacs home directory" ";;;; Environment: Files: General" ";;;; Org Mode: Functions: org-get-file-data" ";;;; Org Mode: Babel: Configuration" ";;;; Org Mode: Babel: Tangle Update Timestamps" ";;;; Org Mode: Babel: Tangle Case-Sensitive" ";;;; Functions: Emacs Functions: delete-line" ";;; Packages: htmlize" ";;; Packages: w3m") (let ((start (progn (goto-char (point-min)) (re-search-forward "^[ \t]*:CUSTOM_ID: org-website$"))) (end (re-search-forward "^[ \t]*:CUSTOM_ID: org-website-generate-website-emacs-initialization-file$")) list) (goto-char start) (while (re-search-forward "^[ \t]*\\(;;;; .*\\)$" end :noerror) (push (match-string-no-properties 1) list)) (nreverse list)))) (prefix (concat "(require 'cl-macs)\n" "(require 'subr-x)\n" "(require 'org)\n" "(require 'ox)\n"))) (org-copy-tangled-sections source-file target-file sections prefix))))) (defun after-save-hook--generate-init-emacs-website-elisp-file () "Hook to generate init-emacs-website.el file on save." (when (and buffer-file-name (string= (file-truename buffer-file-name) init-emacs-true-file-name)) (org-website-generate-website-emacs-initialization-file))) (add-hook 'after-save-hook #'after-save-hook--generate-init-emacs-website-elisp-file :append)
Tangle and Publish Script
Shell script to asynchronously run org-website-tangle-publish
. This process
can be started by running org-website-tangle-publish-async
.
# -*- mode: shell-script -*- #=============================================================================== # website-tangle-publish # # Org-Website Tangle and Publish Sites # # Parameters; # # -h | --help - Output usage help # -s | --site - Limit the scope to just one site # -f | --force - Force a full tangle/publish (not incremental) # # Author: Kyle W T Sherman # # init-emacs.org => website-tangle-publish #=============================================================================== set -eu site="" force="nil" while [[ $# != 0 ]] ; do arg="$1" shift if [ "${arg}" == "-s" ] || [ "${arg}" == "--site" ] ; then site="$1" shift elif [ "${arg}" == "-f" ] || [ "${arg}" == "--force" ] ; then force="t" else echo "$0 usage:" echo " -h | --help - Output usage help" echo " -s | --site - Limit the scope to just one site" echo " -f | --force - Forces a full tangle/publish (not incremental)" exit 1 fi done cmd="(org-website-tangle-publish (if (> (length \"${site}\") 0) \"${site}\" nil) ${force})" echo "Running command: ${cmd}" emacs --no-init-file --batch --load=${HOME}/web/bin/init-emacs-website.el --eval="${cmd}" 2>&1 #=============================================================================== # End of File #===============================================================================
Remote Synchronization
;;------------------------------------------------------------------------------ ;;; Org Website: Remote Synchronization ;;------------------------------------------------------------------------------ (init-message 2 "Org Website: Remote Synchronization")
Rsync to localhost
;; ;;------------------------------------------------------------------------------ ;; ;;;; Org Website: Remote Synchronization: Rsync to localhost ;; ;;------------------------------------------------------------------------------ ;; (init-message 3 "Org Website: Remote Synchronization: Rsync to localhost") ;; (defun org-website-rsync-to-localhost (&optional property-list) ;; "Synchronize published site with localhost server." ;; (interactive) ;; (shell-command (concat "rsync -rlptx --delete --force" ;; " --exclude=\".git*\"" ;; " \"${HOME}/public_html/sites/\"" ;; " \"/srv/http/sites/\""))) ;; (defun org-website-rsync-to-localhost-async (&optional property-list) ;; "Asynchronous version of `org-website-rsync-to-localhost'." ;; (interactive) ;; (eval ;; `(async-spinner ;; (lambda () ;; (fset 'org-website-rsync-to-localhost ,(symbol-function 'org-website-rsync-to-localhost)) ;; (org-website-rsync-to-localhost ,property-list)) ;; (lambda (result) ;; (message "Website rsync to localhost finished")))))
Rsync to Morpheus
;;------------------------------------------------------------------------------ ;;;; Org Website: Remote Synchronization: Rsync to Morpheus ;;------------------------------------------------------------------------------ (init-message 3 "Org Website: Remote Synchronization: Rsync to Morpheus") (defun org-website-rsync-to-morpheus (&optional property-list) "Synchronize published site with morpheus server." (interactive) (shell-command (concat "rsync -rlptx --delete --force" " --exclude=\".git*\"" " \"${HOME}/public_html/\"" " \"morpheus:${HOME}/public_html/\"")) (shell-command (concat "rsync -rlptx --delete --force" " --exclude=\".git*\"" " \"${HOME}/public_gopher/\"" " \"morpheus:${HOME}/public_gopher/\"")) (shell-command (concat "rsync -rlptx --delete --force" " --exclude=\".git*\"" " \"${HOME}/public_gemini/\"" " \"morpheus:${HOME}/public_gemini/\""))) (defun org-website-rsync-to-morpheus-async (&optional property-list) "Asynchronous version of `org-website-rsync-to-morpheus'." (interactive) (eval `(async-spinner (lambda () (fset 'org-website-rsync-to-morpheus ,(symbol-function 'org-website-rsync-to-morpheus)) (org-website-rsync-to-morpheus ,property-list)) (lambda (result) (message "Website rsync to morpheus finished")))))
Rsync to localhost and Morpheus
;; ;;------------------------------------------------------------------------------ ;; ;;;; Org Website: Remote Synchronization: Rsync to localhost and Morpheus ;; ;;------------------------------------------------------------------------------ ;; (init-message 3 "Org Website: Remote Synchronization: Rsync to localhost and Morpheus") ;; (defun org-website-rsync-to-localhost-morpheus (&optional property-list) ;; "Synchronize published site with localhost and morpheus servers." ;; (interactive) ;; (org-website-rsync-to-localhost property-list) ;; (org-website-rsync-to-morpheus property-list))
Rsync to DigitalOcean
;;------------------------------------------------------------------------------ ;;;; Org Website: Remote Synchronization: Rsync to DigitalOcean ;;------------------------------------------------------------------------------ (init-message 3 "Org Website: Remote Synchronization: Rsync to DigitalOcean") (defun org-website-rsync-to-digitalocean (&optional application force) "Synchronize published site with digitalocean server. Normally, applications are not synced. If APPLICATION is non-nil, sync it instead. Supported applications: \"powerhouse\" \"bloodmoon\" If FORCE is non-nil, do not prompt before synchronizing applicaitons." (interactive) (let ((digitalocean "159.203.165.79")) (if application (when (or force (yes-or-no-p (format "Website rsync %s to DigitalOcean" application))) (shell-command (concat "rsync -rlptx --delete --force" " --exclude=\".git*\"" " --rsh=\"ssh -l kyle\"" " \"${HOME}/public_html/sites/nullware/" application "/\"" " \"" digitalocean ":/home/kyle/public_html/sites/nullware/" application "/\""))) (progn (shell-command (concat "rsync -rlptx --delete --force" " --exclude=\".git*\"" " --exclude=\"nullware/powerhouse/*\"" " --exclude=\"nullware/bloodmoon/*\"" " --rsh=\"ssh -l kyle\"" " \"${HOME}/public_html/sites/\"" " \"" digitalocean ":/home/kyle/public_html/sites/\"")) (shell-command (concat "rsync -rlptx --delete --force" " --exclude=\".git*\"" " --rsh=\"ssh -l kyle\"" " \"${HOME}/public_gopher/\"" " \"" digitalocean ":/home/kyle/public_gopher/\"")) (shell-command (concat "rsync -rlptx --delete --force" " --exclude=\".git*\"" " --rsh=\"ssh -l kyle\"" " \"${HOME}/public_gemini/\"" " \"" digitalocean ":/home/kyle/public_gemini/\"")))))) (defun org-website-rsync-to-digitalocean-async (&optional application force) "Asynchronous version of `org-website-rsync-to-digitalocean'." (interactive) (when (or (not application) force (yes-or-no-p (format "Website rsync %s to DigitalOcean" application))) (eval `(async-spinner (lambda () (fset 'org-website-rsync-to-digitalocean ,(symbol-function 'org-website-rsync-to-digitalocean)) (org-website-rsync-to-digitalocean ,application ,force)) (lambda (result) (message "Website rsync to DigitalOcean finished"))))))
Deployment
;;------------------------------------------------------------------------------ ;;; Org Website: Deployment ;;------------------------------------------------------------------------------ (init-message 2 "Org Website: Deployment")
Generate Docker Container
# # -*- mode: shell-script -*- # #=============================================================================== # # website-generate-docker-container # # # # Org-Website Generate Docker Container # # # # Author: Kyle W T Sherman # # # # init-emacs.org => website-generate-docker-container # #=============================================================================== # set -eu # tmpdir=/tmp/website #$$ # webdir=/usr/local/apache2/htdocs # conf=httpd.conf # mkdir -p ${tmpdir} # #=============================================================================== # # Generate httpd.conf # #=============================================================================== # cat << 'EOF' > ${tmpdir}/${conf} # # # # ServerRoot: The top of the directory tree under which the server's # # configuration, error, and log files are kept. # # # # Do not add a slash at the end of the directory path. If you point # # ServerRoot at a non-local disk, be sure to specify a local disk on the # # Mutex directive, if file-based mutexes are used. If you wish to share the # # same ServerRoot for multiple httpd daemons, you will need to change at # # least PidFile. # # # ServerRoot "/usr/local/apache2" # # # # Mutex: Allows you to set the mutex mechanism and mutex file directory # # for individual mutexes, or change the global defaults # # # # Uncomment and change the directory if mutexes are file-based and the default # # mutex file directory is not on a local disk or is not appropriate for some # # other reason. # # # # Mutex default:/run/httpd # # # # Listen: Allows you to bind Apache to specific IP addresses and/or # # ports, instead of the default. See also the <VirtualHost> # # directive. # # # # Change this to Listen on specific IP addresses as shown below to # # prevent Apache from glomming onto all bound IP addresses. # # # #Listen 12.34.56.78:80 # Listen 80 # # # # Dynamic Shared Object (DSO) Support # # # # To be able to use the functionality of a module which was built as a DSO you # # have to place corresponding `LoadModule' lines at this location so the # # directives contained in it are actually available _before_ they are used. # # Statically compiled modules (those listed by `httpd -l') do not need # # to be loaded here. # # # # Example: # # LoadModule foo_module modules/mod_foo.so # # # LoadModule mpm_event_module modules/mod_mpm_event.so # #LoadModule mpm_prefork_module modules/mod_mpm_prefork.so # #LoadModule mpm_worker_module modules/mod_mpm_worker.so # LoadModule authn_file_module modules/mod_authn_file.so # #LoadModule authn_dbm_module modules/mod_authn_dbm.so # #LoadModule authn_anon_module modules/mod_authn_anon.so # #LoadModule authn_dbd_module modules/mod_authn_dbd.so # #LoadModule authn_socache_module modules/mod_authn_socache.so # LoadModule authn_core_module modules/mod_authn_core.so # LoadModule authz_host_module modules/mod_authz_host.so # LoadModule authz_groupfile_module modules/mod_authz_groupfile.so # LoadModule authz_user_module modules/mod_authz_user.so # #LoadModule authz_dbm_module modules/mod_authz_dbm.so # #LoadModule authz_owner_module modules/mod_authz_owner.so # #LoadModule authz_dbd_module modules/mod_authz_dbd.so # LoadModule authz_core_module modules/mod_authz_core.so # #LoadModule authnz_ldap_module modules/mod_authnz_ldap.so # #LoadModule authnz_fcgi_module modules/mod_authnz_fcgi.so # LoadModule access_compat_module modules/mod_access_compat.so # LoadModule auth_basic_module modules/mod_auth_basic.so # #LoadModule auth_form_module modules/mod_auth_form.so # #LoadModule auth_digest_module modules/mod_auth_digest.so # #LoadModule allowmethods_module modules/mod_allowmethods.so # #LoadModule file_cache_module modules/mod_file_cache.so # #LoadModule cache_module modules/mod_cache.so # #LoadModule cache_disk_module modules/mod_cache_disk.so # #LoadModule cache_socache_module modules/mod_cache_socache.so # #LoadModule socache_shmcb_module modules/mod_socache_shmcb.so # #LoadModule socache_dbm_module modules/mod_socache_dbm.so # #LoadModule socache_memcache_module modules/mod_socache_memcache.so # #LoadModule socache_redis_module modules/mod_socache_redis.so # #LoadModule watchdog_module modules/mod_watchdog.so # #LoadModule macro_module modules/mod_macro.so # #LoadModule dbd_module modules/mod_dbd.so # #LoadModule dumpio_module modules/mod_dumpio.so # #LoadModule echo_module modules/mod_echo.so # #LoadModule buffer_module modules/mod_buffer.so # #LoadModule data_module modules/mod_data.so # #LoadModule ratelimit_module modules/mod_ratelimit.so # LoadModule reqtimeout_module modules/mod_reqtimeout.so # #LoadModule ext_filter_module modules/mod_ext_filter.so # #LoadModule request_module modules/mod_request.so # LoadModule include_module modules/mod_include.so # LoadModule filter_module modules/mod_filter.so # #LoadModule reflector_module modules/mod_reflector.so # #LoadModule substitute_module modules/mod_substitute.so # #LoadModule sed_module modules/mod_sed.so # #LoadModule charset_lite_module modules/mod_charset_lite.so # #LoadModule deflate_module modules/mod_deflate.so # #LoadModule xml2enc_module modules/mod_xml2enc.so # #LoadModule proxy_html_module modules/mod_proxy_html.so # #LoadModule brotli_module modules/mod_brotli.so # LoadModule mime_module modules/mod_mime.so # #LoadModule ldap_module modules/mod_ldap.so # LoadModule log_config_module modules/mod_log_config.so # #LoadModule log_debug_module modules/mod_log_debug.so # #LoadModule log_forensic_module modules/mod_log_forensic.so # #LoadModule logio_module modules/mod_logio.so # #LoadModule lua_module modules/mod_lua.so # LoadModule env_module modules/mod_env.so # #LoadModule mime_magic_module modules/mod_mime_magic.so # #LoadModule cern_meta_module modules/mod_cern_meta.so # LoadModule expires_module modules/mod_expires.so # LoadModule headers_module modules/mod_headers.so # #LoadModule ident_module modules/mod_ident.so # #LoadModule usertrack_module modules/mod_usertrack.so # #LoadModule unique_id_module modules/mod_unique_id.so # LoadModule setenvif_module modules/mod_setenvif.so # LoadModule version_module modules/mod_version.so # #LoadModule remoteip_module modules/mod_remoteip.so # LoadModule proxy_module modules/mod_proxy.so # #LoadModule proxy_connect_module modules/mod_proxy_connect.so # #LoadModule proxy_ftp_module modules/mod_proxy_ftp.so # LoadModule proxy_http_module modules/mod_proxy_http.so # #LoadModule proxy_fcgi_module modules/mod_proxy_fcgi.so # #LoadModule proxy_scgi_module modules/mod_proxy_scgi.so # #LoadModule proxy_uwsgi_module modules/mod_proxy_uwsgi.so # #LoadModule proxy_fdpass_module modules/mod_proxy_fdpass.so # #LoadModule proxy_wstunnel_module modules/mod_proxy_wstunnel.so # #LoadModule proxy_ajp_module modules/mod_proxy_ajp.so # #LoadModule proxy_balancer_module modules/mod_proxy_balancer.so # #LoadModule proxy_express_module modules/mod_proxy_express.so # #LoadModule proxy_hcheck_module modules/mod_proxy_hcheck.so # #LoadModule session_module modules/mod_session.so # #LoadModule session_cookie_module modules/mod_session_cookie.so # #LoadModule session_crypto_module modules/mod_session_crypto.so # #LoadModule session_dbd_module modules/mod_session_dbd.so # LoadModule slotmem_shm_module modules/mod_slotmem_shm.so # #LoadModule slotmem_plain_module modules/mod_slotmem_plain.so # #LoadModule ssl_module modules/mod_ssl.so # #LoadModule dialup_module modules/mod_dialup.so # #LoadModule http2_module modules/mod_http2.so # #LoadModule proxy_http2_module modules/mod_proxy_http2.so # #LoadModule md_module modules/mod_md.so # #LoadModule lbmethod_byrequests_module modules/mod_lbmethod_byrequests.so # #LoadModule lbmethod_bytraffic_module modules/mod_lbmethod_bytraffic.so # #LoadModule lbmethod_bybusyness_module modules/mod_lbmethod_bybusyness.so # #LoadModule lbmethod_heartbeat_module modules/mod_lbmethod_heartbeat.so # LoadModule unixd_module modules/mod_unixd.so # #LoadModule heartbeat_module modules/mod_heartbeat.so # #LoadModule heartmonitor_module modules/mod_heartmonitor.so # #LoadModule dav_module modules/mod_dav.so # LoadModule status_module modules/mod_status.so # LoadModule autoindex_module modules/mod_autoindex.so # #LoadModule asis_module modules/mod_asis.so # #LoadModule info_module modules/mod_info.so # #LoadModule suexec_module modules/mod_suexec.so # <IfModule !mpm_prefork_module> # #LoadModule cgid_module modules/mod_cgid.so # </IfModule> # <IfModule mpm_prefork_module> # #LoadModule cgi_module modules/mod_cgi.so # </IfModule> # #LoadModule dav_fs_module modules/mod_dav_fs.so # #LoadModule dav_lock_module modules/mod_dav_lock.so # #LoadModule vhost_alias_module modules/mod_vhost_alias.so # LoadModule negotiation_module modules/mod_negotiation.so # LoadModule dir_module modules/mod_dir.so # #LoadModule imagemap_module modules/mod_imagemap.so # #LoadModule actions_module modules/mod_actions.so # #LoadModule speling_module modules/mod_speling.so # LoadModule userdir_module modules/mod_userdir.so # LoadModule alias_module modules/mod_alias.so # #LoadModule rewrite_module modules/mod_rewrite.so # # # # If you wish httpd to run as a different user or group, you must run # # httpd as root initially and it will switch. # # # # User/Group: The name (or #number) of the user/group to run httpd as. # # It is usually good practice to create a dedicated user and group for # # running httpd, as with most system services. # # # <IfModule unixd_module> # User www-data # Group www-data # </IfModule> # # 'Main' server configuration # # # # The directives in this section set up the values used by the 'main' # # server, which responds to any requests that aren't handled by a # # <VirtualHost> definition. These values also provide defaults for # # any <VirtualHost> containers you may define later in the file. # # # # All of these directives may appear inside <VirtualHost> containers, # # in which case these default settings will be overridden for the # # virtual host being defined. # # # # # # ServerAdmin: Your address, where problems with the server should be # # e-mailed. This address appears on some server-generated pages, such # # as error documents. e.g. admin@your-domain.com # # # ServerAdmin kylewsherman@gmail.com # # # # ServerName gives the name and port that the server uses to identify itself. # # This can often be determined automatically, but we recommend you specify # # it explicitly to prevent problems during startup. # # # # If your host doesn't have a registered DNS name, enter its IP address here. # # # ServerName nullware.com:80 # # # # Deny access to the entirety of your server's filesystem. You must # # explicitly permit access to web content directories in other # # <Directory> blocks below. # # # <Directory /> # AllowOverride none # Require all denied # </Directory> # # # # Note that from this point forward you must specifically allow # # particular features to be enabled - so if something's not working as # # you might expect, make sure that you have specifically enabled it # # below. # # # # # # DocumentRoot: The directory out of which you will serve your # # documents. By default, all requests are taken from this directory, but # # symbolic links and aliases may be used to point to other locations. # # # DocumentRoot "/usr/local/apache2/htdocs" # <Directory "/usr/local/apache2/htdocs" # # # # Possible values for the Options directive are "None", "All", # # or any combination of: # # Indexes Includes FollowSymLinks SymLinksifOwnerMatch ExecCGI MultiViews # # # # Note that "MultiViews" must be named *explicitly* --- "Options All" # # doesn't give it to you. # # # # The Options directive is both complicated and important. Please see # # http://httpd.apache.org/docs/2.4/mod/core.html#options # # for more information. # # # Options Indexes FollowSymLinks # # # # AllowOverride controls what directives may be placed in .htaccess files. # # It can be "All", "None", or any combination of the keywords: # # AllowOverride FileInfo AuthConfig Limit # # # AllowOverride None # # # # Controls who can get stuff from this server. # # # Require all granted # </Directory> # # # # DirectoryIndex: sets the file that Apache will serve if a directory # # is requested. # # # <IfModule dir_module> # DirectoryIndex index.html # </IfModule> # # # # The following lines prevent .htaccess and .htpasswd files from being # # viewed by Web clients. # # # <Files ".ht*"> # Require all denied # </Files> # # # # ErrorLog: The location of the error log file. # # If you do not specify an ErrorLog directive within a <VirtualHost> # # container, error messages relating to that virtual host will be # # logged here. If you *do* define an error logfile for a <VirtualHost> # # container, that host's errors will be logged there and not here. # # # ErrorLog "/usr/local/apache2/logs/error_log" # # # # LogLevel: Control the number of messages logged to the error_log. # # Possible values include: debug, info, notice, warn, error, crit, # # alert, emerg. # # # LogLevel warn # <IfModule log_config_module> # # # # The following directives define some format nicknames for use with # # a CustomLog directive (see below). # # # LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" combined # LogFormat "%h %l %u %t \"%r\" %>s %b" common # <IfModule logio_module> # # You need to enable mod_logio.c to use %I and %O # LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\" %I %O" combinedio # </IfModule> # # # # The location and format of the access logfile (Common Logfile Format). # # If you do not define any access logfiles within a <VirtualHost> # # container, they will be logged here. Contrariwise, if you *do* # # define per-<VirtualHost> access logfiles, transactions will be # # logged therein and *not* in this file. # # # CustomLog "/usr/local/apache2/logs/access_log" common # # # # If you prefer a logfile with access, agent, and referer information # # (Combined Logfile Format) you can use the following directive. # # # #CustomLog "/usr/local/apache2/logs/access_log" combined # </IfModule> # <IfModule alias_module> # # # # Redirect: Allows you to tell clients about documents that used to # # exist in your server's namespace, but do not anymore. The client # # will make a new request for the document at its new location. # # Example: # # Redirect permanent /foo http://www.example.com/bar # # # # Alias: Maps web paths into filesystem paths and is used to # # access content that does not live under the DocumentRoot. # # Example: # # Alias /webpath /full/filesystem/path # # # # If you include a trailing / on /webpath then the server will # # require it to be present in the URL. You will also likely # # need to provide a <Directory> section to allow access to # # the filesystem path. # # # # ScriptAlias: This controls which directories contain server scripts. # # ScriptAliases are essentially the same as Aliases, except that # # documents in the target directory are treated as applications and # # run by the server when requested rather than as documents sent to the # # client. The same rules about trailing "/" apply to ScriptAlias # # directives as to Alias. # # # ScriptAlias /cgi-bin/ "/usr/local/apache2/cgi-bin/" # </IfModule> # <IfModule cgid_module> # # # # ScriptSock: On threaded servers, designate the path to the UNIX # # socket used to communicate with the CGI daemon of mod_cgid. # # # #Scriptsock cgisock # </IfModule> # # # # "/srv/http/cgi-bin" should be changed to whatever your ScriptAliased # # CGI directory exists, if you have that configured. # # # <Directory "/usr/local/apache2/cgi-bin"> # AllowOverride None # Options None # Require all granted # </Directory> # <IfModule headers_module> # # # # Avoid passing HTTP_PROXY environment to CGI's on this or any proxied # # backend servers which have lingering "httpoxy" defects. # # 'Proxy' request header is undefined by the IETF, not listed by IANA # # # RequestHeader unset Proxy early # </IfModule> # <IfModule mime_module> # # # # TypesConfig points to the file containing the list of mappings from # # filename extension to MIME-type. # # # TypesConfig conf/mime.types # # # # AddType allows you to add to or override the MIME configuration # # file specified in TypesConfig for specific file types. # # # #AddType application/x-gzip .tgz # # # # AddEncoding allows you to have certain browsers uncompress # # information on the fly. Note: Not all browsers support this. # # # #AddEncoding x-compress .Z # #AddEncoding x-gzip .gz .tgz # # # # If the AddEncoding directives above are commented-out, then you # # probably should define those extensions to indicate media types: # # # AddType application/x-compress .Z # AddType application/x-gzip .gz .tgz # # # # AddHandler allows you to map certain file extensions to "handlers": # # actions unrelated to filetype. These can be either built into the server # # or added with the Action directive (see below) # # # # To use CGI scripts outside of ScriptAliased directories: # # (You will also need to add "ExecCGI" to the "Options" directive.) # # # #AddHandler cgi-script .cgi # # For type maps (negotiated resources): # #AddHandler type-map var # # # # Filters allow you to process content before it is sent to the client. # # # # To parse .shtml files for server-side includes (SSI): # # (You will also need to add "Includes" to the "Options" directive.) # # # #AddType text/html .shtml # #AddOutputFilter INCLUDES .shtml # </IfModule> # # # # The mod_mime_magic module allows the server to use various hints from the # # contents of the file itself to determine its type. The MIMEMagicFile # # directive tells the module where the hint definitions are located. # # # #MIMEMagicFile conf/magic # # # # Customizable error responses come in three flavors: # # 1) plain text 2) local redirects 3) external redirects # # # # Some examples: # #ErrorDocument 500 "The server made a boo boo." # #ErrorDocument 404 /missing.html # #ErrorDocument 404 "/cgi-bin/missing_handler.pl" # #ErrorDocument 402 http://www.example.com/subscription_info.html # # # # # # MaxRanges: Maximum number of Ranges in a request before # # returning the entire resource, or one of the special # # values 'default', 'none' or 'unlimited'. # # Default setting is to accept 200 Ranges. # #MaxRanges unlimited # # # # EnableMMAP and EnableSendfile: On systems that support it, # # memory-mapping or the sendfile syscall may be used to deliver # # files. This usually improves server performance, but must # # be turned off when serving from networked-mounted # # filesystems or if support for these functions is otherwise # # broken on your system. # # Defaults: EnableMMAP On, EnableSendfile Off # # # #EnableMMAP off # #EnableSendfile on # # Supplemental configuration # # # # The configuration files in the conf/extra/ directory can be # # included to add extra features or to modify the default configuration of # # the server, or you may simply copy their contents here and change as # # necessary. # # Server-pool management (MPM specific) # Include conf/extra/httpd-mpm.conf # # Multi-language error messages # Include conf/extra/httpd-multilang-errordoc.conf # # Fancy directory listings # Include conf/extra/httpd-autoindex.conf # # Language settings # Include conf/extra/httpd-languages.conf # # User home directories # Include conf/extra/httpd-userdir.conf # # Real-time info on requests and configuration # #Include conf/extra/httpd-info.conf # # Virtual hosts # #Include conf/extra/httpd-vhosts.conf # # Local access to the Apache HTTP Server Manual # #Include conf/extra/httpd-manual.conf # # Distributed authoring and versioning (WebDAV) # #Include conf/extra/httpd-dav.conf # # Various default settings # Include conf/extra/httpd-default.conf # # Configure mod_proxy_html to understand HTML4/XHTML1 # <IfModule proxy_html_module> # Include conf/extra/proxy-html.conf # </IfModule> # # Secure (SSL/TLS) connections # #Include conf/extra/httpd-ssl.conf # # # # Note: The following must must be present to support # # starting without SSL on platforms with no /dev/random equivalent # # but a statically compiled-in mod_ssl. # # # <IfModule ssl_module> # SSLRandomSeed startup builtin # SSLRandomSeed connect builtin # </IfModule> # #============================================================================= # # module: expires # # enable the directives - assuming they're not enabled globally # ExpiresActive on # # send an expires header for each of these mimetypes (as defined by server) # # ico|pdf|flv|jpg|jpeg|png|gif|js|css|swf # ExpiresByType image/png "access plus 1 month" # ExpiresByType image/gif "access plus 1 month" # ExpiresByType image/jpg "access plus 1 month" # ExpiresByType image/jpeg "access plus 1 month" # ExpiresByType image/flv "access plus 1 month" # ExpiresByType image/swf "access plus 1 month" # ExpiresByType image/pdf "access plus 1 month" # ExpiresByType text/css "access plus 1 day" # ExpiresByType text/js "access plus 1 day" # # special mine type for icons (http://www.iana.org/assignments/media-types/image/vnd.microsoft.icon) # AddType image/vnd.microsoft.icon .ico # ExpiresByType image/vnd.microsoft.icon "access plus 3 months" # #============================================================================= # # site: athruz # <VirtualHost *> # ServerName athruz.com # ServerAlias athruz.com *.athruz.com # ServerAdmin webmaster@nullware.com # # ProxyPass / http://localhost/sites/athruz/ # # ProxyPassReverse / http://localhost/sites/athruz/ # </VirtualHost> # <VirtualHost *> # ServerName athruz.org # ServerAlias athruz.org *.athruz.org # ServerAdmin webmaster@nullware.com # Redirect permanent / http://athruz.com/ # </VirtualHost> # # # site: barland # # <VirtualHost *> # # ServerName barland.net # # ServerAlias barland.net *.barland.net # # ServerAdmin webmaster@nullware.com # # ProxyPass / http://barland.net/ # # ProxyPassReverse / http://barland.net/ # # </VirtualHost> # # # site: colleenbarland # # <VirtualHost *> # # ServerName colleenbarland.com # # ServerAlias colleenbarland.com *.colleenbarland.com # # ServerAdmin webmaster@nullware.com # # ProxyPass / http://colleenbarland.com/ # # ProxyPassReverse / http://colleenbarland.com/ # # </VirtualHost> # # # site: colleensherman # # <VirtualHost *> # # ServerName colleensherman.com # # ServerAlias colleensherman.com *.colleensherman.com colleensherman.org *.colleensherman.org colleensherman.net *.colleensherman.net # # ServerAdmin webmaster@nullware.com # # ProxyPass / http://colleensherman.com/ # # ProxyPassReverse / http://colleensherman.com/ # # </VirtualHost> # # # site: dowat # # <VirtualHost *> # # ServerName dowat.com # # ServerAlias dowat.com *.dowat.com dowat.org *.dowat.org dowat.net *.dowat.net # # ServerAdmin webmaster@nullware.com # # ProxyPass / http://dowat.com/ # # ProxyPassReverse / http://dowat.com/ # # </VirtualHost> # # # site: keehn # # <VirtualHost *> # # ServerName keehn.net # # ServerAlias keehn.net *.keehn.net # # ServerAdmin webmaster@nullware.com # # ProxyPass / http://keehn.net/ # # ProxyPassReverse / http://keehn.net/ # # </VirtualHost> # # site: kylesherman # <VirtualHost *> # ServerName kylesherman.net # ServerAlias kylesherman.net *.kylesherman.net # ServerAdmin webmaster@nullware.net # ProxyPass / http://localhost/sites/kylesherman/ # ProxyPassReverse / http://localhost/sites/kylesherman/ # </VirtualHost> # <VirtualHost *> # ServerName kylesherman.com # ServerAlias kylesherman.com *.kylesherman.com # ServerAdmin webmaster@nullware.com # Redirect permanent / http://kylesherman.net/ # </VirtualHost> # <VirtualHost *> # ServerName kylesherman.org # ServerAlias kylesherman.org *.kylesherman.org # ServerAdmin webmaster@nullware.com # Redirect permanent / http://kylesherman.net/ # </VirtualHost> # # # site: nulldigital # # <VirtualHost *> # # ServerName nulldigital.com # # ServerAlias nulldigital.com *.nulldigital.com # # ServerAdmin webmaster@nullware.com # # # ProxyPass / http://nulldigital.com00/ # # # ProxyPassReverse / http://nulldigital.com00/ # # ProxyPass / http://192.168.0.41/ # # ProxyPassReverse / http://192.168.0.41/ # # </VirtualHost> # # site: nulldot # <VirtualHost *> # ServerName nulldot.net # ServerAlias nulldot.net *.nulldot.net # ServerAdmin webmaster@nullware.com # ProxyPass / http://localhost/sites/nulldot/ # ProxyPassReverse / http://localhost/sites/nulldot/ # # ProxyPass / http://nulldot.com:81/ # # ProxyPassReverse / http://nulldot.com:81/ # </VirtualHost> # <VirtualHost *> # ServerName nulldot.com # ServerAlias nulldot.com *.nulldot.com # ServerAdmin webmaster@nullware.com # Redirect permanent / http://nulldot.net/ # </VirtualHost> # <VirtualHost *> # ServerName nulldot.org # ServerAlias nulldot.org *.nulldot.org # ServerAdmin webmaster@nullware.com # Redirect permanent / http://nulldot.net/ # </VirtualHost> # # site: nullman # #<VirtualHost *> # # ServerName nullman.com # # ServerAlias nullman.com *.nullman.com # # ServerAlias nullman.net *.nullman.net # # ServerAlias nullman.org *.nullman.org # # ServerAdmin webmaster@nullware.com # # # # ProxyPass / http://localhost/~kyle/ # # ProxyPassReverse / http://localhost/~kyle/ # # # ## ProxyPass /media http://localhost/media # ## ProxyPassReverse /media http://localhost/media # ## ProxyPass /mp3 http://localhost/mp3 # ## ProxyPassReverse /mp3 http://localhost/mp3 # ## ProxyPass /netjuke http://localhost/netjuke # ## ProxyPassReverse