mirror of
https://github.com/jesseduffield/lazygit.git
synced 2025-05-12 04:45:47 +02:00
feat: add ability to edit hunk
This commit is contained in:
parent
0940e0182b
commit
d458e78d95
9 changed files with 85 additions and 3 deletions
|
@ -173,6 +173,7 @@ _This file is auto-generated. To update, make the changes in the pkg/i18n direct
|
||||||
<kbd>v</kbd>: toggle drag select
|
<kbd>v</kbd>: toggle drag select
|
||||||
<kbd>V</kbd>: toggle drag select
|
<kbd>V</kbd>: toggle drag select
|
||||||
<kbd>a</kbd>: toggle select hunk
|
<kbd>a</kbd>: toggle select hunk
|
||||||
|
<kbd>E</kbd>: edit hunk
|
||||||
</pre>
|
</pre>
|
||||||
|
|
||||||
## Main Panel (Staging)
|
## Main Panel (Staging)
|
||||||
|
@ -192,6 +193,7 @@ _This file is auto-generated. To update, make the changes in the pkg/i18n direct
|
||||||
<kbd>v</kbd>: toggle drag select
|
<kbd>v</kbd>: toggle drag select
|
||||||
<kbd>V</kbd>: toggle drag select
|
<kbd>V</kbd>: toggle drag select
|
||||||
<kbd>a</kbd>: toggle select hunk
|
<kbd>a</kbd>: toggle select hunk
|
||||||
|
<kbd>E</kbd>: edit hunk
|
||||||
</pre>
|
</pre>
|
||||||
|
|
||||||
## Reflog
|
## Reflog
|
||||||
|
|
|
@ -173,6 +173,7 @@ _This file is auto-generated. To update, make the changes in the pkg/i18n direct
|
||||||
<kbd>v</kbd>: toggle drag selecteer
|
<kbd>v</kbd>: toggle drag selecteer
|
||||||
<kbd>V</kbd>: toggle drag selecteer
|
<kbd>V</kbd>: toggle drag selecteer
|
||||||
<kbd>a</kbd>: toggle selecteer hunk
|
<kbd>a</kbd>: toggle selecteer hunk
|
||||||
|
<kbd>E</kbd>: edit hunk
|
||||||
</pre>
|
</pre>
|
||||||
|
|
||||||
## Reflog
|
## Reflog
|
||||||
|
@ -230,6 +231,7 @@ _This file is auto-generated. To update, make the changes in the pkg/i18n direct
|
||||||
<kbd>v</kbd>: toggle drag selecteer
|
<kbd>v</kbd>: toggle drag selecteer
|
||||||
<kbd>V</kbd>: toggle drag selecteer
|
<kbd>V</kbd>: toggle drag selecteer
|
||||||
<kbd>a</kbd>: toggle selecteer hunk
|
<kbd>a</kbd>: toggle selecteer hunk
|
||||||
|
<kbd>E</kbd>: edit hunk
|
||||||
</pre>
|
</pre>
|
||||||
|
|
||||||
## Stash
|
## Stash
|
||||||
|
|
|
@ -109,6 +109,7 @@ _This file is auto-generated. To update, make the changes in the pkg/i18n direct
|
||||||
<kbd>v</kbd>: toggle drag select
|
<kbd>v</kbd>: toggle drag select
|
||||||
<kbd>V</kbd>: toggle drag select
|
<kbd>V</kbd>: toggle drag select
|
||||||
<kbd>a</kbd>: toggle select hunk
|
<kbd>a</kbd>: toggle select hunk
|
||||||
|
<kbd>E</kbd>: edit hunk
|
||||||
</pre>
|
</pre>
|
||||||
|
|
||||||
## Pliki
|
## Pliki
|
||||||
|
@ -169,6 +170,7 @@ _This file is auto-generated. To update, make the changes in the pkg/i18n direct
|
||||||
<kbd>v</kbd>: toggle drag select
|
<kbd>v</kbd>: toggle drag select
|
||||||
<kbd>V</kbd>: toggle drag select
|
<kbd>V</kbd>: toggle drag select
|
||||||
<kbd>a</kbd>: toggle select hunk
|
<kbd>a</kbd>: toggle select hunk
|
||||||
|
<kbd>E</kbd>: edit hunk
|
||||||
</pre>
|
</pre>
|
||||||
|
|
||||||
## Reflog
|
## Reflog
|
||||||
|
|
|
@ -193,6 +193,7 @@ _This file is auto-generated. To update, make the changes in the pkg/i18n direct
|
||||||
<kbd>v</kbd>: 切换拖动选择
|
<kbd>v</kbd>: 切换拖动选择
|
||||||
<kbd>V</kbd>: 切换拖动选择
|
<kbd>V</kbd>: 切换拖动选择
|
||||||
<kbd>a</kbd>: 切换选择区块
|
<kbd>a</kbd>: 切换选择区块
|
||||||
|
<kbd>E</kbd>: edit hunk
|
||||||
</pre>
|
</pre>
|
||||||
|
|
||||||
## 标签页面
|
## 标签页面
|
||||||
|
@ -239,6 +240,7 @@ _This file is auto-generated. To update, make the changes in the pkg/i18n direct
|
||||||
<kbd>v</kbd>: 切换拖动选择
|
<kbd>v</kbd>: 切换拖动选择
|
||||||
<kbd>V</kbd>: 切换拖动选择
|
<kbd>V</kbd>: 切换拖动选择
|
||||||
<kbd>a</kbd>: 切换选择区块
|
<kbd>a</kbd>: 切换选择区块
|
||||||
|
<kbd>E</kbd>: edit hunk
|
||||||
</pre>
|
</pre>
|
||||||
|
|
||||||
## 正常
|
## 正常
|
||||||
|
|
|
@ -255,12 +255,15 @@ func (self *WorkingTreeCommands) WorktreeFileDiffCmdObj(node models.IFile, plain
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *WorkingTreeCommands) ApplyPatch(patch string, flags ...string) error {
|
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")
|
filepath, err := self.SaveTemporaryPatch(patch)
|
||||||
self.Log.Infof("saving temporary patch to %s", filepath)
|
if err != nil {
|
||||||
if err := self.os.CreateFileWithContent(filepath, patch); err != nil {
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return self.ApplyPatchFile(filepath, flags...)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (self *WorkingTreeCommands) ApplyPatchFile(filepath string, flags ...string) error {
|
||||||
flagStr := ""
|
flagStr := ""
|
||||||
for _, flag := range flags {
|
for _, flag := range flags {
|
||||||
flagStr += " --" + flag
|
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()
|
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
|
// 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.
|
// 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) {
|
func (self *WorkingTreeCommands) ShowFileDiff(from string, to string, reverse bool, fileName string, plain bool) (string, error) {
|
||||||
|
|
|
@ -269,6 +269,7 @@ type KeybindingMainConfig struct {
|
||||||
ToggleDragSelectAlt string `yaml:"toggleDragSelect-alt"`
|
ToggleDragSelectAlt string `yaml:"toggleDragSelect-alt"`
|
||||||
ToggleSelectHunk string `yaml:"toggleSelectHunk"`
|
ToggleSelectHunk string `yaml:"toggleSelectHunk"`
|
||||||
PickBothHunks string `yaml:"pickBothHunks"`
|
PickBothHunks string `yaml:"pickBothHunks"`
|
||||||
|
EditSelectHunk string `yaml:"editSelectHunk"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type KeybindingSubmodulesConfig struct {
|
type KeybindingSubmodulesConfig struct {
|
||||||
|
@ -536,6 +537,7 @@ func GetDefaultConfig() *UserConfig {
|
||||||
ToggleDragSelectAlt: "V",
|
ToggleDragSelectAlt: "V",
|
||||||
ToggleSelectHunk: "a",
|
ToggleSelectHunk: "a",
|
||||||
PickBothHunks: "b",
|
PickBothHunks: "b",
|
||||||
|
EditSelectHunk: "E",
|
||||||
},
|
},
|
||||||
Submodules: KeybindingSubmodulesConfig{
|
Submodules: KeybindingSubmodulesConfig{
|
||||||
Init: "i",
|
Init: "i",
|
||||||
|
|
|
@ -543,6 +543,13 @@ func (self *Gui) GetInitialKeybindings() ([]*types.Binding, []*gocui.ViewMouseBi
|
||||||
Handler: self.handleToggleSelectHunk,
|
Handler: self.handleToggleSelectHunk,
|
||||||
Description: self.c.Tr.ToggleSelectHunk,
|
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",
|
ViewName: "main",
|
||||||
Contexts: []string{string(context.MAIN_PATCH_BUILDING_CONTEXT_KEY), string(context.MAIN_STAGING_CONTEXT_KEY)},
|
Contexts: []string{string(context.MAIN_PATCH_BUILDING_CONTEXT_KEY), string(context.MAIN_STAGING_CONTEXT_KEY)},
|
||||||
|
|
|
@ -174,3 +174,54 @@ func (gui *Gui) HandleOpenFile() error {
|
||||||
|
|
||||||
return gui.helpers.Files.OpenFile(file.GetPath())
|
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
|
||||||
|
}
|
||||||
|
|
|
@ -167,6 +167,7 @@ type TranslationSet struct {
|
||||||
ToggleDragSelect string
|
ToggleDragSelect string
|
||||||
ToggleSelectHunk string
|
ToggleSelectHunk string
|
||||||
ToggleSelectionForPatch string
|
ToggleSelectionForPatch string
|
||||||
|
EditHunk string
|
||||||
TogglePanel string
|
TogglePanel string
|
||||||
ReturnToFilesPanel string
|
ReturnToFilesPanel string
|
||||||
FastForward string
|
FastForward string
|
||||||
|
@ -777,6 +778,7 @@ func EnglishTranslationSet() TranslationSet {
|
||||||
ToggleDragSelect: `toggle drag select`,
|
ToggleDragSelect: `toggle drag select`,
|
||||||
ToggleSelectHunk: `toggle select hunk`,
|
ToggleSelectHunk: `toggle select hunk`,
|
||||||
ToggleSelectionForPatch: `add/remove line(s) to patch`,
|
ToggleSelectionForPatch: `add/remove line(s) to patch`,
|
||||||
|
EditHunk: `edit hunk`,
|
||||||
TogglePanel: `switch to other panel`,
|
TogglePanel: `switch to other panel`,
|
||||||
ReturnToFilesPanel: `return to files panel`,
|
ReturnToFilesPanel: `return to files panel`,
|
||||||
FastForward: `fast-forward this branch from its upstream`,
|
FastForward: `fast-forward this branch from its upstream`,
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue