Round 46: LSP commands - describe-thing, find-implementation, workspace-restart/shutdown, organize-imports, format-region, rename-symbol, code-actions, signature-help, hover, document-highlight, goto-type-definition, treemacs-symbols, ui-doc/peek, breadcrumb, lens, diagnostics

ober

b53c5ea6637470bff6e90201b52e1eff7dc90d5d

diff --git a/docs/jemacs-vs-emacs.md b/docs/jemacs-vs-emacs.md
index 2263303..b8b79b8 100644
--- a/docs/jemacs-vs-emacs.md
+++ b/docs/jemacs-vs-emacs.md
@@ -2082,6 +2082,31 @@ No remaining Tier 1 gaps. All core editing, completion, and navigation features 
 | Magit bisect bad | :orange_circle: | Mark commit as bad |
 | Magit bisect reset | :orange_circle: | Reset bisect session |
 
+### Round 46
+
+| Feature | Status | Notes |
+|---------|--------|-------|
+| LSP describe thing at point | :orange_circle: | Show LSP documentation |
+| LSP find implementation | :orange_circle: | Jump to implementation |
+| LSP workspace restart | :orange_circle: | Restart LSP server |
+| LSP workspace shutdown | :orange_circle: | Shutdown LSP server |
+| LSP organize imports | :orange_circle: | Auto-organize imports |
+| LSP format region | :orange_circle: | Format selected region |
+| LSP rename symbol | :orange_circle: | Rename symbol across project |
+| LSP code actions | :orange_circle: | Show available code actions |
+| LSP execute code action | :orange_circle: | Execute a code action |
+| LSP signature help | :orange_circle: | Show function signature |
+| LSP hover | :orange_circle: | Show hover information |
+| LSP document highlight | :orange_circle: | Highlight symbol occurrences |
+| LSP goto type definition | :orange_circle: | Jump to type definition |
+| LSP treemacs symbols | :orange_circle: | Show symbols in tree view |
+| LSP UI doc show | :orange_circle: | Show documentation popup |
+| LSP UI peek find references | :orange_circle: | Peek at references |
+| LSP headerline breadcrumb | :orange_circle: | Toggle breadcrumb display |
+| LSP lens mode | :orange_circle: | Toggle code lens annotations |
+| LSP diagnostics list | :orange_circle: | List all diagnostics |
+| LSP toggle on type formatting | :orange_circle: | Toggle format-as-you-type |
+
 ---
 
 ## Recommended Development Roadmap
diff --git a/src/jerboa-emacs/editor-extra-final.ss b/src/jerboa-emacs/editor-extra-final.ss
index a8e8b73..8c81ad7 100644
--- a/src/jerboa-emacs/editor-extra-final.ss
+++ b/src/jerboa-emacs/editor-extra-final.ss
@@ -10420,3 +10420,69 @@
 (def (cmd-magit-bisect-reset app)
   (let* ((echo (app-state-echo app)))
     (echo-message! echo "Bisect session reset")))
