-
Notifications
You must be signed in to change notification settings - Fork 0
/
explorer_controller.go
183 lines (145 loc) · 4.04 KB
/
explorer_controller.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
package controller
import (
"os"
"strconv"
set "github.com/deckarep/golang-set/v2"
"github.com/dinhhuy258/fm/pkg/config"
"github.com/dinhhuy258/fm/pkg/fs"
"github.com/dinhhuy258/fm/pkg/gui/view"
"github.com/dinhhuy258/fm/pkg/type/optional"
)
// ExplorerController is the controller for the explorer view
type ExplorerController struct {
*BaseController
path string
focus int
entries []fs.IEntry
selections set.Set[string]
view *view.ExplorerView
headerView *view.ExplorerHeaderView
}
// newExplorerController creates a new explorer controller
func newExplorerController(baseController *BaseController,
view *view.ExplorerView,
headerView *view.ExplorerHeaderView,
selections set.Set[string],
) *ExplorerController {
return &ExplorerController{
BaseController: baseController,
view: view,
headerView: headerView,
focus: 0,
selections: selections,
}
}
// GetFocus returns the index of the focused entry
func (ec *ExplorerController) GetFocus() int {
return ec.focus
}
// GetCurrentEntry returns the current entry
func (ec *ExplorerController) GetCurrentEntry() fs.IEntry {
if ec.focus < 0 || ec.focus >= len(ec.entries) {
return nil
}
return ec.entries[ec.focus]
}
// GetEntries returns the list of entries
func (ec *ExplorerController) GetEntries() []fs.IEntry {
return ec.entries
}
// GetPath returns the current path
func (ec *ExplorerController) GetPath() string {
return ec.path
}
// LoadDirectory loads the directory at the given path
func (ec *ExplorerController) LoadDirectory(path string, focusPath optional.Optional[string]) {
if !fs.IsDir(path) {
ec.mediator.notify(ShowErrorLog, optional.New(path+" is not a directory"))
return
}
ec.path = path
generalCfg := config.AppConfig.General
entries, err := fs.LoadEntries(path, generalCfg.ShowHidden, generalCfg.Sorting.SortType,
*generalCfg.Sorting.Reverse, *generalCfg.Sorting.IgnoreCase, *generalCfg.Sorting.IgnoreDiacritics)
if err != nil {
ec.mediator.notify(ShowErrorLog, optional.New("Failed to load directory: "+path))
return
}
// Change the working directory according to the new path
// We can be sure that the path is a directory and its existence is checked before => no need to
// check the error here
_ = os.Chdir(ec.path)
ec.entries = entries
ec.headerView.Title = " " + path + " (" + strconv.Itoa(len(ec.entries)) + ") "
focusPath.IfPresentOrElse(func(focusPath *string) {
ec.focusPath(*focusPath)
}, func() {
ec.FocusFirst()
})
}
// Focus focuses cursor to the current entry
func (ec *ExplorerController) Focus() {
ec.view.FocusPoint(0, ec.focus)
}
// FocusPrevious focuses the previous entry
func (ec *ExplorerController) FocusByIndex(idx int) {
if idx < 0 {
idx = 0
}
if idx >= len(ec.entries) {
idx = len(ec.entries) - 1
}
ec.focus = idx
ec.Focus()
}
// FocusPrevious focuses the previous entry
func (ec *ExplorerController) FocusPrevious() {
if ec.focus <= 0 {
return
}
ec.focus--
ec.Focus()
}
// FocusNext focuses the next entry
func (ec *ExplorerController) FocusNext() {
if ec.focus >= len(ec.entries)-1 {
return
}
ec.focus++
ec.Focus()
}
// FocusFirst focuses the first entry
func (ec *ExplorerController) FocusFirst() {
ec.focus = 0
ec.Focus()
}
// FocusLast focuses the last entry
func (ec *ExplorerController) FocusLast() {
ec.focus = len(ec.entries) - 1
ec.Focus()
}
// FocusPath focuses the entry with the given path
func (ec *ExplorerController) FocusPath(path string) {
if parentPath := fs.Dir(path); ec.path != parentPath {
ec.LoadDirectory(parentPath, optional.New(path))
} else {
ec.focusPath(path)
}
}
// UpdateView updates the view
func (ec *ExplorerController) UpdateView() {
ec.view.UpdateView(ec.entries, ec.selections, ec.focus)
}
// focusPath focuses the entry with the given path
func (ec *ExplorerController) focusPath(path string) {
focus := 0
// Iterate through the list of entries and find the idx for the current path
for idx, entry := range ec.entries {
if entry.GetPath() == path {
focus = idx
break
}
}
ec.focus = focus
ec.Focus()
}