;;; dev-settings.el --- Development environment configuration ;; Disable warnings for config files (setq byte-compile-warnings '(not free-vars unresolved noruntime lexical make-local)) ;;; Package Management (require 'use-package) (setq use-package-always-ensure t) ;;; Core Development Packages ;; Company - autocomplete (use-package company :defer 1 :config (global-company-mode) (setq company-idle-delay 0.2 company-minimum-prefix-length 2 company-show-numbers t company-tooltip-align-annotations t)) ;; Eglot - Built-in LSP client (Emacs 29+) (use-package eglot :ensure nil ; Built-in to Emacs 29+ :defer t :commands (eglot eglot-ensure) :config ;; Disable intrusive features (setq eglot-autoshutdown t eglot-send-changes-idle-time 0.5) ;; Disable eldoc signature help and documentation on hover (setq eldoc-echo-area-use-multiline-p nil) (add-to-list 'eglot-stay-out-of 'eldoc)) ;; DAP Mode - Debug Adapter Protocol (use-package dap-mode :defer t :commands (dap-mode dap-debug) :config (require 'dap-gdb-lldb) ; C/C++ (require 'dap-cpptools)) ;;; Tree-sitter Configuration (Emacs 29+) ;; Tree-sitter is built-in to Emacs 29+ ;; Language grammars need to be installed separately ;; Automatically install tree-sitter grammars (use-package treesit-auto :custom (treesit-auto-install t) ; Auto-install without prompting :config (treesit-auto-add-to-auto-mode-alist 'all) (global-treesit-auto-mode)) ;;; C/C++ Configuration (use-package c-ts-mode :ensure nil ; Built-in :mode (("\\.c\\'" . c-ts-mode) ("\\.h\\'" . c-ts-mode) ("\\.cpp\\'" . c++-ts-mode) ("\\.hpp\\'" . c++-ts-mode) ("\\.cc\\'" . c++-ts-mode) ("\\.cxx\\'" . c++-ts-mode)) :hook ((c-ts-mode . eglot-ensure) (c++-ts-mode . eglot-ensure)) :config (setq c-ts-mode-indent-offset 4)) ;; Install clangd for C/C++ LSP support ;; Arch: sudo pacman -S clang ;; Windows: Download from LLVM releases ;;; Go Configuration (use-package go-ts-mode :ensure nil ; Built-in to Emacs 29+ :mode "\\.go\\'" :hook (go-ts-mode . eglot-ensure) :config (setq go-ts-mode-indent-offset 4)) ;; Install gopls for Go LSP support ;; Arch: sudo pacman -S go gopls ;; Debug adapter: go install github.com/go-delve/delve/cmd/dlv@latest (with-eval-after-load 'dap-mode (require 'dap-dlv-go)) ;;; Rust Configuration (use-package rust-ts-mode :ensure nil ; Built-in to Emacs 29+ :mode "\\.rs\\'" :hook (rust-ts-mode . eglot-ensure) :config (setq rust-ts-mode-indent-offset 4)) ;; Install rust-analyzer for Rust LSP support ;; Arch: sudo pacman -S rust rust-analyzer (with-eval-after-load 'eglot (add-to-list 'eglot-server-programs '(rust-ts-mode . ("rust-analyzer")))) (with-eval-after-load 'dap-mode (require 'dap-gdb-lldb)) ;; Note: Rust debugging uses the same gdb-lldb adapter as C/C++ ;; configured in the DAP Mode section above ;;; Common Lisp Configuration (use-package slime :defer t :commands slime :config (setq inferior-lisp-program "sbcl") (setq slime-contribs '(slime-fancy slime-company)) (setq slime-lisp-implementations '((sbcl ("sbcl") :coding-system utf-8-unix) (ccl ("ccl") :coding-system utf-8-unix)))) (use-package slime-company :defer t :after (slime company) :config (setq slime-company-completion 'fuzzy)) ;;; Emacs Lisp Configuration (use-package elisp-mode :ensure nil :hook ((emacs-lisp-mode . eldoc-mode) (emacs-lisp-mode . company-mode))) ;; Better elisp docs (use-package helpful :defer t :commands (helpful-callable helpful-variable helpful-key)) ;;; Additional Useful Packages (use-package smartparens :defer 1 :hook (prog-mode . smartparens-mode) :config (require 'smartparens-config)) ;; Snippets (use-package yasnippet :defer 2 :config (yas-global-mode 1)) (use-package yasnippet-snippets :defer t :after yasnippet) ;;; LSP Keybindings ;; Standard Emacs bindings for LSP/Eglot features (with-eval-after-load 'eglot (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) (define-key eglot-mode-map (kbd "C-c l h") 'eldoc-doc-buffer) (define-key eglot-mode-map (kbd "C-c l s") 'eldoc) (define-key eglot-mode-map (kbd "C-c l a") 'eglot-code-actions) (define-key eglot-mode-map (kbd "C-c l n") 'eglot-rename) (define-key eglot-mode-map (kbd "C-c l e") 'flymake-show-buffer-diagnostics) (define-key eglot-mode-map (kbd "C-c l f") 'eglot-format-buffer)) ;; Standard Emacs bindings for DAP debugging (with-eval-after-load 'dap-mode (define-key dap-mode-map (kbd "C-c d d") 'dap-debug) (define-key dap-mode-map (kbd "C-c d b") 'dap-breakpoint-toggle) (define-key dap-mode-map (kbd "C-c d c") 'dap-continue) (define-key dap-mode-map (kbd "C-c d n") 'dap-next) (define-key dap-mode-map (kbd "C-c d i") 'dap-step-in) (define-key dap-mode-map (kbd "C-c d o") 'dap-step-out) (define-key dap-mode-map (kbd "C-c d r") 'dap-restart-frame) (define-key dap-mode-map (kbd "C-c d q") 'dap-disconnect) (define-key dap-mode-map (kbd "C-c d e") 'dap-eval) (define-key dap-mode-map (kbd "C-c d l") 'dap-ui-locals) (define-key dap-mode-map (kbd "C-c d s") 'dap-ui-sessions)) ;;; Conditional loading of work-specific settings (Windows only) (when (eq system-type 'windows-nt) (let ((work-settings (expand-file-name "dev-settings-work.el" user-emacs-directory))) (when (file-exists-p work-settings) (load work-settings)))) (provide 'dev-settings) ;;; dev-settings.el ends here