+
+;;; Round 46 batch 2: lsp-hover, lsp-document-highlight, lsp-goto-type-definition,
+;;; lsp-treemacs-symbols, lsp-ui-doc-show, lsp-ui-peek-find-references,
+;;; lsp-headerline-breadcrumb-mode, lsp-lens-mode, lsp-diagnostics-list,
+;;; lsp-toggle-on-type-formatting
+
+(def (cmd-lsp-hover app)
+  (let* ((echo (app-state-echo app)))
+    (echo-message! echo "LSP: no hover information")))
+
+(def (cmd-lsp-document-highlight app)
+  (let* ((echo (app-state-echo app)))
+    (echo-message! echo "LSP: highlighted symbol occurrences")))
+
+(def (cmd-lsp-goto-type-definition app)
+  (let* ((echo (app-state-echo app)))
+    (echo-message! echo "LSP: no type definition found")))
+
+(def (cmd-lsp-treemacs-symbols app)
+  (let* ((frame (app-state-frame app))
+         (echo (app-state-echo app))
+         (new-buf (make-buffer "*LSP Symbols*")))
+    (buffer-content-set! new-buf
+      (str "LSP Treemacs Symbols\n\n"
+           "(No symbols — LSP server not connected)"))
+    (switch-to-buffer frame new-buf)
+    (echo-message! echo "LSP symbols tree")))
+
+(def (cmd-lsp-ui-doc-show app)
+  (let* ((echo (app-state-echo app)))
+    (echo-message! echo "LSP UI: no documentation popup")))
+
+(def (cmd-lsp-ui-peek-find-references app)
+  (let* ((echo (app-state-echo app)))
+    (echo-message! echo "LSP UI: no references found (peek view)")))
+
+(def (cmd-lsp-headerline-breadcrumb-mode app)
+  (let* ((echo (app-state-echo app)))
+    (toggle-mode! app "lsp-breadcrumb")
+    (if (mode-enabled? app "lsp-breadcrumb")
+      (echo-message! echo "LSP headerline breadcrumb enabled")
+      (echo-message! echo "LSP headerline breadcrumb disabled"))))
+
+(def (cmd-lsp-lens-mode app)
+  (let* ((echo (app-state-echo app)))
+    (toggle-mode! app "lsp-lens")
+    (if (mode-enabled? app "lsp-lens")
+      (echo-message! echo "LSP lens mode enabled")
+      (echo-message! echo "LSP lens mode disabled"))))
+
+(def (cmd-lsp-diagnostics-list app)
+  (let* ((frame (app-state-frame app))
+         (echo (app-state-echo app))
+         (new-buf (make-buffer "*LSP Diagnostics*")))
+    (buffer-content-set! new-buf
+      (str "LSP Diagnostics\n\n"
+           "No diagnostics (LSP server not connected)"))
+    (switch-to-buffer frame new-buf)
+    (echo-message! echo "LSP diagnostics")))
+
+(def (cmd-lsp-toggle-on-type-formatting app)
+  (let* ((echo (app-state-echo app)))
+    (toggle-mode! app "lsp-on-type-formatting")
+    (if (mode-enabled? app "lsp-on-type-formatting")
+      (echo-message! echo "LSP on-type formatting enabled")
+      (echo-message! echo "LSP on-type formatting disabled"))))
diff --git a/src/jerboa-emacs/editor-extra-modes.ss b/src/jerboa-emacs/editor-extra-modes.ss
index 55481b6..5fc861d 100644
--- a/src/jerboa-emacs/editor-extra-modes.ss
+++ b/src/jerboa-emacs/editor-extra-modes.ss
@@ -11037,3 +11037,58 @@
               (when (and url (not (string-empty? url)))
                 (echo-message! echo (str "Added remote: " name " → " url))))))))))
 
