From 3a717104a96380d50cbba4b7793ac1c2e2b8449f Mon Sep 17 00:00:00 2001 From: Maas Lalani Date: Thu, 28 Mar 2024 16:19:06 -0400 Subject: [PATCH] feat: huh file picker (#523) Use `huh` for `gum file`. --- file/command.go | 69 +++++++++++++++++++---------------------------- file/file.go | 72 ------------------------------------------------- file/options.go | 2 +- go.mod | 2 +- go.sum | 2 ++ 5 files changed, 32 insertions(+), 115 deletions(-) delete mode 100644 file/file.go diff --git a/file/command.go b/file/command.go index 0d34cab..20b9924 100644 --- a/file/command.go +++ b/file/command.go @@ -3,13 +3,10 @@ package file import ( "errors" "fmt" - "os" "path/filepath" - "github.com/charmbracelet/gum/internal/exit" - - "github.com/charmbracelet/bubbles/filepicker" - tea "github.com/charmbracelet/bubbletea" + "github.com/charmbracelet/huh" + "github.com/charmbracelet/lipgloss" ) // Run is the interface to picking a file. @@ -27,46 +24,36 @@ func (o Options) Run() error { return fmt.Errorf("file not found: %w", err) } - fp := filepicker.New() - fp.CurrentDirectory = path - fp.Path = path - fp.Height = o.Height - fp.AutoHeight = o.Height == 0 - fp.Cursor = o.Cursor - fp.DirAllowed = o.Directory - fp.FileAllowed = o.File - fp.ShowHidden = o.All - fp.Styles = filepicker.DefaultStyles() - fp.Styles.Cursor = o.CursorStyle.ToLipgloss() - fp.Styles.Symlink = o.SymlinkStyle.ToLipgloss() - fp.Styles.Directory = o.DirectoryStyle.ToLipgloss() - fp.Styles.File = o.FileStyle.ToLipgloss() - fp.Styles.Permission = o.PermissionsStyle.ToLipgloss() - fp.Styles.Selected = o.SelectedStyle.ToLipgloss() - fp.Styles.FileSize = o.FileSizeStyle.ToLipgloss() + theme := huh.ThemeCharm() + theme.Focused.Base = lipgloss.NewStyle() + theme.Focused.File = o.FileStyle.ToLipgloss() + theme.Focused.Directory = o.DirectoryStyle.ToLipgloss() + theme.Focused.SelectedOption = o.SelectedStyle.ToLipgloss() - m := model{ - filepicker: fp, - timeout: o.Timeout, - hasTimeout: o.Timeout > 0, - aborted: false, - } + // XXX: These should be file selected specific. + theme.Focused.TextInput.Placeholder = o.PermissionsStyle.ToLipgloss() + theme.Focused.TextInput.Prompt = o.CursorStyle.ToLipgloss() + + err = huh.NewForm( + huh.NewGroup( + huh.NewFilePicker(). + Picking(true). + CurrentDirectory(path). + DirAllowed(o.Directory). + FileAllowed(o.File). + Height(o.Height). + ShowHidden(o.All). + Value(&path), + ), + ). + WithShowHelp(false). + WithTheme(theme). + Run() - tm, err := tea.NewProgram(&m, tea.WithOutput(os.Stderr)).Run() if err != nil { - return fmt.Errorf("unable to pick selection: %w", err) + return err } - m = tm.(model) - if m.aborted { - return exit.ErrAborted - } - - if m.selectedPath == "" { - os.Exit(1) - } - - fmt.Println(m.selectedPath) - + fmt.Println(path) return nil } diff --git a/file/file.go b/file/file.go deleted file mode 100644 index 3328d79..0000000 --- a/file/file.go +++ /dev/null @@ -1,72 +0,0 @@ -// Package file provides an interface to pick a file from a folder (tree). -// The user is provided a file manager-like interface to navigate, to -// select a file. -// -// Let's pick a file from the current directory: -// -// $ gum file -// $ gum file . -// -// Let's pick a file from the home directory: -// -// $ gum file $HOME -package file - -import ( - "time" - - "github.com/charmbracelet/bubbles/filepicker" - tea "github.com/charmbracelet/bubbletea" - "github.com/charmbracelet/gum/timeout" -) - -type model struct { - filepicker filepicker.Model - selectedPath string - aborted bool - quitting bool - timeout time.Duration - hasTimeout bool -} - -func (m model) Init() tea.Cmd { - return tea.Batch( - timeout.Init(m.timeout, nil), - m.filepicker.Init(), - ) -} - -func (m model) Update(msg tea.Msg) (tea.Model, tea.Cmd) { - switch msg := msg.(type) { - case tea.KeyMsg: - switch msg.String() { - case "ctrl+c", "q", "esc": - m.aborted = true - m.quitting = true - return m, tea.Quit - } - case timeout.TickTimeoutMsg: - if msg.TimeoutValue <= 0 { - m.quitting = true - m.aborted = true - return m, tea.Quit - } - m.timeout = msg.TimeoutValue - return m, timeout.Tick(msg.TimeoutValue, msg.Data) - } - var cmd tea.Cmd - m.filepicker, cmd = m.filepicker.Update(msg) - if didSelect, path := m.filepicker.DidSelectFile(msg); didSelect { - m.selectedPath = path - m.quitting = true - return m, tea.Quit - } - return m, cmd -} - -func (m model) View() string { - if m.quitting { - return "" - } - return m.filepicker.View() -} diff --git a/file/options.go b/file/options.go index 85ca87f..31146f3 100644 --- a/file/options.go +++ b/file/options.go @@ -16,7 +16,7 @@ type Options struct { File bool `help:"Allow files selection" default:"true" env:"GUM_FILE_FILE"` Directory bool `help:"Allow directories selection" default:"false" env:"GUM_FILE_DIRECTORY"` - Height int `help:"Maximum number of files to display" default:"0" env:"GUM_FILE_HEIGHT"` + Height int `help:"Maximum number of files to display" default:"10" env:"GUM_FILE_HEIGHT"` CursorStyle style.Styles `embed:"" prefix:"cursor." help:"The cursor style" set:"defaultForeground=212" envprefix:"GUM_FILE_CURSOR_"` SymlinkStyle style.Styles `embed:"" prefix:"symlink." help:"The style to use for symlinks" set:"defaultForeground=36" envprefix:"GUM_FILE_SYMLINK_"` DirectoryStyle style.Styles `embed:"" prefix:"directory." help:"The style to use for directories" set:"defaultForeground=99" envprefix:"GUM_FILE_DIRECTORY_"` diff --git a/go.mod b/go.mod index 5d70db2..5a213f0 100644 --- a/go.mod +++ b/go.mod @@ -8,7 +8,7 @@ require ( github.com/charmbracelet/bubbles v0.18.0 github.com/charmbracelet/bubbletea v0.25.0 github.com/charmbracelet/glamour v0.7.0 - github.com/charmbracelet/huh v0.3.1-0.20240327025511-ec643317aa10 + github.com/charmbracelet/huh v0.3.1-0.20240328185852-590ecabc34b9 github.com/charmbracelet/lipgloss v0.10.0 github.com/charmbracelet/log v0.4.0 github.com/mattn/go-isatty v0.0.20 diff --git a/go.sum b/go.sum index 1d6cb9d..8b19bed 100644 --- a/go.sum +++ b/go.sum @@ -29,6 +29,8 @@ github.com/charmbracelet/huh v0.3.0 h1:CxPplWkgW2yUTDDG0Z4S5HH8SJOosWHd4LxCvi0Xs github.com/charmbracelet/huh v0.3.0/go.mod h1:fujUdKX8tC45CCSaRQdw789O6uaCRwx8l2NDyKfC4jA= github.com/charmbracelet/huh v0.3.1-0.20240327025511-ec643317aa10 h1:779PmXc9Zt/Hxa0yg4I8sQk/1Nfa5TQisXaHZEW60Yk= github.com/charmbracelet/huh v0.3.1-0.20240327025511-ec643317aa10/go.mod h1:x0rYoA1kpsaefXhRJZuxLM+qP4CYyEFE67T3ZGl7zPU= +github.com/charmbracelet/huh v0.3.1-0.20240328185852-590ecabc34b9 h1:Izr4MC+shs9PpR4MWz/OFA4+ywbKutvPv0eSHJwfn60= +github.com/charmbracelet/huh v0.3.1-0.20240328185852-590ecabc34b9/go.mod h1:x0rYoA1kpsaefXhRJZuxLM+qP4CYyEFE67T3ZGl7zPU= github.com/charmbracelet/lipgloss v0.10.0 h1:KWeXFSexGcfahHX+54URiZGkBFazf70JNMtwg/AFW3s= github.com/charmbracelet/lipgloss v0.10.0/go.mod h1:Wig9DSfvANsxqkRsqj6x87irdy123SR4dOXlKa91ciE= github.com/charmbracelet/log v0.3.1 h1:TjuY4OBNbxmHWSwO3tosgqs5I3biyY8sQPny/eCMTYw=