474 lines
15 KiB
EmacsLisp
Executable file
474 lines
15 KiB
EmacsLisp
Executable file
;;;; Appearance
|
|
|
|
(defun apply-appearance-first-frame ()
|
|
(message "Set first frame appearance")
|
|
;; Set theme
|
|
(load-theme 'my-theme +1))
|
|
|
|
(defun apply-appearance-per-frame ()
|
|
(message "Set per frame appearance")
|
|
;; Hide scroll bar
|
|
(toggle-scroll-bar -1)
|
|
;; Use JBMono
|
|
(set-frame-font "-JB-JetBrainsMonoNL Nerd Font-normal-normal-normal-*-14-*-*-*-m-0-iso10646-1" nil t))
|
|
|
|
(apply-appearance-first-frame)
|
|
(apply-appearance-per-frame)
|
|
|
|
(setq seen-first-frame nil)
|
|
(add-hook 'after-make-frame-functions
|
|
(lambda (frame)
|
|
(with-selected-frame frame
|
|
(apply-appearance-per-frame)
|
|
(if (not seen-first-frame)
|
|
(progn
|
|
(setq seen-first-frame 1)
|
|
(apply-appearance-first-frame))))))
|
|
|
|
;; Hide ribbon, menu bar
|
|
(menu-bar-mode -1)
|
|
(tool-bar-mode -1)
|
|
|
|
;; Show colum number in status bar
|
|
(column-number-mode +1)
|
|
|
|
;; Relative line numbers
|
|
(setq-default display-line-numbers 'visual)
|
|
|
|
;; Highlight current line
|
|
(global-hl-line-mode +1)
|
|
|
|
;; Replace yes/no prompts with y/n prompts
|
|
(fset #'yes-or-no-p #'y-or-n-p)
|
|
|
|
;; Fix jumpy scrolling
|
|
(setq mouse-wheel-scroll-amount '(3 ((shift) . 1))
|
|
mouse-wheel-progressive-speed nil
|
|
mouse-wheel-follow-mouse +1
|
|
scroll-step 1) ;; C-n C-p scroll step
|
|
|
|
;; Fix (?) mouse focus getting stuck in a single frame = https://stackoverflow.com/questions/1139124/emacs-mouse-focus-stuck-in-one-frame
|
|
(setq focus-follows-mouse t
|
|
mouse-autoselect-window t)
|
|
|
|
;; Disable annoying bell sound
|
|
(setq ring-bell-function 'ignore)
|
|
|
|
;; Highlight matching parens faster
|
|
(setq show-paren-delay 0)
|
|
|
|
;; Indentation
|
|
(setq-default tab-width 2)
|
|
(defun disable-tabs ()
|
|
(indent-tabs-mode -1))
|
|
(defun enable-tabs ()
|
|
(indent-tabs-mode t))
|
|
(setq tab-always-indent nil) ;; tab key inserts tabs after hitting indent point
|
|
|
|
;; display mismatched whitespace at the beginning or end of lines
|
|
(add-hook 'after-change-major-mode-hook
|
|
(lambda ()
|
|
(if (derived-mode-p 'prog-mode)
|
|
(progn
|
|
(if (eq indent-tabs-mode t)
|
|
(setq whitespace-style '(face indentation::tab trailing missing-newline-at-eof))
|
|
(setq whitespace-style '(face indentation::space trailing missing-newline-at-eof)))
|
|
(whitespace-mode t)))))
|
|
|
|
(add-hook 'prog-mode-hook 'enable-tabs)
|
|
(add-hook 'lisp-mode-hook 'disable-tabs)
|
|
(add-hook 'emacs-lisp-mode-hook 'disable-tabs)
|
|
|
|
(add-hook 'nxml-mode-hook 'enable-tabs)
|
|
(setq nxml-child-indent 2
|
|
nxml-attribute-indent 4)
|
|
|
|
(let ((savedir (concat (file-name-as-directory (getenv "XDG_DATA_HOME")) "emacs/autosave/")))
|
|
(make-directory savedir t)
|
|
(setq backup-directory-alist `(("." . ,savedir)))
|
|
(setq auto-save-list-file-prefix (concat savedir ".saves-"))
|
|
(setq auto-save-file-name-transforms `((".*" ,savedir t)))
|
|
(setq tramp-auto-save-directory savedir))
|
|
|
|
(setq backup-by-copying t
|
|
delete-old-versions t
|
|
version-control t
|
|
kept-new-versions 2
|
|
kept-old-versions 2)
|
|
|
|
;; Packages
|
|
(require 'use-package)
|
|
|
|
;; Evil (Vim Emulation)
|
|
(use-package evil
|
|
:init
|
|
(setq evil-want-C-u-scroll t
|
|
evil-mode-beyond-eol t
|
|
evil-mode-fine-undo t
|
|
evil-undo-system 'undo-redo
|
|
evil-want-keybinding nil)
|
|
:config
|
|
(add-hook 'evil-local-mode-hook (lambda ()
|
|
(setq-local interprogram-cut-function nil)
|
|
(setq-local interprogram-paste-function nil)))
|
|
(evil-mode +1))
|
|
|
|
(use-package evil-collection
|
|
:after evil
|
|
:config
|
|
(evil-collection-init '(magit ibuffer)))
|
|
|
|
(use-package better-jumper
|
|
:after evil
|
|
:config
|
|
(setq better-jumper-context 'window
|
|
better-jumper-new-window-behavior 'copy
|
|
better-jumper-max-length 1000
|
|
better-jumper-use-evil-jump-advice t)
|
|
(define-key evil-motion-state-map (kbd "C-o") #'better-jumper-jump-backward)
|
|
(define-key evil-motion-state-map (kbd "C-i") #'better-jumper-jump-forward)
|
|
(define-key evil-normal-state-map (kbd "SPC j") #'better-jumper-set-jump)
|
|
(better-jumper-mode))
|
|
|
|
(use-package crux)
|
|
|
|
;; Avy (jump to char)
|
|
(use-package avy
|
|
:bind
|
|
(("C-;" . avy-goto-char)
|
|
("C-:" . avy-goto-word-1)
|
|
("M-g g" . avy-goto-line)))
|
|
|
|
(use-package undo-tree
|
|
:after evil
|
|
:config
|
|
(setq undo-tree-auto-save-history nil)
|
|
(advice-add #'evil-undo :override #'undo-tree-undo)
|
|
(advice-add #'evil-redo :override #'undo-tree-redo)
|
|
(define-key evil-normal-state-map (kbd "SPC u v") #'undo-tree-visualize)
|
|
(global-undo-tree-mode))
|
|
|
|
;; Magit (git frontend)
|
|
(use-package magit
|
|
:config
|
|
(setq magit-diff-refine-hunk t
|
|
magit-diff-refine-ignore-whitespace t))
|
|
|
|
;; Rainbow-Mode (show hex strings in color)
|
|
(use-package rainbow-mode)
|
|
|
|
;; Vertico (completion helper)
|
|
(use-package vertico
|
|
:config
|
|
(keymap-set vertico-map "M-j" #'vertico-next)
|
|
(keymap-set vertico-map "M-k" #'vertico-previous)
|
|
(keymap-set vertico-map "C-j" #'vertico-next)
|
|
(keymap-set vertico-map "C-k" #'vertico-previous)
|
|
(keymap-set vertico-map "M-`" #'vertico-exit)
|
|
(keymap-set vertico-map "M-ESC" #'vertico-exit)
|
|
(vertico-mode))
|
|
|
|
(use-package vertico-indexed
|
|
:after vertico
|
|
:init
|
|
(setq vertico-indexed-start 1)
|
|
:config
|
|
(dotimes (i 9)
|
|
(keymap-set vertico-map (format "M-%d" (+ i 1))
|
|
`(lambda () (interactive)
|
|
(setq vertico--index ,i)
|
|
(vertico-exit))))
|
|
(vertico-indexed-mode))
|
|
|
|
;; Editorconfig support
|
|
(use-package editorconfig
|
|
:config
|
|
(editorconfig-mode 1))
|
|
|
|
;; Direnv support (nix shell, gitconfig, etc...)
|
|
(use-package direnv
|
|
:config
|
|
(direnv-mode))
|
|
|
|
;; Remove trailing whitespace
|
|
(use-package ws-butler
|
|
:config
|
|
(add-hook 'prog-mode-hook #'ws-butler-mode))
|
|
|
|
;; Markdown
|
|
(use-package markdown-mode
|
|
:init
|
|
(setq markdown-fontify-code-blocks-natively t))
|
|
|
|
;; Justfile
|
|
(use-package just-mode)
|
|
|
|
;; String casing functions
|
|
(use-package string-inflection)
|
|
|
|
;; Treesitter
|
|
(use-package treesit
|
|
:config
|
|
(customize-set-variable 'treesit-font-lock-level 4)
|
|
(setq major-mode-remap-alist
|
|
'((c-mode . c-ts-mode)
|
|
(csharp-mode . csharp-ts-mode)
|
|
(cmake-mode . cmake-ts-mode)
|
|
(c++-mode . c++-ts-mode)
|
|
(css-mode . css-ts-mode)
|
|
(java-mode . java-ts-mode)
|
|
(json-mode . json-ts-mode)
|
|
(python-mode . python-ts-mode))))
|
|
|
|
;; Highlight operations
|
|
(use-package evil-goggles
|
|
:after evil
|
|
:init
|
|
(setq evil-goggles-duration 0.15)
|
|
:config
|
|
(evil-goggles-mode +1))
|
|
|
|
;; Project
|
|
(use-package projectile
|
|
:config
|
|
(define-key prog-mode-map (kbd "C-c p") 'projectile-command-map)
|
|
(define-key projectile-mode-map (kbd "C-c p") 'projectile-command-map)
|
|
(projectile-mode +1))
|
|
|
|
;; File tree (+ related integrations)
|
|
(use-package treemacs
|
|
:init
|
|
(setq treemacs-tag-follow-delay 0.5)
|
|
:config
|
|
(treemacs-resize-icons 15)
|
|
(treemacs-follow-mode +1)
|
|
(treemacs-tag-follow-mode +1)
|
|
(treemacs-project-follow-mode +1))
|
|
(use-package treemacs-evil
|
|
:after (treemacs evil))
|
|
(use-package treemacs-projectile
|
|
:after (treemacs projectile))
|
|
(use-package treemacs-magit
|
|
:after (treemacs magit))
|
|
|
|
;; Explanations for keybindings
|
|
(use-package which-key
|
|
:config
|
|
(which-key-mode +1))
|
|
|
|
;; On the fly syntax checking
|
|
(use-package flycheck
|
|
:after evil
|
|
:config
|
|
(define-key evil-normal-state-map (kbd "SPC e") #'flycheck-list-errors))
|
|
|
|
;; Completions
|
|
(use-package company
|
|
:init
|
|
(setq company-minimum-prefix-length 1
|
|
company-idle-delay 0
|
|
company-selection-wrap-around t
|
|
company-tooltip-align-annotations t
|
|
company-tooltip-flip-when-above t
|
|
company-tooltip-margin 0
|
|
company-show-quick-access 'left
|
|
;; fix lowercase completions in raw text
|
|
company-dabbrev-downcase nil)
|
|
:config
|
|
(setq company-transformers '(delete-consecutive-dups
|
|
company-sort-prefer-same-case-prefix
|
|
company-sort-by-backend-importance
|
|
company-sort-by-occurrence))
|
|
(define-key company-active-map (kbd "<return>") nil)
|
|
(define-key company-active-map (kbd "RET") nil)
|
|
(define-key company-active-map (kbd "M-`") #'company-complete-selection)
|
|
(define-key company-active-map (kbd "M-ESC") #'company-complete-selection)
|
|
(define-key company-active-map (kbd "M-n") #'company-select-next)
|
|
(define-key company-active-map (kbd "M-p") #'company-select-previous)
|
|
(define-key company-active-map (kbd "M-j") #'company-select-next)
|
|
(define-key company-active-map (kbd "M-k") #'company-select-previous)
|
|
(global-company-mode +1))
|
|
|
|
;; Fuzzy forawrd search in completions
|
|
(use-package fussy
|
|
:config
|
|
(setq completion-styles '(fussy basic)))
|
|
|
|
;; Lsp
|
|
(use-package lsp-mode
|
|
:init
|
|
(setq lsp-headerline-breadcrumb-enable nil
|
|
lsp-signature-auto-activate nil
|
|
lsp-signature-doc-lines 0)
|
|
:config
|
|
(add-hook 'lsp-mode-hook #'lsp-enable-which-key-integration)
|
|
(add-hook 'evil-insert-state-entry-hook #'lsp-signature-activate)
|
|
(add-hook 'evil-insert-state-exit-hook #'lsp-signature-stop)
|
|
(define-key evil-normal-state-map (kbd "SPC l r") #'lsp-rename)
|
|
(define-key evil-normal-state-map (kbd "SPC l a") #'lsp-execute-code-action)
|
|
(define-key evil-normal-state-map (kbd "SPC l = =") #'lsp-format-buffer)
|
|
(define-key evil-normal-state-map (kbd "SPC l = r") #'lsp-format-region)
|
|
(define-key evil-normal-state-map (kbd "SPC l s q") #'lsp-workspace-shutdown)
|
|
(define-key evil-normal-state-map (kbd "SPC l s r") #'lsp-workspace-restart)
|
|
(define-key evil-normal-state-map (kbd "SPC l i") #'lsp-describe-thing-at-point))
|
|
|
|
(use-package lsp-ui
|
|
:after lsp-mode
|
|
:init
|
|
(setq lsp-ui-doc-enable nil
|
|
lsp-ui-sideline-enable nil)
|
|
:config
|
|
(define-key lsp-ui-mode-map [remap xref-find-definitions] #'lsp-ui-peek-find-definitions)
|
|
(define-key lsp-ui-mode-map [remap xref-find-references] #'lsp-ui-peek-find-references)
|
|
(define-key evil-normal-state-map (kbd "SPC l d") #'lsp-ui-peek-find-definitions)
|
|
(define-key evil-normal-state-map (kbd "SPC l u") #'lsp-ui-peek-find-references)
|
|
;; Controls inside references popup
|
|
(define-key lsp-ui-peek-mode-map (kbd "j") #'lsp-ui-peek--select-next)
|
|
(define-key lsp-ui-peek-mode-map (kbd "k") #'lsp-ui-peek--select-prev)
|
|
(define-key lsp-ui-peek-mode-map (kbd "J") #'lsp-ui-peek--select-next-file)
|
|
(define-key lsp-ui-peek-mode-map (kbd "K") #'lsp-ui-peek--select-prev-file)
|
|
(define-key lsp-ui-peek-mode-map (kbd "o") #'lsp-ui-peek--goto-xref))
|
|
|
|
(use-package lsp-treemacs
|
|
:after (lsp-mode treemacs))
|
|
|
|
(use-package kotlin-mode
|
|
:after lsp-mode
|
|
:hook (kotlin-mode . lsp-deferred))
|
|
|
|
(use-package lsp-java
|
|
:after lsp-mode
|
|
:hook (java-ts-mode . lsp-deferred)
|
|
:config
|
|
(setq lsp-java-server-install-dir (getenv "JDTLS_PATH"))
|
|
(defun lsp-java--ls-command ()
|
|
(list "jdt-language-server"
|
|
;; this is called "configuration" for come reasn, its acually a cache
|
|
"-configuration" (concat (file-name-as-directory (getenv "XDG_CACHE_HOME")) "jdtls")
|
|
"-data" "../.jdtls")))
|
|
|
|
(setq lsp-glsl-executable '("glslls" "--stdin" "--target-env" "opengl"))
|
|
|
|
(use-package groovy-mode)
|
|
|
|
;; Nasm support
|
|
(use-package nasm-mode)
|
|
|
|
;; Nix support
|
|
(use-package nix-mode
|
|
:mode "\\.nix\\'"
|
|
:hook (nix-mode . disable-tabs))
|
|
|
|
;; QML Support
|
|
(setq qml-ts-mode-indent-offset 2)
|
|
|
|
;; Haskell
|
|
(use-package haskell-ts-mode
|
|
:hook (haskell-ts-mode . disable-tabs))
|
|
|
|
;; Zig
|
|
(use-package zig-ts-mode
|
|
:mode (("\\.zig\\'" . zig-ts-mode)
|
|
("\\.zon\\'" . zig-ts-mode))
|
|
:hook ((zig-ts-mode . lsp-deferred)
|
|
(zig-ts-mode . disable-tabs)
|
|
(zig-ts-mode . (lambda () (setq-local tab-width 4)))))
|
|
|
|
(use-package qml-ts-mode
|
|
:after lsp-mode
|
|
:config
|
|
(add-to-list 'lsp-language-id-configuration '(qml-ts-mode . "qml-ts"))
|
|
(lsp-register-client
|
|
(make-lsp-client :new-connection (lsp-stdio-connection '("qmlls" "-E"))
|
|
:activation-fn (lsp-activate-on "qml-ts")
|
|
:server-id 'qmlls))
|
|
(add-hook 'qml-ts-mode-hook (lambda ()
|
|
(setq-local electric-indent-chars '(?\n ?\( ?\) ?{ ?} ?\[ ?\] ?\; ?,))
|
|
(lsp-deferred))))
|
|
|
|
;; Astro support
|
|
;;(use-package astro-ts-mode
|
|
;;:after lsp-mode
|
|
;;:config
|
|
;;(add-to-list 'lsp-language-id-configuration '(astro-ts-mode . "astro-ts"))
|
|
;;(lsp-register-client
|
|
;;(make-lsp-client :new-connection (lsp-stdio-connection "astro-ls")
|
|
;;:activation-fn (lsp-activate-on "astro-ts")
|
|
;;:server-id 'astro-ls)))
|
|
|
|
(add-to-list 'auto-mode-alist '("\\.rs\\'" . rust-ts-mode))
|
|
(add-to-list 'auto-mode-alist '("\\.hs\\'" . haskell-ts-mode))
|
|
(add-to-list 'auto-mode-alist '("\\.ts\\'" . typescript-ts-mode))
|
|
(add-to-list 'auto-mode-alist '("\\.tsx\\'" . typescript-ts-mode))
|
|
(add-to-list 'auto-mode-alist '("\\.astro\\'" . astro-ts-mode))
|
|
(add-to-list 'auto-mode-alist '("\\.toml\\'" . toml-ts-mode))
|
|
(add-to-list 'auto-mode-alist '("\\.yaml\\'" . yaml-ts-mode))
|
|
(add-to-list 'auto-mode-alist '("\\.yml\\'" . yaml-ts-mode))
|
|
(add-hook 'rust-ts-mode-hook #'lsp-deferred)
|
|
(add-hook 'c++-ts-mode-hook #'lsp-deferred)
|
|
(add-hook 'typescript-ts-mode-hook #'lsp-deferred)
|
|
(add-hook 'astro-ts-mode-hook #'lsp-deferred)
|
|
(add-hook 'glsl-mode-hook #'lsp-deferred)
|
|
(add-hook 'haskell-ts-mode-hook #'lsp-deferred)
|
|
(add-hook 'zig-ts-mode-hook #'lsp-deferred)
|
|
|
|
;; Fix indent
|
|
(add-hook 'rust-ts-mode-hook
|
|
(lambda () (setq-local electric-indent-chars '(?\n ?\( ?\) ?{ ?} ?\[ ?\] ?\; ?,))))
|
|
|
|
(add-hook 'yaml-ts-mode #'disable-tabs)
|
|
|
|
(setq gc-cons-threshold (* 1024 1024 100)
|
|
read-process-output-max (* 1024 1024))
|
|
|
|
;; Misc keybinds
|
|
|
|
;; hy3 retardation
|
|
(use-package frames-only-mode
|
|
:config
|
|
(frames-only-mode))
|
|
|
|
(defun hyprctl (&rest args)
|
|
(apply #'start-process (append '("hyprctl" "hyprctl-buf" "hyprctl" "dispatch") args)))
|
|
|
|
(advice-add #'evil-window-split :override
|
|
(lambda (&optional count file)
|
|
(hyprctl "hy3:makegroup" "v, ephemeral")
|
|
(make-frame-command)))
|
|
(advice-add #'evil-window-vsplit :override
|
|
(lambda (&optional count file)
|
|
(hyprctl "hy3:makegroup" "h, ephemeral")
|
|
(make-frame-command)))
|
|
|
|
(define-key evil-normal-state-map (kbd "C-w a")
|
|
(lambda () (interactive)
|
|
(hyprctl "hy3:makegroup" "tab, ephemeral")
|
|
(make-frame-command)))
|
|
|
|
(define-key evil-normal-state-map (kbd "C-w r") #'make-frame-command)
|
|
|
|
(advice-add #'evil-window-left :override
|
|
(lambda (&optional count file) (hyprctl "hy3:movefocus" "l")))
|
|
(advice-add #'evil-window-right :override
|
|
(lambda (&optional count file) (hyprctl "hy3:movefocus" "r")))
|
|
(advice-add #'evil-window-up :override
|
|
(lambda (&optional count file) (hyprctl "hy3:movefocus" "u")))
|
|
(advice-add #'evil-window-down :override
|
|
(lambda (&optional count file) (hyprctl "hy3:movefocus" "d")))
|
|
|
|
;;; Overrides
|
|
|
|
;; stop lsp-mode from yoloing code actions when only one is present
|
|
(defun lsp--select-action (actions)
|
|
"Select an action to execute from ACTIONS."
|
|
(cond
|
|
((seq-empty-p actions) (signal 'lsp-no-code-actions nil))
|
|
;;((and (eq (seq-length actions) 1) lsp-auto-execute-action)
|
|
;;(lsp-seq-first actions))
|
|
(t (let ((completion-ignore-case t))
|
|
(lsp--completing-read "Select code action: "
|
|
(seq-into actions 'list)
|
|
(-compose (lsp--create-unique-string-fn)
|
|
#'lsp:code-action-title)
|
|
nil t)))))
|