mirror of
https://github.com/jesseduffield/lazygit.git
synced 2026-10-05 21:46:49 -04:00
Remove the staging and patch-building panel shells
Nothing routes to the explorer contexts after line actions and file entry moved into the normal main pair. Delete their contexts, views, main-pair wiring, discovery API, test drivers, and selection-state package so the surviving diff view is the only implementation. Their names go from the contexts a custom command may bind to as well, so that a config still naming one is reported as the config error it now is rather than taken as a context we simply failed to find. Co-Authored-By: GitHub Copilot <copilot@github.com>
This commit is contained in:
co-authored by
GitHub Copilot
parent
fb3ad64e80
commit
ca8223caad
@@ -241,18 +241,6 @@ _This file is auto-generated. To update, make the changes in the pkg/i18n direct
|
||||
| `` <ctrl+f> `` | Find base commit for fixup | Find the commit that your current changes are building upon, for the sake of amending/fixing up the commit. This spares you from having to look through your branch's commits one-by-one to see which commit should be amended/fixed up. See docs: <https://github.com/jesseduffield/lazygit/tree/master/docs/Fixup_Commits.md> |
|
||||
| `` / `` | Search the current view by text | |
|
||||
|
||||
## Main panel (patch building)
|
||||
|
||||
| Key | Action | Info |
|
||||
|-----|--------|-------------|
|
||||
| `` / `` | Search the current view by text | |
|
||||
|
||||
## Main panel (staging)
|
||||
|
||||
| Key | Action | Info |
|
||||
|-----|--------|-------------|
|
||||
| `` / `` | Search the current view by text | |
|
||||
|
||||
## Menu
|
||||
|
||||
| Key | Action | Info |
|
||||
|
||||
@@ -259,18 +259,6 @@ _This file is auto-generated. To update, make the changes in the pkg/i18n direct
|
||||
| `` 0 `` | メインビューにフォーカス | |
|
||||
| `` / `` | 現在のビューをテキストでフィルタリング | |
|
||||
|
||||
## メインパネル(ステージング)
|
||||
|
||||
| Key | Action | Info |
|
||||
|-----|--------|-------------|
|
||||
| `` / `` | 現在のビューをテキストで検索 | |
|
||||
|
||||
## メインパネル(パッチ作成)
|
||||
|
||||
| Key | Action | Info |
|
||||
|-----|--------|-------------|
|
||||
| `` / `` | 現在のビューをテキストで検索 | |
|
||||
|
||||
## メインパネル(マージ中)
|
||||
|
||||
| Key | Action | Info |
|
||||
|
||||
@@ -195,18 +195,6 @@ _This file is auto-generated. To update, make the changes in the pkg/i18n direct
|
||||
| `` <ctrl+f> `` | Find base commit for fixup | Find the commit that your current changes are building upon, for the sake of amending/fixing up the commit. This spares you from having to look through your branch's commits one-by-one to see which commit should be amended/fixed up. See docs: <https://github.com/jesseduffield/lazygit/tree/master/docs/Fixup_Commits.md> |
|
||||
| `` / `` | 검색 시작 | |
|
||||
|
||||
## 메인 패널 (Patch Building)
|
||||
|
||||
| Key | Action | Info |
|
||||
|-----|--------|-------------|
|
||||
| `` / `` | 검색 시작 | |
|
||||
|
||||
## 메인 패널 (Staging)
|
||||
|
||||
| Key | Action | Info |
|
||||
|-----|--------|-------------|
|
||||
| `` / `` | 검색 시작 | |
|
||||
|
||||
## 브랜치
|
||||
|
||||
| Key | Action | Info |
|
||||
|
||||
@@ -249,12 +249,6 @@ _This file is auto-generated. To update, make the changes in the pkg/i18n direct
|
||||
| `` <ctrl+f> `` | Find base commit for fixup | Vind de commit waar je huidige wijzigingen bovenop zijn gebouwd met als doel die commit te amenden/fixen. Hierdoor hoef je dit niet met de hand te doen. Zie: <https://github.com/jesseduffield/lazygit/tree/master/docs/Fixup_Commits.md> |
|
||||
| `` / `` | Start met zoeken | |
|
||||
|
||||
## Patch bouwen
|
||||
|
||||
| Key | Action | Info |
|
||||
|-----|--------|-------------|
|
||||
| `` / `` | Start met zoeken | |
|
||||
|
||||
## Reflog
|
||||
|
||||
| Key | Action | Info |
|
||||
@@ -329,12 +323,6 @@ _This file is auto-generated. To update, make the changes in the pkg/i18n direct
|
||||
| `` <ctrl+f> `` | Find base commit for fixup | Vind de commit waar je huidige wijzigingen bovenop zijn gebouwd met als doel die commit te amenden/fixen. Hierdoor hoef je dit niet met de hand te doen. Zie: <https://github.com/jesseduffield/lazygit/tree/master/docs/Fixup_Commits.md> |
|
||||
| `` / `` | Start met zoeken | |
|
||||
|
||||
## Staging
|
||||
|
||||
| Key | Action | Info |
|
||||
|-----|--------|-------------|
|
||||
| `` / `` | Start met zoeken | |
|
||||
|
||||
## Stash
|
||||
|
||||
| Key | Action | Info |
|
||||
|
||||
@@ -147,12 +147,6 @@ _This file is auto-generated. To update, make the changes in the pkg/i18n direct
|
||||
| `` <enter> `` | Pokaż commity | |
|
||||
| `` / `` | Filtruj bieżący widok po tekście | |
|
||||
|
||||
## Główny panel (budowanie łatki)
|
||||
|
||||
| Key | Action | Info |
|
||||
|-----|--------|-------------|
|
||||
| `` / `` | Szukaj w bieżącym widoku po tekście | |
|
||||
|
||||
## Input prompt
|
||||
|
||||
| Key | Action | Info |
|
||||
@@ -240,12 +234,6 @@ _This file is auto-generated. To update, make the changes in the pkg/i18n direct
|
||||
| `` M `` | View merge conflict options | View options for resolving merge conflicts. |
|
||||
| `` <esc> `` | Wróć do panelu plików | |
|
||||
|
||||
## Panel główny (zatwierdzanie)
|
||||
|
||||
| Key | Action | Info |
|
||||
|-----|--------|-------------|
|
||||
| `` / `` | Szukaj w bieżącym widoku po tekście | |
|
||||
|
||||
## Panel potwierdzenia
|
||||
|
||||
| Key | Action | Info |
|
||||
|
||||
@@ -253,12 +253,6 @@ _This file is auto-generated. To update, make the changes in the pkg/i18n direct
|
||||
| `` <ctrl+f> `` | Encontrar commit da base para corrigir | Encontre o commit em que as suas mudanças atuais estão se baseando, para alterar/consertar o commit. Isso poupa-te você de ter que olhar pelos commits da sua branch um por um para ver qual commit deve ser alterado/consertado<br>Veja a documentação:<br><https://github.com/jesseduffield/lazygit/tree/master/docs/Fixup_Commits.md> |
|
||||
| `` / `` | Pesquisar na visualização atual por texto | |
|
||||
|
||||
## Painel Principal (preparação)
|
||||
|
||||
| Key | Action | Info |
|
||||
|-----|--------|-------------|
|
||||
| `` / `` | Pesquisar na visualização atual por texto | |
|
||||
|
||||
## Painel de confirmação
|
||||
|
||||
| Key | Action | Info |
|
||||
@@ -283,12 +277,6 @@ _This file is auto-generated. To update, make the changes in the pkg/i18n direct
|
||||
| `` M `` | View merge conflict options | View options for resolving merge conflicts. |
|
||||
| `` <esc> `` | Retornar ao painel de arquivos | |
|
||||
|
||||
## Painel principal (patch build)
|
||||
|
||||
| Key | Action | Info |
|
||||
|-----|--------|-------------|
|
||||
| `` / `` | Pesquisar na visualização atual por texto | |
|
||||
|
||||
## Reflog
|
||||
|
||||
| Key | Action | Info |
|
||||
|
||||
@@ -92,12 +92,6 @@ _This file is auto-generated. To update, make the changes in the pkg/i18n direct
|
||||
| `` <ctrl+f> `` | Find base commit for fixup | Find the commit that your current changes are building upon, for the sake of amending/fixing up the commit. This spares you from having to look through your branch's commits one-by-one to see which commit should be amended/fixed up. See docs: <https://github.com/jesseduffield/lazygit/tree/master/docs/Fixup_Commits.md> |
|
||||
| `` / `` | Найти | |
|
||||
|
||||
## Главная панель (Индексирование)
|
||||
|
||||
| Key | Action | Info |
|
||||
|-----|--------|-------------|
|
||||
| `` / `` | Найти | |
|
||||
|
||||
## Главная панель (Обычный)
|
||||
|
||||
| Key | Action | Info |
|
||||
@@ -139,12 +133,6 @@ _This file is auto-generated. To update, make the changes in the pkg/i18n direct
|
||||
| `` M `` | View merge conflict options | View options for resolving merge conflicts. |
|
||||
| `` <esc> `` | Вернуться к панели файлов | |
|
||||
|
||||
## Главная панель (сборка патчей)
|
||||
|
||||
| Key | Action | Info |
|
||||
|-----|--------|-------------|
|
||||
| `` / `` | Найти | |
|
||||
|
||||
## Журнал ссылок (Reflog)
|
||||
|
||||
| Key | Action | Info |
|
||||
|
||||
@@ -249,12 +249,6 @@ _This file is auto-generated. To update, make the changes in the pkg/i18n direct
|
||||
| `` <enter> `` | 查看提交 | |
|
||||
| `` / `` | 通过文本过滤当前视图 | |
|
||||
|
||||
## 构建补丁中
|
||||
|
||||
| Key | Action | Info |
|
||||
|-----|--------|-------------|
|
||||
| `` / `` | 开始搜索 | |
|
||||
|
||||
## 标签
|
||||
|
||||
| Key | Action | Info |
|
||||
@@ -310,12 +304,6 @@ _This file is auto-generated. To update, make the changes in the pkg/i18n direct
|
||||
| `` M `` | 查看合并冲突选项 | 查看用于解决合并冲突的选项。 |
|
||||
| `` <esc> `` | 返回文件面板 | |
|
||||
|
||||
## 正在暂存
|
||||
|
||||
| Key | Action | Info |
|
||||
|-----|--------|-------------|
|
||||
| `` / `` | 开始搜索 | |
|
||||
|
||||
## 正常
|
||||
|
||||
| Key | Action | Info |
|
||||
|
||||
@@ -52,12 +52,6 @@ _This file is auto-generated. To update, make the changes in the pkg/i18n direct
|
||||
| `` ] `` | 下一個索引標籤 | |
|
||||
| `` [ `` | 上一個索引標籤 | |
|
||||
|
||||
## 主面板 (補丁生成)
|
||||
|
||||
| Key | Action | Info |
|
||||
|-----|--------|-------------|
|
||||
| `` / `` | 搜尋 | |
|
||||
|
||||
## 主面板(一般)
|
||||
|
||||
| Key | Action | Info |
|
||||
@@ -99,12 +93,6 @@ _This file is auto-generated. To update, make the changes in the pkg/i18n direct
|
||||
| `` M `` | 檢視合併衝突選項 | 檢視用於解決合併衝突的選項。 |
|
||||
| `` <esc> `` | 返回檔案面板 | |
|
||||
|
||||
## 主面板(預存)
|
||||
|
||||
| Key | Action | Info |
|
||||
|-----|--------|-------------|
|
||||
| `` / `` | 搜尋 | |
|
||||
|
||||
## 功能表
|
||||
|
||||
| Key | Action | Info |
|
||||
|
||||
@@ -120,9 +120,7 @@ func localisedTitle(tr *i18n.TranslationSet, str string) string {
|
||||
"prompt": tr.PromptTitle,
|
||||
"information": tr.InformationTitle,
|
||||
"main": tr.NormalTitle,
|
||||
"patchBuilding": tr.PatchBuildingTitle,
|
||||
"mergeConflicts": tr.MergingTitle,
|
||||
"staging": tr.StagingTitle,
|
||||
"menu": tr.MenuTitle,
|
||||
"search": tr.SearchTitle,
|
||||
"secondary": tr.SecondaryTitle,
|
||||
@@ -141,12 +139,7 @@ func localisedTitle(tr *i18n.TranslationSet, str string) string {
|
||||
}
|
||||
|
||||
func getBindingSections(bindings []*types.Binding, tr *i18n.TranslationSet) []*bindingSection {
|
||||
excludedViews := []string{"stagingSecondary", "patchBuildingSecondary"}
|
||||
bindingsToDisplay := lo.Filter(bindings, func(binding *types.Binding, _ int) bool {
|
||||
if lo.Contains(excludedViews, binding.ViewName) {
|
||||
return false
|
||||
}
|
||||
|
||||
return (binding.Description != "" || binding.Alternative != "") && len(binding.Keys) > 0
|
||||
})
|
||||
|
||||
|
||||
@@ -265,17 +265,3 @@ func (self *Patch) AdjustLineNumber(lineNumber int) int {
|
||||
|
||||
return adjustedLineNumber
|
||||
}
|
||||
|
||||
func (self *Patch) IsSingleHunkForWholeFile() bool {
|
||||
if len(self.hunks) != 1 {
|
||||
return false
|
||||
}
|
||||
|
||||
// We consider a patch to be a single hunk for the whole file if it has only additions or
|
||||
// deletions but not both, and no context lines. This not quite correct, because it will also
|
||||
// return true for a block of added or deleted lines if the diff context size is 0, but in this
|
||||
// case you wouldn't be able to stage things anyway, so it doesn't matter.
|
||||
bodyLines := self.hunks[0].bodyLines
|
||||
return nLinesWithKind(bodyLines, []PatchLineKind{DELETION, CONTEXT}) == 0 ||
|
||||
nLinesWithKind(bodyLines, []PatchLineKind{ADDITION, CONTEXT}) == 0
|
||||
}
|
||||
|
||||
@@ -921,64 +921,3 @@ func TestAdjustLineNumber(t *testing.T) {
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestIsSingleHunkForWholeFile(t *testing.T) {
|
||||
scenarios := []struct {
|
||||
testName string
|
||||
patchStr string
|
||||
expectedResult bool
|
||||
}{
|
||||
{
|
||||
testName: "simpleDiff",
|
||||
patchStr: simpleDiff,
|
||||
expectedResult: false,
|
||||
},
|
||||
{
|
||||
testName: "addNewlineToEndOfFile",
|
||||
patchStr: addNewlineToEndOfFile,
|
||||
expectedResult: false,
|
||||
},
|
||||
{
|
||||
testName: "removeNewlinefromEndOfFile",
|
||||
patchStr: removeNewlinefromEndOfFile,
|
||||
expectedResult: false,
|
||||
},
|
||||
{
|
||||
testName: "twoHunks",
|
||||
patchStr: twoHunks,
|
||||
expectedResult: false,
|
||||
},
|
||||
{
|
||||
testName: "twoChangesInOneHunk",
|
||||
patchStr: twoChangesInOneHunk,
|
||||
expectedResult: false,
|
||||
},
|
||||
{
|
||||
testName: "newFile",
|
||||
patchStr: newFile,
|
||||
expectedResult: true,
|
||||
},
|
||||
{
|
||||
testName: "deletedFile",
|
||||
patchStr: deletedFile,
|
||||
expectedResult: true,
|
||||
},
|
||||
{
|
||||
testName: "addNewlineToPreviouslyEmptyFile",
|
||||
patchStr: addNewlineToPreviouslyEmptyFile,
|
||||
expectedResult: true,
|
||||
},
|
||||
{
|
||||
testName: "exampleHunk",
|
||||
patchStr: exampleHunk,
|
||||
expectedResult: false,
|
||||
},
|
||||
}
|
||||
|
||||
for _, s := range scenarios {
|
||||
t.Run(s.testName, func(t *testing.T) {
|
||||
patch := Parse(s.patchStr)
|
||||
assert.Equal(t, s.expectedResult, patch.IsSingleHunkForWholeFile())
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -232,10 +232,6 @@ var ValidCustomCommandContexts = []string{
|
||||
"stash",
|
||||
"normal",
|
||||
"normalSecondary",
|
||||
"staging",
|
||||
"stagingSecondary",
|
||||
"patchBuilding",
|
||||
"patchBuildingSecondary",
|
||||
"mergeConflicts",
|
||||
"menu",
|
||||
"confirmation",
|
||||
|
||||
@@ -242,6 +242,10 @@ func TestUserConfigValidate_enums(t *testing.T) {
|
||||
{value: "commits,subCommits", valid: true},
|
||||
{value: "invalid_value", valid: false},
|
||||
{value: "commits, invalid_value", valid: false},
|
||||
// The staging and patch-building panels are gone, so a config that
|
||||
// still names their contexts is reported rather than fatal.
|
||||
{value: "staging", valid: false},
|
||||
{value: "patchBuilding", valid: false},
|
||||
},
|
||||
},
|
||||
{
|
||||
|
||||
@@ -350,18 +350,6 @@ func (self *ContextMgr) AllList() []types.IListContext {
|
||||
return listContexts
|
||||
}
|
||||
|
||||
func (self *ContextMgr) AllPatchExplorer() []types.IPatchExplorerContext {
|
||||
var listContexts []types.IPatchExplorerContext
|
||||
|
||||
for _, context := range self.allContexts.Flatten() {
|
||||
if listContext, ok := context.(types.IPatchExplorerContext); ok {
|
||||
listContexts = append(listContexts, listContext)
|
||||
}
|
||||
}
|
||||
|
||||
return listContexts
|
||||
}
|
||||
|
||||
func (self *ContextMgr) ContextForKey(key types.ContextKey) types.Context {
|
||||
self.RLock()
|
||||
defer self.RUnlock()
|
||||
|
||||
+42
-58
@@ -8,27 +8,23 @@ const (
|
||||
// used as a nil value when passing a context key as an arg
|
||||
NO_CONTEXT types.ContextKey = "none"
|
||||
|
||||
GLOBAL_CONTEXT_KEY types.ContextKey = "global"
|
||||
STATUS_CONTEXT_KEY types.ContextKey = "status"
|
||||
SNAKE_CONTEXT_KEY types.ContextKey = "snake"
|
||||
FILES_CONTEXT_KEY types.ContextKey = "files"
|
||||
LOCAL_BRANCHES_CONTEXT_KEY types.ContextKey = "localBranches"
|
||||
REMOTES_CONTEXT_KEY types.ContextKey = "remotes"
|
||||
WORKTREES_CONTEXT_KEY types.ContextKey = "worktrees"
|
||||
REMOTE_BRANCHES_CONTEXT_KEY types.ContextKey = "remoteBranches"
|
||||
TAGS_CONTEXT_KEY types.ContextKey = "tags"
|
||||
LOCAL_COMMITS_CONTEXT_KEY types.ContextKey = "commits"
|
||||
REFLOG_COMMITS_CONTEXT_KEY types.ContextKey = "reflogCommits"
|
||||
SUB_COMMITS_CONTEXT_KEY types.ContextKey = "subCommits"
|
||||
COMMIT_FILES_CONTEXT_KEY types.ContextKey = "commitFiles"
|
||||
STASH_CONTEXT_KEY types.ContextKey = "stash"
|
||||
NORMAL_MAIN_CONTEXT_KEY types.ContextKey = "normal"
|
||||
NORMAL_SECONDARY_CONTEXT_KEY types.ContextKey = "normalSecondary"
|
||||
STAGING_MAIN_CONTEXT_KEY types.ContextKey = "staging"
|
||||
STAGING_SECONDARY_CONTEXT_KEY types.ContextKey = "stagingSecondary"
|
||||
PATCH_BUILDING_MAIN_CONTEXT_KEY types.ContextKey = "patchBuilding"
|
||||
PATCH_BUILDING_SECONDARY_CONTEXT_KEY types.ContextKey = "patchBuildingSecondary"
|
||||
MERGE_CONFLICTS_CONTEXT_KEY types.ContextKey = "mergeConflicts"
|
||||
GLOBAL_CONTEXT_KEY types.ContextKey = "global"
|
||||
STATUS_CONTEXT_KEY types.ContextKey = "status"
|
||||
SNAKE_CONTEXT_KEY types.ContextKey = "snake"
|
||||
FILES_CONTEXT_KEY types.ContextKey = "files"
|
||||
LOCAL_BRANCHES_CONTEXT_KEY types.ContextKey = "localBranches"
|
||||
REMOTES_CONTEXT_KEY types.ContextKey = "remotes"
|
||||
WORKTREES_CONTEXT_KEY types.ContextKey = "worktrees"
|
||||
REMOTE_BRANCHES_CONTEXT_KEY types.ContextKey = "remoteBranches"
|
||||
TAGS_CONTEXT_KEY types.ContextKey = "tags"
|
||||
LOCAL_COMMITS_CONTEXT_KEY types.ContextKey = "commits"
|
||||
REFLOG_COMMITS_CONTEXT_KEY types.ContextKey = "reflogCommits"
|
||||
SUB_COMMITS_CONTEXT_KEY types.ContextKey = "subCommits"
|
||||
COMMIT_FILES_CONTEXT_KEY types.ContextKey = "commitFiles"
|
||||
STASH_CONTEXT_KEY types.ContextKey = "stash"
|
||||
NORMAL_MAIN_CONTEXT_KEY types.ContextKey = "normal"
|
||||
NORMAL_SECONDARY_CONTEXT_KEY types.ContextKey = "normalSecondary"
|
||||
MERGE_CONFLICTS_CONTEXT_KEY types.ContextKey = "mergeConflicts"
|
||||
|
||||
// these shouldn't really be needed for anything but I'm giving them unique keys nonetheless
|
||||
OPTIONS_CONTEXT_KEY types.ContextKey = "options"
|
||||
@@ -66,10 +62,6 @@ var AllContextKeys = []types.ContextKey{
|
||||
STASH_CONTEXT_KEY,
|
||||
NORMAL_MAIN_CONTEXT_KEY,
|
||||
NORMAL_SECONDARY_CONTEXT_KEY,
|
||||
STAGING_MAIN_CONTEXT_KEY,
|
||||
STAGING_SECONDARY_CONTEXT_KEY,
|
||||
PATCH_BUILDING_MAIN_CONTEXT_KEY,
|
||||
PATCH_BUILDING_SECONDARY_CONTEXT_KEY,
|
||||
MERGE_CONFLICTS_CONTEXT_KEY,
|
||||
|
||||
MENU_CONTEXT_KEY,
|
||||
@@ -83,35 +75,31 @@ var AllContextKeys = []types.ContextKey{
|
||||
}
|
||||
|
||||
type ContextTree struct {
|
||||
Global types.Context
|
||||
Status types.Context
|
||||
Snake types.Context
|
||||
Files *WorkingTreeContext
|
||||
Menu *MenuContext
|
||||
Branches *BranchesContext
|
||||
Tags *TagsContext
|
||||
LocalCommits *LocalCommitsContext
|
||||
CommitFiles *CommitFilesContext
|
||||
Remotes *RemotesContext
|
||||
Worktrees *WorktreesContext
|
||||
Submodules *SubmodulesContext
|
||||
RemoteBranches *RemoteBranchesContext
|
||||
ReflogCommits *ReflogCommitsContext
|
||||
SubCommits *SubCommitsContext
|
||||
Stash *StashContext
|
||||
Suggestions *SuggestionsContext
|
||||
Normal *MainContext
|
||||
NormalSecondary *MainContext
|
||||
Staging *PatchExplorerContext
|
||||
StagingSecondary *PatchExplorerContext
|
||||
CustomPatchBuilder *PatchExplorerContext
|
||||
CustomPatchBuilderSecondary types.Context
|
||||
MergeConflicts *MergeConflictsContext
|
||||
Confirmation *ConfirmationContext
|
||||
Prompt *PromptContext
|
||||
CommitMessage *CommitMessageContext
|
||||
CommitDescription types.Context
|
||||
CommandLog types.Context
|
||||
Global types.Context
|
||||
Status types.Context
|
||||
Snake types.Context
|
||||
Files *WorkingTreeContext
|
||||
Menu *MenuContext
|
||||
Branches *BranchesContext
|
||||
Tags *TagsContext
|
||||
LocalCommits *LocalCommitsContext
|
||||
CommitFiles *CommitFilesContext
|
||||
Remotes *RemotesContext
|
||||
Worktrees *WorktreesContext
|
||||
Submodules *SubmodulesContext
|
||||
RemoteBranches *RemoteBranchesContext
|
||||
ReflogCommits *ReflogCommitsContext
|
||||
SubCommits *SubCommitsContext
|
||||
Stash *StashContext
|
||||
Suggestions *SuggestionsContext
|
||||
Normal *MainContext
|
||||
NormalSecondary *MainContext
|
||||
MergeConflicts *MergeConflictsContext
|
||||
Confirmation *ConfirmationContext
|
||||
Prompt *PromptContext
|
||||
CommitMessage *CommitMessageContext
|
||||
CommitDescription types.Context
|
||||
CommandLog types.Context
|
||||
|
||||
// display contexts
|
||||
AppStatus types.Context
|
||||
@@ -149,10 +137,6 @@ func (self *ContextTree) Flatten() []types.Context {
|
||||
self.CommitDescription,
|
||||
|
||||
self.MergeConflicts,
|
||||
self.StagingSecondary,
|
||||
self.Staging,
|
||||
self.CustomPatchBuilderSecondary,
|
||||
self.CustomPatchBuilder,
|
||||
self.NormalSecondary,
|
||||
self.Normal,
|
||||
|
||||
|
||||
@@ -1,154 +0,0 @@
|
||||
package context
|
||||
|
||||
import (
|
||||
"github.com/jesseduffield/lazygit/pkg/gocui"
|
||||
"github.com/jesseduffield/lazygit/pkg/gui/patch_exploring"
|
||||
"github.com/jesseduffield/lazygit/pkg/gui/types"
|
||||
deadlock "github.com/sasha-s/go-deadlock"
|
||||
)
|
||||
|
||||
type PatchExplorerContext struct {
|
||||
*SimpleContext
|
||||
*SearchTrait
|
||||
|
||||
state *patch_exploring.State
|
||||
viewTrait *ViewTrait
|
||||
getIncludedLineIndices func() []int
|
||||
c *ContextCommon
|
||||
mutex deadlock.Mutex
|
||||
|
||||
// true if we're inside the OnSelectItem callback; in that case we don't want to update the
|
||||
// search result index.
|
||||
inOnSelectItemCallback bool
|
||||
}
|
||||
|
||||
var (
|
||||
_ types.IPatchExplorerContext = (*PatchExplorerContext)(nil)
|
||||
_ types.ISearchableContext = (*PatchExplorerContext)(nil)
|
||||
)
|
||||
|
||||
func NewPatchExplorerContext(
|
||||
view *gocui.View,
|
||||
windowName string,
|
||||
key types.ContextKey,
|
||||
|
||||
getIncludedLineIndices func() []int,
|
||||
|
||||
c *ContextCommon,
|
||||
) *PatchExplorerContext {
|
||||
ctx := &PatchExplorerContext{
|
||||
state: nil,
|
||||
viewTrait: NewViewTrait(view),
|
||||
c: c,
|
||||
getIncludedLineIndices: getIncludedLineIndices,
|
||||
SimpleContext: NewSimpleContext(NewBaseContext(NewBaseContextOpts{
|
||||
View: view,
|
||||
WindowName: windowName,
|
||||
Key: key,
|
||||
Kind: types.MAIN_CONTEXT,
|
||||
Focusable: true,
|
||||
HasSelectableContent: true,
|
||||
NeedsRerenderOnWidthChange: types.NEEDS_RERENDER_ON_WIDTH_CHANGE_WHEN_WIDTH_CHANGES,
|
||||
})),
|
||||
SearchTrait: NewSearchTrait(c),
|
||||
}
|
||||
|
||||
ctx.SetHandleRenderFunc(ctx.OnViewWidthChanged)
|
||||
|
||||
return ctx
|
||||
}
|
||||
|
||||
func (self *PatchExplorerContext) IsPatchExplorerContext() {}
|
||||
|
||||
func (self *PatchExplorerContext) GetState() *patch_exploring.State {
|
||||
return self.state
|
||||
}
|
||||
|
||||
func (self *PatchExplorerContext) SetState(state *patch_exploring.State) {
|
||||
self.state = state
|
||||
}
|
||||
|
||||
func (self *PatchExplorerContext) GetViewTrait() types.IViewTrait {
|
||||
return self.viewTrait
|
||||
}
|
||||
|
||||
func (self *PatchExplorerContext) GetIncludedLineIndices() []int {
|
||||
return self.getIncludedLineIndices()
|
||||
}
|
||||
|
||||
func (self *PatchExplorerContext) RenderAndFocus() {
|
||||
self.setContent()
|
||||
|
||||
self.FocusSelection()
|
||||
self.c.Render()
|
||||
}
|
||||
|
||||
func (self *PatchExplorerContext) Render() {
|
||||
self.setContent()
|
||||
|
||||
self.c.Render()
|
||||
}
|
||||
|
||||
func (self *PatchExplorerContext) setContent() {
|
||||
self.GetView().SetContent(self.GetContentToRender())
|
||||
}
|
||||
|
||||
func (self *PatchExplorerContext) FocusSelection() {
|
||||
view := self.GetView()
|
||||
state := self.GetState()
|
||||
bufferHeight := view.InnerHeight()
|
||||
_, origin := view.Origin()
|
||||
numLines := view.ViewLinesHeight()
|
||||
|
||||
newOriginY := state.CalculateOrigin(origin, bufferHeight, numLines)
|
||||
|
||||
view.SetOriginY(newOriginY)
|
||||
|
||||
startIdx, endIdx := state.SelectedViewRange()
|
||||
// As far as the view is concerned, we are always selecting a range
|
||||
view.SetRangeSelectStart(startIdx)
|
||||
view.SetCursorY(endIdx - newOriginY)
|
||||
|
||||
if !self.inOnSelectItemCallback {
|
||||
view.SetNearestSearchPosition()
|
||||
}
|
||||
}
|
||||
|
||||
func (self *PatchExplorerContext) GetContentToRender() string {
|
||||
if self.GetState() == nil {
|
||||
return ""
|
||||
}
|
||||
|
||||
return self.GetState().RenderForLineIndices(self.GetIncludedLineIndices())
|
||||
}
|
||||
|
||||
func (self *PatchExplorerContext) NavigateTo(selectedLineIdx int) {
|
||||
self.GetState().SetLineSelectMode()
|
||||
self.GetState().SelectLine(selectedLineIdx)
|
||||
|
||||
self.RenderAndFocus()
|
||||
}
|
||||
|
||||
func (self *PatchExplorerContext) GetMutex() *deadlock.Mutex {
|
||||
return &self.mutex
|
||||
}
|
||||
|
||||
func (self *PatchExplorerContext) ModelSearchResults(searchStr string, caseSensitive bool) []gocui.SearchPosition {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (self *PatchExplorerContext) OnSearchSelect(selectedLineIdx int) {
|
||||
self.GetMutex().Lock()
|
||||
defer self.GetMutex().Unlock()
|
||||
self.inOnSelectItemCallback = true
|
||||
self.NavigateTo(selectedLineIdx)
|
||||
self.inOnSelectItemCallback = false
|
||||
}
|
||||
|
||||
func (self *PatchExplorerContext) OnViewWidthChanged() {
|
||||
if state := self.GetState(); state != nil {
|
||||
state.OnViewWidthChanged(self.GetView())
|
||||
self.setContent()
|
||||
self.RenderAndFocus()
|
||||
}
|
||||
}
|
||||
@@ -41,48 +41,6 @@ func NewContextTree(c *ContextCommon) *ContextTree {
|
||||
Suggestions: NewSuggestionsContext(c),
|
||||
Normal: NewMainContext(c.Views().Main, "main", NORMAL_MAIN_CONTEXT_KEY, c),
|
||||
NormalSecondary: NewMainContext(c.Views().Secondary, "secondary", NORMAL_SECONDARY_CONTEXT_KEY, c),
|
||||
Staging: NewPatchExplorerContext(
|
||||
c.Views().Staging,
|
||||
"main",
|
||||
STAGING_MAIN_CONTEXT_KEY,
|
||||
func() []int { return nil },
|
||||
c,
|
||||
),
|
||||
StagingSecondary: NewPatchExplorerContext(
|
||||
c.Views().StagingSecondary,
|
||||
"secondary",
|
||||
STAGING_SECONDARY_CONTEXT_KEY,
|
||||
func() []int { return nil },
|
||||
c,
|
||||
),
|
||||
CustomPatchBuilder: NewPatchExplorerContext(
|
||||
c.Views().PatchBuilding,
|
||||
"main",
|
||||
PATCH_BUILDING_MAIN_CONTEXT_KEY,
|
||||
func() []int {
|
||||
file := commitFilesContext.GetSelectedFile()
|
||||
if file == nil {
|
||||
return nil
|
||||
}
|
||||
includedLineIndices, err := c.Git().Patch.PatchBuilder.GetFileIncLineIndices(file.Path, file.PreviousPath)
|
||||
if err != nil {
|
||||
c.Log.Error(err)
|
||||
return nil
|
||||
}
|
||||
|
||||
return includedLineIndices
|
||||
},
|
||||
c,
|
||||
),
|
||||
CustomPatchBuilderSecondary: NewSimpleContext(
|
||||
NewBaseContext(NewBaseContextOpts{
|
||||
Kind: types.MAIN_CONTEXT,
|
||||
View: c.Views().PatchBuildingSecondary,
|
||||
WindowName: "secondary",
|
||||
Key: PATCH_BUILDING_SECONDARY_CONTEXT_KEY,
|
||||
Focusable: false,
|
||||
}),
|
||||
),
|
||||
MergeConflicts: NewMergeConflictsContext(
|
||||
c,
|
||||
),
|
||||
|
||||
@@ -227,7 +227,7 @@ func (self *DiffHelper) OpenDiffToolForRef(selectedRef models.Ref) error {
|
||||
// AdjustLineNumber is used to adjust a line number in the diff that's currently
|
||||
// being viewed, so that it corresponds to the line number in the actual working
|
||||
// copy state of the file. It is used when clicking on a delta hyperlink in a
|
||||
// diff, or when pressing `e` in the staging or patch building panels. It works
|
||||
// diff, or when pressing `e` in a focused diff. It works
|
||||
// by getting a diff of what's being viewed in the main view against the working
|
||||
// copy, and then using that diff to adjust the line number.
|
||||
// path is the file path of the file being viewed
|
||||
@@ -238,7 +238,7 @@ func (self *DiffHelper) OpenDiffToolForRef(selectedRef models.Ref) error {
|
||||
func (self *DiffHelper) AdjustLineNumber(path string, linenumber int, viewname string) int {
|
||||
switch viewname {
|
||||
|
||||
case "main", "patchBuilding":
|
||||
case "main":
|
||||
if diffableContext, ok := self.c.Context().CurrentSide().(types.DiffableContext); ok {
|
||||
ref := diffableContext.RefForAdjustingLineNumberInDiff()
|
||||
if len(ref) != 0 {
|
||||
@@ -249,7 +249,7 @@ func (self *DiffHelper) AdjustLineNumber(path string, linenumber int, viewname s
|
||||
// unstaged changes view of the Files panel; no need to adjust line
|
||||
// numbers in this case
|
||||
|
||||
case "secondary", "stagingSecondary":
|
||||
case "secondary":
|
||||
return self.adjustLineNumber(linenumber, "--", path)
|
||||
}
|
||||
|
||||
|
||||
@@ -219,8 +219,7 @@ func (self *DiffLineHelper) IsChangeLine(view *gocui.View, viewLineIdx int) bool
|
||||
// is shown as one solid block of changes — every row of its diff a change of the same
|
||||
// kind, no context — which is what a newly added or deleted file looks like. That is
|
||||
// the case where widening the selection to the change block would select the file
|
||||
// entire, so hunk mode drops to a single line there instead. It asks of a rendered
|
||||
// diff the question patch.Patch.IsSingleHunkForWholeFile asks of a patch.
|
||||
// entire, so hunk mode drops to a single line there instead.
|
||||
//
|
||||
// It says false while the diff is still being read in, since the rows that would
|
||||
// answer otherwise — a context line, a change of the other kind — may not have
|
||||
|
||||
@@ -1,30 +1,10 @@
|
||||
package controllers
|
||||
|
||||
import (
|
||||
"errors"
|
||||
|
||||
"github.com/jesseduffield/lazygit/pkg/gui/context"
|
||||
"github.com/jesseduffield/lazygit/pkg/gui/types"
|
||||
"github.com/samber/lo"
|
||||
)
|
||||
|
||||
type ToggleWhitespaceAction struct {
|
||||
c *ControllerCommon
|
||||
}
|
||||
|
||||
func (self *ToggleWhitespaceAction) Call() error {
|
||||
contextsThatDontSupportIgnoringWhitespace := []types.ContextKey{
|
||||
context.STAGING_MAIN_CONTEXT_KEY,
|
||||
context.STAGING_SECONDARY_CONTEXT_KEY,
|
||||
context.PATCH_BUILDING_MAIN_CONTEXT_KEY,
|
||||
}
|
||||
|
||||
if lo.Contains(contextsThatDontSupportIgnoringWhitespace, self.c.Context().Current().GetKey()) {
|
||||
// Ignoring whitespace is not supported in these views. Let the user
|
||||
// know that it's not going to work in case they try to turn it on.
|
||||
return errors.New(self.c.Tr.IgnoreWhitespaceNotSupportedHere)
|
||||
}
|
||||
|
||||
self.c.UserConfig().Git.IgnoreWhitespaceInDiffView = !self.c.UserConfig().Git.IgnoreWhitespaceInDiffView
|
||||
|
||||
// You toggle this to see whether what you are looking at is more than
|
||||
|
||||
@@ -175,8 +175,6 @@ func (self *guiCommon) RenderToMainViews(opts types.RefreshMainOpts) {
|
||||
func (self *guiCommon) MainViewPairs() types.MainViewPairs {
|
||||
return types.MainViewPairs{
|
||||
Normal: self.gui.normalMainContextPair(),
|
||||
Staging: self.gui.stagingMainContextPair(),
|
||||
PatchBuilding: self.gui.patchBuildingMainContextPair(),
|
||||
MergeConflicts: self.gui.mergingMainContextPair(),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -84,20 +84,6 @@ func (gui *Gui) normalMainContextPair() types.MainContextPair {
|
||||
)
|
||||
}
|
||||
|
||||
func (gui *Gui) stagingMainContextPair() types.MainContextPair {
|
||||
return types.NewMainContextPair(
|
||||
gui.State.Contexts.Staging,
|
||||
gui.State.Contexts.StagingSecondary,
|
||||
)
|
||||
}
|
||||
|
||||
func (gui *Gui) patchBuildingMainContextPair() types.MainContextPair {
|
||||
return types.NewMainContextPair(
|
||||
gui.State.Contexts.CustomPatchBuilder,
|
||||
gui.State.Contexts.CustomPatchBuilderSecondary,
|
||||
)
|
||||
}
|
||||
|
||||
func (gui *Gui) mergingMainContextPair() types.MainContextPair {
|
||||
return types.NewMainContextPair(
|
||||
gui.State.Contexts.MergeConflicts,
|
||||
@@ -108,8 +94,6 @@ func (gui *Gui) mergingMainContextPair() types.MainContextPair {
|
||||
func (gui *Gui) allMainContextPairs() []types.MainContextPair {
|
||||
return []types.MainContextPair{
|
||||
gui.normalMainContextPair(),
|
||||
gui.stagingMainContextPair(),
|
||||
gui.patchBuildingMainContextPair(),
|
||||
gui.mergingMainContextPair(),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,47 +0,0 @@
|
||||
package patch_exploring
|
||||
|
||||
func calculateOrigin(currentOrigin int, bufferHeight int, numLines int, firstLineIdx int, lastLineIdx int, selectedLineIdx int, mode selectMode) int {
|
||||
needToSeeIdx, wantToSeeIdx := getNeedAndWantLineIdx(firstLineIdx, lastLineIdx, selectedLineIdx, mode)
|
||||
|
||||
return calculateNewOriginWithNeededAndWantedIdx(currentOrigin, bufferHeight, numLines, needToSeeIdx, wantToSeeIdx)
|
||||
}
|
||||
|
||||
// we want to scroll our origin so that the index we need to see is in view
|
||||
// and the other index we want to see (e.g. the other side of a line range)
|
||||
// is as close to being in view as possible.
|
||||
func calculateNewOriginWithNeededAndWantedIdx(currentOrigin int, bufferHeight int, numLines int, needToSeeIdx int, wantToSeeIdx int) int {
|
||||
origin := currentOrigin
|
||||
if needToSeeIdx < currentOrigin || needToSeeIdx >= currentOrigin+bufferHeight {
|
||||
origin = max(min(needToSeeIdx-bufferHeight/2, numLines-bufferHeight), 0)
|
||||
}
|
||||
|
||||
bottom := origin + bufferHeight
|
||||
|
||||
if wantToSeeIdx < origin {
|
||||
requiredChange := origin - wantToSeeIdx
|
||||
allowedChange := bottom - needToSeeIdx
|
||||
return origin - min(requiredChange, allowedChange)
|
||||
} else if wantToSeeIdx >= bottom {
|
||||
requiredChange := wantToSeeIdx + 1 - bottom
|
||||
allowedChange := needToSeeIdx - origin
|
||||
return origin + min(requiredChange, allowedChange)
|
||||
}
|
||||
return origin
|
||||
}
|
||||
|
||||
func getNeedAndWantLineIdx(firstLineIdx int, lastLineIdx int, selectedLineIdx int, mode selectMode) (int, int) {
|
||||
switch mode {
|
||||
case LINE:
|
||||
return selectedLineIdx, selectedLineIdx
|
||||
case RANGE:
|
||||
if selectedLineIdx == firstLineIdx {
|
||||
return firstLineIdx, lastLineIdx
|
||||
}
|
||||
return lastLineIdx, firstLineIdx
|
||||
case HUNK:
|
||||
return firstLineIdx, lastLineIdx
|
||||
default:
|
||||
// we should never land here
|
||||
panic("unknown mode")
|
||||
}
|
||||
}
|
||||
@@ -1,129 +0,0 @@
|
||||
package patch_exploring
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestNewOrigin(t *testing.T) {
|
||||
type scenario struct {
|
||||
name string
|
||||
origin int
|
||||
bufferHeight int
|
||||
numLines int
|
||||
firstLineIdx int
|
||||
lastLineIdx int
|
||||
selectedLineIdx int
|
||||
selectMode selectMode
|
||||
expected int
|
||||
}
|
||||
|
||||
scenarios := []scenario{
|
||||
{
|
||||
name: "selection above scroll window, enough room to put it in the middle",
|
||||
origin: 250,
|
||||
bufferHeight: 100,
|
||||
numLines: 500,
|
||||
firstLineIdx: 210,
|
||||
lastLineIdx: 210,
|
||||
selectedLineIdx: 210,
|
||||
selectMode: LINE,
|
||||
expected: 160,
|
||||
},
|
||||
{
|
||||
name: "selection above scroll window, not enough room to put it in the middle",
|
||||
origin: 50,
|
||||
bufferHeight: 100,
|
||||
numLines: 500,
|
||||
firstLineIdx: 10,
|
||||
lastLineIdx: 10,
|
||||
selectedLineIdx: 10,
|
||||
selectMode: LINE,
|
||||
expected: 0,
|
||||
},
|
||||
{
|
||||
name: "selection below scroll window, enough room to put it in the middle",
|
||||
origin: 0,
|
||||
bufferHeight: 100,
|
||||
numLines: 500,
|
||||
firstLineIdx: 150,
|
||||
lastLineIdx: 150,
|
||||
selectedLineIdx: 150,
|
||||
selectMode: LINE,
|
||||
expected: 100,
|
||||
},
|
||||
{
|
||||
name: "selection below scroll window, not enough room to put it in the middle",
|
||||
origin: 0,
|
||||
bufferHeight: 100,
|
||||
numLines: 200,
|
||||
firstLineIdx: 199,
|
||||
lastLineIdx: 199,
|
||||
selectedLineIdx: 199,
|
||||
selectMode: LINE,
|
||||
expected: 100,
|
||||
},
|
||||
{
|
||||
name: "selection within scroll window",
|
||||
origin: 0,
|
||||
bufferHeight: 100,
|
||||
numLines: 500,
|
||||
firstLineIdx: 50,
|
||||
lastLineIdx: 50,
|
||||
selectedLineIdx: 50,
|
||||
selectMode: LINE,
|
||||
expected: 0,
|
||||
},
|
||||
{
|
||||
name: "range ending below scroll window with selection at end of range",
|
||||
origin: 0,
|
||||
bufferHeight: 100,
|
||||
numLines: 500,
|
||||
firstLineIdx: 40,
|
||||
lastLineIdx: 150,
|
||||
selectedLineIdx: 150,
|
||||
selectMode: RANGE,
|
||||
expected: 50,
|
||||
},
|
||||
{
|
||||
name: "range ending below scroll window with selection at beginning of range",
|
||||
origin: 0,
|
||||
bufferHeight: 100,
|
||||
numLines: 500,
|
||||
firstLineIdx: 40,
|
||||
lastLineIdx: 150,
|
||||
selectedLineIdx: 40,
|
||||
selectMode: RANGE,
|
||||
expected: 40,
|
||||
},
|
||||
{
|
||||
name: "range starting above scroll window with selection at beginning of range",
|
||||
origin: 50,
|
||||
bufferHeight: 100,
|
||||
numLines: 500,
|
||||
firstLineIdx: 40,
|
||||
lastLineIdx: 150,
|
||||
selectedLineIdx: 40,
|
||||
selectMode: RANGE,
|
||||
expected: 40,
|
||||
},
|
||||
{
|
||||
name: "hunk extending beyond both bounds of scroll window",
|
||||
origin: 50,
|
||||
bufferHeight: 100,
|
||||
numLines: 500,
|
||||
firstLineIdx: 40,
|
||||
lastLineIdx: 200,
|
||||
selectedLineIdx: 70,
|
||||
selectMode: HUNK,
|
||||
expected: 40,
|
||||
},
|
||||
}
|
||||
|
||||
for _, s := range scenarios {
|
||||
t.Run(s.name, func(t *testing.T) {
|
||||
assert.EqualValues(t, s.expected, calculateOrigin(s.origin, s.bufferHeight, s.numLines, s.firstLineIdx, s.lastLineIdx, s.selectedLineIdx, s.selectMode))
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -1,438 +0,0 @@
|
||||
package patch_exploring
|
||||
|
||||
import (
|
||||
"strings"
|
||||
|
||||
"github.com/jesseduffield/generics/set"
|
||||
"github.com/jesseduffield/lazygit/pkg/commands/patch"
|
||||
"github.com/jesseduffield/lazygit/pkg/gocui"
|
||||
"github.com/jesseduffield/lazygit/pkg/utils"
|
||||
"github.com/samber/lo"
|
||||
)
|
||||
|
||||
// State represents the current state of the patch explorer context i.e. when
|
||||
// you're staging a file or you're building a patch from an existing commit
|
||||
// this struct holds the info about the diff you're interacting with and what's currently selected.
|
||||
type State struct {
|
||||
// These are in terms of view lines (wrapped), not patch lines
|
||||
selectedLineIdx int
|
||||
rangeStartLineIdx int
|
||||
// If a range is sticky, it means we expand the range when we move up or down.
|
||||
// Otherwise, we cancel the range when we move up or down.
|
||||
rangeIsSticky bool
|
||||
diff string
|
||||
patch *patch.Patch
|
||||
selectMode selectMode
|
||||
|
||||
// Array of indices of the wrapped lines indexed by a patch line index
|
||||
viewLineIndices []int
|
||||
// Array of indices of the original patch lines indexed by a wrapped view line index
|
||||
patchLineIndices []int
|
||||
|
||||
// whether the user has switched to hunk mode manually; if hunk mode is on
|
||||
// but this is false, then hunk mode was enabled because the config makes it
|
||||
// on by default.
|
||||
// this makes a difference for whether we want to escape out of hunk mode
|
||||
userEnabledHunkMode bool
|
||||
}
|
||||
|
||||
// these represent what select mode we're in
|
||||
type selectMode int
|
||||
|
||||
const (
|
||||
LINE selectMode = iota
|
||||
RANGE
|
||||
HUNK
|
||||
)
|
||||
|
||||
func NewState(diff string, selectedLineIdx int, view *gocui.View, oldState *State, useHunkModeByDefault bool) *State {
|
||||
if oldState != nil && diff == oldState.diff && selectedLineIdx == -1 {
|
||||
// if we're here then we can return the old state. If selectedLineIdx was not -1
|
||||
// then that would mean we were trying to click and potentially drag a range, which
|
||||
// is why in that case we continue below
|
||||
return oldState
|
||||
}
|
||||
|
||||
patch := patch.Parse(diff)
|
||||
|
||||
if !patch.ContainsChanges() {
|
||||
return nil
|
||||
}
|
||||
|
||||
viewLineIndices, patchLineIndices := wrapPatchLines(diff, view)
|
||||
|
||||
rangeStartLineIdx := 0
|
||||
if oldState != nil {
|
||||
rangeStartLineIdx = oldState.rangeStartLineIdx
|
||||
}
|
||||
|
||||
selectMode := LINE
|
||||
if useHunkModeByDefault && !patch.IsSingleHunkForWholeFile() {
|
||||
selectMode = HUNK
|
||||
}
|
||||
|
||||
userEnabledHunkMode := false
|
||||
if oldState != nil {
|
||||
userEnabledHunkMode = oldState.userEnabledHunkMode
|
||||
}
|
||||
|
||||
// if we have clicked from the outside to focus the main view we'll pass in a non-negative line index so that we can instantly select that line
|
||||
if selectedLineIdx >= 0 {
|
||||
// Clamp to the number of wrapped view lines; index might be out of
|
||||
// bounds if a custom diff renderer is being used which produces more lines
|
||||
selectedLineIdx = min(selectedLineIdx, len(viewLineIndices)-1)
|
||||
|
||||
selectMode = RANGE
|
||||
rangeStartLineIdx = selectedLineIdx
|
||||
} else if oldState != nil {
|
||||
// if we previously had a selectMode of RANGE, we want that to now be line again (or hunk, if that's the default)
|
||||
if oldState.selectMode != RANGE {
|
||||
selectMode = oldState.selectMode
|
||||
}
|
||||
oldPatchLineIdx := oldState.patchLineIndices[oldState.selectedLineIdx]
|
||||
newPatchLineIdx := patch.GetNextChangeIdx(oldPatchLineIdx)
|
||||
// When staging an addition from a consecutive changes block, the unselected deletions get
|
||||
// reordered to appear before the remaining additions in the new diff. This can cause the
|
||||
// cursor to land on a deletion at the same patch line index where the staged addition used
|
||||
// to be. In that case, skip forward past any deletions, then call GetNextChangeIdx from the
|
||||
// first non-deletion position, which correctly lands on the next meaningful change.
|
||||
newLines := patch.Lines()
|
||||
if newPatchLineIdx == oldPatchLineIdx &&
|
||||
oldState.patch.Lines()[oldPatchLineIdx].IsAddition() &&
|
||||
newLines[newPatchLineIdx].IsDeletion() &&
|
||||
patch.HunkOldStartForLine(newPatchLineIdx) == oldState.patch.HunkOldStartForLine(oldPatchLineIdx) {
|
||||
for newPatchLineIdx < len(newLines) && newLines[newPatchLineIdx].IsDeletion() {
|
||||
newPatchLineIdx++
|
||||
}
|
||||
newPatchLineIdx = patch.GetNextChangeIdx(newPatchLineIdx)
|
||||
}
|
||||
selectedLineIdx = viewLineIndices[newPatchLineIdx]
|
||||
} else {
|
||||
selectedLineIdx = viewLineIndices[patch.GetNextChangeIdx(0)]
|
||||
}
|
||||
|
||||
return &State{
|
||||
patch: patch,
|
||||
selectedLineIdx: selectedLineIdx,
|
||||
selectMode: selectMode,
|
||||
rangeStartLineIdx: rangeStartLineIdx,
|
||||
rangeIsSticky: false,
|
||||
diff: diff,
|
||||
viewLineIndices: viewLineIndices,
|
||||
patchLineIndices: patchLineIndices,
|
||||
userEnabledHunkMode: userEnabledHunkMode,
|
||||
}
|
||||
}
|
||||
|
||||
func (s *State) OnViewWidthChanged(view *gocui.View) {
|
||||
if !view.Wrap {
|
||||
return
|
||||
}
|
||||
|
||||
selectedPatchLineIdx := s.patchLineIndices[s.selectedLineIdx]
|
||||
var rangeStartPatchLineIdx int
|
||||
if s.selectMode == RANGE {
|
||||
rangeStartPatchLineIdx = s.patchLineIndices[s.rangeStartLineIdx]
|
||||
}
|
||||
s.viewLineIndices, s.patchLineIndices = wrapPatchLines(s.diff, view)
|
||||
s.selectedLineIdx = s.viewLineIndices[selectedPatchLineIdx]
|
||||
if s.selectMode == RANGE {
|
||||
s.rangeStartLineIdx = s.viewLineIndices[rangeStartPatchLineIdx]
|
||||
}
|
||||
}
|
||||
|
||||
func (s *State) GetSelectedPatchLineIdx() int {
|
||||
return s.patchLineIndices[s.selectedLineIdx]
|
||||
}
|
||||
|
||||
func (s *State) GetSelectedViewLineIdx() int {
|
||||
return s.selectedLineIdx
|
||||
}
|
||||
|
||||
func (s *State) GetDiff() string {
|
||||
return s.diff
|
||||
}
|
||||
|
||||
func (s *State) ToggleSelectHunk() {
|
||||
if s.selectMode == HUNK {
|
||||
s.selectMode = LINE
|
||||
} else {
|
||||
s.selectMode = HUNK
|
||||
s.userEnabledHunkMode = true
|
||||
|
||||
// If we are not currently on a change line, select the next one (or the
|
||||
// previous one if there is no next one):
|
||||
s.selectedLineIdx = s.viewLineIndices[s.patch.GetNextChangeIdx(
|
||||
s.patchLineIndices[s.selectedLineIdx])]
|
||||
}
|
||||
}
|
||||
|
||||
func (s *State) ToggleStickySelectRange() {
|
||||
s.ToggleSelectRange(true)
|
||||
}
|
||||
|
||||
func (s *State) ToggleSelectRange(sticky bool) {
|
||||
if s.SelectingRange() {
|
||||
s.selectMode = LINE
|
||||
} else {
|
||||
s.selectMode = RANGE
|
||||
s.rangeStartLineIdx = s.selectedLineIdx
|
||||
s.rangeIsSticky = sticky
|
||||
}
|
||||
}
|
||||
|
||||
func (s *State) SetRangeIsSticky(value bool) {
|
||||
s.rangeIsSticky = value
|
||||
}
|
||||
|
||||
func (s *State) SelectingHunk() bool {
|
||||
return s.selectMode == HUNK
|
||||
}
|
||||
|
||||
func (s *State) SelectingHunkEnabledByUser() bool {
|
||||
return s.selectMode == HUNK && s.userEnabledHunkMode
|
||||
}
|
||||
|
||||
func (s *State) SelectingRange() bool {
|
||||
return s.selectMode == RANGE && (s.rangeIsSticky || s.rangeStartLineIdx != s.selectedLineIdx)
|
||||
}
|
||||
|
||||
func (s *State) SelectingLine() bool {
|
||||
return s.selectMode == LINE
|
||||
}
|
||||
|
||||
func (s *State) SetLineSelectMode() {
|
||||
s.selectMode = LINE
|
||||
}
|
||||
|
||||
func (s *State) DismissHunkSelectMode() {
|
||||
if s.SelectingHunk() {
|
||||
s.selectMode = LINE
|
||||
}
|
||||
}
|
||||
|
||||
// For when you move the cursor without holding shift (meaning if we're in
|
||||
// a non-sticky range select, we'll cancel it)
|
||||
func (s *State) SelectLine(newSelectedLineIdx int) {
|
||||
if s.selectMode == RANGE && !s.rangeIsSticky {
|
||||
s.selectMode = LINE
|
||||
}
|
||||
|
||||
s.selectLineWithoutRangeCheck(newSelectedLineIdx)
|
||||
}
|
||||
|
||||
func (s *State) clampLineIdx(lineIdx int) int {
|
||||
return lo.Clamp(lineIdx, 0, len(s.patchLineIndices)-1)
|
||||
}
|
||||
|
||||
// This just moves the cursor without caring about range select
|
||||
func (s *State) selectLineWithoutRangeCheck(newSelectedLineIdx int) {
|
||||
s.selectedLineIdx = s.clampLineIdx(newSelectedLineIdx)
|
||||
}
|
||||
|
||||
func (s *State) SelectNewLineForRange(newSelectedLineIdx int) {
|
||||
s.rangeStartLineIdx = s.clampLineIdx(newSelectedLineIdx)
|
||||
|
||||
s.selectMode = RANGE
|
||||
|
||||
s.selectLineWithoutRangeCheck(newSelectedLineIdx)
|
||||
}
|
||||
|
||||
func (s *State) DragSelectLine(newSelectedLineIdx int) {
|
||||
s.selectMode = RANGE
|
||||
|
||||
s.selectLineWithoutRangeCheck(newSelectedLineIdx)
|
||||
}
|
||||
|
||||
func (s *State) CycleSelection(forward bool) {
|
||||
if s.SelectingHunk() {
|
||||
if forward {
|
||||
s.SelectNextHunk()
|
||||
} else {
|
||||
s.SelectPreviousHunk()
|
||||
}
|
||||
} else {
|
||||
s.CycleLine(forward)
|
||||
}
|
||||
}
|
||||
|
||||
func (s *State) SelectPreviousHunk() {
|
||||
patchLines := s.patch.Lines()
|
||||
patchLineIdx := s.patchLineIndices[s.selectedLineIdx]
|
||||
nextNonChangeLine := patchLineIdx
|
||||
for nextNonChangeLine >= 0 && patchLines[nextNonChangeLine].IsChange() {
|
||||
nextNonChangeLine--
|
||||
}
|
||||
nextChangeLine := nextNonChangeLine
|
||||
for nextChangeLine >= 0 && !patchLines[nextChangeLine].IsChange() {
|
||||
nextChangeLine--
|
||||
}
|
||||
if nextChangeLine >= 0 {
|
||||
// Now we found a previous hunk, but we're on its last line. Skip to the beginning.
|
||||
for nextChangeLine > 0 && patchLines[nextChangeLine-1].IsChange() {
|
||||
nextChangeLine--
|
||||
}
|
||||
s.selectedLineIdx = s.viewLineIndices[nextChangeLine]
|
||||
}
|
||||
}
|
||||
|
||||
func (s *State) SelectNextHunk() {
|
||||
patchLines := s.patch.Lines()
|
||||
patchLineIdx := s.patchLineIndices[s.selectedLineIdx]
|
||||
nextNonChangeLine := patchLineIdx
|
||||
for nextNonChangeLine < len(patchLines) && patchLines[nextNonChangeLine].IsChange() {
|
||||
nextNonChangeLine++
|
||||
}
|
||||
nextChangeLine := nextNonChangeLine
|
||||
for nextChangeLine < len(patchLines) && !patchLines[nextChangeLine].IsChange() {
|
||||
nextChangeLine++
|
||||
}
|
||||
if nextChangeLine < len(patchLines) {
|
||||
s.selectedLineIdx = s.viewLineIndices[nextChangeLine]
|
||||
}
|
||||
}
|
||||
|
||||
func (s *State) CycleLine(forward bool) {
|
||||
change := 1
|
||||
if !forward {
|
||||
change = -1
|
||||
}
|
||||
|
||||
s.SelectLine(s.selectedLineIdx + change)
|
||||
}
|
||||
|
||||
// This is called when we use shift+arrow to expand the range (i.e. a non-sticky
|
||||
// range)
|
||||
func (s *State) CycleRange(forward bool) {
|
||||
if !s.SelectingRange() {
|
||||
s.ToggleSelectRange(false)
|
||||
}
|
||||
|
||||
s.SetRangeIsSticky(false)
|
||||
|
||||
change := 1
|
||||
if !forward {
|
||||
change = -1
|
||||
}
|
||||
|
||||
s.selectLineWithoutRangeCheck(s.selectedLineIdx + change)
|
||||
}
|
||||
|
||||
// returns first and last patch line index of current hunk
|
||||
func (s *State) CurrentHunkBounds() (int, int) {
|
||||
hunkIdx := s.patch.HunkContainingLine(s.patchLineIndices[s.selectedLineIdx])
|
||||
start := s.patch.HunkStartIdx(hunkIdx)
|
||||
end := s.patch.HunkEndIdx(hunkIdx)
|
||||
return start, end
|
||||
}
|
||||
|
||||
func (s *State) selectionRangeForCurrentBlockOfChanges() (int, int) {
|
||||
patchLines := s.patch.Lines()
|
||||
patchLineIdx := s.patchLineIndices[s.selectedLineIdx]
|
||||
|
||||
patchStart := patchLineIdx
|
||||
for patchStart > 0 && patchLines[patchStart-1].IsChange() {
|
||||
patchStart--
|
||||
}
|
||||
|
||||
patchEnd := patchLineIdx
|
||||
for patchEnd < len(patchLines)-1 && patchLines[patchEnd+1].IsChange() {
|
||||
patchEnd++
|
||||
}
|
||||
|
||||
viewStart, viewEnd := s.viewLineIndices[patchStart], s.viewLineIndices[patchEnd]
|
||||
|
||||
// Increase viewEnd in case the last patch line is wrapped to more than one view line.
|
||||
for viewEnd < len(s.patchLineIndices)-1 && s.patchLineIndices[viewEnd] == s.patchLineIndices[viewEnd+1] {
|
||||
viewEnd++
|
||||
}
|
||||
|
||||
return viewStart, viewEnd
|
||||
}
|
||||
|
||||
func (s *State) SelectedViewRange() (int, int) {
|
||||
switch s.selectMode {
|
||||
case HUNK:
|
||||
return s.selectionRangeForCurrentBlockOfChanges()
|
||||
case RANGE:
|
||||
if s.rangeStartLineIdx > s.selectedLineIdx {
|
||||
return s.selectedLineIdx, s.rangeStartLineIdx
|
||||
}
|
||||
return s.rangeStartLineIdx, s.selectedLineIdx
|
||||
case LINE:
|
||||
return s.selectedLineIdx, s.selectedLineIdx
|
||||
default:
|
||||
// should never happen
|
||||
return 0, 0
|
||||
}
|
||||
}
|
||||
|
||||
func (s *State) SelectedPatchRange() (int, int) {
|
||||
start, end := s.SelectedViewRange()
|
||||
return s.patchLineIndices[start], s.patchLineIndices[end]
|
||||
}
|
||||
|
||||
// Returns the line indices of the selected patch range that are changes (i.e. additions or deletions)
|
||||
func (s *State) LineIndicesOfAddedOrDeletedLinesInSelectedPatchRange() []int {
|
||||
viewStart, viewEnd := s.SelectedViewRange()
|
||||
patchStart, patchEnd := s.patchLineIndices[viewStart], s.patchLineIndices[viewEnd]
|
||||
lines := s.patch.Lines()
|
||||
indices := []int{}
|
||||
for i := patchStart; i <= patchEnd; i++ {
|
||||
if lines[i].IsChange() {
|
||||
indices = append(indices, i)
|
||||
}
|
||||
}
|
||||
return indices
|
||||
}
|
||||
|
||||
func (s *State) CurrentLineNumber() int {
|
||||
return s.patch.LineNumberOfLine(s.patchLineIndices[s.selectedLineIdx])
|
||||
}
|
||||
|
||||
func (s *State) AdjustSelectedLineIdx(change int) {
|
||||
s.DismissHunkSelectMode()
|
||||
s.SelectLine(s.selectedLineIdx + change)
|
||||
}
|
||||
|
||||
func (s *State) RenderForLineIndices(includedLineIndices []int) string {
|
||||
includedLineIndicesSet := set.NewFromSlice(includedLineIndices)
|
||||
return s.patch.FormatView(patch.FormatViewOpts{
|
||||
IncLineIndices: includedLineIndicesSet,
|
||||
})
|
||||
}
|
||||
|
||||
func (s *State) PlainRenderSelected() string {
|
||||
firstLineIdx, lastLineIdx := s.SelectedPatchRange()
|
||||
return s.patch.FormatRangePlain(firstLineIdx, lastLineIdx)
|
||||
}
|
||||
|
||||
func (s *State) SelectBottom() {
|
||||
s.DismissHunkSelectMode()
|
||||
s.SelectLine(len(s.patchLineIndices) - 1)
|
||||
}
|
||||
|
||||
func (s *State) SelectTop() {
|
||||
s.DismissHunkSelectMode()
|
||||
s.SelectLine(0)
|
||||
}
|
||||
|
||||
func (s *State) CalculateOrigin(currentOrigin int, bufferHeight int, numLines int) int {
|
||||
firstLineIdx, lastLineIdx := s.SelectedViewRange()
|
||||
|
||||
return calculateOrigin(currentOrigin, bufferHeight, numLines, firstLineIdx, lastLineIdx, s.GetSelectedViewLineIdx(), s.selectMode)
|
||||
}
|
||||
|
||||
func wrapPatchLines(diff string, view *gocui.View) ([]int, []int) {
|
||||
_, viewLineIndices, patchLineIndices := utils.WrapViewLinesToWidth(
|
||||
view.Wrap, view.Editable, strings.TrimSuffix(diff, "\n"), view.InnerWidth(), view.TabWidth)
|
||||
return viewLineIndices, patchLineIndices
|
||||
}
|
||||
|
||||
func (s *State) SelectNextStageableLineOfSameIncludedState(includedLines []int, included bool) {
|
||||
_, lastLineIdx := s.SelectedPatchRange()
|
||||
patchLineIdx, found := s.patch.GetNextChangeIdxOfSameIncludedState(lastLineIdx+1, includedLines, included)
|
||||
if found {
|
||||
s.SelectLine(s.viewLineIndices[patchLineIdx])
|
||||
}
|
||||
}
|
||||
@@ -3,9 +3,7 @@ package types
|
||||
import (
|
||||
"github.com/jesseduffield/lazygit/pkg/config"
|
||||
"github.com/jesseduffield/lazygit/pkg/gocui"
|
||||
"github.com/jesseduffield/lazygit/pkg/gui/patch_exploring"
|
||||
"github.com/jesseduffield/lazygit/pkg/utils"
|
||||
"github.com/sasha-s/go-deadlock"
|
||||
)
|
||||
|
||||
type ContextKind int
|
||||
@@ -292,20 +290,6 @@ type IListContext interface {
|
||||
IndexForGotoBottom() int
|
||||
}
|
||||
|
||||
type IPatchExplorerContext interface {
|
||||
Context
|
||||
|
||||
GetState() *patch_exploring.State
|
||||
SetState(*patch_exploring.State)
|
||||
GetIncludedLineIndices() []int
|
||||
RenderAndFocus()
|
||||
Render()
|
||||
GetContentToRender() string
|
||||
NavigateTo(selectedLineIdx int)
|
||||
GetMutex() *deadlock.Mutex
|
||||
IsPatchExplorerContext() // used for type switch
|
||||
}
|
||||
|
||||
type IViewTrait interface {
|
||||
FocusPoint(yIdx int, scrollIntoView bool)
|
||||
SetRangeSelectStart(yIdx int)
|
||||
@@ -441,5 +425,4 @@ type IContextMgr interface {
|
||||
AllList() []IListContext
|
||||
AllFilterable() []IFilterableContext
|
||||
AllSearchable() []ISearchableContext
|
||||
AllPatchExplorer() []IPatchExplorerContext
|
||||
}
|
||||
|
||||
@@ -31,8 +31,6 @@ const (
|
||||
type MainViewPairs struct {
|
||||
Normal MainContextPair
|
||||
MergeConflicts MainContextPair
|
||||
Staging MainContextPair
|
||||
PatchBuilding MainContextPair
|
||||
}
|
||||
|
||||
type ViewUpdateOpts struct {
|
||||
|
||||
@@ -15,13 +15,9 @@ type Views struct {
|
||||
Commits *gocui.View
|
||||
Stash *gocui.View
|
||||
|
||||
Main *gocui.View
|
||||
Secondary *gocui.View
|
||||
Staging *gocui.View
|
||||
StagingSecondary *gocui.View
|
||||
PatchBuilding *gocui.View
|
||||
PatchBuildingSecondary *gocui.View
|
||||
MergeConflicts *gocui.View
|
||||
Main *gocui.View
|
||||
Secondary *gocui.View
|
||||
MergeConflicts *gocui.View
|
||||
|
||||
Options *gocui.View
|
||||
Confirmation *gocui.View
|
||||
|
||||
+2
-14
@@ -41,10 +41,6 @@ func (gui *Gui) orderedViewNameMappings() []viewNameMapping {
|
||||
{viewPtr: &gui.Views.SubCommits, name: "subCommits"},
|
||||
{viewPtr: &gui.Views.CommitFiles, name: "commitFiles"},
|
||||
|
||||
{viewPtr: &gui.Views.Staging, name: "staging"},
|
||||
{viewPtr: &gui.Views.StagingSecondary, name: "stagingSecondary"},
|
||||
{viewPtr: &gui.Views.PatchBuilding, name: "patchBuilding"},
|
||||
{viewPtr: &gui.Views.PatchBuildingSecondary, name: "patchBuildingSecondary"},
|
||||
{viewPtr: &gui.Views.MergeConflicts, name: "mergeConflicts"},
|
||||
{viewPtr: &gui.Views.Secondary, name: "secondary"},
|
||||
{viewPtr: &gui.Views.Main, name: "main"},
|
||||
@@ -106,16 +102,12 @@ func (gui *Gui) createAllViews() error {
|
||||
gui.Views.Search.Frame = false
|
||||
gui.Views.Search.Editor = gocui.EditorFunc(gui.searchEditor)
|
||||
|
||||
for _, view := range []*gocui.View{gui.Views.Main, gui.Views.Secondary, gui.Views.Staging, gui.Views.StagingSecondary, gui.Views.PatchBuilding, gui.Views.PatchBuildingSecondary, gui.Views.MergeConflicts} {
|
||||
for _, view := range []*gocui.View{gui.Views.Main, gui.Views.Secondary, gui.Views.MergeConflicts} {
|
||||
view.Wrap = true
|
||||
view.UnderlineHyperLinksOnlyOnHover = true
|
||||
view.AutoRenderHyperLinks = true
|
||||
}
|
||||
|
||||
gui.Views.Staging.Wrap = true
|
||||
gui.Views.StagingSecondary.Wrap = true
|
||||
gui.Views.PatchBuilding.Wrap = true
|
||||
gui.Views.PatchBuildingSecondary.Wrap = true
|
||||
gui.Views.MergeConflicts.Wrap = false
|
||||
gui.Views.Limit.Wrap = true
|
||||
|
||||
@@ -237,19 +229,15 @@ func (gui *Gui) configureViewProperties() {
|
||||
gui.Views.Submodules.Title = gui.c.Tr.SubmodulesTitle
|
||||
gui.Views.Tags.Title = gui.c.Tr.TagsTitle
|
||||
gui.Views.Files.Title = gui.c.Tr.FilesTitle
|
||||
gui.Views.PatchBuilding.Title = gui.c.Tr.Patch
|
||||
gui.Views.PatchBuildingSecondary.Title = gui.c.Tr.CustomPatch
|
||||
gui.Views.MergeConflicts.Title = gui.c.Tr.MergeConflictsTitle
|
||||
gui.Views.Limit.Title = gui.c.Tr.NotEnoughSpace
|
||||
gui.Views.Status.Title = gui.c.Tr.StatusTitle
|
||||
gui.Views.Staging.Title = gui.c.Tr.UnstagedChanges
|
||||
gui.Views.StagingSecondary.Title = gui.c.Tr.StagedChanges
|
||||
gui.Views.CommitMessage.Title = gui.c.Tr.CommitSummary
|
||||
gui.Views.CommitDescription.Title = gui.c.Tr.CommitDescriptionTitle
|
||||
gui.Views.Extras.Title = gui.c.Tr.CommandLog
|
||||
gui.Views.Snake.Title = gui.c.Tr.SnakeTitle
|
||||
|
||||
for _, view := range []*gocui.View{gui.Views.Main, gui.Views.Secondary, gui.Views.Staging, gui.Views.StagingSecondary, gui.Views.PatchBuilding, gui.Views.PatchBuildingSecondary, gui.Views.MergeConflicts} {
|
||||
for _, view := range []*gocui.View{gui.Views.Main, gui.Views.Secondary, gui.Views.MergeConflicts} {
|
||||
view.Title = gui.c.Tr.DiffTitle
|
||||
view.CanScrollPastBottom = gui.c.UserConfig().Gui.ScrollPastBottom
|
||||
view.TabWidth = gui.c.UserConfig().Gui.TabWidth
|
||||
|
||||
@@ -34,10 +34,6 @@ func (self *Views) regularView(viewName string) *ViewDriver {
|
||||
}
|
||||
}
|
||||
|
||||
func (self *Views) patchExplorerViewByName(viewName string) *ViewDriver {
|
||||
return self.regularView(viewName)
|
||||
}
|
||||
|
||||
func (self *Views) MergeConflicts() *ViewDriver {
|
||||
return self.regularView("mergeConflicts")
|
||||
}
|
||||
@@ -102,24 +98,6 @@ func (self *Views) Stash() *ViewDriver {
|
||||
return self.regularView("stash")
|
||||
}
|
||||
|
||||
func (self *Views) Staging() *ViewDriver {
|
||||
return self.patchExplorerViewByName("staging")
|
||||
}
|
||||
|
||||
func (self *Views) StagingSecondary() *ViewDriver {
|
||||
return self.patchExplorerViewByName("stagingSecondary")
|
||||
}
|
||||
|
||||
func (self *Views) PatchBuilding() *ViewDriver {
|
||||
return self.patchExplorerViewByName("patchBuilding")
|
||||
}
|
||||
|
||||
func (self *Views) PatchBuildingSecondary() *ViewDriver {
|
||||
// this is not a patch explorer view because you can't actually focus it: it
|
||||
// just renders content
|
||||
return self.regularView("patchBuildingSecondary")
|
||||
}
|
||||
|
||||
func (self *Views) Menu() *ViewDriver {
|
||||
return self.regularView("menu")
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user