Split init.el into seperate modules

This commit is contained in:
Jens Luedicke
2025-09-08 12:14:12 +02:00
parent 39d5bafe42
commit e3a5872218
25 changed files with 2306 additions and 783 deletions

140
lisp/init-eglot.el Normal file
View File

@@ -0,0 +1,140 @@
;;; init-eglot.el --- Eglot (built-in LSP) configuration -*- lexical-binding: t -*-
;;; Commentary:
;;; Lightweight LSP client using Emacs built-in Eglot (Emacs 29+)
;;; Code:
;; Eglot is built-in for Emacs 29+, otherwise install it
(unless (fboundp 'eglot)
(use-package eglot
:ensure t))
;; Configure Eglot
(with-eval-after-load 'eglot
;; Performance tuning
(setq eglot-autoshutdown t) ; Shutdown language server after closing last file
(setq eglot-sync-connect 0) ; Don't block on language server startup
(setq eglot-connect-timeout 10) ; Connection timeout in seconds
(setq eglot-events-buffer-size 0) ; Disable events buffer for performance
(setq eglot-ignored-server-capabilities '(:documentHighlightProvider)) ; Disable some features for speed
;; Don't let Eglot manage Flymake, we'll configure it separately
(setq eglot-stay-out-of '(flymake))
;; Workspace configuration for different servers
(setq-default eglot-workspace-configuration
'(:pylsp (:plugins (:pycodestyle (:enabled t)
:pyflakes (:enabled t)
:pylint (:enabled nil)))
:gopls (:usePlaceholders t)
;; Disable ESLint for TypeScript/JavaScript by default
:typescript (:validate (:enable :json-false))
:javascript (:validate (:enable :json-false))
:eslint (:enable :json-false)))
;; Configure language servers
(add-to-list 'eglot-server-programs
'((c-mode c++-mode c-ts-mode c++-ts-mode) . ("clangd"
"--background-index"
"--clang-tidy"
"--completion-style=detailed"
"--header-insertion=iwyu"
"--pch-storage=memory")))
(add-to-list 'eglot-server-programs
'((python-mode python-ts-mode) . ("pylsp")))
(add-to-list 'eglot-server-programs
'((rust-mode rust-ts-mode) . ("rust-analyzer")))
(add-to-list 'eglot-server-programs
'((go-mode go-ts-mode) . ("gopls")))
(add-to-list 'eglot-server-programs
'((typescript-mode typescript-ts-mode tsx-ts-mode) . ("typescript-language-server" "--stdio")))
(add-to-list 'eglot-server-programs
'((js-mode js-ts-mode) . ("typescript-language-server" "--stdio")))
;; QML support (if qmlls is available)
(when (executable-find "qmlls")
(add-to-list 'eglot-server-programs
'(qml-mode . ("qmlls"))))
;; Format on save
(defun eglot-format-buffer-on-save ()
"Format buffer with eglot before saving."
(add-hook 'before-save-hook #'eglot-format-buffer -10 t))
;; Keybindings
(define-key eglot-mode-map (kbd "C-c l r") 'eglot-rename)
(define-key eglot-mode-map (kbd "C-c l a") 'eglot-code-actions)
(define-key eglot-mode-map (kbd "C-c l f") 'eglot-format)
(define-key eglot-mode-map (kbd "C-c l F") 'eglot-format-buffer)
(define-key eglot-mode-map (kbd "C-c l h") 'eldoc)
(define-key eglot-mode-map (kbd "C-c l d") 'xref-find-definitions)
(define-key eglot-mode-map (kbd "C-c l R") 'xref-find-references)
(define-key eglot-mode-map (kbd "C-c l i") 'eglot-find-implementation)
(define-key eglot-mode-map (kbd "C-c l t") 'eglot-find-typeDefinition))
;; Hook eglot to programming modes
(defun maybe-enable-eglot ()
"Enable eglot if a language server is available."
(when (and (not (bound-and-true-p lsp-mode)) ; Don't conflict with lsp-mode
(eglot-current-server)) ; Only if server is available
(eglot-ensure)))
;; Enable eglot for specific modes
(dolist (mode '(c-mode-hook
c++-mode-hook
c-ts-mode-hook
c++-ts-mode-hook
python-mode-hook
python-ts-mode-hook
rust-mode-hook
rust-ts-mode-hook
go-mode-hook
go-ts-mode-hook
js-mode-hook
js-ts-mode-hook
typescript-mode-hook
typescript-ts-mode-hook
tsx-ts-mode-hook))
(add-hook mode #'eglot-ensure))
;; Integration with Corfu for completion
(with-eval-after-load 'corfu
(setq completion-category-overrides '((eglot (styles orderless))))
(add-hook 'eglot-managed-mode-hook
(lambda ()
(setq-local completion-at-point-functions
(list (cape-super-capf
#'eglot-completion-at-point
#'cape-file))))))
;; Eldoc configuration for better documentation display
(with-eval-after-load 'eldoc
(setq eldoc-echo-area-use-multiline-p nil) ; Don't use multi-line eldoc
(setq eldoc-idle-delay 0.5))
;; Diagnostic display with Flymake (built-in)
(with-eval-after-load 'flymake
(define-key flymake-mode-map (kbd "C-c ! n") 'flymake-goto-next-error)
(define-key flymake-mode-map (kbd "C-c ! p") 'flymake-goto-prev-error)
(define-key flymake-mode-map (kbd "C-c ! l") 'flymake-show-buffer-diagnostics)
(define-key flymake-mode-map (kbd "C-c ! L") 'flymake-show-project-diagnostics))
;; Helper functions
(defun eglot-organize-imports ()
"Organize imports using Eglot."
(interactive)
(eglot-code-actions nil nil "source.organizeImports" t))
(defun eglot-restart-server ()
"Restart the Eglot server."
(interactive)
(call-interactively #'eglot-shutdown)
(call-interactively #'eglot))
(provide 'init-eglot)
;;; init-eglot.el ends here