diff --git a/Cargo.lock b/Cargo.lock index a8fadc7..0763226 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -342,6 +342,18 @@ dependencies = [ "crossbeam-utils", ] +[[package]] +name = "console" +version = "0.15.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "054ccb5b10f9f2cbf51eb355ca1d05c2d279ce1804688d0db74b4733a5aeafd8" +dependencies = [ + "encode_unicode", + "libc", + "once_cell", + "windows-sys 0.59.0", +] + [[package]] name = "const-oid" version = "0.9.6" @@ -556,6 +568,12 @@ dependencies = [ "serde", ] +[[package]] +name = "encode_unicode" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34aa73646ffb006b8f5147f3dc182bd4bcb190227ce861fc4a4844bf8e3cb2c0" + [[package]] name = "equivalent" version = "1.0.2" @@ -1009,6 +1027,17 @@ version = "2.0.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f4c7245a08504955605670dbf141fceab975f15ca21570696aebe9d2e71576bd" +[[package]] +name = "insta" +version = "1.43.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "154934ea70c58054b556dd430b99a98c2a7ff5309ac9891597e339b5c28f4371" +dependencies = [ + "console", + "once_cell", + "similar", +] + [[package]] name = "instability" version = "0.3.9" @@ -1855,6 +1884,12 @@ dependencies = [ "rand_core 0.6.4", ] +[[package]] +name = "similar" +version = "2.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbbb5d9659141646ae647b42fe094daf6c6192d1620870b449d9557f748b2daa" + [[package]] name = "slab" version = "0.4.11" @@ -1901,7 +1936,7 @@ dependencies = [ [[package]] name = "sqlk" -version = "0.1.4" +version = "0.1.5" dependencies = [ "anyhow", "async-trait", @@ -1912,6 +1947,7 @@ dependencies = [ "dirs", "dotenv", "futures", + "insta", "rand 0.9.2", "ratatui", "regex", diff --git a/sqlk/Cargo.toml b/sqlk/Cargo.toml index 66b1170..291a1ef 100644 --- a/sqlk/Cargo.toml +++ b/sqlk/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "sqlk" -version = "0.1.4" +version = "0.1.5" authors = ["Seth "] edition = "2024" description = "A terminal-based PostgreSQL query execution and visualization tool with vim-like navigation." @@ -54,4 +54,5 @@ uuid = "1.18.0" cli-clipboard = "0.4.0" [dev-dependencies] +insta = "1.43.1" tempfile = "3.8" diff --git a/sqlk/src/application/events/mod.rs b/sqlk/src/application/events/mod.rs index 30c1725..143cfb3 100644 --- a/sqlk/src/application/events/mod.rs +++ b/sqlk/src/application/events/mod.rs @@ -183,3 +183,4 @@ impl App { Ok(()) } } + diff --git a/sqlk/src/application/modes/mod.rs b/sqlk/src/application/modes/mod.rs index 359cd36..cccc032 100644 --- a/sqlk/src/application/modes/mod.rs +++ b/sqlk/src/application/modes/mod.rs @@ -24,9 +24,12 @@ impl App { } KeyCode::Enter => { if let Some(viewer) = &mut self.table_viewer { - viewer.search( &self.search_input, &mut self.ui); + viewer.search(&self.search_input, &mut self.ui); } - self.current_mode = AppMode::TableViewer; + // Correctly reset search input and cursor position + self.search_input.clear(); + self.search_cursor_position = 0; + self.current_mode = AppMode::TableViewer; } KeyCode::Char(c) => { // Insert character at cursor position @@ -34,10 +37,10 @@ impl App { self.search_cursor_position += 1; } KeyCode::Backspace => { - // Remove character at cursor position if self.search_cursor_position > 0 { + self.search_input + .remove(Into::::into(self.search_cursor_position) - 1); self.search_cursor_position -= 1; - self.search_input.remove(self.search_cursor_position.into()); } } KeyCode::Esc => { diff --git a/sqlk/src/application/state/mod.rs b/sqlk/src/application/state/mod.rs index f4e6b01..b65acb3 100644 --- a/sqlk/src/application/state/mod.rs +++ b/sqlk/src/application/state/mod.rs @@ -82,7 +82,7 @@ impl App { query_parser: QueryParser::new(), query_blocks: Vec::new(), is_querying: false, - search_cursor_position: 0 + search_cursor_position: 0, }; Ok(app) diff --git a/sqlk/src/config/db/mod.rs b/sqlk/src/config/db/mod.rs index b8b91ab..3f1756c 100644 --- a/sqlk/src/config/db/mod.rs +++ b/sqlk/src/config/db/mod.rs @@ -66,7 +66,7 @@ impl DatabaseType { match self { DatabaseType::PostgreSQL => 5432, DatabaseType::MySQL => 3306, - DatabaseType::SQLite => 0, + DatabaseType::SQLite => 0, } } } diff --git a/sqlk/src/config/loader/mod.rs b/sqlk/src/config/loader/mod.rs index 7f10708..05eba10 100644 --- a/sqlk/src/config/loader/mod.rs +++ b/sqlk/src/config/loader/mod.rs @@ -29,7 +29,7 @@ impl ConfigLoader { let config_path = self.config_dir.join("config.toml"); if config_path.exists() { config = self.load_config_file(&config_path)?; - config.env_file = env_file.to_path_buf(); + config.env_file = env_file.to_path_buf(); } config.database = self.load_database_config(env_file)?; diff --git a/sqlk/src/config/parser/mod.rs b/sqlk/src/config/parser/mod.rs index f49a4a4..36a655e 100644 --- a/sqlk/src/config/parser/mod.rs +++ b/sqlk/src/config/parser/mod.rs @@ -18,7 +18,13 @@ impl DatabaseUrlParser { fn extract_value(value_part: &str) -> Option { let trimmed = value_part.trim(); - if trimmed.starts_with('"') && trimmed.ends_with('"') && trimmed.len() >= 2 && trimmed.starts_with('\'') && trimmed.ends_with('\'') && trimmed.len() >= 2 { + if trimmed.starts_with('"') + && trimmed.ends_with('"') + && trimmed.len() >= 2 + && trimmed.starts_with('\'') + && trimmed.ends_with('\'') + && trimmed.len() >= 2 + { Some(trimmed[1..trimmed.len() - 1].to_string()) } else if !trimmed.is_empty() { Some(trimmed.to_string()) diff --git a/sqlk/src/database/postgres/formatting.rs b/sqlk/src/database/postgres/formatting.rs index 3b44f3d..86c643c 100644 --- a/sqlk/src/database/postgres/formatting.rs +++ b/sqlk/src/database/postgres/formatting.rs @@ -44,9 +44,7 @@ impl PostgresFormatter { .columns() .iter() .enumerate() - .map(|(idx, _col)| { - self.get_column_type_from_rows(&rows, idx) - }) + .map(|(idx, _col)| self.get_column_type_from_rows(&rows, idx)) .collect(); let mut result_rows = Vec::new(); diff --git a/sqlk/src/main.rs b/sqlk/src/main.rs index 833e77b..eac91c5 100644 --- a/sqlk/src/main.rs +++ b/sqlk/src/main.rs @@ -15,3 +15,4 @@ async fn main() -> Result<()> { Ok(()) } + diff --git a/sqlk/src/matrix/colours/mod.rs b/sqlk/src/matrix/colours/mod.rs index 772123c..c42f4e0 100644 --- a/sqlk/src/matrix/colours/mod.rs +++ b/sqlk/src/matrix/colours/mod.rs @@ -55,7 +55,7 @@ impl ColorCalculator { let b = b1 as f32 + (b2 as f32 - b1 as f32) * factor; Color::Rgb(r as u8, g as u8, b as u8) } - _ => from, + _ => from, } } } diff --git a/sqlk/src/table_viewer/chart/mod.rs b/sqlk/src/table_viewer/chart/mod.rs index 6de1841..cdcf7ea 100644 --- a/sqlk/src/table_viewer/chart/mod.rs +++ b/sqlk/src/table_viewer/chart/mod.rs @@ -66,8 +66,7 @@ impl TableViewer { let mut temp_items: Vec<_> = sorted_items.iter().take(max_items - 1).cloned().collect(); - if let Some(pos) = temp_items.iter().position(|(l, _)| l == value_to_highlight) - { + if let Some(pos) = temp_items.iter().position(|(l, _)| l == value_to_highlight) { let highlighted = temp_items.remove(pos); temp_items.insert(0, highlighted); } @@ -144,7 +143,7 @@ impl TableViewer { self.show_chart = false; self.chart_data = None; } else { - let max_items = 20; + let max_items = 20; let value_to_highlight = self.get_current_cell_value().unwrap_or_default(); @@ -169,7 +168,7 @@ impl TableViewer { )); lines.push("├─────────────────────────────────────────┤".to_string()); - let label_width = width.saturating_sub(25).max(10); + let label_width = width.saturating_sub(25).max(10); let bar_char = "█"; for item in &chart_data.items { diff --git a/sqlk/src/table_viewer/navigation/mod.rs b/sqlk/src/table_viewer/navigation/mod.rs index a8fbd52..71b0221 100644 --- a/sqlk/src/table_viewer/navigation/mod.rs +++ b/sqlk/src/table_viewer/navigation/mod.rs @@ -51,7 +51,7 @@ impl TableViewer { KeyCode::Char('N') => self.prev_search_match(1), KeyCode::Char('c') => { - let bar_width = 30; + let bar_width = 30; self.toggle_chart(bar_width); } diff --git a/sqlk/src/table_viewer/search/mod.rs b/sqlk/src/table_viewer/search/mod.rs index 55fca50..fe5f1b7 100644 --- a/sqlk/src/table_viewer/search/mod.rs +++ b/sqlk/src/table_viewer/search/mod.rs @@ -1,6 +1,9 @@ use regex::Regex; -use crate::{table_viewer::{CellPosition, TableViewer}, ui::{ToastType, UI}}; +use crate::{ + table_viewer::{CellPosition, TableViewer}, + ui::{ToastType, UI}, +}; #[derive(Debug, Default)] pub struct SearchState { @@ -22,7 +25,7 @@ impl TableViewer { let Ok(re) = Regex::new(&format!("(?i){}", term)) else { return; }; - + for (row_idx, row) in self.data.rows.iter().enumerate() { for (col_idx, cell) in row.iter().enumerate() { if re.is_match(cell) { @@ -34,7 +37,10 @@ impl TableViewer { } } - ui.add_toast(format!("Found {:?} matches", self.search_state.matches.iter().len()), ToastType::Info); + ui.add_toast( + format!("Found {:?} matches", self.search_state.matches.iter().len()), + ToastType::Info, + ); if !self.search_state.matches.is_empty() { self.jump_to_match(0); diff --git a/sqlk/src/ui/home/mod.rs b/sqlk/src/ui/home/mod.rs index 03e7728..792712e 100644 --- a/sqlk/src/ui/home/mod.rs +++ b/sqlk/src/ui/home/mod.rs @@ -126,7 +126,7 @@ impl UI { .add_modifier(Modifier::BOLD), )), status_line, - Line::from(""), + Line::from(""), Line::from(Span::styled( "Lines:", Style::default() diff --git a/sqlk/src/ui/search/mod.rs b/sqlk/src/ui/search/mod.rs index 1797382..e775dff 100644 --- a/sqlk/src/ui/search/mod.rs +++ b/sqlk/src/ui/search/mod.rs @@ -80,13 +80,11 @@ impl UI { f.render_widget(help_text, chunks[2]); // Position the cursor at the end of the input text - f.set_cursor_position( - Position { + f.set_cursor_position(Position { // x-coordinate: start of the block + border + text length x: chunks[1].x + app.search_cursor_position + 1, // y-coordinate: start of the block + top border y: chunks[1].y + 1, - } - ); + }); } }