;;; 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 (with-eval-after-load 'general (rh/leader-keys "g" '(:ignore t :which-key "lsp/go-to") "gd" '(xref-find-definitions :which-key "go to definition") "gr" '(xref-find-references :which-key "find references") "gi" '(eglot-find-implementation :which-key "go to implementation") "gt" '(eglot-find-typeDefinition :which-key "go to type definition") "gh" '(eldoc-doc-buffer :which-key "show documentation") "gs" '(eldoc :which-key "signature help") "ga" '(eglot-code-actions :which-key "code actions") "gn" '(eglot-rename :which-key "rename symbol") "ge" '(flymake-show-buffer-diagnostics :which-key "show diagnostics") "gf" '(eglot-format-buffer :which-key "format buffer") "d" '(:ignore t :which-key "debug") "dd" '(dap-debug :which-key "start debugging") "db" '(dap-breakpoint-toggle :which-key "toggle breakpoint") "dc" '(dap-continue :which-key "continue") "dn" '(dap-next :which-key "step over") "di" '(dap-step-in :which-key "step into") "do" '(dap-step-out :which-key "step out") "dr" '(dap-restart-frame :which-key "restart") "dq" '(dap-disconnect :which-key "quit/disconnect") "de" '(dap-eval :which-key "eval expression") "dl" '(dap-ui-locals :which-key "show locals") "ds" '(dap-ui-sessions :which-key "show 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