Lsp #58
No reviewers
Labels
No labels
bug
documentation
duplicate
enhancement
good first issue
help wanted
invalid
question
seq-lisp-2-backport
wontfix
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
navicore/seq-lisp!58
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "lsp"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
PR Review: LSP Document Symbols Implementation
Overview
This PR adds document symbols support to the SeqLisp LSP server, enabling outline/navigation features (e.g., Ctrl+Shift+O in VSCode). The implementation finds all
defineanddefmacrostatements and reports their locations to the editor.✅ Strengths
Good test coverage: Both new features (diagnostics documentation and document symbols) have dedicated test files that verify correct LSP protocol responses.
Follows LSP specification: The
textDocument/documentSymbolresponse correctly returnsSymbolInformationobjects with proper structure (name, kind, location, range).Code reuse: Cleverly extends existing
find-definitionslogic to track positions, avoiding duplication.Documentation: Updated comments and roadmap appropriately to reflect new capabilities.
Consistent style: The implementation follows the existing SeqLisp coding patterns (e.g., recursive helper functions with
-loopsuffix).🔍 Issues & Recommendations
1. Correctness: Range calculation bug
Location:
lib/lsp.slisp:450The range calculation for document symbols is incorrect:
This uses the start of the
(definekeyword as the symbol location, butcolpoints to the opening paren, not the symbol name. The range should span only the symbol name itself, not from the(character.Impact: In editors, the highlighted range will be off by several characters, making navigation confusing.
Suggested fix: Calculate the actual position where the symbol name starts (after
(defineor(defmacro), or pass this information fromextract-defined-symbol.2. Code organization: Function ordering inconsistency
Location:
lib/lsp.slisp:342-374In the "Completion Support" section, helper functions are reordered so that
string-index-of-loopappears beforestring-index-of, andextract-symbol-loopbeforeextract-symbol. While this follows a "declare before use" pattern, it's inconsistent with other sections of the file where wrapper functions come first.Example of existing pattern (lines 64-65):
Recommendation: Consider keeping the existing pattern (wrapper first, then loop implementation) for consistency, unless there's a technical requirement for forward declaration in SeqLisp.
3. Maintainability: Repeated boolean chaining pattern
Location:
lib/lsp.slisp:359, 369The code uses deeply nested
ifexpressions to check multiple whitespace characters:Issues:
Suggested refactoring: Define a helper predicate:
Then use:
Alternatively, once SeqLisp supports
or, this could be:4. Performance: Redundant position calculations
Location:
lib/lsp.slisp:432-434The
offset-to-positionfunction is called for every found definition, scanning from the beginning of the document each time. For a file with many definitions, this creates O(n²) complexity.Example: In a 1000-line file with 50 definitions, this scans ~25,000 lines unnecessarily.
Suggested optimization: Thread the current position through the loop, similar to how other functions maintain position state:
This would make the algorithm O(n), scanning the document only once.
5. Testing: Missing edge cases
Location:
tests/lsp/test_documentsymbols.txtThe test only covers the happy path with two simple definitions. Consider adding tests for:
(define x 1) (define y 2)(define (outer) (define inner 42))- should inner be reported?(define (bar x) x)- currently tested but could verify position accuracydefine, should also testdefmacro6. Semantic correctness: Symbol kind classification
Location:
lib/lsp.slisp:445All symbols are marked with kind
12(Function), even when they're variables:Issue:
(define x 42)creates a variable, not a function, but it's marked as a function in the outline.LSP SymbolKind values:
Recommendation: Detect whether the definition is a function or variable:
7. Documentation: Missing limitation note
Location:
lib/lsp.slisp:17-19The limitations section should mention that document symbols:
definekeyword, not the symbol name (if not fixed per #1)🎯 Priority Summary
✅ Approval
Despite the issues noted above, this PR:
Recommendation: ✅ Approve with suggestions - The issues are mostly minor improvements and can be addressed in follow-up PRs if desired. The range calculation bug (#1) is the most user-facing issue and would be good to fix before merging.
Great work on extending the LSP server! The document symbols feature will significantly improve the editor experience for SeqLisp users. 🎉
Code Review: LSP Document Symbols Implementation
Summary
This PR adds document symbol support to the SeqLisp LSP server, enabling outline/navigation features (Ctrl+Shift+O in VSCode). The implementation finds all
defineanddefmacrodeclarations and reports their positions with proper LSP SymbolKind classifications.✅ Strengths
string-index-of,skip-whitespace, etc.) and extends them thoughtfully🔍 Code Quality Observations
Good Practices
extract-defined-symbol-infofunction cleanly extendsextract-defined-symbolby adding position and kind trackingfind-definitions-with-pos,offset-to-position)whitespace?anddelimiter?improves code readability vs. the previous inline boolean checksMinor Refactoring
The code moves
string-index-ofdefinition (lines 342-352) from its previous location (lines 340-348). This appears to be a reorganization to place the loop helper before the main function, which is a reasonable style choice for readability.🐛 Potential Issues
1. Character Encoding Assumption (Minor)
The
offset-to-positionfunction in lib/lsp.slisp:441-451 assumes byte offsets equal character offsets. This works for ASCII but may produce incorrect positions with multi-byte UTF-8 characters.Impact: For SeqLisp files with ASCII-only identifiers, this is fine. If users include Unicode symbols or comments, positions may be off.
Recommendation: Document this limitation or consider whether SeqLisp supports Unicode identifiers.
2. Return Type Inconsistency (Minor)
The
extract-symbolfunction changed its return type from(symbol . end-pos)(cons pair) to(symbol end-pos)(list). The comment was updated correctly on line 376, but verify all callers handle this change.Looking at the code, both
extract-defined-symbol(line 397) andextract-defined-symbol-info(line 411, 414) usecarto extract the symbol name, which works correctly for lists. This change appears intentional and safe.3. Test Assertions Could Be More Specific (Minor)
The new test in justfile:193-209 uses
grepto check for both symbol names:While functional, this doesn't verify:
bar, 13 for variablefoo)Recommendation: Consider adding more specific assertions for symbol kinds and positions in future improvements.
🔒 Security Considerations
No security concerns identified. The implementation:
⚡ Performance Considerations
Linear search pattern:
find-definitions-pos-loop(line 455) searches the entire document linearly for each pattern. For large files with many definitions, this could be slow.However, this is acceptable because:
find-definitionspatternOffset conversion:
offset-to-positionscans from the beginning of the document each time. With the current code structure, this is called once per definition found.Current complexity: O(n × m) where n = document size, m = number of definitions
This is reasonable for typical use cases.
📝 Test Coverage
Excellent test coverage:
test_diagnostics.txt): Verifies diagnostics include error details with severitytest_documentsymbols.txt): Verifies document symbols returns both variable and function definitionsThe test file content shows proper LSP message formatting and lifecycle (initialize → initialized → request → shutdown → exit).
📋 Recommendations
offset-to-positionnoting the ASCII assumptionfind-defined-symbols-with-posinfrastructure could enable user-defined symbol completion in a future PRdefmacrodefinitions✨ Conclusion
This is a well-implemented, focused PR that adds valuable LSP functionality. The code quality is good, follows existing patterns, and includes appropriate test coverage. The few minor issues noted are not blockers and could be addressed in future refinements if needed.
Recommendation: Approve and merge ✅
Great work on implementing this feature! The document symbols support will significantly improve the developer experience when working with SeqLisp files in modern editors.