summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMaas Lalani <maas@lalani.dev>2024-03-28 16:19:06 -0400
committerGitHub <noreply@github.com>2024-03-28 16:19:06 -0400
commit3a717104a96380d50cbba4b7793ac1c2e2b8449f (patch)
tree5c18ad2e18e4cb7f178dba7035705b005c2913e4
parentf7572e387ebc7e9c52cd576b244535a89496860e (diff)
feat: huh file picker (#523)
Use `huh` for `gum file`.
-rw-r--r--file/command.go71
-rw-r--r--file/file.go72
-rw-r--r--file/options.go2
-rw-r--r--go.mod2
-rw-r--r--go.sum2
5 files changed, 33 insertions, 116 deletions
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()
-
- m := model{
- filepicker: fp,
- timeout: o.Timeout,
- hasTimeout: o.Timeout > 0,
- aborted: false,
- }
+ 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()
+
+ // 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)
- }
-
- m = tm.(model)
- if m.aborted {
- return exit.ErrAborted
- }
-
- if m.selectedPath == "" {
- os.Exit(1)
+ return err
}
- 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=