Skip to content

Commit

Permalink
feat: add possibility of directly select a single file
Browse files Browse the repository at this point in the history
  • Loading branch information
Filippo Trotter authored and Filippo Trotter committed Jul 16, 2024
1 parent 48b57d2 commit 4bfd850
Show file tree
Hide file tree
Showing 4 changed files with 43 additions and 34 deletions.
3 changes: 3 additions & 0 deletions utils/tui/model.go
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,9 @@ func (m Model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
m.ActionSelector = newActionSelector.(modelutils.ModeSelector)
if m.ActionSelector.Back {
if len(m.Files) == 1 {
if !m.FilesSelector.MultipleSelection {
m.FilesSelector.FilesPath = []string{}
}
m.State = "FileSelection"
m.FilesSelector.Done = false
} else {
Expand Down
42 changes: 15 additions & 27 deletions utils/tui/model_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,13 @@ import (
)

func TestModel(t *testing.T) {
tempDir := t.TempDir()
tempFile := filepath.Join(tempDir, "file.txt")
_, err := os.Create(tempFile)
assert.NoError(t, err)

t.Run("Init", func(t *testing.T) {
model := Model{FilesSelector: modelutils.InitialModel(".", 10, 10)}
model := Model{FilesSelector: modelutils.InitialModel(tempDir, 10, 10)}
cmd := model.Init()
assert.Nil(t, cmd)
})
Expand All @@ -32,9 +37,10 @@ func TestModel(t *testing.T) {
name: "FileSelection to ModeSelection",
model: Model{
State: "FileSelection",
FilesSelector: modelutils.InitialModel(".", 10, 10),
FilesSelector: modelutils.InitialModel(tempDir, 10, 10),
},
setup: func(m *Model) {
m.FilesSelector.MultipleSelection = true
m.FilesSelector.FilesPath = []string{"path/test/file1", "path/test/file2"}

},
Expand All @@ -51,16 +57,14 @@ func TestModel(t *testing.T) {
name: "FileSelection to ActionSelection",
model: Model{
State: "FileSelection",
FilesSelector: modelutils.InitialModel(".", 10, 10),
FilesSelector: modelutils.InitialModel(tempDir, 10, 10),
},
setup: func(m *Model) {
m.FilesSelector.FilesPath = []string{"path/test/file1"}

},
msg: tea.KeyMsg{Type: tea.KeyRunes, Runes: []rune{'x'}},
msg: tea.KeyMsg{Type: tea.KeyEnter},
verify: func(t *testing.T, m Model) {
assert.True(t, m.FilesSelector.Done)
assert.Contains(t, m.Files, "path/test/file1")
assert.Contains(t, m.Files, tempFile)
assert.Equal(t, "ActionSelection", m.State)

},
Expand All @@ -69,7 +73,7 @@ func TestModel(t *testing.T) {
name: "No file selected",
model: Model{
State: "FileSelection",
FilesSelector: modelutils.InitialModel(".", 10, 10),
FilesSelector: modelutils.InitialModel(tempDir, 10, 10),
},
msg: tea.KeyMsg{Type: tea.KeyRunes, Runes: []rune{'x'}},
verify: func(t *testing.T, m Model) {
Expand Down Expand Up @@ -156,7 +160,7 @@ func TestModel(t *testing.T) {
name: "ModeSelection to FileSelection",
model: Model{
State: "ModeSelection",
FilesSelector: modelutils.InitialModel(".", 10, 10),
FilesSelector: modelutils.InitialModel(tempDir, 10, 10),
SpeedSelector: modelutils.NewModeSelector([]string{"Fast mode", "Slow mode"}, "", "", 10, 10),
Files: []string{"file1.txt", "file2.txt"},
},
Expand All @@ -174,7 +178,7 @@ func TestModel(t *testing.T) {
name: "ActionSelection to FileSelection",
model: Model{
State: "ActionSelection",
FilesSelector: modelutils.InitialModel(".", 10, 10),
FilesSelector: modelutils.InitialModel(tempDir, 10, 10),
SpeedSelector: modelutils.ModeSelector{Selected: "Fast mode"},
ActionSelector: modelutils.NewModeSelector([]string{"toggle", "comment", "uncomment"}, "", "", 10, 10),
Files: []string{"file1.txt"},
Expand Down Expand Up @@ -424,25 +428,9 @@ func TestModel(t *testing.T) {
tests := []viewTest{
{
name: "FileSelection View",
model: Model{State: "FileSelection", FilesSelector: modelutils.InitialModel(".", 10, 10)},
model: Model{State: "FileSelection", FilesSelector: modelutils.InitialModel(tempDir, 10, 10)},
expected: "Select the files you want to modify",
},
{
name: "ModeSelection View",
model: Model{State: "ModeSelection", SpeedSelector: modelutils.NewModeSelector([]string{"Fast mode", "Slow mode"}, "", "", 10, 10)},
expected: "Select 'Fast mode'",
},
{
name: "ActionSelection View",
model: Model{State: "ActionSelection", ActionSelector: modelutils.NewModeSelector([]string{"toggle", "comment", "uncomment"}, "", "Fast mode", 10, 10)},
expected: "Select action",
},
{
name: "LabelInput View",
model: Model{State: "LabelInput", LabelInput: modelutils.NewLabelInput("", 10, 10)},
expected: "Type below the section to modify",
},

{
name: "Final View with Error",
model: Model{State: "Final", Error: fmt.Errorf("test error")},
Expand Down
28 changes: 22 additions & 6 deletions utils/tui/modelutils/file.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ type FilesSelector struct {
Error error
NoFileSelected bool
WindowWidth int
MultipleSelection bool
}

func InitialModel(currentDir string, windowHeight int, windowWidth int) FilesSelector {
Expand Down Expand Up @@ -66,6 +67,14 @@ func (m FilesSelector) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
switch msg.String() {
case "ctrl+c", "q":
return m, tea.Quit
case " ":
if !m.MultipleSelection {
m.MultipleSelection = true
} else {
m.MultipleSelection = false
m.FilesPath = []string{}
}

case "up":
if m.cursor > 0 {
m.cursor--
Expand Down Expand Up @@ -98,6 +107,10 @@ func (m FilesSelector) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
m.FilesPath = Remove(m.FilesPath, m.FilesAndDir[m.cursor])
} else {
m.FilesPath = append(m.FilesPath, m.FilesAndDir[m.cursor])
if !m.MultipleSelection {
m.Done = true
m.WindowWidth /= 2
}
}
m.SelectedFilesAndDir[m.cursor] = !m.SelectedFilesAndDir[m.cursor]
}
Expand All @@ -108,11 +121,13 @@ func (m FilesSelector) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
return m, tea.Quit
}
case "x":
if len(m.FilesPath) == 0 {
m.NoFileSelected = true
} else {
m.Done = true
m.WindowWidth /= 2
if m.MultipleSelection {
if len(m.FilesPath) == 0 {
m.NoFileSelected = true
} else {
m.Done = true
m.WindowWidth /= 2
}
}
}
case tea.WindowSizeMsg:
Expand All @@ -138,8 +153,9 @@ func (m FilesSelector) View() string {
// Help messages
helpMessages := []string{
"'q' to quit 'esc' to move to parent directory",
"'↑' to go up 'x' to modify selected files",
"'↑' to go up 'space' to select multiple files",
"'↓' to go down 'enter' to select pointed file/move to pointed sub folder",
"'x' to modify select files",
}

// File selection and error messages
Expand Down
4 changes: 3 additions & 1 deletion utils/tui/modelutils/file_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@ func TestFilesSelector(t *testing.T) {
},
verify: func(t *testing.T, m FilesSelector) {
assert.Contains(t, m.FilesPath, tempFile)
assert.True(t, m.Done)
},
},
{
Expand Down Expand Up @@ -112,10 +113,11 @@ func TestFilesSelector(t *testing.T) {
},
},
{
name: "Confirm",
name: "Confirm multiple file",
msg: tea.KeyMsg{Type: tea.KeyRunes, Runes: []rune{'x'}},
setup: func(m *FilesSelector) {
*m = InitialModel(tempDir, 10, 10)
m.MultipleSelection = true
m.FilesPath = []string{tempFile}
},
verify: func(t *testing.T, m FilesSelector) {
Expand Down

0 comments on commit 4bfd850

Please sign in to comment.