-
Notifications
You must be signed in to change notification settings - Fork 4
feat: SQL template generation from schema panel #8
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
Conversation
Adds new [sql] configuration section to control identifier formatting and default limits for generated SQL templates. Supports minimal (quote only when needed) and qualified_quoted (always schema-qualify and quote) identifier styles.
Pressing Enter on a table in the schema panel now starts a key sequence for generating SQL templates: - Enter+s: SELECT with configurable LIMIT - Enter+i: INSERT with all columns - Enter+u: UPDATE with first column - Enter+d: DELETE with TODO condition - Enter+n: Insert table name only Templates use configurable identifier formatting (minimal or qualified_quoted) and respect schema qualification rules.
|
Warning Rate limit exceeded@fcoury has exceeded the limit for the number of commits or files that can be reviewed per hour. Please wait 2 minutes and 3 seconds before requesting another review. ⌛ How to resolve this issue?After the wait time has elapsed, a review can be triggered using the We recommend that you space out your commits to avoid hitting the rate limit. 🚦 How do rate limits work?CodeRabbit enforces hourly rate limits for each developer per organization. Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout. Please see our FAQ for further information. 📒 Files selected for processing (1)
WalkthroughAdds schema-aware multi-key command context, percent-encoded sidebar IDs, SQL identifier/style configuration and template builders, a context-propagating key-sequence handler with new SchemaTable actions, UI help/hint updates, AGENTS.md docs, and workspace dependency on percent-encoding. Changes
Sequence Diagram(s)sequenceDiagram
actor User
participant Sidebar
participant App
participant KeySeq as KeySequenceHandlerWithContext
participant Config
participant Editor
User->>Sidebar: select node + Enter
Sidebar->>App: notify Enter with encoded node id
App->>App: parse_schema_tree_identifier(id) -> SchemaTableContext
App->>KeySeq: start_with_context(PendingKey::SchemaTable, SchemaTableContext)
note right of KeySeq: awaiting second key
User->>App: press second key (e.g. 's')
App->>KeySeq: process_second_key('s')
KeySeq-->>App: Completed(KeySequenceCompletion{ action: SchemaTableSelect, context: Some(context) })
App->>Config: read sql.identifier_style & default_select_limit
App->>App: build_select_template(context, config)
App->>Editor: insert_into_editor_and_focus(SQL template)
Editor->>User: display inserted SQL
Estimated code review effort🎯 4 (Complex) | ⏱️ ~45 minutes
Possibly related PRs
Poem
Pre-merge checks and finishing touches✅ Passed checks (3 passed)
Comment |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 2
🧹 Nitpick comments (1)
crates/tsql/src/ui/key_sequence.rs (1)
248-382: Consider adding tests forSchemaTablesequences and context propagation.The existing tests are correctly updated for the new
KeySequenceCompletiontype, but there's no coverage for:
SchemaTablekey sequences (s/i/u/d/n mappings)start_with_contextand context propagation through completionExample test for context propagation:
#[test] fn test_schema_table_sequence_with_context() { let mut handler: KeySequenceHandlerWithContext<String> = KeySequenceHandlerWithContext::new(500); handler.start_with_context(PendingKey::SchemaTable, "my_table".to_string()); assert!(handler.is_waiting()); let result = handler.process_second_key('s'); assert_eq!( result, KeySequenceResult::Completed(KeySequenceCompletion { action: KeySequenceAction::SchemaTableSelect, context: Some("my_table".to_string()) }) ); }
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
Disabled knowledge base sources:
- Linear integration is disabled by default for public repositories
You can enable these sources in your CodeRabbit configuration.
📒 Files selected for processing (9)
AGENTS.md(1 hunks)config.example.toml(1 hunks)crates/tsql/src/app/app.rs(7 hunks)crates/tsql/src/config/mod.rs(1 hunks)crates/tsql/src/config/schema.rs(2 hunks)crates/tsql/src/ui/help_popup.rs(2 hunks)crates/tsql/src/ui/key_hint_popup.rs(3 hunks)crates/tsql/src/ui/key_sequence.rs(12 hunks)crates/tsql/src/ui/mod.rs(1 hunks)
🧰 Additional context used
📓 Path-based instructions (1)
**/*.rs
📄 CodeRabbit inference engine (CLAUDE.md)
**/*.rs: Runcargo fmt --allto format the code before committing changes
Runcargo clippy --all --all-targets -- -D warningsto check for lints and fix them before pushing changes
Files:
crates/tsql/src/ui/key_hint_popup.rscrates/tsql/src/ui/mod.rscrates/tsql/src/ui/help_popup.rscrates/tsql/src/config/mod.rscrates/tsql/src/config/schema.rscrates/tsql/src/app/app.rscrates/tsql/src/ui/key_sequence.rs
🧠 Learnings (2)
📚 Learning: 2025-12-14T00:13:37.858Z
Learnt from: CR
Repo: fcoury/tsql PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-14T00:13:37.858Z
Learning: Applies to **/*.rs : Run `cargo fmt --all` to format the code before committing changes
Applied to files:
AGENTS.md
📚 Learning: 2025-12-14T00:13:37.858Z
Learnt from: CR
Repo: fcoury/tsql PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-14T00:13:37.858Z
Learning: Applies to **/*.rs : Run `cargo clippy --all --all-targets -- -D warnings` to check for lints and fix them before pushing changes
Applied to files:
AGENTS.md
🧬 Code graph analysis (1)
crates/tsql/src/app/app.rs (3)
crates/tsql/src/ui/key_sequence.rs (1)
new(98-106)crates/tsql/src/ui/grid.rs (5)
new(733-744)s(1161-1161)s(1161-1161)s(1652-1655)quote_identifier(1141-1151)crates/tsql/src/vim/handler.rs (1)
key(412-414)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
- GitHub Check: Test (windows-latest)
🔇 Additional comments (16)
AGENTS.md (1)
1-47: Nice addition; guidance is clear and actionable.
Covers structure, common commands, and expectations (fmt/clippy/tests) succinctly.crates/tsql/src/ui/key_hint_popup.rs (2)
41-68: Schema-table hint wiring looks correct (and well-tested).
The newSCHEMA_TABLE_HINTSandPendingKey::SchemaTablematch arm are straightforward and consistent with the feature.
183-205: Good test coverage for the new PendingKey branch.
Covers both content and the title char path.crates/tsql/src/ui/help_popup.rs (1)
95-110: Help section addition is sensible; keep bindings/hints in sync.
The new “Sidebar - Schema” entries match the new Enter+{s/i/u/d/n} flow; just ensure these strings stay aligned with the key-hint popup and actual actions over time.Also applies to: 236-250
config.example.toml (1)
33-42: Config example for SQL generation is clear and matches the new knobs.
identifier_style = "minimal"/"qualified_quoted"anddefault_select_limitare easy to understand.crates/tsql/src/ui/mod.rs (1)
36-39: Re-exports look appropriate for the new context-aware key-sequence flow.crates/tsql/src/config/mod.rs (1)
18-21: Config re-exports are fine and improve discoverability.crates/tsql/src/config/schema.rs (1)
9-20: Config schema changes look solid (defaults + serde shape).
#[serde(default)]+SqlConfig::default()should keep older configs working while enabling the new[sql]section.Also applies to: 166-193
crates/tsql/src/app/app.rs (2)
4111-4179: Template generation + insertion flow looks clean and cohesive.
Helpers (format_table_ref,format_column,build_*_template,insert_into_editor_and_focus) keep the key-sequence completion handler readable.Also applies to: 4181-4245
1689-1716: The suggested fix is redundant—process_second_key()already clears pending state onKeySequenceResult::Cancelled.Verification of
crates/tsql/src/ui/key_sequence.rsshows thatprocess_second_key()callsself.cancel()internally when no matching second key is found (line 227), which clears all pending state viaclear_state(). The sequence will not remain stuck in a "waiting" state;is_waiting()will correctly returnfalseafter the invalid second key is processed. Adding another explicitcancel()call in theCancelledmatch arm is unnecessary.crates/tsql/src/ui/key_sequence.rs (6)
9-26: LGTM!The
PendingKey::SchemaTablevariant and its display character mapping to '⏎' are well-implemented. Using the Enter symbol provides clear visual feedback for users.
28-46: LGTM!The generic design with
KeySequenceResult<C = ()>andKeySequenceCompletion<C = ()>is well-structured. The default type parameter ensures backward compatibility while enabling context-aware sequences.
48-70: LGTM!The new
SchemaTable*action variants are well-named and consistent with existing conventions. The separator comment improves code organization.
72-94: LGTM!The generic
KeySequenceHandlerWithContext<C>struct with the backwards-compatible type alias is a clean design. LimitingDefaultto the()specialization is appropriate since context-aware handlers require explicit initialization.
96-173: LGTM!The context lifecycle is correctly managed:
start_with_contextsets context,startclears it, andclear_stateensures cleanup on cancel/complete. This prevents stale context from persisting across sequences.
175-230: LGTM!The processing logic is well-structured. Using
.take()onpending_contextbefore callingcomplete()correctly extracts context while ensuring it's cleared. Theprocess_first_keyhandling only 'g' is intentional sinceSchemaTablesequences are initiated externally viastart_with_context.
- Fix AGENTS.md clippy command to match CLAUDE.md guidelines - Remove "public" schema special-casing in format_table_ref for consistent identifier formatting regardless of schema name - Add comprehensive tests for SchemaTable key sequences and context propagation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 2
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
crates/tsql/src/ui/key_sequence.rs (1)
8-26:PendingKey::SchemaTablehint glyph may be double-width in some terminals
display_char()returning'⏎'can render as wide/ambiguous width depending on font/terminal, potentially misaligning the hint popup. If the popup layout assumes 1-column chars, consider a simple ASCII fallback (e.g.,'↵'or'E') or render the label as a string instead of a single char.
🧹 Nitpick comments (1)
crates/tsql/src/app/app.rs (1)
2003-2037: Enter-on-table starts SchemaTable sequence, but invalid second key “falls through” silently
On invalid follow-up keys, the sequence cancels and the key then gets handled normally; in the schema sidebar that likely becomes a no-op with no feedback. Consider setting a status message onCancelledto help discoverability.- let result = self.key_sequence.process_second_key(c); + let result = self.key_sequence.process_second_key(c); match result { KeySequenceResult::Completed(completed) => { self.execute_key_sequence_completion(completed); return false; } KeySequenceResult::Cancelled => { - // Invalid second key - let it fall through to normal handling. + self.last_status = Some("Invalid key sequence".to_string()); + // Let it fall through to normal handling. } _ => {} }
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
Disabled knowledge base sources:
- Linear integration is disabled by default for public repositories
You can enable these sources in your CodeRabbit configuration.
📒 Files selected for processing (3)
AGENTS.md(1 hunks)crates/tsql/src/app/app.rs(7 hunks)crates/tsql/src/ui/key_sequence.rs(13 hunks)
✅ Files skipped from review due to trivial changes (1)
- AGENTS.md
🧰 Additional context used
📓 Path-based instructions (1)
**/*.rs
📄 CodeRabbit inference engine (CLAUDE.md)
**/*.rs: Runcargo fmt --allto format the code before committing changes
Runcargo clippy --all --all-targets -- -D warningsto check for lints and fix them before pushing changes
Files:
crates/tsql/src/ui/key_sequence.rscrates/tsql/src/app/app.rs
🧬 Code graph analysis (1)
crates/tsql/src/app/app.rs (3)
crates/tsql/src/ui/key_sequence.rs (1)
new(98-106)crates/tsql/src/ui/key_hint_popup.rs (2)
new(27-29)new(58-60)crates/tsql/src/ui/grid.rs (5)
new(733-744)s(1161-1161)s(1161-1161)s(1652-1655)quote_identifier(1141-1151)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
- GitHub Check: Test (windows-latest)
🔇 Additional comments (10)
crates/tsql/src/app/app.rs (5)
601-627: Key-sequence handler integration looks clean
Swapping toKeySequenceHandlerWithContext<SchemaTableContext>and initializing vianew(timeout)is straightforward and keeps the field private.Also applies to: 734-755
1689-1733: Good: sequence-state isolation prevents operator-pending leakage
Clearingself.pending_keybefore processing the second key avoids cross-feature interference (vim-ish operator pending vs key sequences).
4176-4240: SchemaTable actions execution path is cohesive
Centralizing completion handling inexecute_key_sequence_completion()keeps key-sequence expansion localized and avoids scattering SQL generation across input handlers.
4074-4087: “Minimal” style now avoids surprising schema omission
Always schema-qualifying informat_table_ref()removes the “public special-casing” footgun from earlier iterations.
1-40: Ensurecargo fmtandcargo clippy -D warningsare run before pushingPer repo guidelines for
**/*.rsfiles.crates/tsql/src/ui/key_sequence.rs (5)
28-70: Generic completion payload is a solid extension
KeySequenceResult<C>+KeySequenceCompletion<C>keeps existing no-context usage ergonomic while enabling contextual sequences cleanly.
72-175: Context lifecycle is handled correctly (cleared on start/cancel/complete)
start()wipingpending_context, andclear_state()wiping it on cancel/complete prevents context bleed across sequences.
175-231: SchemaTable action mapping matches the documented keys
s/i/u/d/n→SchemaTable{Select,Insert,Update,Delete,Name}is clear and thepending_context.take()behavior ensures one-shot consumption.
248-516: Tests cover context propagation + clearing semantics well
The added SchemaTable tests and the “context cleared after completion/cancel” checks are the right regression net for this feature.
1-246: Runcargo fmt --allandcargo clippy --all --all-targets -- -D warningslocally before pushingPer repository guidelines for
**/*.rsfiles, ensure formatting and linting checks pass on your development machine before committing changes.
- Use ASCII 'E' instead of '⏎' for SchemaTable display_char to avoid ambiguous-width rendering issues in various terminals - Add status message "Invalid key sequence" when a key sequence is cancelled to improve discoverability - Implement percent-encoding for schema tree identifiers to handle colons in schema/table/column names safely - Fix Enter+n to insert table name only (without schema qualification) as documented in the PR description
Reverting the ASCII fallback as the unicode character is preferred.
Both gt and gs now navigate to the schema panel for intuitive access.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 0
🧹 Nitpick comments (4)
crates/tsql/src/ui/key_sequence.rs (4)
10-25: Unicode '⏎' hint glyph may render inconsistently in terminals
If this gets shown in a terminal UI, consider a safer ASCII fallback (e.g.,'↵'/'⏎'behind a feature flag, or just"Enter"in the UI layer) to avoid tofu/width issues.
30-46: Public API hardening: consider#[non_exhaustive]for extensible enums/structs
PendingKey,KeySequenceAction,KeySequenceResult, andKeySequenceCompletionare now more broadly used; marking them#[non_exhaustive]can reduce future breaking changes when adding variants/fields.#[derive(Debug, Clone, Copy, PartialEq, Eq)] +#[non_exhaustive] pub enum PendingKey { #[derive(Debug, Clone, PartialEq, Eq)] +#[non_exhaustive] pub enum KeySequenceResult<C = ()> { #[derive(Debug, Clone, PartialEq, Eq)] +#[non_exhaustive] pub struct KeySequenceCompletion<C = ()> { #[derive(Debug, Clone, Copy, PartialEq, Eq)] +#[non_exhaustive] pub enum KeySequenceAction {Also applies to: 49-70
72-155:start_with_contextshould probably clear any existing pending sequence (match cancel+restart semantics)
Right now it overwrites fields directly; callingclear_state()first makes behavior consistent withprocess_first_key’s “cancel existing then start” approach.pub fn start_with_context(&mut self, key: PendingKey, context: C) { + self.clear_state(); self.pending = Some(key); self.pending_since = Some(Instant::now()); self.hint_shown = false; self.pending_context = Some(context); }Also applies to: 168-173
178-230: Nice propagation logic for context; add a guard test for cancel+restart viaprocess_first_key
Thepending_context.take()beforecomplete()is the right ordering. Only missing piece is a test thatprocess_first_keycancels an in-flight context-bearing SchemaTable sequence (so we don’t regress the “cancel+restart clears context” guarantee).#[test] fn test_context_cleared_after_cancel() { ... } +#[test] +fn test_process_first_key_cancels_schema_table_context() { + let mut handler: KeySequenceHandlerWithContext<String> = KeySequenceHandlerWithContext::new(500); + handler.start_with_context(PendingKey::SchemaTable, "table1".to_string()); + + // Starting a new sequence via process_first_key should cancel prior pending state (and its context) + let result = handler.process_first_key('g'); + assert_eq!(result, KeySequenceResult::Started(PendingKey::G)); + + let result = handler.process_second_key('g'); + assert_eq!( + result, + KeySequenceResult::Completed(KeySequenceCompletion { + action: KeySequenceAction::GotoFirst, + context: None + }) + ); +}
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
Disabled knowledge base sources:
- Linear integration is disabled by default for public repositories
You can enable these sources in your CodeRabbit configuration.
📒 Files selected for processing (3)
crates/tsql/src/ui/help_popup.rs(2 hunks)crates/tsql/src/ui/key_hint_popup.rs(3 hunks)crates/tsql/src/ui/key_sequence.rs(13 hunks)
🚧 Files skipped from review as they are similar to previous changes (2)
- crates/tsql/src/ui/key_hint_popup.rs
- crates/tsql/src/ui/help_popup.rs
🧰 Additional context used
📓 Path-based instructions (1)
**/*.rs
📄 CodeRabbit inference engine (CLAUDE.md)
**/*.rs: Runcargo fmt --allto format the code before committing changes
Runcargo clippy --all --all-targets -- -D warningsto check for lints and fix them before pushing changes
Files:
crates/tsql/src/ui/key_sequence.rs
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
- GitHub Check: Test (windows-latest)
🔇 Additional comments (1)
crates/tsql/src/ui/key_sequence.rs (1)
248-531: Tests look solid and cover the new SchemaTable/action matrix and context clearing
The added assertions aroundcontext: NonevsSome(...)are especially helpful for preventing subtle regressions.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 0
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
crates/tsql/src/ui/key_hint_popup.rs (1)
75-121: Popup positioning ignoresframe_area.x/yand can produce 0-sized rects on tiny terminals.
This will misplace the popup ifframe_areaisn’t rooted at (0,0), and 0 width/height can trigger odd rendering edge cases.@@ fn popup_area(&self, frame_area: Rect) -> Rect { @@ - // Position in bottom-right with padding - let x = frame_area.width.saturating_sub(width + PADDING); - let y = frame_area.height.saturating_sub(height + PADDING); + // Ensure non-zero size (ratatui widgets generally assume positive area) + let width = width.max(1); + let height = height.max(1); + + // Position in bottom-right with padding (respecting frame_area origin) + let x = frame_area + .x + .saturating_add(frame_area.width.saturating_sub(width + PADDING)); + let y = frame_area + .y + .saturating_add(frame_area.height.saturating_sub(height + PADDING)); Rect::new(x, y, width, height) }
🧹 Nitpick comments (1)
crates/tsql/src/ui/key_sequence.rs (1)
141-147: Consider cancel+restart semantics instart_with_context()(defensive against misuse).
Ifstart_with_context()can be called while a sequence is already pending, it should likely clear the previous state first (matchingprocess_first_key()behavior).pub fn start_with_context(&mut self, key: PendingKey, context: C) { + if self.pending.is_some() { + self.cancel(); + } self.pending = Some(key); self.pending_since = Some(Instant::now()); self.hint_shown = false; self.pending_context = Some(context); }
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
Disabled knowledge base sources:
- Linear integration is disabled by default for public repositories
You can enable these sources in your CodeRabbit configuration.
📒 Files selected for processing (3)
crates/tsql/src/ui/help_popup.rs(2 hunks)crates/tsql/src/ui/key_hint_popup.rs(3 hunks)crates/tsql/src/ui/key_sequence.rs(12 hunks)
🧰 Additional context used
📓 Path-based instructions (1)
**/*.rs
📄 CodeRabbit inference engine (CLAUDE.md)
**/*.rs: Runcargo fmt --allto format the code before committing changes
Runcargo clippy --all --all-targets -- -D warningsto check for lints and fix them before pushing changes
Files:
crates/tsql/src/ui/help_popup.rscrates/tsql/src/ui/key_hint_popup.rscrates/tsql/src/ui/key_sequence.rs
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
- GitHub Check: Test (windows-latest)
🔇 Additional comments (8)
crates/tsql/src/ui/help_popup.rs (2)
84-93: Go-to keybinding rename togslooks consistent with schema sidebar navigation.
95-109: Help text likely to drift—please verify the schema Enter+key sequences match runtime behavior.
In particular, “Enter (table) then s/i/u/d/n” and the hint popup timing should match what users actually see.Also applies to: 236-240
crates/tsql/src/ui/key_hint_popup.rs (2)
33-48: Schema-table hint wiring is clean and test-covered.Also applies to: 62-68
183-206: Nice coverage for SchemaTable hints + title char.crates/tsql/src/ui/key_sequence.rs (4)
10-46: Context-carrying completion is a good evolution of the API; state cleanup looks consistent.Also applies to: 72-105, 141-155, 168-174
175-191: Please verify caller dispatch: pending sequences must go throughprocess_second_key(), notprocess_first_key().
Sinceprocess_first_key()now cancels any pending sequence up front, a caller that naïvely calls it for all keystrokes could cancel sequences unexpectedly.Also applies to: 193-230
383-515: Schema-table sequence tests are solid and exercise context propagation/clearing well.
1-246: Ensure Rust code is properly formatted and passes linting.
Runcargo fmt --allandcargo clippy --all --all-targets -- -D warningsbefore committing changes per repository guidelines.
- Add clear_state() call at start of start_with_context and start methods to match cancel+restart semantics of process_first_key - Add test to verify process_first_key cancels in-flight context-bearing SchemaTable sequences
- Account for frame_area.x/y when positioning the popup - Ensure minimum 1x1 dimensions to avoid 0-sized rects on tiny terminals
Summary
Features
Pressing Enter on a table in the schema panel now starts a key sequence for generating SQL templates:
Enter+sEnter+iEnter+uEnter+dEnter+nConfiguration
New
[sql]section in config:Test plan
Summary by CodeRabbit
New Features
Documentation
Chores
✏️ Tip: You can customize this high-level summary in your review settings.