Compare commits

...

10 Commits

Author SHA1 Message Date
Dawid Dziurla
1dc837527f workflows: update PPA repo as part of CD process 2020-10-13 13:43:14 +02:00
Jesse Duffield
b1dd3c4866 support rebinding confirm/newline keys in editor 2020-10-13 08:21:09 +11:00
Jesse Duffield
624fb8da21 preserve width of side panel when main view split unless window is wide enough 2020-10-13 07:31:14 +11:00
nullawhale
1ff405edd8 Copy a commit message to clipboard: Changes to latest version 2020-10-12 21:04:01 +11:00
Jesse Duffield
031e97ef91 more password checks on commands that talk to the remote 2020-10-12 19:07:40 +11:00
Jesse Duffield
3df0a9f132 update in-app release notes 2020-10-12 09:08:47 +11:00
Jesse Duffield
1e79ab78dd return default config when dealing with read only filesystem rather than create new config file 2020-10-12 08:48:28 +11:00
Jesse Duffield
1e48afeb8f quote config file when editing 2020-10-12 08:47:12 +11:00
Jesse Duffield
b8ad1883f5 fix delta 2020-10-12 08:26:31 +11:00
band-a-prend
582fd24d78 Add SSH key passphrase prompt to pull/push from/to remote git repo
This commit resolves issue with absence of ssh key prompting
to pull from or push to remote git repository.

I checked lazygit with this patch for successfully pull from
and push to https://gitweb.gentoo.org/repo/proj/guru.git repository.
While for lazygit-0.23.1 I'm not able to do that.

The check for Passphrase follows the Password because of
more long time before SSH key is prompt in terminal.
Otherwise after timeout "Password" prompt is appears.

Excuse me for google translated i18n dutch lines.

Bug: https://github.com/jesseduffield/lazygit/issues/534

Signed-off-by: band-a-prend <torokhov-s-a@yandex.ru>
2020-10-10 17:58:23 +11:00
25 changed files with 276 additions and 92 deletions

View File

@@ -26,3 +26,20 @@ jobs:
with:
token: ${{secrets.GITHUB_API_TOKEN}}
formula: lazygit
- name: Checkout PPA repo
uses: actions/checkout@v2
with:
repository: dawidd6/lazygit-debian
token: ${{secrets.GITHUB_API_TOKEN}}
fetch-depth: 0
- name: Update PPA repo
run: |
version="$(echo "$GITHUB_REF" | sed 's@refs/tags/v@@')"
sudo apt install -y git-buildpackage
git fetch --tags https://github.com/$GITHUB_REPOSITORY
gbp import-ref -u "$version"
gbp dch -D xenial -N "$version"-1
git add debian/changelog
git commit -S -m "d/changelog: dch $version"
gbp tag
git push --tags origin master

View File

@@ -111,6 +111,8 @@ Default path for the config file:
diffingMenu: 'W'
diffingMenu-alt: '<c-e>' # deprecated
copyToClipboard: '<c-o>'
submitEditorText: '<enter>'
appendNewline: '<tab>'
status:
checkForUpdate: 'u'
recentRepos: '<enter>'
@@ -156,6 +158,7 @@ Default path for the config file:
tagCommit: 'T'
checkoutCommit: '<space>'
resetCherryPick: '<c-R>'
copyCommitMessageToClipboard: '<c-y>'
stash:
popStash: 'g'
commitFiles:

2
go.mod
View File

