First commit.

This commit is contained in:
2022-01-09 21:19:46 +01:00
commit df36844dcc
107 changed files with 6565 additions and 0 deletions

44
lisp/ux/backups.el Normal file
View File

@@ -0,0 +1,44 @@
;;; backups.el --- Emacs backup system -*- lexical-binding: t; -*-
;;; Commentary:
;;; Code:
;; Set up the backups directory.
(defconst *user-backup-directory* (path-join *user-cache-directory* "backups"))
;; Set up the autosaves directory.
(defconst *user-auto-save-directory* (path-join *user-cache-directory* "auto-saves"))
;; Emacs will create the backup dir automatically, but not the autosaves dir.
(make-directory *user-auto-save-directory* t)
(defun user--backups-config ()
"Initialize Emacs backup system."
(validate-setq
;; Put backups in the cache directory
backup-directory-alist `((".*" . ,*user-backup-directory*))
;; Version-control backup files
version-control t
;; Keep 16 new versions and 2 old versions
kept-new-versions 6
kept-old-versions 2
;; Delete old versions without asking
delete-old-versions t
;; Always backup by copy
backup-by-copying t)
(validate-setq
;; Auto-save every minute or 300 events
auto-save-interval 300
auto-save-timeout 60
;; Always auto-save buffers.
auto-save-default t
;; Put autosave files (ie #foo#) and backup files (ie foo~) into a cache dir.
auto-save-file-name-transforms `((".*" ,(concat *user-auto-save-directory* "/\\1") t))
;; Put session backups into the cache directory.
auto-save-list-file-prefix (path-join *user-auto-save-directory* ".saves-")))
(user--backups-config)
(provide 'ux/backups)
;;; backups.el ends here

55
lisp/ux/buffers.el Normal file
View File

@@ -0,0 +1,55 @@
;;; buffers.el --- Configure Emacs buffers -*- lexical-binding: t; -*-
;;; Commentary:
;;; Code:
(defun user/kill-matching-buffers (regexp &optional exclude-p)
"Kill buffers whose name match the specified REGEXP but not EXCLUDE-P."
(interactive "sKill buffers matching this regular expression: \nP")
(dolist (buffer (buffer-list))
(let ((name (buffer-name buffer)))
(when (and name (not (string-equal name ""))
(/= (aref name 0) ?\s)
(string-match regexp name))
(unless (and exclude-p (funcall exclude-p buffer))
(kill-buffer buffer))))))
(defun user/kill-all-buffers ()
"Close all open buffers."
(interactive)
(mapc 'kill-buffer (buffer-list))
(switch-to-buffer "*scratch*"))
(defun user/kill-other-buffers ()
"Close all open buffers except current one."
(interactive)
(mapc 'kill-buffer (delq (current-buffer) (buffer-list))))
(defun user--buffers-config ()
"Initialize Emacs buffers.
;; The library uniquify overrides Emacs default mechanism for making buffer names unique"
(use-package uniquify
:ensure nil
:config
(validate-setq
;; Set up uniquify's style.
uniquify-buffer-name-style 'reverse
uniquify-separator ""
uniquify-after-kill-buffer-p t
uniquify-ignore-buffers-re "^\\*"))
;;; (Bindings) ;;;
(user/bind-key-global :basic :open-file 'find-file)
(user/bind-key-global :basic :open-buffer 'switch-to-buffer)
(user/bind-key-global :basic :save 'save-buffer)
(user/bind-key-global :basic :save-as 'write-file)
(user/bind-key-global :basic :close 'kill-buffer)
(user/bind-key-global :basic :quit 'save-buffers-kill-terminal))
(user--buffers-config)
(provide 'ux/buffers)
;;; buffers.el ends here

15
lisp/ux/cache.el Normal file
View File

@@ -0,0 +1,15 @@
;;; cache.el --- Configure Emacs persistent caches -*- lexical-binding: t; -*-
;;; Commentary:
;;; Code:
;; https://github.com/sigma/pcache
;; Persistent caching for Emacs
(use-package pcache
:pin "MELPA"
:init
(setq-default
pcache-directory (path-join *user-cache-directory* "pcache")))
(provide 'ux/cache)
;;; cache.el ends here

29
lisp/ux/coding.el Normal file
View File

@@ -0,0 +1,29 @@
;;; coding.el --- Coding system configuration -*- lexical-binding: t; -*-
;;; Commentary:
;;; Code:
(defun user--coding-config ()
"Initialize coding system."
;; Prefer UTF-8 if there is a choice
(prefer-coding-system 'utf-8)
(when (eq default-terminal-coding-system 'utf-8)
;; Set coding systems to UTF-8
(set-default-coding-systems 'utf-8)
(set-terminal-coding-system 'utf-8)
(set-keyboard-coding-system 'utf-8)
(when (eq window-system 'x)
;; Treat X11 clipboard input as UTF-8 string first; compound text next,
;; etc.
(validate-setq
x-select-request-type '(UTF8_STRING COMPOUND_TEXT TEXT STRING))))
;;; (Bindings) ;;;
(user/bind-key-global :emacs :describe-coding 'describe-coding-system)
(user/bind-key-global :emacs :describe-char 'describe-char)
(user/bind-key-global :emacs :describe-language 'describe-language-environment))
(user--coding-config)
(provide 'ux/coding)
;;; coding.el ends here

281
lisp/ux/completion.el Normal file
View File

@@ -0,0 +1,281 @@
;;; completion.el --- Configures automatic code completion -*- lexical-binding: t; -*-
;;; Commentary:
;;; Code:
(eval-when-compile
(require 'cl))
(defun user--company-mode-hook ()
"Company mode hook."
(message "user--company-mode-hook")
(when (derived-mode-p 'prog-mode)
(define-key (current-local-map) (user/get-key :code :complete) 'company-indent-or-complete-common))
;; ;; (user/complete-at-point-install)
;; ;;; (Bindings) ;;;
;; ;; (when (current-local-map)
;; ;; (define-key (current-local-map) (user/get-key :code :auto-complete) 'company-complete))
;; (when (current-local-map)
;; (define-key (current-local-map) (user/get-key :code :complete) 'company-complete))
;; (when (current-local-map)
;; (define-key (current-local-map) (user/get-key :code :complete) 'company-indent-or-complete-common))
)
(defun user/company-mode-p ()
"True if auto-complete should be used."
(and (boundp 'global-company-mode)
global-company-mode))
;; (defun user/complete-at-point-install ()
;; "Install completion backend in complete-at-point."
;; (setq
;; ;; Insert completion backend into `completion-at-point'.
;; completion-at-point-functions
;; (cons 'user/complete-at-point
;; (remove 'user/complete-at-point completion-at-point-functions))))
;; (defun user/company-check-expansion ()
;; "Check if expression can be expanded by company."
;; (save-excursion
;; (if (looking-at "\\_>") t
;; (backward-char 1)
;; (if (looking-at "\\.") t
;; (backward-char 1)
;; (if (looking-at "->") t nil)))))
;; (defun user/complete-at-point ()
;; "Complete thing at point using completion backend."
;; (cond
;; ((minibufferp) (minibuffer-complete))
;; ;; ((and (boundp 'auto-complete-mode) auto-complete-mode) #'auto-complete)
;; ((and (boundp 'company-mode) company-mode (user/company-check-expansion)) #'company-complete-common)
;; (t #'indent-for-tab-command)))
;; (defun ac-pcomplete ()
;; "Auto-complete source for pcomplete."
;; ;; eshell uses `insert-and-inherit' to insert a \t if no completion
;; ;; can be found, but this must not happen as auto-complete source
;; (cl-flet ((insert-and-inherit (&rest args)))
;; ;; this code is stolen from `pcomplete' in pcomplete.el
;; (let* (tramp-mode ;; do not automatically complete remote stuff
;; (pcomplete-stub)
;; (pcomplete-show-list t) ;; inhibit patterns like * being deleted
;; pcomplete-seen pcomplete-norm-func
;; pcomplete-args pcomplete-last pcomplete-index
;; (pcomplete-autolist pcomplete-autolist)
;; (pcomplete-suffix-list pcomplete-suffix-list)
;; (candidates (pcomplete-completions))
;; (beg (pcomplete-begin))
;; ;; note, buffer text and completion argument may be
;; ;; different because the buffer text may bet transformed
;; ;; before being completed (e.g. variables like $HOME may be
;; ;; expanded)
;; (buftext (buffer-substring beg (point)))
;; (arg (nth pcomplete-index pcomplete-args)))
;; ;; we auto-complete only if the stub is non-empty and matches
;; ;; the end of the buffer text
;; (when (and (not (zerop (length pcomplete-stub)))
;; (or (string= pcomplete-stub ; Emacs 23
;; (substring buftext
;; (max 0
;; (- (length buftext)
;; (length pcomplete-stub)))))
;; (string= pcomplete-stub ; Emacs 24
;; (substring arg
;; (max 0
;; (- (length arg)
;; (length pcomplete-stub)))))))
;; ;; Collect all possible completions for the stub. Note that
;; ;; `candidates` may be a function, that's why we use
;; ;; `all-completions`.
;; (let* ((cnds (all-completions pcomplete-stub candidates))
;; (bnds (completion-boundaries pcomplete-stub
;; candidates
;; nil
;; ""))
;; (skip (- (length pcomplete-stub) (car bnds))))
;; ;; We replace the stub at the beginning of each candidate by
;; ;; the real buffer content.
;; (mapcar #'(lambda (cand) (concat buftext (substring cand skip)))
;; cnds))))))
;; (defvar ac-source-pcomplete
;; '((candidates . ac-pcomplete)))
;; (defun add-ac-sources (&rest sources)
;; "Add SOURCES for auto-complete after it has been loaded."
;; (when (user/auto-complete-p)
;; (dolist (source sources)
;; (if (boundp 'ac-sources)
;; (add-to-list 'ac-sources source)
;; (error "Declaration of ac-sources is missing!")))))
;; (defun add-ac-modes (&rest major-modes)
;; "Add MAJOR-MODES for auto-complete after it has been loaded."
;; (when (user/auto-complete-p)
;; (dolist (mode major-modes)
;; (if (boundp 'ac-modes)
;; (add-to-list 'ac-modes mode)
;; (error "Declaration of ac-modes is missing!")))))
;; (defun company-complete-common-or-selection ()
;; "Insert the common part of all candidates, or the selection."
;; (interactive)
;; (when (company-manual-begin)
;; (let ((tick (buffer-chars-modified-tick)))
;; (call-interactively 'company-complete-common)
;; (when (eq tick (buffer-chars-modified-tick))
;; (let ((company-selection-wrap-around t))
;; (call-interactively 'company-complete-selection))))))
;; (defun add-company-sources (&rest sources)
;; "Add SOURCES for company completion in current mode, if it has been loaded."
;; (when (user/company-mode-p)
;; (when (boundp 'company-backends)
;; (setq-local
;; company-backends
;; (append sources company-backends)))))
(defun user--completion-config ()
"Initialize automatic code completion."
(setq
;; Activate completion on tab.
tab-always-indent 'complete
;; Cycle completions in minibuffer below a certain threshold.
completion-cycle-threshold 5)
;; Allow completion of acronyms and initialisms.
(add-to-list 'completion-styles 'initials t)
;;; (Packages) ;;;
;; (use-package auto-complete
;; :disabled
;; :requires popup fuzzy
;; :defer
;; :quelpa (auto-complete
;; :fetcher github
;; :repo "auto-complete/auto-complete")
;; :diminish auto-complete-mode
;; :init
;; (add-hook 'flymake-mode-hook 'ac-flyspell-workaround)
;; (add-hook 'auto-complete-mode-hook 'user--auto-complete-mode-hook)
;; :config
;; (with-feature 'auto-complete-config
;; ;; Load default configuration.
;; (ac-config-default)
;; ;; Don't forcibly enable auto-complete.
;; (global-auto-complete-mode -1))
;; (validate-setq
;; ;; Limit the number of candidates.
;; ac-candidate-limit 40
;; ;; Delay until narrowing completions.
;; ac-delay 0.5
;; ;; Do not trigger completion automatically.
;; ac-auto-start nil
;; ;; Use fuzzy matching.
;; ac-fuzzy-enable t
;; ac-use-fuzzy t
;; ;; Do not pop up menu automatically.
;; ac-auto-show-menu nil
;; ;; Allow normal navigation keys in menu.
;; ac-use-menu-map t
;; ;; Do not auto-expand common candidates.
;; ac-expand-on-auto-complete nil
;; ;; Show quick help popup after half a second.
;; ac-use-quick-help t
;; ac-quick-help-delay 0.5
;; ;; Store the completion history in the cache directory.
;; ac-comphist-file (path-join *user-cache-directory* "ac-comphist.dat"))
;; ;; Set up auto-complete for lisp-interaction- and ielm-mode.
;; (dolist (hook (list 'lisp-interaction-mode-hook
;; 'ielm-mode-hook))
;; (add-hook hook 'ac-emacs-lisp-mode-setup))
;; ;;; (Bindings) ;;;
;; (ac-set-trigger-key (user/get-key :code :try-complete))
;; (validate-setq
;; ac-completing-map
;; (let ((map (make-sparse-keymap)))
;; ;; Expand on tab.
;; (define-key map (user/get-key :code :try-complete) 'ac-expand-common)
;; ;; Complete on enter.
;; (define-key map (user/get-key :code :complete) 'ac-complete)
;; ;; Bind configured auto complete key.
;; (define-key map (user/get-key :code :auto-complete) 'auto-complete)
;; ;; Scroll quick-help using M-n/p.
;; (define-key map (kbd "C-M-n") 'ac-quick-help-scroll-down)
;; (define-key map (kbd "C-M-p") 'ac-quick-help-scroll-up)
;; map)))
(use-package company
:diminish company-mode
:hook (company-mode-hook . user--company-mode-hook)
:config
(validate-setq
;; Do not trigger completion automatically.
;; company-idle-delay nil
;; Complete immediately.
company-minimum-prefix-length 0
;; Show commonly used matches first.
company-transformers '(company-sort-by-occurrence)
;; Align annotations to the right of tooltip.
company-tooltip-align-annotations t
;; Active company frontends.
;; company-frontends
;; '(company-pseudo-tooltip-unless-just-one-frontend
;; company-preview-frontend
;; company-echo-metadata-frontend)
)
;; (define-key company-active-map (user/get-key :code :complete) 'company-complete-selection)
;; (define-key company-active-map
;; (user/get-key :code :try-complete) 'company-complete-common-or-selection)
;; (define-key company-active-map
;; (user/get-key :basic :forward-line) 'company-select-next)
;; (define-key company-active-map
;; (user/get-key :basic :backward-line) 'company-select-previous)
;; (define-key company-active-map (user/get-key :code :complete) 'company-search-candidates)
(use-package company-dabbrev-code
:ensure company
:config
(validate-setq
;; Complete even outside of code.
company-dabbrev-code-everywhere t))
(use-package company-flx
:after (company)
:config
(company-flx-mode t))
(use-package company-quickhelp
:if window-system
:after (company)
:hook (company-mode-hook . company-quickhelp-mode)
:config
(validate-setq
;; Show quick help popup after half a second.
company-quickhelp-delay 0.5))
(use-package company-box
:if (display-graphic-p)
:hook (company-mode . company-box-mode))
(global-company-mode t)))
(user--completion-config)
(provide 'ux/completion)
;;; completion.el ends here

130
lisp/ux/editing.el Normal file
View File

@@ -0,0 +1,130 @@
;;; editing.el --- Configure Emacs editing -*- lexical-binding: t; -*-
;;; Commentary:
;;; Code:
(defun beginning-or-indentation ()
"Move cursor to beginning of line or to its indentation."
(interactive)
(if (bolp)
(back-to-indentation)
(beginning-of-line)))
(defun point-in-comment ()
"Determine if the point is inside a comment."
(interactive)
(let ((syn (syntax-ppss)))
(and (nth 8 syn)
(not (nth 3 syn)))))
(defun end-of-line-or-code (arg)
"Move point to end of line or forward ARG.
If already there, move back to end of code. By 'end of code' we
mean before a possible comment. Comments are recognized in any
mode that sets `syntax-ppss' properly."
(interactive "P")
(let ((eol (save-excursion
(move-end-of-line arg)
(point))))
(cond ((= (point) eol)
(move-end-of-line arg)
(while (point-in-comment)
(backward-char))
(skip-chars-backward " \t"))
(t (move-end-of-line arg)))))
(defun user--editing-config ()
"Initialize editing in Emacs."
(validate-setq
;; Increase history.
history-length 1000)
;; Enable narrowing.
(put 'narrow-to-region 'disabled nil)
(put 'narrow-to-page 'disabled nil)
(put 'narrow-to-defun 'disabled nil)
;; Enable case modification.
(put 'upcase-region 'disabled nil)
(put 'downcase-region 'disabled nil)
;;; (Packages) ;;;
(use-package simple
:ensure nil
:diminish auto-fill-function)
(when (eq window-system 'ns)
(use-package ns-win
:ensure nil
:config
(validate-setq
;; Swap command and option on MacOS X.
mac-option-modifier 'alt
mac-command-modifier 'meta
;; Use right option key for writing special characters.
mac-right-option-modifier nil)))
;; Fix https://github.com/rolandwalker/unicode-fonts/issues/21
;; (use-package unicode-fonts
;; :if (eq default-terminal-coding-system 'utf-8)
;; ;; Ensure `pcache-directory' has been set first.
;; :after ux/cache
;; :config
;; (require 'persistent-soft)
;; (unicode-fonts-setup))
(load-file (path-join *user-cache-directory* "unicode-fonts-setup.el"))
(when (feature-p 'helm)
(use-package helm-unicode
:if (eq default-terminal-coding-system 'utf-8)
:bind ("C-c h 8" . helm-unicode)))
(use-package selected
:ensure t
:diminish selected-minor-mode
:commands selected-minor-mode
:init
(setq
selected-org-mode-map (make-sparse-keymap))
(selected-global-mode t)
:bind (:map selected-keymap
;; Region.
("q" . selected-off)
("e" . er/expand-region)
;; Modification.
("f" . fill-region)
("u" . upcase-region)
("d" . downcase-region)
("s" . sort-lines)
("m" . apply-macro-to-region-lines)
;; Information.
("w" . count-words-region)
;; Motion.
("p" . move-text-up)
("n" . move-text-down)
:map selected-org-mode-map
("t" . org-table-convert-region)))
;;; (Bindings) ;;;
(global-set-key [remap move-beginning-of-line] 'beginning-or-indentation)
(global-set-key [remap move-end-of-line] 'end-of-line-or-code)
(user/bind-key-global :basic :forward-word 'forward-word)
(user/bind-key-global :basic :backward-word 'backward-word)
(user/bind-key-global :basic :forward-expr 'forward-sexp)
(user/bind-key-global :basic :backward-expr 'backward-sexp)
(user/bind-key-global :basic :del-char-left 'delete-backward-char)
(user/bind-key-global :basic :del-char-right 'delete-char)
(user/bind-key-global :basic :widen 'widen)
(user/bind-key-global :basic :narrow-to-page 'narrow-to-page)
(user/bind-key-global :basic :narrow-to-region 'narrow-to-region)
(user/bind-key-global :basic :narrow-to-function 'narrow-to-defun)
(user/bind-key-global :code :join-line 'join-line)
(user/bind-key-global :code :fill-paragraph 'fill-paragraph))
(user--editing-config)
(provide 'ux/editing)
;;; editing.el ends here

108
lisp/ux/frames.el Normal file
View File

@@ -0,0 +1,108 @@
;;; frames.el --- Configure behavior of Emacs frames -*- lexical-binding: t; -*-
;;; Commentary:
;;; Code:
(defun user--window-configuration-change-hook ()
;; "Window configuration change hook."
;; (setq
;; ;; Only split frame if it occupies at least 2/3 of the current screen width.
;; split-width-threshold (* (/ (window-total-width (frame-root-window)) 3) 2)))
)
(defun user/iconify-or-deiconify-frame ()
"Iconify the selected frame, or deiconify if it's currently an icon."
(interactive)
(if (display-graphic-p)
(iconify-or-deiconify-frame)
(suspend-frame)))
(defun user/close-and-kill-current-window ()
"If multiple windows are open, close the current one and kill the buffer."
(interactive)
(kill-this-buffer)
(if (not (one-window-p))
(delete-window)))
(defun user/close-and-kill-other-window ()
"If multiple windows are open, close the next one and kill its buffer."
(interactive)
(other-window 1)
(kill-this-buffer)
(if (not (one-window-p))
(delete-window)))
(progn
(validate-setq
;; Inhibit GUI features
use-file-dialog nil
;; Don't split frames horizontally.
split-height-threshold nil)
;; Remove all the mouse-assisted frames
(when (fboundp 'scroll-bar-mode) (scroll-bar-mode -1))
(when (fboundp 'tool-bar-mode) (tool-bar-mode -1))
(when (fboundp 'menu-bar-mode) (menu-bar-mode -1))
;;; (Hooks) ;;;
(add-to-list 'window-configuration-change-hook
'user--window-configuration-change-hook)
;;; (Bindings) ;;;
(when (display-graphic-p)
(user/bind-key-global :emacs :fullscreen 'toggle-frame-fullscreen))
(user/bind-key-global :emacs :grow-vertical 'enlarge-window)
(user/bind-key-global :emacs :shrink-vertical 'shrink-window)
(user/bind-key-global :emacs :grow-horizontal 'enlarge-window-horizontally)
(user/bind-key-global :emacs :shrink-horizontal 'shrink-window-horizontally)
;;; (Packages) ;;;
;; https://github.com/tomterl/fullframe
;; Advice commands to execute fullscreen, restoring the window setup when exiting
(use-package fullframe)
;; https://github.com/emacsorphanage/transpose-frame/blob/master/transpose-frame.el
;; Transpose windows arrangement in a frame
(use-package transpose-frame
:defer
:init
(user/bind-key-global :emacs :flip-frame 'flip-frame)
(user/bind-key-global :emacs :flop-frame 'flop-frame)
(user/bind-key-global :emacs :rotate-frame-forward 'rotate-frame-clockwise)
(user/bind-key-global :emacs :rotate-frame-backward
'rotate-frame-anticlockwise))
;; https://github.com/cyrus-and/zoom
;; Fixed and automatic balanced window layout for Emacs
(use-package zoom
:diminish zoom-mode
:config
(validate-setq
;; Ignored buffers.
zoom-ignored-buffer-name-regexps
'("^*calc")
;; Ignore predicate definitions.
zoom-ignore-predicates
'((lambda () (> (count-lines (point-min) (point-max)) 20))))
(zoom-mode t))
(use-package frame
:ensure nil
:config
;; Enable blinking cursor
(blink-cursor-mode))
;;
;;
(use-package framemove
:quelpa (framemove
:fetcher github
:repo "emacsmirror/framemove")
:init
(windmove-default-keybindings)
(setq framemove-hook-into-windmove t)))
(provide 'ux/frames)
;;; frames.el ends here

11
lisp/ux/gc.el Normal file
View File

@@ -0,0 +1,11 @@
;;; gc.el --- Garbage collector settings -*- lexical-binding: t; -*-
;;; Commentary:
;;; Code:
(use-package gcmh
:config
(gcmh-mode t))
(provide 'ux/gc)
;;; gc.el ends here

115
lisp/ux/help.el Normal file
View File

@@ -0,0 +1,115 @@
;;; help.el --- Emacs help -*- lexical-binding: t; -*-
;;; Commentary:
;;; Code:
(use-package help-mode
:ensure nil
:defer
:config
(use-package help-fns
:ensure nil
:init
(user/bind-key-global :emacs :describe-variable 'describe-variable)
(user/bind-key-global :emacs :describe-syntax 'describe-syntax))
(use-package helpful
:init
(user/bind-key-global :emacs :describe-function 'helpful-function)
(user/bind-key-global :emacs :describe-macro 'helpful-macro)
(user/bind-key-global :emacs :describe-command 'helpful-command)
:config
(with-eval-after-load 'popwin
;; Use popwin for helpful buffer.
(add-to-list
'popwin:special-display-config
;; Don't select compilation window when shown
'(helpful-mode :position bottom :height 20)))))
(use-package apropos
:ensure nil
:defer
:init
(user/bind-key-global :emacs :search-variable-value 'apropos-value))
(use-package info-look
:ensure nil
:defer
:init
(user/bind-key-global :emacs :describe-symbol 'info-lookup-symbol))
(use-package help
:ensure nil
:defer
:init
(user/bind-key-global :emacs :describe-bindings 'describe-bindings)
(user/bind-key-global :emacs :describe-key 'describe-key)
(user/bind-key-global :emacs :where-is 'where-is)
(user/bind-key-global :emacs :describe-mode 'describe-mode)
(use-package helm-describe-modes
:init
(global-set-key [remap describe-mode] #'helm-describe-modes)))
(use-package find-func
:ensure nil
:defer
:init
(user/bind-key-global :emacs :find-library 'find-library))
(use-package finder
:ensure nil
:defer
:init
(user/bind-key-global :emacs :find-package 'finder-by-keyword))
(use-package menu-bar
:ensure nil
:defer
:init
(user/bind-key-global :emacs :elisp-search 'elisp-index-search))
(use-package tutorial
:ensure nil
:defer
:init
(user/bind-key-global :emacs :tutorial 'help-with-tutorial))
(use-package which-key
:diminish which-key-mode
:config
(validate-setq
;; Number of seconds until help is shown.
which-key-idle-delay 1.0
which-key-special-keys
'("SPC"
"TAB"
"RET"
"DLT" ; delete key
"BS" ; backspace key
"ESC"))
(when (eq default-terminal-coding-system 'utf-8)
(add-many-to-list
'which-key-replacement-alist
'(("TAB" . nil) . ("" . nil))
'(("RET" . nil) . ("" . nil))
'(("DEL" . nil) . ("" . nil))
'(("deletechar" . nil) . ("" . nil))
'(("DEL" . nil) . ("" . nil))
'(("SPC" . nil) . ("" . nil))))
(which-key-add-key-based-replacements
user/view-prefix "view"
user/help-prefix "help"
user/documentation-prefix "doc"
user/code-prefix "code"
user/code-eval-prefix "eval"
user/vcs-prefix "vcs"
user/utilities-prefix "utils"
user/apps-prefix "apps")
(which-key-mode t))
(provide 'ux/help)
;;; help.el ends here

18
lisp/ux/indentation.el Normal file
View File

@@ -0,0 +1,18 @@
;;; indentation.el --- Configure Emacs indentation behavior -*- lexical-binding: t; -*-
;;; Commentary:
;;; Code:
(use-package dtrt-indent
:config
(validate-setq
dtrt-indent-verbosity 0
global-mode-string (delq 'dtrt-indent-mode-line-info global-mode-string)))
(use-package smart-tabs-mode
:quelpa (smart-tabs-mode
:fetcher github
:repo "jcsalomon/smarttabs"))
(provide 'ux/indentation)
;;; indentation.el ends here

91
lisp/ux/kill-yank.el Normal file
View File

@@ -0,0 +1,91 @@
;;; kill-yank.el --- Configuration for copying and pasting of data -*- lexical-binding: t; -*-
;;; Commentary:
;;; Code:
(use-package mouse
:ensure nil
:config
(validate-setq
;; Mouse selection should not automatically go to kill ring.
mouse-drag-copy-region nil)
(when (eq window-system 'x)
(validate-setq
;; Don't inject mouse selection into X11 clipboard.
mouse-drag-copy-region nil)
;; Set middle mouse button to paste from primary X11 selection.
(global-set-key [mouse-2] 'mouse-yank-primary)))
(use-package select
:if window-system
:ensure nil
:config
(validate-setq
;; Do not interact with X11 primary selection.
select-enable-primary nil
;; Make kill/yank interact with X11 clipboard selection.
select-enable-clipboard t
;; Active region should set primary X11 selection.
select-active-regions t))
(use-package menu-bar
:ensure nil
:config
;; Rebind to new clipboard functions when available.
(when (fboundp 'clipboard-kill-region)
(global-set-key [remap kill-region] 'clipboard-kill-region))
(when (fboundp 'clipboard-kill-ring-save)
(global-set-key [remap kill-ring-save] 'clipboard-kill-ring-save))
(when (fboundp 'clipboard-yank)
(global-set-key [remap yank] 'clipboard-yank)))
(use-package expand-region
:bind-wrap
(((:key :basic :selection-expand) . er/expand-region)
((:key :basic :select-paragraph) . er/mark-paragraph)
((:key :basic :select-function) . er/mark-defun)
((:key :basic :select-inside) . er/mark-inside-pairs)))
(use-package multiple-cursors
:defer
:bind-wrap
(((:key :basic :selection-next) . mc/mark-next-like-this)
((:key :basic :selection-prev) . mc/mark-previous-like-this)
((:key :basic :selection-all) . mc/mark-all-like-this)
((:key :basic :selection-edit-lines) . mc/edit-lines)))
(use-package rect-mark
:defer
:quelpa (rect-mark
:fetcher url
:url "https://www.emacswiki.org/emacs/download/rect-mark.el"))
(use-package simple
:ensure nil
:bind-wrap
(;; Delete words with C/M-w and rebind kill/yank region to C-x C-k/C-x C-w.
((:key :basic :cut-word-left) . backward-kill-word)
((:key :basic :cut-word-right) . kill-word)
;; Set up basic copy/paste
((:key :basic :selection-start) . set-mark-command)
((:key :basic :copy) . kill-ring-save)
((:key :basic :cut) . kill-region)
((:key :basic :paste) . yank)
((:key :basic :cycle-paste) . yank-pop))
:config
(validate-setq
;; Increase the maximum number of saved kill ring entries.
kill-ring-max 200
;; Do not store duplicates in kill ring.
kill-do-not-save-duplicates t
;; Save clipboard before killing it.
save-interprogram-paste-before-kill t))
(use-package move-text
:defer)
(user/bind-key-global :basic :cut-expr 'kill-sexp)
(provide 'ux/kill-yank)
;;; kill-yank.el ends here

51
lisp/ux/mode-line.el Normal file
View File

@@ -0,0 +1,51 @@
;;; mode-line.el --- Mode line configuration -*- lexical-binding: t; -*-
;;; Commentary:
;;; Code:
(defun user--modeline-config ()
"Initialize Emacs mode line."
;; Show row and column numbers.
(validate-setq
line-number-mode t
column-number-mode t
display-time-mode nil)
;;; (Packages) ;;;
;; Display the current time and system load.
(use-package time
:disabled
:config
(validate-setq
display-time-24hr-format t
display-time-day-and-date t)
(display-time))
;; Display battery status.
(use-package battery
:disabled
:config
(when (and (functionp battery-status-function)
(not (string-match-p "N/A" (battery-format "%B" (funcall battery-status-function)))))
(validate-setq battery-mode-line-format
(format " [%s%s%s]" "%b%p%" " (%t)"
(if (string-match-p "N/A" (battery-format "%d" (funcall battery-status-function)))
""
" %d°C")))
(display-battery-mode t)))
(use-package doom-modeline
:hook (after-init-hook . doom-modeline-init)
:config
(validate-setq
doom-modeline-height 18))
(use-package mode-line-bell
:config
(mode-line-bell-mode t)))
(user--modeline-config)
(provide 'ux/mode-line)
;;; mode-line.el ends here

60
lisp/ux/navigation.el Normal file
View File

@@ -0,0 +1,60 @@
;;; navigation.el --- Set up Emacs buffer navigation -*- lexical-binding: t; -*-
;;; Commentary:
;;; Code:
(defun user/scroll-up ()
"Scroll page up without moving point."
(interactive)
(scroll-down 1))
(defun user/scroll-down ()
"Scroll page down without moving point."
(interactive)
(scroll-up 1))
(defun user--navigation-config ()
"Set up Emacs buffer navigation."
;; Enable mouse in iTerm2
(when (eq system-type 'darwin)
(with-feature 'mouse
(xterm-mouse-mode t)
(defun track-mouse (e))))
;;; (Bindings) ;;;
(user/bind-key-global :nav :scroll-up 'user/scroll-up)
(user/bind-key-global :nav :scroll-down 'user/scroll-down)
(user/bind-key-global :nav :goto-line 'goto-line)
(user/bind-key-global :nav :go-back 'pop-global-mark)
;; https://github.com/abo-abo/avy
;; Jump to things in Emacs tree-style
(use-package avy
:bind ("M-s" . avy-goto-char)
:config
(avy-setup-default))
;; https://github.com/jcs-elpa/goto-line-preview
;; Preview line when executing goto-line command.
(use-package goto-line-preview
:disabled
:config
(user/bind-key-global :nav :goto-line 'goto-line-preview))
;; https://github.com/magnars/smart-forward.el
;; smart-forward gives you semantic navigation, building on expand-region
(use-package smart-forward
:disabled
:defer
:init
(user/bind-key-global :nav :context-forward 'smart-forward)
(user/bind-key-global :nav :context-backward 'smart-backward)
(user/bind-key-global :nav :context-up 'smart-up)
(user/bind-key-global :nav :context-down 'smart-down)))
(user--navigation-config)
(provide 'ux/navigation)
;;; navigation.el ends here

12
lisp/ux/paths.el Normal file
View File

@@ -0,0 +1,12 @@
;;; paths.el --- Configure system paths in Emacs -*- lexical-binding: t; -*-
;;; Commentary:
;;; Code:
(use-package exec-path-from-shell
:if (memq window-system '(mac ns x))
:config
(exec-path-from-shell-initialize))
(provide 'ux/paths)
;;; paths.el ends here

35
lisp/ux/popups.el Normal file
View File

@@ -0,0 +1,35 @@
;;; popups.el --- Configure Emacs popups -*- lexical-binding: t; -*-
;;; Commentary:
;;; Code:
(defun user--popups-config ()
"Initialize Emacs popups."
(validate-setq
;; Timeout for messages shown in minibuffer.
minibuffer-message-timeout 5)
;;; (Packages) ;;;
(use-package popup
:config
;; Install workaround for whitespace-mode bug.
(with-eval-after-load 'modes/whitespace
(defadvice popup-draw (before user/turn-off-whitespace activate compile)
"Turn off whitespace mode before showing popup."
(user/whitespace-mode-suppress t))
(defadvice popup-delete (after user/restore-whitespace activate compile)
"Restore previous whitespace mode when deleting popup."
(user/whitespace-mode-suppress nil))))
(use-package popwin
:init
(user/bind-key-global :util :popwin-close 'popwin:close-popup-window)
(user/bind-key-global :util :popwin-buffer 'popwin:popup-buffer)
:config
(popwin-mode t)))
(user--popups-config)
(provide 'ux/popups)
;;; popups.el ends here

30
lisp/ux/prompts.el Normal file
View File

@@ -0,0 +1,30 @@
;;; prompts.el --- Configure Emacs prompting -*- lexical-binding: t; -*-
;;; Commentary:
;;; Code:
(defun user--prompts-config ()
"Initialize Emacs prompting."
(validate-setq
;; Always follow links to version controlled files.
vc-follow-symlinks t
;; Always ask before killing Emacs.
confirm-kill-emacs 'y-or-n-p)
;; Use shorter y/n prompts instead of yes/no.
(fset 'yes-or-no-p 'y-or-n-p)
(when (display-graphic-p)
(validate-setq
;; Don't use graphical dialog boxes when prompting.
use-dialog-box nil))
(defadvice save-buffers-kill-emacs (around no-query-kill-emacs activate)
"Prevent \"Active processes exist\" query when you quit Emacs."
(with-feature 'cl-lib
(cl-flet ((process-list ())) ad-do-it))))
(user--prompts-config)
(provide 'ux/prompts)
;;; prompts.el ends here

53
lisp/ux/rendering.el Normal file
View File

@@ -0,0 +1,53 @@
;;; rendering.el --- Configure Emacs user interface rendering -*- lexical-binding: t; -*-
;;; Commentary:
;;; Code:
(defconst *user-fast-font-lock-buffer-limit* (* 128 1024)
"Maximum buffer size for maximum font lock decorations.")
(defun user--rendering-find-file-hook ()
"Rendering hook for `find-file'."
(when (> (buffer-size) *user-fast-font-lock-buffer-limit*)
(setq
;; Reduce the level of fontification.
font-lock-maximum-decoration nil)
(font-lock-refresh-defaults)))
(defun user--rendering-config ()
"Setup Emacs user interface rendering."
(with-eval-after-load 'font-lock
;; Allow reduction of decoration level in large buffers.
(make-variable-buffer-local 'font-lock-maximum-decoration))
(validate-setq
;; Redraw the entire screen before checking for pending input events.
;; This will improve performance in general but might degrade performance of
;; key repeat.
redisplay-dont-pause t
;; Use the maximum amount of decorations by default.
font-lock-maximum-decoration t
;; Always use JIT mode for font-lock.
font-lock-support-mode 'jit-lock-mode
;; Set up font-lock JIT mode to do background parsing.
jit-lock-stealth-time 1.0
jit-lock-stealth-nice 0.03
jit-lock-stealth-load 200
jit-lock-stealth-verbose nil
jit-lock-chunk-size 500
;; Do not reorder text during rendering.
bidi-display-reordering nil)
;;; (Hooks) ;;;
(add-hook 'find-file-hook 'user--rendering-find-file-hook)
;;; (Bindings) ;;;
(user/bind-key-global :emacs :redraw 'redraw-display))
(user--rendering-config)
(provide 'ux/rendering)
;;; rendering.el ends here

34
lisp/ux/scrolling.el Normal file
View File

@@ -0,0 +1,34 @@
;;; scrolling.el --- Configure scrolling in Emacs buffers -*- lexical-binding: t; -*-
;;; Commentary:
;;; Code:
(defun user--scrolling-config ()
"Configure Emacs buffer scrolling."
(validate-setq
;; Set distance in line from margin before scrolling commences.
scroll-margin 5
;; Prevent cursor from jumping to center of window on scroll.
scroll-conservatively 100000
;; Try to maintain screen position when scrolling entire pages.
scroll-preserve-screen-position t)
;;; (Bindings) ;;;
(user/bind-key-global :emacs :recenter 'recenter))
(use-package mwheel
:ensure nil
:if window-system
:config
(validate-setq
;; Scroll five lines when using mouse wheel.
mouse-wheel-scroll-amount '(5 ((shift) . 5))
;; Use constant speed when scrolling with mouse wheel.
mouse-wheel-progressive-speed nil
;; Scroll the window that the cursor is over.
mouse-wheel-follow-mouse t))
(user--scrolling-config)
(provide 'ux/scrolling)
;;; scrolling.el ends here

60
lisp/ux/search-replace.el Normal file
View File

@@ -0,0 +1,60 @@
;;; search-replace.el --- Configuration for searching and replacing -*- lexical-binding: t; -*-
;;; Commentary:
;;; Code:
(defun user--search-replace-config ()
"Initialize Emacs search and replace."
(validate-setq
;; Highlight all visible matches.
search-highlight t
query-replace-highlight t
;; Perform certain commands only on the marked region.
transient-mark-mode t)
;;; (Bindings) ;;;
;; Use regular expression searches by default.
(user/bind-key-global :basic :search-forward 'isearch-forward-regexp)
(user/bind-key-global :basic :search-backward 'isearch-backward-regexp)
(user/bind-key-global :basic :search-files 'find-grep)
;;; (Packages) ;;;
(use-package visual-regexp
:defer
:bind* (([remap query-replace-regexp] . vr/query-replace)
([remap replace-regexp] . vr/replace)))
(use-package replace-with-inflections
:bind (:map search-map
("n" . query-replace-names-with-inflections)))
(use-package anzu
:defer
:diminish anzu-mode
:config
(global-anzu-mode t))
(use-package grep
:defer
:config
(validate-setq
;; Highlight matches when using grep.
grep-highlight-matches t)
(when (eq system-type 'darwin)
(-when-let (gnu-find (executable-find "gfind"))
(validate-setq find-program gnu-find)))
(-when-let (gnu-xargs (executable-find "gxargs"))
(validate-setq xargs-program gnu-xargs))
(use-package wgrep
:defer
:config
(use-package wgrep-helm)
(use-package wgrep-ag
:if (executable-find "ag")))))
(user--search-replace-config)
(provide 'ux/search-replace)
;;; search-replace.el ends here

35
lisp/ux/server.el Normal file
View File

@@ -0,0 +1,35 @@
;;; server.el --- Emacs server setup -*- lexical-binding: t; -*-
;;; Commentary:
;;; Code:
(defun user/server-save ()
"Save and quickly exit from server edit mode."
(interactive)
(save-buffer)
(server-edit))
(defun user--server-after-init-hook ()
"Initialize Emacs server after init has completed."
(with-feature 'server
(unless (server-running-p)
(server-start)
(when (and (display-graphic-p)
(feature-p 'edit-server))
(edit-server-start)))))
(use-package server
;; Emacs clients regularly causes Emacs to crash on Darwin.
:disabled
:if (not (eq system-type 'darwin))
:ensure nil
:hook (after-init-hook . user--server-after-init-hook)
:config
(use-package edit-server
:if window-system))
(provide 'ux/server)
;;; server.el ends here

40
lisp/ux/sessions.el Normal file
View File

@@ -0,0 +1,40 @@
;;; sessions.el --- Set up Emacs to remember things between sessions -*- lexical-binding: t; -*-
;;; Commentary:
;;; Code:
(use-package recentf
;; Prevent entries from loading tramp resulting in the stable
;; version of CEDET being loaded before devel.
:hook (after-init-hook . recentf-mode)
:config
(validate-setq
recentf-max-saved-items 1000
recentf-exclude '("/elpa/" "/tmp/")
recentf-save-file (path-join *user-cache-directory* "recentf")))
(use-package savehist
:init
;; Must be set before enabling savehist so validate cannot be used
;; here.
(setq-default
savehist-file (path-join *user-cache-directory* "savehist")
;; Save minibuffer history.
savehist-save-minibuffer-history t
;; Additional history to save.
savehist-additional-variables '(search-ring regexp-search-ring kill-ring)
;; Autosave every once in a while.
savehist-autosave-interval 180)
(savehist-mode t))
(use-package saveplace
:config
(validate-setq
;; Location of saveplace cache store.
save-place-file (path-join *user-cache-directory* "saveplace")
;; Enable.
save-place-mode t))
(provide 'ux/sessions)
;;; sessions.el ends here

18
lisp/ux/startup.el Normal file
View File

@@ -0,0 +1,18 @@
;;; startup.el --- Configure Emacs startup behavior -*- lexical-binding: t; -*-
;;; Commentary:
;;; Code:
;; startup.el has no `provide' statement.
(progn
(validate-setq
;; Do not show the splash screen or message
inhibit-startup-screen t
inhibit-startup-echo-area-message (getenv "USER"))
(use-package dashboard
:config
(dashboard-setup-startup-hook)))
(provide 'ux/startup)
;;; startup.el ends here

19
lisp/ux/symbols.el Normal file
View File

@@ -0,0 +1,19 @@
;;; symbols.el --- Configure how Emacs handles certain symbols -*- lexical-binding: t; -*-
;;; Commentary:
;;; Code:
(use-package page-break-lines
:diminish page-break-lines-mode
:config
(global-page-break-lines-mode t))
;; (with-eval-after-load 'ux/coding
;; (when (eq default-terminal-coding-system 'utf-8)
;; (use-package pretty-mode-plus)))
(use-package all-the-icons
:if window-system)
(provide 'ux/symbols)
;;; symbols.el ends here

63
lisp/ux/theme.el Normal file
View File

@@ -0,0 +1,63 @@
;;; theme.el --- Configure Emacs theme -*- lexical-binding: t; -*-
;;; Commentary:
;;; Code:
(use-package custom
:ensure nil
:config
;; Use 20210731.818 release.
(use-package doom-themes
:config
(setq doom-themes-enable-bold t ; if nil, bold is universally disabled
doom-themes-enable-italic t) ; if nil, italics is universally disabled
(load-theme 'doom-material t)
(custom-set-faces
`(outline-1 ((t (:foreground ,(doom-color 'yellow)))))
`(outline-2 ((t (:foreground ,(doom-color 'orange)))))
`(outline-3 ((t (:foreground ,(doom-color 'dark-blue)))))
`(outline-4 ((t (:foreground ,(doom-color 'teal)))))
`(markdown-header-face-1 ((t (:inherit 'outline-1))))
`(markdown-header-face-2 ((t (:inherit 'outline-2))))
`(markdown-header-face-3 ((t (:inherit 'outline-3))))
`(markdown-header-face-4 ((t (:inherit 'outline-4))))
`(org-drawer ((t (:foreground ,(doom-lighten 'base6 .30)))))
`(font-lock-comment-face ((t (:foreground ,(doom-lighten 'base6 .20)))))
`(org-default ((t (:inherit 'default))))
`(org-table ((t (:foreground ,(doom-lighten 'base2 0.70)))))
`(org-agenda-done ((t (:inherit 'org-default)))))
))
(use-package faces
:ensure nil
:defer
:bind-wrap
(((:key :emacs :describe-face) . describe-face)
((:key :emacs :describe-all-faces) . list-faces-display))
:config
(when (display-graphic-p)
(cond
((eq system-type 'darwin)
(set-face-attribute 'default nil :family "Menlo" :height 110 :weight 'normal))
((eq system-type 'windows-nt)
(set-face-attribute 'default nil :family "Consolas" :height 100 :weight 'normal))
((eq system-type 'gnu/linux)
(set-face-attribute 'default nil :foundry "DejaVu Sans Mono" :family "Monospace"
:height 90 :weight 'normal)))))
(use-package ns-auto-titlebar
:if (eq system-type 'darwin)
:config
(ns-auto-titlebar-mode))
(use-package face-remap
:ensure nil
:bind-wrap
(((:key :emacs :text-scale-reset) . (lambda () (interactive)
(text-scale-set 0)))
((:key :emacs :text-scale-increase) . text-scale-increase)
((:key :emacs :text-scale-decrease) . text-scale-decrease)))
(provide 'ux/theme)
;;; theme.el ends here

19
lisp/ux/tree.el Normal file
View File

@@ -0,0 +1,19 @@
;;; tree.el --- Configures tree representation -*- lexical-bindings: t -*-
;;; Commentary:
;;; Code:
;; (defun treemacs--split-window-advice (original-split-function &rest args)
;; (-let [w (treemacs--is-visible?)]
;; (unwind-protect
;; (progn
;; (when w (set-window-parameter w 'window-side treemacs-position))
;; (apply original-split-function args))
;; (when w (set-window-parameter w 'window-side treemacs-position)))))
;; (advice-add 'split-window-right :around #'treemacs--split-window-advice)
(use-package treemacs
:ensure t
:defer t)
(provide 'ux/tree)
;;; tree.el ends here.

46
lisp/ux/undo.el Normal file
View File

@@ -0,0 +1,46 @@
;;; undo.el --- Configure Emacs undo -*- lexical-binding: t; -*-
;;; Commentary:
;;; Code:
(defconst *user-undo-tree-cache-directory*
(path-join *user-cache-directory* "undo-tree")
"Path to user's undo-tree cache store.")
;;; (Bindings) ;;;
(user/bind-key-global :basic :undo 'undo)
(use-package undo-tree
:bind-wrap
(([remap undo] . undo-tree-undo)
([remap redo] . undo-tree-redo)
((:key :basic :undo) . undo-tree-undo)
((:key :basic :redo) . undo-tree-redo)
((:key :util :undo-tree) . undo-tree-visualize))
:config
;; Ensure that cache store exists.
(make-directory *user-undo-tree-cache-directory* t)
(validate-setq
;; Set up undo history cache store.
undo-tree-history-directory-alist
`((".*" . ,*user-undo-tree-cache-directory*))
;; Persistent undo history.
undo-tree-auto-save-history t
;; Don't display in mode-line.
undo-tree-mode-lighter ""
;; Display time stamps in visualizer by default.
undo-tree-visualizer-timestamps t
;; Display diffs in visualizer by default.
undo-tree-visualizer-diff t)
;; Compress undo history.
(defadvice undo-tree-make-history-save-file-name
(after undo-tree activate)
(validate-setq ad-return-value (concat ad-return-value ".gz")))
(global-undo-tree-mode t))
(provide 'ux/undo)
;;; undo.el ends here

11
lisp/ux/windows.el Normal file
View File

@@ -0,0 +1,11 @@
;;; windows.el --- Configure behavior of Emacs windows -*- lexical-binding: t; -*-
;;; Commentary:
;;; Code:
;; https://www.emacswiki.org/emacs/WindMove
;; Move point from window to window using Shift and the arrow keys.
(when (fboundp 'windmove-default-keybindings)
(windmove-default-keybindings))
(provide 'ux/windows)
;;; windows.el ends here