mirror of
https://github.com/ddworken/hishtory.git
synced 2024-11-25 01:33:28 +01:00
Merge branch 'master' into quote-init
This commit is contained in:
commit
15bc95c560
17
README.md
17
README.md
@ -159,8 +159,8 @@ hishtory config-set filter-duplicate-commands true
|
|||||||
|
|
||||||
If you don't need the ability to sync your shell history, you can install hiSHtory in offline mode:
|
If you don't need the ability to sync your shell history, you can install hiSHtory in offline mode:
|
||||||
|
|
||||||
```
|
```sh
|
||||||
curl https://hishtory.dev/install.py | HISHTORY_OFFLINE=true python3 -
|
curl https://hishtory.dev/install.py | python3 - --offline
|
||||||
```
|
```
|
||||||
|
|
||||||
This disables syncing completely so that the client will not rely on the hiSHtory backend at all. You can also change the syncing status via `hishtory syncing enable` or `hishtory syncing disable`.
|
This disables syncing completely so that the client will not rely on the hiSHtory backend at all. You can also change the syncing status via `hishtory syncing enable` or `hishtory syncing disable`.
|
||||||
@ -199,6 +199,19 @@ You can configure a custom timestamp format for hiSHtory via `hishtory config-se
|
|||||||
|
|
||||||
</blockquote></details>
|
</blockquote></details>
|
||||||
|
|
||||||
|
<details>
|
||||||
|
<summary>Custom rendering</summary><blockquote>
|
||||||
|
|
||||||
|
By default, hiHStory tries to render the TUI in a reasonable way that balances terminal space consumption and TUI usability. If you find that you wish to customize this behavior, there are two config options that you can experiment with enabling:
|
||||||
|
|
||||||
|
```
|
||||||
|
hishtory config-set compact-mode true # Renders the TUI in "compact mode" with less whitespace
|
||||||
|
hishtory config-set full-screen true # Renders the TUI in "full-screen mode" so that it uses the entire terminal
|
||||||
|
```
|
||||||
|
|
||||||
|
</blockquote></details>
|
||||||
|
|
||||||
|
|
||||||
<details>
|
<details>
|
||||||
<summary>Web UI for sharing</summary><blockquote>
|
<summary>Web UI for sharing</summary><blockquote>
|
||||||
|
|
||||||
|
@ -53,6 +53,9 @@ os.system('chmod +x ' + tmpFilePath)
|
|||||||
cmd = tmpFilePath + ' install'
|
cmd = tmpFilePath + ' install'
|
||||||
if os.environ.get('HISHTORY_OFFLINE'):
|
if os.environ.get('HISHTORY_OFFLINE'):
|
||||||
cmd += " --offline"
|
cmd += " --offline"
|
||||||
|
additional_flags = [flag for flag in sys.argv[1:] if flag.startswith("-") and flag != "-" and flag != "--"]
|
||||||
|
if additional_flags:
|
||||||
|
cmd += " " + " ".join(additional_flags)
|
||||||
exitCode = os.system(cmd)
|
exitCode = os.system(cmd)
|
||||||
os.remove(tmpFilePath)
|
os.remove(tmpFilePath)
|
||||||
if exitCode != 0:
|
if exitCode != 0:
|
||||||
|
@ -119,6 +119,7 @@ func TestParam(t *testing.T) {
|
|||||||
t.Run("testTui/ai", wrapTestForSharding(testTui_ai))
|
t.Run("testTui/ai", wrapTestForSharding(testTui_ai))
|
||||||
t.Run("testTui/defaultFilter", wrapTestForSharding(testTui_defaultFilter))
|
t.Run("testTui/defaultFilter", wrapTestForSharding(testTui_defaultFilter))
|
||||||
t.Run("testTui/escaping", wrapTestForSharding(testTui_escaping))
|
t.Run("testTui/escaping", wrapTestForSharding(testTui_escaping))
|
||||||
|
t.Run("testTui/fullscreen", wrapTestForSharding(testTui_fullscreen))
|
||||||
|
|
||||||
// Assert there are no leaked connections
|
// Assert there are no leaked connections
|
||||||
assertNoLeakedConnections(t)
|
assertNoLeakedConnections(t)
|
||||||
@ -838,13 +839,13 @@ func testHishtoryBackgroundSaving(t *testing.T, tester shellTester) {
|
|||||||
// Setup
|
// Setup
|
||||||
defer testutils.BackupAndRestore(t)()
|
defer testutils.BackupAndRestore(t)()
|
||||||
|
|
||||||
// Check that we can find the go binary
|
// Check that we can find the go binary and use that path to it for consistency
|
||||||
_, err := exec.LookPath("go")
|
goBinPath, err := exec.LookPath("go")
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
// Test install with an unset HISHTORY_TEST var so that we save in the background (this is likely to be flakey!)
|
// Test install with an unset HISHTORY_TEST var so that we save in the background (this is likely to be flakey!)
|
||||||
out := tester.RunInteractiveShell(t, `unset HISHTORY_TEST
|
out := tester.RunInteractiveShell(t, `unset HISHTORY_TEST
|
||||||
CGO_ENABLED=0 go build -o /tmp/client
|
CGO_ENABLED=0 `+goBinPath+` build -o /tmp/client
|
||||||
/tmp/client install`)
|
/tmp/client install`)
|
||||||
r := regexp.MustCompile(`Setting secret hishtory key to (.*)`)
|
r := regexp.MustCompile(`Setting secret hishtory key to (.*)`)
|
||||||
matches := r.FindStringSubmatch(out)
|
matches := r.FindStringSubmatch(out)
|
||||||
@ -1063,18 +1064,16 @@ func TestInstallViaPythonScriptWithCustomHishtoryPath(t *testing.T) {
|
|||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.NoError(t, os.RemoveAll(path.Join(homedir, altHishtoryPath)))
|
require.NoError(t, os.RemoveAll(path.Join(homedir, altHishtoryPath)))
|
||||||
|
|
||||||
testInstallViaPythonScriptChild(t, zshTester{})
|
testInstallViaPythonScriptChild(t, zshTester{}, Online)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestInstallViaPythonScriptInOfflineMode(t *testing.T) {
|
func TestInstallViaPythonScriptInOfflineMode(t *testing.T) {
|
||||||
markTestForSharding(t, 1)
|
markTestForSharding(t, 1)
|
||||||
defer testutils.BackupAndRestore(t)()
|
defer testutils.BackupAndRestore(t)()
|
||||||
defer testutils.BackupAndRestoreEnv("HISHTORY_OFFLINE")()
|
|
||||||
os.Setenv("HISHTORY_OFFLINE", "1")
|
|
||||||
tester := zshTester{}
|
tester := zshTester{}
|
||||||
|
|
||||||
// Check that installing works
|
// Check that installing works
|
||||||
testInstallViaPythonScriptChild(t, tester)
|
testInstallViaPythonScriptChild(t, tester, Offline)
|
||||||
|
|
||||||
// And check that it installed in offline mode
|
// And check that it installed in offline mode
|
||||||
out := tester.RunInteractiveShell(t, `hishtory status -v`)
|
out := tester.RunInteractiveShell(t, `hishtory status -v`)
|
||||||
@ -1083,14 +1082,14 @@ func TestInstallViaPythonScriptInOfflineMode(t *testing.T) {
|
|||||||
|
|
||||||
func testInstallViaPythonScript(t *testing.T, tester shellTester) {
|
func testInstallViaPythonScript(t *testing.T, tester shellTester) {
|
||||||
defer testutils.BackupAndRestore(t)()
|
defer testutils.BackupAndRestore(t)()
|
||||||
testInstallViaPythonScriptChild(t, tester)
|
testInstallViaPythonScriptChild(t, tester, Online)
|
||||||
|
|
||||||
// And check that it installed in online mode
|
// And check that it installed in online mode
|
||||||
out := tester.RunInteractiveShell(t, `hishtory status -v`)
|
out := tester.RunInteractiveShell(t, `hishtory status -v`)
|
||||||
require.Contains(t, out, "\nSync Mode: Enabled\n")
|
require.Contains(t, out, "\nSync Mode: Enabled\n")
|
||||||
}
|
}
|
||||||
|
|
||||||
func testInstallViaPythonScriptChild(t *testing.T, tester shellTester) {
|
func testInstallViaPythonScriptChild(t *testing.T, tester shellTester, onlineStatus OnlineStatus) {
|
||||||
if !testutils.IsOnline() {
|
if !testutils.IsOnline() {
|
||||||
t.Skip("skipping because we're currently offline")
|
t.Skip("skipping because we're currently offline")
|
||||||
}
|
}
|
||||||
@ -1099,7 +1098,11 @@ func testInstallViaPythonScriptChild(t *testing.T, tester shellTester) {
|
|||||||
defer testutils.BackupAndRestoreEnv("HISHTORY_TEST")()
|
defer testutils.BackupAndRestoreEnv("HISHTORY_TEST")()
|
||||||
|
|
||||||
// Install via the python script
|
// Install via the python script
|
||||||
out := tester.RunInteractiveShell(t, `curl https://hishtory.dev/install.py | python3 -`)
|
additionalFlags := " "
|
||||||
|
if onlineStatus == Offline {
|
||||||
|
additionalFlags = "--offline"
|
||||||
|
}
|
||||||
|
out := tester.RunInteractiveShell(t, `curl https://hishtory.dev/install.py | python3 - `+additionalFlags)
|
||||||
require.Contains(t, out, "Succesfully installed hishtory")
|
require.Contains(t, out, "Succesfully installed hishtory")
|
||||||
r := regexp.MustCompile(`Setting secret hishtory key to (.*)`)
|
r := regexp.MustCompile(`Setting secret hishtory key to (.*)`)
|
||||||
matches := r.FindStringSubmatch(out)
|
matches := r.FindStringSubmatch(out)
|
||||||
@ -1869,6 +1872,54 @@ func testTui_escaping(t *testing.T) {
|
|||||||
testutils.CompareGoldens(t, out, "TestTui-Escaping")
|
testutils.CompareGoldens(t, out, "TestTui-Escaping")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func testTui_fullscreen(t *testing.T) {
|
||||||
|
// Setup
|
||||||
|
defer testutils.BackupAndRestore(t)()
|
||||||
|
tester, _, _ := setupTestTui(t, Online)
|
||||||
|
|
||||||
|
// By default full-screen mode is disabled
|
||||||
|
require.Equal(t, "false", strings.TrimSpace(tester.RunInteractiveShell(t, `hishtory config-get full-screen`)))
|
||||||
|
require.Equal(t, "false", strings.TrimSpace(tester.RunInteractiveShell(t, `hishtory config-get compact-mode`)))
|
||||||
|
|
||||||
|
// Test that we can enable it
|
||||||
|
tester.RunInteractiveShell(t, `hishtory config-set full-screen true`)
|
||||||
|
require.Equal(t, "true", strings.TrimSpace(tester.RunInteractiveShell(t, `hishtory config-get full-screen`)))
|
||||||
|
|
||||||
|
// Test that it renders in full-screen mode taking up the entire terminal
|
||||||
|
out := captureTerminalOutput(t, tester, []string{
|
||||||
|
"echo foo ENTER",
|
||||||
|
"hishtory SPACE tquery ENTER",
|
||||||
|
})
|
||||||
|
testutils.CompareGoldens(t, out, "TestTui-FullScreenRender")
|
||||||
|
|
||||||
|
// Test that it clears full-screen mode and restores the original terminal state
|
||||||
|
out = captureTerminalOutput(t, tester, []string{
|
||||||
|
"echo SPACE foo ENTER",
|
||||||
|
"hishtory SPACE tquery ENTER",
|
||||||
|
"Escape",
|
||||||
|
})
|
||||||
|
require.Contains(t, out, "echo foo\n")
|
||||||
|
require.Contains(t, out, "hishtory tquery\n")
|
||||||
|
require.NotContains(t, out, "Search Query")
|
||||||
|
require.True(t, len(strings.Split(out, "\n")) <= 7)
|
||||||
|
|
||||||
|
// Test that it renders the help page fine
|
||||||
|
out = captureTerminalOutput(t, tester, []string{
|
||||||
|
"echo SPACE foo ENTER",
|
||||||
|
"hishtory SPACE tquery ENTER",
|
||||||
|
"C-h",
|
||||||
|
})
|
||||||
|
testutils.CompareGoldens(t, out, "TestTui-FullScreenHelp")
|
||||||
|
|
||||||
|
// Test that it renders fine in full-screen mode and compact-mode
|
||||||
|
tester.RunInteractiveShell(t, `hishtory config-set compact-mode true`)
|
||||||
|
out = captureTerminalOutput(t, tester, []string{
|
||||||
|
"echo foo ENTER",
|
||||||
|
"hishtory SPACE tquery ENTER",
|
||||||
|
})
|
||||||
|
testutils.CompareGoldens(t, out, "TestTui-FullScreenCompactRender")
|
||||||
|
}
|
||||||
|
|
||||||
func testTui_defaultFilter(t *testing.T) {
|
func testTui_defaultFilter(t *testing.T) {
|
||||||
// Setup
|
// Setup
|
||||||
defer testutils.BackupAndRestore(t)()
|
defer testutils.BackupAndRestore(t)()
|
||||||
|
@ -184,6 +184,7 @@ func init() {
|
|||||||
configGetCmd.AddCommand(getAiCompletionEndpoint)
|
configGetCmd.AddCommand(getAiCompletionEndpoint)
|
||||||
configGetCmd.AddCommand(getCompactMode)
|
configGetCmd.AddCommand(getCompactMode)
|
||||||
configGetCmd.AddCommand(getLogLevelCmd)
|
configGetCmd.AddCommand(getLogLevelCmd)
|
||||||
|
configGetCmd.AddCommand(getFullScreenCmd)
|
||||||
}
|
}
|
||||||
|
|
||||||
var getLogLevelCmd = &cobra.Command{
|
var getLogLevelCmd = &cobra.Command{
|
||||||
@ -195,3 +196,13 @@ var getLogLevelCmd = &cobra.Command{
|
|||||||
fmt.Println(config.LogLevel.String())
|
fmt.Println(config.LogLevel.String())
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var getFullScreenCmd = &cobra.Command{
|
||||||
|
Use: "full-screen",
|
||||||
|
Short: "Get whether or not hishtory is configured to run in full-screen mode",
|
||||||
|
Run: func(cmd *cobra.Command, args []string) {
|
||||||
|
ctx := hctx.MakeContext()
|
||||||
|
config := hctx.GetConf(ctx)
|
||||||
|
fmt.Println(config.FullScreenRendering)
|
||||||
|
},
|
||||||
|
}
|
||||||
|
@ -262,6 +262,19 @@ var setLogLevelCmd = &cobra.Command{
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var setFullScreenCmd = &cobra.Command{
|
||||||
|
Use: "full-screen",
|
||||||
|
Short: "Configure whether or not hishtory is configured to run in full-screen mode",
|
||||||
|
Args: cobra.MatchAll(cobra.ExactArgs(1), cobra.OnlyValidArgs),
|
||||||
|
ValidArgs: []string{"true", "false"},
|
||||||
|
Run: func(cmd *cobra.Command, args []string) {
|
||||||
|
ctx := hctx.MakeContext()
|
||||||
|
config := hctx.GetConf(ctx)
|
||||||
|
config.FullScreenRendering = args[0] == "true"
|
||||||
|
lib.CheckFatalError(hctx.SetConfig(config))
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
rootCmd.AddCommand(configSetCmd)
|
rootCmd.AddCommand(configSetCmd)
|
||||||
configSetCmd.AddCommand(setEnableControlRCmd)
|
configSetCmd.AddCommand(setEnableControlRCmd)
|
||||||
@ -277,6 +290,7 @@ func init() {
|
|||||||
configSetCmd.AddCommand(setAiCompletionEndpoint)
|
configSetCmd.AddCommand(setAiCompletionEndpoint)
|
||||||
configSetCmd.AddCommand(compactMode)
|
configSetCmd.AddCommand(compactMode)
|
||||||
configSetCmd.AddCommand(setLogLevelCmd)
|
configSetCmd.AddCommand(setLogLevelCmd)
|
||||||
|
configSetCmd.AddCommand(setFullScreenCmd)
|
||||||
setColorSchemeCmd.AddCommand(setColorSchemeSelectedText)
|
setColorSchemeCmd.AddCommand(setColorSchemeSelectedText)
|
||||||
setColorSchemeCmd.AddCommand(setColorSchemeSelectedBackground)
|
setColorSchemeCmd.AddCommand(setColorSchemeSelectedBackground)
|
||||||
setColorSchemeCmd.AddCommand(setColorSchemeBorderColor)
|
setColorSchemeCmd.AddCommand(setColorSchemeBorderColor)
|
||||||
|
@ -42,6 +42,9 @@ var installCmd = &cobra.Command{
|
|||||||
if len(args) > 0 {
|
if len(args) > 0 {
|
||||||
secretKey = args[0]
|
secretKey = args[0]
|
||||||
}
|
}
|
||||||
|
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))
|
||||||
if os.Getenv("HISHTORY_SKIP_INIT_IMPORT") == "" {
|
if os.Getenv("HISHTORY_SKIP_INIT_IMPORT") == "" {
|
||||||
db, err := hctx.OpenLocalSqliteDb()
|
db, err := hctx.OpenLocalSqliteDb()
|
||||||
|
@ -221,6 +221,8 @@ type ClientConfig struct {
|
|||||||
KeyBindings keybindings.SerializableKeyMap `json:"key_bindings"`
|
KeyBindings keybindings.SerializableKeyMap `json:"key_bindings"`
|
||||||
// The log level for hishtory (e.g., "debug", "info", "warn", "error")
|
// The log level for hishtory (e.g., "debug", "info", "warn", "error")
|
||||||
LogLevel logrus.Level `json:"log_level"`
|
LogLevel logrus.Level `json:"log_level"`
|
||||||
|
// Whether the TUI should render in full-screen mode
|
||||||
|
FullScreenRendering bool `json:"full_screen_rendering"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type ColorScheme struct {
|
type ColorScheme struct {
|
||||||
|
@ -46,7 +46,7 @@ function __hishtory_postcommand() {
|
|||||||
|
|
||||||
if [ -n "${HISHTORY_FIRST_PROMPT:-}" ]; then
|
if [ -n "${HISHTORY_FIRST_PROMPT:-}" ]; then
|
||||||
unset HISHTORY_FIRST_PROMPT
|
unset HISHTORY_FIRST_PROMPT
|
||||||
return
|
return $EXIT_CODE
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Run after every prompt
|
# Run after every prompt
|
||||||
@ -57,6 +57,8 @@ function __hishtory_postcommand() {
|
|||||||
LAST_SAVED_COMMAND=$CMD
|
LAST_SAVED_COMMAND=$CMD
|
||||||
|
|
||||||
(hishtory updateLocalDbFromRemote &)
|
(hishtory updateLocalDbFromRemote &)
|
||||||
|
|
||||||
|
return $EXIT_CODE
|
||||||
}
|
}
|
||||||
PROMPT_COMMAND="__hishtory_postcommand; $PROMPT_COMMAND"
|
PROMPT_COMMAND="__hishtory_postcommand; $PROMPT_COMMAND"
|
||||||
export HISTTIMEFORMAT=$HISTTIMEFORMAT
|
export HISTTIMEFORMAT=$HISTTIMEFORMAT
|
||||||
|
40
client/testdata/TestTui-FullScreenCompactRender
vendored
Normal file
40
client/testdata/TestTui-FullScreenCompactRender
vendored
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
Search Query: > ls
|
||||||
|
┌────────────────────────────────────────────────────────────────────────────────────────────────────────┐
|
||||||
|
│ Hostname CWD Timestamp Runtime Exit Code Command │
|
||||||
|
│────────────────────────────────────────────────────────────────────────────────────────────────────────│
|
||||||
|
│ localhost /tmp/ Oct 17 2022 21:43:21 PDT 3s 2 echo 'aaaaaa bbbb' │
|
||||||
|
│ localhost /tmp/ Oct 17 2022 21:43:16 PDT 3s 2 ls ~/ │
|
||||||
|
│ │
|
||||||
|
│ │
|
||||||
|
│ │
|
||||||
|
│ │
|
||||||
|
│ │
|
||||||
|
│ │
|
||||||
|
│ │
|
||||||
|
│ │
|
||||||
|
│ │
|
||||||
|
│ │
|
||||||
|
│ │
|
||||||
|
│ │
|
||||||
|
│ │
|
||||||
|
│ │
|
||||||
|
│ │
|
||||||
|
│ │
|
||||||
|
│ │
|
||||||
|
│ │
|
||||||
|
│ │
|
||||||
|
│ │
|
||||||
|
│ │
|
||||||
|
│ │
|
||||||
|
│ │
|
||||||
|
│ │
|
||||||
|
│ │
|
||||||
|
│ │
|
||||||
|
│ │
|
||||||
|
│ │
|
||||||
|
│ │
|
||||||
|
│ │
|
||||||
|
│ │
|
||||||
|
│ │
|
||||||
|
│ │
|
||||||
|
└────────────────────────────────────────────────────────────────────────────────────────────────────────┘
|
46
client/testdata/TestTui-FullScreenHelp
vendored
Normal file
46
client/testdata/TestTui-FullScreenHelp
vendored
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
Search Query: > ls
|
||||||
|
|
||||||
|
┌────────────────────────────────────────────────────────────────────────────────────────────────────────┐
|
||||||
|
│ Hostname CWD Timestamp Runtime Exit Code Command │
|
||||||
|
│────────────────────────────────────────────────────────────────────────────────────────────────────────│
|
||||||
|
│ localhost /tmp/ Oct 17 2022 21:43:21 PDT 3s 2 echo 'aaaaaa bbbb' │
|
||||||
|
│ localhost /tmp/ Oct 17 2022 21:43:16 PDT 3s 2 ls ~/ │
|
||||||
|
│ │
|
||||||
|
│ │
|
||||||
|
│ │
|
||||||
|
│ │
|
||||||
|
│ │
|
||||||
|
│ │
|
||||||
|
│ │
|
||||||
|
│ │
|
||||||
|
│ │
|
||||||
|
│ │
|
||||||
|
│ │
|
||||||
|
│ │
|
||||||
|
│ │
|
||||||
|
│ │
|
||||||
|
│ │
|
||||||
|
│ │
|
||||||
|
│ │
|
||||||
|
│ │
|
||||||
|
│ │
|
||||||
|
│ │
|
||||||
|
│ │
|
||||||
|
│ │
|
||||||
|
│ │
|
||||||
|
│ │
|
||||||
|
│ │
|
||||||
|
│ │
|
||||||
|
│ │
|
||||||
|
│ │
|
||||||
|
│ │
|
||||||
|
│ │
|
||||||
|
│ │
|
||||||
|
│ │
|
||||||
|
│ │
|
||||||
|
└────────────────────────────────────────────────────────────────────────────────────────────────────────┘
|
||||||
|
hiSHtory: Search your shell history
|
||||||
|
↑ scroll up ↓ scroll down pgup page up pgdn page down
|
||||||
|
← move left → move right shift+← scroll the table left shift+→ scroll the table right
|
||||||
|
enter select an entry ctrl+k delete the highlighted entry esc exit hiSHtory ctrl+h help
|
||||||
|
ctrl+x select an entry and cd into that directory
|
42
client/testdata/TestTui-FullScreenRender
vendored
Normal file
42
client/testdata/TestTui-FullScreenRender
vendored
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
Search Query: > ls
|
||||||
|
|
||||||
|
┌────────────────────────────────────────────────────────────────────────────────────────────────────────┐
|
||||||
|
│ Hostname CWD Timestamp Runtime Exit Code Command │
|
||||||
|
│────────────────────────────────────────────────────────────────────────────────────────────────────────│
|
||||||
|
│ localhost /tmp/ Oct 17 2022 21:43:21 PDT 3s 2 echo 'aaaaaa bbbb' │
|
||||||
|
│ localhost /tmp/ Oct 17 2022 21:43:16 PDT 3s 2 ls ~/ │
|
||||||
|
│ │
|
||||||
|
│ │
|
||||||
|
│ │
|
||||||
|
│ │
|
||||||
|
│ │
|
||||||
|
│ │
|
||||||
|
│ │
|
||||||
|
│ │
|
||||||
|
│ │
|
||||||
|
│ │
|
||||||
|
│ │
|
||||||
|
│ │
|
||||||
|
│ │
|
||||||
|
│ │
|
||||||
|
│ │
|
||||||
|
│ │
|
||||||
|
│ │
|
||||||
|
│ │
|
||||||
|
│ │
|
||||||
|
│ │
|
||||||
|
│ │
|
||||||
|
│ │
|
||||||
|
│ │
|
||||||
|
│ │
|
||||||
|
│ │
|
||||||
|
│ │
|
||||||
|
│ │
|
||||||
|
│ │
|
||||||
|
│ │
|
||||||
|
│ │
|
||||||
|
│ │
|
||||||
|
│ │
|
||||||
|
│ │
|
||||||
|
└────────────────────────────────────────────────────────────────────────────────────────────────────────┘
|
||||||
|
hiSHtory: Search your shell history • ctrl+h help
|
@ -30,11 +30,6 @@ import (
|
|||||||
"golang.org/x/term"
|
"golang.org/x/term"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
|
||||||
TABLE_HEIGHT = 20
|
|
||||||
PADDED_NUM_ENTRIES = TABLE_HEIGHT * 5
|
|
||||||
)
|
|
||||||
|
|
||||||
var (
|
var (
|
||||||
CURRENT_QUERY_FOR_HIGHLIGHTING string = ""
|
CURRENT_QUERY_FOR_HIGHLIGHTING string = ""
|
||||||
SELECTED_COMMAND string = ""
|
SELECTED_COMMAND string = ""
|
||||||
@ -225,7 +220,7 @@ func runQueryAndUpdateTable(m model, forceUpdateTable, maintainCursor bool) tea.
|
|||||||
// The default filter was cleared for this session, so don't apply it
|
// The default filter was cleared for this session, so don't apply it
|
||||||
defaultFilter = ""
|
defaultFilter = ""
|
||||||
}
|
}
|
||||||
rows, entries, searchErr := getRows(m.ctx, conf.DisplayedColumns, m.shellName, defaultFilter, query, PADDED_NUM_ENTRIES)
|
rows, entries, searchErr := getRows(m.ctx, conf.DisplayedColumns, m.shellName, defaultFilter, query, getNumEntriesNeeded(m.ctx))
|
||||||
return asyncQueryFinishedMsg{queryId, rows, entries, searchErr, forceUpdateTable, maintainCursor, nil, false}
|
return asyncQueryFinishedMsg{queryId, rows, entries, searchErr, forceUpdateTable, maintainCursor, nil, false}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -467,7 +462,7 @@ func getBaseStyle(config hctx.ClientConfig) lipgloss.Style {
|
|||||||
|
|
||||||
func renderNullableTable(m model, helpText string) string {
|
func renderNullableTable(m model, helpText string) string {
|
||||||
if m.table == nil {
|
if m.table == nil {
|
||||||
return strings.Repeat("\n", TABLE_HEIGHT+3)
|
return strings.Repeat("\n", getTableHeight(m.ctx)+3)
|
||||||
}
|
}
|
||||||
helpTextLen := strings.Count(helpText, "\n")
|
helpTextLen := strings.Count(helpText, "\n")
|
||||||
baseStyle := getBaseStyle(*hctx.GetConf(m.ctx))
|
baseStyle := getBaseStyle(*hctx.GetConf(m.ctx))
|
||||||
@ -666,6 +661,25 @@ func min(a, b int) int {
|
|||||||
return b
|
return b
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func getTableHeight(ctx context.Context) int {
|
||||||
|
config := hctx.GetConf(ctx)
|
||||||
|
if config.FullScreenRendering {
|
||||||
|
_, terminalHeight, err := getTerminalSize()
|
||||||
|
if err != nil {
|
||||||
|
// A reasonable guess at a default if for some reason we fail to retrieve the terminal size
|
||||||
|
return 30
|
||||||
|
}
|
||||||
|
return max(terminalHeight-15, 20)
|
||||||
|
}
|
||||||
|
// Default to 20 when not full-screen since we want to balance showing a large table with not using the entire screen
|
||||||
|
return 20
|
||||||
|
}
|
||||||
|
|
||||||
|
func getNumEntriesNeeded(ctx context.Context) int {
|
||||||
|
// Get more than table height since the TUI filters some out (e.g. duplicate entries)
|
||||||
|
return getTableHeight(ctx) * 5
|
||||||
|
}
|
||||||
|
|
||||||
func makeTable(ctx context.Context, shellName string, rows []table.Row) (table.Model, error) {
|
func makeTable(ctx context.Context, shellName string, rows []table.Row) (table.Model, error) {
|
||||||
config := hctx.GetConf(ctx)
|
config := hctx.GetConf(ctx)
|
||||||
columns, err := makeTableColumns(ctx, shellName, config.DisplayedColumns, rows)
|
columns, err := makeTableColumns(ctx, shellName, config.DisplayedColumns, rows)
|
||||||
@ -699,7 +713,7 @@ func makeTable(ctx context.Context, shellName string, rows []table.Row) (table.M
|
|||||||
if isExtraCompactHeightMode(ctx) {
|
if isExtraCompactHeightMode(ctx) {
|
||||||
tuiSize -= 3
|
tuiSize -= 3
|
||||||
}
|
}
|
||||||
tableHeight := min(TABLE_HEIGHT, terminalHeight-tuiSize)
|
tableHeight := min(getTableHeight(ctx), terminalHeight-tuiSize)
|
||||||
t := table.New(
|
t := table.New(
|
||||||
table.WithColumns(columns),
|
table.WithColumns(columns),
|
||||||
table.WithRows(rows),
|
table.WithRows(rows),
|
||||||
@ -918,12 +932,16 @@ func TuiQuery(ctx context.Context, shellName string, initialQueryArray []string)
|
|||||||
}
|
}
|
||||||
loadedKeyBindings = hctx.GetConf(ctx).KeyBindings.ToKeyMap()
|
loadedKeyBindings = hctx.GetConf(ctx).KeyBindings.ToKeyMap()
|
||||||
configureColorProfile(ctx)
|
configureColorProfile(ctx)
|
||||||
p := tea.NewProgram(initialModel(ctx, shellName, initialQueryWithEscaping), tea.WithOutput(os.Stderr))
|
additionalOptions := []tea.ProgramOption{tea.WithOutput(os.Stderr)}
|
||||||
|
if hctx.GetConf(ctx).FullScreenRendering {
|
||||||
|
additionalOptions = append(additionalOptions, tea.WithAltScreen())
|
||||||
|
}
|
||||||
|
p := tea.NewProgram(initialModel(ctx, shellName, initialQueryWithEscaping), additionalOptions...)
|
||||||
// Async: Get the initial set of rows
|
// Async: Get the initial set of rows
|
||||||
go func() {
|
go func() {
|
||||||
queryId := allocateQueryId()
|
queryId := allocateQueryId()
|
||||||
conf := hctx.GetConf(ctx)
|
conf := hctx.GetConf(ctx)
|
||||||
rows, entries, err := getRows(ctx, conf.DisplayedColumns, shellName, conf.DefaultFilter, initialQueryWithEscaping, PADDED_NUM_ENTRIES)
|
rows, entries, err := getRows(ctx, conf.DisplayedColumns, shellName, conf.DefaultFilter, initialQueryWithEscaping, getNumEntriesNeeded(ctx))
|
||||||
if err == nil || initialQueryWithEscaping == "" {
|
if err == nil || initialQueryWithEscaping == "" {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
@ -932,7 +950,7 @@ func TuiQuery(ctx context.Context, shellName string, initialQueryArray []string)
|
|||||||
} else {
|
} else {
|
||||||
// The initial query 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 := ""
|
emptyQuery := ""
|
||||||
rows, entries, err := getRows(ctx, hctx.GetConf(ctx).DisplayedColumns, shellName, conf.DefaultFilter, emptyQuery, PADDED_NUM_ENTRIES)
|
rows, entries, err := getRows(ctx, hctx.GetConf(ctx).DisplayedColumns, shellName, conf.DefaultFilter, emptyQuery, getNumEntriesNeeded(ctx))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user