ambevar-dotfiles/.emacs.d/init.el

500 lines
18 KiB
EmacsLisp
Raw Normal View History

;;; Emacs config
2016-10-14 14:03:30 +02:00
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;; Prerequisites
2017-06-18 19:05:50 +02:00
(let ((minver "24.1"))
(when (version< emacs-version minver)
(error "Your Emacs is too old -- this config requires v%s or higher" minver)))
;;; Speed up init.
;;; Temporarily reduce garbage collection during startup. Inspect `gcs-done'.
(defun ambrevar/reset-gc-cons-threshold ()
(setq gc-cons-threshold (car (get 'gc-cons-threshold 'standard-value))))
(setq gc-cons-threshold (* 64 1024 1024))
(add-hook 'after-init-hook 'ambrevar/reset-gc-cons-threshold)
;;; Temporarily disable the file name handler.
(setq default-file-name-handler-alist file-name-handler-alist)
(setq file-name-handler-alist nil)
(defun ambrevar/reset-file-name-handler-alist ()
(setq file-name-handler-alist default-file-name-handler-alist))
(add-hook 'after-init-hook 'ambrevar/reset-file-name-handler-alist)
(defvar ambrevar/emacs-cache-folder "~/.cache/emacs/"
2017-08-14 11:16:17 +02:00
"Cache folder is everything we do not want to track together
with the configuration files.")
(if (not (file-directory-p ambrevar/emacs-cache-folder))
(make-directory ambrevar/emacs-cache-folder t))
2013-06-12 22:56:30 +02:00
;;; Store additional config in a 'lisp' subfolder and add it to the load path so
;;; that `require' can find the files.
(add-to-list 'load-path (expand-file-name "lisp/" user-emacs-directory))
(when (require 'package nil t)
;; TODO: MELPA's https sometimes return
;; emacs melpa invalid: certificate host does not match hostname
;; Try the following:
;; (setq tls-checktrust nil)
(setq package-archives '(("gnu" . "https://elpa.gnu.org/packages/")))
(add-to-list 'package-archives '("melpa" . "https://melpa.milkbox.net/packages/"))
(add-to-list 'package-archives '("org" . "https://orgmode.org/elpa/") t)
(setq package-user-dir (concat ambrevar/emacs-cache-folder "elpa"))
(package-initialize))
;;; Site Lisp folder for local packages and development.
;; We need to roll it out manually since we want it first in the `load-path',
;; while `normal-top-level-add-subdirs-to-load-path' appends it to the very end.
(defun ambrevar/package-refresh-load-path (path)
"Add every non-hidden sub-folder of PATH to `load-path'."
(when (file-directory-p path)
(dolist (dir (directory-files path t "^[^\\.]"))
(when (file-directory-p dir)
(setq load-path (add-to-list 'load-path dir))))))
(let ((site-lisp (expand-file-name "site-lisp/" user-emacs-directory)))
(add-to-list 'load-path site-lisp)
(ambrevar/package-refresh-load-path site-lisp))
;;; Local config. See below for an example usage.
(load "local-before" t)
(require 'functions)
(require 'main)
(require 'visual)
2014-02-12 17:48:29 +01:00
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2014-03-08 11:48:35 +01:00
;;; Assembly
(push 'nasm-mode package-selected-packages)
;;; Asymptote
2014-12-16 10:10:41 +01:00
(add-to-list 'load-path "/usr/share/asymptote")
(autoload 'asy-mode "asy-mode" "Asymptote major mode." t)
(autoload 'lasy-mode "asy-mode" "Hybrid Asymptote/Latex major mode." t)
(autoload 'asy-insinuate-latex "asy-mode" "Asymptote insinuate LaTeX." t)
2014-12-16 10:10:41 +01:00
(add-to-list 'auto-mode-alist '("\\.asy$" . asy-mode))
;;; BBCode
(nconc package-selected-packages '(bbcode-mode))
(with-eval-after-load 'bbcode-mode (require 'init-bbcode))
2014-09-11 22:33:39 +02:00
;;; Bibtex
(setq bibtex-entry-format '(opts-or-alts required-fields numerical-fields whitespace realign last-comma delimiters braces sort-fields))
(setq bibtex-field-delimiters 'double-quotes)
(add-hook 'bibtex-mode-hook 'ambrevar/turn-off-indent-tabs)
;;; Bison/Flex
;; (nconc package-selected-packages '(bison-mode))
2014-03-08 15:58:29 +01:00
2018-01-29 11:37:39 +01:00
;;; Camcorder
2018-02-04 15:10:01 +01:00
;; (nconc package-selected-packages '(camcorder))
2018-01-29 11:37:39 +01:00
(with-eval-after-load 'camcorder
2018-02-04 15:10:01 +01:00
(setq camcorder-output-directory (expand-file-name "temp" "~")
camcorder-gif-output-directory camcorder-output-directory)
(setq camcorder-recording-command '("recordmydesktop" " --fps 10 --no-sound --windowid " window-id " -o " file))
(add-to-list 'camcorder-gif-conversion-commands '("ffmpeg-slow" "ffmpeg -i " input-file " -vf 'fps=10,scale=1024:-1:flags=lanczos' " gif-file)))
2018-01-29 11:37:39 +01:00
;;; C/C++
(with-eval-after-load 'cc-mode (require 'init-cc))
;;; ChangeLog
(defun ambrevar/change-log-set-indent-rules ()
(setq tab-width 2 left-margin 2))
(add-hook 'change-log-mode-hook 'ambrevar/change-log-set-indent-rules)
2017-08-14 11:16:17 +02:00
;;; Completion
(nconc package-selected-packages '(company helm-company))
(when (require 'company nil t)
(setq company-idle-delay nil))
;;; Debbugs
(nconc package-selected-packages '(debbugs))
(with-eval-after-load 'debbugs
2017-10-23 21:07:03 +02:00
(setq debbugs-gnu-all-severities t
debbugs-gnu-persistency-file (expand-file-name "debbugs" ambrevar/emacs-cache-folder)))
2017-08-03 15:34:22 +02:00
;;; Diff
;;; TODO: In diff-mode, both `[[` and `C-M-a` do not go back to previous index
;;; once they are at the beginning of an index.
2017-08-03 15:34:22 +02:00
(nconc package-selected-packages '(ztree))
;;; Dired
;;; Dired is loaded after init.el, so configure it only then.
2017-10-08 20:36:28 +02:00
;;; TODO: Improve dired-du:
;;; - Hangs when the `ls` time format is changed.
;;; - Cache recursive results.
(nconc package-selected-packages '(dired-du))
(with-eval-after-load 'dired (require 'init-dired))
;;; Emms
2017-09-01 13:09:54 +02:00
(nconc package-selected-packages '(emms helm-emms emms-player-mpv))
(with-eval-after-load 'emms (require 'init-emms))
;;; Evil
(nconc package-selected-packages '(evil
evil-commentary evil-multiedit linum-relative
evil-ediff evil-magit evil-mu4e evil-org evil-collection))
2018-01-11 09:43:25 +01:00
(setq evil-want-integration nil)
(when (require 'evil nil t) (require 'init-evil))
;;; Eshell
;;; Extend completion.
(nconc package-selected-packages '(fish-completion bash-completion
pcomplete-extension pcmpl-args pcmpl-git))
(nconc package-selected-packages '(esh-autosuggest))
(when (and (executable-find "fish")
(require 'fish-completion nil t))
(setq fish-completion-fallback-on-bash-p t)
(global-fish-completion-mode))
(with-eval-after-load 'eshell (require 'init-eshell))
2018-02-15 13:28:49 +01:00
(autoload 'ambrevar/eshell-or-new-session "eshell")
;;; Eww
(with-eval-after-load 'eww (require 'init-eww))
2018-02-15 13:28:49 +01:00
(autoload 'ambrevar/eww-switch-back "eww")
;;; Expand region.
(nconc package-selected-packages '(expand-region))
(when (require 'expand-region nil t)
(global-set-key (kbd "C-=") 'er/expand-region))
;;; GLSL
(nconc package-selected-packages '(glsl-mode))
2014-03-08 15:58:29 +01:00
;;; Go
(nconc package-selected-packages '(go-mode go-eldoc go-guru go-rename helm-go-package company-go))
(with-eval-after-load 'go-mode (require 'init-go))
;;; Graphviz dot
2017-10-08 20:36:28 +02:00
;;; The view command is broken but the preview command works (it displays the PNG
;;; in a new window), which is enough and probably not worth a fix.
(nconc package-selected-packages '(graphviz-dot-mode))
;;; GUD (GDB, etc.)
(with-eval-after-load 'gud (require 'init-gud))
;;; Helm
(nconc package-selected-packages '(helm helm-descbinds helm-ls-git))
(when (require 'helm-config nil t) (require 'init-helm))
;;; Hex editing
(nconc package-selected-packages '(nhexl-mode))
2018-02-13 23:25:12 +01:00
;;; Iedit
(nconc package-selected-packages '(iedit))
(when (require 'iedit nil t)
(global-set-key (kbd "C-;") 'iedit-mode))
;;; Image
;;; TODO: Disable white frame.
;;; I think it's the cursor.
;;; Evil-mode reverts cursor changes.
2018-02-15 13:28:49 +01:00
;; (set-face-foreground 'cursor "black")
;;; TODO: Implement other sxiv features:
;;; - Gamma
;;; - Marks
;;; - Gallery
;;; TODO: Is it possible to display an image fullscreen?
2018-02-15 13:28:49 +01:00
;;; TODO: Image+: Dot no auto-adjust animated files
;;; https://github.com/mhayashi1120/Emacs-imagex/issues/10
;;; TODO: Image+: Restore animation state
;;; https://github.com/mhayashi1120/Emacs-imagex/issues/9
(nconc package-selected-packages '(image+))
(with-eval-after-load 'image
(setq image-animate-loop t)
(add-hook 'image-mode-hook 'image-toggle-animation)
(require 'image+ nil t))
;;; Indentation engine fix.
;; (require 'smiext "init-smiext")
;;; Indentation style guessing.
;; (nconc 'package-selected-packages '(dtrt-indent))
2017-08-14 11:16:17 +02:00
;;; JavaScript
(add-hook 'js-mode-hook (lambda () (defvaralias 'js-indent-level 'tab-width)))
;;; Lisp
2018-02-07 12:06:57 +01:00
(nconc package-selected-packages '(lispy lispyville))
(with-eval-after-load 'lispyville
2018-02-15 23:39:27 +01:00
;; TODO: Use '=' to indent.
;; TODO: lispy-occur: helm-occur does not restrict to region.
2018-02-07 12:06:57 +01:00
(lispyville-set-key-theme
2018-02-15 23:39:27 +01:00
'(operators ; Add equivalent for lispy-delete?
c-w ; Bind M-backspace to lispyville-delete-backward-word?
2018-02-07 12:06:57 +01:00
(escape insert)
2018-02-15 23:39:27 +01:00
slurp/barf-cp
;; (mark insert)
mark-toggle ; TODO: Check out readme.
))
(lispyville--define-key '(motion normal insert)
(kbd "M-h") #'lispyville-previous-opening
(kbd "M-l") #'lispyville-next-opening
(kbd "M-j") #'lispy-down
(kbd "M-k") #'lispy-up
(kbd "M-H") #'lispy-up-slurp ; lispy-down-slurp?
2018-02-15 23:39:27 +01:00
(kbd "M-J") #'lispyville-drag-forward
(kbd "M-K") #'lispyville-drag-backward
(kbd "M-L") #'lispy-move-right ; lispy-up-slurp?
(kbd "C-x C-e") #'lispy-eval
(kbd "M-;") #'lispy-comment)
2018-02-15 23:39:27 +01:00
(lispyville--define-key '(motion normal)
"Y" 'lispy-new-copy
"D" 'lispy-kill))
(defun ambrevar/init-lispy ()
2018-02-07 12:06:57 +01:00
(when (require 'lispy nil t)
(set-face-foreground 'lispy-face-hint "#FF00FF")
(when (require 'lispyville nil t)
2018-02-08 09:25:35 +01:00
(add-hook 'lispy-mode-hook 'lispyville-mode))
(lispy-mode)))
(dolist (hook '(lisp-mode-hook emacs-lisp-mode-hook))
2018-02-15 14:23:46 +01:00
(add-hook hook 'ambrevar/turn-on-prettify-before-save)
(add-hook hook 'ambrevar/turn-on-complete-filename)
(add-hook hook 'ambrevar/turn-on-tab-width-to-8) ; Because some existing code uses tabs.
(add-hook hook 'ambrevar/turn-off-indent-tabs) ; Should not use tabs.
(add-hook hook 'ambrevar/init-lispy))
;;; Common LISP
(setq inferior-lisp-program "clisp")
;;; Lua
(nconc package-selected-packages '(lua-mode))
(with-eval-after-load 'lua-mode (require 'init-lua))
;;; Magit
2017-06-25 14:37:15 +02:00
;;; Magit can be loaded just-in-time.
(nconc package-selected-packages '(magit))
2017-06-25 14:37:15 +02:00
(with-eval-after-load 'magit
(setq auto-revert-mode-text "")
(set-face-foreground 'magit-branch-remote "orange red")
(setq git-commit-summary-max-length fill-column)
;; Customize what to fold by default.
;; (push (cons [* commitbuf] 'hide) magit-section-initial-visibility-alist)
;; Avoid conflict with WM.
(define-key magit-mode-map (kbd "s-<tab>") nil)
2017-06-25 14:37:15 +02:00
(setq magit-diff-refine-hunk 'all))
(when (fboundp 'magit-status)
(global-set-key (kbd "C-x g") 'magit-status))
;;; Mail
2017-08-14 11:16:17 +02:00
;;; mu4e is usually site-local and not part of ELPA.
(when (delq nil (mapcar (lambda (path) (string-match "/mu4e/\\|/mu4e$" path)) load-path))
;; (nconc package-selected-packages '(mu4e-maildirs-extension))
(nconc package-selected-packages '(helm-mu)))
(with-eval-after-load 'mu4e (require 'init-mu4e))
2018-02-15 13:28:49 +01:00
(autoload 'ambrevar/mu4e-headers "mu4e")
;;; Makefile
(with-eval-after-load 'make-mode (require 'init-makefile))
;;; Markdown
(nconc package-selected-packages '(markdown-mode))
(with-eval-after-load 'markdown-mode (require 'init-markdown))
;;; Matlab / Octave
(add-to-list 'auto-mode-alist '("\\.m\\'" . octave-mode)) ; matlab
(defun ambrevar/octave-set-comment-start ()
"Set comment character to '%' to be Matlab-compatible."
(set (make-local-variable 'comment-start) "% "))
(add-hook 'octave-mode-hook 'ambrevar/octave-set-comment-start)
;;; Maxima
(autoload 'maxima-mode "maxima" "Maxima mode" t)
(autoload 'maxima "maxima" "Maxima interaction" t)
(add-to-list 'auto-mode-alist '("\\.mac" . maxima-mode))
;;; Mediawiki
(nconc package-selected-packages '(mediawiki))
(add-to-list 'auto-mode-alist '("\\.wiki\\'" . mediawiki-mode))
(with-eval-after-load 'mediawiki (require 'init-mediawiki))
2017-07-17 08:59:36 +02:00
;;; News
(nconc package-selected-packages '(elfeed))
(with-eval-after-load 'elfeed (require 'init-elfeed))
2018-02-15 13:28:49 +01:00
(autoload 'ambrevar/elfeed-switch-back "elfeed")
2017-07-17 08:59:36 +02:00
;;; Org-mode
2017-12-13 18:17:17 +01:00
(nconc package-selected-packages '(org-plus-contrib org-bullets)) ; org-plus contains latest Org mode.
(with-eval-after-load 'org (require 'init-org))
2018-02-15 13:28:49 +01:00
(autoload 'ambrevar/org-switch-agenda-file "org")
(autoload 'ambrevar/org-switch-agenda-file-other-window "org")
;;; Packaging
(nconc package-selected-packages '(esup package-lint))
;;; Pass
(nconc package-selected-packages '(helm-pass))
;;; PDF
;;; pdf-tools requires poppler built with cairo support.
;;; We cannot defer loading as `pdf-tools-install' is required for PDF
;;; association.
2017-10-11 17:18:23 +02:00
;;; REVIEW: `save-place' does not seem to work with pdf-tools.
;;; See https://github.com/politza/pdf-tools/issues/18.
;;; TODO: windmove fails when selecting text and then moving up/down.
2018-02-15 13:28:49 +01:00
;;; It only fails in Evil mode.
2017-07-02 20:07:19 +02:00
(nconc package-selected-packages '(pdf-tools))
(when (require 'pdf-tools nil t)
;; (setq pdf-view-midnight-colors '("#ffffff" . "#000000"))
(setq pdf-view-midnight-colors '("#ff9900" . "#0a0a12" )) ; Amber
(add-hook 'pdf-view-mode-hook 'pdf-view-midnight-minor-mode)
2017-08-14 11:16:17 +02:00
(pdf-tools-install t t t))
;;; Perl
(defun ambrevar/perl-set-indent-rules ()
(defvaralias 'perl-indent-level 'tab-width))
(defun ambrevar/perl-set-compiler ()
(setq compile-command (concat "perl " (shell-quote-argument buffer-file-name))))
(add-hook 'perl-mode-hook 'ambrevar/perl-set-indent-rules)
(add-hook 'perl-mode-hook 'ambrevar/perl-set-compiler)
2018-02-16 12:33:33 +01:00
;;; Pinentry
(nconc package-selected-packages '(pinentry)) ; pinentry.el was remombed from Emacs 26.
;;; po
(nconc package-selected-packages '(po-mode))
;;; Python
(with-eval-after-load 'python (require 'init-python))
2017-08-30 17:42:46 +02:00
;;; Rainbow-mode
(nconc package-selected-packages '(rainbow-mode))
(when (require 'rainbow-mode nil t)
(dolist (hook '(css-mode-hook html-mode-hook sass-mode-hook))
(add-hook hook 'rainbow-mode)))
;;; Roff / Nroff
(with-eval-after-load 'nroff-mode (require 'init-nroff))
;;; Shell
(with-eval-after-load 'sh-script (require 'init-sh))
;;; Arch Linux PKGBUILD
(add-to-list 'auto-mode-alist '("PKGBUILD" . sh-mode))
;;; Gentoo
(add-to-list 'auto-mode-alist '("\\.ebuild\\'" . sh-mode))
(add-to-list 'auto-mode-alist '("\\.eclass\\'" . sh-mode))
(add-to-list 'auto-mode-alist '("package\\.accept_keywords" . sh-mode))
(add-to-list 'auto-mode-alist '("package\\.mask" . sh-mode))
(add-to-list 'auto-mode-alist '("package\\.use" . sh-mode))
;;; If we ever need to edit exotic shell configs:
;; (nconc package-selected-packages '(fish-mode rc-mode))
2016-10-11 17:33:36 +02:00
;;; Srt (subtitles)
(add-to-list 'auto-mode-alist '("\\.srt\\'" . text-mode))
;;; StackExchange
(nconc package-selected-packages '(sx))
(with-eval-after-load 'sx
(setq sx-cache-directory (concat ambrevar/emacs-cache-folder "sx")))
;;; Syntax checking
(nconc package-selected-packages '(flycheck helm-flycheck))
(when (require 'flycheck nil t) (require 'init-flycheck))
;;; System packages
(nconc package-selected-packages '(helm-system-packages))
(global-set-key (kbd "C-x c #") 'helm-system-packages)
;;; Terminal
(with-eval-after-load 'term
2017-11-08 09:13:27 +01:00
;; (require 'init-term)
(setq term-buffer-maximum-size 0))
;;; TeX / LaTeX / Texinfo
(nconc package-selected-packages '(auctex latex-math-preview))
(with-eval-after-load 'tex (require 'init-tex))
;; LaTeX is defined in the same file as TeX. To separate the loading, we add it
;; to the hook.
(add-hook 'latex-mode-hook (lambda () (require 'init-latex)))
;;; Torrent
2017-07-12 23:51:57 +02:00
(nconc package-selected-packages '(transmission))
(with-eval-after-load 'transmission
;; `transmission' will fail to start and will not run any hook if the daemon
;; is not up yet.
;; We need to advice the function :before to guarantee it starts.
(defun ambrevar/transmission-start-daemon ()
(unless (member "transmission-da"
(mapcar
(lambda (pid) (alist-get 'comm (process-attributes pid)))
(list-system-processes)))
(call-process "transmission-daemon")
(sleep-for 1)))
(advice-add 'transmission :before 'ambrevar/transmission-start-daemon)
2017-07-12 23:51:57 +02:00
(setq transmission-refresh-modes '(transmission-mode transmission-files-mode transmission-info-mode transmission-peers-mode)
transmission-refresh-interval 1))
;;; Translator
(nconc package-selected-packages '(google-translate))
(when (require 'google-translate nil t)
(require 'google-translate-default-ui)
;; (global-set-key "\C-ct" 'google-translate-at-point)
;; (global-set-key "\C-cT" 'google-translate-query-translate)
(defun ambrevar/google-translate-line ()
"Translate current line and insert result after it, separated by ' = '."
(interactive)
(let* ((langs (google-translate-read-args nil nil))
(source-language (car langs))
(target-language (cadr langs))
text
result)
(end-of-line)
(just-one-space)
(setq text (buffer-substring-no-properties
(line-beginning-position) (line-end-position)))
(setq result (with-temp-buffer
(google-translate-translate
source-language target-language
text
'current-buffer)
(buffer-string))
(insert "= " result)))))
;;; Web forms.
;;; Remove auto-fill in web edits because wikis and forums do not like it.
;;; This works for qutebrowser, but may need changes for other browsers.
(defun ambrevar/browser-edit ()
(when (require 'with-editor nil t) (with-editor-mode))
(text-mode)
(auto-fill-mode -1))
(add-to-list 'auto-mode-alist `(,(concat (getenv "BROWSER") "-editor-*") . ambrevar/browser-edit))
;;; Wgrep
(nconc package-selected-packages '(wgrep-helm wgrep-pt))
(when (require 'wgrep nil t)
;; TODO: wgrep-face is not so pretty.
(set-face-attribute 'wgrep-face nil :inherit 'ediff-current-diff-C :foreground 'unspecified :background 'unspecified :box nil))
2017-07-26 18:39:19 +02:00
;;; Window manager
2017-11-22 15:34:08 +01:00
(nconc package-selected-packages '(exwm helm-exwm))
(nconc package-selected-packages '(pulseaudio-control))
2017-07-26 18:39:19 +02:00
(when (require 'exwm nil t) (require 'init-exwm))
;;; XML / SGML
(defun ambrevar/sgml-setup ()
(setq sgml-xml-mode t)
;; (toggle-truncate-lines) ; This seems to slow down Emacs.
(turn-off-auto-fill))
(add-hook 'sgml-mode-hook 'ambrevar/sgml-setup)
2017-06-23 15:41:22 +02:00
(with-eval-after-load 'nxml-mode
(set-face-foreground 'nxml-element-local-name "gold1")
2017-06-23 15:41:22 +02:00
(defvaralias 'nxml-child-indent 'tab-width))
;;; Because XML is hard to read.
(add-hook 'nxml-mode-hook 'ambrevar/turn-on-tab-width-to-4)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;; Finalization
2016-10-14 14:03:30 +02:00
;;; Don't let `customize' clutter my config.
2017-07-27 14:56:19 +02:00
(setq custom-file
(if (boundp 'server-socket-dir)
(expand-file-name "custom.el" server-socket-dir)
(expand-file-name (format "emacs-custom-%s.el" (user-uid)) temporary-file-directory)))
(load custom-file t)
;;; Local config. You can use it to set system specific variables, such as the
;;; external web browser or the geographical coordinates:
;;
;; (setq calendar-latitude 20.2158)
;; (setq calendar-longitude 105.938)
(load "local-after" t)