-
-
Notifications
You must be signed in to change notification settings - Fork 234
feat: add LSP Call Hierarchy support to Living Canvas #2043
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
cxxxr
wants to merge
9
commits into
main
Choose a base branch
from
feature/living-canvas-lsp-call-hierarchy
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Conversation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
f10f9bc to
54f7a71
Compare
Introduce bidirectional conversion between call-graph structures and JSON format for testing, debugging, and data exchange with external tools. Key additions: - graph-node-to-alist, graph-edge-to-alist: Structure to alist conversion - call-graph-to-json: Full graph to JSON string serialization - json-to-call-graph: JSON parsing back to call-graph structures - Comprehensive test suite with roundtrip verification
Integrate LSP Call Hierarchy protocol with Living Canvas for language-agnostic call graph visualization. Key additions: - LSP request wrappers: prepare-call-hierarchy, get-incoming-calls, get-outgoing-calls - Capability checking: buffer-has-call-hierarchy-p - Conversion functions: call-hierarchy-item-to-node-alist, incoming/outgoing-call-to-edge-alist - Document symbol utilities for position conversion and flattening
Implement call-graph-provider using LSP Call Hierarchy API for language-agnostic call graph analysis. Key additions: - lsp-call-hierarchy-provider class with priority 20 (higher than micros) - collect-file-call-hierarchy: analyze all callables in a buffer - Automatic node/edge deduplication for complete file coverage - Export document symbol utilities from lsp-call-hierarchy
Move LSP Call Hierarchy conversion logic to Lem-independent package for better modularity and testability. Key changes: - New call-graph-lsp package with pure conversion functions - build-call-graph-from-hierarchy with callback abstraction for LSP requests - Progress reporting support via progress-fn parameter - Update living-canvas to use call-graph-lsp - Comprehensive unit tests with mock callbacks
Replaced lem-lsp-base/protocol-3-17: with lsp: local nickname for better readability and consistency. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add lem:redraw-display calls during LSP request processing to keep the UI responsive. Show progress during both symbol preparation and call hierarchy analysis phases. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add *max-symbols-to-analyze* (default 30) to prevent LSP overload - Abort processing after 3 consecutive errors (likely connection lost) - Show partial results when connection is lost during analysis - Display informative message when symbol limit is applied 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add background thread processing via bt2:make-thread to avoid UI freeze - Add request throttling (100ms delay) to prevent LSP server overload - Add exponential backoff retry for transient LSP errors - Add cancellation support via living-canvas-lsp-cancel command - Remove symbol limit (*max-symbols-to-analyze* now defaults to nil) - Update progress display via send-event for non-blocking UI updates This allows analyzing large files (200+ symbols) without freezing the editor or crashing the LSP server. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
LSP requests are not thread-safe (they use a shared socket connection). Changed from bt2:make-thread to idle-timer based processing: - Process symbols in batches of 5 (configurable via *lsp-batch-size*) - Yield between batches to keep UI responsive - All LSP requests now run on the main thread - Added lsp-async-state struct to track incremental progress This fixes the "Couldn't write to FD-STREAM" socket error that occurred when making LSP requests from a background thread. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
e23cdbf to
1d2544d
Compare
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Summary
Add multi-language call graph visualization to Living Canvas using the LSP Call Hierarchy API.
call-graph-lsppackage - Lem-independent LSP to call-graph conversionlsp-provider.lisp- Async analysis with idle timers (UI-responsive)lsp-call-hierarchy.lisp- LSP request wrappersjson-format.lisp- JSON serialization for call-graphArchitecture
Motivation
call-graph-lsphas no Lem dependencies (only LSP protocol definitions)Changes
extensions/call-graph-lsp/extensions/call-graph/json-format.lispextensions/living-canvas/lsp-call-hierarchy.lispextensions/living-canvas/lsp-provider.lispextensions/living-canvas/living-canvas.lispliving-canvas-lsp, etc.Test Plan
call-graph/tests,call-graph-lsp/tests,lem-living-canvas/tests)M-x living-canvas-lspworks with Go files (gopls)M-x living-canvas-lsp-fullshows incoming + outgoing callsM-x living-canvas-lsp-cancelaborts running analysisAI Usage Disclosure
Did you use LLMs/AI tools for this PR?
Tooling Used: Claude Code (Claude Opus 4.5)
The "Human-in-the-Loop" Verification
1. Logic Walkthrough
The LSP Call Hierarchy integration follows a three-layer architecture:
call-graph-lsp layer: Pure conversion functions from LSP protocol objects to call-graph structures. No Lem dependencies, only uses
lem-lsp-base/protocol-3-17for type definitions.lsp-call-hierarchy layer: Lem-specific LSP request wrappers. Handles buffer→workspace lookup, capability checking, and LSP method invocation.
lsp-provider layer: Orchestrates async analysis using idle timers. Key design decisions:
*lsp-batch-size*= 5)2. Reviewer's Guide
High-risk areas:
lsp-provider.lisp:261-266: Error handling in async batch processinglsp-provider.lisp:110-123: Retry with backoff logiclem-lsp-mode/lsp-mode::buffer-workspace)Suggested focus:
lsp-async-cleanup)