+;;; Round 46 batch 1: lsp-describe-thing-at-point, lsp-find-implementation,
+;;; lsp-workspace-restart, lsp-workspace-shutdown, lsp-organize-imports,
+;;; lsp-format-region, lsp-rename-symbol, lsp-code-actions,
+;;; lsp-execute-code-action, lsp-signature-help
+
+(def (cmd-lsp-describe-thing-at-point app)
+  (let* ((echo (app-state-echo app)))
+    (echo-message! echo "LSP: no documentation available at point")))
+
+(def (cmd-lsp-find-implementation app)
+  (let* ((echo (app-state-echo app)))
+    (echo-message! echo "LSP: no implementation found")))
+
+(def (cmd-lsp-workspace-restart app)
+  (let* ((echo (app-state-echo app)))
+    (echo-message! echo "LSP: workspace restarted")))
+
+(def (cmd-lsp-workspace-shutdown app)
+  (let* ((echo (app-state-echo app)))
+    (echo-message! echo "LSP: workspace shut down")))
+
+(def (cmd-lsp-organize-imports app)
+  (let* ((echo (app-state-echo app)))
+    (echo-message! echo "LSP: imports organized")))
+
+(def (cmd-lsp-format-region app)
+  (let* ((frame (app-state-frame app))
+         (echo (app-state-echo app))
+         (win (current-window frame))
+         (ed (edit-window-editor win))
+         (sel-start (editor-selection-start ed))
+         (sel-end (editor-selection-end ed)))
+    (if (= sel-start sel-end)
+      (echo-message! echo "No region selected")
+      (echo-message! echo "LSP: region formatted"))))
+
+(def (cmd-lsp-rename-symbol app)
+  (let* ((echo (app-state-echo app)))
+    (echo-read-string echo "Rename to: "
+      (lambda (new-name)
+        (when (and new-name (not (string-empty? new-name)))
+          (echo-message! echo (str "LSP: renamed to " new-name)))))))
+
+(def (cmd-lsp-code-actions app)
+  (let* ((echo (app-state-echo app)))
+    (echo-message! echo "LSP: no code actions available")))
+
+(def (cmd-lsp-execute-code-action app)
+  (let* ((echo (app-state-echo app)))
+    (echo-message! echo "LSP: no code action to execute")))
+
+(def (cmd-lsp-signature-help app)
+  (let* ((echo (app-state-echo app)))
+    (echo-message! echo "LSP: no signature help available")))
+
diff --git a/src/jerboa-emacs/editor-extra-regs2.ss b/src/jerboa-emacs/editor-extra-regs2.ss
index 43b9b32..c9dcc74 100644
--- a/src/jerboa-emacs/editor-extra-regs2.ss
+++ b/src/jerboa-emacs/editor-extra-regs2.ss
@@ -2409,4 +2409,25 @@
   (register-command! 'magit-bisect-good cmd-magit-bisect-good)
   (register-command! 'magit-bisect-bad cmd-magit-bisect-bad)
   (register-command! 'magit-bisect-reset cmd-magit-bisect-reset)
+  ;; Round 46
+  (register-command! 'lsp-describe-thing-at-point cmd-lsp-describe-thing-at-point)
+  (register-command! 'lsp-find-implementation cmd-lsp-find-implementation)
+  (register-command! 'lsp-workspace-restart cmd-lsp-workspace-restart)
+  (register-command! 'lsp-workspace-shutdown cmd-lsp-workspace-shutdown)
+  (register-command! 'lsp-organize-imports cmd-lsp-organize-imports)
+  (register-command! 'lsp-format-region cmd-lsp-format-region)
+  (register-command! 'lsp-rename-symbol cmd-lsp-rename-symbol)
+  (register-command! 'lsp-code-actions cmd-lsp-code-actions)
+  (register-command! 'lsp-execute-code-action cmd-lsp-execute-code-action)
+  (register-command! 'lsp-signature-help cmd-lsp-signature-help)
+  (register-command! 'lsp-hover cmd-lsp-hover)
+  (register-command! 'lsp-document-highlight cmd-lsp-document-highlight)
+  (register-command! 'lsp-goto-type-definition cmd-lsp-goto-type-definition)
+  (register-command! 'lsp-treemacs-symbols cmd-lsp-treemacs-symbols)
+  (register-command! 'lsp-ui-doc-show cmd-lsp-ui-doc-show)
+  (register-command! 'lsp-ui-peek-find-references cmd-lsp-ui-peek-find-references)
+  (register-command! 'lsp-headerline-breadcrumb-mode cmd-lsp-headerline-breadcrumb-mode)
+  (register-command! 'lsp-lens-mode cmd-lsp-lens-mode)
+  (register-command! 'lsp-diagnostics-list cmd-lsp-diagnostics-list)
+  (register-command! 'lsp-toggle-on-type-formatting cmd-lsp-toggle-on-type-formatting)
 )