From 830cd8405155c441dac95a7c4db07166f2a48ff7 Mon Sep 17 00:00:00 2001 From: Filippo Trotter Date: Tue, 9 Jul 2024 17:49:11 +0200 Subject: [PATCH 1/3] allow to specify the port --- cmd/root.go | 2 ++ cmd/server.go | 6 ++++-- utils/server/server.go | 4 ++-- 3 files changed, 8 insertions(+), 4 deletions(-) diff --git a/cmd/root.go b/cmd/root.go index ceab267..7cdfea2 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -62,11 +62,13 @@ func init() { rootCmd.PersistentFlags().StringVarP(&inputFlag.EndLabel, "end-label", "e", "", "pass argument to end-label to modify lines up to end-label") rootCmd.PersistentFlags().StringVarP(&inputFlag.Lang, "language", "L", "", "pass argument to language to specify the language of the input code") rootCmd.PersistentFlags().StringVarP(&remotePath, "remote", "w", "", "pass remote user, host, and directory in the format user@host:/path/to/directory") + rootCmd.PersistentFlags().StringVarP(&port, "port", "p", "2222", "Specify the port number to use for connecting to the server. This option allows you to override the default port, which 2222.") rootCmd.PersistentFlags().BoolVarP(&Tui, "tui", "t", false, "run the terminal user interface") // Mark flags based on command name rootCmd.PersistentPreRunE = func(cmd *cobra.Command, args []string) error { if cmd.Name() != "server" { cmd.MarkFlagsRequiredTogether("start-label", "end-label") + cmd.MarkFlagsRequiredTogether("remote", "port") cmd.MarkFlagsMutuallyExclusive("line", "start-label") cmd.MarkFlagsMutuallyExclusive("line", "end-label") cmd.MarkFlagsOneRequired("file", "language", "remote", "tui") diff --git a/cmd/server.go b/cmd/server.go index 48e2b19..b1a94bc 100644 --- a/cmd/server.go +++ b/cmd/server.go @@ -23,11 +23,13 @@ var serverCmd = &cobra.Command{ Short: "Start the SSH server", Long: `Start the SSH server that allows remote interactions with tgcom.`, Run: func(cmd *cobra.Command, args []string) { - server.StartServer() + server.StartServer(port) }, } +var port string func init() { + serverCmd.PersistentFlags().StringVarP(&port, "port", "p", "2222", "Specify the port number to use for connecting to the server. This option allows you to override the default port, which 2222.") // Register the server command rootCmd.AddCommand(serverCmd) } @@ -50,7 +52,7 @@ func executeRemoteCommand(remotePath string) { dir := pathParts[1] sshCmd := "ssh" - sshArgs := []string{"-t", "-p", "2222", userHost + "@" + host, "tgcom", dir} + sshArgs := []string{"-t", "-p", port, userHost + "@" + host, "tgcom", dir} // Start SSH command with PTY if err := startSSHWithPTY(sshCmd, sshArgs); err != nil { diff --git a/utils/server/server.go b/utils/server/server.go index ea7defd..e95a7f9 100644 --- a/utils/server/server.go +++ b/utils/server/server.go @@ -31,13 +31,13 @@ var ( dir string ) -func StartServer() { +func StartServer(port string) { withHostKey := wish.WithHostKeyPath(pathHostKey) if pem, ok := os.LookupEnv(envHostKey); ok { withHostKey = wish.WithHostKeyPEM([]byte(pem)) } srv, err := wish.NewServer( - wish.WithAddress(":2222"), + wish.WithAddress(":"+port), wish.WithMiddleware( bm.Middleware(func(s ssh.Session) (tea.Model, []tea.ProgramOption) { pty, _, _ := s.Pty() From 49a8376209cbd2f3b5d091e2ceb0556d8a87925c Mon Sep 17 00:00:00 2001 From: Filippo Trotter Date: Wed, 10 Jul 2024 16:43:57 +0200 Subject: [PATCH 2/3] feat: add ssh_config support --- cmd/root.go | 4 ++-- cmd/server.go | 57 ++++++++++++++++++++++++++++++++++++--------------- go.mod | 1 + go.sum | 2 ++ 4 files changed, 45 insertions(+), 19 deletions(-) diff --git a/cmd/root.go b/cmd/root.go index 7cdfea2..530cda0 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -21,6 +21,7 @@ var ( inputFlag modfile.Config remotePath string Tui bool + port string ) var rootCmd = &cobra.Command{ @@ -62,13 +63,12 @@ func init() { rootCmd.PersistentFlags().StringVarP(&inputFlag.EndLabel, "end-label", "e", "", "pass argument to end-label to modify lines up to end-label") rootCmd.PersistentFlags().StringVarP(&inputFlag.Lang, "language", "L", "", "pass argument to language to specify the language of the input code") rootCmd.PersistentFlags().StringVarP(&remotePath, "remote", "w", "", "pass remote user, host, and directory in the format user@host:/path/to/directory") - rootCmd.PersistentFlags().StringVarP(&port, "port", "p", "2222", "Specify the port number to use for connecting to the server. This option allows you to override the default port, which 2222.") + rootCmd.PersistentFlags().StringVarP(&port, "port", "p", "", "Specify the port number to use for connecting to the server. This option allows you to override the default port, which 2222.") rootCmd.PersistentFlags().BoolVarP(&Tui, "tui", "t", false, "run the terminal user interface") // Mark flags based on command name rootCmd.PersistentPreRunE = func(cmd *cobra.Command, args []string) error { if cmd.Name() != "server" { cmd.MarkFlagsRequiredTogether("start-label", "end-label") - cmd.MarkFlagsRequiredTogether("remote", "port") cmd.MarkFlagsMutuallyExclusive("line", "start-label") cmd.MarkFlagsMutuallyExclusive("line", "end-label") cmd.MarkFlagsOneRequired("file", "language", "remote", "tui") diff --git a/cmd/server.go b/cmd/server.go index b1a94bc..2097d0b 100644 --- a/cmd/server.go +++ b/cmd/server.go @@ -13,6 +13,7 @@ import ( "github.com/creack/pty" "github.com/dyne/tgcom/utils/server" + "github.com/kevinburke/ssh_config" "github.com/spf13/cobra" "golang.org/x/term" ) @@ -23,36 +24,58 @@ var serverCmd = &cobra.Command{ Short: "Start the SSH server", Long: `Start the SSH server that allows remote interactions with tgcom.`, Run: func(cmd *cobra.Command, args []string) { - server.StartServer(port) + server.StartServer(serverPort) }, } -var port string +var serverPort string func init() { - serverCmd.PersistentFlags().StringVarP(&port, "port", "p", "2222", "Specify the port number to use for connecting to the server. This option allows you to override the default port, which 2222.") + serverCmd.PersistentFlags().StringVarP(&serverPort, "port", "p", "2222", "Specify the port number to use for connecting to the server. This option allows you to override the default port, which 2222.") // Register the server command rootCmd.AddCommand(serverCmd) } func executeRemoteCommand(remotePath string) { - parts := strings.SplitN(remotePath, "@", 2) - if len(parts) != 2 { - fmt.Println("Invalid format. Usage: tgcom -w user@remote:/path/folder") - os.Exit(1) - } + var userHost, dir, sshPort string + + if strings.Contains(remotePath, ":") && !strings.Contains(remotePath, "@") { + // Using SSH config alias format + parts := strings.SplitN(remotePath, ":", 2) + if len(parts) != 2 { + fmt.Println("Invalid format. Usage: tgcom config:path/to/folder") + os.Exit(1) + } + configAlias := parts[0] + dir = parts[1] - userHost := parts[0] - pathParts := strings.SplitN(parts[1], ":", 2) - if len(pathParts) != 2 { - fmt.Println("Invalid format. Usage: tgcom -w user@remote:/path/folder") - os.Exit(1) - } + userHost = configAlias + sshPort = ssh_config.Get(configAlias, "Port") + if sshPort == "" { + sshPort = port + } + } else { + // Using user@host:/path format + parts := strings.SplitN(remotePath, "@", 2) + if len(parts) != 2 { + fmt.Println("Invalid format. Usage: tgcom -w user@remote:/path/folder or tgcom config:path/to/folder") + os.Exit(1) + } + + userHost = parts[0] + pathParts := strings.SplitN(parts[1], ":", 2) + if len(pathParts) != 2 { + fmt.Println("Invalid format. Usage: tgcom -w user@remote:/path/folder or tgcom config:path/to/folder") + os.Exit(1) + } - host := pathParts[0] - dir := pathParts[1] + host := pathParts[0] + dir = pathParts[1] + sshPort = port + userHost = fmt.Sprintf("%s@%s", userHost, host) + } sshCmd := "ssh" - sshArgs := []string{"-t", "-p", port, userHost + "@" + host, "tgcom", dir} + sshArgs := []string{"-t", "-p", sshPort, userHost, "tgcom", dir} // Start SSH command with PTY if err := startSSHWithPTY(sshCmd, sshArgs); err != nil { diff --git a/go.mod b/go.mod index 17a8928..44142f0 100644 --- a/go.mod +++ b/go.mod @@ -9,6 +9,7 @@ require ( github.com/charmbracelet/ssh v0.0.0-20240604154955-a40c6a0d028f github.com/charmbracelet/wish v1.4.0 github.com/creack/pty v1.1.21 + github.com/kevinburke/ssh_config v1.2.0 github.com/spf13/cobra v1.8.0 github.com/spf13/pflag v1.0.5 github.com/stretchr/testify v1.9.0 diff --git a/go.sum b/go.sum index 7002fdb..ad3bdcb 100644 --- a/go.sum +++ b/go.sum @@ -42,6 +42,8 @@ github.com/go-logfmt/logfmt v0.6.0 h1:wGYYu3uicYdqXVgoYbvnkrPVXkuLM1p1ifugDMEdRi github.com/go-logfmt/logfmt v0.6.0/go.mod h1:WYhtIu8zTZfxdn5+rREduYbwxfcBr/Vr6KEVveWlfTs= github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= +github.com/kevinburke/ssh_config v1.2.0 h1:x584FjTGwHzMwvHx18PXxbBVzfnxogHaAReU4gf13a4= +github.com/kevinburke/ssh_config v1.2.0/go.mod h1:CT57kijsi8u/K/BOFA39wgDQJ9CxiF4nAY/ojJ6r6mM= github.com/lucasb-eyer/go-colorful v1.2.0 h1:1nnpGOrhyZZuNyfu1QjKiUICQ74+3FNCN69Aj6K7nkY= github.com/lucasb-eyer/go-colorful v1.2.0/go.mod h1:R4dSotOR9KMtayYi1e77YzuveK+i7ruzyGqttikkLy0= github.com/mattn/go-isatty v0.0.18 h1:DOKFKCQ7FNG2L1rbrmstDN4QVRdS89Nkh85u68Uwp98= From 7800b7b68b8838856ac9d0710bce3547a6c2dc6f Mon Sep 17 00:00:00 2001 From: Filippo Trotter Date: Thu, 11 Jul 2024 11:52:08 +0200 Subject: [PATCH 3/3] fix: remove terminal resize problems during file selection --- cmd/root.go | 2 +- utils/server/server.go | 2 +- utils/tui/model_test.go | 14 ++++----- utils/tui/modelutils/file.go | 47 +++++++++++++++++++++++++------ utils/tui/modelutils/file_test.go | 32 ++++++++++----------- 5 files changed, 63 insertions(+), 34 deletions(-) diff --git a/cmd/root.go b/cmd/root.go index 530cda0..1865b48 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -102,7 +102,7 @@ func ReadFlags(cmd *cobra.Command) { // Initialize your model with the current directory model := tui.Model{ State: "FileSelection", - FilesSelector: modelutils.InitialModel(currentDir, 20), + FilesSelector: modelutils.InitialModel(currentDir, 20, 20), } clearScreen() // Bubble Tea program diff --git a/utils/server/server.go b/utils/server/server.go index e95a7f9..2de030b 100644 --- a/utils/server/server.go +++ b/utils/server/server.go @@ -44,7 +44,7 @@ func StartServer(port string) { // Initialize the file selector model with the directory argument model := tui.Model{ State: "FileSelection", - FilesSelector: modelutils.InitialModel(dir, pty.Window.Height-5), // Initialize the FilesSelector model with window height + FilesSelector: modelutils.InitialModel(dir, pty.Window.Height-5, pty.Window.Width-5), // Initialize the FilesSelector model with window height } if model.Error != nil { wish.Println(s, model.Error.Error()) diff --git a/utils/tui/model_test.go b/utils/tui/model_test.go index e5fadc1..c9652ce 100644 --- a/utils/tui/model_test.go +++ b/utils/tui/model_test.go @@ -13,7 +13,7 @@ import ( func TestModel(t *testing.T) { t.Run("Init", func(t *testing.T) { - model := Model{FilesSelector: modelutils.InitialModel(".", 10)} + model := Model{FilesSelector: modelutils.InitialModel(".", 10, 10)} cmd := model.Init() assert.Nil(t, cmd) }) @@ -32,7 +32,7 @@ func TestModel(t *testing.T) { name: "FileSelection to ModeSelection", model: Model{ State: "FileSelection", - FilesSelector: modelutils.InitialModel(".", 10), + FilesSelector: modelutils.InitialModel(".", 10, 10), }, setup: func(m *Model) { m.FilesSelector.FilesPath = []string{"path/test/file1", "path/test/file2"} @@ -51,7 +51,7 @@ func TestModel(t *testing.T) { name: "FileSelection to ActionSelection", model: Model{ State: "FileSelection", - FilesSelector: modelutils.InitialModel(".", 10), + FilesSelector: modelutils.InitialModel(".", 10, 10), }, setup: func(m *Model) { m.FilesSelector.FilesPath = []string{"path/test/file1"} @@ -69,7 +69,7 @@ func TestModel(t *testing.T) { name: "No file selected", model: Model{ State: "FileSelection", - FilesSelector: modelutils.InitialModel(".", 10), + FilesSelector: modelutils.InitialModel(".", 10, 10), }, msg: tea.KeyMsg{Type: tea.KeyRunes, Runes: []rune{'x'}}, verify: func(t *testing.T, m Model) { @@ -156,7 +156,7 @@ func TestModel(t *testing.T) { name: "ModeSelection to FileSelection", model: Model{ State: "ModeSelection", - FilesSelector: modelutils.InitialModel(".", 10), + FilesSelector: modelutils.InitialModel(".", 10, 10), SpeedSelector: modelutils.NewModeSelector([]string{"Fast mode", "Slow mode"}, "", ""), Files: []string{"file1.txt", "file2.txt"}, }, @@ -174,7 +174,7 @@ func TestModel(t *testing.T) { name: "ActionSelection to FileSelection", model: Model{ State: "ActionSelection", - FilesSelector: modelutils.InitialModel(".", 10), + FilesSelector: modelutils.InitialModel(".", 10, 10), SpeedSelector: modelutils.ModeSelector{Selected: "Fast mode"}, ActionSelector: modelutils.NewModeSelector([]string{"toggle", "comment", "uncomment"}, "", ""), Files: []string{"file1.txt"}, @@ -424,7 +424,7 @@ func TestModel(t *testing.T) { tests := []viewTest{ { name: "FileSelection View", - model: Model{State: "FileSelection", FilesSelector: modelutils.InitialModel(".", 10)}, + model: Model{State: "FileSelection", FilesSelector: modelutils.InitialModel(".", 10, 10)}, expected: "Select the files you want to modify", }, { diff --git a/utils/tui/modelutils/file.go b/utils/tui/modelutils/file.go index 54ad8b3..95b95b6 100644 --- a/utils/tui/modelutils/file.go +++ b/utils/tui/modelutils/file.go @@ -3,6 +3,7 @@ package modelutils import ( "fmt" "os" + "strings" tea "github.com/charmbracelet/bubbletea" "github.com/charmbracelet/lipgloss" @@ -19,9 +20,10 @@ type FilesSelector struct { WindowHeight int Error error NoFileSelected bool + WindowWidth int } -func InitialModel(currentDir string, windowHeight int) FilesSelector { +func InitialModel(currentDir string, windowHeight int, windowWidth int) FilesSelector { var filesAndDir []string selectedFilesAndDir := make(map[int]bool) @@ -47,6 +49,7 @@ func InitialModel(currentDir string, windowHeight int) FilesSelector { FilesAndDir: filesAndDir, SelectedFilesAndDir: selectedFilesAndDir, WindowHeight: windowHeight, + WindowWidth: windowWidth, } } @@ -111,24 +114,41 @@ func (m FilesSelector) Update(msg tea.Msg) (tea.Model, tea.Cmd) { m.Done = true } } + case tea.WindowSizeMsg: + return m, m.doResize(msg) } return m, nil } +func (m *FilesSelector) doResize(msg tea.WindowSizeMsg) tea.Cmd { + m.WindowHeight = msg.Height + m.WindowWidth = msg.Width + return nil +} + func (m FilesSelector) View() string { if m.Error != nil { return Paint("red").Render(fmt.Sprintf("An error occurred: %v", m.Error)) } - s := Paint("silver").Render("\n Select the files you want to modify...") + "\n" - s += Paint("silver").Render("\n Selected files till now:") + "\n" + // Help messages + helpMessages := []string{ + "'q' to quit 'esc' to move to parent directory", + "'↑' to go up 'x' to modify selected files", + "'↓' to go down 'enter' to select pointed file/move to pointed sub folder", + } + + // File selection and error messages + var sb strings.Builder + sb.WriteString(Paint("silver").Render("\n Select the files you want to modify...") + "\n") + sb.WriteString(Paint("silver").Render("\n Selected files till now:") + "\n") if m.NoFileSelected { - s += Paint("red").Render("\n No file selected. Please select at least one file or quit.") + "\n" + sb.WriteString(Paint("red").Render("\n No file selected. Please select at least one file or quit.") + "\n") } for i := 0; i < len(m.FilesPath); i++ { - s += fmt.Sprintf(" %s\n", Paint("green").Render(m.FilesPath[i])) + sb.WriteString(fmt.Sprintf(" %s\n", Paint("green").Render(m.FilesPath[i]))) } - s += "\n" + sb.WriteString("\n") for i := m.scrollOffset; i < m.scrollOffset+m.WindowHeight && i < len(m.FilesAndDir); i++ { choice := m.FilesAndDir[i] @@ -150,10 +170,19 @@ func (m FilesSelector) View() string { cursor = Paint("red").Render(" ➪") } - s += fmt.Sprintf("%s %s\n", cursor, choice) + sb.WriteString(fmt.Sprintf("%s %s\n", cursor, choice)) } - s += Paint("silver").Render("\n 'q' to quit 'esc' to move to parent directory\n '↑' to go up 'x' to modify selected files\n '↓' to go down 'enter' to select pointed file/move to pointed sub folder") - return s + + fileSelection := sb.String() + + // Combine file selection with help messages + helpView := lipgloss.JoinVertical(lipgloss.Left, helpMessages...) + content := lipgloss.JoinVertical(lipgloss.Left, fileSelection, helpView) + + // Place the content in the center of the screen + fullView := lipgloss.Place(m.WindowWidth, m.WindowHeight, lipgloss.Left, lipgloss.Left, content) + + return fullView } func Paint(color string) lipgloss.Style { diff --git a/utils/tui/modelutils/file_test.go b/utils/tui/modelutils/file_test.go index adff2f9..8c21401 100644 --- a/utils/tui/modelutils/file_test.go +++ b/utils/tui/modelutils/file_test.go @@ -30,14 +30,14 @@ func TestFilesSelector(t *testing.T) { { name: "InitialModel", setup: func(m *FilesSelector) { - *m = InitialModel(tempDir, 10) + *m = InitialModel(tempDir, 10, 10) }, verify: func(t *testing.T, m FilesSelector) { assert.Equal(t, tempDir, m.CurrentDir) assert.Contains(t, m.FilesAndDir, subDir) assert.NotNil(t, m.SelectedFilesAndDir) assert.Equal(t, 0, m.cursor) - assert.Equal(t, 10, m.WindowHeight) + assert.Equal(t, 10, 10, m.WindowHeight) assert.NoError(t, m.Error) }, }, @@ -45,7 +45,7 @@ func TestFilesSelector(t *testing.T) { name: "KeyDown", msg: tea.KeyMsg{Type: tea.KeyDown}, setup: func(m *FilesSelector) { - *m = InitialModel(tempDir, 10) + *m = InitialModel(tempDir, 10, 10) }, verify: func(t *testing.T, m FilesSelector) { @@ -56,7 +56,7 @@ func TestFilesSelector(t *testing.T) { name: "KeyUp", msg: tea.KeyMsg{Type: tea.KeyUp}, setup: func(m *FilesSelector) { - *m = InitialModel(tempDir, 10) + *m = InitialModel(tempDir, 10, 10) m.cursor = 1 }, verify: func(t *testing.T, m FilesSelector) { @@ -67,7 +67,7 @@ func TestFilesSelector(t *testing.T) { name: "EnterDirectory", msg: tea.KeyMsg{Type: tea.KeyEnter}, setup: func(m *FilesSelector) { - *m = InitialModel(tempDir, 10) + *m = InitialModel(tempDir, 10, 10) m.cursor = 1 }, verify: func(t *testing.T, m FilesSelector) { @@ -78,7 +78,7 @@ func TestFilesSelector(t *testing.T) { name: "SelectFile", msg: tea.KeyMsg{Type: tea.KeyEnter}, setup: func(m *FilesSelector) { - *m = InitialModel(subDir, 10) + *m = InitialModel(subDir, 10, 10) m.cursor = 0 }, verify: func(t *testing.T, m FilesSelector) { @@ -89,7 +89,7 @@ func TestFilesSelector(t *testing.T) { name: "Exit", msg: tea.KeyMsg{Type: tea.KeyCtrlC}, setup: func(m *FilesSelector) { - *m = InitialModel(tempDir, 10) + *m = InitialModel(tempDir, 10, 10) }, verify: func(t *testing.T, m FilesSelector) { // Call Update with the exit message @@ -105,7 +105,7 @@ func TestFilesSelector(t *testing.T) { name: "MoveToPreviousDir", msg: tea.KeyMsg{Type: tea.KeyEsc}, setup: func(m *FilesSelector) { - *m = InitialModel(subDir, 10) + *m = InitialModel(subDir, 10, 10) }, verify: func(t *testing.T, m FilesSelector) { assert.Equal(t, tempDir, m.CurrentDir) @@ -115,7 +115,7 @@ func TestFilesSelector(t *testing.T) { name: "Confirm", msg: tea.KeyMsg{Type: tea.KeyRunes, Runes: []rune{'x'}}, setup: func(m *FilesSelector) { - *m = InitialModel(tempDir, 10) + *m = InitialModel(tempDir, 10, 10) m.FilesPath = []string{tempFile} }, verify: func(t *testing.T, m FilesSelector) { @@ -127,7 +127,7 @@ func TestFilesSelector(t *testing.T) { name: "No file selected", msg: tea.KeyMsg{Type: tea.KeyRunes, Runes: []rune{'x'}}, setup: func(m *FilesSelector) { - *m = InitialModel(tempDir, 10) + *m = InitialModel(tempDir, 10, 10) }, verify: func(t *testing.T, m FilesSelector) { assert.Equal(t, tempDir, m.CurrentDir) @@ -138,7 +138,7 @@ func TestFilesSelector(t *testing.T) { for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - model := InitialModel(tempDir, 10) + model := InitialModel(tempDir, 10, 10) if tt.setup != nil { tt.setup(&model) } @@ -173,7 +173,7 @@ func TestFilesSelectorView(t *testing.T) { { name: "No selected file", setup: func(m *FilesSelector) { - *m = InitialModel(tempDir, 10) + *m = InitialModel(tempDir, 10, 10) }, verify: func(t *testing.T, view string) { assert.Contains(t, view, "Select the files you want to modify...") @@ -184,7 +184,7 @@ func TestFilesSelectorView(t *testing.T) { { name: " with a selected file", setup: func(m *FilesSelector) { - *m = InitialModel(tempDir, 10) + *m = InitialModel(tempDir, 10, 10) m.cursor = 1 m.FilesPath = append(m.FilesPath, tempFile1) }, @@ -198,7 +198,7 @@ func TestFilesSelectorView(t *testing.T) { { name: " inside subdir", setup: func(m *FilesSelector) { - *m = InitialModel(tempDir, 10) + *m = InitialModel(tempDir, 10, 10) msg := tea.KeyMsg{Type: tea.KeyEnter} m.cursor = 1 newModel, _ := m.Update(msg) @@ -212,7 +212,7 @@ func TestFilesSelectorView(t *testing.T) { { name: "Navigate above root directory", setup: func(m *FilesSelector) { - *m = InitialModel("/", 10) + *m = InitialModel("/", 10, 10) msg := tea.KeyMsg{Type: tea.KeyEsc} m.cursor = 1 newModel, _ := m.Update(msg) @@ -225,7 +225,7 @@ func TestFilesSelectorView(t *testing.T) { } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - model := InitialModel(tempDir, 10) + model := InitialModel(tempDir, 10, 10) if tt.setup != nil { tt.setup(&model) }