@@ -18,7 +18,7 @@ require (
github.com/imdario/mergo v0.3.11
github.com/integrii/flaggy v1.4.0
github.com/jesseduffield/go-git/v5 v5.1.2-0.20201006095850-341962be15a4
github.com/jesseduffield/gocui v0.3.1-0.20201007110350-cc51e317126e
github.com/jesseduffield/gocui v0.3.1-0.20201010224802-8a6768078fd7
github.com/jesseduffield/termbox-go v0.0.0-20200823212418-a2289ed6aafe
github.com/jesseduffield/yaml v2.1.0+incompatible
github.com/kardianos/osext v0.0.0-20190222173326-2bc1f35cddc0

4
go.sum
View File

@@ -63,8 +63,8 @@ github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 h1:BQSFePA1RWJOl
github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99/go.mod h1:1lJo3i6rXxKeerYnT8Nvf0QmHCRC1n8sfWVwXF2Frvo=
github.com/jesseduffield/go-git/v5 v5.1.2-0.20201006095850-341962be15a4 h1:GOQrmaE8i+KEdB8NzAegKYd4tPn/inM0I1uo0NXFerg=
github.com/jesseduffield/go-git/v5 v5.1.2-0.20201006095850-341962be15a4/go.mod h1:nGNEErzf+NRznT+N2SWqmHnDnF9aLgANB1CUNEan09o=
github.com/jesseduffield/gocui v0.3.1-0.20201007110350-cc51e317126e h1:FYXSJfL6JKWB+1NjGqT5/kYJbMI9oMx+JAI3CcrtLsM=
github.com/jesseduffield/gocui v0.3.1-0.20201007110350-cc51e317126e/go.mod h1:2RtZznzYKt8RLRwvFiSkXjU0Ei8WwHdubgnlaYH47dw=
github.com/jesseduffield/gocui v0.3.1-0.20201010224802-8a6768078fd7 h1:K3MGrjmpPtIhfXmKh/zsIF0CdmNKOkjpIwcUfAa/J2A=
github.com/jesseduffield/gocui v0.3.1-0.20201010224802-8a6768078fd7/go.mod h1:2RtZznzYKt8RLRwvFiSkXjU0Ei8WwHdubgnlaYH47dw=
github.com/jesseduffield/termbox-go v0.0.0-20200823212418-a2289ed6aafe h1:qsVhCf2RFyyKIUe/+gJblbCpXMUki9rZrHuEctg6M/E=
github.com/jesseduffield/termbox-go v0.0.0-20200823212418-a2289ed6aafe/go.mod h1:anMibpZtqNxjDbxrcDEAwSdaJ37vyUeM1f/M4uekib4=
github.com/jesseduffield/yaml v2.1.0+incompatible h1:HWQJ1gIv2zHKbDYNp0Jwjlj24K8aqpFHnMCynY1EpmE=

View File

@@ -22,7 +22,13 @@ func (c *GitCommand) ResetToCommit(sha string, strength string, options oscomman
// Commit commits to git
func (c *GitCommand) Commit(message string, flags string) (*exec.Cmd, error) {
command := fmt.Sprintf("git commit %s -m %s", flags, strconv.Quote(message))
splitMessage := strings.Split(message, "\n")
lineArgs := ""
for _, line := range splitMessage {
lineArgs += fmt.Sprintf(" -m %s", strconv.Quote(line))
}
command := fmt.Sprintf("git commit %s%s", flags, lineArgs)
if c.usingGpg() {
return c.OSCommand.ShellCommandFromString(command), nil
}

View File

@@ -143,18 +143,19 @@ func (c *OSCommand) RunCommandWithOutputLive(command string, output func(string)
return RunCommandWithOutputLiveWrapper(c, command, output)
}
// DetectUnamePass detect a username / password question in a command
// promptUserForCredential is a function that gets executed when this function detect you need to fillin a password
// The promptUserForCredential argument will be "username" or "password" and expects the user's password or username back
// DetectUnamePass detect a username / password / passphrase question in a command
// promptUserForCredential is a function that gets executed when this function detect you need to fillin a password or passphrase
// The promptUserForCredential argument will be "username", "password" or "passphrase" and expects the user's password/passphrase or username back
func (c *OSCommand) DetectUnamePass(command string, promptUserForCredential func(string) string) error {
ttyText := ""
errMessage := c.RunCommandWithOutputLive(command, func(word string) string {
ttyText = ttyText + " " + word
prompts := map[string]string{
`.+'s password:`: "password",
`Password\s*for\s*'.+':`: "password",
`Username\s*for\s*'.+':`: "username",
`.+'s password:`: "password",
`Password\s*for\s*'.+':`: "password",
`Username\s*for\s*'.+':`: "username",
`Enter\s*passphrase\s*for\s*key\s*'.+':`: "passphrase",
}
for pattern, askFor := range prompts {
@@ -254,7 +255,7 @@ func (c *OSCommand) EditFile(filename string) (*exec.Cmd, error) {
return nil, errors.New("No editor defined in $VISUAL, $EDITOR, or git config")
}
splitCmd := str.ToArgv(fmt.Sprintf("%s %s", editor, filename))
splitCmd := str.ToArgv(fmt.Sprintf("%s %s", editor, c.Quote(filename)))
return c.PrepareSubProcess(splitCmd[0], splitCmd[1:]...), nil
}

View File

@@ -227,6 +227,28 @@ func TestOSCommandEditFile(t *testing.T) {
assert.NoError(t, err)
},
},
{
"file/with space",
func(name string, args ...string) *exec.Cmd {
if name == "which" {
return exec.Command("echo")
}
assert.EqualValues(t, "vi", name)
assert.EqualValues(t, "file/with space", args[0])
return nil
},
func(env string) string {
return ""
},
func(cf string) (string, error) {
return "", nil
},
func(cmd *exec.Cmd, err error) {
assert.NoError(t, err)
},
},
}
for _, s := range scenarios {

View File

@@ -1,6 +1,8 @@
package commands
import (
"fmt"
"github.com/jesseduffield/lazygit/pkg/commands/models"
)
@@ -20,8 +22,9 @@ func (c *GitCommand) UpdateRemoteUrl(remoteName string, updatedUrl string) error
return c.OSCommand.RunCommand("git remote set-url %s %s", remoteName, updatedUrl)
}
func (c *GitCommand) DeleteRemoteBranch(remoteName string, branchName string) error {
return c.OSCommand.RunCommand("git push %s --delete %s", remoteName, branchName)
func (c *GitCommand) DeleteRemoteBranch(remoteName string, branchName string, promptUserForCredential func(string) string) error {
command := fmt.Sprintf("git push %s --delete %s", remoteName, branchName)
return c.OSCommand.DetectUnamePass(command, promptUserForCredential)
}
// CheckRemoteBranchExists Returns remote branch

View File

@@ -1,5 +1,7 @@
package commands
import "fmt"
func (c *GitCommand) CreateLightweightTag(tagName string, commitSha string) error {
return c.OSCommand.RunCommand("git tag %s %s", tagName, commitSha)
}
@@ -8,6 +10,7 @@ func (c *GitCommand) DeleteTag(tagName string) error {
return c.OSCommand.RunCommand("git tag -d %s", tagName)
}
func (c *GitCommand) PushTag(remoteName string, tagName string) error {
return c.OSCommand.RunCommand("git push %s %s", remoteName, tagName)
func (c *GitCommand) PushTag(remoteName string, tagName string, promptUserForCredential func(string) string) error {
command := fmt.Sprintf("git push %s %s", remoteName, tagName)
return c.OSCommand.DetectUnamePass(command, promptUserForCredential)
}

View File

@@ -4,6 +4,7 @@ import (
"io/ioutil"
"os"
"path/filepath"
"strings"
"github.com/OpenPeeDeeP/xdg"
yaml "github.com/jesseduffield/yaml"
@@ -114,6 +115,9 @@ func loadUserConfig(configDir string, base *UserConfig) (*UserConfig, error) {
if os.IsNotExist(err) {
file, err := os.Create(fileName)
if err != nil {
if strings.Contains(err.Error(), "read-only file system") {
return base, nil
}
return nil, err
}
file.Close()

View File

@@ -144,6 +144,8 @@ type KeybindingUniversalConfig struct {
DiffingMenu string `yaml:"diffingMenu"`
DiffingMenuAlt string `yaml:"diffingMenu-alt"`
CopyToClipboard string `yaml:"copyToClipboard"`
SubmitEditorText string `yaml:"submitEditorText"`
AppendNewline string `yaml:"appendNewline"`
}
type KeybindingStatusConfig struct {
@@ -180,24 +182,25 @@ type KeybindingBranchesConfig struct {
}
type KeybindingCommitsConfig struct {
SquashDown string `yaml:"squashDown"`
RenameCommit string `yaml:"renameCommit"`
RenameCommitWithEditor string `yaml:"renameCommitWithEditor"`
ViewResetOptions string `yaml:"viewResetOptions"`
MarkCommitAsFixup string `yaml:"markCommitAsFixup"`
CreateFixupCommit string `yaml:"createFixupCommit"`
SquashAboveCommits string `yaml:"squashAboveCommits"`
MoveDownCommit string `yaml:"moveDownCommit"`
MoveUpCommit string `yaml:"moveUpCommit"`
AmendToCommit string `yaml:"amendToCommit"`
PickCommit string `yaml:"pickCommit"`
RevertCommit string `yaml:"revertCommit"`
CherryPickCopy string `yaml:"cherryPickCopy"`
CherryPickCopyRange string `yaml:"cherryPickCopyRange"`
PasteCommits string `yaml:"pasteCommits"`
TagCommit string `yaml:"tagCommit"`
CheckoutCommit string `yaml:"checkoutCommit"`
ResetCherryPick string `yaml:"resetCherryPick"`
SquashDown string `yaml:"squashDown"`
RenameCommit string `yaml:"renameCommit"`
RenameCommitWithEditor string `yaml:"renameCommitWithEditor"`
ViewResetOptions string `yaml:"viewResetOptions"`
MarkCommitAsFixup string `yaml:"markCommitAsFixup"`
CreateFixupCommit string `yaml:"createFixupCommit"`
SquashAboveCommits string `yaml:"squashAboveCommits"`
MoveDownCommit string `yaml:"moveDownCommit"`
MoveUpCommit string `yaml:"moveUpCommit"`
AmendToCommit string `yaml:"amendToCommit"`
PickCommit string `yaml:"pickCommit"`
RevertCommit string `yaml:"revertCommit"`
CherryPickCopy string `yaml:"cherryPickCopy"`
CherryPickCopyRange string `yaml:"cherryPickCopyRange"`
PasteCommits string `yaml:"pasteCommits"`
TagCommit string `yaml:"tagCommit"`
CheckoutCommit string `yaml:"checkoutCommit"`
ResetCherryPick string `yaml:"resetCherryPick"`
CopyCommitMessageToClipboard string `yaml:"copyCommitMessageToClipboard"`
}
type KeybindingStashConfig struct {
@@ -359,6 +362,8 @@ func GetDefaultConfig() *UserConfig {
DiffingMenu: "W",
DiffingMenuAlt: "<c-e>",
CopyToClipboard: "<c-o>",
SubmitEditorText: "<enter>",
AppendNewline: "<tab>",
},
Status: KeybindingStatusConfig{
CheckForUpdate: "u",
@@ -390,24 +395,26 @@ func GetDefaultConfig() *UserConfig {
SetUpstream: "u",
FetchRemote: "f",
},
Commits: KeybindingCommitsConfig{SquashDown: "s",
RenameCommit: "r",
RenameCommitWithEditor: "R",
ViewResetOptions: "g",
MarkCommitAsFixup: "f",
CreateFixupCommit: "F",
SquashAboveCommits: "S",
MoveDownCommit: "<c-j>",
MoveUpCommit: "<c-k>",
AmendToCommit: "A",
PickCommit: "p",
RevertCommit: "t",
CherryPickCopy: "c",
CherryPickCopyRange: "C",
PasteCommits: "v",
TagCommit: "T",
CheckoutCommit: "<space>",
ResetCherryPick: "<c-R>",
Commits: KeybindingCommitsConfig{
SquashDown: "s",
RenameCommit: "r",
RenameCommitWithEditor: "R",
ViewResetOptions: "g",
MarkCommitAsFixup: "f",
CreateFixupCommit: "F",
SquashAboveCommits: "S",
MoveDownCommit: "<c-j>",
MoveUpCommit: "<c-k>",
AmendToCommit: "A",
PickCommit: "p",
RevertCommit: "t",
CherryPickCopy: "c",
CherryPickCopyRange: "C",
PasteCommits: "v",
TagCommit: "T",
CheckoutCommit: "<space>",
ResetCherryPick: "<c-R>",
CopyCommitMessageToClipboard: "<c-y>",
},
Stash: KeybindingStashConfig{
PopStash: "g",

View File

@@ -47,7 +47,7 @@ func (gui *Gui) getMidSectionWeights() (int, int) {
mainSectionWeight := int(1/sidePanelWidthRatio) - 1
sideSectionWeight := 1
if gui.isMainPanelSplit() {
if gui.splitMainPanelSideBySide() {
mainSectionWeight = 5 // need to shrink side panel to make way for main panels if side-by-side
}
@@ -108,6 +108,28 @@ func (gui *Gui) infoSectionChildren(informationStr string, appStatus string) []*
return result
}
func (gui *Gui) splitMainPanelSideBySide() bool {
if !gui.isMainPanelSplit() {
return false
}
mainPanelSplitMode := gui.Config.GetUserConfig().Gui.MainPanelSplitMode
width, height := gui.g.Size()
switch mainPanelSplitMode {
case "vertical":
return false
case "horizontal":
return true
default:
if width < 200 && height > 30 { // 2 80 character width panels + 40 width for side panel
return false
} else {
return true
}
}
}
func (gui *Gui) getWindowDimensions(informationStr string, appStatus string) map[string]boxlayout.Dimensions {
width, height := gui.g.Size()
@@ -119,6 +141,11 @@ func (gui *Gui) getWindowDimensions(informationStr string, appStatus string) map
sidePanelsDirection = boxlayout.ROW
}
mainPanelsDirection := boxlayout.ROW
if gui.splitMainPanelSideBySide() {
mainPanelsDirection = boxlayout.COLUMN
}
root := &boxlayout.Box{
Direction: boxlayout.ROW,
Children: []*boxlayout.Box{
@@ -132,23 +159,7 @@ func (gui *Gui) getWindowDimensions(informationStr string, appStatus string) map
ConditionalChildren: gui.sidePanelChildren,
},
{
ConditionalDirection: func(width int, height int) int {
mainPanelSplitMode := gui.Config.GetUserConfig().Gui.MainPanelSplitMode
switch mainPanelSplitMode {
case "vertical":
return boxlayout.ROW
case "horizontal":
return boxlayout.COLUMN
default:
if width < 160 && height > 30 { // 2 80 character width panels
return boxlayout.ROW
} else {
return boxlayout.COLUMN
}
}
},
Direction: boxlayout.COLUMN,
Direction: mainPanelsDirection,
Weight: mainSectionWeight,
Children: gui.mainSectionChildren(),
},

View File

@@ -83,6 +83,11 @@ func (gui *Gui) RenderCommitLength() {
// we've just copy+pasted the editor from gocui to here so that we can also re-
// render the commit message length on each keypress
func (gui *Gui) commitMessageEditor(v *gocui.View, key gocui.Key, ch rune, mod gocui.Modifier) {
newlineKey, ok := gui.getKey(gui.Config.GetUserConfig().Keybinding.Universal.AppendNewline).(gocui.Key)
if !ok {
newlineKey = gocui.KeyTab
}
switch {
case key == gocui.KeyBackspace || key == gocui.KeyBackspace2:
v.EditDelete(true)
@@ -96,7 +101,7 @@ func (gui *Gui) commitMessageEditor(v *gocui.View, key gocui.Key, ch rune, mod g
v.MoveCursor(-1, 0, false)
case key == gocui.KeyArrowRight:
v.MoveCursor(1, 0, false)
case key == gocui.KeyTab:
case key == newlineKey:
v.EditNewLine()
case key == gocui.KeySpace:
v.EditWrite(' ')

View File

@@ -591,3 +591,16 @@ func (gui *Gui) handleGotoBottomForCommitsPanel(g *gocui.Gui, v *gocui.View) err
return nil
}
func (gui *Gui) handleCopySelectedCommitMessageToClipboard() error {
commit := gui.getSelectedLocalCommit()
if commit == nil {
return nil
}
message, err := gui.GitCommand.GetCommitMessage(commit.Sha)
if err != nil {
return gui.surfaceError(err)
}
return gui.OSCommand.CopyToClipboard(message)
}

View File

@@ -9,7 +9,7 @@ import (
type credentials chan string
// promptUserForCredential wait for a username or password input from the credentials popup
// promptUserForCredential wait for a username, password or passphrase input from the credentials popup
func (gui *Gui) promptUserForCredential(passOrUname string) string {
gui.credentials = make(chan string)
gui.g.Update(func(g *gocui.Gui) error {
@@ -17,9 +17,12 @@ func (gui *Gui) promptUserForCredential(passOrUname string) string {
if passOrUname == "username" {
credentialsView.Title = gui.Tr.CredentialsUsername
credentialsView.Mask = 0
} else {
} else if passOrUname == "password" {
credentialsView.Title = gui.Tr.CredentialsPassword
credentialsView.Mask = '*'
} else {
credentialsView.Title = gui.Tr.CredentialsPassphrase
credentialsView.Mask = '*'
}
if err := gui.switchContext(gui.Contexts.Credentials.Context); err != nil {
@@ -30,7 +33,7 @@ func (gui *Gui) promptUserForCredential(passOrUname string) string {
return nil
})
// wait for username/passwords input
// wait for username/passwords/passphrase input
userInput := <-gui.credentials
return userInput + "\n"
}
@@ -70,10 +73,10 @@ func (gui *Gui) handleCredentialsViewFocused() error {
func (gui *Gui) handleCredentialsPopup(cmdErr error) {
if cmdErr != nil {
errMessage := cmdErr.Error()
if strings.Contains(errMessage, "Invalid username or password") {
if strings.Contains(errMessage, "Invalid username, password or passphrase") {
errMessage = gui.Tr.PassUnameWrong
}
// we are not logging this error because it may contain a password
// we are not logging this error because it may contain a password or a passphrase
gui.createErrorPanel(errMessage)
} else {
_ = gui.closeConfirmationPrompt(false)

View File

@@ -821,6 +821,13 @@ func (gui *Gui) GetInitialKeybindings() []*Binding {
Handler: gui.wrappedHandler(gui.exitCherryPickingMode),
Description: gui.Tr.LcResetCherryPick,
},
{
ViewName: "commits",
Contexts: []string{BRANCH_COMMITS_CONTEXT_KEY},
Key: gui.getKey(config.Commits.CopyCommitMessageToClipboard),
Handler: gui.wrappedHandler(gui.handleCopySelectedCommitMessageToClipboard),
Description: gui.Tr.LcCopyCommitMessageToClipboard,
},
{
ViewName: "commits",
Contexts: []string{REFLOG_COMMITS_CONTEXT_KEY},
@@ -964,7 +971,7 @@ func (gui *Gui) GetInitialKeybindings() []*Binding {
},
{
ViewName: "commitMessage",
Key: gui.getKey(config.Universal.Confirm),
Key: gui.getKey(config.Universal.SubmitEditorText),
Modifier: gocui.ModNone,
Handler: gui.handleCommitConfirm,
},

View File

@@ -60,9 +60,8 @@ func (gui *Gui) handleDeleteRemoteBranch(g *gocui.Gui, v *gocui.View) error {
prompt: message,
handleConfirm: func() error {
return gui.WithWaitingStatus(gui.Tr.DeletingStatus, func() error {
if err := gui.GitCommand.DeleteRemoteBranch(remoteBranch.RemoteName, remoteBranch.Name); err != nil {
return err
}
err := gui.GitCommand.DeleteRemoteBranch(remoteBranch.RemoteName, remoteBranch.Name, gui.promptUserForCredential)
gui.handleCredentialsPopup(err)
return gui.refreshSidePanels(refreshOptions{scope: []int{BRANCHES, REMOTES}})
})

View File

@@ -166,7 +166,6 @@ func (gui *Gui) handleFetchRemote(g *gocui.Gui, v *gocui.View) error {
gui.Mutexes.FetchMutex.Lock()
defer gui.Mutexes.FetchMutex.Unlock()
// TODO: test this
err := gui.GitCommand.FetchRemote(remote.Name, gui.promptUserForCredential)
gui.handleCredentialsPopup(err)

View File

@@ -98,10 +98,12 @@ func (gui *Gui) handlePushTag(g *gocui.Gui, v *gocui.View) error {
)
return gui.prompt(title, "origin", func(response string) error {
if err := gui.GitCommand.PushTag(response, tag.Name); err != nil {
return gui.surfaceError(err)
}
return nil
return gui.WithWaitingStatus(gui.Tr.PushingTagStatus, func() error {
err := gui.GitCommand.PushTag(response, tag.Name, gui.promptUserForCredential)
gui.handleCredentialsPopup(err)
return nil
})
})
}

View File

@@ -19,6 +19,7 @@ func dutchTranslationSet() TranslationSet {
CommitMessage: "Commit bericht",
CredentialsUsername: "Gebruikersnaam",
CredentialsPassword: "Wachtwoord",
CredentialsPassphrase: "Voer een wachtwoordzin in voor de SSH-sleutel",
PassUnameWrong: "Wachtwoord en/of gebruikersnaam verkeert",
CommitChanges: "Commit veranderingen",
AmendLastCommit: "wijzig laatste commit",
@@ -370,6 +371,7 @@ func dutchTranslationSet() TranslationSet {
LcOpenDiffingMenu: "open diff menu",
LcShowingGitDiff: "laat output zien voor:",
LcCopyCommitShaToClipboard: "copieer commit SHA naar clipboard",
LcCopyCommitMessageToClipboard: "copieer commit bericht naar clipboard",
LcCopyBranchNameToClipboard: "copieer branch name naar clipboard",
LcCopyFileNameToClipboard: "kopieer de bestandsnaam naar het klembord",
LcCopyCommitFileNameToClipboard: "kopieer de vastgelegde bestandsnaam naar het klembord",

View File

@@ -30,6 +30,7 @@ type TranslationSet struct {
CommitMessage string
CredentialsUsername string
CredentialsPassword string
CredentialsPassphrase string
PassUnameWrong string
CommitChanges string
AmendLastCommit string
@@ -380,6 +381,7 @@ type TranslationSet struct {
LcOpenDiffingMenu string
LcShowingGitDiff string
LcCopyCommitShaToClipboard string
LcCopyCommitMessageToClipboard string
LcCopyBranchNameToClipboard string
LcCopyFileNameToClipboard string
LcCopyCommitFileNameToClipboard string
@@ -426,9 +428,17 @@ type TranslationSet struct {
SubCommitsTitle string
SubmodulesTitle string
NavigationTitle string
PushingTagStatus string
}
const englishReleaseNotes = `## lazygit 0.23 Release Notes
const englishReleaseNotes = `## lazygit 0.23.2 Release Notes
- Fixed bug where editing a file with spaces did not work
- Fixed formatting issue with delta that rendered '[0;K' to the screen
- Fixed bug where lazygit failed upon attempting to create a config file in a
read-only filesystem
## lazygit 0.23 Release Notes
Custom Commands:
- You can now create your own custom commands complete with menus and prompts
@@ -519,7 +529,8 @@ func englishTranslationSet() TranslationSet {
CommitMessage: "Commit message",
CredentialsUsername: "Username",
CredentialsPassword: "Password",
PassUnameWrong: "Password and/or username wrong",
CredentialsPassphrase: "Enter passphrase for SSH key",
PassUnameWrong: "Password, passphrase and/or username wrong",
CommitChanges: "commit changes",
AmendLastCommit: "amend last commit",
SureToAmend: "Are you sure you want to amend last commit? Afterwards, you can change commit message from the commits panel.",
@@ -869,6 +880,7 @@ func englishTranslationSet() TranslationSet {
LcOpenDiffingMenu: "open diff menu",
LcShowingGitDiff: "showing output for:",
LcCopyCommitShaToClipboard: "copy commit SHA to clipboard",
LcCopyCommitMessageToClipboard: "copy commit message to clipboard",
LcCopyBranchNameToClipboard: "copy branch name to clipboard",
LcCopyFileNameToClipboard: "copy the file name to the clipboard",
LcCopyCommitFileNameToClipboard: "copy the committed file name to the clipboard",
@@ -915,5 +927,6 @@ func englishTranslationSet() TranslationSet {
SubCommitsTitle: "Sub-commits",
SubmodulesTitle: "Submodules",
NavigationTitle: "List Panel Navigation",
PushingTagStatus: "pushing tag",
}
}

View File

@@ -15,7 +15,8 @@ func polishTranslationSet() TranslationSet {
CommitMessage: "Wiadomość commita",
CredentialsUsername: "Username",
CredentialsPassword: "Password",
PassUnameWrong: "Password and/or username wrong",
CredentialsPassphrase: "Passphrase",
PassUnameWrong: "Password, passphrase and/or username wrong",
CommitChanges: "commituj zmiany",
AmendLastCommit: "zmień ostatnie zatwierdzenie",
SureToAmend: "Czy na pewno chcesz zmienić ostatnie zatwierdzenie? Możesz zmienić komunikat zatwierdzenia z panelu zatwierdzeń.",

View File

@@ -16,6 +16,19 @@ type escapeInterpreter struct {
csiParam []string
curFgColor, curBgColor Attribute
mode OutputMode
instruction instruction
}
const (
NONE = 1 << iota
ERASE_IN_LINE
)
type instruction struct {
kind int
param1 int
param2 int
toWrite []rune
}
type escapeState int
@@ -57,10 +70,11 @@ func (ei *escapeInterpreter) runes() []rune {
// terminal escape sequences.
func newEscapeInterpreter(mode OutputMode) *escapeInterpreter {
ei := &escapeInterpreter{
state: stateNone,
curFgColor: ColorDefault,
curBgColor: ColorDefault,
mode: mode,
state: stateNone,
curFgColor: ColorDefault,
curBgColor: ColorDefault,
mode: mode,
instruction: instruction{kind: NONE},
}
return ei
}
@@ -73,6 +87,10 @@ func (ei *escapeInterpreter) reset() {
ei.csiParam = nil
}
func (ei *escapeInterpreter) instructionRead() {
ei.instruction.kind = NONE
}
// parseOne parses a rune. If isEscape is true, it means that the rune is part
// of an escape sequence, and as such should not be printed verbatim. Otherwise,
// it's not an escape sequence.
@@ -131,6 +149,17 @@ func (ei *escapeInterpreter) parseOne(ch rune) (isEscape bool, err error) {
return false, errCSIParseError
}
ei.state = stateNone
ei.csiParam = nil
return true, nil
case ch == 'K':
p, err := strconv.Atoi(ei.csiParam[0])
if err != nil {
return false, errCSIParseError
}
ei.instruction.kind = ERASE_IN_LINE
ei.instruction.param1 = p
ei.state = stateNone
ei.csiParam = nil
return true, nil

View File

@@ -400,6 +400,15 @@ func (v *View) Write(p []byte) (n int, err error) {
}
default:
cells := v.parseInput(ch)
if v.ei.instruction.kind != NONE {
switch v.ei.instruction.kind {
case ERASE_IN_LINE:
v.eraseInLine()
}
v.ei.instructionRead()
continue
}
if cells == nil {
continue
}
@@ -416,6 +425,31 @@ func (v *View) Write(p []byte) (n int, err error) {
return len(p), nil
}
func (v *View) eraseInLine() {
code := v.ei.instruction.param1
switch code {
case 0:
// need to write till end of the line with cells containing the same bg colour as we currently have.
if len(v.lines) == 0 {
v.lines = append(v.lines, []cell{})
}
nl := len(v.lines)
width, _ := v.Size()
cellCount := width - len(v.lines[nl-1])
c := cell{
fgColor: v.ei.curFgColor,
bgColor: v.ei.curBgColor,
chr: ' ',
}
for i := 0; i < cellCount; i++ {
v.lines[nl-1] = append(v.lines[nl-1], c)
}
default:
// don't recognise sequence. Until we merge the gocui master branch we can't handle going backwards.
}
}
// parseInput parses char by char the input written to the View. It returns nil
// while processing ESC sequences. Otherwise, it returns a cell slice that
// contains the processed data.

2
vendor/modules.txt vendored
View File

@@ -104,7 +104,7 @@ github.com/jesseduffield/go-git/v5/utils/merkletrie/filesystem
github.com/jesseduffield/go-git/v5/utils/merkletrie/index
github.com/jesseduffield/go-git/v5/utils/merkletrie/internal/frame
github.com/jesseduffield/go-git/v5/utils/merkletrie/noder
# github.com/jesseduffield/gocui v0.3.1-0.20201007110350-cc51e317126e
# github.com/jesseduffield/gocui v0.3.1-0.20201010224802-8a6768078fd7
## explicit
github.com/jesseduffield/gocui
# github.com/jesseduffield/termbox-go v0.0.0-20200823212418-a2289ed6aafe