visual.el 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402
  1. ;;; visual.el --- Visual settings: fonts, themes, mode-line, … -*- lexical-binding: t -*-
  2. ;; Copyright © 2012–2018 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. ;;; Frame specific settings
  17. (defun al/frame-visual-actions (&optional frame)
  18. "Perform some visual actions specific to a FRAME type."
  19. (when (and (display-graphic-p)
  20. (require 'al-font nil t))
  21. (set-frame-font (al/first-existing-font) nil t)
  22. ;; Should be "solved": 武; 🐼, 😻, ⚽, 💩, ∵, ⸪ (symbola);
  23. ;; ࿌ (unifont); 🃜, 🜒, 🝖 (quivira).
  24. (al/set-fontset
  25. "fontset-default" nil nil
  26. '(("Symbola"
  27. (#x2020 . #x24ff)
  28. (#x2600 . #x27ff)
  29. (#x2900 . #x29ff)
  30. (#x2e00 . #x2e42)
  31. (#x1d300 . #x1d371)
  32. (#x1d400 . #x1d7ff)
  33. (#x1f000 . #x1f1ff)
  34. (#x1f300 . #x1f9ff))
  35. ("Ubuntu Mono"
  36. (?² . ?³)
  37. (?¼ . ?¾)
  38. (#x2070 . #x208f))
  39. ("Quivira" nil)))))
  40. (al/add-hook-maybe
  41. '(after-make-frame-functions window-setup-hook)
  42. 'al/frame-visual-actions)
  43. ;;; Global keys
  44. (al/bind-keys
  45. :prefix-map al/visual-map
  46. :prefix-docstring "Map for visual stuff."
  47. :prefix "M-V"
  48. ("T" . tool-bar-mode)
  49. ("M" . menu-bar-mode)
  50. ("S" . scroll-bar-mode)
  51. ("I" . tooltip-mode)
  52. ("r" . rainbow-mode)
  53. ("t" . al/load-theme)
  54. ("C" . make-color)
  55. ("c" . make-color-switch-to-buffer)
  56. ("l" (al/load-theme 'alect-light))
  57. ("M-l" (al/load-theme 'alect-light-alt))
  58. ("d" (al/load-theme 'alect-dark))
  59. ("M-d" (al/load-theme 'alect-dark-alt))
  60. ("b" (al/load-theme 'alect-black))
  61. ("M-b" (al/load-theme 'alect-black-alt))
  62. ("h" . hl-line-mode)
  63. ("w" . whitespace-mode)
  64. ("W" . global-whitespace-mode)
  65. ("M-W" (setq show-trailing-whitespace
  66. (not show-trailing-whitespace)))
  67. ("f" . al/face-to-kill-ring)
  68. ("F" . facemenu-set-foreground)
  69. ("B" . facemenu-set-background)
  70. ("M-F" . make-color-foreground-color-to-kill-ring)
  71. ("M-B" . make-color-background-color-to-kill-ring))
  72. ;;; Themes
  73. (with-eval-after-load 'custom
  74. (setq custom-safe-themes t)
  75. ;; Fix bug <http://debbugs.gnu.org/cgi/bugreport.cgi?bug=16266>.
  76. (defun al/fix-custom-variables-bug (fun &rest args)
  77. "Allow setting undefined variables in themes."
  78. (let (custom--inhibit-theme-enable)
  79. (apply fun args)))
  80. (advice-add 'custom-theme-set-variables
  81. :around #'al/fix-custom-variables-bug))
  82. (with-eval-after-load 'alect-themes
  83. (setq
  84. alect-display-class '((class color) (min-colors 256))
  85. alect-overriding-faces
  86. '((hl-line ((((type graphic)) :background bg)
  87. (t :background unspecified))))))
  88. (al/eval-after-init
  89. (and (require 'alect-themes nil t)
  90. (require 'al-color nil t)
  91. ;; Load the dark theme if it is less than 1 hour before the
  92. ;; sunset, and the light theme otherwise.
  93. (al/load-theme
  94. (if (and (require 'al-calendar nil t)
  95. (< (float-time
  96. (time-subtract (al/solar-time 'sunset)
  97. (current-time)))
  98. 3600))
  99. 'alect-dark
  100. 'alect-light))))
  101. ;;; Mode line
  102. (defface al/mode-name
  103. '((((background light)) :foreground "#028902")
  104. (((background dark)) :foreground "yellow"))
  105. "Face for `mode-name' displayed in the mode line.")
  106. ;; To have a server name of the running server in the mode-line, I use
  107. ;; an auxiliary variable `al/server-running?', because calling of
  108. ;; `server-running-p' in the mode-line construct eats CPU. Idea of
  109. ;; right-aligning from
  110. ;; <http://lists.gnu.org/archive/html/help-gnu-emacs/2013-12/msg00191.html>
  111. (defvar al/mode-server
  112. '(al/server-running?
  113. (:eval (list (propertize " " 'display
  114. `(space :align-to (- right ,(length server-name))))
  115. server-name)))
  116. "Mode line construct for displaying `server-name' if server is running.")
  117. (put 'al/mode-server 'risky-local-variable t)
  118. (when (require 'dim nil t)
  119. (dim-major-names
  120. '((emacs-lisp-mode "EL")
  121. (elisp-byte-code-mode "EL-byte")
  122. (lisp-interaction-mode "ELi")
  123. (inferior-emacs-lisp-mode "EL>")
  124. (lisp-mode "CL")
  125. (slime-repl-mode "CL>")
  126. (scheme-mode "λ")
  127. (geiser-repl-mode "λ>")
  128. (geiser-doc-mode "λ🄷")
  129. (python-mode "Py")
  130. (inferior-python-mode "Py>")
  131. (js-mode "JS")
  132. (sh-mode "Sh")
  133. (shell-mode "Sh>")
  134. (eshell-mode "ESh>")
  135. (dired-mode "🗀")
  136. (wdired-mode "🗁")
  137. (Info-mode "🄸")
  138. (help-mode "🄷")
  139. (doc-view-mode "Doc")
  140. (pdf-view-mode "pdf-View")
  141. (pdf-outline-buffer-mode "pdf🖹")
  142. (sql-interactive-mode "SQL>")
  143. (ibuffer-mode "IB")
  144. (message-mode "🖂")
  145. (erc-view-log-mode "ERC🄻")
  146. (erc-list-menu-mode "ERC🗋")
  147. (calc-mode "=")
  148. (debugger-mode "🔨")
  149. (snippet-mode "🗍")
  150. (diary-mode "🕮")
  151. (ediff-mode "ε")
  152. (xref--xref-buffer-mode "xref")
  153. (gnus-server-mode "𝗚Srv")
  154. (gnus-browse-mode "𝗚Srv🗋")
  155. (gnus-group-mode "𝗚Gr")
  156. (gnus-summary-mode "𝗚Sum")
  157. (gnus-article-mode "𝗚Art")
  158. (guix-package-info-mode "γ🄷pkg")
  159. (guix-generation-info-mode "γ🄷gen")
  160. (guix-package-list-mode "γ🗋pkg")
  161. (guix-output-list-mode "γ🗋out")
  162. (guix-generation-list-mode "γ🗋gen")
  163. (guix-profile-list-mode "γ🗋prof")
  164. (guix-build-log-mode "γ🄻")
  165. (magit-status-mode "µStatus")
  166. (magit-process-mode "µProc")
  167. (magit-log-mode "µ🄻")
  168. (magit-log-select-mode "µ🄻Select")
  169. (magit-reflog-mode "µReflog")
  170. (magit-refs-mode "µRefs")
  171. (magit-diff-mode "µDiff")
  172. (magit-revision-mode "µRevision")
  173. (magit-cherry-mode "µCherry")
  174. (magit-stash-mode "µStash")
  175. (magit-stashes-mode "µStashes")
  176. (magit-popup-mode "µPopup")
  177. (magit-popup-sequence-mode "µPopupSeq")
  178. (git-rebase-mode "git-Rebase")
  179. (gitconfig-mode "git-Config")
  180. (gitignore-mode "git-Ignore")
  181. (gitattributes-mode "git-Attributes")
  182. (calendar-mode "📆")
  183. (w3m-form-input-select-mode "w3m🗹")
  184. (package-menu-mode "Pkg🗋")
  185. (emms-playlist-mode "🎝")
  186. (emms-stream-mode "🎝 Streams")
  187. (sauron-mode "👁")))
  188. (dim-minor-names
  189. '((visual-line-mode " ↩")
  190. (auto-fill-function " ↵")
  191. (isearch-mode " 🔎")
  192. (whitespace-mode " _" whitespace)
  193. (indent-guide-mode " ¦" indent-guide)
  194. (rainbow-mode " 🖌" rainbow-mode)
  195. (abbrev-mode " Ab" abbrev)
  196. (company-mode " ⍈" company)
  197. (yas-minor-mode " ⮞" yasnippet)
  198. (paredit-mode " PE" paredit)
  199. (view-mode " 👀" view)
  200. (eldoc-mode "" eldoc)
  201. (edebug-mode " 🔧" edebug)
  202. (counsel-mode "" counsel)
  203. (gnus-topic-mode " T" gnus-topic)
  204. (gnus-dired-mode " 𝗚" gnus-dired)
  205. (guix-build-log-minor-mode " γ🄻" guix-build-log)
  206. (guix-devel-mode " γ" guix-devel)
  207. (magit-blame-mode " µBlame" magit-blame)
  208. (erc-notifications-mode " 🗩" erc-desktop-notifications)
  209. (al/emms-notification-mode " 🎧" al/emms)
  210. (flyspell-mode " fly" flyspell))))
  211. (setq-default
  212. mode-line-format
  213. `("%e" mode-line-front-space
  214. mode-line-mule-info mode-line-client mode-line-modified mode-line-remote
  215. " " mode-line-buffer-identification " " mode-line-position
  216. " %l,%c"
  217. (vc-mode vc-mode)
  218. " " mode-line-modes mode-line-misc-info
  219. al/mode-server
  220. mode-line-end-spaces)
  221. mode-line-buffer-identification
  222. (propertized-buffer-identification "%b")
  223. mode-line-mule-info
  224. `(""
  225. (current-input-method
  226. (:propertize
  227. current-input-method-title
  228. help-echo (concat ,(purecopy "Input method: ")
  229. current-input-method
  230. ,(purecopy
  231. (concat "\n" "mouse-2: Disable input method\n"
  232. "mouse-3: Describe input method")))
  233. local-map ,mode-line-input-method-map
  234. face font-lock-warning-face
  235. mouse-face mode-line-highlight))
  236. ,(propertize
  237. "%z"
  238. 'help-echo 'mode-line-mule-info-help-echo
  239. 'mouse-face 'mode-line-highlight
  240. 'local-map mode-line-coding-system-map)
  241. (:eval (mode-line-eol-desc))))
  242. (setq
  243. mode-line-position
  244. `((-3 ,(propertize "%P" 'face 'font-lock-builtin-face)))
  245. mode-line-modes
  246. (let ((recursive-edit-help-echo "Recursive edit")
  247. (mode-help-echo (concat "Mode actions:\n"
  248. "mouse-1: Show menu\n"
  249. "mouse-2: Show help\n"
  250. "mouse-3: Minor modes")))
  251. (list '(:eval
  252. (let ((proc (get-buffer-process (current-buffer))))
  253. (propertize
  254. (if proc (symbol-name (process-status proc)) "–")
  255. 'face 'font-lock-constant-face)))
  256. " "
  257. (propertize "%["
  258. 'help-echo recursive-edit-help-echo
  259. 'face 'font-lock-warning-face)
  260. "│"
  261. `(:propertize mode-name
  262. help-echo ,mode-help-echo
  263. face al/mode-name
  264. mouse-face mode-line-highlight
  265. local-map ,mode-line-major-mode-keymap)
  266. '(al/mode-info
  267. ("("
  268. (:propertize al/mode-info face font-lock-comment-face)
  269. ")"))
  270. `(:propertize minor-mode-alist
  271. mouse-face mode-line-highlight
  272. help-echo ,mode-help-echo
  273. local-map ,mode-line-minor-mode-keymap)
  274. '(:eval
  275. (if (buffer-narrowed-p)
  276. (propertize " ↕"
  277. 'help-echo "mouse-1: Remove narrowing"
  278. 'mouse-face 'mode-line-highlight
  279. 'local-map (make-mode-line-mouse-map 'mouse-1 #'mode-line-widen))
  280. ""))
  281. "│"
  282. (propertize "%]"
  283. 'help-echo recursive-edit-help-echo
  284. 'face 'font-lock-warning-face))))
  285. ;;; Misc settings and packages
  286. (setq-default
  287. indicate-buffer-boundaries 'left
  288. visual-line-fringe-indicators '(nil vertical-bar)
  289. indicate-empty-lines t
  290. font-lock-extra-managed-props '(composition))
  291. (setq jit-lock-defer-time 0.1)
  292. ;; Make page breaks look fancier than the default "^L".
  293. ;; Idea from <http://www.jurta.org/en/emacs/dotemacs>.
  294. (or standard-display-table
  295. (setq standard-display-table (make-display-table)))
  296. (aset standard-display-table ?\^L
  297. (let ((line (make-vector 30 ?—)))
  298. (vconcat line " page break " line)))
  299. (column-number-mode)
  300. (blink-cursor-mode 0)
  301. (tool-bar-mode 0)
  302. (menu-bar-mode 0)
  303. ;; (mouse-avoidance-mode 'banish)
  304. (setq tooltip-delay 0.2)
  305. (setq scroll-bar-mode 'right)
  306. (scroll-bar-mode 0)
  307. (with-eval-after-load 'whitespace
  308. (setq
  309. whitespace-line-column 78
  310. whitespace-display-mappings
  311. `((space-mark ?\s [?·])
  312. (space-mark ?  [?○])
  313. ;; (newline-mark ?\n [?↵ ?\n])
  314. (newline-mark ?\^L ,(aref standard-display-table ?\^L))
  315. (tab-mark ?\t [?⇉ ?\t]))
  316. whitespace-style
  317. '(face spaces tabs trailing lines space-before-tab newline
  318. indentation space-after-tab tab-mark newline-mark)))
  319. (with-eval-after-load 'ruler-mode
  320. (setq ruler-mode-show-tab-stops t))
  321. (setq show-paren-delay 0.1)
  322. (with-eval-after-load 'paren
  323. (setq show-paren-when-point-inside-paren t
  324. show-paren-when-point-in-periphery t))
  325. (al/add-after-init-hook 'show-paren-mode)
  326. (with-eval-after-load 'indent-guide
  327. (setq
  328. indent-guide-delay 0.3
  329. indent-guide-char "¦")
  330. ;; https://github.com/zk-phi/indent-guide/issues/29
  331. (defun al/indent-guide-post-command-hook ()
  332. (if (null indent-guide-delay)
  333. (indent-guide-show)
  334. (run-with-idle-timer indent-guide-delay nil
  335. #'indent-guide-show)))
  336. (advice-add 'indent-guide-post-command-hook
  337. :override 'al/indent-guide-post-command-hook))
  338. (with-eval-after-load 'make-color
  339. (al/add-hook-maybe 'make-color-mode-hook 'al/bar-cursor-type))
  340. (with-eval-after-load 'rainbow-mode
  341. (setq rainbow-x-colors t)
  342. (advice-add 'rainbow-mode :after #'al/refontify))
  343. (setq hl-todo-keyword-faces
  344. (mapcar (lambda (word)
  345. (cons word 'hl-todo))
  346. '("TODO" "FIXME" "XXX" "WARNING" "ERROR"))
  347. hl-todo-keywords
  348. `(((lambda (_)
  349. (let (case-fold-search)
  350. (re-search-forward hl-todo-regexp nil t)))
  351. (1 (hl-todo-get-face) t t))))
  352. ;;; visual.el ends here