Add support for quotes around colons when searching (#162)

This commit is contained in:
David Dworken 2024-01-07 18:56:30 -08:00 committed by GitHub
parent 12f0aa1bff
commit e86f7bf382
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 119 additions and 3 deletions

View File

@ -1923,7 +1923,27 @@ func testTui_search(t *testing.T, onlineStatus OnlineStatus) {
}))
testutils.CompareGoldens(t, out, "TestTui-SearchBackslash")
// TODO: Add a test for the behavior when quoting something containing a colon
// Add another entry for testing quoting a colon
require.NoError(t, db.Create(testutils.MakeFakeHistoryEntry("foo:bar")).Error)
out = tester.RunInteractiveShell(t, `hishtory export`)
testutils.CompareGoldens(t, out, "TestTui-ExportWithEvenMoreEntries")
// And check that we can quote colons
out = stripTuiCommandPrefix(t, captureTerminalOutput(t, tester, []string{
"hishtory SPACE tquery ENTER",
"foo:bar",
}))
testutils.CompareGoldens(t, out, "TestTui-SearchColonError")
out = stripTuiCommandPrefix(t, captureTerminalOutput(t, tester, []string{
"hishtory SPACE tquery ENTER",
"foo\\\\:bar",
}))
testutils.CompareGoldens(t, out, "TestTui-SearchColonEscaped")
out = stripTuiCommandPrefix(t, captureTerminalOutput(t, tester, []string{
"hishtory SPACE tquery ENTER",
"'\"'foo:bar'\"'",
}))
testutils.CompareGoldens(t, out, "TestTui-SearchColonDoubleQuoted")
}
func testTui_general(t *testing.T, onlineStatus OnlineStatus) {

View File

@ -1005,6 +1005,9 @@ func splitEscaped(query string, separator rune, maxSplit int) []string {
} else if runeQuery[i] == '\'' && !isInDoubleQuotedString && !heuristicIgnoreUnclosedQuote(isInSingleQuotedString, '\'', runeQuery, i) {
isInSingleQuotedString = !isInSingleQuotedString
} else {
if (isInSingleQuotedString || isInDoubleQuotedString) && separator == ' ' && runeQuery[i] == ':' {
token = append(token, '\\')
}
token = append(token, runeQuery[i])
}
}

View File

@ -288,7 +288,7 @@ func TestSplitEscaped(t *testing.T) {
{"'foo bar baz", ' ', -1, []string{"'foo", "bar", "baz"}},
{"'foo bar baz\\''", ' ', -1, []string{"foo bar baz'"}},
{"cwd:'foo bar :baz\\''", ':', -1, []string{"cwd", "foo bar :baz'"}},
{"cwd:'foo bar :baz\\''", ' ', -1, []string{"cwd:foo bar :baz'"}},
{"cwd:'foo bar :baz\\''", ' ', -1, []string{"cwd:foo bar \\:baz'"}},
// Tests for double quotes
{"\"foo bar\"", ' ', -1, []string{"foo bar"}},
{"\"foo bar\" \" \"", ' ', -1, []string{"foo bar", " "}},
@ -296,7 +296,7 @@ func TestSplitEscaped(t *testing.T) {
{"\"foo bar baz", ' ', -1, []string{"\"foo", "bar", "baz"}},
{"\"foo bar baz\\\"\"", ' ', -1, []string{"foo bar baz\""}},
{"cwd:\"foo bar :baz\\\"\"", ':', -1, []string{"cwd", "foo bar :baz\""}},
{"cwd:\"foo bar :baz\\\"\"", ' ', -1, []string{"cwd:foo bar :baz\""}},
{"cwd:\"foo bar :baz\\\"\"", ' ', -1, []string{"cwd:foo bar \\:baz\""}},
// Tests for complex quotes
{"\"foo'bar\"", ' ', -1, []string{"foo'bar"}},
{"'foo\"bar'", ' ', -1, []string{"foo\"bar"}},
@ -318,6 +318,10 @@ func TestSplitEscaped(t *testing.T) {
{"foo:bar", ' ', -1, []string{"foo:bar"}},
{"foo\\:bar", ':', -1, []string{"foo\\:bar"}},
{"foo\\:bar", ' ', -1, []string{"foo\\:bar"}},
// Tests for quoting colons
{"foo:bar", ' ', -1, []string{"foo:bar"}},
{"'foo:bar'", ' ', -1, []string{"foo\\:bar"}},
{"\"foo:bar\"", ' ', -1, []string{"foo\\:bar"}},
}
for _, tc := range testcases {
actual := splitEscaped(tc.input, tc.char, tc.limit)

View File

@ -0,0 +1,6 @@
ls ~/
echo 'aaaaaa bbbb'
for i in 1
for i in 2
i for in
foo:bar

View File

@ -0,0 +1,27 @@
Search Query: > "foo:bar"
┌────────────────────────────────────────────────────────────────────────────────────────────────────────┐
│ Hostname CWD Timestamp Runtime Exit Code Command │
│────────────────────────────────────────────────────────────────────────────────────────────────────────│
│ localhost /tmp/ Oct 17 2022 21:43:41 PDT 3s 2 foo:bar │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
└────────────────────────────────────────────────────────────────────────────────────────────────────────┘
hiSHtory: Search your shell history • ctrl+h help

View File

@ -0,0 +1,29 @@
Warning: failed to search: search query contains unknown search atom 'foo' that doesn't match any column names
Search Query: > foo:bar
┌────────────────────────────────────────────────────────────────────────────────────────────────────────┐
│ Hostname CWD Timestamp Runtime Exit Code Command │
│────────────────────────────────────────────────────────────────────────────────────────────────────────│
│ localhost /tmp/ Oct 17 2022 21:43:41 PDT 3s 2 foo:bar │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
└────────────────────────────────────────────────────────────────────────────────────────────────────────┘
hiSHtory: Search your shell history • ctrl+h help

View File

@ -0,0 +1,27 @@
Search Query: > foo\:bar
┌────────────────────────────────────────────────────────────────────────────────────────────────────────┐
│ Hostname CWD Timestamp Runtime Exit Code Command │
│────────────────────────────────────────────────────────────────────────────────────────────────────────│
│ localhost /tmp/ Oct 17 2022 21:43:41 PDT 3s 2 foo:bar │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
└────────────────────────────────────────────────────────────────────────────────────────────────────────┘
hiSHtory: Search your shell history • ctrl+h help