Emacs-Configuration-Modern/init.el

774 lines
24 KiB
EmacsLisp

(menu-bar-mode 0)
(tool-bar-mode 0)
(scroll-bar-mode 0)
(column-number-mode 1)
;; Set custom tab width here
(defvar custom-tab-width 8)
;; Disable bell/messages sound
(set-message-beep 'silent)
;; Temporary file config
(setq backup-directory-alist
`((".*" . ,temporary-file-directory)))
(setq auto-save-file-name-transforms
`((".*" ,temporary-file-directory t)))
;; Fixes to stop weird window geometry issues
(setq frame-inhibit-implied-resize t)
(setq frame-resize-pixelwise t)
;; Ensure that tabs are default over spaces
(setq-default tab-width custom-tab-width)
(setq tab-width custom-tab-width)
(setq-default indent-tabs-mode 't)
(setq indent-tabs-mode 't)
(advice-add 'indent-to :around
(lambda (orig-fun column &rest args)
(when (eq indent-tabs-mode 'only)
(setq column (* tab-width (round column tab-width))))
(apply orig-fun column args)))
(defvaralias 'c-basic-offset 'tab-width)
(electric-indent-mode 0)
;; Hide all minor modes from the modeline
(setq mode-line-modes
(mapcar (lambda (elem)
(pcase elem
(`(:propertize (,_ minor-mode-alist . ,_) . ,_) "")
(t elem)))
mode-line-modes))
;; Clipboard config
(setopt select-active-regions nil)
(setopt select-enable-clipboard 't)
(setopt select-enable-primary nil)
(setopt interprogram-cut-function #'gui-select-text)
;; Midnight Mode
; Automatically clean up old unused buffers
(midnight-mode 1)
;; Emacs client configuration
(set-frame-font "MesloLGL Nerd Font 20")
(setq default-frame-alist '((font . "MesloLGL Nerd Font 20")))
(defun client-config ()
(scroll-bar-mode 0)
)
(add-hook 'after-make-frame-functions #'(lambda (frame)
(select-frame frame)
(client-config)))
;; Ensure TAB key ACTUALLY works like a TAB key
(defun my/complete-or-tab ()
"Complete at point or insert a tab if no characters before point."
(interactive)
(if (and (char-before) (not (member (char-before) '(?\s ?\t ?\n)))) ; Check for whitespace, tabs or newline
(completion-at-point) ; If yes, do completion at point
(insert-tab))) ; If no, insert a tab character
(global-set-key (kbd "TAB") 'my/complete-or-tab)
(define-key global-map [remap backward-delete-char-untabify] 'backward-delete-char)
;; Track recently opened files
(recentf-mode 1)
;; Stop weird C-9 keybindings causing conflicts on typo
(define-key global-map [remap digit-argument] "")
;; Package management setup
; Elpaca
(unload-feature 'tramp t)
(defvar elpaca-installer-version 0.11)
(defvar elpaca-directory (expand-file-name "elpaca/" user-emacs-directory))
(defvar elpaca-builds-directory (expand-file-name "builds/" elpaca-directory))
(defvar elpaca-repos-directory (expand-file-name "repos/" elpaca-directory))
(defvar elpaca-order '(elpaca :repo "https://github.com/progfolio/elpaca.git"
:ref nil :depth 1 :inherit ignore
:files (:defaults "elpaca-test.el" (:exclude "extensions"))
:build (:not elpaca--activate-package)))
(let* ((repo (expand-file-name "elpaca/" elpaca-repos-directory))
(build (expand-file-name "elpaca/" elpaca-builds-directory))
(order (cdr elpaca-order))
(default-directory repo))
(add-to-list 'load-path (if (file-exists-p build) build repo))
(unless (file-exists-p repo)
(make-directory repo t)
(when (<= emacs-major-version 28) (require 'subr-x))
(condition-case-unless-debug err
(if-let* ((buffer (pop-to-buffer-same-window "*elpaca-bootstrap*"))
((zerop (apply #'call-process `("git" nil ,buffer t "clone"
,@(when-let* ((depth (plist-get order :depth)))
(list (format "--depth=%d" depth) "--no-single-branch"))
,(plist-get order :repo) ,repo))))
((zerop (call-process "git" nil buffer t "checkout"
(or (plist-get order :ref) "--"))))
(emacs (concat invocation-directory invocation-name))
((zerop (call-process emacs nil buffer nil "-Q" "-L" "." "--batch"
"--eval" "(byte-recompile-directory \".\" 0 'force)")))
((require 'elpaca))
((elpaca-generate-autoloads "elpaca" repo)))
(progn (message "%s" (buffer-string)) (kill-buffer buffer))
(error "%s" (with-current-buffer buffer (buffer-string))))
((error) (warn "%s" err) (delete-directory repo 'recursive))))
(unless (require 'elpaca-autoloads nil t)
(require 'elpaca)
(elpaca-generate-autoloads "elpaca" repo)
(let ((load-source-file-function nil)) (load "./elpaca-autoloads"))))
(add-hook 'after-init-hook #'elpaca-process-queues)
(elpaca `(,@elpaca-order))
; Install use-package support
(elpaca elpaca-use-package
;; Enable use-package :ensure support for Elpaca.
(elpaca-use-package-mode))
(elpaca-wait)
;; Optimisation
; GCMH
;Enforce a sneaky Garbage Collection strategy to minimize GC interference with user activity.
;During normal use a high GC threshold is set.
;When idling GC is triggered and a low threshold is set.
;This greatly improves performance/startup time of emacs.
(use-package gcmh
:ensure t
:init
(gcmh-mode 1)
;; Ensure garbage collector does not run TOO frequently which causes random freezes
(defun gcmh-mode-optimisation-setup-hook ()
(setq gc-cons-threshold most-positive-fixnum))
(defun gcmh-mode-optimisation-exit-hook ()
(setq gc-cons-threshold 800000))
(add-hook 'minibuffer-setup-hook 'gcmh-mode-optimisation-setup-hook)
(add-hook 'minibuffer-exit-hook 'gcmh-mode-optimisation-exit-hook)
)
; Fontification
(jit-lock-mode 1)
(jit-lock-debug-mode 1)
(setq jit-lock-stealth-time 1.25)
(setq jit-lock-stealth-nice 0.5) ;; Seconds between font locking.
(setq jit-lock-chunk-size 4096)
(setq jit-lock-defer-time 0)
(with-eval-after-load 'evil
(add-hook 'evil-insert-state-entry-hook
(lambda ()
(setq jit-lock-defer-time 0.25)) nil t)
(add-hook 'evil-insert-state-exit-hook
(lambda ()
(setq jit-lock-defer-time 0)) nil t))
;; TRAMP
;TRAMP edit files over SSH configuration
(use-package tramp
:ensure t
:config
;; To speed up connections
(setq tramp-verbose 0
tramp-chunksize 2000
tramp-use-ssh-controlmaster-options nil
tramp-default-method "ssh"
tramp-verbose 1
tramp-default-remote-shell "/bin/sh"
tramp-connection-local-default-shell-variables
'((shell-file-name . "/bin/bash")
(shell-command-switch . "-c")))
(add-to-list 'tramp-remote-path 'tramp-own-remote-path)
(when (eq window-system 'w32)
(setq tramp-default-method "plink"))
)
; Tramp RPC - Alternate backend promising more speed
(use-package tramp-rpc
:ensure (:host github :repo "ArthurHeymans/emacs-tramp-rpc")
:after tramp
:config
(setq tramp-rpc-deploy-local-cache-directory
"~/.cache/emacs/tramp-rpc-binaries"))
;; Org Mode Config
;Agenda
;For Org-Agenda, you can set a location of your Org Agenda file here. Set Agenda Directory:
(use-package org
:ensure (:wait t)
:demand t
:config
(setq org-agenda-files '("~/Nextcloud/Agenda"))
;This is will integrate the Calendar/Diary into Org-Agenda, so you can get access to dates on public holidays etc. Set diary to true:
(setq org-agenda-include-diary t)
;Ensure done date/closed timestamps are logged
(setq org-log-done 'time)
;Ensure state changes are logged into logbook
(setq org-log-into-drawer "LOGBOOK")
;Ensure agenda still shows DONE items
(setq org-agenda-skip-scheduled-if-done nil)
(setq agenda-skip-deadline-if-done nil)
(setq org-startup-folded t)
)
; For Org Pomodoro notification sound
(use-package sound-wav
:ensure t
)
; Org Pomodoro
(use-package org-pomodoro
:ensure t
:after org
:defer t
:config
(setq org-pomodoro-manual-break t)
(setq org-pomodoro-keep-killed-pomodoro-time t)
(setq org-pomodoro-play-sounds t)
(setq org-pomodoro-ticking-sound-p nil)
(setq org-pomodoro-audio-player "mpv")
)
(defun sound-alert (alert)
"Play a sound notification and show message ALERT."
(sound-wav-play (expand-file-name (concat user-emacs-directory "elpaca/builds/org-pomodoro/resources/bell.wav")))
(message alert))
; Org timer set timer alert sound
(defun org-timer-sound-alert ()
"Sound notification on org timer finish."
(sound-alert "Timer done!"))
(add-hook 'org-timer-done-hook 'org-timer-sound-alert)
; System notifications of org agenda items
(use-package org-alert
:ensure t
:after org
:config
(setq org-alert-headline-regexp "TODO\\|WAITING")
(setq org-agenda-skip-scheduled-if-done t)
(setq org-agenda-skip-deadline-if-done t)
(alert-define-style 'custom-org-alert-notification
:title "Custom Notification"
:notifier
(lambda (info)
; 'info' is a plist containing :title, :message, :severity, etc.
(sound-alert (concat "ORG ALERT: "
;(plist-get info :title)
(plist-get info :message)))))
(setq alert-default-style 'custom-org-alert-notification)
(org-alert-enable)
; Update notifications whenever the agenda is refreshed
(add-hook 'org-finalize-agenda-hook 'org-alert-enable)
)
; Org Mode Journalling
(use-package org-journal
:ensure t
:after org
:config
(setq org-journal-dir "~/Nextcloud/Journal/")
(setq org-journal-file-type 'daily)
(setq org-journal-file-format "%Y%m%d.org")
)
;; Org Latex Preview Scale
; Automatically toggle Org mode LaTeX fragment previews as the cursor enters and exits them
(use-package org-fragtog
:ensure t
:after org
:config
(add-hook 'org-mode-hook 'org-latex-preview)
(add-hook 'org-mode-hook 'org-fragtog-mode)
(setq org-format-latex-options (plist-put org-format-latex-options :scale 3.0))
)
;; Emacs minibuffer configurations.
(use-package emacs
:ensure nil
:custom
(tab-always-indent 'complete)
;; Enable context menu. `vertico-multiform-mode' adds a menu in the minibuffer
;; to switch display modes.
(context-menu-mode t)
;; Support opening new minibuffers from inside existing minibuffers.
(enable-recursive-minibuffers t)
;; Hide commands in M-x which do not work in the current mode. Vertico
;; commands are hidden in normal buffers. This setting is useful beyond
;; Vertico.
(read-extended-command-predicate #'command-completion-default-include-p)
;; Do not allow the cursor in the minibuffer prompt
(minibuffer-prompt-properties
'(read-only t cursor-intangible t face minibuffer-prompt)
)
)
;; Doom Theme
(use-package doom-themes
:ensure t
:config
;; Global settings (defaults)
(setq
doom-themes-enable-bold t ; if nil, bold is universally disabled
doom-themes-enable-italic t ; if nil, italics is universally disabled
)
(load-theme 'doom-gruvbox-light t)
)
;; Autocompletion configuration
;(use-package ido-vertical-mode
; :ensure t
; :config (ido-vertical-mode 1))
;; Enable Vertico.
(use-package vertico
:ensure t
;;:custom
;; (vertico-scroll-margin 0) ;; Different scroll margin
;; (vertico-count 20) ;; Show more candidates
;; (vertico-resize t) ;; Grow and shrink the Vertico minibuffer
;; (vertico-cycle t) ;; Enable cycling for `vertico-next/previous'
:config
(define-key vertico-map (kbd "C-k") 'vertico-previous)
(define-key vertico-map (kbd "C-j") 'vertico-next)
:init
(vertico-mode)
)
;; Fuzzy matching for completion frameworks like Vertico
(use-package orderless
:ensure t
:custom
(completion-styles '(orderless basic))
(completion-category-overrides '((file (styles partial-completion))))
(completion-pcm-leading-wildcard t) ;; Emacs 31: partial-completion behaves like substring
)
;; Enhanced commands that Vertico can make use of
(use-package consult
:ensure t
:config
(define-key global-map [remap isearch-forward] 'consult-ripgrep)
(define-key global-map [remap switch-to-buffer] 'consult-buffer)
)
;; Persist history over Emacs restarts. Vertico sorts by history position.
(use-package savehist
:ensure nil
:init
(savehist-mode)
)
;; Corfu Autocomplete in buffer
(use-package corfu
:ensure t
:hook
(prog-mode . corfu-mode)
(html-ts-mode . corfu-mode)
(css-ts-mode . corfu-mode)
;; (shell-mode . corfu-mode)
;; (eshell-mode . corfu-mode))
:config
(setq
auto nil
corfu-preselect 'first
)
;;(global-corfu-mode)
)
;; Evil Config
; Vim Bindings
(use-package evil
:ensure t
:bind (("<escape>" . keyboard-escape-quit))
:init
(setq evil-want-keybinding nil)
(evil-mode 1)
:config
(define-key evil-insert-state-map (kbd "C-g") 'evil-force-normal-state)
(define-key evil-motion-state-map [remap evil-search-forward] 'consult-line)
)
; Evil Collection, configs evil bindings for more packages
(use-package evil-collection
:after evil
:ensure t
:config
(evil-collection-init)
)
;; Eshell config
; Like zoxide
(use-package eshell-z
:ensure t
:after tramp
:config
(add-hook 'eshell-mode-hook
(defun my-eshell-mode-hook ()
(require 'eshell-z)))
)
; Bash completion commands in eshell
(use-package bash-completion
:ensure t
:init
(autoload 'bash-completion-dynamic-complete
"bash-completion"
"BASH completion hook")
(add-hook 'shell-dynamic-complete-functions
'bash-completion-dynamic-complete)
(add-hook 'eshell-mode-hook
(lambda ()
(add-hook 'completion-at-point-functions
'bash-completion-capf-nonexclusive nil t)))
)
; Import bash aliases to eshell
(defun eshell-load-bash-aliases ()
"Read Bash aliases and add them to the list of eshell aliases."
;; Bash needs to be run - temporarily - interactively
;; in order to get the list of aliases.
(with-temp-buffer
(call-process "bash" nil '(t nil) nil "-ci" "alias")
(goto-char (point-min))
; Bash aliases to exclude
(flush-lines "^alias magit\\|^alias oc\\|^alias z\\|^alias zi\\|^alias cd\\|^alias cdi\\|^alias sudo")
(while (re-search-forward "alias \\(.+\\)='\\(.+\\)'$" nil t)
(add-to-list 'eshell-command-aliases-list (list (match-string 1) (match-string 2))))))
;; We only want Bash aliases to be loaded when Eshell loads its own aliases,
;; rather than every time `eshell-mode' is enabled.
(add-hook 'eshell-first-time-mode-hook 'eshell-load-bash-aliases t)
; Eat is a terminal emulator that can integrate nicely with eshell, allows us to run full ncurses applications inside eshell.
(use-package eat
:ensure t
:init
;; For `eat-eshell-mode'.
(add-hook 'eshell-load-hook #'eat-eshell-mode)
;; For `eat-eshell-visual-command-mode'.
(add-hook 'eshell-load-hook #'eat-eshell-visual-command-mode)
)
; New create new eshell instance
(defun eshell/new ()
(interactive)
(eshell t))
;; Sudo edit command to escalate priv if need be
(use-package sudo-edit
:ensure t
:config
(add-hook 'before-save-hook 'sudo-before-save-hook)
)
(setq tramp-auto-save-directory "~/.emacs.d/tramp-autosave")
;; Magit
(use-package transient
:ensure t)
(use-package magit
:ensure t
:after transient)
;; Mu4e Mail Config
(if (executable-find "mu")
(use-package mu4e
:ensure nil
:config
(setq mu4e-mu-binary (executable-find "mu"))
;; This is set to 't' to avoid mail syncing issues when using mbsync
(setq mu4e-change-filenames-when-moving t)
;; Refresh mail using isync every 10 minutes
;(setq mu4e-update-interval (* 10 60))
(setq mu4e-get-mail-command "mbsync -a")
(setq mu4e-maildir "~/Mail")
;; Sending mail function
(setq message-send-mail-function 'smtpmail-send-it)
;; Make sure plain text mails flow correctly for recipients
(setq mu4e-compose-format-flowed t)
;; Use completing read AKA vertico
(setq mu4e-completing-read-function 'completing-read)
(setq mu4e-contexts
(list
;; Work account
(make-mu4e-context
:name "A CSpark Work"
:match-func
(lambda (msg)
(when msg
(string-prefix-p "/work-cspark" (mu4e-message-field msg :maildir))))
:vars '((user-mail-address . "work@cspark.dev")
(user-full-name . "Curt Spark (Work)")
(smtpmail-smtp-server . "smtp.cspark.dev")
(smtpmail-smtp-service . 465)
(smtpmail-stream-type . ssl)
(mu4e-compose-signature . "- Curt")
(mu4e-inbox-folder . "/work-cspark/Inbox")
(mu4e-drafts-folder . "/work-cspark/Drafts")
(mu4e-sent-folder . "/work-cspark/Sent Mail")
(mu4e-trash-folder . "/work-cspark/Trash")))
;; Services account
(make-mu4e-context
:name "B CSpark Services"
:match-func
(lambda (msg)
(when msg
(string-prefix-p "/services-cspark" (mu4e-message-field msg :maildir))))
:vars '((user-mail-address . "services@cspark.dev")
(user-full-name . "Curt Spark (services)")
(smtpmail-smtp-server . "smtp.cspark.dev")
(smtpmail-smtp-service . 465)
(smtpmail-stream-type . ssl)
(mu4e-compose-signature . "- Curt")
(mu4e-inbox-folder . "/services-cspark/Inbox")
(mu4e-drafts-folder . "/services-cspark/Drafts")
(mu4e-sent-folder . "/services-cspark/Sent Mail")
(mu4e-trash-folder . "/services-cspark/Trash")))
;; Personal account
(make-mu4e-context
:name "C CSpark Personal"
:match-func
(lambda (msg)
(when msg
(string-prefix-p "/personal-cspark" (mu4e-message-field msg :maildir))))
:vars '((user-mail-address . "personal@cspark.dev")
(user-full-name . "Curt Spark (personal)")
(smtpmail-smtp-server . "smtp.cspark.dev")
(smtpmail-smtp-service . 465)
(smtpmail-stream-type . ssl)
(mu4e-compose-signature . "- Curt")
(mu4e-inbox-folder . "/personal-cspark/Inbox")
(mu4e-drafts-folder . "/personal-cspark/Drafts")
(mu4e-sent-folder . "/personal-cspark/Sent Mail")
(mu4e-trash-folder . "/personal-cspark/Trash")))
;; Tuxtank Services account
(make-mu4e-context
:name "D Tuxtank Services"
:match-func
(lambda (msg)
(when msg
(string-prefix-p "/personal-tuxtank" (mu4e-message-field msg :maildir))))
:vars '((user-mail-address . "personal@tuxtank.dev")
(user-full-name . "Tuxtank (personal)")
(smtpmail-smtp-server . "smtp.tuxtank.dev")
(smtpmail-smtp-service . 465)
(smtpmail-stream-type . ssl)
(mu4e-compose-signature . "- Tuxtank")
(mu4e-inbox-folder . "/personal-tuxtank/Inbox")
(mu4e-drafts-folder . "/personal-tuxtank/Drafts")
(mu4e-sent-folder . "/personal-tuxtank/Sent Mail")
(mu4e-trash-folder . "/personal-tuxtank/Trash"))))
)
;(setq mu4e-maildir-shortcuts
; '(("/Gmail/Inbox" . ?i)
; ("/Gmail/[Gmail]/Sent Mail" . ?s)
; ("/Gmail/[Gmail]/Trash" . ?t)
; ("/Gmail/[Gmail]/Drafts" . ?d)
; ("/Gmail/[Gmail]/All Mail" . ?a)))
)
)
;; Rainbow delimiters
(use-package rainbow-delimiters
:ensure t
:hook
(prog-mode . rainbow-delimiters-mode))
;; Treesit Config
(use-package treesit
:ensure nil
:commands (treesit-install-language-grammar nf/treesit-install-all-languages)
:init
(setq treesit-language-source-alist
'((bash . ("https://github.com/tree-sitter/tree-sitter-bash"))
(c . ("https://github.com/tree-sitter/tree-sitter-c"))
(cpp . ("https://github.com/tree-sitter/tree-sitter-cpp"))
(css . ("https://github.com/tree-sitter/tree-sitter-css"))
(cmake . ("https://github.com/uyha/tree-sitter-cmake"))
(go . ("https://github.com/tree-sitter/tree-sitter-go"))
(html . ("https://github.com/tree-sitter/tree-sitter-html"))
(javascript . ("https://github.com/tree-sitter/tree-sitter-javascript"))
(json . ("https://github.com/tree-sitter/tree-sitter-json"))
(julia . ("https://github.com/tree-sitter/tree-sitter-julia"))
(lua . ("https://github.com/Azganoth/tree-sitter-lua"))
(make . ("https://github.com/alemuller/tree-sitter-make"))
(ocaml . ("https://github.com/tree-sitter/tree-sitter-ocaml" "master" "ocaml/src"))
(python . ("https://github.com/tree-sitter/tree-sitter-python"))
(php . ("https://github.com/tree-sitter/tree-sitter-php"))
(typescript . ("https://github.com/tree-sitter/tree-sitter-typescript" "master" "typescript/src"))
(tsx . ("https://github.com/tree-sitter/tree-sitter-typescript" "master" "tsx/src"))
(ruby . ("https://github.com/tree-sitter/tree-sitter-ruby"))
(rust . ("https://github.com/tree-sitter/tree-sitter-rust"))
(sql . ("https://github.com/m-novikov/tree-sitter-sql"))
(toml . ("https://github.com/tree-sitter/tree-sitter-toml"))
(zig . ("https://github.com/GrayJack/tree-sitter-zig")))
)
:config ;; Credit to https://github.com/Nathan-Furnal/dotemacs/blob/df9b845563a84a927ff762e172334cf772253a44/init.el#L1154
(defun nf/treesit-install-all-languages ()
"Install all languages specified by `treesit-language-source-alist'."
(interactive)
(let ((languages (mapcar 'car treesit-language-source-alist)))
(dolist (lang languages)
(treesit-install-language-grammar lang)
(message "`%s' parser was installed." lang)
(sit-for 0.75))))
)
(setq treesit-font-lock-level 4)
; Remap basic modes to treesit equivalent
(use-package bash-ts-mode
:ensure nil
:mode "\\.sh\\'")
(use-package c-ts-mode
:ensure nil
:mode "\\.c\\'")
(use-package rust-ts-mode
:ensure nil
:mode "\\.rs\\'")
(use-package swift-ts-mode
:ensure t
:mode "\\.swift\\'")
(use-package nix-ts-mode
:ensure nil
:mode "\\.nix\\'")
(use-package html-ts-mode
:ensure nil
:mode "\\.html\\'")
(use-package css-ts-mode
:ensure nil
:mode "\\.css\\'")
(use-package js-ts-mode
:ensure nil
:mode "\\.js\\'")
(use-package typescript-ts-mode
:ensure nil
:mode "\\.ts\\'")
(use-package tsx-ts-mode
:ensure nil
:mode "\\.tsx\\'")
;(use-package emacs-lisp-ts-mode
; :ensure t)
; Remap base modes to their treesitter counterpart
(setq major-mode-remap-alist
'(
;(emacs-lisp-mode . emacs-lisp-ts-mode)
(c-mode . c-ts-mode)
(rust-mode . rust-ts-mode)
(rustic-mode . rust-ts-mode)
(python-mode . python-ts-mode)
(html-mode . html-ts-mode)
(css-mode . css-ts-mode)
(js-mode . js-ts-mode)
(javascript-mode . js-ts-mode)
)
)
;; Programming treesit style config
; Enforcing tabs as programming style
(add-hook 'prog-mode-hook
(lambda ()
(setq-local tab-width custom-tab-width)
(setq-local indent-tabs-mode 't)))
(add-hook 'nix-ts-mode-hook
(lambda ()
(setq-local nix-ts-mode-indent-offset custom-tab-width)))
(add-hook 'c-ts-mode-hook
(lambda ()
(setq-local c-ts-mode-indent-style 'linux)
(setq-local c-ts-mode-indent-offset custom-tab-width)
(c-ts-mode-toggle-comment-style -1)))
(add-hook 'rust-ts-mode-hook
(lambda ()
(setq-local rust-ts-mode-indent-offset custom-tab-width)))
;; Flymake Configuration
(use-package flymake
:ensure nil
:hook
(prog-mode . flymake-mode)
(emacs-lisp-mode . flymake-mode)
)
; Flyover for nice in buffer flymake error/warning messages.
(use-package flyover
:ensure t
:hook
(flymake-mode . flyover-mode)
:custom
;; Checker settings
(flyover-checkers '(flymake))
;; Display mode (controls cursor-based visibility)
(flyover-display-mode 'show-only-on-same-line)
;; Completion integration
(flyover-hide-during-completion t)
)
;; LSP Configuration
(use-package eglot
:hook
(((
bash-ts-mode
c-ts-mode
rust-ts-mode
swift-ts-mode
nix-ts-mode
html-ts-mode
css-ts-mode
js-ts-mode
typescript-ts-mode
tsx-ts-mode
) . eglot-ensure))
:custom
(eglot-ignored-server-capabilities '(:documentOnTypeFormattingProvider))
)
;; HTML Emmet Snippets
(use-package emmet-mode
:ensure t
:hook
(typescript-ts-mode . emmet-mode)
(tsx-ts-mode . emmet-mode)
(html-ts-mode . emmet-mode)
(css-ts-mode . emmet-mode)
:config
(setq emmet-indentation custom-tab-width)
)
;; JS Prettier Mode
(use-package prettier-js
:ensure t
:hook
(js-ts-mode . prettier-js-mode)
(typescript-ts-mode . prettier-js-mode)
(tsx-ts-mode . prettier-js-mode)
:config
(setq prettier-js-use-modules-bin t)
)
(custom-set-variables
;; custom-set-variables was added by Custom.
;; If you edit it by hand, you could mess it up, so be careful.
;; Your init file should contain only one such instance.
;; If there is more than one, they won't work right.
'(auth-source-save-behavior nil)
'(package-selected-packages nil)
'(smtpmail-smtp-server "smtp.cspark.dev")
'(smtpmail-smtp-service 25))
(custom-set-faces
;; custom-set-faces was added by Custom.
;; If you edit it by hand, you could mess it up, so be careful.
;; Your init file should contain only one such instance.
;; If there is more than one, they won't work right.
)