377 lines
12 KiB
EmacsLisp
377 lines
12 KiB
EmacsLisp
(setq gc-cons-threshold 100000000)
|
||
(add-to-list 'load-path "~/.emacs.d/lisp/")
|
||
|
||
(require 'package)
|
||
(add-to-list 'package-archives '("melpa" . "https://melpa.org/packages/") t)
|
||
(package-initialize)
|
||
|
||
(menu-bar-mode -1)
|
||
(tool-bar-mode -1)
|
||
(scroll-bar-mode -1)
|
||
(savehist-mode -1)
|
||
(column-number-mode)
|
||
(recentf-mode)
|
||
(save-place-mode)
|
||
|
||
;; basic key binds
|
||
(global-set-key (kbd "C-`") 'other-window)
|
||
(global-set-key (kbd "C-x w c") 'whitespace-cleanup)
|
||
(global-set-key (kbd "C-x w f") 'forward-whitespace)
|
||
(global-set-key (kbd "C-c c") 'compile)
|
||
(global-set-key (kbd "C-c r") 'recompile)
|
||
(global-set-key (kbd "C-c k") 'kill-current-buffer)
|
||
|
||
;; utilities
|
||
(defun edit-init-file ()
|
||
"Switch to a buffer visiting your init file."
|
||
(interactive)
|
||
(find-file user-init-file))
|
||
(defvar hidden-minor-modes '()
|
||
"Modes which lighters are hidden by `hide-minor-modes'.")
|
||
(defun hide-minor-modes ()
|
||
"Disable lighter for every mode in `hidden-minor-modes'."
|
||
(interactive)
|
||
(dolist (mode hidden-minor-modes)
|
||
(let ((lighter (cdr (assoc mode minor-mode-alist))))
|
||
(when lighter (setcar lighter "")))))
|
||
(defun kill-all-buffers ()
|
||
"Kill all buffers."
|
||
(interactive)
|
||
(eglot-shutdown-all)
|
||
(mapc #'kill-buffer (buffer-list)))
|
||
(defun reindent-buffer ()
|
||
"Reindent the current buffer."
|
||
(interactive)
|
||
(indent-region (point-min) (point-max)))
|
||
(defun set-face-attributes (list-of-lists)
|
||
"For each sublist of LIST-OF-LISTS, apply the attributes specified in
|
||
the cdr to the face specified by the car.
|
||
|
||
That is, the call:
|
||
|
||
(set-face-attributes '((font-lock-comment-face :slant italic)))
|
||
|
||
will set the `:slant' attribute of `font-lock-comment-face' to the
|
||
value `italic'."
|
||
(mapc #'(lambda (l)
|
||
(apply #'set-face-attribute
|
||
(append (list (car l) t) (cdr l))))
|
||
list-of-lists))
|
||
(defun touch (file-name)
|
||
"Create FILE-NAME or update its modified date."
|
||
(find-file custom-file)
|
||
(save-buffer)
|
||
(kill-current-buffer))
|
||
(defun trim-extra-space ()
|
||
(interactive)
|
||
(delete-all-space)
|
||
(insert " "))
|
||
|
||
(add-hook 'after-change-major-mode-hook #'hide-minor-modes)
|
||
|
||
;; aliases
|
||
(defalias 'cal 'calendar)
|
||
(defalias 'rs 'replace-string)
|
||
(defalias 'wc 'count-words)
|
||
|
||
;; other key binds
|
||
(global-set-key (kbd "C-x w d") 'trim-extra-space)
|
||
(global-set-key (kbd "C-c e b k") 'kill-all-buffers)
|
||
(global-set-key (kbd "C-c e i") 'edit-init-file)
|
||
(global-set-key (kbd "C-c e r") 'reindent-buffer)
|
||
(global-set-key (kbd "C-h w") 'dictionary-search)
|
||
|
||
;; variables
|
||
(setq compilation-scroll-output t
|
||
debug-on-error t
|
||
dictionary-server "dict.org"
|
||
dired-listing-switches "-alh --group-directories-first"
|
||
fill-column 74
|
||
frame-resize-pixelwise t
|
||
window-resize-pixelwise t
|
||
show-paren-context-when-offscreen 'overlay
|
||
treesit-font-lock-level 4
|
||
wdired-allow-to-change-permissions t)
|
||
|
||
;; modes
|
||
(package-install 'git-modes)
|
||
(package-install 'lua-mode)
|
||
(package-install 'markdown-mode)
|
||
(package-install 'nix-mode)
|
||
|
||
;; hooks
|
||
(defun indent-common-hook ()
|
||
;; set indent width to 4 spaces
|
||
(setq-local tab-width 4
|
||
c-basic-offset 4
|
||
c-syntactic-indentation nil
|
||
c-ts-mode-indent-offset 4
|
||
lua-indent-level 4))
|
||
(defun indent-tab-hook ()
|
||
(indent-common-hook)
|
||
(setq-local indent-tabs-mode t))
|
||
(defun indent-spc-hook (&optional w)
|
||
(or w (setq w 4))
|
||
(indent-common-hook)
|
||
(setq-local indent-tabs-mode nil
|
||
tab-width w))
|
||
|
||
(add-hook 'prog-mode-hook 'display-line-numbers-mode)
|
||
(add-hook 'prog-mode-hook #'hl-line-mode)
|
||
(add-hook 'text-mode-hook #'hl-line-mode)
|
||
|
||
(add-hook 'prog-mode-hook 'indent-tab-hook)
|
||
(add-hook 'sgml-mode-hook 'indent-spc-hook)
|
||
(add-hook 'd-mode-hook 'indent-tab-hook)
|
||
(add-hook 'nix-mode-hook #'(lambda () (indent-spc-hook 2)))
|
||
|
||
(defun lisp-hook ()
|
||
(indent-spc-hook 2))
|
||
(add-hook 'lisp-mode-hook 'lisp-hook)
|
||
(add-hook 'lisp-data-mode-hook 'lisp-hook)
|
||
|
||
(add-hook 'mail-mode-hook 'auto-fill-mode)
|
||
(add-hook 'markdown-mode-hook 'auto-fill-mode)
|
||
(add-hook 'nroff-mode-hook 'auto-fill-mode)
|
||
(add-hook 'org-mode-hook 'auto-fill-mode)
|
||
|
||
;; file extensions
|
||
(add-to-list 'auto-mode-alist '("\\.scd\\'" . markdown-mode))
|
||
(add-to-list 'auto-mode-alist '("\\.nix\\'" . nix-mode))
|
||
(add-to-list 'auto-mode-alist '("\\.3lua\\'" . nroff-mode))
|
||
|
||
;; treesitter modes
|
||
(setq major-mode-remap-alist
|
||
'((c-mode . c-ts-mode)
|
||
(c++-mode . c++-ts-mode)
|
||
(sh-mode . bash-ts-mode)))
|
||
|
||
(package-install 'd-mode)
|
||
;; fix to make d-mode highlight primitive types properly
|
||
(font-lock-add-keywords 'd-mode
|
||
'(("\\<\\(bool\\|byte\\|ubyte\\|char\\|delegate\\|double\\|float\\|function\\|int\\|long\\|short\\|uint\\|ulong\\|ushort\\|cent\\|ucent\\|real\\|ireal\\|idouble\\|ifloat\\|creal\\|cfloat\\|cdouble\\|wchar\\|dchar\\|void\\|string\\|wstring\\|dstring\\|__vector\\|Runtime\\|Thread\\)\\>" . 'font-lock-type-face)))
|
||
|
||
;; undo-tree
|
||
(package-install 'undo-tree)
|
||
(global-undo-tree-mode)
|
||
(add-to-list 'hidden-minor-modes 'undo-tree-mode)
|
||
|
||
;; isearch match count
|
||
(package-install 'anzu)
|
||
(global-anzu-mode)
|
||
(add-to-list 'hidden-minor-modes 'anzu-mode)
|
||
|
||
;; highlight colours
|
||
(package-install 'rainbow-mode)
|
||
(add-hook 'prog-mode-hook 'rainbow-mode)
|
||
(add-to-list 'hidden-minor-modes 'rainbow-mode)
|
||
|
||
;; rainbow parens in lisp-mode
|
||
(package-install 'rainbow-delimiters)
|
||
(add-hook 'lisp-mode-hook 'rainbow-delimiters-mode)
|
||
(add-hook 'lisp-data-mode-hook 'rainbow-delimiters-mode)
|
||
|
||
;; modernize org-mode
|
||
(package-install 'org-modern)
|
||
(add-hook 'org-mode-hook 'org-modern-mode)
|
||
;; enable spell checking in org mode
|
||
(add-hook 'org-mode-hook #'(lambda () (flyspell-mode)))
|
||
|
||
;; slime
|
||
(package-install 'slime)
|
||
(setq inferior-lisp-program "sbcl")
|
||
(add-hook 'slime-repl-mode-hook
|
||
#'(lambda ()
|
||
(keymap-local-set "C-c l" 'slime-hyperspec-lookup)))
|
||
|
||
;; completion with arbitrary order
|
||
(package-install 'orderless)
|
||
(require 'orderless)
|
||
(setq completion-styles '(orderless basic)
|
||
completion-category-overrides '((file (styles basic partial-completion))))
|
||
|
||
;; minibuffer completion
|
||
(package-install 'marginalia)
|
||
(package-install 'vertico)
|
||
(marginalia-mode)
|
||
(vertico-mode)
|
||
|
||
;; completion with corfu
|
||
(package-install 'corfu)
|
||
(require 'corfu)
|
||
(setq corfu-auto t
|
||
corfu-cycle t
|
||
corfu-preselect 'prompt
|
||
corfu-quit-no-match t)
|
||
(add-hook 'prog-mode-hook #'corfu-mode)
|
||
;; mix and match completion
|
||
(package-install 'cape)
|
||
(setq completion-at-point-functions (list (cape-capf-super
|
||
#'cape-keyword
|
||
#'cape-file
|
||
#'cape-dabbrev
|
||
#'cape-emoji)))
|
||
;; icons
|
||
(package-install 'kind-icon)
|
||
(setq kind-icon-default-face 'corfu-default)
|
||
(add-to-list 'corfu-margin-formatters #'kind-icon-margin-formatter)
|
||
|
||
;; eglot
|
||
(require 'eglot)
|
||
;(add-hook 'c-ts-mode-hook 'eglot-ensure)
|
||
(add-hook 'c++-ts-mode-hook 'eglot-ensure)
|
||
(add-to-list 'eglot-server-programs `(d-mode . ("serve-d")))
|
||
|
||
;; diff information in the gutter
|
||
(package-install 'diff-hl)
|
||
(global-diff-hl-mode)
|
||
(add-hook 'magit-pre-refresh-hook 'diff-hl-magit-pre-refresh)
|
||
(add-hook 'magit-post-refresh-hook 'diff-hl-magit-post-refresh)
|
||
|
||
;; editorconfig
|
||
(package-install 'editorconfig)
|
||
(editorconfig-mode)
|
||
(add-to-list 'hidden-minor-modes 'editorconfig-mode)
|
||
|
||
;; which-key
|
||
(package-install 'which-key)
|
||
(which-key-mode)
|
||
(add-to-list 'hidden-minor-modes 'which-key-mode)
|
||
(setq which-key-side-window-location 'bottom
|
||
which-key-sort-order 'which-key-key-order-alpha
|
||
which-key-sort-uppercase-first nil
|
||
which-key-add-column-padding 1
|
||
which-key-max-display-columns nil
|
||
which-key-min-display-lines 6
|
||
which-key-side-window-slot -10
|
||
which-key-side-window-max-height 0.25
|
||
which-key-idle-delay 0.8
|
||
which-key-max-description-length 25
|
||
which-key-allow-imprecise-window-fit t
|
||
which-key-separator " ")
|
||
|
||
;; image-dired
|
||
(package-install 'image-dired)
|
||
(global-set-key (kbd "C-c i") 'image-dired)
|
||
(add-hook 'image-dired-thumbnail-mode-hook
|
||
#'(lambda ()
|
||
(keymap-local-set "M-RET" 'image-dired-display-this)))
|
||
|
||
;; magit
|
||
(package-install 'magit)
|
||
(require 'magit)
|
||
(global-set-key (kbd "C-c b") 'magit-blame)
|
||
|
||
;; breadcrumbs
|
||
(package-install 'breadcrumb)
|
||
(require 'breadcrumb)
|
||
(setq breadcrumb-project-crumb-separator " / "
|
||
breadcrumb-imenu-crumb-separator " ] ")
|
||
(add-hook 'prog-mode-hook
|
||
#'(lambda ()
|
||
(setq header-line-format
|
||
'(" "
|
||
(:eval (breadcrumb-project-crumbs))
|
||
" : "
|
||
(:eval (breadcrumb-imenu-crumbs))))))
|
||
|
||
;; dashboard
|
||
(package-install 'dashboard)
|
||
(require 'dashboard)
|
||
(setq dashboard-banner-logo-title (concat "Welcome to GNU Emacs, one "
|
||
"component of the GNU/Linux "
|
||
"operating system.")
|
||
dashboard-startup-banner "~/pix/jemacs-book.png"
|
||
dashboard-center-content t
|
||
dashboard-vertically-center-content t
|
||
dashboard-items '((bookmarks . 4)
|
||
(recents . 4))
|
||
dashboard-item-names '(("Bookmarks:" . "Bookmarks")
|
||
("Recent Files:" . "Recents"))
|
||
dashboard-footer-messages
|
||
(list
|
||
"At its core is an interpreter for Emacs Lisp."
|
||
"Merely an interface to your code."
|
||
"“We don't use the term ‘corelibs,’ and I am not sure what that would mean.”"
|
||
"50 years and Dired is still the best file manager on the planet")
|
||
initial-buffer-choice (lambda ()
|
||
(get-buffer-create dashboard-buffer-name)))
|
||
(add-hook 'after-init-hook 'dashboard-insert-startupify-lists)
|
||
(add-hook 'after-init-hook 'dashboard-initialize)
|
||
(dashboard-setup-startup-hook)
|
||
|
||
;; catppuccin theme
|
||
(package-install 'catppuccin-theme)
|
||
(require 'catppuccin-theme)
|
||
(setq catppuccin-flavor 'mocha)
|
||
(load-theme 'catppuccin :no-confirm)
|
||
|
||
;; faces
|
||
(require 'cus-edit) ; custom faces
|
||
(require 'dictionary)
|
||
(let
|
||
((fixedpt "Roboto Mono")
|
||
( varpt "Roboto")
|
||
( accent (catppuccin-get-color 'blue))
|
||
(bground (catppuccin-get-color 'base))
|
||
( darker (catppuccin-get-color 'mantle))
|
||
(darkest (catppuccin-get-color 'crust))
|
||
( text (catppuccin-get-color 'text)))
|
||
(add-to-list 'default-frame-alist `(font . ,fixedpt))
|
||
(add-to-list 'default-frame-alist '(height . 36))
|
||
(set-face-attributes
|
||
`((default :height 112)
|
||
(fixed-pitch :family ,fixedpt)
|
||
(variable-pitch :family ,varpt)
|
||
(font-lock-comment-face :slant italic)
|
||
(font-lock-keyword-face :slant italic)
|
||
(link :foreground ,accent :underline t)
|
||
(mode-line-inactive :weight light)
|
||
(widget-field
|
||
:extend t :background ,darker
|
||
:box (:line-width (1 . 1) :color ,darkest))
|
||
(custom-button
|
||
:background ,darker :foreground ,text
|
||
:box (:line-width (1 . 1) :color ,darkest :style nil))
|
||
(custom-button-mouse :background ,darkest :foreground ,text)
|
||
(custom-button-pressed :inherit custom-button-mouse
|
||
:box (:line-width (1 . 1) :color ,darkest))
|
||
(breadcrumb-imenu-leaf-face :foreground ,accent)
|
||
(dashboard-heading :foreground ,accent :height 1.2 :weight bold)
|
||
(dictionary-word-definition-face :family ,varpt)
|
||
(corfu-default :background ,darker)
|
||
(corfu-current :background ,darkest :box ,accent)
|
||
(corfu-border :background ,accent)
|
||
(corfu-bar :background ,accent)
|
||
(orderless-match-face-0 :foreground ,accent)
|
||
(magit-section-heading :family ,varpt :foreground ,accent
|
||
:height 1.1))))
|
||
|
||
;; custom
|
||
(setq custom-file "~/.emacs.d/custom.el")
|
||
(touch custom-file)
|
||
(load custom-file)
|
||
|
||
;; mu4e
|
||
(let ((mu4e-file "~/.emacs.d/mu4e.el"))
|
||
(when (file-exists-p mu4e-file)
|
||
(load mu4e-file)))
|
||
|
||
;; other packages
|
||
(require 'esv)
|
||
(add-to-list 'esv-arguments "-f")
|
||
(setq esv-close-existing-buffers t)
|
||
|
||
(require 'phobos)
|
||
(setq phobos-browser "firefox")
|
||
|
||
(add-to-list 'load-path "~/git/d-ts-mode/")
|
||
;(require 'd-ts-mode)
|
||
|
||
;; enable disabled commands
|
||
(put 'dired-find-alternate-file 'disabled nil)
|
||
(put 'downcase-region 'disabled nil)
|
||
(put 'upcase-region 'disabled nil)
|
||
(put 'narrow-to-region 'disabled nil)
|
||
|
||
;;; init.el ends here
|