mirror of
https://github.com/ddworken/hishtory.git
synced 2024-11-21 15:53:32 +01:00
Merge branch 'master' into silence
This commit is contained in:
commit
38ee17ae57
@ -2165,6 +2165,14 @@ func testTui_search(t *testing.T, onlineStatus OnlineStatus) {
|
||||
"'\"'foo:bar'\"'",
|
||||
}))
|
||||
testutils.CompareGoldens(t, out, "TestTui-SearchColonDoubleQuoted")
|
||||
|
||||
// And check that we can quote dashes
|
||||
require.NoError(t, db.Create(testutils.MakeFakeHistoryEntry("foo --bar")).Error)
|
||||
out = stripTuiCommandPrefix(t, captureTerminalOutput(t, tester, []string{
|
||||
"hishtory SPACE tquery ENTER",
|
||||
"'\"'--bar'\"'",
|
||||
}))
|
||||
testutils.CompareGoldens(t, out, "TestTui-SearchQuoteDash")
|
||||
}
|
||||
|
||||
func testTui_general(t *testing.T, onlineStatus OnlineStatus) {
|
||||
@ -2520,8 +2528,8 @@ echo bar`)
|
||||
tester.RunInteractiveShell(t, `hishtory config-set displayed-columns 'Exit Code' git_remote Command`)
|
||||
out = tester.RunInteractiveShell(t, `hishtory query -pipefail`)
|
||||
testutils.CompareGoldens(t, out, fmt.Sprintf("testCustomColumns-query-isAction=%v", testutils.IsGithubAction()))
|
||||
out = captureTerminalOutput(t, tester, []string{"hishtory SPACE tquery SPACE -pipefail ENTER"})
|
||||
out = stripRequiredPrefix(t, out, "hishtory tquery -pipefail")
|
||||
out = captureTerminalOutput(t, tester, []string{"hishtory SPACE tquery SPACE ENTER", "-pipefail"})
|
||||
out = stripRequiredPrefix(t, out, "hishtory tquery")
|
||||
testName := "testCustomColumns-tquery-" + tester.ShellName()
|
||||
if testutils.IsGithubAction() {
|
||||
testName += "-isAction"
|
||||
@ -2778,8 +2786,8 @@ func TestTimestampFormat(t *testing.T) {
|
||||
// And check that it is displayed in both the tui and the classic view
|
||||
out := hishtoryQuery(t, tester, "-pipefail -tablesizing")
|
||||
testutils.CompareGoldens(t, out, "TestTimestampFormat-query")
|
||||
out = captureTerminalOutput(t, tester, []string{"hishtory SPACE tquery SPACE -pipefail SPACE -tablesizing ENTER"})
|
||||
out = stripRequiredPrefix(t, out, "hishtory tquery -pipefail -tablesizing")
|
||||
out = captureTerminalOutput(t, tester, []string{"hishtory SPACE tquery ENTER", "table_cmd SPACE -tquery"})
|
||||
out = stripRequiredPrefix(t, out, "hishtory tquery")
|
||||
testutils.CompareGoldens(t, out, "TestTimestampFormat-tquery")
|
||||
}
|
||||
|
||||
@ -2818,7 +2826,7 @@ func TestSortByConsistentTimezone(t *testing.T) {
|
||||
testutils.CompareGoldens(t, out, "TestSortByConsistentTimezone-query")
|
||||
out = tester.RunInteractiveShell(t, `hishtory export -pipefail -tablesizing`)
|
||||
testutils.CompareGoldens(t, out, "TestSortByConsistentTimezone-export")
|
||||
out = captureTerminalOutput(t, tester, []string{"hishtory SPACE tquery SPACE -pipefail SPACE -tablesizing ENTER"})
|
||||
out = captureTerminalOutput(t, tester, []string{"hishtory SPACE tquery ENTER", "-pipefail SPACE -tablesizing"})
|
||||
out = stripTuiCommandPrefix(t, out)
|
||||
require.Regexp(t, regexp.MustCompile(`Timestamp[\s\S]*Command[\s\S]*Apr 16 2022 01:36:26 PDT[\s\S]*third_entry[\s\S]*Apr 16 2022 01:19:46 PDT[\s\S]*second_entry[\s\S]*Apr 16 2022 01:03:06 PDT[\s\S]*first_entry`), out)
|
||||
}
|
||||
@ -2879,8 +2887,8 @@ echo foo`)
|
||||
tester.RunInteractiveShell(t, `hishtory config-set displayed-columns 'Exit Code' Command`)
|
||||
out = tester.RunInteractiveShell(t, `hishtory query -pipefail`)
|
||||
testutils.CompareGoldens(t, out, "testRemoveDuplicateRows-query")
|
||||
out = captureTerminalOutput(t, tester, []string{"hishtory SPACE tquery SPACE -pipefail ENTER"})
|
||||
out = stripRequiredPrefix(t, out, "hishtory tquery -pipefail")
|
||||
out = captureTerminalOutput(t, tester, []string{"hishtory SPACE tquery ENTER", "-pipefail"})
|
||||
out = stripRequiredPrefix(t, out, "hishtory tquery")
|
||||
testutils.CompareGoldens(t, out, "testRemoveDuplicateRows-tquery")
|
||||
|
||||
// And change the config to filter out duplicate rows
|
||||
@ -2895,18 +2903,20 @@ echo foo`)
|
||||
testutils.CompareGoldens(t, out, "testRemoveDuplicateRows-enabled-query")
|
||||
|
||||
// Check tquery
|
||||
out = captureTerminalOutput(t, tester, []string{"hishtory SPACE tquery SPACE -pipefail ENTER"})
|
||||
out = stripRequiredPrefix(t, out, "hishtory tquery -pipefail")
|
||||
out = captureTerminalOutput(t, tester, []string{"hishtory SPACE tquery ENTER", "-pipefail"})
|
||||
out = stripRequiredPrefix(t, out, "hishtory tquery")
|
||||
testutils.CompareGoldens(t, out, "testRemoveDuplicateRows-enabled-tquery")
|
||||
|
||||
// Check actually selecting it with query
|
||||
out = captureTerminalOutputWithComplexCommands(t, tester, []TmuxCommand{
|
||||
{Keys: "hishtory SPACE tquery SPACE -pipefail ENTER", ExtraDelay: 1.0},
|
||||
{Keys: "Down Down"},
|
||||
{Keys: "hishtory SPACE tquery ENTER", ExtraDelay: 1.0},
|
||||
{Keys: "-pipefail", ExtraDelay: 1.0},
|
||||
{Keys: "Down Down Down"},
|
||||
{Keys: "ENTER", ExtraDelay: 1.0},
|
||||
})
|
||||
out = stripTuiCommandPrefix(t, out)
|
||||
require.Contains(t, out, "\necho foo\n")
|
||||
require.Contains(t, out, "echo foo\n")
|
||||
require.NotContains(t, out, "hishtory tquery")
|
||||
require.NotContains(t, out, "echo baz")
|
||||
require.NotContains(t, out, "config-set")
|
||||
}
|
||||
|
@ -26,10 +26,14 @@ import (
|
||||
)
|
||||
|
||||
var (
|
||||
offlineInit *bool
|
||||
forceInit *bool
|
||||
offlineInstall *bool
|
||||
skipConfigModification *bool
|
||||
offlineInit *bool
|
||||
forceInit *bool
|
||||
offlineInstall *bool
|
||||
skipConfigModification *bool
|
||||
skipUpdateConfigModification *bool
|
||||
|
||||
//lint:ignore U1000 Flag that is allowed to be specified, but not used
|
||||
currentlyInstalledVersion *string
|
||||
)
|
||||
|
||||
var installCmd = &cobra.Command{
|
||||
@ -45,7 +49,7 @@ var installCmd = &cobra.Command{
|
||||
if strings.HasPrefix(secretKey, "-") {
|
||||
lib.CheckFatalError(fmt.Errorf("secret key %#v looks like a CLI flag, please use a secret key that does not start with a -", secretKey))
|
||||
}
|
||||
lib.CheckFatalError(install(secretKey, *offlineInstall, *skipConfigModification))
|
||||
lib.CheckFatalError(install(secretKey, *offlineInstall, *skipConfigModification || *skipUpdateConfigModification))
|
||||
if os.Getenv("HISHTORY_SKIP_INIT_IMPORT") == "" {
|
||||
db, err := hctx.OpenLocalSqliteDb()
|
||||
lib.CheckFatalError(err)
|
||||
@ -686,4 +690,6 @@ func init() {
|
||||
forceInit = initCmd.Flags().Bool("force", false, "Force re-init without any prompts")
|
||||
offlineInstall = installCmd.Flags().Bool("offline", false, "Install hiSHtory in offline mode with all syncing capabilities disabled")
|
||||
skipConfigModification = installCmd.Flags().Bool("skip-config-modification", false, "Skip modifying shell configs and instead instruct the user on how to modify their configs")
|
||||
skipUpdateConfigModification = installCmd.Flags().Bool("skip-update-config-modification", false, "Skip modifying shell configs for updates")
|
||||
currentlyInstalledVersion = installCmd.Flags().String("currently-installed-version", "", "The currently installed version (used by the update command)")
|
||||
}
|
||||
|
@ -55,7 +55,7 @@ var tqueryCmd = &cobra.Command{
|
||||
if os.Getenv("HISHTORY_SHELL_NAME") != "" {
|
||||
shellName = os.Getenv("HISHTORY_SHELL_NAME")
|
||||
}
|
||||
lib.CheckFatalError(tui.TuiQuery(ctx, shellName, strings.Join(args, " ")))
|
||||
lib.CheckFatalError(tui.TuiQuery(ctx, shellName, args))
|
||||
},
|
||||
}
|
||||
|
||||
|
@ -965,7 +965,9 @@ func splitEscaped(query string, separator rune, maxSplit int) []string {
|
||||
isInSingleQuotedString := false
|
||||
for i := 0; i < len(runeQuery); i++ {
|
||||
if (maxSplit < 0 || splits < maxSplit) && runeQuery[i] == separator && !isInSingleQuotedString && !isInDoubleQuotedString {
|
||||
tokens = append(tokens, string(token))
|
||||
if string(token) != "" {
|
||||
tokens = append(tokens, string(token))
|
||||
}
|
||||
token = token[:0]
|
||||
splits++
|
||||
} else if runeQuery[i] == '\\' && i+1 < len(runeQuery) {
|
||||
@ -982,8 +984,13 @@ 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, '\\')
|
||||
if (isInSingleQuotedString || isInDoubleQuotedString) && separator == ' ' {
|
||||
if runeQuery[i] == ':' {
|
||||
token = append(token, '\\')
|
||||
}
|
||||
if runeQuery[i] == '-' && len(token) == 0 {
|
||||
token = append(token, '\\')
|
||||
}
|
||||
}
|
||||
token = append(token, runeQuery[i])
|
||||
}
|
||||
|
@ -324,6 +324,11 @@ 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 dashes
|
||||
{"'-foo'", ' ', -1, []string{"\\-foo"}},
|
||||
{"'--foo'", ' ', -1, []string{"\\--foo"}},
|
||||
{"bar '--foo'", ' ', -1, []string{"bar", "\\--foo"}},
|
||||
{"bar 'foo-baz'", ' ', -1, []string{"bar", "foo-baz"}},
|
||||
}
|
||||
for _, tc := range testcases {
|
||||
actual := splitEscaped(tc.input, tc.char, tc.limit)
|
||||
|
8
client/testdata/TestTimestampFormat-tquery
vendored
8
client/testdata/TestTimestampFormat-tquery
vendored
@ -1,10 +1,10 @@
|
||||
Search Query: > -pipefail -tablesizing
|
||||
Search Query: > table_cmd -tquery
|
||||
|
||||
┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
|
||||
│ Hostname CWD Timestamp Runtime Exit Code Command │
|
||||
│ Hostname CWD Timestamp Runtime Exit Code Command │
|
||||
│──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────│
|
||||
│ localhost ~/foo/ 2022/Apr/16 01:03 24s 3 table_cmd2 │
|
||||
│ localhost /tmp/ 2022/Apr/16 01:03 4s 2 table_cmd1 aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa… │
|
||||
│ localhost ~/foo/ 2022/Apr/16 01:03 24s 3 table_cmd2 │
|
||||
│ localhost /tmp/ 2022/Apr/16 01:03 4s 2 table_cmd1 aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa… │
|
||||
│ │
|
||||
│ │
|
||||
│ │
|
||||
|
27
client/testdata/TestTui-SearchQuoteDash
vendored
Normal file
27
client/testdata/TestTui-SearchQuoteDash
vendored
Normal file
@ -0,0 +1,27 @@
|
||||
Search Query: > "--bar"
|
||||
|
||||
┌────────────────────────────────────────────────────────────────────────────────────────────────────────┐
|
||||
│ Hostname CWD Timestamp Runtime Exit Code Command │
|
||||
│────────────────────────────────────────────────────────────────────────────────────────────────────────│
|
||||
│ localhost /tmp/ Oct 17 2022 21:43:46 PDT 3s 2 foo --bar │
|
||||
│ │
|
||||
│ │
|
||||
│ │
|
||||
│ │
|
||||
│ │
|
||||
│ │
|
||||
│ │
|
||||
│ │
|
||||
│ │
|
||||
│ │
|
||||
│ │
|
||||
│ │
|
||||
│ │
|
||||
│ │
|
||||
│ │
|
||||
│ │
|
||||
│ │
|
||||
│ │
|
||||
│ │
|
||||
└────────────────────────────────────────────────────────────────────────────────────────────────────────┘
|
||||
hiSHtory: Search your shell history • ctrl+h help
|
@ -3,6 +3,7 @@ Search Query: > -pipefail
|
||||
┌────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
|
||||
│ Exit Code git_remote Command │
|
||||
│────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────│
|
||||
│ 0 https://github.com/ddworken/hishtory hishtory tquery │
|
||||
│ 0 https://github.com/ddworken/hishtory hishtory config-set displayed-columns 'Exit Code' git_remote Command │
|
||||
│ 0 echo bar │
|
||||
│ 0 cd / │
|
||||
@ -22,6 +23,5 @@ Search Query: > -pipefail
|
||||
│ │
|
||||
│ │
|
||||
│ │
|
||||
│ │
|
||||
└────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
|
||||
hiSHtory: Search your shell history • ctrl+h help
|
@ -3,6 +3,7 @@ Search Query: > -pipefail
|
||||
┌────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
|
||||
│ Exit Code git_remote Command │
|
||||
│────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────│
|
||||
│ 0 https://github.com/ddworken/hishtory hishtory tquery │
|
||||
│ 0 https://github.com/ddworken/hishtory hishtory config-set displayed-columns 'Exit Code' git_remote Command │
|
||||
│ 0 echo bar │
|
||||
│ 0 cd / │
|
||||
@ -22,6 +23,5 @@ Search Query: > -pipefail
|
||||
│ │
|
||||
│ │
|
||||
│ │
|
||||
│ │
|
||||
└────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
|
||||
hiSHtory: Search your shell history • ctrl+h help
|
@ -4,4 +4,5 @@ echo baz
|
||||
echo baz
|
||||
echo foo
|
||||
hishtory config-set displayed-columns 'Exit Code' Command
|
||||
hishtory tquery
|
||||
hishtory config-set filter-duplicate-commands true
|
||||
|
@ -1,5 +1,6 @@
|
||||
Exit Code Command
|
||||
0 hishtory config-set filter-duplicate-commands true
|
||||
0 hishtory tquery
|
||||
0 hishtory config-set displayed-columns 'Exit Code' Command
|
||||
0 echo foo
|
||||
0 echo baz
|
||||
|
@ -3,6 +3,7 @@ Search Query: > -pipefail
|
||||
┌───────────────────────────────────────────────────────────────────────────┐
|
||||
│ Exit Code Command │
|
||||
│───────────────────────────────────────────────────────────────────────────│
|
||||
│ 0 hishtory tquery │
|
||||
│ 0 hishtory config-set filter-duplicate-commands true │
|
||||
│ 0 hishtory config-set displayed-columns 'Exit Code' Command │
|
||||
│ 0 echo foo │
|
||||
@ -22,6 +23,5 @@ Search Query: > -pipefail
|
||||
│ │
|
||||
│ │
|
||||
│ │
|
||||
│ │
|
||||
└───────────────────────────────────────────────────────────────────────────┘
|
||||
hiSHtory: Search your shell history • ctrl+h help
|
@ -3,6 +3,7 @@ Search Query: > -pipefail
|
||||
┌───────────────────────────────────────────────────────────────────────────┐
|
||||
│ Exit Code Command │
|
||||
│───────────────────────────────────────────────────────────────────────────│
|
||||
│ 0 hishtory tquery │
|
||||
│ 0 hishtory config-set displayed-columns 'Exit Code' Command │
|
||||
│ 0 echo foo │
|
||||
│ 0 echo baz │
|
||||
@ -22,6 +23,5 @@ Search Query: > -pipefail
|
||||
│ │
|
||||
│ │
|
||||
│ │
|
||||
│ │
|
||||
└───────────────────────────────────────────────────────────────────────────┘
|
||||
hiSHtory: Search your shell history • ctrl+h help
|
@ -361,7 +361,7 @@ func stripShellPrefix(out string) string {
|
||||
|
||||
func stripRequiredPrefix(t *testing.T, out, prefix string) string {
|
||||
require.Contains(t, out, prefix)
|
||||
return strings.TrimSpace(strings.Split(out, prefix)[1])
|
||||
return strings.TrimSpace(strings.SplitN(out, prefix, 2)[1])
|
||||
}
|
||||
|
||||
func stripTuiCommandPrefix(t *testing.T, out string) string {
|
||||
|
@ -3,6 +3,7 @@ package tui
|
||||
import (
|
||||
"context"
|
||||
_ "embed" // for embedding config.sh
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"os"
|
||||
"path/filepath"
|
||||
@ -95,6 +96,9 @@ type model struct {
|
||||
|
||||
// The currently executing shell. Defaults to bash if not specified. Used for more precise AI suggestions.
|
||||
shellName string
|
||||
|
||||
// Whether we've finished the first load of results. If we haven't, we refuse to run additional queries to avoid race conditions with how we handle invalid initial queries.
|
||||
hasFinishedFirstLoad bool
|
||||
}
|
||||
|
||||
type (
|
||||
@ -119,6 +123,8 @@ type asyncQueryFinishedMsg struct {
|
||||
maintainCursor bool
|
||||
// An updated search query. May be used for initial queries when they're invalid.
|
||||
overriddenSearchQuery *string
|
||||
|
||||
isFirstQuery bool
|
||||
}
|
||||
|
||||
func initialModel(ctx context.Context, shellName, initialQuery string) model {
|
||||
@ -148,7 +154,7 @@ func initialModel(ctx context.Context, shellName, initialQuery string) model {
|
||||
queryInput.SetValue(initialQuery)
|
||||
}
|
||||
CURRENT_QUERY_FOR_HIGHLIGHTING = initialQuery
|
||||
return model{ctx: ctx, spinner: s, isLoading: true, table: nil, tableEntries: []*data.HistoryEntry{}, runQuery: &initialQuery, queryInput: queryInput, help: help.New(), shellName: shellName}
|
||||
return model{ctx: ctx, spinner: s, isLoading: true, table: nil, tableEntries: []*data.HistoryEntry{}, runQuery: &initialQuery, queryInput: queryInput, help: help.New(), shellName: shellName, hasFinishedFirstLoad: false}
|
||||
}
|
||||
|
||||
func (m model) Init() tea.Cmd {
|
||||
@ -199,13 +205,14 @@ func preventTableOverscrolling(m model) {
|
||||
|
||||
func runQueryAndUpdateTable(m model, forceUpdateTable, maintainCursor bool) tea.Cmd {
|
||||
if (m.runQuery != nil && *m.runQuery != m.lastQuery) || forceUpdateTable || m.searchErr != nil {
|
||||
// if !m.hasFinishedFirstLoad {
|
||||
// return nil
|
||||
// }
|
||||
query := m.lastQuery
|
||||
if m.runQuery != nil {
|
||||
query = *m.runQuery
|
||||
}
|
||||
LAST_DISPATCHED_QUERY_ID++
|
||||
queryId := LAST_DISPATCHED_QUERY_ID
|
||||
LAST_DISPATCHED_QUERY_TIMESTAMP = time.Now()
|
||||
queryId := allocateQueryId()
|
||||
return func() tea.Msg {
|
||||
conf := hctx.GetConf(m.ctx)
|
||||
defaultFilter := conf.DefaultFilter
|
||||
@ -214,7 +221,7 @@ func runQueryAndUpdateTable(m model, forceUpdateTable, maintainCursor bool) tea.
|
||||
defaultFilter = ""
|
||||
}
|
||||
rows, entries, searchErr := getRows(m.ctx, conf.DisplayedColumns, m.shellName, defaultFilter, query, getNumEntriesNeeded(m.ctx))
|
||||
return asyncQueryFinishedMsg{queryId, rows, entries, searchErr, forceUpdateTable, maintainCursor, nil}
|
||||
return asyncQueryFinishedMsg{queryId, rows, entries, searchErr, forceUpdateTable, maintainCursor, nil, false}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
@ -331,6 +338,9 @@ func (m model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
|
||||
m.queryInput.SetValue(*msg.overriddenSearchQuery)
|
||||
}
|
||||
}
|
||||
if msg.isFirstQuery {
|
||||
m.hasFinishedFirstLoad = true
|
||||
}
|
||||
return m, nil
|
||||
default:
|
||||
var cmd tea.Cmd
|
||||
@ -879,28 +889,72 @@ func configureColorProfile(ctx context.Context) {
|
||||
}
|
||||
}
|
||||
|
||||
func TuiQuery(ctx context.Context, shellName, initialQuery string) error {
|
||||
func buildInitialQueryWithSearchEscaping(initialQueryArray []string) (string, error) {
|
||||
var initialQuery string
|
||||
|
||||
for i, queryChunk := range initialQueryArray {
|
||||
if i != 0 {
|
||||
initialQuery += " "
|
||||
}
|
||||
if strings.HasPrefix(queryChunk, "-") {
|
||||
quoted, err := json.Marshal(queryChunk)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("failed to marshal query chunk for escaping: %w", err)
|
||||
}
|
||||
initialQuery += string(quoted)
|
||||
} else {
|
||||
initialQuery += queryChunk
|
||||
}
|
||||
}
|
||||
|
||||
return initialQuery, nil
|
||||
}
|
||||
|
||||
func splitQueryArray(initialQueryArray []string) []string {
|
||||
var splitQueryArray []string
|
||||
for _, queryChunk := range initialQueryArray {
|
||||
splitQueryArray = append(splitQueryArray, strings.Split(queryChunk, " ")...)
|
||||
}
|
||||
return splitQueryArray
|
||||
}
|
||||
|
||||
func allocateQueryId() int {
|
||||
LAST_DISPATCHED_QUERY_ID++
|
||||
LAST_DISPATCHED_QUERY_TIMESTAMP = time.Now()
|
||||
return LAST_DISPATCHED_QUERY_ID
|
||||
}
|
||||
|
||||
func TuiQuery(ctx context.Context, shellName string, initialQueryArray []string) error {
|
||||
initialQueryArray = splitQueryArray(initialQueryArray)
|
||||
initialQueryWithEscaping, err := buildInitialQueryWithSearchEscaping(initialQueryArray)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
loadedKeyBindings = hctx.GetConf(ctx).KeyBindings.ToKeyMap()
|
||||
configureColorProfile(ctx)
|
||||
additionalOptions := []tea.ProgramOption{tea.WithOutput(os.Stderr)}
|
||||
if hctx.GetConf(ctx).FullScreenRendering {
|
||||
additionalOptions = append(additionalOptions, tea.WithAltScreen())
|
||||
}
|
||||
p := tea.NewProgram(initialModel(ctx, shellName, initialQuery), additionalOptions...)
|
||||
p := tea.NewProgram(initialModel(ctx, shellName, initialQueryWithEscaping), additionalOptions...)
|
||||
// Async: Get the initial set of rows
|
||||
go func() {
|
||||
LAST_DISPATCHED_QUERY_ID++
|
||||
queryId := LAST_DISPATCHED_QUERY_ID
|
||||
LAST_DISPATCHED_QUERY_TIMESTAMP = time.Now()
|
||||
queryId := allocateQueryId()
|
||||
conf := hctx.GetConf(ctx)
|
||||
rows, entries, err := getRows(ctx, conf.DisplayedColumns, shellName, conf.DefaultFilter, initialQuery, getNumEntriesNeeded(ctx))
|
||||
if err == nil || initialQuery == "" {
|
||||
p.Send(asyncQueryFinishedMsg{queryId: queryId, rows: rows, entries: entries, searchErr: err, forceUpdateTable: true, maintainCursor: false, overriddenSearchQuery: nil})
|
||||
rows, entries, err := getRows(ctx, conf.DisplayedColumns, shellName, conf.DefaultFilter, initialQueryWithEscaping, getNumEntriesNeeded(ctx))
|
||||
if err == nil || initialQueryWithEscaping == "" {
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
p.Send(asyncQueryFinishedMsg{queryId: queryId, rows: rows, entries: entries, searchErr: err, forceUpdateTable: true, maintainCursor: false, overriddenSearchQuery: nil, isFirstQuery: true})
|
||||
} else {
|
||||
// initialQuery is likely invalid in some way, let's just drop it
|
||||
// The initial query is likely invalid in some way, let's just drop it
|
||||
emptyQuery := ""
|
||||
rows, entries, err := getRows(ctx, hctx.GetConf(ctx).DisplayedColumns, shellName, conf.DefaultFilter, emptyQuery, getNumEntriesNeeded(ctx))
|
||||
p.Send(asyncQueryFinishedMsg{queryId: queryId, rows: rows, entries: entries, searchErr: err, forceUpdateTable: true, maintainCursor: false, overriddenSearchQuery: &emptyQuery})
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
p.Send(asyncQueryFinishedMsg{queryId: allocateQueryId(), rows: rows, entries: entries, searchErr: err, forceUpdateTable: true, maintainCursor: false, overriddenSearchQuery: &emptyQuery, isFirstQuery: true})
|
||||
}
|
||||
}()
|
||||
// Async: Retrieve additional entries from the backend
|
||||
@ -931,13 +985,13 @@ func TuiQuery(ctx context.Context, shellName, initialQuery string) error {
|
||||
p.Send(bannerMsg{banner: string(banner)})
|
||||
}()
|
||||
// Blocking: Start the TUI
|
||||
_, err := p.Run()
|
||||
_, err = p.Run()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if SELECTED_COMMAND == "" && os.Getenv("HISHTORY_TERM_INTEGRATION") != "" {
|
||||
// Print out the initialQuery instead so that we don't clear the terminal
|
||||
SELECTED_COMMAND = initialQuery
|
||||
// Print out the initialQuery instead so that we don't clear the terminal (note that we don't use the escaped one here)
|
||||
SELECTED_COMMAND = strings.Join(initialQueryArray, " ")
|
||||
}
|
||||
fmt.Printf("%s\n", SELECTED_COMMAND)
|
||||
return nil
|
||||
@ -945,4 +999,3 @@ func TuiQuery(ctx context.Context, shellName, initialQuery string) error {
|
||||
|
||||
// TODO: support custom key bindings
|
||||
// TODO: make the help page wrap
|
||||
// TODO: If the initial query contains dashes, maybe we should smartly escape them?
|
||||
|
Loading…
Reference in New Issue
Block a user