2017-06-08 11:47:56 +02:00
|
|
|
;;; core-editor.el -*- lexical-binding: t; -*-
|
2017-01-16 23:15:48 -05:00
|
|
|
|
2018-10-03 15:10:08 -04:00
|
|
|
(defvar doom-large-file-size 2
|
2017-05-06 22:55:10 +02:00
|
|
|
"Size (in MB) above which the user will be prompted to open the file literally
|
|
|
|
to avoid performance issues. Opening literally means that no major or minor
|
|
|
|
modes are active and the buffer is read-only.")
|
2017-05-06 11:53:10 -04:00
|
|
|
|
2017-05-06 22:55:10 +02:00
|
|
|
(defvar doom-large-file-modes-list
|
2018-05-26 03:06:22 +02:00
|
|
|
'(fundamental-mode special-mode archive-mode tar-mode jka-compr
|
|
|
|
git-commit-mode image-mode doc-view-mode doc-view-mode-maybe
|
2018-10-03 15:08:25 -04:00
|
|
|
ebrowse-tree-mode pdf-view-mode tags-table-mode)
|
2017-05-06 22:55:10 +02:00
|
|
|
"Major modes that `doom|check-large-file' will ignore.")
|
2017-05-06 11:53:10 -04:00
|
|
|
|
2018-05-18 01:28:40 +02:00
|
|
|
(defvar-local doom-inhibit-indent-detection nil
|
|
|
|
"A buffer-local flag that indicates whether `dtrt-indent' should try to detect
|
|
|
|
indentation settings or not. This should be set by editorconfig if it
|
|
|
|
successfully sets indent_style/indent_size.")
|
|
|
|
|
2018-07-29 02:54:19 +02:00
|
|
|
(defvar doom-detect-indentation-excluded-modes '(fundamental-mode)
|
|
|
|
"A list of major modes in which indentation should be automatically
|
|
|
|
detected.")
|
|
|
|
|
2017-02-19 18:11:28 -05:00
|
|
|
(setq-default
|
2019-03-02 01:12:48 -05:00
|
|
|
large-file-warning-threshold 15000000
|
2017-06-16 02:06:21 +02:00
|
|
|
vc-follow-symlinks t
|
2017-02-19 18:11:28 -05:00
|
|
|
;; Save clipboard contents into kill-ring before replacing them
|
|
|
|
save-interprogram-paste-before-kill t
|
|
|
|
;; Bookmarks
|
2017-11-04 22:34:55 +01:00
|
|
|
bookmark-default-file (concat doom-etc-dir "bookmarks")
|
2017-02-19 18:11:28 -05:00
|
|
|
bookmark-save-flag t
|
|
|
|
;; Formatting
|
|
|
|
delete-trailing-lines nil
|
|
|
|
fill-column 80
|
|
|
|
sentence-end-double-space nil
|
2017-06-05 23:00:50 +02:00
|
|
|
word-wrap t
|
2017-02-19 18:11:28 -05:00
|
|
|
;; Scrolling
|
2018-06-30 02:46:09 +02:00
|
|
|
hscroll-margin 2
|
2017-02-19 18:11:28 -05:00
|
|
|
hscroll-step 1
|
|
|
|
scroll-conservatively 1001
|
2019-03-09 02:43:07 -05:00
|
|
|
scroll-margin 2
|
2017-02-19 18:11:28 -05:00
|
|
|
scroll-preserve-screen-position t
|
|
|
|
;; Whitespace (see `editorconfig')
|
|
|
|
indent-tabs-mode nil
|
|
|
|
require-final-newline t
|
|
|
|
tab-always-indent t
|
|
|
|
tab-width 4
|
2017-06-16 02:06:21 +02:00
|
|
|
tabify-regexp "^\t* [ \t]+" ; for :retab
|
2017-02-19 18:11:28 -05:00
|
|
|
;; Wrapping
|
|
|
|
truncate-lines t
|
2018-05-08 23:21:17 +02:00
|
|
|
truncate-partial-width-windows 50)
|
2017-06-16 02:06:21 +02:00
|
|
|
|
2018-06-30 02:49:52 +02:00
|
|
|
;; Remove hscroll-margin in shells, otherwise it causes jumpiness
|
|
|
|
(setq-hook! '(eshell-mode-hook term-mode-hook) hscroll-margin 0)
|
|
|
|
|
2019-03-02 01:12:48 -05:00
|
|
|
(defun doom*optimize-literal-mode-for-large-files (buffer)
|
|
|
|
(with-current-buffer buffer
|
|
|
|
(when find-file-literally
|
|
|
|
(setq buffer-read-only t)
|
|
|
|
(buffer-disable-undo))
|
|
|
|
buffer))
|
|
|
|
(advice-add #'find-file-noselect-1 :filter-return #'doom*optimize-literal-mode-for-large-files)
|
2017-05-06 11:53:10 -04:00
|
|
|
|
2017-01-16 23:15:48 -05:00
|
|
|
|
2017-06-05 23:00:50 +02:00
|
|
|
;;
|
2019-02-18 00:09:57 -05:00
|
|
|
;; Extra file extensions to support
|
2017-06-05 23:00:50 +02:00
|
|
|
|
2018-05-24 19:12:36 +02:00
|
|
|
(push '("/LICENSE\\'" . text-mode) auto-mode-alist)
|
2018-05-17 15:29:54 +02:00
|
|
|
|
2019-02-18 00:09:57 -05:00
|
|
|
|
|
|
|
;;
|
|
|
|
;; Built-in plugins
|
2018-05-14 18:40:35 +02:00
|
|
|
|
2018-09-20 10:41:19 -04:00
|
|
|
(def-package! server
|
|
|
|
:when (display-graphic-p)
|
|
|
|
:after-call (pre-command-hook after-find-file)
|
|
|
|
:config
|
|
|
|
(when-let* ((name (getenv "EMACS_SERVER_NAME")))
|
|
|
|
(setq server-name name))
|
|
|
|
(unless (server-running-p)
|
|
|
|
(server-start)))
|
|
|
|
|
2018-05-14 18:40:35 +02:00
|
|
|
(def-package! autorevert
|
2018-09-07 21:43:32 -04:00
|
|
|
;; revert buffers for changed files
|
2018-06-14 00:08:16 +02:00
|
|
|
:after-call after-find-file
|
2018-05-14 18:40:35 +02:00
|
|
|
:config
|
|
|
|
(setq auto-revert-verbose nil)
|
|
|
|
(global-auto-revert-mode +1))
|
|
|
|
|
|
|
|
(def-package! savehist
|
2018-09-07 21:43:32 -04:00
|
|
|
;; persist variables across sessions
|
2018-12-23 00:25:51 -05:00
|
|
|
:defer-incrementally (custom)
|
2018-05-20 20:07:15 +02:00
|
|
|
:after-call post-command-hook
|
2018-05-14 18:40:35 +02:00
|
|
|
:config
|
|
|
|
(setq savehist-file (concat doom-cache-dir "savehist")
|
|
|
|
savehist-save-minibuffer-history t
|
|
|
|
savehist-autosave-interval nil ; save on kill only
|
|
|
|
savehist-additional-variables '(kill-ring search-ring regexp-search-ring))
|
2018-07-28 01:30:23 +02:00
|
|
|
(savehist-mode +1)
|
|
|
|
|
|
|
|
(defun doom|unpropertize-kill-ring ()
|
|
|
|
"Remove text properties from `kill-ring' in the interest of shrinking the
|
|
|
|
savehist file."
|
2018-08-11 02:05:33 +02:00
|
|
|
(setq kill-ring (cl-loop for item in kill-ring
|
|
|
|
if (stringp item)
|
|
|
|
collect (substring-no-properties item)
|
|
|
|
else if item collect it)))
|
2018-07-28 01:30:23 +02:00
|
|
|
(add-hook 'kill-emacs-hook #'doom|unpropertize-kill-ring))
|
2018-05-14 18:40:35 +02:00
|
|
|
|
|
|
|
(def-package! saveplace
|
2018-09-07 21:43:32 -04:00
|
|
|
;; persistent point location in buffers
|
2018-06-14 00:08:16 +02:00
|
|
|
:after-call (after-find-file dired-initial-position-hook)
|
2018-05-14 18:40:35 +02:00
|
|
|
:config
|
|
|
|
(setq save-place-file (concat doom-cache-dir "saveplace"))
|
|
|
|
(defun doom*recenter-on-load-saveplace (&rest _)
|
|
|
|
"Recenter on cursor when loading a saved place."
|
|
|
|
(if buffer-file-name (ignore-errors (recenter))))
|
|
|
|
(advice-add #'save-place-find-file-hook
|
|
|
|
:after-while #'doom*recenter-on-load-saveplace)
|
|
|
|
(save-place-mode +1))
|
2017-06-05 23:00:50 +02:00
|
|
|
|
|
|
|
(def-package! recentf
|
2018-09-07 21:43:32 -04:00
|
|
|
;; Keep track of recently opened files
|
2018-12-23 00:25:51 -05:00
|
|
|
:defer-incrementally (easymenu tree-widget timer)
|
2018-06-14 00:08:16 +02:00
|
|
|
:after-call after-find-file
|
2018-05-14 18:40:35 +02:00
|
|
|
:commands recentf-open-files
|
2017-06-05 23:00:50 +02:00
|
|
|
:config
|
2017-12-23 14:30:36 -05:00
|
|
|
(setq recentf-save-file (concat doom-cache-dir "recentf")
|
2018-07-29 19:29:05 +02:00
|
|
|
recentf-auto-cleanup 'never
|
2017-06-05 23:00:50 +02:00
|
|
|
recentf-max-menu-items 0
|
2017-06-11 23:50:50 +02:00
|
|
|
recentf-max-saved-items 300
|
2018-09-21 22:43:52 -04:00
|
|
|
recentf-filename-handlers '(file-truename abbreviate-file-name)
|
2017-06-11 23:50:50 +02:00
|
|
|
recentf-exclude
|
2018-05-20 20:07:46 +02:00
|
|
|
(list #'file-remote-p "\\.\\(?:gz\\|gif\\|svg\\|png\\|jpe?g\\)$"
|
2018-03-14 18:28:48 -04:00
|
|
|
"^/tmp/" "^/ssh:" "\\.?ido\\.last$" "\\.revive$" "/TAGS$"
|
2017-06-11 23:50:50 +02:00
|
|
|
"^/var/folders/.+$"
|
|
|
|
;; ignore private DOOM temp files (but not all of them)
|
2018-05-20 20:07:46 +02:00
|
|
|
(lambda (file) (file-in-directory-p file doom-local-dir))))
|
2018-08-03 16:16:01 +02:00
|
|
|
(unless noninteractive
|
|
|
|
(add-hook 'kill-emacs-hook #'recentf-cleanup)
|
|
|
|
(quiet! (recentf-mode +1))))
|
2018-05-14 18:40:35 +02:00
|
|
|
|
2017-06-05 23:00:50 +02:00
|
|
|
|
2017-01-16 23:15:48 -05:00
|
|
|
;;
|
2018-09-07 19:36:16 -04:00
|
|
|
;; Packages
|
2017-01-16 23:15:48 -05:00
|
|
|
|
2017-06-05 23:00:50 +02:00
|
|
|
(def-package! smartparens
|
2018-09-07 21:43:32 -04:00
|
|
|
;; Auto-close delimiters and blocks as you type. It's more powerful than that,
|
|
|
|
;; but that is all Doom uses it for.
|
2019-03-07 00:26:51 -05:00
|
|
|
:after-call (doom-switch-buffer-hook after-find-file)
|
2019-01-05 15:21:27 -05:00
|
|
|
:commands (sp-pair sp-local-pair sp-with-modes sp-point-in-comment sp-point-in-string)
|
2017-07-26 18:49:08 +02:00
|
|
|
:config
|
2017-12-08 22:33:12 -05:00
|
|
|
(require 'smartparens-config)
|
2018-05-02 15:53:51 +02:00
|
|
|
(setq sp-highlight-pair-overlay nil
|
2018-06-17 02:12:14 +02:00
|
|
|
sp-highlight-wrap-overlay nil
|
|
|
|
sp-highlight-wrap-tag-overlay nil
|
|
|
|
sp-show-pair-from-inside t
|
2017-01-16 23:15:48 -05:00
|
|
|
sp-cancel-autoskip-on-backward-movement nil
|
2018-06-17 02:12:14 +02:00
|
|
|
sp-show-pair-delay 0.1
|
2018-06-24 15:08:00 +02:00
|
|
|
sp-max-pair-length 4
|
2018-06-28 14:44:47 +02:00
|
|
|
sp-max-prefix-length 50
|
|
|
|
sp-escape-quotes-after-insert nil) ; not smart enough
|
2015-06-06 06:40:33 -04:00
|
|
|
|
2018-07-24 20:08:11 +02:00
|
|
|
;; Smartparens' navigation feature is neat, but does not justify how expensive
|
|
|
|
;; it is. It's also less useful for evil users. This may need to be
|
|
|
|
;; reactivated for non-evil users though. Needs more testing!
|
2018-06-24 15:08:00 +02:00
|
|
|
(defun doom|disable-smartparens-navigate-skip-match ()
|
|
|
|
(setq sp-navigate-skip-match nil
|
|
|
|
sp-navigate-consider-sgml-tags nil))
|
|
|
|
(add-hook 'after-change-major-mode-hook #'doom|disable-smartparens-navigate-skip-match)
|
2018-06-23 23:21:02 +02:00
|
|
|
|
2018-06-25 15:54:38 +02:00
|
|
|
;; autopairing in `eval-expression' and `evil-ex'
|
2018-06-16 11:41:07 +02:00
|
|
|
(defun doom|init-smartparens-in-eval-expression ()
|
2018-06-16 12:40:57 +02:00
|
|
|
"Enable `smartparens-mode' in the minibuffer, during `eval-expression' or
|
|
|
|
`evil-ex'."
|
|
|
|
(when (memq this-command '(eval-expression evil-ex))
|
2018-06-16 11:41:07 +02:00
|
|
|
(smartparens-mode)))
|
|
|
|
(add-hook 'minibuffer-setup-hook #'doom|init-smartparens-in-eval-expression)
|
2018-06-16 12:40:57 +02:00
|
|
|
(sp-local-pair 'minibuffer-inactive-mode "'" nil :actions nil)
|
2018-06-24 15:08:00 +02:00
|
|
|
|
2018-07-24 20:08:11 +02:00
|
|
|
;; smartparens breaks evil-mode's replace state
|
2018-06-25 15:54:38 +02:00
|
|
|
(add-hook 'evil-replace-state-entry-hook #'turn-off-smartparens-mode)
|
|
|
|
(add-hook 'evil-replace-state-exit-hook #'turn-on-smartparens-mode)
|
2018-06-24 14:52:57 +02:00
|
|
|
|
2018-05-14 18:40:35 +02:00
|
|
|
(smartparens-global-mode +1))
|
2016-03-23 11:59:06 -04:00
|
|
|
|
2018-09-07 21:43:32 -04:00
|
|
|
|
2018-07-29 02:54:19 +02:00
|
|
|
(def-package! dtrt-indent
|
2018-09-07 21:43:32 -04:00
|
|
|
;; Automatic detection of indent settings
|
2018-07-29 02:54:19 +02:00
|
|
|
:unless noninteractive
|
|
|
|
:defer t
|
|
|
|
:init
|
|
|
|
(defun doom|detect-indentation ()
|
|
|
|
(unless (or (not after-init-time)
|
|
|
|
doom-inhibit-indent-detection
|
|
|
|
(member (substring (buffer-name) 0 1) '(" " "*"))
|
|
|
|
(memq major-mode doom-detect-indentation-excluded-modes))
|
|
|
|
(dtrt-indent-mode +1)))
|
|
|
|
(add-hook! '(change-major-mode-after-body-hook read-only-mode-hook)
|
|
|
|
#'doom|detect-indentation)
|
|
|
|
:config
|
|
|
|
(setq dtrt-indent-verbosity (if doom-debug-mode 2 0))
|
2018-09-07 21:43:32 -04:00
|
|
|
;; always keep tab-width up-to-date
|
|
|
|
(push '(t tab-width) dtrt-indent-hook-generic-mapping-list)
|
|
|
|
|
|
|
|
(defvar dtrt-indent-run-after-smie)
|
2018-08-30 22:39:03 +02:00
|
|
|
(defun doom*fix-broken-smie-modes (orig-fn arg)
|
|
|
|
"Some smie modes throw errors when trying to guess their indentation, like
|
|
|
|
`nim-mode'. This prevents them from leaving Emacs in a broken state."
|
|
|
|
(let ((dtrt-indent-run-after-smie dtrt-indent-run-after-smie))
|
|
|
|
(cl-letf* ((old-smie-config-guess (symbol-function 'smie-config-guess))
|
|
|
|
((symbol-function 'smie-config-guess)
|
|
|
|
(lambda ()
|
|
|
|
(condition-case e (funcall old-smie-config-guess)
|
|
|
|
(error (setq dtrt-indent-run-after-smie t)
|
|
|
|
(message "[WARNING] Indent detection: %s"
|
|
|
|
(error-message-string e))
|
|
|
|
(message "")))))) ; warn silently
|
|
|
|
(funcall orig-fn arg))))
|
|
|
|
(advice-add #'dtrt-indent-mode :around #'doom*fix-broken-smie-modes))
|
2018-07-29 02:54:19 +02:00
|
|
|
|
2018-09-07 21:43:32 -04:00
|
|
|
|
2019-03-07 00:26:51 -05:00
|
|
|
(def-package! undo-tree
|
2018-09-07 21:43:32 -04:00
|
|
|
;; Branching & persistent undo
|
2019-03-07 00:26:51 -05:00
|
|
|
:after-call (doom-switch-buffer-hook after-find-file)
|
2017-06-05 03:15:21 +02:00
|
|
|
:config
|
2018-08-03 18:25:24 +02:00
|
|
|
(setq undo-tree-auto-save-history t
|
|
|
|
;; undo-in-region is known to cause undo history corruption, which can
|
|
|
|
;; be very destructive! Disabling it deters the error, but does not fix
|
|
|
|
;; it entirely!
|
2018-07-28 01:04:49 +02:00
|
|
|
undo-tree-enable-undo-in-region nil
|
2017-06-16 02:06:21 +02:00
|
|
|
undo-tree-history-directory-alist
|
2018-08-03 18:25:24 +02:00
|
|
|
`(("." . ,(concat doom-cache-dir "undo-tree-hist/"))))
|
2018-08-03 18:34:51 +02:00
|
|
|
(global-undo-tree-mode +1)
|
|
|
|
|
2019-04-08 23:02:50 -04:00
|
|
|
;; compress undo history with xz/gzip
|
2019-03-28 01:53:15 -04:00
|
|
|
(and (fset 'doom*undo-tree-make-history-save-file-name
|
|
|
|
(cond ((executable-find "zstd") (lambda (file) (concat file ".zst")))
|
|
|
|
((executable-find "gzip") (lambda (file) (concat file ".gz")))))
|
|
|
|
(advice-add #'undo-tree-make-history-save-file-name :filter-return
|
|
|
|
#'doom*undo-tree-make-history-save-file-name))
|
2018-08-07 03:14:28 +02:00
|
|
|
|
2018-08-28 13:36:44 +02:00
|
|
|
(defun doom*strip-text-properties-from-undo-history (&rest _)
|
2018-08-03 18:34:51 +02:00
|
|
|
(dolist (item buffer-undo-list)
|
|
|
|
(and (consp item)
|
|
|
|
(stringp (car item))
|
2018-08-07 03:27:24 +02:00
|
|
|
(setcar item (substring-no-properties (car item))))))
|
2019-03-28 01:53:15 -04:00
|
|
|
(advice-add #'undo-list-transfer-to-tree :before #'doom*strip-text-properties-from-undo-history))
|
2017-06-05 03:15:21 +02:00
|
|
|
|
2016-03-03 15:04:14 -05:00
|
|
|
|
2018-09-28 11:49:51 -04:00
|
|
|
(def-package! command-log-mode
|
|
|
|
:commands global-command-log-mode
|
|
|
|
:config
|
|
|
|
(setq command-log-mode-auto-show t
|
|
|
|
command-log-mode-open-log-turns-on-mode nil
|
|
|
|
command-log-mode-is-global t))
|
2018-08-08 23:22:37 +02:00
|
|
|
|
2018-09-07 21:43:32 -04:00
|
|
|
|
2018-08-17 03:37:07 +02:00
|
|
|
;; `helpful' --- a better *help* buffer
|
2019-03-02 01:12:48 -05:00
|
|
|
(def-package! helpful
|
2019-03-13 06:44:39 +10:00
|
|
|
:commands helpful--read-symbol
|
2019-03-02 01:12:48 -05:00
|
|
|
:init
|
2019-03-07 23:21:58 -05:00
|
|
|
(define-key!
|
|
|
|
[remap describe-function] #'helpful-callable
|
|
|
|
[remap describe-command] #'helpful-command
|
|
|
|
[remap describe-variable] #'helpful-variable
|
2019-03-12 14:21:41 +10:00
|
|
|
[remap describe-key] #'helpful-key
|
|
|
|
[remap describe-symbol] #'doom/describe-symbol)
|
|
|
|
|
|
|
|
(after! apropos
|
|
|
|
;; patch apropos buttons to call helpful instead of help
|
|
|
|
(dolist (fun-bt '(apropos-function apropos-macro apropos-command))
|
|
|
|
(button-type-put
|
|
|
|
fun-bt 'action
|
|
|
|
(lambda (button)
|
|
|
|
(helpful-callable (button-get button 'apropos-symbol)))))
|
|
|
|
(dolist (var-bt '(apropos-variable apropos-user-option))
|
|
|
|
(button-type-put
|
|
|
|
var-bt 'action
|
|
|
|
(lambda (button)
|
|
|
|
(helpful-variable (button-get button 'apropos-symbol)))))))
|
2017-01-16 23:15:48 -05:00
|
|
|
|
2018-09-07 21:43:32 -04:00
|
|
|
|
2018-08-31 13:56:50 +02:00
|
|
|
(def-package! ws-butler
|
2018-09-07 21:43:32 -04:00
|
|
|
;; a less intrusive `delete-trailing-whitespaces' on save
|
2018-10-06 00:27:52 -04:00
|
|
|
:after-call (after-find-file)
|
2018-08-31 13:56:50 +02:00
|
|
|
:config
|
2018-09-02 17:18:31 +02:00
|
|
|
(setq ws-butler-global-exempt-modes
|
|
|
|
(append ws-butler-global-exempt-modes
|
|
|
|
'(special-mode comint-mode term-mode eshell-mode)))
|
2018-08-31 13:56:50 +02:00
|
|
|
(ws-butler-global-mode))
|
|
|
|
|
2015-06-04 18:23:21 -04:00
|
|
|
(provide 'core-editor)
|
|
|
|
;;; core-editor.el ends here
|