Skip to content

Commit 56c9d5a

Browse files
authored
Add a "Copy to clipboard" menu to the Commit Files panel (#4271)
- **PR Description** Add a "Copy to clipboard" menu to the Commit Files panel This is very similar to the same menu in the Files panel, except that it works on whatever diff is currently shown in the main view, including range diffs either in diffing mode (shift-W), or from a range selection of commits. The menu has some code duplication with the existing menu in the Files panel, but actually not so much. The first two menu items could be unified once we have generalized the filetrees, but these are pretty trivial; the other two menu items are sufficiently different that unifying them is not practical, I think. Fixes #4254.
2 parents e15e495 + c919681 commit 56c9d5a

19 files changed

+223
-45
lines changed

docs/keybindings/Keybindings_en.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ _Legend: `<c-b>` means ctrl+b, `<a-b>` means alt+b, `B` means shift+b_
5656
| Key | Action | Info |
5757
|-----|--------|-------------|
5858
| `` <c-o> `` | Copy path to clipboard | |
59+
| `` y `` | Copy to clipboard | |
5960
| `` c `` | Checkout | Checkout file. This replaces the file in your working tree with the version from the selected commit. |
6061
| `` d `` | Remove | Discard this commit's changes to this file. This runs an interactive rebase in the background, so you may get a merge conflict if a later commit also changes this file. |
6162
| `` o `` | Open file | Open file in default application. |

docs/keybindings/Keybindings_ja.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,7 @@ If you would instead like to start an interactive rebase from the selected commi
134134
| Key | Action | Info |
135135
|-----|--------|-------------|
136136
| `` <c-o> `` | ファイル名をクリップボードにコピー | |
137+
| `` y `` | Copy to clipboard | |
137138
| `` c `` | チェックアウト | Checkout file. This replaces the file in your working tree with the version from the selected commit. |
138139
| `` d `` | Remove | Discard this commit's changes to this file. This runs an interactive rebase in the background, so you may get a merge conflict if a later commit also changes this file. |
139140
| `` o `` | ファイルを開く | Open file in default application. |

docs/keybindings/Keybindings_ko.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -299,6 +299,7 @@ If you would instead like to start an interactive rebase from the selected commi
299299
| Key | Action | Info |
300300
|-----|--------|-------------|
301301
| `` <c-o> `` | 파일명을 클립보드에 복사 | |
302+
| `` y `` | 클립보드에 복사 | |
302303
| `` c `` | 체크아웃 | Checkout file |
303304
| `` d `` | Remove | Discard this commit's changes to this file |
304305
| `` o `` | 파일 닫기 | Open file in default application. |

docs/keybindings/Keybindings_nl.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,7 @@ _Legend: `<c-b>` means ctrl+b, `<a-b>` means alt+b, `B` means shift+b_
129129
| Key | Action | Info |
130130
|-----|--------|-------------|
131131
| `` <c-o> `` | Kopieer de bestandsnaam naar het klembord | |
132+
| `` y `` | Copy to clipboard | |
132133
| `` c `` | Uitchecken | Bestand uitchecken |
133134
| `` d `` | Remove | Uitsluit deze commit zijn veranderingen aan dit bestand |
134135
| `` o `` | Open bestand | Open file in default application. |

docs/keybindings/Keybindings_pl.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -238,6 +238,7 @@ Jeśli chcesz zamiast tego rozpocząć interaktywny rebase od wybranego commita,
238238
| Key | Action | Info |
239239
|-----|--------|-------------|
240240
| `` <c-o> `` | Kopiuj ścieżkę do schowka | |
241+
| `` y `` | Kopiuj do schowka | |
241242
| `` c `` | Przełącz | Przełącz plik. Zastępuje plik w twoim drzewie roboczym wersją z wybranego commita. |
242243
| `` d `` | Usuń | Odrzuć zmiany w tym pliku z tego commita. Uruchamia interaktywny rebase w tle, więc możesz otrzymać konflikt scalania, jeśli późniejszy commit również zmienia ten plik. |
243244
| `` o `` | Otwórz plik | Otwórz plik w domyślnej aplikacji. |

docs/keybindings/Keybindings_pt.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,7 @@ Veja a documentação:
135135
| Key | Action | Info |
136136
|-----|--------|-------------|
137137
| `` <c-o> `` | Copy path to clipboard | |
138+
| `` y `` | Copy to clipboard | |
138139
| `` c `` | Verificar | Checkout file. This replaces the file in your working tree with the version from the selected commit. |
139140
| `` d `` | Remove | Discard this commit's changes to this file. This runs an interactive rebase in the background, so you may get a merge conflict if a later commit also changes this file. |
140141
| `` o `` | Abrir arquivo | Abrir arquivo no aplicativo padrão. |

docs/keybindings/Keybindings_ru.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -261,6 +261,7 @@ If you would instead like to start an interactive rebase from the selected commi
261261
| Key | Action | Info |
262262
|-----|--------|-------------|
263263
| `` <c-o> `` | Скопировать название файла в буфер обмена | |
264+
| `` y `` | Copy to clipboard | |
264265
| `` c `` | Переключить | Переключить файл |
265266
| `` d `` | Remove | Отменить изменения коммита в этом файле |
266267
| `` o `` | Открыть файл | Open file in default application. |

docs/keybindings/Keybindings_zh-CN.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -186,6 +186,7 @@ _图例:`<c-b>` 意味着ctrl+b, `<a-b>意味着Alt+b, `B` 意味着shift+b_
186186
| Key | Action | Info |
187187
|-----|--------|-------------|
188188
| `` <c-o> `` | 将文件名复制到剪贴板 | |
189+
| `` y `` | 复制到剪贴板 | |
189190
| `` c `` | 检出 | 检出文件 |
190191
| `` d `` | 删除 | 放弃对此文件的提交变更 |
191192
| `` o `` | 打开文件 | 使用默认程序打开该文件 |

docs/keybindings/Keybindings_zh-TW.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -210,6 +210,7 @@ If you would instead like to start an interactive rebase from the selected commi
210210
| Key | Action | Info |
211211
|-----|--------|-------------|
212212
| `` <c-o> `` | 複製檔案名稱到剪貼簿 | |
213+
| `` y `` | 複製到剪貼簿 | |
213214
| `` c `` | 檢出 | 檢出檔案 |
214215
| `` d `` | Remove | Discard this commit's changes to this file. This runs an interactive rebase in the background, so you may get a merge conflict if a later commit also changes this file. |
215216
| `` o `` | 開啟檔案 | 使用預設軟體開啟 |

pkg/gui/controllers/commits_files_controller.go

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,12 @@ func NewCommitFilesController(
4141

4242
func (self *CommitFilesController) GetKeybindings(opts types.KeybindingsOpts) []*types.Binding {
4343
bindings := []*types.Binding{
44+
{
45+
Key: opts.GetKey(opts.Config.Files.CopyFileInfoToClipboard),
46+
Handler: self.openCopyMenu,
47+
Description: self.c.Tr.CopyToClipboardMenu,
48+
OpensMenu: true,
49+
},
4450
{
4551
Key: opts.GetKey(opts.Config.CommitFiles.CheckoutCommitFile),
4652
Handler: self.withItem(self.checkout),
@@ -181,6 +187,77 @@ func (self *CommitFilesController) onClickMain(opts gocui.ViewMouseBindingOpts)
181187
return self.enterCommitFile(node, types.OnFocusOpts{ClickedWindowName: "main", ClickedViewLineIdx: opts.Y})
182188
}
183189

190+
func (self *CommitFilesController) copyDiffToClipboard(path string, toastMessage string) error {
191+
from, to := self.context().GetFromAndToForDiff()
192+
from, reverse := self.c.Modes().Diffing.GetFromAndReverseArgsForDiff(from)
193+
194+
cmdObj := self.c.Git().WorkingTree.ShowFileDiffCmdObj(from, to, reverse, path, true)
195+
diff, err := cmdObj.RunWithOutput()
196+
if err != nil {
197+
return err
198+
}
199+
if err := self.c.OS().CopyToClipboard(diff); err != nil {
200+
return err
201+
}
202+
self.c.Toast(toastMessage)
203+
return nil
204+
}
205+
206+
func (self *CommitFilesController) openCopyMenu() error {
207+
node := self.context().GetSelected()
208+
209+
copyNameItem := &types.MenuItem{
210+
Label: self.c.Tr.CopyFileName,
211+
OnPress: func() error {
212+
if err := self.c.OS().CopyToClipboard(node.Name()); err != nil {
213+
return err
214+
}
215+
self.c.Toast(self.c.Tr.FileNameCopiedToast)
216+
return nil
217+
},
218+
DisabledReason: self.require(self.singleItemSelected())(),
219+
Key: 'n',
220+
}
221+
copyPathItem := &types.MenuItem{
222+
Label: self.c.Tr.CopyFilePath,
223+
OnPress: func() error {
224+
if err := self.c.OS().CopyToClipboard(node.Path); err != nil {
225+
return err
226+
}
227+
self.c.Toast(self.c.Tr.FilePathCopiedToast)
228+
return nil
229+
},
230+
DisabledReason: self.require(self.singleItemSelected())(),
231+
Key: 'p',
232+
}
233+
copyFileDiffItem := &types.MenuItem{
234+
Label: self.c.Tr.CopySelectedDiff,
235+
OnPress: func() error {
236+
return self.copyDiffToClipboard(node.GetPath(), self.c.Tr.FileDiffCopiedToast)
237+
},
238+
DisabledReason: self.require(self.singleItemSelected())(),
239+
Key: 's',
240+
}
241+
copyAllDiff := &types.MenuItem{
242+
Label: self.c.Tr.CopyAllFilesDiff,
243+
OnPress: func() error {
244+
return self.copyDiffToClipboard(".", self.c.Tr.AllFilesDiffCopiedToast)
245+
},
246+
DisabledReason: self.require(self.itemsSelected())(),
247+
Key: 'a',
248+
}
249+
250+
return self.c.Menu(types.CreateMenuOptions{
251+
Title: self.c.Tr.CopyToClipboardMenu,
252+
Items: []*types.MenuItem{
253+
copyNameItem,
254+
copyPathItem,
255+
copyFileDiffItem,
256+
copyAllDiff,
257+
},
258+
})
259+
}
260+
184261
func (self *CommitFilesController) checkout(node *filetree.CommitFileNode) error {
185262
self.c.LogAction(self.c.Tr.Actions.CheckoutFile)
186263
if err := self.c.Git().WorkingTree.CheckoutFile(self.context().GetRef().RefName(), node.GetPath()); err != nil {

0 commit comments

Comments
 (0)