diff --git a/TODO.md b/TODO.md index 9ba6d1a..f1ef5de 100644 --- a/TODO.md +++ b/TODO.md @@ -8,4 +8,5 @@ - `yc` should copy to csv format - should be able to copy without row names (`Y` keybinding) - `Ym` should copy to markdown format - - `Yc` should copy to csv format \ No newline at end of file + - `Yc` should copy to csv format +- [ ] add ability to update values from the row view \ No newline at end of file diff --git a/src/app.rs b/src/app.rs index c3834cc..3805590 100644 --- a/src/app.rs +++ b/src/app.rs @@ -677,6 +677,10 @@ fn append_record<'a>( if index > 0 { output.push(','); } + if !value.contains([',', '"', '\r', '\n']) { + output.push_str(value); + continue; + } output.push('"'); for character in value.chars() { if character == '"' { @@ -755,6 +759,17 @@ fn moved_index(selected: Option, count: usize, delta: isize) -> Option crate::Result<()> { use super::{App, Focus}; @@ -799,14 +814,14 @@ mod tests { ); assert_eq!( app.selection_text(true, false).as_deref(), - Some("\"b\",\"c\"\r\n\"a|b\",\"say \"\"hi\"\",界\"\r\n\"NULL\",\"<&>\\tail\"\r\n") + Some("b,c\r\na|b,\"say \"\"hi\"\",界\"\r\nNULL,<&>\\tail\r\n") ); assert_eq!( app.selection_text(false, false).as_deref(), - Some("\"a|b\",\"say \"\"hi\"\",界\"\r\n\"NULL\",\"<&>\\tail\"\r\n") + Some("a|b,\"say \"\"hi\"\",界\"\r\nNULL,<&>\\tail\r\n") ); assert!(app.handle_rows_command(KeyEvent::new(KeyCode::Esc, KeyModifiers::NONE))); - assert_eq!(app.selection_text(false, false).as_deref(), Some("\"a|b\"\r\n")); + assert_eq!(app.selection_text(false, false).as_deref(), Some("a|b\r\n")); // A prefix cancels on focus changes rather than capturing a later key. app.handle_rows_command(key('y')); assert!(!app.handle_rows_command(KeyEvent::new(KeyCode::Tab, KeyModifiers::NONE))); @@ -814,7 +829,7 @@ mod tests { app.handle_rows_command(key('v')); app.handle_key(key('n')); assert!(app.selection_anchor.is_none()); - assert_eq!(app.selection_text(false, false).as_deref(), Some("\"101\"\r\n")); + assert_eq!(app.selection_text(false, false).as_deref(), Some("101\r\n")); app.handle_rows_command(key('v')); app.handle_key(key('s')); assert!(app.selection_anchor.is_none()); @@ -824,11 +839,11 @@ mod tests { app.query.value = "SELECT 42 AS answer".into(); app.execute_query(); assert!(app.selection_anchor.is_none()); - assert_eq!(app.selection_text(true, false).as_deref(), Some("\"answer\"\r\n\"42\"\r\n")); + assert_eq!(app.selection_text(true, false).as_deref(), Some("answer\r\n42\r\n")); app.handle_rows_command(key('v')); app.query.value = "SELECT missing FROM nowhere".into(); app.execute_query(); - assert_eq!(app.selection_text(false, false).as_deref(), Some("\"42\"\r\n")); + assert_eq!(app.selection_text(false, false).as_deref(), Some("42\r\n")); assert!(app.selection_anchor.is_some()); app.open_relation(Some(0)); assert!(app.selection_anchor.is_none()); diff --git a/src/connection.rs b/src/connection.rs index 6a463bc..ff440a3 100644 --- a/src/connection.rs +++ b/src/connection.rs @@ -433,7 +433,8 @@ fn draw_help(frame: &mut Frame, screen: Rect, offset: &mut u16) { With no block, copy uses the current cell. Blocks stay within the loaded page.\n\ Paging, refresh, schema/relation changes, and successful queries clear blocks.\n\ Copy uses full displayed values; NULL/control escapes are preserved.\n\ - Headerless Markdown has blank headings. CSV quotes fields with CRLF endings.\n\ + Headerless Markdown has blank headings. CSV uses CRLF and quotes only fields\n\ + containing commas, double quotes, or line breaks.\n\ Clipboard: macOS pbcopy; Windows PowerShell; Wayland wl-copy; X11 xclip.\n\n\ Query editor\n\ i/a/I/A Enter Insert mode (at/after/start/end)\n\ diff --git a/src/main.rs b/src/main.rs index b25d709..e8fb233 100644 --- a/src/main.rs +++ b/src/main.rs @@ -79,7 +79,8 @@ Navigation: Blocks cover the current loaded page, including cells scrolled out of view. Paging, refreshing, opening a relation, schema changes, and successful queries clear blocks. Copies use full displayed cell values (NULL and escaped control characters included). - Headerless Markdown uses blank headings; CSV quotes fields and uses CRLF line endings. + Headerless Markdown uses blank headings; CSV quotes only fields containing commas, + double quotes, or line breaks, and uses CRLF line endings. Clipboard tools: pbcopy on macOS, PowerShell on Windows, wl-copy on Wayland, or xclip on X11. A missing/failing tool reports an error without clearing the block. c Add a configured database in a floating window