add err log for file io
This commit is contained in:
+4
-32
@@ -93,41 +93,13 @@ func createFolder(path string) error {
|
|||||||
return os.Mkdir(path, 0755)
|
return os.Mkdir(path, 0755)
|
||||||
}
|
}
|
||||||
|
|
||||||
func deleteFile(path string) error {
|
func deletePath(path string) error {
|
||||||
if path == "" {
|
if path == "" {
|
||||||
return errors.New("file path cannot be empty")
|
return errors.New("path cannot be empty")
|
||||||
}
|
}
|
||||||
|
|
||||||
info, err := os.Stat(path)
|
if _, err := os.Stat(path); os.IsNotExist(err) {
|
||||||
if err != nil {
|
return errors.New("path does not exist")
|
||||||
if os.IsNotExist(err) {
|
|
||||||
return errors.New("file does not exist")
|
|
||||||
}
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
if info.IsDir() {
|
|
||||||
return errors.New("path is a directory, not a file")
|
|
||||||
}
|
|
||||||
|
|
||||||
return os.Remove(path)
|
|
||||||
}
|
|
||||||
|
|
||||||
func deleteFolder(path string) error {
|
|
||||||
if path == "" {
|
|
||||||
return errors.New("folder path cannot be empty")
|
|
||||||
}
|
|
||||||
|
|
||||||
info, err := os.Stat(path)
|
|
||||||
if err != nil {
|
|
||||||
if os.IsNotExist(err) {
|
|
||||||
return errors.New("folder does not exist")
|
|
||||||
}
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
if !info.IsDir() {
|
|
||||||
return errors.New("path is a file, not a directory")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return os.RemoveAll(path)
|
return os.RemoveAll(path)
|
||||||
|
|||||||
+41
-4
@@ -51,6 +51,7 @@ type FsTree struct {
|
|||||||
lines map[int]*FsNode // flattened view of nodes for easy line access, map so that I can handle blank padding
|
lines map[int]*FsNode // flattened view of nodes for easy line access, map so that I can handle blank padding
|
||||||
selectedNode *FsNode
|
selectedNode *FsNode
|
||||||
hoveredNode *FsNode
|
hoveredNode *FsNode
|
||||||
|
errMsg string
|
||||||
}
|
}
|
||||||
|
|
||||||
// ==================== Bubble Tea Interface Implementation ====================
|
// ==================== Bubble Tea Interface Implementation ====================
|
||||||
@@ -61,6 +62,7 @@ func (t *FsTree) Init() tea.Cmd {
|
|||||||
func (t *FsTree) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
|
func (t *FsTree) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
|
||||||
switch m := msg.(type) {
|
switch m := msg.(type) {
|
||||||
case tea.KeyMsg:
|
case tea.KeyMsg:
|
||||||
|
t.errMsg = ""
|
||||||
switch m.String() {
|
switch m.String() {
|
||||||
case "up", "k":
|
case "up", "k":
|
||||||
_ = t.MoveUp()
|
_ = t.MoveUp()
|
||||||
@@ -69,16 +71,29 @@ func (t *FsTree) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
|
|||||||
case "enter", " ":
|
case "enter", " ":
|
||||||
_ = t.ToggleSelectedExpand()
|
_ = t.ToggleSelectedExpand()
|
||||||
case "n": // new file
|
case "n": // new file
|
||||||
_ = t.CreateNode(t.selectedNode, "new_file.txt", FileNode)
|
err := t.CreateNode(t.selectedNode, "new_file.txt", FileNode)
|
||||||
|
if err != nil {
|
||||||
|
t.errMsg = err.Error()
|
||||||
|
}
|
||||||
case "N": // new folder
|
case "N": // new folder
|
||||||
_ = t.CreateNode(t.selectedNode, "new_folder", FolderNode)
|
err := t.CreateNode(t.selectedNode, "new_folder", FolderNode)
|
||||||
|
if err != nil {
|
||||||
|
t.errMsg = err.Error()
|
||||||
|
}
|
||||||
case "C": // new root node
|
case "C": // new root node
|
||||||
_ = t.CreateNode(t.root, "new_root_folder", FolderNode)
|
err := t.CreateNode(t.root, "new_root_folder", FolderNode)
|
||||||
|
if err != nil {
|
||||||
|
t.errMsg = err.Error()
|
||||||
|
}
|
||||||
case "d", "delete": // delete node
|
case "d", "delete": // delete node
|
||||||
_ = t.DeleteNode(t.selectedNode)
|
err := t.DeleteNode(t.selectedNode)
|
||||||
|
if err != nil {
|
||||||
|
t.errMsg = err.Error()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
case tea.MouseMsg:
|
case tea.MouseMsg:
|
||||||
|
t.errMsg = ""
|
||||||
t.hoveredNode = t.lines[m.Y] // hover
|
t.hoveredNode = t.lines[m.Y] // hover
|
||||||
|
|
||||||
// click
|
// click
|
||||||
@@ -96,6 +111,10 @@ func (t *FsTree) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (t *FsTree) View() string {
|
func (t *FsTree) View() string {
|
||||||
|
if t.errMsg != "" {
|
||||||
|
return t.errMsg
|
||||||
|
}
|
||||||
|
|
||||||
builder := &strings.Builder{}
|
builder := &strings.Builder{}
|
||||||
t.renderNode(t.root, 0, builder)
|
t.renderNode(t.root, 0, builder)
|
||||||
return builder.String()
|
return builder.String()
|
||||||
@@ -131,6 +150,11 @@ func (t *FsTree) DeleteNode(node *FsNode) error {
|
|||||||
return errors.New("node to delete must have a parent")
|
return errors.New("node to delete must have a parent")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// materialise
|
||||||
|
if err := deletePath(node.path); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
t.selectedNode = node.prev // cannot be next as subfolder/file deletion
|
t.selectedNode = node.prev // cannot be next as subfolder/file deletion
|
||||||
parent.children = utils.RemoveFromSlice(parent.children, node)
|
parent.children = utils.RemoveFromSlice(parent.children, node)
|
||||||
|
|
||||||
@@ -303,6 +327,19 @@ func (t *FsTree) CreateNode(folder *FsNode, name string, nodeType FsNodeType) er
|
|||||||
}
|
}
|
||||||
|
|
||||||
path := filepath.Join(folder.path, name)
|
path := filepath.Join(folder.path, name)
|
||||||
|
// materialise it first
|
||||||
|
if nodeType == FileNode {
|
||||||
|
err := createFile(path, []byte{})
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
} else if nodeType == FolderNode {
|
||||||
|
err := createFolder(path)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
expanded := false
|
expanded := false
|
||||||
if nodeType == FolderNode {
|
if nodeType == FolderNode {
|
||||||
expanded = true
|
expanded = true
|
||||||
|
|||||||
Reference in New Issue
Block a user