From d458e78d95132a894d0577a31b3af643f070b3e6 Mon Sep 17 00:00:00 2001 From: Ryooooooga Date: Wed, 4 May 2022 21:20:45 +0900 Subject: [PATCH] feat: add ability to edit hunk --- docs/keybindings/Keybindings_en.md | 2 + docs/keybindings/Keybindings_nl.md | 2 + docs/keybindings/Keybindings_pl.md | 2 + docs/keybindings/Keybindings_zh.md | 2 + pkg/commands/git_commands/working_tree.go | 18 ++++++-- pkg/config/user_config.go | 2 + pkg/gui/keybindings.go | 7 ++++ pkg/gui/staging_panel.go | 51 +++++++++++++++++++++++ pkg/i18n/english.go | 2 + 9 files changed, 85 insertions(+), 3 deletions(-) diff --git a/docs/keybindings/Keybindings_en.md b/docs/keybindings/Keybindings_en.md index 5fe50cfd8..c20dc54bc 100644 --- a/docs/keybindings/Keybindings_en.md +++ b/docs/keybindings/Keybindings_en.md @@ -173,6 +173,7 @@ _This file is auto-generated. To update, make the changes in the pkg/i18n direct v: toggle drag select V: toggle drag select a: toggle select hunk + E: edit hunk ## Main Panel (Staging) @@ -192,6 +193,7 @@ _This file is auto-generated. To update, make the changes in the pkg/i18n direct v: toggle drag select V: toggle drag select a: toggle select hunk + E: edit hunk ## Reflog diff --git a/docs/keybindings/Keybindings_nl.md b/docs/keybindings/Keybindings_nl.md index 0fb4c8bb8..17b001908 100644 --- a/docs/keybindings/Keybindings_nl.md +++ b/docs/keybindings/Keybindings_nl.md @@ -173,6 +173,7 @@ _This file is auto-generated. To update, make the changes in the pkg/i18n direct v: toggle drag selecteer V: toggle drag selecteer a: toggle selecteer hunk + E: edit hunk ## Reflog @@ -230,6 +231,7 @@ _This file is auto-generated. To update, make the changes in the pkg/i18n direct v: toggle drag selecteer V: toggle drag selecteer a: toggle selecteer hunk + E: edit hunk ## Stash diff --git a/docs/keybindings/Keybindings_pl.md b/docs/keybindings/Keybindings_pl.md index b2e7eff11..12e4f536e 100644 --- a/docs/keybindings/Keybindings_pl.md +++ b/docs/keybindings/Keybindings_pl.md @@ -109,6 +109,7 @@ _This file is auto-generated. To update, make the changes in the pkg/i18n direct v: toggle drag select V: toggle drag select a: toggle select hunk + E: edit hunk ## Pliki @@ -169,6 +170,7 @@ _This file is auto-generated. To update, make the changes in the pkg/i18n direct v: toggle drag select V: toggle drag select a: toggle select hunk + E: edit hunk ## Reflog diff --git a/docs/keybindings/Keybindings_zh.md b/docs/keybindings/Keybindings_zh.md index 2393e9b49..95ea852b4 100644 --- a/docs/keybindings/Keybindings_zh.md +++ b/docs/keybindings/Keybindings_zh.md @@ -193,6 +193,7 @@ _This file is auto-generated. To update, make the changes in the pkg/i18n direct v: 切换拖动选择 V: 切换拖动选择 a: 切换选择区块 + E: edit hunk ## 标签页面 @@ -239,6 +240,7 @@ _This file is auto-generated. To update, make the changes in the pkg/i18n direct v: 切换拖动选择 V: 切换拖动选择 a: 切换选择区块 + E: edit hunk ## 正常 diff --git a/pkg/commands/git_commands/working_tree.go b/pkg/commands/git_commands/working_tree.go index cac93385a..5986392a8 100644 --- a/pkg/commands/git_commands/working_tree.go +++ b/pkg/commands/git_commands/working_tree.go @@ -255,12 +255,15 @@ func (self *WorkingTreeCommands) WorktreeFileDiffCmdObj(node models.IFile, plain } func (self *WorkingTreeCommands) ApplyPatch(patch string, flags ...string) error { - filepath := filepath.Join(self.os.GetTempDir(), utils.GetCurrentRepoName(), time.Now().Format("Jan _2 15.04.05.000000000")+".patch") - self.Log.Infof("saving temporary patch to %s", filepath) - if err := self.os.CreateFileWithContent(filepath, patch); err != nil { + filepath, err := self.SaveTemporaryPatch(patch) + if err != nil { return err } + return self.ApplyPatchFile(filepath, flags...) +} + +func (self *WorkingTreeCommands) ApplyPatchFile(filepath string, flags ...string) error { flagStr := "" for _, flag := range flags { flagStr += " --" + flag @@ -269,6 +272,15 @@ func (self *WorkingTreeCommands) ApplyPatch(patch string, flags ...string) error return self.cmd.New(fmt.Sprintf("git apply%s %s", flagStr, self.cmd.Quote(filepath))).Run() } +func (self *WorkingTreeCommands) SaveTemporaryPatch(patch string) (string, error) { + filepath := filepath.Join(self.os.GetTempDir(), utils.GetCurrentRepoName(), time.Now().Format("Jan _2 15.04.05.000000000")+".patch") + self.Log.Infof("saving temporary patch to %s", filepath) + if err := self.os.CreateFileWithContent(filepath, patch); err != nil { + return "", err + } + return filepath, nil +} + // ShowFileDiff get the diff of specified from and to. Typically this will be used for a single commit so it'll be 123abc^..123abc // but when we're in diff mode it could be any 'from' to any 'to'. The reverse flag is also here thanks to diff mode. func (self *WorkingTreeCommands) ShowFileDiff(from string, to string, reverse bool, fileName string, plain bool) (string, error) { diff --git a/pkg/config/user_config.go b/pkg/config/user_config.go index 95b3c87b5..4a059c0c3 100644 --- a/pkg/config/user_config.go +++ b/pkg/config/user_config.go @@ -269,6 +269,7 @@ type KeybindingMainConfig struct { ToggleDragSelectAlt string `yaml:"toggleDragSelect-alt"` ToggleSelectHunk string `yaml:"toggleSelectHunk"` PickBothHunks string `yaml:"pickBothHunks"` + EditSelectHunk string `yaml:"editSelectHunk"` } type KeybindingSubmodulesConfig struct { @@ -536,6 +537,7 @@ func GetDefaultConfig() *UserConfig { ToggleDragSelectAlt: "V", ToggleSelectHunk: "a", PickBothHunks: "b", + EditSelectHunk: "E", }, Submodules: KeybindingSubmodulesConfig{ Init: "i", diff --git a/pkg/gui/keybindings.go b/pkg/gui/keybindings.go index 772aa7b6e..a334d7f7a 100644 --- a/pkg/gui/keybindings.go +++ b/pkg/gui/keybindings.go @@ -543,6 +543,13 @@ func (self *Gui) GetInitialKeybindings() ([]*types.Binding, []*gocui.ViewMouseBi Handler: self.handleToggleSelectHunk, Description: self.c.Tr.ToggleSelectHunk, }, + { + ViewName: "main", + Contexts: []string{string(context.MAIN_PATCH_BUILDING_CONTEXT_KEY), string(context.MAIN_STAGING_CONTEXT_KEY)}, + Key: opts.GetKey(opts.Config.Main.EditSelectHunk), + Handler: self.handleEditHunk, + Description: self.c.Tr.EditHunk, + }, { ViewName: "main", Contexts: []string{string(context.MAIN_PATCH_BUILDING_CONTEXT_KEY), string(context.MAIN_STAGING_CONTEXT_KEY)}, diff --git a/pkg/gui/staging_panel.go b/pkg/gui/staging_panel.go index d17b1d2d9..01ccdb290 100644 --- a/pkg/gui/staging_panel.go +++ b/pkg/gui/staging_panel.go @@ -174,3 +174,54 @@ func (gui *Gui) HandleOpenFile() error { return gui.helpers.Files.OpenFile(file.GetPath()) } + +func (gui *Gui) handleEditHunk() error { + return gui.withLBLActiveCheck(func(state *LblPanelState) error { + return gui.editHunk(state.SecondaryFocused, state) + }) +} + +func (gui *Gui) editHunk(reverse bool, state *LblPanelState) error { + file := gui.getSelectedFile() + if file == nil { + return nil + } + + hunk := state.CurrentHunk() + patchText := patch.ModifiedPatchForRange(gui.Log, file.Name, state.GetDiff(), hunk.FirstLineIdx, hunk.LastLineIdx(), reverse, false) + patchFilepath, err := gui.git.WorkingTree.SaveTemporaryPatch(patchText) + if err != nil { + return err + } + + lineOffset := 3 + lineIdxInHunk := state.GetSelectedLineIdx() - hunk.FirstLineIdx + if err := gui.helpers.Files.EditFileAtLine(patchFilepath, lineIdxInHunk+lineOffset); err != nil { + return err + } + + editedPatchText, err := gui.git.File.Cat(patchFilepath) + if err != nil { + return err + } + + applyFlags := []string{} + if !reverse || state.SecondaryFocused { + applyFlags = append(applyFlags, "cached") + } + gui.c.LogAction(gui.c.Tr.Actions.ApplyPatch) + + lineCount := strings.Count(editedPatchText, "\n") + 1 + newPatchText := patch.ModifiedPatchForRange(gui.Log, file.Name, editedPatchText, 0, lineCount, false, false) + if err := gui.git.WorkingTree.ApplyPatch(newPatchText, applyFlags...); err != nil { + return gui.c.Error(err) + } + + if err := gui.c.Refresh(types.RefreshOptions{Scope: []types.RefreshableView{types.FILES}}); err != nil { + return err + } + if err := gui.refreshStagingPanel(false, -1); err != nil { + return err + } + return nil +} diff --git a/pkg/i18n/english.go b/pkg/i18n/english.go index 8b2837ef2..8466a6571 100644 --- a/pkg/i18n/english.go +++ b/pkg/i18n/english.go @@ -167,6 +167,7 @@ type TranslationSet struct { ToggleDragSelect string ToggleSelectHunk string ToggleSelectionForPatch string + EditHunk string TogglePanel string ReturnToFilesPanel string FastForward string @@ -777,6 +778,7 @@ func EnglishTranslationSet() TranslationSet { ToggleDragSelect: `toggle drag select`, ToggleSelectHunk: `toggle select hunk`, ToggleSelectionForPatch: `add/remove line(s) to patch`, + EditHunk: `edit hunk`, TogglePanel: `switch to other panel`, ReturnToFilesPanel: `return to files panel`, FastForward: `fast-forward this branch from its upstream`,