mirror of
https://github.com/pestctrl/emacs-config.git
synced 2026-02-16 08:14:15 +00:00
1038 lines
38 KiB
Org Mode
1038 lines
38 KiB
Org Mode
#+PROPERTY: header-args:emacs-lisp :tangle "~/.emacs.d/config-min.el" :comments both
|
|
|
|
* setup ssh keys
|
|
#+begin_src emacs-lisp
|
|
(use-package keychain-environment)
|
|
(require 'ssh-key-management)
|
|
(keychain-refresh-environment)
|
|
(rb/ssh-add)
|
|
#+end_src
|
|
* misc emacs settings
|
|
#+begin_src emacs-lisp
|
|
(setq garbage-collection-messages t)
|
|
|
|
(setq backup-directory-alist `(("." . ,(concat user-emacs-directory "backups"))))
|
|
|
|
(setq xref-history-storage #'xref-window-local-history)
|
|
|
|
(setq use-dialog-box nil)
|
|
|
|
;; Don't fricken suspend emacs
|
|
(when (eq #'suspend-frame
|
|
(key-binding (kbd "C-z")))
|
|
(global-set-key (kbd "C-z") nil))
|
|
|
|
;; Minibuffer reading
|
|
(setq switch-window-input-style 'minibuffer)
|
|
|
|
;; Help window select stuff
|
|
(setq help-window-select t)
|
|
|
|
;; I don't care about backup files, stop bothering me
|
|
(setq delete-old-versions t)
|
|
|
|
;; Stop creating lock files
|
|
(setq create-lockfiles nil)
|
|
|
|
;; ;; Undo tree is useful
|
|
(use-package undo-tree)
|
|
(setq undo-tree-history-directory-alist '(("." . "~/.emacs.d/undo"))
|
|
undo-tree-limit 8000000
|
|
undo-tree-auto-save-history nil)
|
|
(global-undo-tree-mode t)
|
|
(add-to-list 'undo-tree-incompatible-major-modes 'vterm-mode)
|
|
(add-to-list 'undo-tree-incompatible-major-modes 'compilation-mode)
|
|
|
|
;; Try out vundo instead?
|
|
;; (use-package vundo
|
|
;; :commands (vundo))
|
|
|
|
;; Beacon-mode
|
|
(use-package beacon)
|
|
(beacon-mode 1)
|
|
(setq beacon-blink-delay 0.1)
|
|
(setq beacon-color "#006400")
|
|
|
|
;; Use my fork of chinese-etzy
|
|
(load-file (ef "lisp/my-etzy.el"))
|
|
|
|
;; If I ever decide to turn on display-lines-mode, use relative line
|
|
;; numbering
|
|
(setq display-line-numbers-type 'relative)
|
|
|
|
;; Make sure shell and rgrep works in windows
|
|
(when (eq 'windows-nt system-type)
|
|
(setq-default explicit-shell-file-name "bash")
|
|
(setq shell-file-name "bash"))
|
|
|
|
;; Show the column number!
|
|
(column-number-mode t)
|
|
|
|
(global-set-key (kbd "C-x C-p") #'pp-macroexpand-last-sexp)
|
|
#+end_src
|
|
|
|
* switching keyboards
|
|
#+begin_src emacs-lisp
|
|
(require 'keyboard-toggle)
|
|
(exwm-global-set-key (kbd "s-a") #'my/toggle-keyboard)
|
|
#+end_src
|
|
* minibuffers
|
|
#+begin_src emacs-lisp
|
|
;; Allow minibuffer-ception
|
|
(setq enable-recursive-minibuffers t)
|
|
|
|
;; I like ido for finding files
|
|
;; (require 'ido)
|
|
;; (ido-mode 'file)
|
|
|
|
(use-package vertico
|
|
:demand t
|
|
:config
|
|
(require 'vertico-jumper)
|
|
(vertico-mode)
|
|
(vertico-multiform-mode)
|
|
(setq vertico-count 8)
|
|
|
|
(use-package consult
|
|
;; :bind (
|
|
;; ("C-x b" . consult-buffer) ;; orig. switch-to-buffer
|
|
;; ("C-x 4 b" . consult-buffer-other-window) ;; orig. switch-to-buffer-other-window
|
|
;; ("C-x 5 b" . consult-buffer-other-frame) ;; orig. switch-to-buffer-other-frame
|
|
;; ("C-x t b" . consult-buffer-other-tab) ;; orig. switch-to-buffer-other-tab
|
|
;; )
|
|
)
|
|
|
|
(setq completion-in-region-function
|
|
(lambda (&rest args)
|
|
(apply (if vertico-mode
|
|
#'consult-completion-in-region
|
|
#'completion--in-region)
|
|
args)))
|
|
|
|
(use-package affe
|
|
:config
|
|
(defun my/affe-find (&optional dir initial)
|
|
"Fuzzy find in DIR with optional INITIAL input."
|
|
(interactive "P")
|
|
(pcase-let* ((`(,prompt ,paths ,dir) (consult--directory-prompt "Fuzzy find" dir))
|
|
(default-directory dir))
|
|
(consult--read
|
|
(thread-first (consult--async-sink)
|
|
(consult--async-refresh-timer 0.05)
|
|
(consult--async-map (lambda (x) (string-remove-prefix "./" x)))
|
|
(affe--async (affe--command affe-find-command paths))
|
|
(consult--async-split #'consult--split-nil))
|
|
:prompt prompt
|
|
:sort nil
|
|
:require-match t
|
|
:history '(:input affe--find-history)
|
|
:initial initial
|
|
:category 'file
|
|
:add-history (thing-at-point 'filename)
|
|
:state (lambda (action cand)
|
|
(when (and cand (eq action 'return))
|
|
(find-file (expand-file-name cand dir)))))))
|
|
|
|
(advice-add #'affe-find
|
|
:override
|
|
#'my/affe-find)
|
|
|
|
(with-eval-after-load 'projectile
|
|
(define-key projectile-command-map (kbd "F") #'affe-find)
|
|
(define-key projectile-command-map (kbd "s G") #'affe-grep))
|
|
|
|
(with-eval-after-load 'llvm-shared
|
|
(defun affe-quick-prompt-dirs (orig &optional dir initial)
|
|
(message "%s" dir)
|
|
(cl-flet ((dir-plus-subdirs
|
|
(dir)
|
|
(cons dir
|
|
(->>
|
|
(directory-files "/scratch/benson/tools4/cgt" t "[^.]")
|
|
(remove-if #'(lambda (dir) (not (file-directory-p dir))))
|
|
(mapcar #'(lambda (x) (file-name-as-directory x)))))))
|
|
(-->
|
|
(not (equal '(16) dir))
|
|
(if it default-directory
|
|
(completing-read "Quick select directory?"
|
|
`(,(expand-file-name "lib/Target/Argo/"
|
|
(lls/conf-get 'build-release-dir))
|
|
,(expand-file-name "lib/Target/Argo/"
|
|
(lls/conf-get 'build-debug-dir))
|
|
,(expand-file-name "llvm/lib/Target/Argo/"
|
|
(lls/get-llvm-root-dir))
|
|
,(expand-file-name "llvm_cgt/argo/"
|
|
(lls/conf-aux-get 'tools-directory))
|
|
,@(dir-plus-subdirs
|
|
(expand-file-name "cgt/"
|
|
(lls/conf-aux-get 'tools-directory))))))
|
|
(let ((default-directory it))
|
|
(funcall orig dir initial)))))
|
|
|
|
(advice-add #'affe-find
|
|
:around
|
|
#'affe-quick-prompt-dirs)))
|
|
|
|
(setq vertico-multiform-commands
|
|
'((find-file flat (vertico-cycle . t))))
|
|
|
|
;; (setq vertico-multiform-categories
|
|
;; '((file flat (vertico-cycle . t))))
|
|
|
|
(use-package embark)
|
|
(define-key *root-map* (kbd "C-o") #'embark-act)
|
|
(define-key embark-buffer-map (kbd "e") #'embark-export)
|
|
|
|
(advice-add #'vertico--format-candidate
|
|
:around
|
|
#'my/highlight-active-mode)
|
|
|
|
(defun my/is-mode-enabled (str)
|
|
(let ((symbol (intern str)))
|
|
(when (fboundp symbol)
|
|
(if (not (boundp symbol))
|
|
(eq major-mode symbol)
|
|
(eval symbol)))))
|
|
|
|
(defface vertico-current-mode-enabled `((t (:foreground "cyan" :extend t :inherit vertico-current))) nil)
|
|
|
|
(defun my/highlight-active-mode (orig cand prefix suffix index _start)
|
|
(let ((res (funcall orig cand prefix suffix index _start)))
|
|
(cond ((not (my/is-mode-enabled cand))
|
|
res)
|
|
((= index vertico--index)
|
|
(propertize res 'face 'vertico-current-mode-enabled))
|
|
(t (propertize res 'face font-lock-keyword-face))))))
|
|
|
|
(use-package vertico-directory
|
|
:after vertico
|
|
:ensure nil
|
|
;; More convenient directory navigation commands
|
|
:bind (:map vertico-map
|
|
("RET" . vertico-directory-enter)
|
|
("DEL" . vertico-directory-delete-char)
|
|
("M-DEL" . vertico-directory-delete-word)
|
|
("C-s" . vertico-next))
|
|
;; Tidy shadowed file names
|
|
:hook (rfn-eshadow-update-overlay . vertico-directory-tidy)
|
|
:config
|
|
(defun my/should-backwards-tramp ()
|
|
(and (not (eq (char-before) ?:))
|
|
(not (eq (char-before) ?@))
|
|
(save-excursion
|
|
(re-search-backward "@" nil t))
|
|
(save-excursion
|
|
(re-search-backward "/" nil t))
|
|
(< (save-excursion
|
|
(re-search-backward "/" nil t)
|
|
(point))
|
|
(save-excursion
|
|
(re-search-backward "@" nil t)
|
|
(point)))))
|
|
|
|
(defun my/vertico-directory-up (&optional n)
|
|
(interactive "p")
|
|
(when (and (> (point) (minibuffer-prompt-end))
|
|
(or (eq (char-before) ?/)
|
|
(my/should-backwards-tramp))
|
|
(eq 'file (vertico--metadata-get 'category)))
|
|
(let ((path (buffer-substring (minibuffer-prompt-end) (point))) found)
|
|
(when (string-match-p "\\`~[^/]*/\\'" path)
|
|
(delete-minibuffer-contents)
|
|
(insert (expand-file-name path)))
|
|
(dotimes (_ n found)
|
|
(save-excursion
|
|
(let ((end (point)))
|
|
(goto-char (1- end))
|
|
(when (re-search-backward (rx (or "/" "@" ":")) (minibuffer-prompt-end) t)
|
|
(delete-region (1+ (point)) end)
|
|
(setq found t))))))))
|
|
|
|
(advice-add #'vertico-directory-up
|
|
:override
|
|
#'my/vertico-directory-up))
|
|
|
|
;; Optionally use the `orderless' completion style. See
|
|
;; `+orderless-dispatch' in the Consult wiki for an advanced Orderless style
|
|
;; dispatcher. Additionally enable `partial-completion' for file path
|
|
;; expansion. `partial-completion' is important for wildcard support.
|
|
;; Multiple files can be opened at once with `find-file' if you enter a
|
|
;; wildcard. You may also give the `initials' completion style a try.
|
|
(use-package orderless
|
|
:init
|
|
;; Configure a custom style dispatcher (see the Consult wiki)
|
|
;; (setq orderless-style-dispatchers '(+orderless-dispatch)
|
|
;; orderless-component-separator #'orderless-escapable-split-on-space)
|
|
(setq completion-styles '(orderless basic)
|
|
completion-category-defaults nil
|
|
completion-category-overrides '((file (styles basic partial-completion)))))
|
|
|
|
;; Persist history over Emacs restarts. Vertico sorts by history position.
|
|
(use-package savehist
|
|
:init
|
|
(savehist-mode))
|
|
|
|
(use-package marginalia
|
|
:after vertico
|
|
:custom
|
|
(marginalia-annotators '(marginalia-annotators-heavy marginalia-annotators-light nil))
|
|
(marginalia-align 'left)
|
|
(marginalia-align-offset (if my/puppet-p 20 100))
|
|
:init
|
|
(marginalia-mode))
|
|
|
|
;; (defun basic-remote-try-completion (string table pred point)
|
|
;; (and (vertico--remote-p string)
|
|
;; (completion-basic-try-completion string table pred point)))
|
|
;; (defun basic-remote-all-completions (string table pred point)
|
|
;; (and (vertico--remote-p string)
|
|
;; (completion-basic-all-completions string table pred point)))
|
|
;; (add-to-list
|
|
;; 'completion-styles-alist
|
|
;; '(basic-remote basic-remote-try-completion basic-remote-all-completions nil))
|
|
;; (setq completion-styles '(orderless basic)
|
|
;; completion-category-overrides '((file (styles basic-remote partial-completion))))
|
|
#+end_src
|
|
* navigation
|
|
#+begin_src emacs-lisp
|
|
(defun update-window-third-height (&optional arg &rest ignore)
|
|
(let ((win
|
|
(cond ((framep arg)
|
|
(frame-selected-window arg))
|
|
((windowp arg)
|
|
arg)
|
|
((null arg) (selected-window)))))
|
|
;; (message "Updating window height for %s" (window-buffer win))
|
|
(when (not (active-minibuffer-window))
|
|
(setq next-screen-context-lines
|
|
(max 1 (* 2 (/ (window-height win) 3)))))))
|
|
|
|
(update-window-third-height)
|
|
|
|
(add-hook 'window-selection-change-functions
|
|
#'update-window-third-height)
|
|
|
|
(add-hook 'window-configuration-change-hook
|
|
#'update-window-third-height)
|
|
|
|
(advice-add #'select-window
|
|
:after
|
|
'update-window-third-height)
|
|
|
|
;; Word navigation
|
|
(global-set-key (kbd "M-f") 'forward-to-word)
|
|
(global-set-key (kbd "M-F") 'forward-word)
|
|
|
|
;; Goto-char
|
|
(require 'brumlow-goto-char)
|
|
(global-set-key (kbd "M-m") #'jump-to-char)
|
|
#+end_src
|
|
* window manipulation
|
|
#+begin_src emacs-lisp
|
|
;; The prefix
|
|
(define-prefix-command '*window-map*)
|
|
(define-key *root-map* (kbd "w") '*window-map*)
|
|
|
|
;; Side-window stuff
|
|
(use-package resize-window)
|
|
(require 'side-window-split)
|
|
|
|
(defun side-window-exwm-hide-window (buffer alist)
|
|
(when-let (window (and (with-current-buffer buffer
|
|
(eq major-mode 'exwm-mode))
|
|
(get-buffer-window buffer)))
|
|
(with-selected-window window
|
|
(previous-buffer))))
|
|
|
|
(advice-add #'display-buffer-in-side-window
|
|
:before
|
|
#'side-window-exwm-hide-window)
|
|
|
|
(setq window-sides-vertical t)
|
|
(define-key *window-map* (kbd "j") 'side-bottom-window)
|
|
(define-key *window-map* (kbd "k") 'side-top-window)
|
|
(define-key *window-map* (kbd "h") 'side-left-window)
|
|
(define-key *window-map* (kbd "l") 'side-right-window)
|
|
(define-key *window-map* (kbd "d") 'side-window-delete-all)
|
|
(define-key *window-map* (kbd "r") 'resize-window)
|
|
|
|
(global-set-key (kbd "C-x 4 B") #'my/display-buffer-in-side-window)
|
|
(global-set-key (kbd "C-x 4 F") #'my/find-file-side-window)
|
|
(global-set-key (kbd "C-x 4 )") #'side-window-delete-all)
|
|
|
|
;; Dedicated window
|
|
(defun my/toggle-dedicated-window ()
|
|
(interactive)
|
|
(let ((win (selected-window)))
|
|
(set-window-dedicated-p win (not (window-dedicated-p win)))))
|
|
#+end_src
|
|
* dired
|
|
#+begin_src emacs-lisp
|
|
;; I like dired+'s formatting for listing files
|
|
(use-package dired+
|
|
:ensure nil
|
|
:quelpa (dired+ :fetcher "github" :repo "emacsmirror/dired-plus" :branch "master"))
|
|
(require 'dired+)
|
|
(setq diredp-hide-details-initially-flag nil)
|
|
(setq diredp-hide-details-propagate-flag nil)
|
|
|
|
(defun dired-mark-pop-up (buffer-or-name op-symbol files function &rest args)
|
|
"Return FUNCTION's result on ARGS after showing which files are marked.
|
|
Displays the file names in a window showing a buffer named
|
|
BUFFER-OR-NAME; the default name being \" *Marked Files*\". The
|
|
window is not shown if there is just one file, `dired-no-confirm'
|
|
is t, or OP-SYMBOL is a member of the list in `dired-no-confirm'.
|
|
|
|
By default, Dired shrinks the display buffer to fit the marked files.
|
|
To disable this, use the Customization interface to add a new rule
|
|
to `display-buffer-alist' where condition regexp is \"^ \\*Marked Files\\*$\",
|
|
action argument symbol is `window-height' and its value is nil.
|
|
|
|
FILES is the list of marked files. It can also be (t FILENAME)
|
|
in the case of one marked file, to distinguish that from using
|
|
just the current file.
|
|
|
|
FUNCTION should not manipulate files, just read input (an
|
|
argument or confirmation)."
|
|
(if (or (eq dired-no-confirm t)
|
|
(memq op-symbol dired-no-confirm)
|
|
;; If FILES defaulted to the current line's file.
|
|
(= (length files) 1))
|
|
(apply function args)
|
|
(let ((buffer (get-buffer-create (or buffer-or-name " *Marked Files*")))
|
|
;; Mark *Marked Files* window as softly-dedicated, to prevent
|
|
;; other buffers e.g. *Completions* from reusing it (bug#17554).
|
|
(display-buffer-mark-dedicated 'soft))
|
|
(with-current-buffer-window
|
|
buffer
|
|
`(display-buffer-below-selected
|
|
(window-height . fit-window-to-buffer)
|
|
(preserve-size . (nil . t))
|
|
(body-function
|
|
. ,#'(lambda (_window)
|
|
;; Handle (t FILE) just like (FILE), here. That value is
|
|
;; used (only in some cases), to mean just one file that was
|
|
;; marked, rather than the current line file.
|
|
(dired-format-columns-of-files
|
|
(if (eq (car files) t) (cdr files) files))
|
|
(remove-text-properties (point-min) (point-max)
|
|
'(mouse-face nil help-echo nil))
|
|
(setq tab-line-exclude nil))))
|
|
#'(lambda (window _value)
|
|
(with-selected-window window
|
|
(unwind-protect
|
|
(apply function args)
|
|
(when (window-live-p window)
|
|
(quit-restore-window window 'kill)))))))))
|
|
|
|
;; This hook is neat, I get to see how far down the file I
|
|
;; am. However, it's way too slow. Causes doom-modeline to lock up in
|
|
;; redisplay. Disabling for now.
|
|
(remove-hook 'dired-after-readin-hook 'diredp-nb-marked-in-mode-name)
|
|
(remove-hook 'dired-mode-hook 'diredp-nb-marked-in-mode-name)
|
|
|
|
;; dired configuration
|
|
(setq dired-dwim-target t)
|
|
(setq dired-listing-switches "-alh --group-directories-first --sort=extension")
|
|
|
|
(when (string-match-p ".*NATIVE_COMP.*" system-configuration-features)
|
|
(require 'dired-native-compile)
|
|
(define-key dired-mode-map (kbd "B") #'dired-do-native-compile))
|
|
|
|
;; diredx lets me hide stuff I don't want to see
|
|
(require 'dired-x)
|
|
(add-hook 'dired-mode-hook (lambda () (dired-omit-mode)))
|
|
(setq dired-omit-files (concat dired-omit-files "\\|^\\..+$"))
|
|
|
|
;; Useful for traversing folders
|
|
(use-package dired-subtree)
|
|
|
|
(define-key dired-mode-map (kbd "<tab>") 'dired-subtree-insert)
|
|
(define-key dired-mode-map (kbd "<backtab>") 'dired-subtree-remove)
|
|
#+end_src
|
|
* emacs lisp
|
|
#+begin_src emacs-lisp
|
|
;; These are the programming facilities I like the most for a minimal
|
|
;; setup for emacs-lisp programming
|
|
|
|
;; Don't leave any whitespace on the end of lines in a file.
|
|
(use-package ws-butler)
|
|
(ws-butler-global-mode t)
|
|
|
|
;; Errors
|
|
(use-package flycheck)
|
|
(add-to-list 'display-buffer-alist
|
|
`(,(rx bos "*Flycheck errors*" eos)
|
|
(display-buffer-reuse-window
|
|
display-buffer-in-side-window)
|
|
(side . bottom)
|
|
(reusable-frames . visible)
|
|
(window-height . 0.10)))
|
|
|
|
;; Autocompletion
|
|
(use-package corfu
|
|
:after orderless
|
|
:custom
|
|
(corfu-quit-at-boundary t)
|
|
(corfu-quit-no-match t)
|
|
(corfu-cycle t)
|
|
(corfu-auto t)
|
|
:init
|
|
(add-hook 'prog-mode-hook
|
|
'corfu-mode)
|
|
:config
|
|
(unless window-system
|
|
(use-package corfu-terminal)
|
|
(corfu-terminal-mode 1))
|
|
(when my-ec/enable-exwm
|
|
(require 'corfu-hack)))
|
|
|
|
;; Magit
|
|
(use-package magit)
|
|
(use-package magit-popup)
|
|
;; (use-package magit-todos
|
|
;; :config
|
|
;; (require 'hl-todo)
|
|
;; (add-to-list 'hl-todo-keyword-faces
|
|
;; '("TODO(pestctrl)" . "#FFFFFF"))
|
|
;; (add-to-list 'magit-todos-keywords-list
|
|
;; "TODO(pestctrl)")
|
|
;; (magit-todos-mode 1))
|
|
;; Todo: Figure out why transient side-window stuff wrecks my
|
|
;; side-window stuff
|
|
(setq transient-display-buffer-action
|
|
'(display-buffer-in-side-window
|
|
(side . left)
|
|
(dedicated . t)
|
|
(inhibit-same-window . t)))
|
|
(global-set-key (kbd "C-x g") 'magit-status)
|
|
(global-set-key (kbd "C-x M-g") 'magit-dispatch)
|
|
(require 'magit-overrides)
|
|
|
|
;; Magit uses ediff
|
|
(with-eval-after-load 'ediff
|
|
(setq ediff-window-setup-function 'ediff-setup-windows-plain
|
|
ediff-split-window-function 'split-window-horizontally)
|
|
|
|
(defun ediff-clear-up-windows (&rest optional)
|
|
(let ((tab-name (alist-get 'name (tab-bar--current-tab))))
|
|
(unless (string-match-p "-ediff$" tab-name)
|
|
(switch-or-create-tab (concat tab-name "-ediff"))))
|
|
(when (window-parameter (selected-window) 'window-side)
|
|
(window-toggle-side-windows))
|
|
(let ((ignore-window-parameters t))
|
|
(delete-other-windows)))
|
|
|
|
(advice-add #'ediff-setup
|
|
:before
|
|
#'ediff-clear-up-windows)
|
|
|
|
(require 'ediff-transition)
|
|
|
|
(advice-add #'ediff-quit
|
|
:after
|
|
#'tab-bar-close-tab)
|
|
|
|
(defun ediff-copy-both-to-C ()
|
|
(interactive)
|
|
(ediff-copy-diff ediff-current-difference nil 'C nil
|
|
(concat
|
|
(ediff-get-region-contents ediff-current-difference 'A ediff-control-buffer)
|
|
(ediff-get-region-contents ediff-current-difference 'B ediff-control-buffer))))
|
|
(defun add-d-to-ediff-mode-map () (define-key ediff-mode-map "d" 'ediff-copy-both-to-C))
|
|
(add-hook 'ediff-keymap-setup-hook 'add-d-to-ediff-mode-map)
|
|
(set-face-attribute 'ediff-even-diff-A nil :background "midnight blue")
|
|
(set-face-attribute 'ediff-even-diff-Ancestor nil :background "midnight blue")
|
|
(set-face-attribute 'ediff-even-diff-B nil :background "midnight blue")
|
|
(set-face-attribute 'ediff-even-diff-C nil :background "midnight blue")
|
|
(set-face-attribute 'ediff-odd-diff-A nil :background "midnight blue")
|
|
(set-face-attribute 'ediff-odd-diff-Ancestor nil :background "midnight blue")
|
|
(set-face-attribute 'ediff-odd-diff-B nil :background "midnight blue")
|
|
(set-face-attribute 'ediff-odd-diff-C nil :background "midnight blue")
|
|
|
|
;; (set-face-attribute 'ediff-odd-diff-A nil :background "gray30")
|
|
;; (set-face-attribute 'ediff-odd-diff-B nil :background "gray30")
|
|
;; (set-face-attribute 'ediff-even-diff-A nil :background "#5c370f")
|
|
;; (set-face-attribute 'ediff-even-diff-B nil :background "#5c370f")
|
|
;; ;; (set-face-attribute 'ediff-current-diff-A nil :background "")
|
|
;; (set-face-attribute 'ediff-current-diff-B nil :background "dark green")
|
|
)
|
|
|
|
(with-eval-after-load 'diff
|
|
(set-face-attribute 'diff-header nil :background "gray20")
|
|
(set-face-attribute 'diff-file-header nil :background "gray20")
|
|
(set-face-attribute 'diff-function nil :background "midnight blue")
|
|
(set-face-attribute 'diff-added nil :background "#104010")
|
|
(set-face-attribute 'diff-refine-added nil :background "#308030"))
|
|
|
|
;; Paredit
|
|
(use-package paredit
|
|
:bind (:map paredit-mode-map
|
|
("M-?" . nil))
|
|
:hook ((emacs-lisp-mode . paredit-mode)
|
|
(lisp-mode . paredit-mode)))
|
|
|
|
;; Paren highlighting
|
|
(show-paren-mode t)
|
|
|
|
;; Rainbow parens
|
|
(use-package rainbow-delimiters)
|
|
(add-hook 'prog-mode-hook #'rainbow-delimiters-mode)
|
|
|
|
;; Which function
|
|
(which-function-mode 1)
|
|
|
|
;; Macroexpander
|
|
(use-package macrostep)
|
|
|
|
(define-key macrostep-keymap (kbd "C-c C-c") nil)
|
|
|
|
(define-key macrostep-keymap (kbd "DEL") nil)
|
|
(define-key macrostep-keymap (kbd "c") nil)
|
|
(define-key macrostep-keymap (kbd "u") nil)
|
|
(define-key macrostep-keymap (kbd "C-c q") #'macrostep-collapse)
|
|
;; (define-key macrostep-keymap (kbd "q") #'macrostep-collapse)
|
|
|
|
(define-key macrostep-keymap (kbd "RET") nil)
|
|
(define-key macrostep-keymap (kbd "e") nil)
|
|
(define-key emacs-lisp-mode-map (kbd "C-c e") #'macrostep-expand)
|
|
|
|
|
|
(define-key macrostep-keymap (kbd "n") nil)
|
|
(define-key macrostep-keymap (kbd "C-c C-n") #'macrostep-next-macro)
|
|
|
|
(define-key macrostep-keymap (kbd "p") nil)
|
|
(define-key macrostep-keymap (kbd "C-c C-p") #'macrostep-prev-macro)
|
|
|
|
;; Auto highlighting of symbols
|
|
(use-package auto-highlight-symbol)
|
|
(add-hook 'prog-mode-hook
|
|
'auto-highlight-symbol-mode)
|
|
|
|
;; wgrep
|
|
(use-package wgrep)
|
|
|
|
;; Use cursors, sooo good
|
|
(use-package multiple-cursors)
|
|
|
|
(define-prefix-command '*multiple-cursors-map*)
|
|
(define-key *multiple-cursors-map* (kbd "a") 'mc/mark-all-like-this)
|
|
(define-key *multiple-cursors-map* (kbd "A") 'mc/vertical-align)
|
|
(define-key *multiple-cursors-map* (kbd "SPC") 'mc/vertical-align-with-space)
|
|
(define-key *multiple-cursors-map* (kbd "n") 'mc/insert-numbers)
|
|
|
|
(defhydra mc-interactive (*multiple-cursors-map* "i")
|
|
"For those looping commands"
|
|
("n" mc/mark-next-like-this)
|
|
("p" mc/mark-previous-like-this)
|
|
("s" mc/skip-to-next-like-this)
|
|
("S" mc/skip-to-previous-like-this)
|
|
("q" nil))
|
|
|
|
(global-set-key (kbd "C-c m") '*multiple-cursors-map*)
|
|
|
|
;; Space and tab configuration
|
|
(setq default-tab-width 4)
|
|
(setq-default indent-tabs-mode nil)
|
|
(setq-default tab-width 4)
|
|
|
|
;; If I have to switch to viewing tabs
|
|
(defun my/TABS (num)
|
|
(interactive "p")
|
|
(setq tab-width (if (= num 1)
|
|
8
|
|
num)))
|
|
|
|
;; Eval buffer, slime-ism
|
|
(define-key emacs-lisp-mode-map (kbd "C-c C-k") #'eval-buffer)
|
|
|
|
;; Make scratch buffers out of nowhere!
|
|
(require 'cl)
|
|
(defun scratch-buffer ()
|
|
(interactive)
|
|
(let ((count 0))
|
|
(while (get-buffer (format "*scratch%d*" count))
|
|
(cl-incf count))
|
|
(let ((buff (get-buffer-create (format "*scratch%d*" count))))
|
|
(with-current-buffer buff
|
|
(lisp-interaction-mode)
|
|
(insert (substitute-command-keys initial-scratch-message)))
|
|
(display-buffer-same-window buff nil))))
|
|
|
|
;; Eval and replace
|
|
(defun my/eval-and-replace ()
|
|
"Replace the preceding sexp with its value."
|
|
(interactive)
|
|
(backward-kill-sexp)
|
|
(condition-case nil
|
|
(prin1 (eval (read (current-kill 0)))
|
|
(current-buffer))
|
|
(error (message "Invalid expression")
|
|
(insert (current-kill 0)))))
|
|
|
|
(define-key emacs-lisp-mode-map (kbd "C-c C-e") 'my/eval-and-replace)
|
|
|
|
;; Use cider's eval expression
|
|
(use-package cider)
|
|
(autoload 'cider--make-result-overlay "cider-overlays")
|
|
|
|
(defun endless/eval-overlay (value point)
|
|
(let ((comment-start ";;"))
|
|
(cider--make-result-overlay (format "%S" value)
|
|
:where point
|
|
:duration 'command))
|
|
value)
|
|
|
|
(advice-add 'eval-region :around
|
|
(lambda (f beg end &rest r)
|
|
(endless/eval-overlay
|
|
(apply f beg end r)
|
|
end)))
|
|
|
|
(advice-add 'eval-last-sexp :filter-return
|
|
(lambda (r)
|
|
(endless/eval-overlay r (point))))
|
|
|
|
(advice-add 'eval-defun :filter-return
|
|
(lambda (r)
|
|
(endless/eval-overlay
|
|
r
|
|
(save-excursion
|
|
(end-of-defun)
|
|
(point)))))
|
|
|
|
;; expand-region
|
|
(use-package expand-region
|
|
:commands er/expand-region
|
|
:bind (("M-E" . #'er/expand-region)))
|
|
|
|
;; Banner comments
|
|
(unless my-ec/at-ti
|
|
(use-package banner-comment
|
|
:commands banner-comment
|
|
:bind (("C-c b" . #'banner-comment))))
|
|
|
|
(add-hook 'lisp-mode-hook
|
|
(lambda () (setq comment-start ";; ")))
|
|
|
|
(add-hook 'emacs-lisp-mode-hook
|
|
(lambda () (setq comment-start ";; ")))
|
|
|
|
;; re-builder
|
|
(require 're-builder)
|
|
(setq reb-re-syntax 'rx)
|
|
#+end_src
|
|
* ibuffer
|
|
#+begin_src emacs-lisp
|
|
(global-set-key (kbd "C-x C-b") 'ibuffer)
|
|
|
|
(setq ibuffer-show-empty-filter-groups nil)
|
|
|
|
(add-hook 'ibuffer-mode-hook
|
|
#'(lambda ()
|
|
(ibuffer-switch-to-saved-filter-groups "default")
|
|
(ibuffer-do-sort-by-custom)
|
|
;; (ibuffer-auto-mode)
|
|
))
|
|
|
|
(require 'ibuf-ext)
|
|
|
|
(define-key ibuffer-mode-map my/keymap-key nil)
|
|
|
|
(with-eval-after-load "ibuf-ext"
|
|
(define-ibuffer-filter directory-name
|
|
"Filter files in the agenda folder"
|
|
(:description "agenda")
|
|
(and (buffer-file-name buf)
|
|
(string-match qualifier
|
|
(buffer-file-name buf))))
|
|
|
|
(define-ibuffer-sorter custom
|
|
"My custom ibuffer sorter."
|
|
(:description "custom")
|
|
(cl-labels ((exwm-name-or-directory (buffer)
|
|
(with-current-buffer buffer
|
|
(if (eq major-mode 'exwm-mode)
|
|
(downcase (buffer-name))
|
|
(concat
|
|
(symbol-name major-mode)
|
|
" - "
|
|
(or (ibuffer-buffer-file-name)
|
|
""))))))
|
|
(not
|
|
(string-greaterp (downcase (or (exwm-name-or-directory (car a)) ""))
|
|
(downcase (or (exwm-name-or-directory (car b)) "")))))))
|
|
|
|
(add-to-list 'ibuffer-never-show-predicates
|
|
#'(lambda (buf)
|
|
(with-current-buffer buf
|
|
(eq major-mode 'helm-major-mode))))
|
|
|
|
(setq ibuffer-saved-filter-groups
|
|
'(("default"
|
|
("X-Windows" (mode . exwm-mode))
|
|
("Terminals" (or (mode . vterm-mode)
|
|
(mode . term-mode)))
|
|
("emacs-config" (and (or (filename . ".emacs.d")
|
|
(filename . "emacs-config"))
|
|
(not (mode . magit-status-mode))
|
|
(not (mode . magit-log-mode))
|
|
(not (mode . magit-diff-mode))
|
|
(not (mode . magit-process-mode))))
|
|
("code-aux" (or (mode . slime-repl-mode)
|
|
(mode . slime-mode)
|
|
(mode . magit-status-mode)
|
|
(mode . magit-status-mode)
|
|
(mode . magit-log-mode)
|
|
(mode . magit-diff-mode)
|
|
(mode . magit-process-mode)
|
|
(mode . ein:notebooklist-mode)
|
|
(mode . cider-repl-mode)
|
|
(mode . comint-mode)
|
|
(mode . makefile-gmake-mode)
|
|
(mode . conf-space-mode)
|
|
(mode . sh-mode)))
|
|
("code" (and (predicate . (not (file-remote-p default-directory)))
|
|
(or (mode . perl-mode)
|
|
(mode . asm-mode)
|
|
(mode . php-mode)
|
|
(mode . clojure-mode)
|
|
(mode . csharp-mode)
|
|
(mode . c++-mode)
|
|
(mode . c-mode)
|
|
(mode . scala-mode)
|
|
(mode . emacs-lisp-mode)
|
|
(mode . java-mode)
|
|
(mode . js-mode)
|
|
(mode . python-mode)
|
|
(mode . ng2-ts-mode)
|
|
(mode . lisp-mode)
|
|
(mode . ein:notebook-multilang-mode)
|
|
(mode . llvm-mode))))
|
|
("web" (or (mode . web-mode)
|
|
(mode . mhtml-mode)
|
|
(mode . js2-mode)
|
|
(mode . css-mode)))
|
|
("Org Mode" (and (mode . org-mode)
|
|
(not (directory-name . "agenda"))))
|
|
("Shell" (or (mode . shell-mode)
|
|
(mode . compilation-mode)))
|
|
("text" (filename . "\\.txt"))
|
|
("pdfs" (or (mode . doc-view-mode)
|
|
(mode . pdf-view-mode)))
|
|
("Agenda Buffers" (mode . org-agenda-mode))
|
|
("Agenda Files" (mode . org-mode))
|
|
("folders" (and (mode . dired-mode)
|
|
(predicate . (not (file-remote-p default-directory)))))
|
|
("tramp" (predicate . (file-remote-p default-directory)))
|
|
("Help" (or (name . "\*Help\*")
|
|
(name . "\*Apropos\*")
|
|
(name . "\*info\*"))))))
|
|
|
|
(defun ibuffer-find-file-with-ido ()
|
|
"Like `find-file', but default to the directory of the buffer at point."
|
|
(interactive)
|
|
(let ((completing-read-function #'ido-completing-read)
|
|
(default-directory (let ((buf (ibuffer-current-buffer)))
|
|
(if (buffer-live-p buf)
|
|
(with-current-buffer buf
|
|
default-directory)
|
|
default-directory))))
|
|
(call-interactively #'ido-find-file)))
|
|
|
|
;; (define-key ibuffer-mode-map (kbd "C-x C-f") #'ibuffer-find-file-with-ido)
|
|
#+end_src
|
|
* useful tools
|
|
** org-mode
|
|
#+begin_src emacs-lisp
|
|
(require 'org)
|
|
|
|
(setq org-src-window-setup 'current-window)
|
|
(setq org-use-speed-commands t)
|
|
#+end_src
|
|
*** Indent look
|
|
#+begin_src emacs-lisp
|
|
(setq org-startup-indented t)
|
|
|
|
(defun my/org-indent-prefixes ()
|
|
"Compute prefix strings for regular text and headlines."
|
|
(setq org-indent--heading-line-prefixes
|
|
(make-vector org-indent--deepest-level nil))
|
|
(setq org-indent--inlinetask-line-prefixes
|
|
(make-vector org-indent--deepest-level nil))
|
|
(setq org-indent--text-line-prefixes
|
|
(make-vector org-indent--deepest-level nil))
|
|
(dotimes (n org-indent--deepest-level)
|
|
(let ((indentation (if (<= n 1) 0
|
|
(* (1- org-indent-indentation-per-level)
|
|
(1- n)))))
|
|
;; Headlines line prefixes.
|
|
(let ((heading-prefix ""))
|
|
(aset org-indent--heading-line-prefixes
|
|
n
|
|
(org-add-props heading-prefix nil 'face 'org-indent))
|
|
;; Inline tasks line prefixes
|
|
(aset org-indent--inlinetask-line-prefixes
|
|
n
|
|
(cond ((<= n 1) "")
|
|
((bound-and-true-p org-inlinetask-show-first-star)
|
|
(concat org-indent-inlinetask-first-star
|
|
(substring heading-prefix 1)))
|
|
(t (org-add-props heading-prefix nil 'face 'org-indent)))))
|
|
;; Text line prefixes.
|
|
(aset org-indent--text-line-prefixes
|
|
n
|
|
(org-add-props
|
|
(concat (make-string (if (< n 2) n
|
|
(1+ indentation)) ?\s)
|
|
(and (> n 0)
|
|
(char-to-string org-indent-boundary-char)))
|
|
nil 'face 'org-indent)))))
|
|
|
|
|
|
(advice-add #'org-indent--compute-prefixes
|
|
:override
|
|
#'my/org-indent-prefixes)
|
|
#+end_src
|
|
** terminal
|
|
#+begin_src emacs-lisp
|
|
(if (eq system-type 'windows-nt)
|
|
(define-key *root-map* "c" #'shell)
|
|
(quelpa '(vterm))
|
|
(require 'multi-vterm-tabs)
|
|
(use-package vterm
|
|
:ensure nil
|
|
:commands vterm vterm-kill
|
|
:bind (("C-x 4 t" . #'find-vterm-other-window)
|
|
:map *root-map*
|
|
("c" . #'multi-vterm-tab))
|
|
:config
|
|
(add-to-list 'vterm-tramp-shells
|
|
'("ssh" "/bin/bash"))
|
|
|
|
(add-to-list 'vterm-tramp-shells
|
|
'("sudo" "/bin/bash"))
|
|
|
|
(setq ansi-color-names-vector
|
|
["black" "red3" "green3" "yellow3" "DodgerBlue2" "magenta3" "cyan3" "gray90"])
|
|
|
|
(set-face-attribute 'term-bold nil :weight 'bold)
|
|
(set-face-attribute 'vterm-color-blue nil :foreground "DodgerBlue2")
|
|
|
|
(define-key vterm-mode-map my/keymap-key nil)
|
|
|
|
(defun vterm/delete-to-side (arg)
|
|
(interactive "P")
|
|
(if arg
|
|
(vterm-send "C-u")
|
|
(vterm-send "C-k")))
|
|
|
|
(define-key vterm-mode-map (kbd "C-k") #'vterm/delete-to-side)
|
|
|
|
(setq vterm-kill-buffer-on-exit t)))
|
|
#+end_src
|
|
** wgrep
|
|
#+begin_src emacs-lisp
|
|
#+end_src
|
|
** Query replace rx
|
|
#+begin_src emacs-lisp
|
|
(defun my/query-replace-rx (&rest _)
|
|
"Call `query-replace-regexp', reading regexp in `rx' syntax.
|
|
Automatically wraps in parens and adds `seq' to the beginning of
|
|
the form."
|
|
(interactive)
|
|
(cl-letf (((symbol-function #'query-replace-read-from) (lambda (&rest _)
|
|
(--> (read-string "rx form: ")
|
|
(concat "'(seq " it ")")
|
|
(read it)
|
|
(cadr it)
|
|
(rx-to-string it)))))
|
|
(call-interactively #'query-replace-regexp)))
|
|
#+end_src
|
|
** helm info is pretty slick
|
|
#+begin_src emacs-lisp
|
|
(use-package helm)
|
|
;; (require 'helm-info)
|
|
|
|
;; (defun helm-info-emacs-stuff ()
|
|
;; "Helm for Emacs, Elisp, and
|
|
;; CL-library info pages."
|
|
;; (interactive)
|
|
;; (helm :sources
|
|
;; '(helm-source-info-emacs helm-source-info-elisp helm-source-info-cl)))
|
|
|
|
;; (global-set-key (kbd "C-c h") #'helm-info-emacs-stuff)
|
|
#+end_src
|
|
** helpful
|
|
#+begin_src emacs-lisp
|
|
(use-package helpful)
|
|
(global-set-key (kbd "C-h f") #'helpful-function)
|
|
(global-set-key (kbd "C-h v") #'helpful-variable)
|
|
(global-set-key (kbd "C-h k") #'helpful-key)
|
|
(global-set-key (kbd "C-h o") #'helpful-symbol)
|
|
(setq helpful-switch-buffer-function #'pop-to-buffer)
|
|
#+end_src
|
|
** olivetti
|
|
#+begin_src emacs-lisp
|
|
(use-package olivetti
|
|
:commands (olivetti-mode)
|
|
:hook ((prog-mode . olivetti-mode)
|
|
(org-mode . olivetti-mode)
|
|
(dired-mode . olivetti-mode)
|
|
(org-agenda . olivetti-mode)
|
|
(Info-mode . olivetti-mode)
|
|
(message-mode . olivetti-mode)
|
|
(markdown-mode . olivetti-mode))
|
|
:config
|
|
(add-to-list 'window-persistent-parameters
|
|
'(spilt-window . t))
|
|
|
|
(advice-add 'window-toggle-side-windows
|
|
:before
|
|
'olivetti-reset-all-windows)
|
|
|
|
(setq-default olivetti-body-width 140)
|
|
|
|
(with-eval-after-load 'mu4e
|
|
(add-hook 'mu4e-view-mode-hook
|
|
'olivetti-mode)))
|
|
#+end_src
|
|
** w3m
|
|
#+begin_src emacs-lisp
|
|
;; Remove when Emacs 27 releases
|
|
(when (executable-find "w3m")
|
|
(setq w3m-use-tabs nil)
|
|
(use-package w3m)
|
|
|
|
(defun dired-browse-with-w3m (arg)
|
|
(interactive "P")
|
|
(let ((browse-url-browser-function (if arg
|
|
(symbol-function browse-url-browser-function)
|
|
#'w3m-browse-url)))
|
|
(browse-url-of-dired-file)))
|
|
|
|
(define-key dired-mode-map (kbd "W") 'dired-browse-with-w3m)
|
|
|
|
(global-set-key (kbd "C-c g")
|
|
(lambda ()
|
|
(interactive)
|
|
(w3m-goto-url "https://google.com"))))
|
|
#+end_src
|
|
** ztree, for directory diffing
|
|
#+begin_src emacs-lisp
|
|
(use-package ztree)
|
|
#+end_src
|
|
* time zones
|
|
#+begin_src emacs-lisp
|
|
(when my/puppet-p
|
|
(setenv "TZ" "CST6CDT"))
|
|
#+end_src
|
|
* opening links
|
|
#+begin_src emacs-lisp
|
|
(if (not my-ec/is-wsl)
|
|
(setq browse-url-browser-function 'browse-url-firefox)
|
|
(setq browse-url-generic-program "/mnt/c/Windows/System32/cmd.exe"
|
|
browse-url-generic-args '("/c" "start")
|
|
browse-url-browser-function 'browse-url-generic
|
|
search-web-default-browser 'browse-url-generic))
|
|
#+end_src
|