;;; init.el --- Initialization file for Emacs
;;; Commentary: Emacs Startup File --- initialization for Emacs
(add-to-list 'load-path (locate-user-emacs-file "lisp/"))
(require 'android-setup nil t)
(require 'custom-setup nil t)
(require 'functions)
(require 'elpaca-loader)
(setq no-littering-etc-directory (expand-file-name "stateful/config" user-emacs-directory))
(setq no-littering-var-directory (expand-file-name "stateful/data" user-emacs-directory))
;; Startup time
(defun efs/display-startup-time ()
(message
"Emacs loaded in %s with %d garbage collections."
(format
"%.2f seconds"
(float-time
(time-subtract after-init-time before-init-time)))
gcs-done))
(add-hook 'emacs-startup-hook #'efs/display-startup-time)
;; Loaded early to prevent all littering
(my-use-package no-littering
:ensure (:wait t)
:demand t)
(elpaca-wait) ; No littering
;; Loaded early to prevent loading unnecessary stuff
(my-use-package general
:ensure (:wait t) ; Adds general use-package keyword
:config
(general-auto-unbind-keys)
(general-create-definer my-leader
:states '(motion normal insert visual emacs)
:keymaps 'override
:prefix "SPC"
:non-normal-prefix "M-SPC")
(general-create-definer my-local-leader
:states 'normal
:keymaps 'override
:prefix "\\")
(my-leader
"" '(nil :wk "global leader")
"h" '(:keymap help-map :wk "Help")
"C-g" '(keyboard-quit :wk "abort")
"!" '(shell-command :wk "Shell command")
"&" '(async-shell-command :wk "Async shell command")
;; "'" '()
"x" '(execute-extended-command :wk "Execute extended command")
":" '(eval-expression :wk "Evaluate expression")))
;; Loaded early cause I genuinely am not able to use emacs much without evil
;; so if stuff brokes, it's good to have evil at hand
;; (general-def 'insert 'override
;; "C-\\" 'evil-normal-state)
(my-use-package evil
:ensure t
:demand t
:general
(my-leader
"u" '(universal-argument :wk "Universal argument"))
(general-def 'insert 'override
"C-\\" '(evil-normal-state :wk "Enter normal state"))
(general-def 'visual 'override
"C-\\" '(evil-normal-state :wk "Enter normal state"))
:custom
(evil-undo-system 'undo-redo)
(evil-want-integration t)
(evil-want-keybinding nil)
(evil-search-module 'evil-search)
:init
; evil-want-Y-yank-to-eol cannot be set by custom. Use this instead
(setq evil-want-Y-yank-to-eol t)
:config
(my-unbind-key-in-evil-states "C-.")
(evil-mode 1))
(my-use-package evil-collection
:after evil
:ensure t
:demand t
:config
(evil-collection-init))
(elpaca-wait)
;; some visual configs
(my-use-package monokai-theme
:ensure t
:demand t
:config
(load-theme 'monokai t))
;; (my-use-package solaire-mode
;; :ensure t
;; :config
;; (solaire-global-mode 1))
(setq-default inhibit-startup-screen t)
(setq inhibit-splash-screen t)
(setq inhibit-startup-message t)
(setq initial-scratch-message "")
(setq display-line-numbers-type 'relative)
(global-display-line-numbers-mode 1)
(setq-default scroll-step 1
scroll-margin 3
scroll-conservatively 101
hscroll-step 1
hscroll-margin 3)
(setq-default resize-mini-windows t)
;; Editing
(my-use-package whitespace
:hook
((before-save . whitespace-cleanup)
((prog-mode text-mode) . whitespace-mode))
:config
(setq whitespace-line-column 512) ;; limit line length
(setq whitespace-style '(face tabs empty trailing lines-tail)))
(my-use-package evil-terminal-cursor-changer
:ensure t
:config
(evil-terminal-cursor-changer-activate))
;; Default editing configs
(setq create-lockfiles nil)
(setq auto-save-default nil)
(setq backup-directory-alist `(("." . ,(expand-file-name "saves/" no-littering-var-directory))))
(setq-default tab-width 2)
(setq-default indent-tabs-mode nil)
(setq-default sentence-end-double-space nil)
(setq-default truncate-lines t)
(defcustom my/indent-variable-mode-alist '()
"Maps modes to their respective indent variable"
:type '(alist :key-type (symbol :tag "Mode")
:value-type (symbol :tag "Variable")))
(defmacro my/indent-variable-mode-alist-add (mode variable)
`(add-to-list 'my/indent-variable-mode-alist '(,mode . ,variable)))
(defun my/hook-indent-adjust-shift-widths ()
(when-let ((indent (symbol-value (cdr (assoc major-mode my/indent-variable-mode-alist)))))
(setq-local tab-width indent))
(setq-local evil-shift-width tab-width))
;; This doesn't work. Why?
;; it's not a good approach, but I don't understand it!
;; (defmacro my/adjust-shift-widths (variable)
;; `(let
;; ((shift-width ,variable))
;; (setq-local evil-shift-width shift-width)
;; (setq-local tab-width shift-width)))
;; (defmacro my/add-hook-adjust-shift-widths (mode variable)
;; `(add-hook
;; (intern (concat (symbol-name ',mode) "-hook"))
;; (lambda (&rest args) (my/adjust-shift-widths ,variable))))
;; ENV
(unless (getenv "EMACS_NO_SHELL_ENV")
(my-use-package exec-path-from-shell
:ensure t
:demand t
:custom
(exec-path-from-shell-shell-name (getenv "SHELL"))
; (exec-path-from-shell-arguments "-l -i") ; Set by default for bash, zsh etc.
(exec-path-from-shell-variables
'("PATH"
"MANPATH"
"INFOPATH"
"CXX"
"CC"
"XDG_CONFIG_HOME"
"XDG_CACHE_HOME"
"XDG_DATA_HOME"
"NIX_PATH"
"GUILE_LOAD_PATH"
"GUILE_LOAD_COMPILED_PATH"))
:config
(setenv "SHLVL" "0")
(unless (memq system-type '(windows-nt android))
(exec-path-from-shell-initialize))
;; This is for Matlab + my WM without reparenting.
;; This cannot be sourced from the env, as the script that adds
;; this environment, is not part of shell initialization
(setenv "_JAVA_AWT_WM_NONREPARENTING" "1")))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; KEYS ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Early keys stuff (general.el) is loaded earlier
(my-use-package which-key
:ensure t
:demand t
:custom
(which-key-idle-delay 0.6)
:config
(which-key-mode 1))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; EVIL ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Early evil stuff is loaded earlier
(my-use-package evil-easymotion
:after (evil evil-snipe)
:ensure t
:demand t
:general
(my-leader
"l" '(:keymap evilem-map :wk "Evilem"))
:config
(evilem-make-motion evilem-motion-forward-word-begin #'evil-forward-word-begin)
(evilem-make-motion evilem-motion-forward-WORD-begin #'evil-forward-WORD-begin)
(evilem-make-motion evilem-motion-forward-word-end #'evil-forward-word-end)
(evilem-make-motion evilem-motion-forward-WORD-end #'evil-forward-WORD-end)
(evilem-make-motion evilem-motion-backward-word-begin #'evil-backward-word-begin)
(evilem-make-motion evilem-motion-backward-WORD-begin #'evil-backward-WORD-begin)
(evilem-make-motion evilem-motion-backward-word-end #'evil-backward-word-end)
(evilem-make-motion evilem-motion-backward-WORD-end #'evil-backward-WORD-end)
(define-key evilem-map "s"
(evilem-create 'evil-snipe-repeat
:pre-hook (save-excursion (call-interactively #'evil-snipe-s))
:bind ((evil-snipe-scope 'buffer)
(evil-snipe-enable-highlight)
(evil-snipe-enable-incremental-highlight))))
(define-key evilem-map "S"
(evilem-create 'evil-snipe-repeat
:pre-hook (save-excursion (call-interactively #'evil-snipe-s))
:bind ((evil-snipe-scope 'buffer)
(evil-snipe-enable-highlight)
(evil-snipe-enable-incremental-highlight)))))
(my-use-package evil-surround
:after evil
:ensure t
:demand t
:config
(global-evil-surround-mode 1))
(my-use-package evil-goggles
:after evil
:ensure t
:demand t
:custom
(evil-goggles-duration 0.1)
:config
(evil-goggles-mode))
(my-use-package evil-commentary
:after evil
:ensure t
:demand t
:config
(evil-commentary-mode))
(my-use-package evil-snipe
:after evil
:ensure t
:demand t
:hook
(magit-mode . turn-off-evil-snipe-override-mode)
:custom
(evil-snipe-scope 'buffer)
(evil-snipe-repeat-keys nil)
(evil-snipe-override-evil-repeat-keys t)
:config
(evil-snipe-mode))
(my-use-package evil-numbers
:ensure t
:general
(normal
"g+" '(evil-numbers/inc-at-pt :wk "Increment at point")
"g-" '(evil-numbers/dec-at-pt :wk "Decrement at point"))
(visual
"g+" '(evil-numbers/inc-at-pt-incremental :wk "Increment at point")
"g-" '(evil-numbers/dec-at-pt-incremental :wk "Decrement at point"))
)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; VERTICO, CONSULT, EMBARK ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(my-use-package vertico
:ensure t
:after savehist
:hook
(minibuffer-setup . vertico-repeat-save)
:bind (:map vertico-map
("M-P" . vertico-repeat-previous)
("M-N" . vertico-repeat-next)
("S-<prior>" . vertico-repeat-previous)
("S-<next>" . vertico-repeat-next)
;; Exit without substituting selected
("M-RET" . vertico-exit-input)
("?" . minibuffer-completion-help)
("M-TAB" . minibuffer-complete))
:general
(my-leader "'" '(vertico-repeat :wk "Last search"))
:init
(vertico-mode 1)
(add-to-list 'savehist-additional-variables 'vertico-repeat-history))
(my-use-package vertico-directory
:ensure nil
:after vertico
:bind (:map vertico-map
("C-h" . vertico-directory-up)))
(my-use-package vertico-quick
:ensure nil
:after vertico
:bind (:map vertico-map
("M-q" . vertico-quick-insert)
("C-q" . vertico-quick-exit)))
(use-package marginalia
:ensure t
:bind (:map minibuffer-local-map
("M-A" . marginalia-cycle))
:config
(marginalia-mode))
(use-package embark
:ensure t
:general
(my-leader
"." '(embark-act :wk "Act")
";" '(embark-dwim :wk "Dwim"))
:bind
(("C-." . embark-act) ;; pick some comfortable binding
("C-;" . embark-dwim) ;; good alternative: M-.
("C-h B" . embark-bindings)) ;; alternative for `describe-bindings'
:custom
(prefix-help-command #'embark-prefix-help-command)
:config
; TODO: use general.el :general block
(define-key embark-file-map (kbd "o") (my/embark-ace-action find-file))
(define-key embark-buffer-map (kbd "o") (my/embark-ace-action switch-to-buffer))
(define-key embark-bookmark-map (kbd "o") (my/embark-ace-action bookmark-jump))
;; Hide the mode line of the Embark live/completions buffers
(add-to-list 'display-buffer-alist
'("\\`\\*Embark Collect \\(Live\\|Completions\\)\\*"
nil
(window-parameters (mode-line-format . none)))))
;; Consult users will also want the embark-consult package.
(my-use-package embark-consult
:ensure t
:hook
((embark-collect-mode . consult-preview-at-point-mode)))
(my-use-package consult
:ensure t
:general
(my-leader
"f" '(nil :wk "File")
"f f" '(find-file :wk "Find file")
"f F" '(consult-fd :wk "Consult fd")
"f r" '(consult-recent-file :wk "Recent file")
"f s" '(save-buffer :wk "Save file")
"f l" '(consult-locate : "Locate file")
"b" '(nil :wk "Buffer")
"b r" '(revert-buffer :wk "Revert buffer")
"b b" '(consult-buffer :wk "Switch buffer")
"b k" '(kill-buffer :wk "Kill buffer")
"b B" '(consult-project-buffer :wk "Switch project buffer")
"," '(consult-buffer :wk "Switch buffer")
"d h" '(consult-history :wk "Consult history")
"d k" '(consult-kmacro :wk "Consult kmacro")
"d m" '(consult-man :wk "Consult uan")
"d i" '(consult-info :wk "Consult info")
"e c" '(consult-flymake :wk "Consult flymake")
"y" '(consult-yank-pop :wk "Yank pop")
"s" '(:keymap search-map :wk "Search")
"/" '(consult-ripgrep-all :wk "Search project")
)
:bind (;; C-c bindings in `mode-specific-map'
("C-c M-x" . consult-mode-command)
("C-c h" . consult-history)
("C-c k" . consult-kmacro)
("C-c m" . consult-man)
("C-c i" . consult-info)
([remap Info-search] . consult-info)
;; C-x bindings in `ctl-x-map'
("C-x M-:" . consult-complex-command) ;; orig. repeat-complex-command
("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
("C-x r b" . consult-bookmark) ;; orig. bookmark-jump
("C-x p b" . consult-project-buffer) ;; orig. project-switch-to-buffer
;; Custom M-# bindings for fast register access
("M-#" . consult-register-load)
("M-'" . consult-register-store) ;; orig. abbrev-prefix-mark (unrelated)
("C-M-#" . consult-register)
;; Other custom bindings
("M-y" . consult-yank-pop) ;; orig. yank-pop
;; M-g bindings in `goto-map'
("M-g e" . consult-compile-error)
("M-g f" . consult-flymake) ;; Alternative: consult-flycheck
("M-g g" . consult-goto-line) ;; orig. goto-line
("M-g M-g" . consult-goto-line) ;; orig. goto-line
("M-g o" . consult-outline) ;; Alternative: consult-org-heading
("M-g m" . consult-mark)
("M-g k" . consult-global-mark)
("M-g i" . consult-imenu)
("M-g I" . consult-imenu-multi)
;; M-s bindings in `search-map'
("M-s d" . consult-find) ;; Alternative: consult-fd
("M-s c" . consult-locate)
("M-s g" . consult-grep)
("M-s G" . consult-git-grep)
("M-s r" . consult-ripgrep)
("M-s l" . consult-line)
("M-s L" . consult-line-multi)
("M-s k" . consult-keep-lines)
("M-s u" . consult-focus-lines)
;; Isearch integration
("M-s e" . consult-isearch-history)
:map isearch-mode-map
("M-e" . consult-isearch-history) ;; orig. isearch-edit-string
("M-s e" . consult-isearch-history) ;; orig. isearch-edit-string
("M-s l" . consult-line) ;; needed by consult-line to detect isearch
("M-s L" . consult-line-multi) ;; needed by consult-line to detect isearch
;; Minibuffer history
:map minibuffer-local-map
("M-s" . consult-history) ;; orig. next-matching-history-element
("M-r" . consult-history)) ;; orig. previous-matching-history-element
(:map search-map
("s" . consult-ripgrep-all)
("i" . consult-imenu)
("I" . consult-imenu-multi)
("f" . consult-flymake))
:custom
(register-preview-delay 0.5)
(register-preview-function #'consult-register-format)
(xref-show-xrefs-function #'consult-xref)
(xref-show-definitions-function #'consult-xref)
(consult-narrow-key "<")
:init
(advice-add #'register-preview :override #'consult-register-window)
:config
(require 'consult-ripgrep-all)
(recentf-mode 1))
(my-use-package orderless
:ensure t
:custom
;; Configure a custom style dispatcher (see the Consult wiki)
;; (setq orderless-style-dispatchers '(+orderless-consult-dispatch orderless-affix-dispatch))
;; orderless-component-separator #'orderless-escapable-split-on-space)
(orderless-matching-styles '(orderless-literal orderless-regexp))
(completion-styles '(orderless basic))
(completion-category-defaults nil)
(completion-category-overrides '((eglot (styles orderless))
(file (styles partial-completion)))))
(my-use-package wgrep
:ensure t)
;;; NAVIGATION, Window managements
(my-use-package emacs
:after evil
:general
(my-leader
"t m" '(switch-to-minibuffer :wk "Switch to minibuffer"))
(normal
"[f" '(+evil/next-frame :wk "Next frame")
"]f" '(+evil/previous-frame :wk "Previous frame"))
:preface
; Taken from doomemacs. https://github.com/doomemacs/doomemacs/blob/a0dadda2666886840e63f28d96a03a6f635a4fe6/modules/editor/evil/autoload/unimpaired.el
(defun +evil/next-frame (count)
"Focus next frame."
(interactive "p")
(dotimes (_ (abs count))
(let ((frame (if (> count 0) (next-frame) (previous-frame))))
(if (eq frame (selected-frame))
(user-error "No other frame")
(select-frame-set-input-focus frame)))))
(defun +evil/previous-frame (count)
"Focus previous frame."
(interactive "p")
(+evil/next-frame (- count)))
:config
(add-to-list 'display-buffer-alist
'((or (major-mode . Info-mode)
(major-mode . help-mode)
(major-mode . Man-mode)
(major-mode . helpful-mode))
(display-buffer-reuse-window
display-buffer-in-side-window)
(reusable-frames . visible)
(side . right)
(window-width . 0.33)))
(add-to-list 'display-buffer-alist
'("\\*vterm\\*" nil
(dedicated . t)))
(defun switch-to-minibuffer ()
"Switch to minibuffer window."
(interactive)
(if (active-minibuffer-window)
(select-window (active-minibuffer-window))
(error "Minibuffer is not active"))))
(my-use-package popper
:ensure t
:demand t
:bind (("C-`" . popper-toggle)
("M-`" . popper-cycle)
("C-M-`" . popper-toggle-type))
:general
(my-leader
"k" '(nil :wk "Popper")
"k s" '(window-toggle-side-windows :wk "Toggle side windows")
"k k" '(popper-toggle :wk "Popper toggle")
"k t" '(popper-toggle-type :wk "Popper toggle popup")
"k j" '(popper-cycle :wk "Popper cycle")
"k J" '(popper-cycle-backwards :wk "Popper cycle backwards"))
:custom
(popper-mode-line '(:eval (propertize " POP " 'face 'mode-line-emphasis)))
(popper-echo-dispatch-keys '(?q ?w ?e ?r ?t ?y ?u ?i ?o ?p))
(popper-group-function #'popper-group-by-directory)
(popper-reference-buffers
'("\\*Messages\\*"
"Output\\*$"
"\\*Async Shell Command\\*"
;; "^\\*Embark Collect: "
"\\*vterm\\*"
"\\*jupyter-repl"
"\\*jupyter-error\\*"
"\\*Python\\*"
"\\*MATLAB\\*"
"\\*Geiser Guile REPL\\*"
compilation-mode))
:config
(popper-mode 1)
(popper-echo-mode 1))
(my-use-package ace-window
:ensure t
:commands (aw-select ace-window ace-window-one-command)
:general
(my-leader
"o" '(ace-window :wk "Ace window")
"C-o" '(ace-window-one-command :wk "Ace window one command")
"O" '(ace-window-prefix :wk "Ace window prefix")
"`" '(evil-switch-to-windows-last-buffer :wk "Switch to last buffer")
"<TAB>" '(evil-switch-to-windows-last-buffer :wk "Switch to last buffer")
"w" '(:keymap evil-window-map :wk "Windows"))
:bind
(("M-o" . ace-window)
("M-C-o". ace-window-one-command))
(:map evil-window-map
("d" . evil-window-delete)
("o" . ace-window))
:custom
(aw-keys '(?a ?s ?d ?f ?g ?h ?j ?k ?l))
(aw-char-position 'top-left)
(aw-leading-char-style 'char)
(aw-scope 'global)
(aw-dispatch-always t)
:custom-face
(aw-background-face ((t (:foreground "dim gray" :background "#1d2021"))))
(aw-leading-char-face ((t (:height 3.0 :foreground "#f0c674"))))
:init
;; (defun ace-window-prefix ()
;; (interactive)
;; (let ((win (aw-select " ACE")))
;; (when (windowp win)
;; (display-buffer-override-next-command
;; (lambda (buffer alist)
;; (cons win 'window))
;; (message "Display next command buffer in selected window...")))))
(defun ace-window-prefix ()
(interactive)
(setq ace-window-prefixed-window (aw-select " ACE"))
(when (windowp ace-window-prefixed-window)
(display-buffer-override-next-command
(lambda (buffer alist)
(cons ace-window-prefixed-window 'reuse)))
(message "Display next command buffer in selected window...")))
;; Thanks https://karthinks.com/software/fifteen-ways-to-use-embark/#open-any-buffer-by-splitting-any-window
(eval-when-compile
(defmacro my/embark-ace-action (fn)
`(defun ,(intern (concat "my/embark-ace-" (symbol-name fn))) ()
(interactive)
(with-demoted-errors "%s"
(require 'ace-window)
(let ((aw-dispatch-always t))
(aw-switch-to-window (aw-select nil))
(call-interactively (symbol-function ',fn)))))))
(defun other-window-mru ()
"Select the most recently used window on this frame."
(interactive)
(when-let ((mru-window
(get-mru-window
nil nil 'not-this-one-dummy)))
(select-window mru-window)))
:config
(ace-window-display-mode 1)
(setq aw-dispatch-alist
'((?k aw-delete-window "Delete Window")
(?x aw-swap-window "Swap Windows")
(?m my/aw-take-over-window "Move Window")
(?c aw-copy-window "Copy Window")
(?j aw-switch-buffer-in-window "Select Buffer")
(?o aw-flip-window)
(?b aw-switch-buffer-other-window "Switch Buffer Other Window")
;; (?c aw-split-window-fair "Split Fair Window")
(?s my-aw-split-window-vert "Split Vert Window")
(?v my-aw-split-window-horz "Split Horz Window")
(?o delete-other-windows "Delete Other Windows")
(?i other-window-mru)
(?? aw-show-dispatch-help)))
(defun my-aw-split-window-vert (window)
"Split WINDOW vertically, and select the new one."
(select-window (split-window-vertically)))
(defun my-aw-split-window-horz (window)
"Split WINDOW horizontally, and select the new one."
(select-window (split-window-horizontally)))
;; Thanks https://karthinks.com/software/emacs-window-management-almanac/
(defun ace-window-one-command ()
(interactive)
(let ((win (aw-select " ACE")))
(when (windowp win)
(with-selected-window win
(let* ((command (key-binding
(read-key-sequence
(format "Run in %s..." (buffer-name)))))
(this-command command))
(call-interactively command)))))))
(my-use-package zoom-window
:ensure t
:general
(my-leader
"z" '(zoom-window-zoom :wk "Zoom current window")
"Z" '(zoom-window-next :wk "Zoom next window")))
(my-use-package winner-mode
:general
(my-leader
"j j" '(winner-undo :wk "Winner undo")
"j k" '(winner-redo :wk "Winner redo"))
:config
(winner-mode))
(my-use-package savehist
:ensure nil
:init
(save-place-mode 1)
(savehist-mode 1))
(my-use-package emacs
:hook
(minibuffer-setup . cursor-intangible-mode)
(after-change-major-mode . my/hook-indent-adjust-shift-widths)
:general
(my-leader
"n" '(:keymap narrow-map :wk "Narrowing")
"f R" '(revert-buffer :wk "Revert"))
:bind
(("C-x C-b" . ibuffer))
:custom
(use-short-answers t)
(enable-recursive-minibuffers t)
(read-extended-command-predicate #'command-completion-default-include-p)
(use-dialog-box nil)
(ediff-setup-windows-plain 'ediff-setup-windows-plain)
:init
(put 'narrow-to-region 'disabled nil)
(setq minibuffer-prompt-properties
'(read-only t cursor-intangible t face minibuffer-prompt)))
(my-use-package autorevert
:ensure nil
:custom
(global-auto-revert-non-file-buffers t)
(global-auto-revert-mode t))
;; Help
(my-use-package helpful
:ensure t
:general
(my-leader
"d d" '(helpful-at-point :wk "Helpful at point"))
:bind (
([remap describe-function] . helpful-function)
([remap describe-variable] . helpful-variable)
([remap describe-key] . helpful-key)
([remap describe-command] . helpful-command)
([remap describe-symbol] . helpful-symbol)))
;; Projects
(my-use-package xref
:ensure t)
(my-use-package project
:ensure t
:custom
(vc-handled-backends '(Git))
(project-vc-extra-root-markers '(".project"))
(project-switch-commands
'(
(consult-project-buffer "Find buffer" "b")
(project-find-file "Find file" "f")
(consult-ripgrep-all "Search" "s")
(project-dired "Dired" "d")
;; (vterm-toggle "Vterm" "v") ;; TODO: make sure it opens inside of the project!
(my/magit-current-window "Magit" "m"))) :general
(my-leader
"p" '(:keymap project-prefix-map :wk "Project"))
:init
(defun my/magit-current-window ()
"Open Magit status in current window"
(interactive)
(same-window-prefix)
(magit-status (project-root (project-current t))))
)
;; Modeline
(my-use-package vs-modeline
:ensure (vs-modeline :type git
:host github
:repo "VojtechStep/vs-modeline.el")
:demand t
:custom
((vs-modeline-left
'("%e"
" "
(:eval (vs-modeline-evil))
mode-line-process
(:eval (vs-modeline-project-el-name))
(:eval (vs-modeline-buffer-name))
(:eval (when (buffer-modified-p) "+"))
(:eval (when buffer-read-only " RO"))))
(vs-modeline-right
'(
(:eval (when which-func-mode which-func-format))
(:eval (when which-function-mode " "))
(:eval (vs-modeline-input-method))
(:eval (when flymake-mode " "))
(:eval (when flymake-mode flymake-mode-line-exception))
(:eval (when flymake-mode flymake-mode-line-counters))
(:eval (when flymake-mode " "))
mode-name
" "
(:eval (vs-modeline-position-rel))
(:eval (vs-modeline-position)))))
:config
;; Why does project.el project-current slow down by a lot?
(defvar project-project-name nil)
(defun obtain-project-name ()
(let ((project-info (project-current)))
(setq-local project-project-name
(or (unless project-info "")
(file-name-nondirectory (directory-file-name (nth 2 project-info)))))))
(defun obtain-project-name-once ()
(if project-project-name
project-project-name
(obtain-project-name)))
(vs-modeline-def-prop-segment project-el-name
(when-let ((project-name (obtain-project-name-once)))
(concat " " project-name))
'vs-modeline-project)
(vs-modeline-mode))
;; File browser
(my-use-package dired
:ensure nil
:general
(my-leader
"o d" '(dired-jump :wk "Dired"))
:custom
(dired-dwim-target t)
(dired-vc-rename-file t))
(my-use-package diredfl
:ensure t
:config
(diredfl-global-mode))
(my-use-package fd-dired
:ensure t
:commands (fd-dired fd-grep-dired)
:general
(my-leader
"s d" '(fd-dired :wk "Search dired")
"s D" '(fd-grep-dired :wk "Search contents dired")))
(my-use-package dired-filter
:ensure t)
(my-use-package dired-subtree
:ensure t)
(my-use-package dired-ranger
:ensure t
:general
(my-local-leader dired-mode-map
:override t
"y" '(dired-ranger-copy :wk "Ranger copy")
"c" '(dired-ranger-copy :wk "Ranger copy")
"m" '(dired-ranger-move :wk "Ranger move")
"p" '(dired-ranger-paste :wk "Ranger paste")
"b" '(dired-ranger-bookmark :wk "Ranger bookmark")
"RET" '(dired-ranger-bookmark-visit :wk "Ranger bookmark visit"))
)
(my-use-package dired-narrow
:ensure t)
;; There is a bug for dired-collapse + dired-subtree.
;; When expanding the last folder in a tree, it cannot
;; be reliably expanded / collapsed...
(my-use-package dired-collapse
:ensure t
:hook
(dired-mode . dired-collapse-mode))
;; TODO: Use this?
;; (my-use-package dirvish
;; :ensure t)
;; Git
(my-use-package transient
:ensure t
:custom
(transient-levels-file (locate-user-emacs-file "transient-levels.el")))
(my-use-package magit
:ensure t
:hook
(with-editor-mode . evil-insert-state)
:general
(my-leader
"g" '(nil :wk "Git")
"g g" '(magit-status :wk "Git status")
"g c" '(magit-clone :wk "Git clone")
"g i" '(magit-init :wk "Git init")
"g ." '(magit-dispatch :wk "Dispatch")
"g b" '(magit-blame :wk "Blame")
"g l" '(magit-log-buffer-file :wk "Log buffer file")
"g L" '(magit-log :wk "Log")
"g d" '(magit-diff-buffer-file :wk "Diff buffer file"))
:custom
(magit-save-repository-buffers 'dontask)
(magit-diff-refine-hunk 'all)
:config
;; I don't know why, but if this is in :custom block,
;; magit-dispatch ends up in an error...
(setq evil-collection-magit-want-horizontal-movement t)
(evil-set-initial-state #'git-commit-mode 'insert))
(my-use-package hl-todo
:ensure (:pin t :tag "v3.6.0")
:after evil
:hook
((prog-mode text-mode) . hl-todo-mode)
:general
(my-local-leader hl-todo-mode-map
"t j" '(hl-todo-next :wk "next TODO" :jump t)
"t k" '(hl-todo-previous :wk "previous TODO" :jump t))
(normal hl-todo-mode-map
"]t" '(hl-todo-next :wk "previous TODO" :jump t)
"[t" '(hl-todo-previous :wk "next TODO" :jump t)))
;; (my-use-package magit-todos
;; :ensure t
;; :after magit
;; :config (magit-todos-mode 1))
(my-use-package git-gutter-fringe
:ensure t
:preface
(defun git-gutter-with-find-file (&rest args)
(global-git-gutter-mode t)
(remove-hook 'find-file-hook #'git-gutter-with-find-file))
(add-hook 'find-file-hook #'git-gutter-with-find-file)
:general
(my-leader
"g p" '(git-gutter:previous-hunk :wk "Previous hunk")
"g n" '(git-gutter:next-hunk :wk "Next hunk")
"g C-g" '(git-gutter :wk "Git gutter")
"g v =" '(git-gutter:popup-hunk :wk "Popup hunk")
"g v s" '(git-gutter:stage-hunk :wk "Stage hunk")
"g v r" '(git-gutter:revert-hunk :wk "Revert hunk")
"g v SPC" '(git-gutter:mark-hunk :wk "Mark hunk"))
(normal
"]d" '(git-gutter:next-hunk :wk "Next hunk")
"[d" '(git-gutter:previous-hunk :wk "Next hunk")))
(my-use-package git-timemachine
:ensure t
:general
(my-leader
"g t" '(git-timemachine-toggle :wk "Git timemachine"))
:config
(evil-define-key 'normal git-timemachine-mode-map
"?" 'git-timemachine-help
"gtc" 'git-timemachine-show-commit)
;; Since the mapping for git-timemachine-help is not
;; updated by updating the map, update it manually.
(transient-define-prefix git-timemachine-help ()
"Show online help."
["Navigate"
[("C-k" "show previous revision" git-timemachine-show-previous-revision)
("C-j" "show next revision" git-timemachine-show-next-revision)
("gtg" "show nth revision" git-timemachine-show-nth-revision)
("gtt" "show fuzzy revision" git-timemachine-show-revision-fuzzy)]]
["Kill current revision"
[("gty" "kill abbreviated revision" git-timemachine-kill-abbreviated-revision)
("gtY" "kill revision" git-timemachine-kill-revision)]]
["Misc"
[("gtb" "blame current revision" git-timemachine-blame)
("gtc" "show commit" git-timemachine-show-commit)
("?" "show help" git-timemachine-help)
("q" "quit" git-timemachine-quit)]])
)
;; Editing
(my-use-package flymake
:ensure t
:general
(my-leader
"e n" '(flymake-goto-next-error :wk "Next error")
"e p" '(flymake-goto-prev-error :wk "Prev error")
"e j" '(flymake-goto-next-error :wk "Next error")
"e k" '(flymake-goto-prev-error :wk "Prev error")
"e R" '(flymake-running-backends :wk "Running backends")
"e d" '(flymake-disabled-backends :wk "Disabled backends")
"e r" '(flymake-reporting-backends :wk "Reported backends")
"e l" '(flymake-show-buffer-diagnostics :wk "Show buffer diagnostics")
"e L" '(flymake-show-project-diagnostics :wk "Show project diagnostics")
))
;; TODO: what about isearch-lazy-count variable?
;; Added in emacs 27, could be an alternative.
(my-use-package evil-anzu
:ensure t
:demand t
:after evil
:config
(global-anzu-mode +1))
;; Vterm
(my-use-package vterm
:ensure nil ; I don't know why, but if this is used through guix-emacs, with vterm already available, it asks for the module compilation if ti his t...
:demand t ; Prevents asking for vterm module in guix-emacs
:config
(add-to-list 'vterm-eval-cmds '("update-pwd" (lambda (path) (setq default-directory path))))
(push (list "find-file-below"
(lambda (path)
(if-let* ((buf (find-file-noselect path))
(window (display-buffer-below-selected buf nil)))
(select-window window)
(message "Failed to open file: %s" path))))
vterm-eval-cmds))
(my-use-package vterm-toggle
:ensure t
:after vterm
:commands vterm-toggle
:custom
(vterm-toggle-scope 'project)
(vterm-toggle-project-root t)
:general
(my-leader
"t t" '(vterm-toggle :wk "Toggle terminal")
"t T" '(vterm :wk "Open terminal")))
;; MMM mode
;; (my-use-package mmm-mode
;; :ensure t
;; :config
;; (setq mmm-global-mode 'maybe))
(my-use-package corfu
:ensure t
:demand t
:bind
("C-SPC" . completion-at-point)
(:map corfu-map
("M-m" . corfu-move-to-minibuffer)
("M-q" . corfu-quick-complete)
("C-q" . corfu-quick-complete)
("M-SPC" . corfu-insert-separator))
:custom
(corfu-cycle t)
(corfu-quit-no-match 'separator)
(completion-cycle-threshold 3)
:init
(defun corfu-move-to-minibuffer ()
(interactive)
(pcase completion-in-region--data
(`(,beg ,end ,table ,pred ,extras)
(let ((completion-extra-properties extras)
completion-cycle-threshold completion-cycling)
(consult-completion-in-region beg end table pred)))))
:config
(global-unset-key (kbd "C-@") )
(global-corfu-mode 1)
(add-to-list 'corfu-continue-commands #'corfu-move-to-minibuffer))
(use-package cape
:ensure t
:demand t
:init
(add-hook 'completion-at-point-functions #'cape-dabbrev)
(add-hook 'completion-at-point-functions #'cape-file)
(add-hook 'completion-at-point-functions #'cape-keyword)
:custom
(cape-dabbrev-min-length 2)
(cape-dabbrev-check-other-buffers #'cape--buffers-major-mode)
:config
(defun kb/cape-capf-setup-git-commit ()
(let ((result))
(dolist (element '(cape-symbol cape-dabbrev) result)
(add-to-list 'completion-at-point-functions element))))
:general(:prefix "M-p"
"p" 'completion-at-point
"t" 'complete-tag ; etags
"d" 'cape-dabbrev ; basically `dabbrev-completion'
"h" 'cape-history
"f" 'cape-file
"k" 'cape-keyword
"s" 'cape-symbol
"a" 'cape-abbrev
"i" 'cape-ispell
"l" 'cape-line
":" 'cape-emoji
"w" 'cape-dict
"\\" 'cape-tex
"_" 'cape-tex
"^" 'cape-tex
"&" 'cape-sgml
"r" 'cape-rfc1345))
;; Programming
(my-use-package gendoxy
:ensure (gendoxy :type git :host gitlab :repo "mp81ss_repo/gendoxy")
:custom
(cc-search-directories '("." "../src" "../include" "/usr/include" "/usr/local/include/*"))
:general
;; TODO: figure out how to merge these into one call
(my-local-leader c-ts-mode-map
"d h" '(gendoxy-tag :wk "Gendoxy header")
"d t" '(gendoxy-tag :wk "Gendoxy tag")
"d T" '(gendoxy-tag-header :wk "Gendoxy tag header")
"d g" '(gendoxy-group :wk "Gendoxy group")
"d G" '(gendoxy-group-header :wk "Gendoxy group header")
"d s" '(gendoxy-group-start :wk "Gendoxy group start")
"d e" '(gendoxy-group-end :wk "Gendoxy group end")
"o" '(ff-find-related-file :wk "Find other file"))
(my-local-leader c-mode-map
"d h" '(gendoxy-tag :wk "Gendoxy header")
"d t" '(gendoxy-tag :wk "Gendoxy tag")
"d T" '(gendoxy-tag-header :wk "Gendoxy tag header")
"d g" '(gendoxy-group :wk "Gendoxy group")
"d G" '(gendoxy-group-header :wk "Gendoxy group header")
"d s" '(gendoxy-group-start :wk "Gendoxy group start")
"d e" '(gendoxy-group-end :wk "Gendoxy group end")
"o" '(ff-find-related-file :wk "Find other file")))
(my-use-package jsonrpc
:ensure t)
(my-use-package eldoc
:ensure t
:custom
(eldoc-documentation-strategy 'eldoc-documentation-compose-eagerly)
:config
(add-to-list 'display-buffer-alist
'("^\\*eldoc for" display-buffer-at-bottom
(window-height . 4))))
(my-use-package eglot
:ensure t
:commands (eglot eglot-ensure)
:hook
((eglot-managed-mode . mp-eglot-eldoc))
:custom
(eglot-ignored-server-capabilities '(:documentHighlightProvider))
(eglot-stay-out-of '(imenu)) ; I prefer the ts imenu for now
:general
(normal eglot--managed-mode
:definer 'minor-mode
"gR" '(eglot-rename :wk "Rename identifier")
"g." '(eglot-code-actions :wk "Code actions"))
:preface
; Thanks https://www.masteringemacs.org/article/seamlessly-merge-multiple-documentation-sources-eldoc
(defun mp-eglot-eldoc ()
(setq eldoc-documentation-strategy
'eldoc-documentation-compose-eagerly)))
(my-use-package envrc
:ensure t
:demand t
:config
(envrc-global-mode 1))
(my-use-package fancy-compilation
:ensure t
:defer 3
:custom
(fancy-compilation-scroll-output 'first-error)
:config
(fancy-compilation-mode))
(my-use-package dape
:ensure t
:custom
(dape-buffer-window-arrangement 'right))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Languages
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; PDF tools
(my-use-package pdf-tools
:ensure nil ;; TODO: how to manage this?
;; I have this package installed via
;; my distribution. To get the executables
;; properly
:hook
(doc-view-mode . (lambda () (display-line-numbers-mode -1)))
(pdf-view-mode . (lambda () (display-line-numbers-mode -1)))
:mode ("\\.pdf\\'" . pdf-view-mode)
:commands pdf-view-mode)
;; Treesit langs
(my-use-package emacs
:ensure nil
:custom
(treesit-font-lock-level 4)
:config
(which-function-mode 1)
(defun my/which-func-try-to-enable ()
(unless (or (not which-function-mode)
(local-variable-p 'which-func-mode))
(setq which-func-mode (or (eq which-func-modes t)
(and (apply 'derived-mode-p which-func-modes) t)))))
(advice-add 'which-func-try-to-enable :override #'my/which-func-try-to-enable))
;; Nix
(my-use-package nix-mode
:ensure t
;; :ensure (nix-mode :fetcher github
;; :repo "NixOS/nix-mode"
;; :files (:defaults (:exclude "nix-company.el")))
;; :after mmm-mode
:mode "\\.nix\\'"
:init
;; (load (expand-file-name "nix-mode-mmm.el" (file-name-directory (locate-library "nix-mode"))))
)
;; Guile and Guix
(my-use-package geiser
:ensure t)
(my-use-package geiser-guile
:ensure t)
(my-use-package guix
:ensure t)
;; Rust
(my-use-package rust-mode
:ensure t
:custom
(rust-mode-treesitter-derive t)
:config
(my/indent-variable-mode-alist-add rust-ts-mode rust-ts-mode-indent-offset))
(my-use-package rustic
:ensure t
:mode
("\\.rs\\'" . rustic-mode))
;; CSharp
(my-use-package csharp-mode
:ensure nil
:after eglot
:mode (("\\.cs\\'" . csharp-ts-mode))
:config
(my/indent-variable-mode-alist-add csharp-mode c-basic-offset)
(my/indent-variable-mode-alist-add csharp-ts-mode csharp-ts-mode-indent-offset))
;; Sh, Bash
(my-use-package sh-script
:ensure nil
:custom
(sh-basic-offset 2))
;; (my-use-package bash-ts-mode
;; :ensure nil
;; :mode "\\.sh\\'"
;; :custom
;; (bash-ts-mode-indent-offset 2))
;; Python
(my-use-package emacs
:ensure nil
:mode
(("\\.py[iw]?\\'" . python-ts-mode))
:config
(my/indent-variable-mode-alist-add python-mode python-indent-offset)
(my/indent-variable-mode-alist-add python-ts-mode python-indent-offset))
;; Matlab
(my-use-package matlab
:ensure matlab-mode
:commands matlab-mode
:mode "\\.m\\'"
:after eglot
:custom
(matlab-shell-run-region-function 'matlab-shell-region->script)
(matlab-shell-tab-use-company nil)
:general
(my-local-leader matlab-mode-map
"b" '(mlgud-break :wk "Breakpoint")
"x" '(mlgud-remove :wk "Remove breakpoint")
"c" '(matlab-shell-run-cell :wk "Run cell")
"r" '(matlab-shell-run-region :wk "Run region")
"v" '(matlab-shell-run-command :wk "Run command"))
(my-local-leader matlab-shell-gud-minor-mode-map
"b" '(mlgud-break :wk "Breakpoint")
"x" '(mlgud-remove :wk "Remove breakpoint")
"v" '(mlgud-list-breakpoints :wk "List breakpoints")
"s" '(mlgud-step :wk "Step")
"n" '(mlgud-next :wk "Next")
"f" '(mlgud-finish :wk "Finish function")
"c" '(mlgud-cont :wk "Continue")
"w" '(mlgud-show-stack :wk "Stack")
"e" '(matlab-shell-gud-show-symbol-value :wk "Symbol")
"q" '(mlgud-stop-subjob :wk "Quit"))
:config
(add-to-list 'eglot-server-programs
'(matlab-mode . ("matlab-language-server" "--stdio")))
(my/indent-variable-mode-alist-add matlab-mode matlab-indent-level)
)
;; Vhdl
(my-use-package vhdl-mode
:ensure nil
:commands vhdl-mode
:after eglot
;; :mode
;; Use vhdl-ts-mode instead
;; ("\\.vhdl?\\'" . vhdl-mode)
:general
(my-local-leader vhdl-mode-map
"a" '(nil :wk "Alignment")
"a a" '(vhdl-align-group :wk "Align group")
"a c" '(vhdl-align-inline-comment-group :wk "Align comment group"))
:hook
((vhdl-mode . vhdl-electric-mode)
(vhdl-mode . vhdl-stutter-mode))
:custom
(vhdl-clock-edge-condition 'function)
(vhdl-clock-name "clk_i")
(vhdl-reset-kind 'sync)
(vhdl-reset-name "rst_in")
(vhdl-basic-offset 2)
(vhdl-end-comment-column 300)
:config
(add-to-list 'eglot-server-programs
'(vhdl-mode . ("vhdl_ls")))
(my/indent-variable-mode-alist-add vhdl-mode vhdl-basic-offset)
(defun my/electric-space-not-in-strings (fun &rest args)
(if (vhdl-in-string-p)
(apply 'self-insert-command args)
(apply fun args)))
(advice-add 'vhdl-electric-space :around #'my/electric-space-not-in-strings))
(my-use-package vhdl-ts-mode
:ensure (:host github :repo "gmlarumbe/vhdl-ts-mode")
:demand t
;; :after vhdl-mode
:general
(my-local-leader vhdl-ts-mode-map
"f" '(nil :wk "Formatting")
"f f" '(my/vhdl-ts/beautify-block-at-point :wk "Beautify block at point")
"f b" '(my/vhdl-ts/beautify-buffer :wk "Beautify buffer"))
:custom
(vhdl-ts-indent-level tab-width)
:mode
("\\.vhdl?\\'" . vhdl-ts-mode)
:init
(defun my/vhdl-ts/beautify-block-at-point ()
(interactive)
(vhdl-align-group)
(vhdl-ts-beautify-block-at-point))
(defun my/vhdl-ts/beautify-buffer ()
(interactive)
(vhdl-align-buffer)
(vhdl-ts-beautify-block-at-point))
:config
(my/indent-variable-mode-alist-add vhdl-ts-mode vhdl-ts-indent-level)
(defun my/vhdl-ts-special-node-identifier-name (node)
"Return identifier name of NODE."
(let (temp-node)
(when node
(cond ((string-match vhdl-ts-instance-re (treesit-node-type node))
(cond ((setq temp-node (treesit-search-subtree node "\\_<component_instantiation\\_>"))
(treesit-node-text (treesit-node-child-by-field-name temp-node "component") :no-prop))
((setq temp-node (treesit-search-subtree node "entity_instantiation"))
(treesit-search-subtree node "entity_instantiation")
(treesit-node-text (treesit-node-child temp-node 1) :no-props))
(t (error "Unexpected component_instantiation_statement subnode!"))))
(t nil)))))
(defun my/vhdl-ts-node-identifier-name (orig node)
(when-let ((original-identifier-name (orig node)))
(let* ((special-identifier-name (my/vhdl-ts-special-node-identifier-name node))
(concat-identifier-name
(when special-identifier-name
(concat ": " special-identifier-name))))
(concat original-identifier-name concat-identifier-name))))
;; (advice-add 'vhdl-ts--node-identifier-name :around #'my/vhdl-ts-node-identifier-name)
)
;; (my-use-package hydra
;; :ensure t)
;; Verilog
;; (my-use-package verilog-mode
;; :ensure nil
;; :mode
;; ("\\.v\\'" . verilog-mode)
;; ("\\.sv\\'" . verilog-mode)
;; :custom
;; (verilog-indent-lists nil)
;; (verilog-indent-level 2)
;; (verilog-indent-level-behavioral 2)
;; (verilog-indent-level-declaration 2)
;; (verilog-indent-level-module 2)
;; (verilog-case-indent 2)
;; (verilog-cexp-indent 2)
;; (verilog-align-ifelse t)
;; (verilog-auto-delete-trailing-whitespace t)
;; (verilog-auto-newline nil)
;; (verilog-auto-save-policy nil)
;; (verilog-auto-template-warn-unused t)
;; (verilog-tab-to-comment t)
;; (verilog-highlight-modules t)
;; (verilog-highlight-grouping-keywords t)
;; )
;; (my-use-package verilog-ext
;; :ensure t
;; :hook
;; (verilog-mode . verilog-ext-mode)
;; :custom
;; (verilog-ext-feature-list
;; '(font-lock
;; xref
;; capf
;; hierarchy
;; lsp
;; navigation
;; template
;; formatter
;; compilation
;; imenu
;; which-func
;; hideshow
;; typedefs
;; time-stamp
;; block-end-comments
;; ports))
;; :config
;; (verilog-ext-mode-setup))
(setq warning-minimum-level :error)
(require 'custom-packages nil t)
;;; init.el ends here