From 107eab7ef6311a5b5f9c85c179ae83b2e3204094 Mon Sep 17 00:00:00 2001 From: Case Duckworth Date: Sun, 8 Jan 2023 18:19:04 -0600 Subject: myeahhhhhh --- basics.el | 315 +++++++++++++++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 270 insertions(+), 45 deletions(-) (limited to 'basics.el') diff --git a/basics.el b/basics.el index 06f5ece..4e9e0a9 100644 --- a/basics.el +++ b/basics.el @@ -8,41 +8,15 @@ ;;; Code: -;;; Directories +(push (locate-user-emacs-file "lisp/") load-path) +(require 'acdw) -(defmacro defdir (name directory &optional docstring makedir) - "Define a variable and a function NAME expanding to DIRECTORY. -DOCSTRING is applied to the variable; its default is DIRECTORY's -path. If MAKEDIR is non-nil, the directory and its parents will -be created." - (declare (indent 2) (doc-string 3)) - `(progn - (defvar ,name (expand-file-name ,directory) - ,(concat (or docstring (format "%s" directory)) "\n" - "Defined by `defdir'.")) - (defun ,name (file &optional mkdir) - ,(concat "Expand FILE relative to variable `" (symbol-name name) "'.\n" - "If MKDIR is non-nil, parent directories are created.\n" - "Defined by `defdir'.") - (let ((file-name (expand-file-name - (convert-standard-filename file) ,name))) - (when mkdir - (make-directory (file-name-directory file-name) :parents)) - file-name)) - ,(if makedir - `(make-directory ,directory :parents) - `(unless (file-exists-p ,directory) - (warn "Directory `%s' doesn't exist." ,directory))))) +;;; Directories (defdir etc/ (locate-user-emacs-file "etc/") "Where various Emacs files are placed." :makedir) -(defdir lisp/ (locate-user-emacs-file "lisp/") - "My bespoke elisp files." - :makedir) -(push lisp/ load-path) - (defdir sync/ "~/Sync/" "My Syncthing directory." :makedir) @@ -50,7 +24,6 @@ be created." (defdir private/ (sync/ "emacs/private/") "Private files and stuff." :makedir) -(push private/ load-path) (use-package no-littering :ensure t :demand t @@ -114,6 +87,15 @@ be created." (file-name-shadow-mode) (minibuffer-electric-default-mode) +(define-minor-mode truncate-lines-local-mode + "Truncate lines locally in a buffer." + :lighter " ..." + :group 'display + (setq-local truncate-lines truncate-lines-local-mode)) + +(add-hook 'minibuffer-setup-hook #'truncate-lines-local-mode) + + (require 'savehist) (setq-default history-length 1024 history-delete-duplicates t @@ -122,13 +104,16 @@ be created." savehist-autosave-interval 30) (savehist-mode) -;; Undo -(setq-default undo-limit (* 10 1024 1024)) - ;; Killing and yanking (setq-default kill-do-not-save-duplicates t kill-read-only-ok t - save-interprogram-paste-before-kill t + ;; XXX: This setting causes an error message the first time it's + ;; called: "Selection owner couldn't convert: TIMESTAMP". I have + ;; absolutely no idea why I get this error, but it's generated in + ;; `x_get_foreign_selection'. I also can't inhibit the message or + ;; do anything else with it, so for now, I'll just live with the + ;; message. + save-interprogram-paste-before-kill t yank-pop-change-selection t) (delete-selection-mode) @@ -147,14 +132,20 @@ be created." initial-buffer-choice t initial-scratch-message nil) -;; (menu-bar-mode -1) +(define-advice startup-echo-area-message (:override ()) + (if (get-buffer "*Warnings*") + ";_;" + "^_^")) + +(menu-bar-mode -1) (tool-bar-mode -1) (tooltip-mode -1) ;; Text editing (setq-default fill-column 80 sentence-end-double-space t - tab-width 8) + tab-width 8 + tab-always-indent 'complete) (global-so-long-mode) (setq-default show-paren-delay 0.01 @@ -202,7 +193,8 @@ be created." auto-save-interval 1 auto-save-no-message t auto-save-timeout 1 - auto-save-visited-interval 1) + auto-save-visited-interval 1 + remote-file-name-inhibit-auto-save-visited t) (add-to-list 'auto-save-file-name-transforms `(".*" ,(etc/ "auto-save/" t) t)) (auto-save-visited-mode) @@ -215,9 +207,9 @@ be created." (require 'recentf) (setq-default ;; recentf-save-file (etc/ "recentf" t) - recentf-max-menu-items 500 - recentf-max-saved-items nil ; Save the whole list - recentf-auto-cleanup 'mode) + recentf-max-menu-items 500 + recentf-max-saved-items nil ; Save the whole list + recentf-auto-cleanup 'mode) (add-to-list 'recentf-exclude etc/) (add-to-list 'recentf-exclude "-autoloads.el\\'") (add-hook 'buffer-list-update-hook #'recentf-track-opened-file) @@ -225,8 +217,8 @@ be created." (require 'saveplace) (setq-default ;; save-place-file (etc/ "places.el") - save-place-forget-unreadable-files (eq system-type - 'gnu/linux)) + save-place-forget-unreadable-files (eq system-type + 'gnu/linux)) (save-place-mode) (require 'uniquify) @@ -247,10 +239,12 @@ be created." (startup-redirect-eln-cache native-compile-target-directory)) ;; Custom file -(setq-default custom-file (sync/ "emacs/custom.el")) -(define-advice package--save-selected-packages (:around (orig &rest args) no-custom) +(setq-default custom-file (private/ "custom.el")) +(define-advice package--save-selected-packages + (:around (orig &rest args) no-custom) "Don't save `package-selected-packages' to `custom-file'." - (let ((custom-file null-device)) + (let ((custom-file (expand-file-name "custom.el" + temporary-file-directory))) (apply orig args))) ;; Goto Address @@ -293,22 +287,56 @@ N spaces." (global-set-key (kbd "C-x 0") #'delete-window|bury-buffer) (global-set-key (kbd "M-SPC") #'+cycle-spacing) (global-set-key (kbd "C-x C-k") #'kill-this-buffer) +(global-set-key (kbd "C-/") #'undo-only) +(global-set-key (kbd "C-?") #'undo-redo) + +(define-key emacs-lisp-mode-map (kbd "C-c C-c") + #'eval-defun) +(define-key emacs-lisp-mode-map (kbd "C-c C-k") + #'elisp-eval-region-or-buffer) +(define-key lisp-interaction-mode-map (kbd "C-c C-c") + #'eval-defun) +(define-key lisp-interaction-mode-map (kbd "C-c C-k") + #'elisp-eval-region-or-buffer) +(define-advice eval-region (:around (orig start end &rest args) pulse) + (apply orig start end args) + (pulse-momentary-highlight-region start end)) + +(global-set-key (kbd "C-x C-b") #'ibuffer) ;;; Hooks (add-hook 'after-save-hook #'executable-make-buffer-file-executable-if-script-p) + (add-hook 'find-file-not-found-functions (defun create-missing-directories () "Automatically create missing directories." (let ((target-dir (file-name-directory buffer-file-name))) (unless (file-exists-p target-dir) (make-directory target-dir :parents))))) + (add-hook 'find-file-hook (defun vc-remote-off () "Turn VC off when remote." (when (file-remote-p (buffer-file-name)) (setq-local vc-handled-backends nil)))) +(add-hook 'after-init-hook + (defun after-init@emoji-font-setup () + "Set up emoji fonts after init." + (run-with-idle-timer + 1 nil (defun emoji-font-setup () + "Set up emoji fonts." + (let ((ffl (font-family-list))) + (dolist (font '("Noto Emoji" "Noto Color Emoji" + "Segoe UI Emoji" "Apple Color Emoji" + "FreeSans" "FreeMono" "FreeSerif" + "Unifont" "Symbola")) + (when (member font (font-family-list)) + (set-fontset-font t 'symbol + (font-spec :family font) + nil :add)))))))) + ;;; Advice (define-advice switch-to-buffer (:after (&rest _) normal-mode) @@ -373,4 +401,201 @@ See also `with-region-or-to-eol'." (use-package _acdw :load-path private/) +(use-package custom-allowed + :load-path "/home/case/src/emacs/custom-allowed/" + :config + (add-to-list 'custom-allowed-variables 'safe-local-variable-values) + (add-to-list 'custom-allowed-variables 'ispell-buffer-session-localwords) + (add-to-list 'custom-allowed-variables 'warning-suppress-types) + (add-to-list 'custom-allowed-variables 'calendar-latitude) + (add-to-list 'custom-allowed-variables 'calendar-longitude) + (add-to-list 'custom-allowed-variables 'user-full-name) + (add-to-list 'custom-allowed-variables 'user-mail-address) + :hook + (after-init-hook . custom-allowed-load-custom-file)) + +(use-package sophomore + :load-path "/home/case/src/emacs/sophomore/" + :config + (sophomore-enable-all) + (sophomore-disable 'view-hello-file + 'describe-gnu-project + 'suspend-frame) + (sophomore-mode)) + +(use-package compat + ;; This shouldn't be necessary, but sadly I believe that it is. + :ensure t) + +(use-package vertico + :ensure t :demand t + :config + (setq vertico-cycle t) + (vertico-mode)) + +(use-package vertico-directory + :after vertico + :bind (:map vertico-map + ("RET" . vertico-directory-enter) + ("DEL" . vertico-directory-delete-char) + ("M-DEL" . vertico-directory-delete-word)) + :hook (rfn-shadow-update-overlay-hook . vertico-directory-tidy)) + +(use-package vertico-mouse + :after vertico + :config (vertico-mouse-mode)) + +;; Example configuration for Consult +(use-package consult + :ensure t + ;; Replace bindings. Lazily loaded due by `use-package'. + :bind (;; C-c bindings (mode-specific-map) + ("C-c h" . consult-history) + ("C-c m" . consult-mode-command) + ("C-c k" . consult-kmacro) + ;; C-x bindings (ctl-x-map) + ("C-x M-:" . consult-complex-command) + ("C-x b" . consult-buffer) + ("C-x 4 b" . consult-buffer-other-window) + ("C-x 5 b" . consult-buffer-other-frame) + ("C-x r b" . consult-bookmark) + ("C-x p b" . consult-project-buffer) + ;; Custom M-# bindings for fast register access + ("M-#" . consult-register-load) + ("M-'" . consult-register-store) + ("C-M-#" . consult-register) + ;; Other custom bindings + ("M-y" . consult-yank-pop) + ;; M-g bindings (goto-map) + ("M-g e" . consult-compile-error) + ("M-g f" . consult-flymake) + ("M-g g" . consult-goto-line) + ("M-g M-g" . consult-goto-line) + ("M-g o" . consult-outline) + ("M-g m" . consult-mark) + ("M-g k" . consult-global-mark) + ("M-g i" . consult-imenu) + ("M-g I" . consult-imenu-multi) + ;; M-s bindings (search-map) + ("M-s d" . consult-find) + ("M-s D" . consult-locate) + ("M-s g" . consult-grep) + ("M-s G" . consult-git-grep) + ("M-s r" . consult-ripgrep) + ("M-s l" . consult-line) + ("M-s L" . consult-line-multi) + ("M-s k" . consult-keep-lines) + ("M-s u" . consult-focus-lines) + ;; Isearch integration + ("M-s e" . consult-isearch-history) + :map isearch-mode-map + ("M-e" . consult-isearch-history) + ("M-s e" . consult-isearch-history) + ("M-s l" . consult-line) + ("M-s L" . consult-line-multi) + ;; Minibuffer history + :map minibuffer-local-map + ("M-s" . consult-history) + ("M-r" . consult-history)) + + ;; Enable automatic preview at point in the *Completions* buffer. This is + ;; relevant when you use the default completion UI. + :hook (completion-list-mode . consult-preview-at-point-mode) + + ;; The :init configuration is always executed (Not lazy) + :init + + ;; Optionally configure the register formatting. This improves the register + ;; preview for `consult-register', `consult-register-load', + ;; `consult-register-store' and the Emacs built-ins. + (setq register-preview-delay 0.5 + register-preview-function #'consult-register-format) + + ;; Optionally tweak the register preview window. + ;; This adds thin lines, sorting and hides the mode line of the window. + (advice-add #'register-preview :override #'consult-register-window) + + (define-advice completing-read-multiple (:filter-args (args) indicator) + (cons (format "[CRM%s] %s" + (replace-regexp-in-string + "\\`\\[.*?]\\*\\|\\[.*?]\\*\\'" "" + crm-separator) + (car args)) + (cdr args))) + + ;; Use Consult to select xref locations with preview + (setq xref-show-xrefs-function #'consult-xref + xref-show-definitions-function #'consult-xref) + + (setq completion-in-region-function #'consult-completion-in-region) + + ;; Configure other variables and modes in the :config section, + ;; after lazily loading the package. + :config + + ;; Optionally configure preview. The default value + ;; is 'any, such that any key triggers the preview. + ;; (setq consult-preview-key 'any) + ;; (setq consult-preview-key (kbd "M-.")) + ;; (setq consult-preview-key (list (kbd "") (kbd ""))) + ;; For some commands and buffer sources it is useful to configure the + ;; :preview-key on a per-command basis using the `consult-customize' macro. + (consult-customize + consult-theme :preview-key '(:debounce 0.2 any) + consult-ripgrep consult-git-grep consult-grep + consult-bookmark consult-recent-file consult-xref + consult--source-bookmark consult--source-file-register + consult--source-recent-file consult--source-project-recent-file + ;; :preview-key (kbd "M-.") + :preview-key '(:debounce 0.4 any)) + + ;; Optionally configure the narrowing key. + ;; Both < and C-+ work reasonably well. + (setq consult-narrow-key "<") ;; (kbd "C-+") + + ;; Optionally make narrowing help available in the minibuffer. + ;; You may want to use `embark-prefix-help-command' or which-key instead. + (define-key consult-narrow-map (vconcat consult-narrow-key "?") + #'consult-narrow-help)) + +(use-package orderless + :ensure t :demand t + :init + (setopt completion-styles '(substring orderless basic) + completion-category-defaults nil + completion-category-overrides + '((file (styles basic partial-completion))))) + +(use-package marginalia + :ensure t :demand t + :config + (marginalia-mode)) + +(use-package embark + :ensure t + :bind + (("C-." . embark-act) + ("M-." . embark-dwim) + ("C-h B" . embark-bindings)) + :init + (setopt prefix-help-command #'embark-prefix-help-command) + :config + (add-to-list 'display-buffer-alist + '("\\`\\*Embark Collect \\(Live\\|Completions\\)\\*" + nil + (window-parameters (mode-line-format . none))))) + +(use-package embark-consult + :ensure t + :hook + (embark-collect-mode . consult-preview-at-point-mode)) + +(use-package undo-fu-session + :ensure t + :config + (setq undo-fu-session-incompatible-files + '("/COMMIT_EDITMSG\\'" + "/git-rebase-todo\\'")) + (global-undo-fu-session-mode)) + ;;; basics.el ends here -- cgit 1.4.1-21-gabe81