mirror of
https://github.com/pestctrl/emacs-config.git
synced 2026-02-16 08:14:15 +00:00
config-min.org should be a bare minimum environment to be able to revive a broken emacs configuration, and should ideally never break.
1069 lines
38 KiB
Org Mode
1069 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 backup-directory-alist `(("." . ,(concat user-emacs-directory "backups"))))
|
|
|
|
;; 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")))
|
|
(global-undo-tree-mode t)
|
|
|
|
;; 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 "~/.emacs.d/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)
|
|
#+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
|
|
:init
|
|
(vertico-mode)
|
|
(vertico-multiform-mode)
|
|
(setq vertico-count 8)
|
|
|
|
(use-package consult)
|
|
(setq completion-in-region-function
|
|
(lambda (&rest args)
|
|
(apply (if vertico-mode
|
|
#'consult-completion-in-region
|
|
#'completion--in-region)
|
|
args)))
|
|
|
|
;; (setq vertico-multiform-commands
|
|
;; '((completion-at-point vertical)))
|
|
|
|
(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))
|
|
|
|
;; 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
|
|
;; Scrollkeeper is helpful for scrolling up and down
|
|
(defun window-third-height ()
|
|
(max 1 (/ (1- (window-height (selected-window))) 3)))
|
|
|
|
(defun scroll-up-third ()
|
|
(interactive)
|
|
(pulse-momentary-highlight-one-line (point))
|
|
(scroll-up (window-third-height)))
|
|
|
|
(defun scroll-down-third ()
|
|
(interactive)
|
|
(pulse-momentary-highlight-one-line (point))
|
|
(scroll-down (window-third-height)))
|
|
|
|
(global-set-key (kbd "C-v") 'scroll-up-third)
|
|
(global-set-key (kbd "M-v") 'scroll-down-third)
|
|
;; (use-package scrollkeeper)
|
|
;; (global-set-key (kbd "C-v") 'scrollkeeper-down)
|
|
;; (global-set-key (kbd "M-v") 'scrollkeeper-up)
|
|
|
|
;; 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)
|
|
|
|
(advice-add #'display-buffer-in-side-window
|
|
:before
|
|
#'(lambda (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)))))
|
|
|
|
(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 "-al --group-directories-first --sort=extension")
|
|
|
|
;; 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 company)
|
|
(setq company-idle-delay 0.2)
|
|
(add-hook 'emacs-lisp-mode-hook 'company-mode)
|
|
(add-hook 'lisp-mode-hook 'company-mode)
|
|
|
|
;; Magit
|
|
(use-package magit)
|
|
(use-package magit-popup)
|
|
(use-package magit-todos)
|
|
;; Todo: Figure out why transient side-window stuff wrecks my
|
|
;; side-window stuff
|
|
(setq transient-display-buffer-action
|
|
'(display-buffer-pop-up-window))
|
|
(global-set-key (kbd "C-x g") 'magit-status)
|
|
(global-set-key (kbd "C-x M-g") 'magit-dispatch)
|
|
|
|
;; Push all branches
|
|
(defun my/magit-push-all ()
|
|
"Push all branches."
|
|
(interactive)
|
|
(magit-run-git-async "push" "-v"
|
|
(magit-read-remote "Remote")
|
|
"--all"))
|
|
|
|
(transient-append-suffix 'magit-push "m"
|
|
'("a" "all remotes" my/magit-push-all))
|
|
|
|
;; Update all submodules
|
|
(defun magit-submodule-update-recursive ()
|
|
(interactive)
|
|
(magit-run-git-async "submodule" "update" "--init" "--recursive"))
|
|
|
|
(transient-append-suffix 'magit-submodule "u"
|
|
'("U" "Update all (recursively)" magit-submodule-update-recursive))
|
|
|
|
;; Magit uses ediff
|
|
(with-eval-after-load 'ediff
|
|
(setq ediff-window-setup-function 'ediff-setup-windows-plain)
|
|
|
|
(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)
|
|
|
|
;; 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 "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
|
|
(let ((fetcher (if my-ec/at-ti "github" "github-ssh"))
|
|
(quelpa-build-default-files-spec
|
|
'("*.el" (:exclude ".dir-locals.el"))))
|
|
(quelpa `(cider :repo "clojure-emacs/cider" :branch "master" :fetcher ,fetcher)))
|
|
(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-alphabetic)
|
|
;; (ibuffer-auto-mode)
|
|
))
|
|
|
|
(require 'ibuf-ext)
|
|
|
|
(define-key ibuffer-mode-map my/keymap-key nil)
|
|
|
|
(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)))))
|
|
|
|
(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" (not (or (mode . magit-status-mode)
|
|
(not (or (filename . ".emacs.d")
|
|
(filename . "emacs-config"))))))
|
|
("code-aux" (or (mode . slime-repl-mode)
|
|
(mode . slime-mode)
|
|
(mode . magit-status-mode)
|
|
(mode . ein:notebooklist-mode)
|
|
(mode . cider-repl-mode)
|
|
(mode . comint-mode)
|
|
(mode . makefile-gmake-mode)
|
|
(mode . conf-space-mode)
|
|
(mode . sh-mode)))
|
|
("code" (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)))
|
|
("web" (or (mode . web-mode)
|
|
(mode . mhtml-mode)
|
|
(mode . js2-mode)
|
|
(mode . css-mode)))
|
|
("Org Mode" (not or (not mode . org-mode)
|
|
(directory-name . "agenda")))
|
|
("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" (mode . dired-mode))
|
|
("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))
|
|
(use-package vterm
|
|
:ensure nil
|
|
:commands vterm find-vterm vterm-kill
|
|
:bind (("C-x 4 t" . #'find-vterm-other-window)
|
|
:map *root-map*
|
|
("c" . #'find-vterm))
|
|
:config
|
|
(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 get-vterm-buffer (name)
|
|
(if-let (buf (get-buffer name))
|
|
buf
|
|
(let ((buf (vterm--internal #'(lambda (_x) nil))))
|
|
(with-current-buffer buf
|
|
(rename-buffer name))
|
|
buf)))
|
|
|
|
(defun get-tab-vterm-buffer ()
|
|
(let* ((current-tab (alist-get 'name (tab-bar--current-tab)))
|
|
(term-name (concat current-tab "-term")))
|
|
(get-vterm-buffer term-name)))
|
|
|
|
(defun find-vterm ()
|
|
(interactive)
|
|
(display-buffer-same-window (get-tab-vterm-buffer) nil))
|
|
|
|
(defun find-vterm-other-window ()
|
|
(interactive)
|
|
(switch-to-buffer-other-window (get-tab-vterm-buffer)))
|
|
|
|
(setq vterm-kill-buffer-on-exit t)
|
|
|
|
(defun rename-vterm-with-tab (orig name &optional arg)
|
|
(let ((current-tab-name (alist-get 'name (tab-bar--current-tab))))
|
|
(funcall orig name arg)
|
|
(when-let (b (get-buffer (concat current-tab-name "-term")))
|
|
(with-current-buffer b
|
|
(rename-buffer (concat (alist-get 'name (tab-bar--current-tab))
|
|
"-term"))))))
|
|
|
|
(advice-add #'tab-bar-rename-tab
|
|
:around
|
|
#'rename-vterm-with-tab)
|
|
|
|
(defun close-vterm-with-tab (orig)
|
|
(let ((current-tab-name (alist-get 'name (tab-bar--current-tab))))
|
|
(when (funcall orig)
|
|
(when-let (b (get-buffer (concat current-tab-name "-term")))
|
|
(with-current-buffer b
|
|
(vterm-send-C-d))))))
|
|
|
|
(advice-add #'close-tab-switch
|
|
:around
|
|
#'close-vterm-with-tab)))
|
|
#+end_src
|
|
** posting source code
|
|
#+begin_src emacs-lisp
|
|
(use-package webpaste)
|
|
|
|
(setq webpaste-paste-confirmation t)
|
|
(setq webpaste-provider-priority '("ix.io"))
|
|
#+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
|
|
** Ace jump
|
|
#+BEGIN_SRC emacs-lisp
|
|
(use-package ace-jump-mode
|
|
:bind (("C-c j" . 'ace-jump-line-mode)
|
|
:map *root-map*
|
|
("SPC" . 'ace-jump-mode)))
|
|
#+END_SRC
|
|
** olivetti
|
|
#+begin_src emacs-lisp
|
|
(use-package olivetti
|
|
:commands olivetti-mode
|
|
:config
|
|
(setq-default olivetti-body-width 140))
|
|
#+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
|
|
* font configuration
|
|
#+begin_src emacs-lisp
|
|
(defvar frame-font-size-cache
|
|
(make-hash-table))
|
|
|
|
;; Font size adjustment
|
|
(defun hoagie-adjust-font-size (&optional frame)
|
|
"Inspired by https://emacs.stackexchange.com/a/44930/17066. FRAME is ignored.
|
|
If I let Windows handle DPI everything looks blurry."
|
|
(interactive)
|
|
;; Using display names is unreliable...switched to checking the resolution
|
|
(let* ((attrs (frame-monitor-attributes)) ;; gets attribs for current frame
|
|
(monitor-name (cdr (assoc 'name attrs)))
|
|
(width-mm (second (assoc 'mm-size attrs)))
|
|
(width-px (fourth (assoc 'geometry attrs)))
|
|
(height-px (fifth (assoc 'geometry attrs)))
|
|
(size 10)) ;; default for first screen at work
|
|
(when (eq height-px 2880)
|
|
(let ((f (selected-frame)))
|
|
(set-face-attribute 'default f :height 130)
|
|
(set-face-attribute 'mode-line f :height 130)
|
|
(set-face-attribute 'mode-line-inactive f :height 130)
|
|
(setq doom-modeline-height 30))
|
|
(exwm-randr-refresh))
|
|
;; (unless (and (gethash frame frame-font-size-cache)
|
|
;; (= size (gethash frame frame-font-size-cache)))
|
|
;; (puthash frame size frame-font-size-cache))
|
|
))
|
|
;; (remove-hook 'window-size-change-functions #'hoagie-adjust-font-size)
|
|
|
|
#+end_src
|
|
* time zones
|
|
#+begin_src emacs-lisp
|
|
(when my/puppet-p
|
|
(setenv "TZ" "CST6CDT"))
|
|
#+end_src
|
|
* look and feel
|
|
** UI
|
|
#+begin_src emacs-lisp
|
|
;; dashboard looks cool
|
|
;; (use-package dashboard)
|
|
;; (setq fancy-splash-image "~/.emacs.d/res/icon.png")
|
|
|
|
;; Disable tool and menu bar, keep the fringe though
|
|
(unless my/puppet-p
|
|
(tool-bar-mode -1)
|
|
(menu-bar-mode -1)
|
|
(scroll-bar-mode -1))
|
|
|
|
(when my/puppet-p
|
|
(define-key-after (default-value 'tool-bar-map) [separator-puppet] menu-bar-separator)
|
|
(tool-bar-add-item "left-arrow" #'previous-buffer 'puppet-previous-buffer)
|
|
(tool-bar-add-item "right-arrow" #'next-buffer 'puppet-next-buffer)
|
|
(tool-bar-add-item "saveas" #'save-some-buffers 'puppet-save)
|
|
;; (when (and (boundp 'compilation-mode-tool-bar-map)
|
|
;; compilation-mode-tool-bar-map)
|
|
;; (save-excursion
|
|
;; (with-current-buffer (find-file-noselect "")
|
|
;; ;; eval-defun
|
|
;; )))
|
|
)
|
|
|
|
(fringe-mode '(10 . 10))
|
|
;; Need to configure all-the-icons so that mode-line doesn't look fat
|
|
;; and ugly
|
|
(use-package all-the-icons
|
|
:config
|
|
(setq all-the-icons-scale-factor 0.9))
|
|
|
|
;; The most efficient cool looking modeline I've found. Faster than even
|
|
;; smart-mode-line
|
|
(use-package doom-modeline
|
|
:hook (window-setup . doom-modeline-mode)
|
|
:config
|
|
(advice-add #'fit-window-to-buffer :before #'doom-modeline-redisplay)
|
|
|
|
;; Removes symlink bug w/ regards to doom-modeline
|
|
(setq doom-modeline-project-detection 'project)
|
|
|
|
(when (not my-ec/at-ti)
|
|
(setq doom-modeline-height 24)))
|
|
|
|
;; Modeline display useful information
|
|
(setq global-mode-string '(" "))
|
|
(setq display-time-day-and-date t)
|
|
|
|
(display-battery-mode t)
|
|
(display-time-mode t)
|
|
(unless (or (eq 'windows-nt system-type)
|
|
(not (executable-find "df")))
|
|
(require 'display-hard-drive-space-mode)
|
|
(display-hard-drive-space-mode))
|
|
#+end_src
|
|
** font
|
|
#+begin_src emacs-lisp
|
|
;;(set-face-attribute 'variable-pitch nil :font '(:family "ETBookOT"))
|
|
|
|
;; I like my unicode to be monospace too, so I use these
|
|
(set-face-attribute 'default nil :family "RobotoMono" :weight 'normal :height 95
|
|
)
|
|
(set-face-attribute 'fixed-pitch nil :inherit 'default)
|
|
(set-fontset-font t 'unicode (font-spec :size 10 :name "FontAwesome"))
|
|
(set-fontset-font t 'unicode (font-spec :name "SourceCodePro"))
|
|
;; HanWangKaiMediumChuIn
|
|
;; (set-fontset-font t 'han (font-spec :size 16 :name "HanWangMingMediumChuIn"))
|
|
;; (set-fontset-font t 'han (font-spec :size 16 :name "HanWangKaiMediumChuIn-20"))
|
|
;; adobe-source-han-sans-otc-fonts
|
|
(set-fontset-font t 'han (font-spec :size 16 :name "Source Han Sans"))
|
|
;; ttf-paratype
|
|
(set-fontset-font t 'cyrillic (font-spec :size 15 :name "PT Sans Expert"))
|
|
;; extra/adobe-source-code-pro-fonts
|
|
(set-fontset-font t '(9472 . 9599) (font-spec :name "Source Code Pro"))
|
|
|
|
;; (custom-set-faces
|
|
;; '(default ((t (:family "ETBookOT" :foundry "QUQA"
|
|
;; :slant normal :weight normal :height 120
|
|
;; :width normal :spacing 90)))))
|
|
#+end_src
|
|
** theme
|
|
#+begin_src emacs-lisp
|
|
(use-package color-theme-modern)
|
|
(load-theme 'calm-forest nil t)
|
|
|
|
(use-package modus-themes)
|
|
(modus-themes-load-themes)
|
|
(load-theme 'modus-operandi nil t)
|
|
|
|
(add-to-list 'custom-theme-load-path "~/.emacs.d/lisp/themes")
|
|
(require 'light-default-theme)
|
|
(load-theme 'light-default nil t)
|
|
(require 'dark-default-theme)
|
|
(load-theme 'dark-default nil t)
|
|
(require 'same-defaults-theme)
|
|
(load-theme 'same-defaults nil t)
|
|
|
|
(defvar current-theme 'dark)
|
|
(defvar dark-theme 'calm-forest)
|
|
(defvar light-theme 'modus-operandi)
|
|
|
|
(defun switch-themes ()
|
|
(interactive)
|
|
(disable-current-theme)
|
|
(setq current-theme (if (eq current-theme 'dark) 'light 'dark))
|
|
(enable-current-theme)
|
|
(set-background-mode current-theme))
|
|
|
|
(defun reload-theme ()
|
|
(interactive)
|
|
(disable-current-theme)
|
|
(enable-current-theme)
|
|
(set-background-mode current-theme))
|
|
|
|
(defun enable-current-theme ()
|
|
(pcase current-theme
|
|
('light
|
|
(enable-theme light-theme)
|
|
(enable-theme 'light-default))
|
|
('dark
|
|
(enable-theme dark-theme)
|
|
(enable-theme 'dark-default)))
|
|
(enable-theme 'same-defaults))
|
|
|
|
(defun disable-current-theme ()
|
|
(disable-theme 'same-defaults)
|
|
(pcase current-theme
|
|
('light
|
|
(disable-theme 'light-default)
|
|
(disable-theme light-theme))
|
|
('dark
|
|
(disable-theme 'dark-default)
|
|
(disable-theme dark-theme))))
|
|
|
|
(defun update-frame-background-mode ()
|
|
(mapc 'frame-set-background-mode (frame-list)))
|
|
|
|
(defun set-background-mode (mode)
|
|
(setq frame-background-mode mode)
|
|
(update-frame-background-mode))
|
|
|
|
(ec/load-or-ask-pred 'my/light-default "Use light-theme? ")
|
|
|
|
;; Executable
|
|
(when (or my/light-default
|
|
my/puppet-p)
|
|
(setq current-theme 'light))
|
|
|
|
(enable-current-theme)
|
|
#+end_src
|
|
** colors
|
|
#+begin_src emacs-lisp
|
|
(defun my/reading-color ()
|
|
(interactive)
|
|
(variable-pitch-mode)
|
|
(face-remap-add-relative 'default :foreground "white smoke"))
|
|
|
|
(add-hook 'Man-mode-hook
|
|
#'my/reading-color)
|
|
|
|
(add-hook 'w3m-mode-hook
|
|
#'my/reading-color)
|
|
#+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
|