;;; init-dev.el --- Language tooling -*- lexical-binding: t; -*- ;;; Commentary: ;; Per-language setup. Currently Odin (tree-sitter + odin-ts-mode + eglot/OLS) ;; plus markdown-mode. Add each language as its own section. ;;; Code: ;;;; Markdown (use-package markdown-mode) ;;;; Odin (setq treesit-language-source-alist '((odin "https://github.com/tree-sitter-grammars/tree-sitter-odin"))) (use-package odin-ts-mode :vc (:url "https://github.com/Sampie159/odin-ts-mode") :mode "\\.odin\\'") ;;;; Lua (use-package lua-mode :ensure t) ;;;; TOML (use-package toml-mode :ensure t) ;;;; Eglot LSP (use-package eglot :hook (odin-ts-mode . eglot-ensure) :bind (:map eglot-mode-map ("C-c r" . eglot-rename) ("C-c a" . eglot-code-actions)) :config ;; Signature-only ElDoc: OLS hover already includes the signature, so ;; showing both would duplicate it in the echo area. (add-hook 'eglot-managed-mode-hook (lambda () (setq-local eldoc-documentation-functions '(eglot-signature-eldoc-function)))) ;; K is context-aware: on a diagnostic (red underline) it shows the error ;; text, otherwise the full hover payload — both in the same focused pane ;; (dismiss with q or K). The echo area keeps the live signature. ;; ] e / [ e jump between diagnostics, echoing each as you land. (define-derived-mode my/eglot-hover-mode special-mode "Eglot-Hover" "Major mode for the eglot hover / diagnostic pane.") (with-eval-after-load 'evil (evil-define-key '(normal motion) my/eglot-hover-mode-map (kbd "q") #'quit-window (kbd "K") #'quit-window)) (defun my/eglot-hover--display (string &rest _) "Show STRING in a focused *eglot-hover* pane, or message if empty." (if (and string (not (string-empty-p string))) (let ((buf (get-buffer-create "*eglot-hover*"))) (with-current-buffer buf (let ((inhibit-read-only t)) (erase-buffer) (insert string) (goto-char (point-min))) (my/eglot-hover-mode)) (select-window (display-buffer buf))) ; focus the pane (message "Nothing to show at point"))) (defun my/eglot-help-at-point () "Show diagnostics at point if any, else eglot hover docs — in the pane." (interactive) (let ((diags (flymake-diagnostics (point)))) (if diags (my/eglot-hover--display (mapconcat #'flymake-diagnostic-text diags "\n\n")) (eglot-hover-eldoc-function #'my/eglot-hover--display)))) (with-eval-after-load 'evil (evil-define-key 'normal 'eglot-mode-map (kbd "K") #'my/eglot-help-at-point (kbd "] e") #'flymake-goto-next-error (kbd "[ e") #'flymake-goto-prev-error)) (with-eval-after-load 'which-key (which-key-add-key-based-replacements "C-c r" "rename" "C-c a" "code actions"))) (provide 'init-dev) ;;; init-dev.el ends here