From bd1f42c08c79a2e0ebb88f218d28af18b85b02b0 Mon Sep 17 00:00:00 2001 From: mistakenelf Date: Tue, 26 Mar 2024 19:34:38 -0400 Subject: [PATCH] feat: move directory items --- filesystem/filesystem.go | 39 ++++++++++++++++++++++-------- filetree/commands.go | 52 ++++++++++++++++++---------------------- filetree/model.go | 15 ++++++------ filetree/update.go | 34 ++++++++++++-------------- internal/tui/commands.go | 8 +++---- internal/tui/helpers.go | 2 +- internal/tui/model.go | 1 + internal/tui/update.go | 16 +++++++++---- 8 files changed, 92 insertions(+), 75 deletions(-) diff --git a/filesystem/filesystem.go b/filesystem/filesystem.go index b8a3cbb..628dfe8 100644 --- a/filesystem/filesystem.go +++ b/filesystem/filesystem.go @@ -431,26 +431,45 @@ func CopyFile(name string) error { return errors.Unwrap(err) } -// CopyDirectory copies a directory given a name. -func CopyDirectory(name string) error { +// CopyDirectory copies a directory given a path. +func CopyDirectory(pathname string) error { + name := filepath.Base(pathname) output := fmt.Sprintf("%s_%d", name, time.Now().Unix()) - err := filepath.Walk(name, func(path string, info os.FileInfo, err error) error { - relPath := strings.Replace(path, name, "", 1) + err := filepath.Walk(pathname, func(path string, info os.FileInfo, err error) error { + if err != nil { + return err // Return early if there's an error walking the path + } + + relPath, err := filepath.Rel(pathname, path) + if err != nil { + return err // Return if there's an error getting the relative path + } + + targetPath := filepath.Join(output, relPath) if info.IsDir() { - return fmt.Errorf("%w", os.Mkdir(filepath.Join(output, relPath), os.ModePerm)) + return os.Mkdir(targetPath, os.ModePerm) } - var data, err1 = os.ReadFile(filepath.Join(filepath.Clean(name), filepath.Clean(relPath))) - if err1 != nil { - return errors.Unwrap(err) + data, err := os.ReadFile(path) + if err != nil { + return err // Return if there's an error reading the file } - return fmt.Errorf("%w", os.WriteFile(filepath.Join(output, relPath), data, os.ModePerm)) + err = os.WriteFile(targetPath, data, os.ModePerm) + if err != nil { + return err // Return if there's an error writing the file + } + + return nil }) - return errors.Unwrap(err) + if err != nil { + return err // Return the final error, if any + } + + return nil } // GetDirectoryItemSize calculates the size of a directory or file. diff --git a/filetree/commands.go b/filetree/commands.go index e96c613..b8be9b2 100644 --- a/filetree/commands.go +++ b/filetree/commands.go @@ -82,6 +82,7 @@ func (m Model) GetDirectoryListingCmd(directoryName string) tea.Cmd { var err error var directoryItems []DirectoryItem var files []fs.DirEntry + var directoryPath string if directoryName == filesystem.HomeDirectory { directoryName, err = filesystem.GetHomeDirectory() @@ -90,7 +91,17 @@ func (m Model) GetDirectoryListingCmd(directoryName string) tea.Cmd { } } - directoryInfo, err := os.Stat(directoryName) + if !filepath.IsAbs(directoryName) { + directoryPath, err = filepath.Abs(directoryName) + fmt.Println(directoryPath) + if err != nil { + return errorMsg(err.Error()) + } + } else { + directoryPath = directoryName + } + + directoryInfo, err := os.Stat(directoryPath) if err != nil { return errorMsg(err.Error()) } @@ -99,11 +110,6 @@ func (m Model) GetDirectoryListingCmd(directoryName string) tea.Cmd { return nil } - err = os.Chdir(directoryName) - if err != nil { - return errorMsg(err.Error()) - } - if !m.showDirectoriesOnly && !m.showFilesOnly { files, err = filesystem.GetDirectoryListing(directoryName, m.showHidden) if err != nil { @@ -122,11 +128,6 @@ func (m Model) GetDirectoryListingCmd(directoryName string) tea.Cmd { } } - workingDirectory, err := filesystem.GetWorkingDirectory() - if err != nil { - return errorMsg(err.Error()) - } - for _, file := range files { fileInfo, err := file.Info() if err != nil { @@ -136,20 +137,19 @@ func (m Model) GetDirectoryListingCmd(directoryName string) tea.Cmd { fileSize := ConvertBytesToSizeString(fileInfo.Size()) directoryItems = append(directoryItems, DirectoryItem{ - Name: file.Name(), - Details: fileInfo.Mode().String(), - Path: filepath.Join(workingDirectory, file.Name()), - Extension: filepath.Ext(fileInfo.Name()), - IsDirectory: fileInfo.IsDir(), - CurrentDirectory: workingDirectory, - FileInfo: fileInfo, - FileSize: fileSize, + Name: file.Name(), + Details: fileInfo.Mode().String(), + Path: filepath.Join(directoryPath, file.Name()), + Extension: filepath.Ext(fileInfo.Name()), + IsDirectory: fileInfo.IsDir(), + FileInfo: fileInfo, + FileSize: fileSize, }) } return getDirectoryListingMsg{ files: directoryItems, - workingDirectory: workingDirectory, + workingDirectory: directoryPath, } } } @@ -211,20 +211,14 @@ func copyDirectoryItemCmd(name string, isDirectory bool) tea.Cmd { } // copyToClipboardCmd copies the provided string to the clipboard. -func copyToClipboardCmd(name string) tea.Cmd { +func copyToClipboardCmd(path string) tea.Cmd { return func() tea.Msg { - workingDir, err := filesystem.GetWorkingDirectory() - if err != nil { - return errorMsg(err.Error()) - } - - filePath := filepath.Join(workingDir, name) - err = clipboard.WriteAll(filePath) + err := clipboard.WriteAll(path) if err != nil { return errorMsg(err.Error()) } - return copyToClipboardMsg(fmt.Sprintf("%s %s %s", "Successfully copied", filePath, "to clipboard")) + return copyToClipboardMsg(fmt.Sprintf("%s %s %s", "Successfully copied", path, "to clipboard")) } } diff --git a/filetree/model.go b/filetree/model.go index 88d9eae..55cdab2 100644 --- a/filetree/model.go +++ b/filetree/model.go @@ -10,14 +10,13 @@ import ( ) type DirectoryItem struct { - Name string - Details string - Path string - Extension string - FileSize string - CurrentDirectory string - IsDirectory bool - FileInfo os.FileInfo + Name string + Details string + Path string + Extension string + FileSize string + IsDirectory bool + FileInfo os.FileInfo } type Model struct { diff --git a/filetree/update.go b/filetree/update.go index 5ba79dd..ce62b3e 100644 --- a/filetree/update.go +++ b/filetree/update.go @@ -35,7 +35,7 @@ func (m Model) Update(msg tea.Msg) (Model, tea.Cmd) { m.CreatingNewFile = false m.CreatingNewDirectory = false - return m, m.GetDirectoryListingCmd(filesystem.CurrentDirectory) + return m, m.GetDirectoryListingCmd(m.CurrentDirectory) case copyToClipboardMsg: cmds = append(cmds, m.NewStatusMessageCmd( lipgloss.NewStyle(). @@ -45,12 +45,12 @@ func (m Model) Update(msg tea.Msg) (Model, tea.Cmd) { m.CreatingNewFile = false m.CreatingNewDirectory = false - return m, m.GetDirectoryListingCmd(filesystem.CurrentDirectory) + return m, m.GetDirectoryListingCmd(m.CurrentDirectory) case createDirectoryMsg: m.CreatingNewDirectory = false m.CreatingNewFile = false - return m, m.GetDirectoryListingCmd(filesystem.CurrentDirectory) + return m, m.GetDirectoryListingCmd(m.CurrentDirectory) case getDirectoryListingMsg: if msg.files != nil { m.files = msg.files @@ -165,7 +165,7 @@ func (m Model) Update(msg tea.Msg) (Model, tea.Cmd) { m.showHidden = !m.showHidden - return m, m.GetDirectoryListingCmd(filesystem.CurrentDirectory) + return m, m.GetDirectoryListingCmd(m.CurrentDirectory) case key.Matches(msg, m.keyMap.OpenDirectory): if m.CreatingNewFile || m.CreatingNewDirectory { return m, nil @@ -179,27 +179,23 @@ func (m Model) Update(msg tea.Msg) (Model, tea.Cmd) { return m, nil } - if len(m.files) == 0 { - return m, m.GetDirectoryListingCmd(filepath.Dir(m.CurrentDirectory)) - } - return m, m.GetDirectoryListingCmd( - filepath.Dir(m.files[m.Cursor].CurrentDirectory), + filepath.Dir(m.CurrentDirectory), ) case key.Matches(msg, m.keyMap.CopyPathToClipboard): if m.CreatingNewFile || m.CreatingNewDirectory { return m, nil } - return m, copyToClipboardCmd(m.files[m.Cursor].Name) + return m, copyToClipboardCmd(m.files[m.Cursor].Path) case key.Matches(msg, m.keyMap.CopyDirectoryItem): if m.CreatingNewFile || m.CreatingNewDirectory { return m, nil } return m, tea.Sequence( - copyDirectoryItemCmd(m.files[m.Cursor].Name, m.files[m.Cursor].IsDirectory), - m.GetDirectoryListingCmd(filesystem.CurrentDirectory), + copyDirectoryItemCmd(m.files[m.Cursor].Path, m.files[m.Cursor].IsDirectory), + m.GetDirectoryListingCmd(m.CurrentDirectory), ) case key.Matches(msg, m.keyMap.DeleteDirectoryItem): if m.CreatingNewFile || m.CreatingNewDirectory { @@ -207,8 +203,8 @@ func (m Model) Update(msg tea.Msg) (Model, tea.Cmd) { } return m, tea.Sequence( - deleteDirectoryItemCmd(m.files[m.Cursor].Name, m.files[m.Cursor].IsDirectory), - m.GetDirectoryListingCmd(filesystem.CurrentDirectory), + deleteDirectoryItemCmd(m.files[m.Cursor].Path, m.files[m.Cursor].IsDirectory), + m.GetDirectoryListingCmd(m.CurrentDirectory), ) case key.Matches(msg, m.keyMap.ZipDirectoryItem): if m.CreatingNewFile || m.CreatingNewDirectory { @@ -216,8 +212,8 @@ func (m Model) Update(msg tea.Msg) (Model, tea.Cmd) { } return m, tea.Sequence( - zipDirectoryCmd(m.files[m.Cursor].Name), - m.GetDirectoryListingCmd(filesystem.CurrentDirectory), + zipDirectoryCmd(m.files[m.Cursor].Path), + m.GetDirectoryListingCmd(m.CurrentDirectory), ) case key.Matches(msg, m.keyMap.UnzipDirectoryItem): if m.CreatingNewFile || m.CreatingNewDirectory { @@ -226,7 +222,7 @@ func (m Model) Update(msg tea.Msg) (Model, tea.Cmd) { return m, tea.Sequence( unzipDirectoryCmd(m.files[m.Cursor].Name), - m.GetDirectoryListingCmd(filesystem.CurrentDirectory), + m.GetDirectoryListingCmd(m.CurrentDirectory), ) case key.Matches(msg, m.keyMap.ShowDirectoriesOnly): if m.CreatingNewFile || m.CreatingNewDirectory { @@ -236,7 +232,7 @@ func (m Model) Update(msg tea.Msg) (Model, tea.Cmd) { m.showDirectoriesOnly = !m.showDirectoriesOnly m.showFilesOnly = false - return m, m.GetDirectoryListingCmd(filesystem.CurrentDirectory) + return m, m.GetDirectoryListingCmd(m.CurrentDirectory) case key.Matches(msg, m.keyMap.ShowFilesOnly): if m.CreatingNewFile || m.CreatingNewDirectory { return m, nil @@ -245,7 +241,7 @@ func (m Model) Update(msg tea.Msg) (Model, tea.Cmd) { m.showFilesOnly = !m.showFilesOnly m.showDirectoriesOnly = false - return m, m.GetDirectoryListingCmd(filesystem.CurrentDirectory) + return m, m.GetDirectoryListingCmd(m.CurrentDirectory) case key.Matches(msg, m.keyMap.WriteSelectionPath): if m.CreatingNewFile || m.CreatingNewDirectory { return m, nil diff --git a/internal/tui/commands.go b/internal/tui/commands.go index e3179e2..94614f4 100644 --- a/internal/tui/commands.go +++ b/internal/tui/commands.go @@ -36,15 +36,15 @@ func (m *model) openFileCmd() tea.Cmd { case selectedFile.Extension == ".png" || selectedFile.Extension == ".jpg" || selectedFile.Extension == ".jpeg": m.state = showImageState - return m.image.SetFileNameCmd(selectedFile.Name) + return m.image.SetFileNameCmd(selectedFile.Path) case selectedFile.Extension == ".md" && m.config.PrettyMarkdown: m.state = showMarkdownState - return m.markdown.SetFileNameCmd(selectedFile.Name) + return m.markdown.SetFileNameCmd(selectedFile.Path) case selectedFile.Extension == ".pdf": m.state = showPdfState - return m.pdf.SetFileNameCmd(selectedFile.Name) + return m.pdf.SetFileNameCmd(selectedFile.Path) case contains(forbiddenExtensions, selectedFile.Extension): return m.newStatusMessageCmd(lipgloss.NewStyle(). Foreground(lipgloss.Color("#cc241d")). @@ -53,7 +53,7 @@ func (m *model) openFileCmd() tea.Cmd { default: m.state = showCodeState - return m.code.SetFileNameCmd(selectedFile.Name) + return m.code.SetFileNameCmd(selectedFile.Path) } } diff --git a/internal/tui/helpers.go b/internal/tui/helpers.go index 9d102aa..f5ee6fd 100644 --- a/internal/tui/helpers.go +++ b/internal/tui/helpers.go @@ -35,7 +35,7 @@ func (m *model) resetViewports() { func (m *model) updateStatusBar() { if m.filetree.GetSelectedItem().Name != "" { statusMessage := - m.filetree.GetSelectedItem().CurrentDirectory + + m.filetree.CurrentDirectory + lipgloss.NewStyle(). Padding(0, 1). Foreground(lipgloss.Color("#eab308")). diff --git a/internal/tui/model.go b/internal/tui/model.go index 08287f4..6081adb 100644 --- a/internal/tui/model.go +++ b/internal/tui/model.go @@ -71,6 +71,7 @@ func New(cfg Config) model { secondaryFiletree.SetTheme(cfg.Theme.SelectedTreeItemColor, cfg.Theme.UnselectedTreeItemColor) secondaryFiletree.SetSelectionPath(cfg.SelectionPath) secondaryFiletree.SetShowIcons(cfg.ShowIcons) + secondaryFiletree.SetDisabled(true) if cfg.ShowIcons { icons.ParseIcons() diff --git a/internal/tui/update.go b/internal/tui/update.go index 04e64d4..0422b23 100644 --- a/internal/tui/update.go +++ b/internal/tui/update.go @@ -61,9 +61,12 @@ func (m model) Update(msg tea.Msg) (tea.Model, tea.Cmd) { m.textinput.Reset() case key.Matches(msg, m.keyMap.MoveDirectoryItem): if m.activePane == 0 && !m.filetree.CreatingNewDirectory && !m.filetree.CreatingNewFile { - m.directoryBeforeMove = m.filetree.GetSelectedItem().CurrentDirectory + m.activePane = (m.activePane + 1) % 2 + m.directoryBeforeMove = m.filetree.CurrentDirectory m.state = showMoveState m.filetree.SetDisabled(true) + m.secondaryFiletree.SetDisabled(false) + cmds = append(cmds, m.secondaryFiletree.GetDirectoryListingCmd(m.filetree.CurrentDirectory)) } case key.Matches(msg, m.keyMap.ShowTextInput): if m.activePane == 0 && !m.filetree.CreatingNewDirectory && !m.filetree.CreatingNewFile { @@ -77,11 +80,12 @@ func (m model) Update(msg tea.Msg) (tea.Model, tea.Cmd) { m.textinput.Reset() } case key.Matches(msg, m.keyMap.Submit): - if m.filetree.CreatingNewFile { + switch { + case m.filetree.CreatingNewFile: cmds = append(cmds, m.filetree.CreateFileCmd(m.textinput.Value())) - } else if m.filetree.CreatingNewDirectory { + case m.filetree.CreatingNewDirectory: cmds = append(cmds, m.filetree.CreateDirectoryCmd(m.textinput.Value())) - } else { + default: cmds = append( cmds, m.filetree.MoveDirectoryItemCmd( @@ -102,6 +106,7 @@ func (m model) Update(msg tea.Msg) (tea.Model, tea.Cmd) { if m.activePane == 0 { m.filetree.SetDisabled(false) + m.secondaryFiletree.SetDisabled(true) m.disableAllViewports() } else { m.filetree.SetDisabled(true) @@ -122,6 +127,9 @@ func (m model) Update(msg tea.Msg) (tea.Model, tea.Cmd) { case showMarkdownState: m.disableAllViewports() m.markdown.SetViewportDisabled(false) + case showMoveState: + m.secondaryFiletree.SetDisabled(false) + m.disableAllViewports() } } }