main.el 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379
  1. ;;; Main options
  2. (require 'functions)
  3. ;;; Minimal UI. Run early to hide it as soon as possible.
  4. (setq inhibit-startup-screen t)
  5. (menu-bar-mode -1)
  6. ;;; `tool-bar-mode' and `scroll-bar-mode' might not be compiled in.
  7. (when (fboundp 'tool-bar-mode) (tool-bar-mode -1))
  8. (when (fboundp 'scroll-bar-mode) (scroll-bar-mode -1))
  9. ;;; In some cases, Emacs can still decide by itself to use graphical boxes.
  10. ;;; Force on using the minibuffer instead.
  11. (setq use-dialog-box nil)
  12. ;;; Timeout before echoing the prefix of an unfinished keystroke.
  13. (setq echo-keystrokes 0.5)
  14. ;;; Remember last cursor position.
  15. (save-place-mode)
  16. ;;; When the daemon is killed abruptly, places are not saved. Adding this hook
  17. ;;; allows to save places at a strategic moment.
  18. (add-hook 'before-save-hook 'save-place-kill-emacs-hook)
  19. ;;; Recent files.
  20. (setq recentf-max-saved-items 40)
  21. ;;; Save M-: history.
  22. (savehist-mode)
  23. ;;; Disable autosave features.
  24. (setq auto-save-default nil)
  25. (setq auto-save-list-file-prefix nil)
  26. ;;; Place backup files in specific directory.
  27. (setq backup-directory-alist
  28. `(("." . ,(expand-file-name "backups" user-emacs-directory))))
  29. ;;; Default mode
  30. (setq-default major-mode 'text-mode)
  31. ;;; Disable suspend key since it is useless on Emacs server.
  32. (global-unset-key (kbd "C-z"))
  33. (global-unset-key (kbd "C-x C-z"))
  34. ;;; Make questions less annoying.
  35. (defalias 'yes-or-no-p 'y-or-n-p)
  36. ;;; Enable all disabled commands.
  37. (setq disabled-command-function nil)
  38. ;;; Print buffer size in mode line.
  39. (size-indication-mode 1)
  40. ;;; Display defun in mode line.
  41. ;; (which-function-mode)
  42. ;;; No need when we have a status bar.
  43. ;; (display-time)
  44. ;; (setq display-time-day-and-date t
  45. ;; display-time-24hr-format t
  46. ;; display-time-default-load-average nil)
  47. ;;; Just like time, no need when we have a status bar.
  48. ;; (display-battery-mode)
  49. ;;; TODO: Battery status (%b) does not work properly.
  50. ;; (setq battery-mode-line-format "[%p%%%b %t]")
  51. ;;; Line numbers
  52. ;;; Adding to `find-file-hook' ensures it will work for every file, regardless of
  53. ;;; the mode, but it won't work for buffers without files nor on mode change.
  54. (dolist (hook '(prog-mode-hook text-mode-hook))
  55. (add-hook hook 'ambrevar/turn-on-column-number-mode)
  56. (add-hook hook 'ambrevar/turn-off-line-number-mode)
  57. (add-hook hook 'display-line-numbers-mode))
  58. (setq display-line-numbers-type 'visual)
  59. ;;; Emacs-nox does not display a fringe after the linum: Setting linum-format in
  60. ;;; linum-before-numbering-hook is not the right approach as it will change the
  61. ;;; type of linum-format in the middle. See linum-update-window.
  62. ;;; See http://stackoverflow.com/questions/3626632/right-align-line-numbers-with-linum-mode
  63. ;;; and http://stackoverflow.com/questions/3626632/right-align-line-numbers-with-linum-mode.
  64. ;;; The complexity is not worth the benefit.
  65. ;;; Alternative scrolling
  66. (setq scroll-error-top-bottom t)
  67. ;;; Kill whole line including \n.
  68. (setq kill-whole-line t)
  69. ;;; Indentation
  70. (setq-default tab-width 2)
  71. (defvaralias 'standard-indent 'tab-width)
  72. (setq-default indent-tabs-mode t)
  73. ;;; Line by line scrolling
  74. (setq scroll-step 1)
  75. (setq
  76. whitespace-style
  77. '(face empty indentation space-after-tab space-before-tab tab-mark trailing))
  78. ;;; REVIEW: `whitespace-report' will mistakenly always report empty lines at
  79. ;;; beginning and end of buffer as long as there is at least one empty line.
  80. ;;; `whitespace-cleanup' works properly however.
  81. ;;; Reported at http://debbugs.gnu.org/cgi/bugreport.cgi?bug=23740.
  82. ;; (setq whitespace-action '(report-on-bogus))
  83. ;;; Add formatting functions to the buffer-local `before-save-hook'.
  84. ;;; WARNING: this can break some configuration files needing whitespaces at the
  85. ;;; end. This can also slow down saving on big files. Some modes (e.g. lisp) run
  86. ;;; `ambrevar/prettify' in their local hook, which is redundant with this.
  87. ;; (add-hook 'find-file-hook 'ambrevar/turn-on-prettify-before-save)
  88. (add-hook 'find-file-hook 'ambrevar/turn-on-delete-trailing-whitespace)
  89. ;;; Cycle spacing instead of just-one-space. This frees M-\.
  90. (global-set-key [remap just-one-space] 'cycle-spacing)
  91. ;;; Hippie expand
  92. ;; (global-set-key (kbd "M-/") 'hippie-expand)
  93. ;;; Abbreviation is like snippets: annoying at times, especially in
  94. ;;; prog-mode. They are useful in text mode to avoid the sprawling of
  95. ;;; abbreviations.
  96. (add-hook 'text-mode-hook 'abbrev-mode)
  97. ;;; Auto-fill
  98. (when (getenv "MANWIDTH")
  99. (setq-default fill-column (string-to-number (getenv "MANWIDTH"))))
  100. (add-hook 'text-mode-hook 'turn-on-auto-fill)
  101. ;; (setq sentence-end-double-space nil)
  102. ;;; Enforce horizontal splitting. 140 means that the window is large enough to
  103. ;;; hold 2 other windows of 70 columns.
  104. (setq split-height-threshold nil
  105. split-width-threshold 140)
  106. ;;; Windmove mode
  107. ;;; By default, it allows easy window switching with Shift+arrows. I like to
  108. ;;; stick to the home-row, but to avoid shadowing other binding I exceptionaly use
  109. ;;; 'super' (normally reserved to the WM).
  110. (when (fboundp 'windmove-default-keybindings)
  111. (ambrevar/global-set-keys
  112. "s-h" 'windmove-left
  113. "s-j" 'windmove-down
  114. "s-k" 'windmove-up
  115. "s-l" 'windmove-right))
  116. (ambrevar/global-set-keys
  117. "s-o" 'delete-other-windows
  118. ;; "s-w" 'other-window
  119. "s-c" 'delete-window)
  120. ;; REVIEW: If xdg-open is not found, set Emacs URL browser to the environment browser,
  121. ;; or w3m if BROWSER is not set.
  122. ;; See https://debbugs.gnu.org/cgi/bugreport.cgi?bug=18986.
  123. (setq browse-url-generic-program (or
  124. (executable-find (or (getenv "BROWSER") "")) ; TODO: Still need this in Emacs 26?
  125. (when (executable-find "xdg-mime")
  126. (let ((desktop-browser (ambrevar/call-process-to-string "xdg-mime" "query" "default" "text/html")))
  127. (substring desktop-browser 0 (string-match "\\.desktop" desktop-browser))))
  128. (executable-find browse-url-mozilla-program)
  129. (executable-find browse-url-firefox-program)
  130. (executable-find browse-url-chromium-program)
  131. (executable-find browse-url-kde-program)
  132. (executable-find browse-url-conkeror-program)
  133. (executable-find browse-url-chrome-program)))
  134. (setq shr-external-browser browse-url-browser-function)
  135. ;; shr
  136. (setq shr-width (string-to-number (or (getenv "MANWIDTH") "80")))
  137. ;;; Extend MIME-types support for videos.
  138. (with-eval-after-load 'mailcap
  139. (add-to-list 'mailcap-mime-extensions '(".webm" . "video/webm"))
  140. (add-to-list 'mailcap-mime-extensions '(".mp4" . "video/mp4"))
  141. (add-to-list 'mailcap-mime-extensions '(".flv" . "video/mp4"))
  142. (add-to-list 'mailcap-mime-extensions '(".ogv" . "video/ogg"))
  143. (add-to-list 'mailcap-mime-extensions '(".mkv" . "video/x-matroska")))
  144. ;;; Default ispell dictionary. If not set, Emacs uses the current locale.
  145. (setq ispell-dictionary "english")
  146. (ambrevar/define-keys text-mode-map
  147. "C-<f6>" 'ispell-change-dictionary
  148. "<f6>" 'ispell-buffer)
  149. ;;; Show matching parenthesis
  150. (show-paren-mode 1)
  151. ;;; By default, there’s a small delay before showing a matching parenthesis. Set
  152. ;;; it to 0 to deactivate.
  153. (setq show-paren-delay 0)
  154. (setq show-paren-when-point-inside-paren t)
  155. ;;; Electric Pairs to auto-complete () [] {} "" etc. It works on regions.
  156. ;; (electric-pair-mode)
  157. ;;; Spawn terminal shortcut: WM's binding is s+<return>.
  158. (global-set-key (kbd "C-x M-<return>") 'spawn-terminal)
  159. ;;; Calendar ISO display.
  160. (setq calendar-week-start-day 1)
  161. (setq calendar-date-style 'iso)
  162. ;;; Compilation bindings and conveniences.
  163. (setq compilation-ask-about-save nil)
  164. (setq compilation-scroll-output 'first-error)
  165. (with-eval-after-load 'compile
  166. ;; Making `compilation-directory' local only works with `recompile'
  167. ;; and if `compile' is never used. In such a scenario,
  168. ;; `compile-command' is not saved by `recompile' itself which adds a
  169. ;; lot of bookkeeping.
  170. ;; (make-variable-buffer-local 'compilation-directory)
  171. ;; (make-variable-buffer-local 'compile-history)
  172. (make-variable-buffer-local 'compile-command))
  173. ;;; Some commands ignore that compilation-mode is a "dumb" terminal and still display colors.
  174. ;;; Thus we render those colors.
  175. (require 'ansi-color)
  176. (defun ambrevar/compilation-colorize-buffer ()
  177. (when (eq major-mode 'compilation-mode)
  178. (ansi-color-apply-on-region compilation-filter-start (point-max))))
  179. (add-hook 'compilation-filter-hook 'ambrevar/compilation-colorize-buffer)
  180. (global-set-key (kbd "<f7>") 'previous-error)
  181. (global-set-key (kbd "<f8>") 'next-error)
  182. (defun ambrevar/compile-last-command ()
  183. (interactive)
  184. (compile compile-command))
  185. (ambrevar/define-keys prog-mode-map
  186. "C-<f6>" 'compile
  187. ;; Do not use `recompile' since we want to change the compilation folder for the current buffer.
  188. "<f6>" 'ambrevar/compile-last-command)
  189. ;;; REVIEW: Bug 26658 reports that cc-modes mistakenly does not make use of prog-mode-map.
  190. ;;; The following line is a suggested work-around.
  191. ;;; This should be fixed in Emacs 26.
  192. (eval-after-load 'cc-mode '(set-keymap-parent c-mode-base-map prog-mode-map))
  193. ;;; Comint mode
  194. (setq comint-prompt-read-only t)
  195. ;;; Desktop-mode
  196. ;;; REVIEW: `desktop-kill' should not query the user in `kill-emacs-hook'.
  197. ;;; https://debbugs.gnu.org/cgi/bugreport.cgi?bug=28943
  198. ;;; TODO: Desktop mode does not save window registers properly.
  199. ;;; See https://groups.google.com/forum/#!topic/gnu.emacs.help/64aO_O43530
  200. ;;; and https://www.reddit.com/r/emacs/comments/4q38s1/save_register_between_sessions/?st=j419vc7r&sh=2617ffb4
  201. ;;; and http://debbugs.gnu.org/cgi/bugreport.cgi?bug=27422
  202. ;;; and https://stackoverflow.com/questions/5830494/windows-configuration-to-registers#5830928
  203. ;;; and https://www.reddit.com/r/emacs/comments/7au3hj/how_do_you_manage_your_emacs_windows_and_stay_sane/dpfbg3a/?context=3.
  204. (when (daemonp)
  205. ;; Auto-load/save sessions only when running the daemon.
  206. ;; `server-running-p' is only useful once the daemon is started and cannot be
  207. ;; used for initialization. Use `daemonp' instead.
  208. (when (< emacs-major-version 27)
  209. ;; By default, Emacs<27 prompts for unsafe variable when loading desktop
  210. ;; which stucks the daemon. Disable this behaviour.
  211. (defun ambrevar/enable-safe-local-variables ()
  212. (setq enable-local-variables t))
  213. (add-hook 'after-init-hook 'ambrevar/enable-safe-local-variables))
  214. (require 'desktop) ; This adds a hook to `after-init-hook'.
  215. (when (< emacs-major-version 27)
  216. (defun ambrevar/enable-all-local-variables ()
  217. (setq enable-local-variables :all))
  218. (add-hook 'after-init-hook 'ambrevar/enable-all-local-variables))
  219. (when (< emacs-major-version 27)
  220. (load "patch-desktop"))
  221. (setq history-length 250
  222. ;; Default timer (30) is way too high: for somebody too frenzy, the timer
  223. ;; might never be saved. See
  224. ;; https://debbugs.gnu.org/cgi/bugreport.cgi?bug=28943.
  225. desktop-auto-save-timeout 5
  226. ;; desktop-restore-eager 4 ; Can be annoying as you don't have your last-loaded buffers immediately.
  227. ;; desktop-load-locked-desktop 'ask
  228. desktop-restore-frames nil
  229. desktop-save t)
  230. ;; Before Emacs 27, initialization needs the patch above.
  231. (if (< emacs-major-version 27)
  232. (desktop-save-mode)
  233. (defun ambrevar/desktop-init (_frame)
  234. (desktop-save-mode)
  235. (desktop-read)
  236. (remove-hook 'server-after-make-frame-hook 'ambrevar/desktop-init))
  237. (add-hook 'server-after-make-frame-hook 'ambrevar/desktop-init))
  238. ;; Discarding PDFs and images makes it lighter.
  239. (add-to-list 'desktop-modes-not-to-save 'pdf-view-mode)
  240. (add-to-list 'desktop-modes-not-to-save 'image-mode)
  241. ;; TODO: `compile-history' should be buffer local but that does not work.
  242. ;; http://user42.tuxfamily.org/compile-history-local/index.html
  243. ;; http://stackoverflow.com/questions/22995203/one-compile-command-per-buffer-not-directory
  244. ;; (add-to-list 'desktop-locals-to-save 'compile-history)
  245. (add-to-list 'desktop-locals-to-save 'compile-command)
  246. (add-to-list 'desktop-locals-to-save 'ispell-local-dictionary))
  247. ;;; Buffer names.
  248. (setq uniquify-buffer-name-style 'forward)
  249. ;;; Skeleton settings
  250. ;;; Do not expand abbrevs in skeletons.
  251. (setq-default skeleton-further-elements '((abbrev-mode nil)))
  252. (ambrevar/turn-on-skeleton-markers)
  253. (ambrevar/global-set-keys
  254. "C->" 'skeleton-next-position
  255. "C-<" 'skeleton-previous-position)
  256. ;;; Disable prompt (but leave warning) on git symlink.
  257. (setq vc-follow-symlinks t)
  258. ;;; Clipboard and primary selection.
  259. ;; (setq select-enable-clipboard t)
  260. (setq select-enable-primary t
  261. save-interprogram-paste-before-kill t)
  262. ;;; Move mouse away.
  263. (mouse-avoidance-mode 'banish)
  264. ;;; That binding is not very useful and gets in the way of C-<mouse-1>.
  265. (global-unset-key (kbd "C-<down-mouse-1>"))
  266. ;;; Scroll zooming.
  267. (ambrevar/global-set-keys
  268. "C-<wheel-down>" 'text-scale-decrease
  269. "C-<mouse-5>" 'text-scale-decrease
  270. "C-<wheel-up>" 'text-scale-increase
  271. "C-<mouse-4>" 'text-scale-increase)
  272. (setq text-scale-mode-step 1.1)
  273. ;;; Sort
  274. (setq sort-fold-case t)
  275. ;;; Replace not-so-useful comment-dwim binding.
  276. (global-set-key (kbd "M-;") 'comment-line)
  277. ;;; Eldoc: Disable if too distracting.
  278. ;; (global-eldoc-mode 0)
  279. ;; (setq eldoc-idle-delay 0.1) ; Could be even more distracting.
  280. ;;; Replace `kill-buffer' binding by `kill-this-buffer'.
  281. (global-set-key (kbd "C-x k") 'kill-this-buffer)
  282. ;;; Ediff
  283. ;;; TODO: Ediff does not seem to auto-refine. Bug? Compare daemon and no-daemon.
  284. (setq ediff-window-setup-function 'ediff-setup-windows-plain
  285. ediff-split-window-function 'split-window-horizontally)
  286. ;;; Trash
  287. (setq delete-by-moving-to-trash t)
  288. ;;; Display Time World
  289. (setq
  290. zoneinfo-style-world-list
  291. '(("UTC" "-")
  292. ("Europe/Paris" "France Germany Sweden")
  293. ("Asia/Calcutta" "India")
  294. ("Indian/Mauritius" "Mauritius")
  295. ("Africa/Tunis" "Tunisia")
  296. ("Asia/Ho_Chi_Minh" "Vietnam")
  297. ("Australia/Melbourne" "Melbourne")
  298. ("Africa/Nairobi" "Uganda")))
  299. ;;; Frame title
  300. (setq frame-title-format (concat "%b" (unless (daemonp) " [serverless]")))
  301. ;;; Initial scratch buffer message.
  302. (require 'functions) ; For `ambrevar/fortune-scratch-message'.
  303. (let ((fortune (ambrevar/fortune-scratch-message)))
  304. (when fortune
  305. (setq initial-scratch-message fortune)))
  306. ;;; Support for Emacs pinentry.
  307. ;;; Required for eshell/sudo and everything relying on GPG queries.
  308. (setq epa-pinentry-mode 'loopback) ; This will fail if gpg>=2.1 is not available.
  309. (when (require 'pinentry nil t)
  310. (pinentry-start))
  311. ;;; Edebug
  312. ;; (setq edebug-trace t)
  313. ;;; Make windowing more reactive on. This is especially true with Helm on EXWM.
  314. (when (= emacs-major-version 26)
  315. (setq x-wait-for-event-timeout nil))
  316. (setq woman-fill-column fill-column)
  317. (provide 'main)