Skip to content

Add "Absolute path" item to the file view's copy menu #4410

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Mar 25, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 17 additions & 3 deletions pkg/gui/controllers/commits_files_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package controllers

import (
"errors"
"path/filepath"
"strings"

"github.com/jesseduffield/gocui"
Expand Down Expand Up @@ -228,8 +229,8 @@ func (self *CommitFilesController) openCopyMenu() error {
DisabledReason: self.require(self.singleItemSelected())(),
Key: 'n',
}
copyPathItem := &types.MenuItem{
Label: self.c.Tr.CopyFilePath,
copyRelativePathItem := &types.MenuItem{
Label: self.c.Tr.CopyRelativeFilePath,
OnPress: func() error {
if err := self.c.OS().CopyToClipboard(node.GetPath()); err != nil {
return err
Expand All @@ -240,6 +241,18 @@ func (self *CommitFilesController) openCopyMenu() error {
DisabledReason: self.require(self.singleItemSelected())(),
Key: 'p',
}
copyAbsolutePathItem := &types.MenuItem{
Label: self.c.Tr.CopyAbsoluteFilePath,
OnPress: func() error {
if err := self.c.OS().CopyToClipboard(filepath.Join(self.c.Git().RepoPaths.RepoPath(), node.GetPath())); err != nil {
return err
}
self.c.Toast(self.c.Tr.FilePathCopiedToast)
return nil
},
DisabledReason: self.require(self.singleItemSelected())(),
Key: 'P',
}
copyFileDiffItem := &types.MenuItem{
Label: self.c.Tr.CopySelectedDiff,
OnPress: func() error {
Expand Down Expand Up @@ -282,7 +295,8 @@ func (self *CommitFilesController) openCopyMenu() error {
Title: self.c.Tr.CopyToClipboardMenu,
Items: []*types.MenuItem{
copyNameItem,
copyPathItem,
copyRelativePathItem,
copyAbsolutePathItem,
copyFileDiffItem,
copyAllDiff,
copyFileContentItem,
Expand Down
20 changes: 17 additions & 3 deletions pkg/gui/controllers/files_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package controllers
import (
"errors"
"fmt"
"path/filepath"
"strings"

"github.com/jesseduffield/gocui"
Expand Down Expand Up @@ -976,8 +977,8 @@ func (self *FilesController) openCopyMenu() error {
DisabledReason: self.require(self.singleItemSelected())(),
Key: 'n',
}
copyPathItem := &types.MenuItem{
Label: self.c.Tr.CopyFilePath,
copyRelativePathItem := &types.MenuItem{
Label: self.c.Tr.CopyRelativeFilePath,
OnPress: func() error {
if err := self.c.OS().CopyToClipboard(node.GetPath()); err != nil {
return err
Expand All @@ -988,6 +989,18 @@ func (self *FilesController) openCopyMenu() error {
DisabledReason: self.require(self.singleItemSelected())(),
Key: 'p',
}
copyAbsolutePathItem := &types.MenuItem{
Label: self.c.Tr.CopyAbsoluteFilePath,
OnPress: func() error {
if err := self.c.OS().CopyToClipboard(filepath.Join(self.c.Git().RepoPaths.RepoPath(), node.GetPath())); err != nil {
return err
}
self.c.Toast(self.c.Tr.FilePathCopiedToast)
return nil
},
DisabledReason: self.require(self.singleItemSelected())(),
Key: 'P',
}
copyFileDiffItem := &types.MenuItem{
Label: self.c.Tr.CopySelectedDiff,
Tooltip: self.c.Tr.CopyFileDiffTooltip,
Expand Down Expand Up @@ -1044,7 +1057,8 @@ func (self *FilesController) openCopyMenu() error {
Title: self.c.Tr.CopyToClipboardMenu,
Items: []*types.MenuItem{
copyNameItem,
copyPathItem,
copyRelativePathItem,
copyAbsolutePathItem,
copyFileDiffItem,
copyAllDiff,
},
Expand Down
6 changes: 4 additions & 2 deletions pkg/i18n/english.go
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,8 @@ type TranslationSet struct {
FileFilter string
CopyToClipboardMenu string
CopyFileName string
CopyFilePath string
CopyRelativeFilePath string
CopyAbsoluteFilePath string
CopyFileDiffTooltip string
CopySelectedDiff string
CopyAllFilesDiff string
Expand Down Expand Up @@ -1120,7 +1121,8 @@ func EnglishTranslationSet() *TranslationSet {
FileFilter: "Filter files by status",
CopyToClipboardMenu: "Copy to clipboard",
CopyFileName: "File name",
CopyFilePath: "Path",
CopyRelativeFilePath: "Relative path",
CopyAbsoluteFilePath: "Absolute path",
CopyFileDiffTooltip: "If there are staged items, this command considers only them. Otherwise, it considers all the unstaged ones.",
CopySelectedDiff: "Diff of selected file",
CopyAllFilesDiff: "Diff of all files",
Expand Down
17 changes: 16 additions & 1 deletion pkg/integration/tests/diff/copy_to_clipboard.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package diff

import (
"os"

"github.com/jesseduffield/lazygit/pkg/config"
. "github.com/jesseduffield/lazygit/pkg/integration/components"
)
Expand Down Expand Up @@ -63,14 +65,27 @@ var CopyToClipboard = NewIntegrationTest(NewIntegrationTestArgs{
Tap(func() {
t.ExpectPopup().Menu().
Title(Equals("Copy to clipboard")).
Select(Contains("Path")).
Select(Contains("Relative path")).
Confirm().
Tap(func() {
t.ExpectToast(Equals("File path copied to clipboard"))
expectClipboard(t, Equals("dir/file1"))
})
}).
Press(keys.Files.CopyFileInfoToClipboard).
Tap(func() {
t.ExpectPopup().Menu().
Title(Equals("Copy to clipboard")).
Select(Contains("Absolute path")).
Confirm().
Tap(func() {
t.ExpectToast(Equals("File path copied to clipboard"))
repoDir, _ := os.Getwd()
// On windows the following path would have backslashes, but we don't run integration tests on windows yet.
expectClipboard(t, Equals(repoDir+"/dir/file1"))
})
}).
Press(keys.Files.CopyFileInfoToClipboard).
Tap(func() {
t.ExpectPopup().Menu().
Title(Equals("Copy to clipboard")).
Expand Down
22 changes: 20 additions & 2 deletions pkg/integration/tests/file/copy_menu.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package file

import (
"os"

"github.com/jesseduffield/lazygit/pkg/config"
. "github.com/jesseduffield/lazygit/pkg/integration/components"
)
Expand Down Expand Up @@ -103,20 +105,36 @@ var CopyMenu = NewIntegrationTest(NewIntegrationTestArgs{
expectClipboard(t, Equals("1-unstaged_file"))
})

// Copy file path
// Copy relative file path
t.Views().Files().
Press(keys.Files.CopyFileInfoToClipboard).
Tap(func() {
t.ExpectPopup().Menu().
Title(Equals("Copy to clipboard")).
Select(Contains("Path")).
Select(Contains("Relative path")).
Confirm()

t.ExpectToast(Equals("File path copied to clipboard"))

expectClipboard(t, Equals("dir/1-unstaged_file"))
})

// Copy absolute file path
t.Views().Files().
Press(keys.Files.CopyFileInfoToClipboard).
Tap(func() {
t.ExpectPopup().Menu().
Title(Equals("Copy to clipboard")).
Select(Contains("Absolute path")).
Confirm()

t.ExpectToast(Equals("File path copied to clipboard"))

repoDir, _ := os.Getwd()
// On windows the following path would have backslashes, but we don't run integration tests on windows yet.
expectClipboard(t, Equals(repoDir+"/dir/1-unstaged_file"))
})

// Selected path diff on a single (unstaged) file
t.Views().Files().
Press(keys.Files.CopyFileInfoToClipboard).
Expand Down