;;;; 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-*-18-*-*-*-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 ;; Disable annoying bell sound (setq ring-bell-function 'ignore) ;; Highlight matching parens faster (setq show-paren-delay 0) (setq tab-width 2) (defun disable-tabs () (setq tab-width 2) (indent-tabs-mode -1)) (defun enable-tabs () (setq tab-width 2) (indent-tabs-mode +1)) (add-hook 'prog-mode-hook 'enable-tabs) (add-hook 'lisp-mode-hook 'disable-tabs) (add-hook 'emacs-lisp-mode-hook 'disable-tabs) (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))) ;; Avy (jump to char) (use-package avy :bind (("C-;" . avy-goto-char) ("C-:" . avy-goto-word-1) ("M-g g" . avy-goto-line))) ;; Magit (git frontend) (use-package magit) ;; 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 "M-`" #'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) (let ((current-prefix-arg (+ ,i 1))) (call-interactively #'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)) ;; 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) ;; 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 "") 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-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)) (use-package lsp-ui :after lsp-mode :init (setq lsp-ui-doc-position 'at-point lsp-ui-doc-delay 0.5) :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) (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-ui-doc-glance) ;; 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)) ;; Nix support (use-package nix-mode :mode "\\.nix\\'" :hook (nix-mode . disable-tabs)) (add-to-list 'auto-mode-alist '("\\.rs\\'" . rust-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 '("\\.toml\\'" . toml-ts-mode)) (add-to-list 'auto-mode-alist '("\\.yaml\\'" . 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) (setq gc-cons-threshold (* 1024 1024 100) read-process-output-max (* 1024 1024)) ;; 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))) (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")))