file-modes.el 9.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305
  1. ;;; file-modes.el --- Modes for various file types -*- lexical-binding: t -*-
  2. ;; Copyright © 2014–2019 Alex Kost
  3. ;; This program is free software; you can redistribute it and/or modify
  4. ;; it under the terms of the GNU General Public License as published by
  5. ;; the Free Software Foundation, either version 3 of the License, or
  6. ;; (at your option) any later version.
  7. ;;
  8. ;; This program is distributed in the hope that it will be useful,
  9. ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. ;; GNU General Public License for more details.
  12. ;;
  13. ;; You should have received a copy of the GNU General Public License
  14. ;; along with this program. If not, see <http://www.gnu.org/licenses/>.
  15. (require 'al-key)
  16. ;;; Org
  17. (al/bind-keys
  18. :prefix-map al/org-map
  19. :prefix-docstring "Map for org mode."
  20. :prefix "M-r"
  21. ("M-r" . org-insert-link)
  22. ("l" . org-store-link)
  23. ("M-l" . org-store-link)
  24. ("M-b" . org-mark-ring-goto)
  25. ("c" . org-capture)
  26. ("a" . org-agenda)
  27. ("b" . org-iswitchb)
  28. ("i" . org-toggle-inline-images)
  29. ("e" . org-export)
  30. ("TAB" . org-indent-mode))
  31. (al/autoload "org"
  32. org-read-date
  33. org-open-file)
  34. (setq org-export-backends
  35. '(ascii html icalendar latex odt texinfo man))
  36. (with-eval-after-load 'org
  37. (require 'org-emms nil t)
  38. (when (require 'al-org nil t)
  39. (advice-add 'org-make-link-string
  40. :around #'al/org-set-link-description))
  41. (setq
  42. org-imenu-depth 6
  43. org-completion-use-ido t
  44. org-confirm-elisp-link-function nil
  45. org-src-fontify-natively t
  46. org-return-follows-link t
  47. org-startup-folded "showall"
  48. org-tags-column -54
  49. org-directory al/notes-dir
  50. org-default-notes-file (al/notes-dir-file "notes.org")
  51. org-url-hexify-p nil
  52. org-link-escape-chars '(?\[ ?\] ?\; ?\= ?\+)
  53. org-ellipsis " […]"
  54. org-file-apps
  55. `(("\\.mm\\'" . default)
  56. ("\\.x?html?\\'" . al/choose-browser)
  57. (,(al/file-regexp "jpg" "png" "gif") . "sxiv %s")
  58. ("\\.pdf\\'" . "zathura %s")
  59. ("\\.djvu\\'" . "zathura %s")
  60. ("\\.pdf::\\([0-9]+\\)\\'" . "zathura --page %1 %s")
  61. ("\\.djvu::\\([0-9]+\\)\\'" . "zathura --page %1 %s")
  62. (auto-mode . emacs)))
  63. (setq
  64. org-use-speed-commands t
  65. org-speed-commands-user
  66. '(("." . (org-speed-move-safe 'outline-previous-visible-heading))
  67. ("e" . (org-speed-move-safe 'outline-next-visible-heading))
  68. (">" . (org-speed-move-safe 'org-backward-heading-same-level))
  69. ("E" . (org-speed-move-safe 'org-forward-heading-same-level))
  70. ("n" . org-narrow-to-subtree)))
  71. (defconst al/org-keys
  72. '("<C-tab>"
  73. ("<M-tab>" . pcomplete)
  74. ("<M-return>" . org-meta-return)
  75. ("M->" . outline-previous-visible-heading)
  76. ("M-E" . outline-next-visible-heading)
  77. ("M-O" . org-backward-sentence)
  78. ("M-U" . org-forward-sentence)
  79. ("<C-kp-enter>" . al/org-table-next-column)
  80. ("<M-kp-enter>" . al/org-table-kill-rows-recalculate)
  81. ("<C-M-kp-enter>" . al/org-table-next-table)
  82. ("C-c e" . org-export-dispatch)
  83. ("C-c M-x" . org-copy-special)
  84. ("C-c C-t" . org-cut-special)
  85. ("C-c C-y" . org-paste-special))
  86. "Alist of auxiliary keys for `org-mode-map'.")
  87. (al/bind-keys-from-vars 'org-mode-map 'al/org-keys)
  88. (when (require 'al-minibuffer nil t)
  89. (advice-add 'org-set-tags :around #'al/complete-default))
  90. (org-add-link-type "pdfview" 'org-pdfview-open 'org-pdfview-export))
  91. (defun al/autoload-org-protocol (fun files &rest args)
  92. "Load `org-protocol' if needed.
  93. `org' is huge and loading it during emacs start is wasteful, but
  94. it is needed to use `org-protocol', isn't it? Not necessarily:
  95. this function makes it possible to avoid requiring `org-protocol'
  96. \(thus the whole `org') in the emacs config file.
  97. Making this function an 'after' advice for `server-visit-files',
  98. will do the right thing."
  99. (if (and (null (featurep 'org-protocol))
  100. (cl-find-if (lambda (spec)
  101. ;; SPEC is (FILENAME . FILEPOS).
  102. (string-match "org-protocol:/" (car spec)))
  103. files))
  104. (if (require 'org-protocol nil t)
  105. ;; `server-visit-files' can't be called as is here, because
  106. ;; `org-protocol' has just been loaded and the protocol advice
  107. ;; is not active yet, so call `server-visit-files' outside
  108. ;; this body.
  109. (apply #'run-with-idle-timer .1 nil
  110. #'server-visit-files files args)
  111. (message "`org-protocol' has not been loaded!"))
  112. (apply fun files args)))
  113. (advice-add 'server-visit-files :around #'al/autoload-org-protocol)
  114. (with-eval-after-load 'org-src
  115. (al/bind-keys
  116. :map org-src-mode-map
  117. ("C-c C-c" . org-edit-src-exit))
  118. (push '("shell" . shell-script) org-src-lang-modes))
  119. (with-eval-after-load 'org-capture
  120. (setq org-capture-templates
  121. '(("n" "notes" entry (file org-default-notes-file)
  122. "* %T\n %?\n"))))
  123. (with-eval-after-load 'org-agenda
  124. (al/bind-keys
  125. :map org-agenda-mode-map
  126. ("." . org-agenda-previous-line)
  127. ("e" . org-agenda-next-line)))
  128. (with-eval-after-load 'org-emms
  129. (setq org-emms-delay 2
  130. org-emms-time-format "%m:%.2s")
  131. (when (require 'al-emms-mpv nil t)
  132. (defun al/org-emms-sync-time (&rest _)
  133. ;; This is asynchronous, so we need to wait.
  134. (al/emms-mpv-sync-playing-time)
  135. (sleep-for 1))
  136. (advice-add 'org-emms-make-link :before #'al/org-emms-sync-time)))
  137. (al/autoload "org-pdfview"
  138. org-pdfview-open
  139. org-pdfview-export)
  140. ;;; Pdf tools
  141. (setq pdf-tools-handle-upgrades nil)
  142. (al/autoload "pdf-view" pdf-view-mode)
  143. (with-eval-after-load 'pdf-view
  144. (al/bind-keys
  145. :map pdf-view-mode-map
  146. ("h" . pdf-view-previous-page-command))
  147. (add-hook 'pdf-view-mode-hook 'pdf-tools-enable-minor-modes)
  148. (require 'org-pdfview nil t))
  149. (with-eval-after-load 'pdf-outline
  150. (al/clean-map 'pdf-outline-minor-mode-map)
  151. (al/bind-keys
  152. :map pdf-outline-minor-mode-map
  153. ("c" . pdf-outline))
  154. (defconst al/pdf-outline-buffer-keys
  155. '(("TAB" . outline-cycle)
  156. ("c" . pdf-outline-select-pdf-window)
  157. ("u" . pdf-outline-follow-link)
  158. ("d" . pdf-outline-display-link)
  159. ("q" . quit-window))
  160. "Alist of auxiliary keys for `pdf-outline-buffer-mode-map'.")
  161. (al/bind-keys-from-vars 'pdf-outline-buffer-mode-map
  162. '(al/lazy-moving-keys
  163. al/lazy-scrolling-keys
  164. al/pdf-outline-buffer-keys))
  165. (add-hook 'pdf-outline-buffer-mode-hook 'hl-line-mode))
  166. (with-eval-after-load 'pdf-links
  167. (setq pdf-links-convert-pointsize-scale 0.02)
  168. (al/clean-map 'pdf-links-minor-mode-map)
  169. (al/bind-keys
  170. :map pdf-links-minor-mode-map
  171. ("u" . pdf-links-action-perform)
  172. ("U" . pdf-links-isearch-link)))
  173. (with-eval-after-load 'pdf-history
  174. (al/clean-map 'pdf-history-minor-mode-map)
  175. (al/bind-keys
  176. :map pdf-history-minor-mode-map
  177. ("," . pdf-history-backward)
  178. ("p" . pdf-history-forward)))
  179. (with-eval-after-load 'pdf-misc
  180. (al/clean-map 'pdf-misc-minor-mode-map)
  181. (al/bind-keys
  182. :map pdf-misc-minor-mode-map
  183. ("f" . pdf-misc-display-metadata)
  184. ("F" . pdf-misc-display-metadata)))
  185. ;;; Misc settings and packages
  186. ;; `normal-mode' should always be called with t argument, otherwise
  187. ;; it simply ignores the value of `enable-local-variables' and sets
  188. ;; it to t.
  189. (defun al/fix-normal-mode (&rest _)
  190. (list t))
  191. (advice-add 'normal-mode :filter-args #'al/fix-normal-mode)
  192. (when (require 'al-file nil t)
  193. (al/add-to-auto-mode-alist
  194. '((sh-mode "/etc/profile\\'"
  195. "bashrc\\'")
  196. (conf-xdefaults-mode "\\.Xmodmap\\'")
  197. (conf-space-mode "\\.mailmap\\'")
  198. (conf-unix-mode "\\.rules\\'"
  199. "\\.hwdb\\'"
  200. "\\.cnf\\'"
  201. "\\.map\\'"
  202. "\\.inc\\'"
  203. "\\.service\\'"
  204. "\\.target\\'"
  205. "\\.socket\\'"
  206. "\\.timer\\'"
  207. "\\.mount\\'")
  208. (conf-unix-mode (".*rc\\'"
  209. "/etc/.*\\'")
  210. t)
  211. (syslog-mode "/var/log.*\\'" t)
  212. (pdf-view-mode "\\.[pP][dD][fF]\\'")
  213. (markdown-mode "\\.mdown\\'")
  214. (pkgbuild-mode "PKGBUILD\\'")
  215. (java-mode ".*tmwa-server-data/world/map/npc/.*txt\\'")
  216. (gtypist-mode "\\.typ\\'")
  217. (gnuplot-mode "\\.plot\\'")
  218. (maxima-mode "\\.max\\'"))))
  219. (with-eval-after-load 'conf-mode
  220. (al/add-hook-maybe 'conf-mode-hook 'hl-line-mode))
  221. (with-eval-after-load 'image-mode
  222. (defconst al/image-keys
  223. '(("C-a" . image-bol)
  224. ("<ctrl-i>" . image-eol)
  225. ("h" . image-previous-file)
  226. ("H" . image-previous-frame)
  227. ("N" . image-next-frame))
  228. "Alist of auxiliary keys for `image-mode-map'.")
  229. (al/bind-keys-from-vars 'image-mode-map 'al/image-keys))
  230. (with-eval-after-load 'doc-view
  231. (setq doc-view-cache-directory "~/.cache/docview")
  232. (push "-r200" doc-view-ghostscript-options) ; picture resolution
  233. )
  234. (with-eval-after-load 'markdown-mode
  235. (defconst al/markdown-keys
  236. '(("M->" . markdown-previous-link)
  237. ("M-E" . markdown-next-link))
  238. "Alist of auxiliary keys for `markdown-mode-map'.")
  239. (al/bind-keys-from-vars 'markdown-mode-map 'al/markdown-keys))
  240. (with-eval-after-load 'tar-mode
  241. (setq tar-mode-show-date t)
  242. (defun al/tar-time-string (time)
  243. (format-time-string " %d-%b-%Y" time))
  244. (advice-add 'tar-clip-time-string :override 'al/tar-time-string)
  245. (al/bind-keys
  246. :map tar-mode-map
  247. ("." . tar-previous-line)
  248. ("e" . tar-next-line)
  249. ("u" . tar-extract))
  250. (add-hook 'tar-mode-hook 'hl-line-mode))
  251. (with-eval-after-load 'nxml-mode
  252. (defconst al/nxml-keys
  253. '(("C-M-." . nxml-backward-up-element)
  254. ("C-M-e" . nxml-down-element)
  255. ("C-M-o" . nxml-backward-element)
  256. ("C-M-u" . nxml-forward-element))
  257. "Alist of auxiliary keys for `nxml-mode-map'.")
  258. (al/bind-keys-from-vars 'nxml-mode-map 'al/nxml-keys)
  259. (add-hook 'nxml-mode-hook
  260. (lambda () (rng-validate-mode 0))))
  261. ;;; file-modes.el ends here