.emacs.d/init.el

976 lines
32 KiB
EmacsLisp
Raw Normal View History

;;; init.el --- tastytea's Emacs init file.
2019-07-28 05:58:13 +02:00
;; Time-stamp: <2019-07-28T03:55:07+00:00>
2019-03-19 00:12:11 +01:00
;;; Commentary:
;; I am using this file with Emacs 26, but most of it will probably work with
;; Emacs 24 and above.
2019-03-19 00:12:11 +01:00
;;; Code:
2019-03-19 01:43:28 +01:00
;;;;;;;;;;;;;;;;;;;; Packages ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2019-03-19 00:12:11 +01:00
(require 'package)
(add-to-list 'package-archives
'("melpa-stable" . "https://stable.melpa.org/packages/") t)
2019-03-19 00:12:11 +01:00
(add-to-list 'package-archives
2019-03-19 08:04:53 +01:00
'("melpa" . "https://melpa.org/packages/") t)
(setq package-archive-priorities '(
("melpa-stable" . 30)
("gnu" . 20)
("melpa" . 10)
2019-07-13 18:46:50 +02:00
))
2019-07-17 04:07:46 +02:00
;; Workaround for 26.2 <https://debbugs.gnu.org/cgi/bugreport.cgi?bug=34341>
(setq gnutls-algorithm-priority "NORMAL:-VERS-TLS1.3")
2019-03-19 00:12:11 +01:00
(package-initialize)
2019-03-22 09:03:23 +01:00
;; Add path for custom packages.
2019-03-19 00:12:11 +01:00
(add-to-list 'load-path "~/.emacs.d/custom-packages/")
2019-03-22 09:03:23 +01:00
;; Install use-package if necessary.
2019-03-19 00:12:11 +01:00
(unless (package-installed-p 'use-package)
(package-refresh-contents)
(package-install 'use-package))
(eval-when-compile
(require 'use-package))
2019-03-22 09:03:23 +01:00
;; Always install packages if they are not present.
2019-03-19 00:12:11 +01:00
(require 'use-package-ensure)
(setq use-package-always-ensure t)
;; autocompile files as needed.
(use-package auto-compile
:custom
2019-03-22 09:03:23 +01:00
;; Use uncompiled file if it is newer than the compiled one.
(load-prefer-newer t)
:config
(auto-compile-on-load-mode))
2019-03-22 09:03:23 +01:00
;; ;; Benchmark for startup-file.
2019-03-19 00:12:11 +01:00
;; (use-package benchmark-init
;; :config
;; ;; To disable collection of benchmark data after init is done.
;; (add-hook 'after-init-hook 'benchmark-init/deactivate))
2019-03-22 09:03:23 +01:00
;; Update packages if at least 7 days have passed.
2019-03-19 00:12:11 +01:00
(use-package auto-package-update
2019-03-22 09:03:23 +01:00
:custom
(auto-package-update-delete-old-versions t)
(auto-package-update-interval 7)
(auto-package-update-hide-results nil)
2019-03-19 00:12:11 +01:00
:config
(auto-package-update-maybe))
2019-03-19 01:43:28 +01:00
;;;;;;;;;;;;;;;;;;;; Global variables ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2019-03-22 09:03:23 +01:00
;; Determine if we run on a slow computer.
2019-03-19 00:12:11 +01:00
(defvar slow-computer nil)
(if (member (system-name) '("steuerbeamter" "azimuth" "localhost"))
(setq slow-computer t)) ; localhost is schnibble
2019-03-30 12:29:09 +01:00
;; Show manpages and error messages from compilers in English.
2019-03-30 00:22:47 +01:00
(setenv "LANG" "en_US.utf8")
2019-03-19 02:18:58 +01:00
;;;;;;;;;;;;;;;;;;;; Configure some essential things ;;;;;;;;;;;;;;;;;;;;;;;;;;;
2019-03-22 09:03:23 +01:00
;; Set garbage collection threshold to 100 MiB (or 20 MiB) to speed up init.
;; It is reset at the end of the file.
(if slow-computer
(setq gc-cons-threshold (* 20 1024 1024))
(setq gc-cons-threshold (* 100 1024 1024)))
(use-package emacs
:init
;; Banish customizations to another file.
(setq custom-file (concat user-emacs-directory "custom.el"))
:custom
(inhibit-startup-screen t)
(inhibit-startup-echo-area-message t)
(backup-directory-alist ; Save backups in ~/.emacs.d/backups/.
`(("." . ,(concat user-emacs-directory "backups"))))
(delete-old-versions t) ; Delete old backups.
(kept-new-versions 6) ; Keep 6 newest backups.
(backup-by-copying t) ; Copy to backup folder.
(version-control t) ; Append version numbers to file names.
(auto-save-file-name-transforms ; Save auto-saves in ~/.emacs.d/backups/.
`((".*" ,(concat user-emacs-directory "backups/") t)))
(user-full-name "tastytea")
(user-mail-address "tastytea@tastytea.de")
(mouse-wheel-scroll-amount '(1 ((shift) . 1))) ; Scroll 1 line at a time.
;; Paste text where the cursor is, not where the mouse is.
(mouse-yank-at-point t)
2019-07-28 05:58:13 +02:00
(initial-scratch-message nil) ; Make scratch buffer empty,
(initial-major-mode 'markdown-mode) ; and select mode.
(require-final-newline t) ; Always add newline at end of file.
(recentf-max-saved-items 40) ; Keep this number of buffers in history.
:config
(defalias 'yes-or-no-p 'y-or-n-p) ; Just type y/n instead of yes/no.
2019-03-19 01:43:28 +01:00
(defun my/set-fill-column-80 ()
"Set fill-column to 80."
(set-fill-column 80))
(defun my/set-fill-column-100 ()
"Set fill-column to 100."
(set-fill-column 100))
2019-04-26 11:34:30 +02:00
(defun my/set-fill-column-120 ()
"Set fill-column to 120."
(set-fill-column 120))
;; kill-region (cut) and kill-ring-save (copy) act on the current line if no
;; text is visually selected.
;; https://www.emacswiki.org/emacs/WholeLineOrRegion
(put 'kill-ring-save 'interactive-form
'(interactive
(if (use-region-p)
(list (region-beginning) (region-end))
(list (line-beginning-position) (line-beginning-position 2)))))
(put 'kill-region 'interactive-form
'(interactive
(if (use-region-p)
(list (region-beginning) (region-end))
(list (line-beginning-position) (line-beginning-position 2)))))
(delete-selection-mode t) ; Delete selection when you start to write.
(savehist-mode t) ; Save minibuffer history.
(global-auto-revert-mode t) ; Auto-revert file if changed on disk.
2019-07-11 01:42:59 +02:00
(defvar my/skippable-buffers '("^\\*" "^magit[:-]")
"Buffer names ignored by `next-buffer' and `previous-buffer'.")
2019-07-11 01:42:59 +02:00
(defvar my/never-skippable-buffers '("^\\*scratch\\*$")
"Buffer names never ignored by `next-buffer' and `previous-buffer'.")
(defun my/buffer-predicate (buffer)
2019-07-15 00:27:30 +02:00
"Returns nil if buffer-name matches expression in `my/skippable-buffers'."
(catch 'return
2019-07-11 01:42:59 +02:00
;; Return t if buffer-name is on never-skippable list.
(dolist (expression my/never-skippable-buffers)
(if (string-match expression (buffer-name buffer))
2019-07-15 00:27:30 +02:00
(throw 'return t)
2019-07-11 01:42:59 +02:00
))
;; Return nil if buffer-name is on skippable list.
(dolist (expression my/skippable-buffers)
(if (string-match expression (buffer-name buffer))
2019-07-15 00:27:30 +02:00
(throw 'return nil)
))
t))
(set-frame-parameter nil 'buffer-predicate 'my/buffer-predicate)
:hook
(prog-mode . my/set-fill-column-80)
(conf-mode . my/set-fill-column-80)
(text-mode . auto-fill-mode)) ; Enable word-wrapping at fill-column.
2019-03-19 00:12:11 +01:00
2019-03-22 09:03:23 +01:00
;; Save cursor position.
(use-package saveplace
:config
(save-place-mode t))
2019-03-19 00:12:11 +01:00
;;;;;;;;;;;;;;;;;;;; Keybindings ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(use-package bind-key
:init
(defun my/delete-word (arg)
"Delete characters forward until encountering the end of a word.
With argument, do this that many times."
(interactive "p")
(if (use-region-p)
(delete-region (region-beginning) (region-end))
(delete-region (point) (progn (forward-word arg) (point)))))
(defun my/backward-delete-word (arg)
"Delete characters backward until encountering the end of a word.
With argument, do this that many times."
(interactive "p")
(my/delete-word (- arg)))
:config
(bind-keys
2019-03-22 09:03:23 +01:00
;; Reduce whitespace around cursor to 0 or 1, according to context.
("C-S-<delete>" . fixup-whitespace)
2019-03-22 09:03:23 +01:00
;; Scroll without moving the cursor.
("M-<down>" . scroll-up-line)
("M-<up>" . scroll-down-line)
;; Delete words without storing them in the kill buffer.
("C-<delete>" . my/delete-word)
("C-<backspace>" . my/backward-delete-word)
2019-05-11 15:58:57 +02:00
;; Switch buffers.
("M-<left>" . previous-buffer)
2019-05-11 15:58:57 +02:00
("M-<right>" . next-buffer)
;; Switch windows.
("M-S-<left>" . previous-multiframe-window)
("M-S-<right>" . next-multiframe-window)
("s-<left>" . previous-multiframe-window) ; s = Super
("s-<right>" . next-multiframe-window)
;; Switch between header and implementation.
("C-:" . ff-find-other-file)
2019-05-11 15:58:57 +02:00
))
2019-03-19 00:12:11 +01:00
;;;;;;;;;;;;;;;;;;;; Programming / general ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2019-03-22 09:03:23 +01:00
;; Online documentation mode.
(use-package eldoc
:hook
(prog-mode . turn-on-eldoc-mode))
2019-03-22 09:03:23 +01:00
;; Syntax checking with many plugins.
(unless slow-computer
(use-package flycheck
:config
2019-04-29 15:22:59 +02:00
(global-flycheck-mode)
(flycheck-add-mode 'html-tidy 'web-mode)
(flycheck-add-mode 'css-csslint 'web-mode)))
2019-03-19 01:34:36 +01:00
2019-03-22 09:03:23 +01:00
;; Autocompletion mode with many plugins.
(unless slow-computer
(use-package company
2019-04-11 18:25:06 +02:00
:custom
;; Show suggestions after entering one character.
(company-minimum-prefix-length 1)
;; Wrap around at end/beginning of list.
(company-selection-wrap-around t)
;; Align annotation to the right border.
(company-tooltip-align-annotations t)
2019-04-01 01:07:09 +02:00
:bind
(:map company-active-map
("<return>" . nil) ; Disable completion on return.
("RET" . nil) ; https://emacs.stackexchange.com/a/13290
("<tab>" . company-complete-selection) ; Make tab work in lists.
("TAB" . company-complete-selection))
:hook
(after-init . global-company-mode)))
2019-03-19 01:34:36 +01:00
2019-03-22 09:03:23 +01:00
;; Fuzzy autocompletion for company.
2019-03-19 00:12:11 +01:00
(use-package company-flx
:after company
:config
(company-flx-mode +1))
2019-04-11 18:25:06 +02:00
(use-package company-statistics
:after company
:hook
2019-05-08 18:14:38 +02:00
(after-init . company-statistics-mode))
2019-04-11 18:25:06 +02:00
;; Set default indentation.
2019-03-19 01:34:36 +01:00
(setq-default indent-tabs-mode nil
tab-width 4)
;; Guess indentation.
(use-package dtrt-indent
:hook
(prog-mode . dtrt-indent-mode))
2019-03-19 01:34:36 +01:00
2019-03-22 09:03:23 +01:00
;; Automatic project management.
(unless slow-computer
(use-package projectile
2019-07-28 05:58:13 +02:00
:after (neotree ivy)
:init
(defun my/projectile-kill-buffers ()
"Kill project buffers and hide neotree."
(interactive)
(projectile-kill-buffers)
2019-04-08 21:30:37 +02:00
(neotree-hide))
(defvar my/cmake-compile-command ; cmake command for compiling with 1
(concat "cmake --build . -- -j" ; core less than available.
(substring (shell-command-to-string "nproc --ignore=1") 0 -1)))
:custom
(projectile-project-compilation-dir "build")
(projectile-switch-project-action 'neotree-projectile-action)
(projectile-project-configure-cmd
"cmake -DCMAKE_BUILD_TYPE=Debug -DCMAKE_EXPORT_COMPILE_COMMANDS=ON \
-GUnix\\ Makefiles ..")
2019-07-28 05:58:13 +02:00
(projectile-completion-system 'ivy)
:config
(setq projectile-project-compilation-cmd
(concat my/cmake-compile-command " && cd tests && ctest -Q"))
(projectile-mode +1)
(put 'projectile-project-compilation-cmd 'safe-local-variable #'stringp)
;; Mark variable as safe. This prevents prompts when using .dir-locals.el.
(put 'projectile-project-configure-cmd 'safe-local-variable #'stringp)
:bind
("C-c p" . 'projectile-command-map)
(:map projectile-command-map
2019-07-18 01:14:19 +02:00
("k" . 'my/projectile-kill-buffers))
))
2019-03-19 00:12:11 +01:00
;; Highlight TODO, FIXME, NOTE and so on.
2019-03-19 01:34:36 +01:00
(use-package hl-todo
:bind
(:map hl-todo-mode-map
2019-03-30 12:29:09 +01:00
("C-c t" . hl-todo-occur))
:hook
(prog-mode . hl-todo-mode))
2019-03-19 01:34:36 +01:00
2019-03-22 09:03:23 +01:00
;; Better commenting.
2019-03-19 01:34:36 +01:00
(use-package smart-comment
:bind
2019-03-20 09:54:12 +01:00
("C-x c" . smart-comment))
2019-03-19 01:34:36 +01:00
2019-03-22 09:03:23 +01:00
;; Toggle betweeen beginning/end of line and beginning/end of code.
(use-package mwim
:bind
("<home>" . mwim-beginning-of-line-or-code)
("<end>" . mwim-end-of-line-or-code))
2019-03-19 01:34:36 +01:00
2019-03-22 09:03:23 +01:00
;; Auto-type closing brackets.
2019-03-19 01:43:28 +01:00
(electric-pair-mode t)
2019-03-22 09:03:23 +01:00
;; Fold code.
(use-package fold-dwim
:bind
("<f7>" . fold-dwim-toggle)
2019-03-21 11:29:28 +01:00
("C-x t" . fold-dwim-toggle)
:hook
(prog-mode . hs-minor-mode))
(use-package hl-indent
:custom-face
(hl-indent-face ((t (:inherit hl-indent-face ; Reversed whitespace.
:background "gray18"
:foreground "#1c1e1f"
))))
:hook
(prog-mode . hl-indent-mode)
)
;; Tries to find points of interest and jumps to them.
(use-package imenu-anywhere
2019-07-28 05:58:13 +02:00
:after ivy
:bind
2019-07-28 05:58:13 +02:00
("M-i" . ivy-imenu-anywhere)
)
(use-package highlight-doxygen
:custom-face
2019-04-12 03:03:37 +02:00
(highlight-doxygen-comment ((t (:inherit font-lock-comment-face
2019-07-28 05:58:13 +02:00
:foreground "#667788"))))
2019-04-12 03:03:37 +02:00
(highlight-doxygen-code-block ((t (:inherit highlight-doxygen-comment-face))))
:hook
(prog-mode . highlight-doxygen-mode))
2019-04-11 19:22:37 +02:00
(use-package dumb-jump
2019-07-28 05:58:13 +02:00
:custom
(dumb-jump-selector 'ivy)
2019-04-11 19:22:37 +02:00
:bind
("M-." . dumb-jump-go)
("M-," . dumb-jump-back))
;;;;;;;;;;;;;;;;;;;; Programming / C++ ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Set coding style.
(use-package cc-mode
:ensure nil ; Included in Emacs.
2019-04-01 01:07:09 +02:00
:config
(c-add-style "tastytea"
'("bsd"
(c-basic-offset . 4)))
:custom
(c-default-style "tastytea"))
(unless slow-computer
2019-04-13 20:40:34 +02:00
;; irony communicates with a clang-server. It needs compile_commands.json.
2019-04-11 18:25:06 +02:00
(use-package irony
:pin melpa ; 1.3.1 Server does not compile.
2019-04-11 18:25:06 +02:00
:after yasnippet
:hook
(c++-mode . irony-mode)
(c-mode . irony-mode)
(irony-mode . irony-cdb-autosetup-compile-options)
:config
2019-04-13 20:40:34 +02:00
;; If irony server is not installed, install it.
2019-04-11 18:25:06 +02:00
(unless (irony--find-server-executable)
(call-interactively #'irony-install-server)))
;; Eldoc shows argument list of the function you are currently writing.
(use-package irony-eldoc
:after (eldoc irony)
:hook
2019-04-11 18:25:06 +02:00
(irony-mode . irony-eldoc))
2019-04-13 20:40:34 +02:00
;; Syntax checker.
2019-04-11 18:25:06 +02:00
(use-package flycheck-irony
:after (flycheck irony)
:hook
(flycheck-mode-hook . flycheck-irony-setup))
2019-04-11 18:25:06 +02:00
;; Auto-complete integration.
(use-package company-irony
:after (company irony)
:config
(add-to-list 'company-backends 'company-irony))
2019-04-11 18:25:06 +02:00
;; Auto-complete headers
(use-package company-irony-c-headers
:after (company-irony)
:config
(add-to-list 'company-backends 'company-irony-c-headers))
;; cmake integration.
(use-package cmake-ide
2019-04-11 18:25:06 +02:00
:after irony
:custom
(cmake-ide-build-dir "build")
(cmake-ide-cmake-opts "") ; Use the already configured options.
:config
2019-04-11 18:25:06 +02:00
(cmake-ide-setup))
2019-04-11 19:22:37 +02:00
) ; unless slow-computer
;; GUI for gdb and other debuggers.
(use-package realgud
:after cc-mode
:config
2019-05-15 02:59:16 +02:00
(defun my/launch-gdb ()
"Load realgud and launch gdb."
(interactive)
(load-library "realgud")
(realgud:gdb))
:bind
(:map c-mode-base-map
("C-c g" . my/launch-gdb)
2019-05-17 15:28:42 +02:00
("M-<down>" . nil) ; Disabled, because I use them for scrolling.
("M-<up>" . nil))) ; ^ FIXME: Does not work. ^
;;;;;;;;;;;;;;;;;;;; Appearance ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2019-04-02 14:45:01 +02:00
;; Hide toolbar.
(tool-bar-mode -1)
;; Put scrollbar to the right side.
(if (display-graphic-p)
(set-scroll-bar-mode 'right))
2019-03-22 09:03:23 +01:00
;; Icons (required by doom).
(use-package all-the-icons
:config
2019-04-29 14:43:42 +02:00
(unless (file-exists-p "~/.local/share/fonts/all-the-icons.ttf")
(all-the-icons-install-fonts t)))
2019-03-22 09:03:23 +01:00
;; Themes for doom-modeline.
(unless slow-computer
(use-package doom-themes
:after all-the-icons
:custom-face
2019-04-12 03:03:37 +02:00
(font-lock-comment-face ((t (:inherit font-lock-comment-face
:foreground "#667755"))))
:config
(load-theme 'doom-molokai t)
))
2019-03-22 09:03:23 +01:00
;; Neat modeline.
(use-package doom-modeline
:after all-the-icons
2019-03-22 01:57:44 +01:00
:init
2019-03-22 09:03:23 +01:00
(column-number-mode t) ; Show column numbers in modeline.
2019-04-09 02:39:22 +02:00
(size-indication-mode) ; Buffer size display in the modeline.
:config
2019-04-09 02:39:22 +02:00
(setq doom-modeline-minor-modes nil
;; doom-modeline-buffer-file-name-style 'relative-to-project
2019-04-09 02:39:22 +02:00
doom-modeline-buffer-file-name-style 'truncate-except-project)
2019-03-22 09:03:23 +01:00
:hook
(after-init . doom-modeline-mode))
2019-03-22 09:03:23 +01:00
;; Miscellaneous visual improvements.
2019-04-12 19:28:16 +02:00
(add-to-list 'default-frame-alist ; Set default font.
'(font . "Source Code Pro-10"))
2019-03-22 09:03:23 +01:00
(global-hl-line-mode t) ; Highlight current line.
(show-paren-mode t) ; Visualize matching parens.
;; Show line numbers on the left side of the buffer.
2019-03-22 09:03:23 +01:00
(use-package display-line-numbers
:if (>= emacs-major-version 26)
:config
(global-display-line-numbers-mode))
2019-04-09 02:39:22 +02:00
;; Colored man pages.
2019-03-22 09:41:57 +01:00
(use-package man
:defer t
:custom-face
(Man-overstrike ((t (:inherit font-lock-type-face :bold t))))
2019-04-12 03:03:37 +02:00
(Man-underline ((t (:inherit font-lock-keyword-face :underline t)))))
2019-03-22 09:41:57 +01:00
2019-03-19 00:12:11 +01:00
;;;;;;;;;;;;;;;;;;;; Misc ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2019-03-22 09:03:23 +01:00
;; Show directory tree in a window.
2019-03-19 00:12:11 +01:00
(use-package neotree
2019-07-18 01:14:19 +02:00
:pin melpa ; <= 0.5.2 changes directory on file switch.
2019-03-19 00:12:11 +01:00
:demand t
2019-03-20 07:16:58 +01:00
:after all-the-icons
:custom
(neo-smart-open t)
(neo-show-updir-line t) ; Disabled by doom-themes?
(neo-window-width 40)
(neo-show-hidden-files t)
(neo-theme 'icons)
2019-03-19 00:12:11 +01:00
:bind
("<f8>" . neotree-show))
2019-03-19 00:12:11 +01:00
2019-03-22 09:03:23 +01:00
;; Git integration.
2019-07-13 18:46:50 +02:00
(use-package git-commit
:pin melpa)
(unless slow-computer
(use-package magit
2019-07-13 18:46:50 +02:00
:pin melpa
:custom
(magit-diff-refine-hunk 'all) ; Show word-granularity differences.
:config
(defun my/magit-kill-buffers (arg)
"Restore window configuration and kill all Magit buffers."
(interactive)
(let ((buffers (magit-mode-get-buffers)))
(magit-restore-window-configuration)
(mapc #'kill-buffer buffers)))
:bind
("C-x g" . magit-status)
("C-x M-g" . magit-dispatch)
2019-05-10 17:37:22 +02:00
))
2019-03-19 00:12:11 +01:00
2019-07-28 05:58:13 +02:00
;; Completion in many Emacs commands.
(use-package ivy
:custom
(ivy-use-virtual-buffers t)
(ivy-count-format "[%d/%d] ")
2019-03-19 08:24:13 +01:00
:config
2019-07-28 05:58:13 +02:00
(ivy-mode 1)
)
2019-03-19 08:24:13 +01:00
2019-07-28 05:58:13 +02:00
;; Extensions for ivy
(use-package counsel
:bind
("C-x C-f" . 'counsel-find-file)
("M-x" . 'counsel-M-x)
)
;; Nicer interface for ivy
(use-package ivy-rich
:after (all-the-icons counsel)
2019-03-19 00:12:11 +01:00
:config
2019-07-28 05:58:13 +02:00
(defun my/ivy-rich-switch-buffer-icon (candidate)
(with-current-buffer
(get-buffer candidate)
(let ((icon (all-the-icons-icon-for-mode major-mode)))
(if (symbolp icon)
(all-the-icons-icon-for-mode 'fundamental-mode)
icon))))
(setq ivy-rich-display-transformers-list
'(ivy-switch-buffer
(:columns
((my/ivy-rich-switch-buffer-icon :width 2)
(ivy-rich-candidate (:width 30))
(ivy-rich-switch-buffer-size (:width 7))
(ivy-rich-switch-buffer-indicators
(:width 4 :face error :align right))
(ivy-rich-switch-buffer-major-mode (:width 12 :face warning))
(ivy-rich-switch-buffer-project (:width 15 :face success))
(ivy-rich-switch-buffer-path
(:width (lambda (x)
(ivy-rich-switch-buffer-shorten-path
x (ivy-rich-minibuffer-width 0.3))))))
:predicate
(lambda (cand) (get-buffer cand)))))
(ivy-rich-mode 1)
(setcdr (assq t ivy-format-functions-alist) #'ivy-format-function-line)
)
2019-03-19 23:24:39 +01:00
2019-07-28 05:58:13 +02:00
;; Better search.
(use-package swiper
:after ivy
:bind
("C-s" . 'swiper)
)
2019-05-15 00:21:23 +02:00
;; Ruler with fill-column marker.
(use-package ruler-mode
:custom-face
(ruler-mode-default ((t
(:inherit default
:background "gray18"
:foreground "dim gray"
:box nil))))
(ruler-mode-column-number ((t
(:inherit ruler-mode-default
:foreground "dark gray"))))
:hook
(find-file . (lambda () (ruler-mode 1)))
(text-mode . (lambda () (ruler-mode 1))) ; For the scratch buffer.
)
2019-03-19 00:12:11 +01:00
2019-03-22 09:03:23 +01:00
;; Visualize whitespace.
2019-03-19 00:12:11 +01:00
(use-package whitespace
2019-04-12 02:01:34 +02:00
:after company
2019-03-19 00:12:11 +01:00
:config
2019-03-22 09:03:23 +01:00
(delete 'newline-mark whitespace-style) ; Don't paint $ at eol.
2019-07-27 08:31:45 +02:00
;; (delete 'lines whitespace-style) ; Don't mark overly long lines.
2019-04-12 03:03:37 +02:00
;; Workaround to not show dots in popup menus.
2019-04-12 02:01:34 +02:00
(defun my/whitespace-mode-enabled-p ()
(symbol-value 'whitespace-mode))
(defvar-local my/ws-enabled nil)
;; company:
2019-03-22 09:03:23 +01:00
(defun my/on-off-whitespace-before-company(command)
(when (string= "show" command)
2019-04-12 02:01:34 +02:00
(setq-local my/ws-enabled (my/whitespace-mode-enabled-p))
(if my/ws-enabled
(whitespace-mode -1)))
(when (string= "hide" command)
2019-04-12 02:01:34 +02:00
(if my/ws-enabled
(whitespace-mode t))))
(advice-add 'company-call-frontends
2019-03-22 09:03:23 +01:00
:before #'my/on-off-whitespace-before-company)
2019-04-12 02:01:34 +02:00
;; popup:
(defadvice popup-create (before my/popup-suppress-whitespace-mode activate)
"Suspend whitespace-mode while popups are visible."
(setq-local my/ws-enabled (my/whitespace-mode-enabled-p))
(if my/ws-enabled
(whitespace-mode -1)))
(defadvice popup-delete (after my/popup-restore-whitespace-mode activate)
"Restore whitespace-mode when all popups have closed."
(if my/ws-enabled
(whitespace-mode t)))
2019-03-19 00:12:11 +01:00
:bind
("C-x w" . 'whitespace-mode)
:hook
(prog-mode . whitespace-mode)
(conf-mode . whitespace-mode)
2019-04-29 18:39:55 +02:00
(text-mode . whitespace-mode)
:custom-face
2019-07-27 08:31:45 +02:00
(whitespace-space ((nil :foreground "gray18")))
(whitespace-line ((nil :inherit whitespace-line
:weight normal
:foreground nil
:background nil
:distant-foreground "red" ; Make dots red.
;; :box (:line-width 1 :color "dark red")
)))
)
2019-03-19 00:12:11 +01:00
2019-03-22 09:03:23 +01:00
;; Spell checking.
(unless slow-computer
(if (or (executable-find "aspell")
(executable-find "hunspell")
(executable-find "ispell"))
(use-package flyspell
:custom
(ispell-dictionary "english")
:config
(defun my/toggle-flyspell ()
"Toggle flyspell-mode and run flyspell-buffer after activating."
(interactive)
(if (bound-and-true-p flyspell-mode)
(flyspell-mode 0)
(flyspell-mode)
(flyspell-buffer)))
(defun my/flyspell-german ()
"Set dictionary to german."
(interactive)
(ispell-change-dictionary "german"))
:bind
("<f6>" . my/toggle-flyspell)
2019-03-30 17:50:50 +01:00
(:map flyspell-mode-map
("C-;" . nil)) ; iedit needs C-;.
:hook
;; Spellcheck comments.
(prog-mode . flyspell-prog-mode)
;; Spellcheck text documents.
(LaTeX-mode . my/flyspell-german)
(LaTeX-mode . flyspell-mode)
(adoc-mode . flyspell-mode)
(markdown-mode . flyspell-mode)
:mode
("COMMIT_EDITMSG\\'" . flyspell-mode)
2019-05-17 15:28:42 +02:00
)))
2019-03-19 00:12:11 +01:00
; Multiple cursors.
2019-03-19 00:12:11 +01:00
(use-package multiple-cursors
:init
(global-unset-key (kbd "M-<down-mouse-1>"))
:bind
2019-03-20 09:54:12 +01:00
("C-x M-m" . mc/edit-lines)
2019-03-19 00:12:11 +01:00
("M-<mouse-1>" . mc/add-cursor-on-click))
2019-03-22 09:03:23 +01:00
;; If 2 files have the same name, append directory name after the filename.
(use-package uniquify
:ensure nil ; Included in Emacs.
:custom
(uniquify-after-kill-buffer-p t)
(uniquify-buffer-name-style 'post-forward)
(uniquify-strip-common-suffix t))
2019-03-22 09:03:23 +01:00
;; Delete old buffers.
2019-03-22 01:57:44 +01:00
;; https://www.emacswiki.org/emacs/CleanBufferList
(use-package midnight
2019-04-13 20:40:34 +02:00
:defer 10
2019-03-22 01:57:44 +01:00
:init
2019-03-30 12:29:09 +01:00
(setq midnight-delay 30 ; 30 seconds after "midnight"
midnight-period (* 2 60 60)) ; Clean every 2 hours.
2019-03-22 09:03:23 +01:00
:custom
(clean-buffer-list-delay-general 1) ; Clean normal bufs after 1d.
(clean-buffer-list-delay-special (* 30 60)) ; Clean special bufs after 30m.
2019-03-22 01:57:44 +01:00
:config
2019-03-22 09:03:23 +01:00
(setq clean-buffer-list-kill-regexps ; Add these to special buffers.
2019-04-13 20:40:34 +02:00
(nconc clean-buffer-list-kill-regexps
2019-03-22 01:57:44 +01:00
'("\\`magit-?.*:"
"\\.log\\'"
"\\`\\*rdm\\*\\'"
"\\`\\*Backtrace\\*\\'")))
2019-03-22 01:57:44 +01:00
(midnight-mode t))
;; The string Time-stamp: <> in the first 8 lines of the file will be updated
;; with the current timestamp.
(use-package time-stamp
2019-03-22 09:03:23 +01:00
:custom
(time-stamp-format "%:y-%02m-%02dT%02H:%02M:%02S+00:00")
(time-stamp-time-zone t) ; Set to UTC until ISO 8601 is supported.
2019-03-22 01:57:44 +01:00
:hook
(before-save . time-stamp))
2019-03-22 09:03:23 +01:00
;; Edit multiple regions in the same way simultaneously.
(use-package iedit
:bind
("C-;" . iedit-mode))
;; Mode for writing blog posts with hugo.
(if (string= (system-name) "ventiloplattform")
(use-package easy-hugo
:custom
(easy-hugo-basedir "~/Projekte/www/blog.tastytea.de/")
(easy-hugo-url "https://blog.tastytea.de")
2019-05-08 01:42:58 +02:00
(easy-hugo-previewtime "7200") ; 2 hours.
(easy-hugo-postdir "content/posts")
(easy-hugo-default-ext ".adoc")
2019-05-06 01:12:48 +02:00
(easy-hugo-asciidoc-extension "adoc")
(easy-hugo-server-flags "-D")
:bind
2019-05-06 01:12:48 +02:00
("C-x M-h" . easy-hugo)))
2019-04-11 18:25:06 +02:00
;; A template system.
(use-package yasnippet)
2019-03-22 09:03:23 +01:00
;; Automatically insert text in new files.
(use-package autoinsert
2019-04-11 18:25:06 +02:00
:after yasnippet
:init
(defun my/autoinsert-yas-expand()
"Replace text in yasnippet template."
(yas-minor-mode t)
(yas-expand-snippet (buffer-string) (point-min) (point-max)))
:config
(add-to-list 'auto-insert-alist
'(("\\.\\(cpp\\|cc\\|cxx\\|c\\+\\+\\)\\'" . "C++ program") .
["cpp" my/autoinsert-yas-expand]))
(add-to-list 'auto-insert-alist
'(("\\.\\(hpp\\|hh\\|hxx\\|h\\+\\+\\)\\'" . "C++ header") .
2019-03-23 10:44:15 +01:00
["hpp" my/autoinsert-yas-expand]))
(add-to-list 'auto-insert-alist
'(("\\.[1-9]\\.adoc\\'" . "AsciiDoc manpage") .
2019-03-23 20:16:51 +01:00
["manpage.adoc" my/autoinsert-yas-expand]))
2019-06-03 20:39:29 +02:00
(add-to-list 'auto-insert-alist
'(("\\.user.js\\'" . "Userscript") .
["user.js" my/autoinsert-yas-expand]))
:custom
(auto-insert-directory (concat user-emacs-directory "auto-insert"))
2019-03-22 09:03:23 +01:00
(auto-insert-query nil) ; Don't ask before inserting.
:hook
(find-file . auto-insert))
(use-package bs
:bind
("C-x C-b" . bs-show))
;;;;;;;;;;;;;;;;;;;; LaTeX ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(if (executable-find "xetex")
(use-package tex-site
:ensure auctex
:custom
(TeX-parse-self t) ; Enable parse on load.
(TeX-auto-save t) ; Enable parse on save
(TeX-PDF-mode t) ; PDF mode (rather than DVI-mode)
(TeX-engine 'xetex)
;; To use pdf-tools with auctex.
;; https://emacs.stackexchange.com/a/21764/21935
(TeX-view-program-selection '((output-pdf "PDF Tools")))
(TeX-view-program-list '(("PDF Tools" TeX-pdf-tools-sync-view)))
:mode
("\\.tex\\'" . LaTeX-mode)
:config
;; To have the buffer refresh after compilation.
(add-hook 'TeX-after-compilation-finished-functions
#'TeX-revert-document-buffer)))
;; Auto complete for LaTeX.
(use-package company-auctex
2019-03-30 18:15:31 +01:00
:after auctex
:hook
(LaTeX-mode . company-auctex-init))
2019-04-11 18:25:06 +02:00
;;;;;;;;;;;;;;;;;;;; (X)HTML / CSS ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2019-04-12 03:03:37 +02:00
;; Use company auto-completion for (X)HTML.
2019-04-11 18:25:06 +02:00
(use-package company-web
:after company
:config
(add-to-list 'company-backends 'company-web-html))
2019-04-29 15:22:59 +02:00
(use-package web-mode
:mode
("\\.p?html?\\'" . web-mode)
("\\.tmpl\\'" . web-mode) ; Gitea templates
2019-04-30 13:50:29 +02:00
("\\.php\\'" . web-mode)
:hook
(web-mode . my/set-fill-column-100))
2019-04-29 15:22:59 +02:00
2019-04-11 18:25:06 +02:00
;;;;;;;;;;;;;;;;;;;; Other file formats ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(use-package conf-mode
:mode
("\\`/etc/conf\\.d/" . conf-mode) ; Use conf-mode for openrc config files.
("\\`/etc/portage/package\\.use/" . conf-mode)
("\\`/etc/portage/package\\.accept_keywords/" . conf-mode)
)
2019-03-19 00:12:11 +01:00
(use-package adoc-mode
:mode
("\\.adoc\\'" . adoc-mode)
2019-04-10 14:30:43 +02:00
:custom-face
;; Style headers.
(markup-title-0-face ((t (:inherit markup-gen-face :height 1.4))))
(markup-title-1-face ((t (:inherit markup-gen-face :height 1.3))))
(markup-title-2-face ((t (:inherit markup-gen-face :height 1.2))))
2019-04-12 03:03:37 +02:00
(markup-title-3-face ((t (:inherit markup-gen-face :height 1.1
:weight bold))))
(markup-title-4-face ((t (:inherit markup-gen-face :height 1.0
:underline t))))
(markup-title-5-face ((t (:inherit markup-gen-face :height 1.0))))
2019-04-28 22:09:38 +02:00
;; Enlarge meta-data to the same size as the other text.
(markup-meta-face ((t (:inherit font-lock-comment-face))))
(markup-secondary-text-face ((t (:inherit markup-gen-face :height 1.0
:foreground "firebrick"))))
(markup-hide-delimiter-face ((t (:inherit markup-meta-face))))
(markup-meta-hide-face ((t (:inherit markup-meta-face))))
;; Style code snippets (``)
(markup-verbatim-face ((t (:background "gray5"))))
:hook
(adoc-mode . auto-fill-mode) ; Wrap at fill-column.
(adoc-mode . my/set-fill-column-80)
(adoc-mode . (lambda () ; Automatically update date.
(setq-local time-stamp-pattern
2019-06-03 20:39:48 +02:00
"8/:[dD[aA][tT][eE]: +%:y-%02m-%02d\n")
(setq-local time-stamp-time-zone nil)))
)
2019-03-19 00:12:11 +01:00
(use-package markdown-mode
2019-03-22 09:03:23 +01:00
:custom
(markdown-command "cmark")
2019-04-10 14:30:43 +02:00
:custom-face
;; Style headers.
2019-04-12 03:03:37 +02:00
(markdown-header-face-1 ((t (:inherit markdown-header-face :height 1.4
:weight normal))))
(markdown-header-face-2 ((t (:inherit markdown-header-face :height 1.3
:weight normal))))
(markdown-header-face-3 ((t (:inherit markdown-header-face :height 1.2
:weight normal))))
(markdown-header-face-4 ((t (:inherit markdown-header-face :height 1.1
:weight bold))))
(markdown-header-face-5 ((t (:inherit markdown-header-face :height 1.0
:weight normal :underline t))))
(markdown-header-face-6 ((t (:inherit markdown-header-face :height 1.0
:weight normal))))
(markdown-header-face-7 ((t (:inherit markdown-header-face :height 1.0
:weight normal))))
:mode
(("README\\.md\\'" . gfm-mode)
("\\.md\\'" . markdown-mode)
("\\.markdown\\'" . markdown-mode))
:hook
(markdown-mode . my/set-fill-column-80)
(markdown-mode . auto-fill-mode)) ; Wrap at fill-column.
2019-03-19 00:12:11 +01:00
(use-package crontab-mode
2019-07-19 04:29:42 +02:00
:custom-face
(outline-1 ((t (:inherit outline-1 ; Shrink minutes to normal size.
:height 1.0))))
:mode
2019-03-30 18:45:24 +01:00
("/cron\\.d/" . crontab-mode)
2019-07-14 18:47:12 +02:00
("\\`'/etc/crontab\\'" . crontab-mode)
:hook
(crontab-mode . (lambda () (auto-fill-mode -1)))
)
2019-03-19 00:12:11 +01:00
2019-03-19 00:28:35 +01:00
(use-package nginx-mode
:defer t)
(use-package company-nginx
:after nginx-mode
:hook
(nginx-mode . company-nginx-keywords))
2019-03-19 00:28:35 +01:00
2019-03-30 18:45:24 +01:00
;; View PDF files.
(use-package pdf-tools
:custom
(pdf-misc-print-programm "/usr/bin/lpr")
2019-03-30 18:45:24 +01:00
:mode
("\\.pdf\\'" . pdf-tools-install))
(use-package yaml-mode
:mode
("\\.yml\\'" . yaml-mode)
:hook
(yaml-mode . my/set-fill-column-80))
(use-package mediawiki)
2019-07-16 00:55:43 +02:00
(use-package csv-mode
:mode
("\\.[Cc][Ss][Vv]\\'" . csv-mode)
)
2019-03-19 00:12:11 +01:00
;;;;;;;;;;;;;;;;;;;; Server / Remote editing ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2019-03-22 09:03:23 +01:00
;; Edit remote files.
(unless slow-computer
(use-package tramp
2019-04-30 13:38:56 +02:00
:custom
(tramp-use-ssh-controlmaster-options nil) ; Don't override SSH config.
(tramp-default-method "ssh") ; ssh is faster than scp and supports ports.
(tramp-password-prompt-regexp ; Add verification code support.
(concat
"^.*"
(regexp-opt
'("passphrase" "Passphrase"
"password" "Password"
"Verification code")
t)
".*:\0? *"))
2019-04-30 13:38:56 +02:00
:config
;; Respect remote PATH.
(add-to-list 'tramp-remote-path 'tramp-own-remote-path)))
2019-03-19 00:12:11 +01:00
;; Run server if:
2019-03-22 09:03:23 +01:00
;; - Our EUID is not 0,
;; - We are not logged in via SSH,
;; - It is not already running.
2019-03-19 00:12:11 +01:00
(unless (equal (user-real-uid) 0)
(unless (getenv "SSH_CONNECTION")
(use-package server
2019-03-23 20:16:51 +01:00
:defer 5
2019-03-19 00:12:11 +01:00
:init
(setq server-use-tcp t
server-port 51313
2019-03-22 09:03:23 +01:00
server-auth-key ; 64 chars, saved in ~/.emacs.d/server/server.
2019-03-19 00:12:11 +01:00
"phahw2ohVoh0oopheish7IVie9desh8aequeenei3uo8wahShe%thuadaeNa4ieh")
:config
2019-05-08 01:42:58 +02:00
(unless (eq (server-running-p) t) ; Run server if not t.
(server-start)))
;; Server for Firefox-extension that allows to use Emacs to edit textareas.
;; https://addons.mozilla.org/de/firefox/addon/edit-with-emacs1/
(use-package edit-server
:config
(edit-server-start)
:custom
(edit-server-url-major-mode-alist
2019-05-22 16:06:57 +02:00
'(
("\\`likeable\\.space/" . markdown-mode)
("\\`schlomp\\.space/" . markdown-mode)
2019-05-05 17:12:28 +02:00
("\\`wiki\\.gentoo\\.org/" . mediawiki-mode)
2019-05-22 16:06:57 +02:00
("\\`github\\.com/" . markdown-mode)
)))
))
2019-03-19 00:12:11 +01:00
2019-03-22 09:03:23 +01:00
;; Set garbage collection threshold to original value.
(setq gc-cons-threshold (car (get 'gc-cons-threshold 'standard-value)))
2019-03-19 00:55:01 +01:00
(provide 'init)
;;; init.el ends here