Compare commits

...

28 Commits

Author SHA1 Message Date
Jesse Duffield
31e201ca52 allow configuring side panel width 2020-03-04 00:12:23 +11:00
Jesse Duffield
0abd7ad6be update config 2020-03-04 00:12:23 +11:00
Jesse Duffield
b3522c48d9 refactor 2020-03-04 00:12:23 +11:00
Jesse Duffield
0fc58a7986 fix test 2020-03-04 00:12:23 +11:00
Jesse Duffield
54241d8ab9 more generic way of supporting custom pagers 2020-03-04 00:12:23 +11:00
Jesse Duffield
355f1615ab supporing custom pagers step 1 2020-03-04 00:12:23 +11:00
Jesse Duffield
113252b0ae bump gocui 2020-03-04 00:12:23 +11:00
Jesse Duffield
1cd7d14029 Update README.md 2020-03-04 00:11:32 +11:00
Jesse Duffield
87c2fb6a4a Update Custom_Pagers.md 2020-03-04 00:06:49 +11:00
Jesse Duffield
9912998bb7 Create Custom_Pagers.md 2020-03-03 23:07:12 +11:00
Patrick DeVivo
e223d3d8de Add TODOs badge to README
Closes #685
2020-03-02 22:39:19 +11:00
William Wagner Moraes Artero
ec31fc4cc7 docs: moved services conf docs to config.md 2020-03-01 10:57:12 +11:00
William Wagner Moraes Artero
3ce2b9b79a chore: keeping coverage up :D 2020-03-01 10:57:12 +11:00
William Wagner Moraes Artero
a79182e50d fix: accidentally escaped %s 2020-03-01 10:57:12 +11:00
William Wagner Moraes Artero
6f4c595dde docs: configuration and pull request services' settings 2020-03-01 10:57:12 +11:00
William Wagner Moraes Artero
0eb3090ad6 fix: owner groups (GitLab) 2020-03-01 10:57:12 +11:00
William Wagner Moraes Artero
6ea25bd259 feat: flexible service configuration 2020-03-01 10:57:12 +11:00
William Wagner Moraes Artero
fe5f087f9c feat: configurable services 2020-03-01 10:57:12 +11:00
Jesse Duffield
79299be3b2 better keybindings for patch building mode 2020-02-29 18:48:10 +11:00
Jesse Duffield
4c9b620bd0 better keybindings for staging by line 2020-02-29 18:48:10 +11:00
Jesse Duffield
a7508a5dfd fix cheatsheet script to support different contexts 2020-02-29 17:46:00 +11:00
hitsuji no shippo
1a3d765c4c fix keybinds document 2020-02-28 23:08:14 +11:00
Dawid Dziurla
4058c71ca0 Merge pull request #684 from ueberBrot/add-scoop-install-option
Add scoop install option to README.
2020-02-27 18:31:21 +01:00
Maurice de Bruyn
3fc22a6010 Add scoop install option to README.
Adds the install option scoop on Windows to the README.
2020-02-27 18:12:23 +01:00
David Chen
a9fe0b8000 set --abbrev-commit to return 8-digit hash strings 2020-02-27 18:05:41 +11:00
David Chen
5af7b0235e fix #680: unpushed commits still appear to be green instead of red 2020-02-27 18:05:41 +11:00
Corentin Rossignon
bf946200e9 Fix OutOfBound array access when looking for ReflogCommits
refs #679
2020-02-27 09:34:40 +11:00
Jesse Duffield
890cc87724 fix bug where commits appeared as green despite not being pushed 2020-02-27 09:33:09 +11:00
33 changed files with 996 additions and 386 deletions

View File

@@ -1,8 +1,8 @@
# lazygit [![CircleCI](https://circleci.com/gh/jesseduffield/lazygit.svg?style=svg)](https://circleci.com/gh/jesseduffield/lazygit) [![codecov](https://codecov.io/gh/jesseduffield/lazygit/branch/master/graph/badge.svg)](https://codecov.io/gh/jesseduffield/lazygit) [![Go Report Card](https://goreportcard.com/badge/github.com/jesseduffield/lazygit)](https://goreportcard.com/report/github.com/jesseduffield/lazygit) [![GolangCI](https://golangci.com/badges/github.com/jesseduffield/lazygit.svg)](https://golangci.com) [![GoDoc](https://godoc.org/github.com/jesseduffield/lazygit?status.svg)](http://godoc.org/github.com/jesseduffield/lazygit) [![GitHub tag](https://img.shields.io/github/tag/jesseduffield/lazygit.svg)]()
# lazygit [![CircleCI](https://circleci.com/gh/jesseduffield/lazygit.svg?style=svg)](https://circleci.com/gh/jesseduffield/lazygit) [![codecov](https://codecov.io/gh/jesseduffield/lazygit/branch/master/graph/badge.svg)](https://codecov.io/gh/jesseduffield/lazygit) [![Go Report Card](https://goreportcard.com/badge/github.com/jesseduffield/lazygit)](https://goreportcard.com/report/github.com/jesseduffield/lazygit) [![GolangCI](https://golangci.com/badges/github.com/jesseduffield/lazygit.svg)](https://golangci.com) [![GoDoc](https://godoc.org/github.com/jesseduffield/lazygit?status.svg)](http://godoc.org/github.com/jesseduffield/lazygit) [![GitHub tag](https://img.shields.io/github/tag/jesseduffield/lazygit.svg)]() [![TODOs](https://badgen.net/https/api.tickgit.com/badgen/github.com/jesseduffield/lazygit)](https://www.tickgit.com/browse?repo=github.com/jesseduffield/lazygit)
A simple terminal UI for git commands, written in Go with the [gocui](https://github.com/jroimartin/gocui 'gocui') library.
Rant time: You've heard it before, git is _powerful_, but what good is that power when everything is so damn hard to do? Interactive rebasing requires you to edit a goddamn TODO file in your editor? *Are you kidding me?* To stage part of a file you need to use a command line program stepping through each hunk and if a hunk can't be split down any further but contains code you don't want to stage, bad luck? *Are you KIDDING me?!* Sometimes you get asked to stash your changes when switching branches only to realise that after you switch and unstash that there weren't even any conflicts and it would have been fine to just checkout the branch directly? *YOU HAVE GOT TO BE KIDDING ME!*
Rant time: You've heard it before, git is _powerful_, but what good is that power when everything is so damn hard to do? Interactive rebasing requires you to edit a goddamn TODO file in your editor? *Are you kidding me?* To stage part of a file you need to use a command line program stepping through each hunk and if a hunk can't be split down any further but contains code you don't want to stage, bad luck? *Are you KIDDING me?!* Sometimes you get asked to stash your changes when switching branches only to realise that after you switch and unstash that there weren't even any conflicts and it would have been fine to just checkout the branch directly? *YOU HAVE GOT TO BE KIDDING ME!*
If you're a mere mortal like me and you're tired of hearing how powerful git is when in your daily life it's a powerful pain in your ass, lazygit might be for you.
@@ -24,9 +24,11 @@ Github Sponsors is matching all donations dollar-for-dollar for 12 months so if
## Installation
### Homebrew
Normally the lazygit formula can be found in the Homebrew core but we suggest you tap our formula to get the frequently updated one. It works with Linux, too.
Tap:
```
brew install jesseduffield/lazygit/lazygit
```
@@ -38,8 +40,10 @@ brew install lazygit
```
### MacPorts
Latest version built from github releases.
Tap:
```
sudo port install lazygit
```
@@ -63,6 +67,17 @@ They follow upstream latest releases
```sh
sudo xbps-install -S lazygit
```
### Scoop (Windows)
You can install `lazygit` using [scoop](https://scoop.sh/). It's in the `extras` bucket:
```sh
# Add the extras bucket
scoop bucket add extras
# Install lazygit
scoop install lazygit
```
### Arch Linux
@@ -71,11 +86,11 @@ Packages for Arch Linux are available via AUR (Arch User Repository).
There are two packages. The stable one which is built with the latest release
and the git version which builds from the most recent commit.
- Stable: https://aur.archlinux.org/packages/lazygit/
- Development: https://aur.archlinux.org/packages/lazygit-git/
- Stable: <https://aur.archlinux.org/packages/lazygit/>
- Development: <https://aur.archlinux.org/packages/lazygit-git/>
Instruction of how to install AUR content can be found here:
https://wiki.archlinux.org/index.php/Arch_User_Repository
<https://wiki.archlinux.org/index.php/Arch_User_Repository>
### Fedora and CentOS 7
@@ -88,7 +103,7 @@ sudo dnf install lazygit
### Conda
Released versions are available for different platforms, see https://anaconda.org/conda-forge/lazygit
Released versions are available for different platforms, see <https://anaconda.org/conda-forge/lazygit>
```sh
conda install -c conda-forge lazygit
@@ -120,10 +135,11 @@ whichever rc file you're using).
- Rebase Magic tutorial [here](https://youtu.be/4XaToVut_hs)
- List of keybindings
[here](/docs/keybindings).
## Changing Directory On Exit
If you change repos in lazygit and want your shell to change directory into that repo on exiting lazygit, add this to your `~/.zshrc` (or other rc file):
```
lg()
{
@@ -137,8 +153,17 @@ lg()
fi
}
```
Then `source ~/.zshrc` and from now on when you call `lg` and exit you'll switch directories to whatever you were in inside lazyigt. To override this behaviour you can exit using `shift+Q` rather than just `q`.
## Configuration
Check the [configuration docs](docs/Config.md).
## Custom Pagers
See the [docs](docs/Custom_Pagers.md)
## Cool features
- Adding files easily

View File

@@ -1,17 +1,18 @@
# User Config:
# User Config
Default path for the config file:
* Linux: `~/.config/jesseduffield/lazygit/config.yml`
* MacOS: `~/Library/Application Support/jesseduffield/lazygit/config.yml`
## Default:
## Default
```yaml
gui:
# stuff relating to the UI
scrollHeight: 2 # how many lines you scroll by
scrollPastBottom: true # enable scrolling past the bottom
sidePanelWidth: 0.3333 # number from 0 to 1
theme:
lightTheme: false # For terminals with a light background
activeBorderColor:
@@ -28,6 +29,9 @@ Default path for the config file:
mouseEvents: true
skipUnstageLineWarning: false
git:
paging:
colorArg: always
useConfig: false
merging:
# only applicable to unix users
manualCommit: false
@@ -136,30 +140,30 @@ Default path for the config file:
undo: 'z'
```
## Platform Defaults:
## Platform Defaults
### Windows:
### Windows
```yaml
os:
openCommand: 'cmd /c "start "" {{filename}}"'
```
### Linux:
### Linux
```yaml
os:
openCommand: 'sh -c "xdg-open {{filename}} >/dev/null"'
```
### OSX:
### OSX
```yaml
os:
openCommand: 'open {{filename}}'
```
### Recommended Config Values:
### Recommended Config Values
for users of VSCode
@@ -168,7 +172,7 @@ for users of VSCode
openCommand: 'code -r {{filename}}'
```
## Color Attributes:
## Color Attributes
For color attributes you can choose an array of attributes (with max one color attribute)
The available attributes are:
@@ -186,7 +190,7 @@ The available attributes are:
- reverse # useful for high-contrast
- underline
## Light terminal theme:
## Light terminal theme
If you have issues with a light terminal theme where you can't read / see the text add these settings
@@ -203,15 +207,16 @@ If you have issues with a light terminal theme where you can't read / see the te
- blue
```
## Example Coloring:
## Example Coloring
![border example](/docs/resources/colored-border-example.png)
## Keybindings:
## Keybindings
For all possible keybinding options, check [Custom_Keybinding.md](https://github.com/jesseduffield/lazygit/blob/master/docs/keybindings/Custom_Keybinding.md)
### Example Keybindings For Colemak Users
#### Example Keybindings For Colemak Users:
```yaml
keybinding:
universal:
@@ -238,3 +243,19 @@ For all possible keybinding options, check [Custom_Keybinding.md](https://github
viewGitFlowOptions: 'I'
```
## Custom pull request URLs
Some git provider setups (e.g. on-premises GitLab) can have distinct URLs for git-related calls and
the web interface/API itself. To work with those, Lazygit needs to know where it needs to create
the pull request. You can do so on your `config.yml` file using the following syntax:
```yaml
services:
"<gitDomain>": "<provider>:<webDomain>"
```
Where:
- `gitDomain` stands for the domain used by git itself (i.e. the one present on clone URLs), e.g. `git.work.com`
- `provider` is one of `github`, `bitbucket` or `gitlab`
- `webDomain` is the URL where your git service exposes a web interface and APIs, e.g. `gitservice.work.com`

64
docs/Custom_Pagers.md Normal file
View File

@@ -0,0 +1,64 @@
# Custom Pagers
Lazygit supports custom pagers, [configured](/docs/Config.md) in the config.yml file (which can be opened by pressing 'o' in the Status panel).
Support does not extend to windows users, because we're making use of a package which doesn't have windows support.
## Default:
```yaml
git:
paging:
colorArg: always
useConfig: false
```
the `colorArg` key is for whether you want the `--color=always` arg in your `git diff` command. Some pagers want it set to always, others want it set to 'never'.
## Delta:
```yaml
git:
paging:
colorArg: always
pager: delta --dark --paging=never --24-bit-color=never
```
![](https://i.imgur.com/QJpQkF3.png)
## Diff-so-fancy
```yaml
git:
paging:
colorArg: always
pager: diff-so-fancy
```
![](https://i.imgur.com/rjH1TpT.png)
## ydiff
```yaml
gui:
sidePanelWidth: 0.2 # gives you more space to show things side-by-side
git:
paging:
colorArg: never
pager: ydiff -p cat -s --wrap --width={{columnWidth}}
```
![](https://i.imgur.com/vaa8z0H.png)
Be careful with this one, I think the homebrew and pip versions are behind master. I needed to directly download the ydiff script to get the no-pager functionality working.
## Using git config
```yaml
git:
paging:
colorArg: always
useConfig: true
```
If you set `useConfig: true`, lazygit will use whatever pager is specified in $GIT_PAGER, $PAGER, or your git config. If the pager ends with something like ' | less' we will strip that part out, because less doesn't play nice with our rendering approach. If the custom pager uses less under the hood, that will also break rendering (hence the `--paging=never` flag for the `delta` pager).

View File

@@ -1,47 +1,21 @@
# Lazygit menu
# Lazygit Keybindings
## Global
## Global Keybindings
<pre>
<kbd>pgup</kbd>: scroll up main panel (fn+up)
<kbd>pgdown</kbd>: scroll down main panel (fn+down)
<kbd>m</kbd>: view merge/rebase options
<kbd>ctrl+p</kbd>: view custom patch options
<kbd>P</kbd>: push
<kbd>p</kbd>: pull
<kbd>R</kbd>: refresh
<kbd>+</kbd>: next screen mode (normal/half/fullscreen)
<kbd>_</kbd>: prev screen mode
<kbd>:</kbd>: execute custom command
</pre>
## Status
<pre>
<kbd>e</kbd>: edit config file
<kbd>o</kbd>: open config file
<kbd>u</kbd>: check for update
<kbd>s</kbd>: switch to a recent repo
</pre>
## Files
<pre>
<kbd>c</kbd>: commit changes
<kbd>w</kbd>: commit changes without pre-commit hook
<kbd>A</kbd>: amend last commit
<kbd>C</kbd>: commit changes using git editor
<kbd>space</kbd>: toggle staged
<kbd>d</kbd>: view 'discard changes' options
<kbd>e</kbd>: edit file
<kbd>o</kbd>: open file
<kbd>i</kbd>: add to .gitignore
<kbd>r</kbd>: refresh files
<kbd>S</kbd>: stash files
<kbd>a</kbd>: stage/unstage all
<kbd>t</kbd>: add patch
<kbd>D</kbd>: view reset options
<kbd>enter</kbd>: stage individual hunks/lines
<kbd>f</kbd>: fetch
<kbd>X</kbd>: execute custom command
</pre>
## Branches
## Branches Panel (Branches Tab)
<pre>
<kbd>space</kbd>: checkout
@@ -50,12 +24,56 @@
<kbd>F</kbd>: force checkout
<kbd>n</kbd>: new branch
<kbd>d</kbd>: delete branch
<kbd>r</kbd>: rebase branch
<kbd>r</kbd>: rebase checked-out branch onto this branch
<kbd>M</kbd>: merge into currently checked out branch
<kbd>i</kbd>: show git-flow options
<kbd>f</kbd>: fast-forward this branch from its upstream
<kbd>g</kbd>: view reset options
</pre>
## Commits
## Branches Panel (Remote Branches (in Remotes tab))
<pre>
<kbd>esc</kbd>: return to remotes list
<kbd>g</kbd>: view reset options
<kbd>space</kbd>: checkout
<kbd>M</kbd>: merge into currently checked out branch
<kbd>d</kbd>: delete branch
<kbd>r</kbd>: rebase checked-out branch onto this branch
<kbd>u</kbd>: set as upstream of checked-out branch
</pre>
## Branches Panel (Remotes Tab)
<pre>
<kbd>f</kbd>: fetch remote
<kbd>n</kbd>: add new remote
<kbd>d</kbd>: remove remote
<kbd>e</kbd>: edit remote
</pre>
## Branches Panel (Tags Tab)
<pre>
<kbd>space</kbd>: checkout
<kbd>d</kbd>: delete tag
<kbd>P</kbd>: push tag
<kbd>n</kbd>: create tag
<kbd>g</kbd>: view reset options
</pre>
## Commit Files Panel
<pre>
<kbd>esc</kbd>: go back
<kbd>c</kbd>: checkout file
<kbd>d</kbd>: discard this commit's changes to this file
<kbd>o</kbd>: open file
<kbd>space</kbd>: toggle file included in patch
<kbd>enter</kbd>: enter file to add selected lines to the patch
</pre>
## Commits Panel (Commits Tab)
<pre>
<kbd>s</kbd>: squash down
@@ -76,46 +94,41 @@
<kbd>C</kbd>: copy commit range (cherry-pick)
<kbd>v</kbd>: paste commits (cherry-pick)
<kbd>enter</kbd>: view commit's files
<kbd>space</kbd>: select commit to diff with another commit
<kbd>space</kbd>: checkout commit
<kbd>i</kbd>: select commit to diff with another commit
<kbd>T</kbd>: tag commit
</pre>
## Stash
## Commits Panel (Reflog Tab)
<pre>
<kbd>space</kbd>: apply
<kbd>g</kbd>: pop
<kbd>d</kbd>: drop
<kbd>space</kbd>: checkout commit
<kbd>g</kbd>: view reset options
</pre>
## Commit files
## Files Panel
<pre>
<kbd>esc</kbd>: go back
<kbd>c</kbd>: checkout file
<kbd>d</kbd>: discard this commit's changes to this file
<kbd>c</kbd>: commit changes
<kbd>w</kbd>: commit changes without pre-commit hook
<kbd>A</kbd>: amend last commit
<kbd>C</kbd>: commit changes using git editor
<kbd>space</kbd>: toggle staged
<kbd>d</kbd>: view 'discard changes' options
<kbd>e</kbd>: edit file
<kbd>o</kbd>: open file
<kbd>i</kbd>: add to .gitignore
<kbd>r</kbd>: refresh files
<kbd>s</kbd>: stash changes
<kbd>S</kbd>: view stash options
<kbd>a</kbd>: stage/unstage all
<kbd>D</kbd>: view reset options
<kbd>enter</kbd>: stage individual hunks/lines
<kbd>f</kbd>: fetch
<kbd>g</kbd>: view upstream reset options
</pre>
## Main (Normal)
<pre>
<kbd>PgDn</kbd>: scroll down (fn+up)
<kbd>PgUp</kbd>: scroll up (fn+down)
</pre>
## Main (Staging)
<pre>
<kbd>esc</kbd>: return to files panel
<kbd>▲</kbd>: select previous line
<kbd>▼</kbd>: select next line
<kbd>◄</kbd>: select previous hunk
<kbd>►</kbd>: select next hunk
<kbd>space</kbd>: stage line
<kbd>a</kbd>: stage hunk
</pre>
## Main (Merging)
## Main Panel (Merging)
<pre>
<kbd>esc</kbd>: return to files panel
@@ -127,3 +140,63 @@
<kbd>▼</kbd>: select bottom hunk
<kbd>z</kbd>: undo
</pre>
## Main Panel (Normal)
<pre>
<kbd> ̄</kbd>: scroll down (fn+up)
<kbd>¦</kbd>: scroll up (fn+down)
</pre>
## Main Panel (Patch Building)
<pre>
<kbd>esc</kbd>: exit line-by-line mode
<kbd>▲</kbd>: select previous line
<kbd>▼</kbd>: select next line
<kbd>◄</kbd>: select previous hunk
<kbd>►</kbd>: select next hunk
<kbd>space</kbd>: stage selection
<kbd>d</kbd>: reset selection
<kbd>v</kbd>: toggle drag select
<kbd>V</kbd>: toggle drag select
<kbd>a</kbd>: toggle select hunk
</pre>
## Main Panel (Staging)
<pre>
<kbd>esc</kbd>: return to files panel
<kbd>space</kbd>: stage selection
<kbd>d</kbd>: reset selection
<kbd>tab</kbd>: switch to other panel
<kbd>▲</kbd>: select previous line
<kbd>▼</kbd>: select next line
<kbd>◄</kbd>: select previous hunk
<kbd>►</kbd>: select next hunk
<kbd>e</kbd>: edit file
<kbd>o</kbd>: open file
<kbd>v</kbd>: toggle drag select
<kbd>V</kbd>: toggle drag select
<kbd>a</kbd>: toggle select hunk
<kbd>c</kbd>: commit changes
<kbd>w</kbd>: commit changes without pre-commit hook
<kbd>C</kbd>: commit changes using git editor
</pre>
## Stash Panel
<pre>
<kbd>space</kbd>: apply
<kbd>g</kbd>: pop
<kbd>d</kbd>: drop
</pre>
## Status Panel
<pre>
<kbd>e</kbd>: edit config file
<kbd>o</kbd>: open config file
<kbd>u</kbd>: check for update
<kbd>enter</kbd>: switch to a recent repo
</pre>

View File

@@ -1,46 +1,21 @@
# Lazygit menu
# Lazygit Keybindings
## Global
<pre>
<kbd>pgup</kbd>: scroll up main panel (fn+up)
<kbd>pgdown</kbd>: scroll down main panel (fn+down)
<kbd>m</kbd>: bekijk merge/rebase opties
<kbd>ctrl+p</kbd>: view custom patch options
<kbd>P</kbd>: push
<kbd>p</kbd>: pull
<kbd>R</kbd>: verversen
<kbd>+</kbd>: next screen mode (normal/half/fullscreen)
<kbd>_</kbd>: prev screen mode
<kbd>:</kbd>: voor aangepast commando uit
</pre>
## Status
<pre>
<kbd>e</kbd>: verander config file
<kbd>o</kbd>: open config file
<kbd>u</kbd>: check voor updates
<kbd>s</kbd>: wissel naar een recente repo
</pre>
## Bestanden
<pre>
<kbd>c</kbd>: Commit veranderingen
<kbd>w</kbd>: commit veranderingen zonder pre-commit hook
<kbd>A</kbd>: wijzig laatste commit
<kbd>C</kbd>: commit veranderingen met de git editor
<kbd>space</kbd>: toggle staged
<kbd>d</kbd>: bekijk 'veranderingen ongedaan maken' opties
<kbd>e</kbd>: verander bestand
<kbd>o</kbd>: open bestand
<kbd>i</kbd>: voeg toe aan .gitignore
<kbd>r</kbd>: refresh bestanden
<kbd>S</kbd>: stash-bestanden
<kbd>a</kbd>: toggle staged alle
<kbd>t</kbd>: bewerkingen toevoegen
<kbd>D</kbd>: bekijk reset opties
<kbd>enter</kbd>: stage individuele hunks/lijnen
<kbd>f</kbd>: fetch
<kbd>X</kbd>: voor aangepast commando uit
</pre>
## Branches
## Branches Panel (Branches Tab)
<pre>
<kbd>space</kbd>: uitchecken
@@ -51,10 +26,54 @@
<kbd>d</kbd>: verwijder branch
<kbd>r</kbd>: rebase branch
<kbd>M</kbd>: merge in met huidige checked out branch
<kbd>i</kbd>: show git-flow options
<kbd>f</kbd>: fast-forward this branch from its upstream
<kbd>g</kbd>: bekijk reset opties
</pre>
## Commits
## Branches Panel (Remote Branches (in Remotes tab))
<pre>
<kbd>esc</kbd>: return to remotes list
<kbd>g</kbd>: bekijk reset opties
<kbd>space</kbd>: uitchecken
<kbd>M</kbd>: merge in met huidige checked out branch
<kbd>d</kbd>: verwijder branch
<kbd>r</kbd>: rebase branch
<kbd>u</kbd>: set as upstream of checked-out branch
</pre>
## Branches Panel (Remotes Tab)
<pre>
<kbd>f</kbd>: fetch remote
<kbd>n</kbd>: add new remote
<kbd>d</kbd>: remove remote
<kbd>e</kbd>: edit remote
</pre>
## Branches Panel (Tags Tab)
<pre>
<kbd>space</kbd>: uitchecken
<kbd>d</kbd>: delete tag
<kbd>P</kbd>: push tag
<kbd>n</kbd>: create tag
<kbd>g</kbd>: bekijk reset opties
</pre>
## Commit bestanden Panel
<pre>
<kbd>esc</kbd>: ga terug
<kbd>c</kbd>: bestand uitchecken
<kbd>d</kbd>: uitsluit deze commit zijn veranderingen aan dit bestand
<kbd>o</kbd>: open bestand
<kbd>space</kbd>: toggle file included in patch
<kbd>enter</kbd>: enter file to add selected lines to the patch
</pre>
## Commits Panel (Commits Tab)
<pre>
<kbd>s</kbd>: squash beneden
@@ -75,39 +94,41 @@
<kbd>C</kbd>: kopiëer commit reeks (cherry-pick)
<kbd>v</kbd>: plak commits (cherry-pick)
<kbd>enter</kbd>: bekijk gecommite bestanden
<kbd>space</kbd>: select commit to diff with another commit
<kbd>space</kbd>: checkout commit
<kbd>i</kbd>: select commit to diff with another commit
<kbd>T</kbd>: tag commit
</pre>
## Stash
## Commits Panel (Reflog Tab)
<pre>
<kbd>space</kbd>: toepassen
<kbd>g</kbd>: pop
<kbd>d</kbd>: drop
<kbd>space</kbd>: checkout commit
<kbd>g</kbd>: bekijk reset opties
</pre>
## Commit bestanden
## Bestanden Panel
<pre>
<kbd>esc</kbd>: ga terug
<kbd>c</kbd>: bestand uitchecken
<kbd>d</kbd>: uitsluit deze commit zijn veranderingen aan dit bestand
<kbd>c</kbd>: Commit veranderingen
<kbd>w</kbd>: commit veranderingen zonder pre-commit hook
<kbd>A</kbd>: wijzig laatste commit
<kbd>C</kbd>: commit veranderingen met de git editor
<kbd>space</kbd>: toggle staged
<kbd>d</kbd>: bekijk 'veranderingen ongedaan maken' opties
<kbd>e</kbd>: verander bestand
<kbd>o</kbd>: open bestand
<kbd>i</kbd>: voeg toe aan .gitignore
<kbd>r</kbd>: refresh bestanden
<kbd>s</kbd>: stash-bestanden
<kbd>S</kbd>: view stash options
<kbd>a</kbd>: toggle staged alle
<kbd>D</kbd>: bekijk reset opties
<kbd>enter</kbd>: stage individuele hunks/lijnen
<kbd>f</kbd>: fetch
<kbd>g</kbd>: view upstream reset options
</pre>
## Hoofd (Stage Lines/Hunks)
<pre>
<kbd>esc</kbd>: ga terug naar het bestanden paneel
<kbd>▲</kbd>: selecteer de vorige lijn
<kbd>▼</kbd>: selecteer de volgende lijn
<kbd>◄</kbd>: selecteer de vorige hunk
<kbd>►</kbd>: selecteer de volgende hunk
<kbd>space</kbd>: stage lijn
<kbd>a</kbd>: stage hunk
</pre>
## Hoofd (Merging)
## Hoofd Panel (Merging)
<pre>
<kbd>esc</kbd>: ga terug naar het bestanden paneel
@@ -120,9 +141,62 @@
<kbd>z</kbd>: ongedaan maken
</pre>
## Hoofd (Normaal)
## Hoofd Panel (Normaal)
<pre>
<kbd>PgDn</kbd>: scroll omlaag (fn+up)
<kbd>PgUp</kbd>: scroll omhoog (fn+down)
<kbd></kbd>: scroll omlaag (fn+up)
<kbd></kbd>: scroll omhoog (fn+down)
</pre>
## Hoofd Panel (Patch Building)
<pre>
<kbd>esc</kbd>: exit line-by-line mode
<kbd>▲</kbd>: selecteer de vorige lijn
<kbd>▼</kbd>: selecteer de volgende lijn
<kbd>◄</kbd>: selecteer de vorige hunk
<kbd>►</kbd>: selecteer de volgende hunk
<kbd>space</kbd>: stage selection
<kbd>d</kbd>: reset selection
<kbd>v</kbd>: toggle drag select
<kbd>V</kbd>: toggle drag select
<kbd>a</kbd>: toggle select hunk
</pre>
## Hoofd Panel (Stage Lines/Hunks)
<pre>
<kbd>esc</kbd>: ga terug naar het bestanden paneel
<kbd>space</kbd>: stage selection
<kbd>d</kbd>: reset selection
<kbd>tab</kbd>: switch to other panel
<kbd>▲</kbd>: selecteer de vorige lijn
<kbd>▼</kbd>: selecteer de volgende lijn
<kbd>◄</kbd>: selecteer de vorige hunk
<kbd>►</kbd>: selecteer de volgende hunk
<kbd>e</kbd>: verander bestand
<kbd>o</kbd>: open bestand
<kbd>v</kbd>: toggle drag select
<kbd>V</kbd>: toggle drag select
<kbd>a</kbd>: toggle select hunk
<kbd>c</kbd>: Commit veranderingen
<kbd>w</kbd>: commit veranderingen zonder pre-commit hook
<kbd>C</kbd>: commit veranderingen met de git editor
</pre>
## Stash Panel
<pre>
<kbd>space</kbd>: toepassen
<kbd>g</kbd>: pop
<kbd>d</kbd>: drop
</pre>
## Status Panel
<pre>
<kbd>e</kbd>: verander config file
<kbd>o</kbd>: open config file
<kbd>u</kbd>: check voor updates
<kbd>enter</kbd>: wissel naar een recente repo
</pre>

View File

@@ -1,46 +1,21 @@
# Lazygit menu
# Lazygit Keybindings
## Globalne
<pre>
<kbd>pgup</kbd>: scroll up main panel (fn+up)
<kbd>pgdown</kbd>: scroll down main panel (fn+down)
<kbd>m</kbd>: view merge/rebase options
<kbd>ctrl+p</kbd>: view custom patch options
<kbd>P</kbd>: push
<kbd>p</kbd>: pull
<kbd>R</kbd>: odśwież
<kbd>+</kbd>: next screen mode (normal/half/fullscreen)
<kbd>_</kbd>: prev screen mode
<kbd>:</kbd>: execute custom command
</pre>
## Status
<pre>
<kbd>e</kbd>: edytuj plik konfiguracyjny
<kbd>o</kbd>: otwórz plik konfiguracyjny
<kbd>u</kbd>: sprawdź aktualizacje
<kbd>s</kbd>: switch to a recent repo
</pre>
## Pliki
<pre>
<kbd>c</kbd>: commituj zmiany
<kbd>w</kbd>: commit changes without pre-commit hook
<kbd>A</kbd>: zmień ostatnie zatwierdzenie
<kbd>C</kbd>: commituj zmiany używając edytora z gita
<kbd>space</kbd>: przełącz zatwierdzenie
<kbd>d</kbd>: view 'discard changes' options
<kbd>e</kbd>: edytuj plik
<kbd>o</kbd>: otwórz plik
<kbd>i</kbd>: dodaj do .gitignore
<kbd>r</kbd>: odśwież pliki
<kbd>S</kbd>: przechowaj pliki
<kbd>a</kbd>: przełącz wszystkie zatwierdzenia
<kbd>t</kbd>: dodaj łatkę
<kbd>D</kbd>: view reset options
<kbd>enter</kbd>: zatwierdź pojedyncze linie
<kbd>f</kbd>: fetch
<kbd>X</kbd>: execute custom command
</pre>
## Gałęzie
## Gałęzie Panel (Branches Tab)
<pre>
<kbd>space</kbd>: przełącz
@@ -51,10 +26,54 @@
<kbd>d</kbd>: usuń gałąź
<kbd>r</kbd>: rebase branch
<kbd>M</kbd>: scal do obecnej gałęzi
<kbd>i</kbd>: show git-flow options
<kbd>f</kbd>: fast-forward this branch from its upstream
<kbd>g</kbd>: view reset options
</pre>
## Commity
## Gałęzie Panel (Remote Branches (in Remotes tab))
<pre>
<kbd>esc</kbd>: return to remotes list
<kbd>g</kbd>: view reset options
<kbd>space</kbd>: przełącz
<kbd>M</kbd>: scal do obecnej gałęzi
<kbd>d</kbd>: usuń gałąź
<kbd>r</kbd>: rebase branch
<kbd>u</kbd>: set as upstream of checked-out branch
</pre>
## Gałęzie Panel (Remotes Tab)
<pre>
<kbd>f</kbd>: fetch remote
<kbd>n</kbd>: add new remote
<kbd>d</kbd>: remove remote
<kbd>e</kbd>: edit remote
</pre>
## Gałęzie Panel (Tags Tab)
<pre>
<kbd>space</kbd>: przełącz
<kbd>d</kbd>: delete tag
<kbd>P</kbd>: push tag
<kbd>n</kbd>: create tag
<kbd>g</kbd>: view reset options
</pre>
## Commit files Panel
<pre>
<kbd>esc</kbd>: go back
<kbd>c</kbd>: checkout file
<kbd>d</kbd>: discard this commit's changes to this file
<kbd>o</kbd>: otwórz plik
<kbd>space</kbd>: toggle file included in patch
<kbd>enter</kbd>: enter file to add selected lines to the patch
</pre>
## Commity Panel (Commits Tab)
<pre>
<kbd>s</kbd>: ściśnij w dół
@@ -75,46 +94,41 @@
<kbd>C</kbd>: copy commit range (cherry-pick)
<kbd>v</kbd>: paste commits (cherry-pick)
<kbd>enter</kbd>: view commit's files
<kbd>space</kbd>: select commit to diff with another commit
<kbd>space</kbd>: checkout commit
<kbd>i</kbd>: select commit to diff with another commit
<kbd>T</kbd>: tag commit
</pre>
## Schowek
## Commity Panel (Reflog Tab)
<pre>
<kbd>space</kbd>: zastosuj
<kbd>g</kbd>: wyciągnij
<kbd>d</kbd>: porzuć
<kbd>space</kbd>: checkout commit
<kbd>g</kbd>: view reset options
</pre>
## Commit files
## Pliki Panel
<pre>
<kbd>esc</kbd>: go back
<kbd>c</kbd>: checkout file
<kbd>d</kbd>: discard this commit's changes to this file
<kbd>c</kbd>: commituj zmiany
<kbd>w</kbd>: commit changes without pre-commit hook
<kbd>A</kbd>: zmień ostatnie zatwierdzenie
<kbd>C</kbd>: commituj zmiany używając edytora z gita
<kbd>space</kbd>: przełącz zatwierdzenie
<kbd>d</kbd>: view 'discard changes' options
<kbd>e</kbd>: edytuj plik
<kbd>o</kbd>: otwórz plik
<kbd>i</kbd>: dodaj do .gitignore
<kbd>r</kbd>: odśwież pliki
<kbd>s</kbd>: przechowaj pliki
<kbd>S</kbd>: view stash options
<kbd>a</kbd>: przełącz wszystkie zatwierdzenia
<kbd>D</kbd>: view reset options
<kbd>enter</kbd>: zatwierdź pojedyncze linie
<kbd>f</kbd>: fetch
<kbd>g</kbd>: view upstream reset options
</pre>
## Main (Normal)
<pre>
<kbd>PgDn</kbd>: scroll down (fn+up)
<kbd>PgUp</kbd>: scroll up (fn+down)
</pre>
## Main (Zatwierdzanie)
<pre>
<kbd>esc</kbd>: wróć do panelu plików
<kbd>▲</kbd>: select previous line
<kbd>▼</kbd>: select next line
<kbd>◄</kbd>: select previous hunk
<kbd>►</kbd>: select next hunk
<kbd>space</kbd>: zatwierdź linię
<kbd>a</kbd>: zatwierdź kawałek
</pre>
## Main (Merging)
## Main Panel (Merging)
<pre>
<kbd>esc</kbd>: wróć do panelu plików
@@ -126,3 +140,63 @@
<kbd>▼</kbd>: select bottom hunk
<kbd>z</kbd>: undo
</pre>
## Main Panel (Normal)
<pre>
<kbd> ̄</kbd>: scroll down (fn+up)
<kbd>¦</kbd>: scroll up (fn+down)
</pre>
## Main Panel (Patch Building)
<pre>
<kbd>esc</kbd>: exit line-by-line mode
<kbd>▲</kbd>: select previous line
<kbd>▼</kbd>: select next line
<kbd>◄</kbd>: select previous hunk
<kbd>►</kbd>: select next hunk
<kbd>space</kbd>: stage selection
<kbd>d</kbd>: reset selection
<kbd>v</kbd>: toggle drag select
<kbd>V</kbd>: toggle drag select
<kbd>a</kbd>: toggle select hunk
</pre>
## Main Panel (Zatwierdzanie)
<pre>
<kbd>esc</kbd>: wróć do panelu plików
<kbd>space</kbd>: stage selection
<kbd>d</kbd>: reset selection
<kbd>tab</kbd>: switch to other panel
<kbd>▲</kbd>: select previous line
<kbd>▼</kbd>: select next line
<kbd>◄</kbd>: select previous hunk
<kbd>►</kbd>: select next hunk
<kbd>e</kbd>: edytuj plik
<kbd>o</kbd>: otwórz plik
<kbd>v</kbd>: toggle drag select
<kbd>V</kbd>: toggle drag select
<kbd>a</kbd>: toggle select hunk
<kbd>c</kbd>: commituj zmiany
<kbd>w</kbd>: commit changes without pre-commit hook
<kbd>C</kbd>: commituj zmiany używając edytora z gita
</pre>
## Schowek Panel
<pre>
<kbd>space</kbd>: zastosuj
<kbd>g</kbd>: wyciągnij
<kbd>d</kbd>: porzuć
</pre>
## Status Panel
<pre>
<kbd>e</kbd>: edytuj plik konfiguracyjny
<kbd>o</kbd>: otwórz plik konfiguracyjny
<kbd>u</kbd>: sprawdź aktualizacje
<kbd>enter</kbd>: switch to a recent repo
</pre>

3
go.mod
View File

@@ -11,9 +11,8 @@ require (
github.com/golang/protobuf v1.3.2 // indirect
github.com/google/go-cmp v0.3.1 // indirect
github.com/integrii/flaggy v1.4.0
github.com/jesseduffield/gocui v0.3.1-0.20200224201655-5024a02682ed
github.com/jesseduffield/gocui v0.3.1-0.20200301081700-d6e485450113
github.com/jesseduffield/pty v1.2.1
github.com/jesseduffield/rollrus v0.0.0-20190701125922-dd028cb0bfd7 // indirect
github.com/jesseduffield/termbox-go v0.0.0-20200130214842-1d31d1faa3c9 // indirect
github.com/kardianos/osext v0.0.0-20190222173326-2bc1f35cddc0
github.com/konsorten/go-windows-terminal-sequences v1.0.2 // indirect

33
go.sum
View File

@@ -54,7 +54,6 @@ github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfU
github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.3.1 h1:YF8+flBXS5eO826T4nzqPrxfhQThhXl0YzfuUPu4SBg=
github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.3.2 h1:6nsPYzhq5kReh6QImI3k5qWzO4PEbvbIW2cwSfR/6xs=
github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
@@ -77,28 +76,12 @@ github.com/integrii/flaggy v1.4.0 h1:A1x7SYx4jqu5NSrY14z8Z+0UyX2S5ygfJJrfolWR3zM
github.com/integrii/flaggy v1.4.0/go.mod h1:tnTxHeTJbah0gQ6/K0RW0J7fMUBk9MCF5blhm43LNpI=
github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 h1:BQSFePA1RWJOlocH6Fxy8MmwDt+yVQYULKfN0RoTN8A=
github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99/go.mod h1:1lJo3i6rXxKeerYnT8Nvf0QmHCRC1n8sfWVwXF2Frvo=
github.com/jesseduffield/gocui v0.3.1-0.20191116013947-b13bda319532 h1:V1Lk2rm5/p27NjnlF2ezzkxDaisHNcveMNueSD7RYgs=
github.com/jesseduffield/gocui v0.3.1-0.20191116013947-b13bda319532/go.mod h1:2RtZznzYKt8RLRwvFiSkXjU0Ei8WwHdubgnlaYH47dw=
github.com/jesseduffield/gocui v0.3.1-0.20200112025325-6c933915c351 h1:+sSqd2YotacWt+1MNRN8ZmXnYoiJeblZeptzKiHIyv0=
github.com/jesseduffield/gocui v0.3.1-0.20200112025325-6c933915c351/go.mod h1:2RtZznzYKt8RLRwvFiSkXjU0Ei8WwHdubgnlaYH47dw=
github.com/jesseduffield/gocui v0.3.1-0.20200131125953-f679540a7039 h1:CVhilJ8ZdN7GmAI+fbH9829Cp/8hbK7Lijbd4VaNgo0=
github.com/jesseduffield/gocui v0.3.1-0.20200131125953-f679540a7039/go.mod h1:2RtZznzYKt8RLRwvFiSkXjU0Ei8WwHdubgnlaYH47dw=
github.com/jesseduffield/gocui v0.3.1-0.20200131131454-a319843434ac h1:vp7I0RpFq4L46nFA9QQokzhFgr68LRGtwDO9xfq4F+A=
github.com/jesseduffield/gocui v0.3.1-0.20200131131454-a319843434ac/go.mod h1:2RtZznzYKt8RLRwvFiSkXjU0Ei8WwHdubgnlaYH47dw=
github.com/jesseduffield/gocui v0.3.1-0.20200201013258-57fdcf23edc5 h1:tE0w3tuL/bj1o5VMhjjE0ep6i7Fva+RYjKcMFcniJEY=
github.com/jesseduffield/gocui v0.3.1-0.20200201013258-57fdcf23edc5/go.mod h1:2RtZznzYKt8RLRwvFiSkXjU0Ei8WwHdubgnlaYH47dw=
github.com/jesseduffield/gocui v0.3.1-0.20200223105115-3e1f0f7c3efe h1:UQyebauOcBzbGq32kTXwEyuJaqp3BkI8JoCrGs2jijU=
github.com/jesseduffield/gocui v0.3.1-0.20200223105115-3e1f0f7c3efe/go.mod h1:2RtZznzYKt8RLRwvFiSkXjU0Ei8WwHdubgnlaYH47dw=
github.com/jesseduffield/gocui v0.3.1-0.20200224201655-5024a02682ed h1:glGs+mzPZOl1iHiUsBW3918WeFwqsbQQ/jtLkkQXDi4=
github.com/jesseduffield/gocui v0.3.1-0.20200224201655-5024a02682ed/go.mod h1:2RtZznzYKt8RLRwvFiSkXjU0Ei8WwHdubgnlaYH47dw=
github.com/jesseduffield/gocui v0.3.1-0.20200301081700-d6e485450113 h1:jHZRVJUWsU8HaQ0crocz0i0BkpOqFLDJEO/AtBp+Ecs=
github.com/jesseduffield/gocui v0.3.1-0.20200301081700-d6e485450113/go.mod h1:2RtZznzYKt8RLRwvFiSkXjU0Ei8WwHdubgnlaYH47dw=
github.com/jesseduffield/pty v1.2.1 h1:7xYBiwNH0PpWqC8JmvrPq1a/ksNqyCavzWu9pbBGYWI=
github.com/jesseduffield/pty v1.2.1/go.mod h1:7jlS40+UhOqkZJDIG1B/H21xnuET/+fvbbnHCa8wSIo=
github.com/jesseduffield/roll v0.0.0-20190629104057-695be2e62b00 h1:+JaOkfBNYQYlGD7dgru8mCwYNEc5tRRI8mThlVANhSM=
github.com/jesseduffield/roll v0.0.0-20190629104057-695be2e62b00/go.mod h1:cWNQljQAWYBp4wchyGfql4q2jRNZXxiE1KhVQgz+JaM=
github.com/jesseduffield/rollrus v0.0.0-20190701125922-dd028cb0bfd7 h1:CRD7bVjlGIiV+M0jlsa+XWpneW0KY0e7Y4z3GWb5S4o=
github.com/jesseduffield/rollrus v0.0.0-20190701125922-dd028cb0bfd7/go.mod h1:VspA3aTkEo0Q7TPCLmX1uHNP+Wb4iSDX09hmTRo1QYc=
github.com/jesseduffield/termbox-go v0.0.0-20190630083001-9dd53af7214e h1:tth7wr6+sfSbdpRWWrwvLYyS56HyIRVfq0Qcl2h28wM=
github.com/jesseduffield/termbox-go v0.0.0-20190630083001-9dd53af7214e/go.mod h1:anMibpZtqNxjDbxrcDEAwSdaJ37vyUeM1f/M4uekib4=
github.com/jesseduffield/termbox-go v0.0.0-20200130214842-1d31d1faa3c9 h1:iBBk1lhFwjwJw//J2m1yyz9S368GeXQTpMVACTyQMh0=
github.com/jesseduffield/termbox-go v0.0.0-20200130214842-1d31d1faa3c9/go.mod h1:anMibpZtqNxjDbxrcDEAwSdaJ37vyUeM1f/M4uekib4=
github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI=
@@ -112,7 +95,6 @@ github.com/kevinburke/ssh_config v0.0.0-20190725054713-01f96b0aa0cd h1:Coekwdh0v
github.com/kevinburke/ssh_config v0.0.0-20190725054713-01f96b0aa0cd/go.mod h1:CT57kijsi8u/K/BOFA39wgDQJ9CxiF4nAY/ojJ6r6mM=
github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q=
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
github.com/konsorten/go-windows-terminal-sequences v1.0.1 h1:mweAR1A6xJ3oS2pRaGiHgQ4OO8tzTaLawm8vnODuwDk=
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
github.com/konsorten/go-windows-terminal-sequences v1.0.2 h1:DB17ag19krx9CFsz4o3enTrPXyIXCl+2iCXH/aMAp9s=
github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
@@ -130,8 +112,6 @@ github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVc
github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
github.com/mattn/go-isatty v0.0.11 h1:FxPOTFNqGkuDUGi3H/qkUbQO4ZiBa2brKq5r0l8TGeM=
github.com/mattn/go-isatty v0.0.11/go.mod h1:PhnuNfih5lzO57/f3n+odYbM4JtupLOxQOAqxQCu2WE=
github.com/mattn/go-runewidth v0.0.7 h1:Ei8KR0497xHyKJPAv59M1dkC+rOZCMBJ+t3fZ+twI54=
github.com/mattn/go-runewidth v0.0.7/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI=
github.com/mattn/go-runewidth v0.0.8 h1:3tS41NlGYSmhhe/8fhGRzc+z3AYCw1Fe1WAyLuujKs0=
github.com/mattn/go-runewidth v0.0.8/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI=
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
@@ -151,7 +131,6 @@ github.com/onsi/ginkgo v1.10.3/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+
github.com/onsi/gomega v1.7.1 h1:K0jcRCwNQM3vFGh1ppMtDh/+7ApJrjldlX8fA0jDTLQ=
github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY=
github.com/pelletier/go-buffruneio v0.2.0/go.mod h1:JkE26KsDizTr40EUHkXVtNPvgGtbSNq5BcowyYOWdKo=
github.com/pelletier/go-toml v1.2.0 h1:T5zMGML61Wp+FlcbWjRDT7yAxhJNAiPPLOFECq181zc=
github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic=
github.com/pelletier/go-toml v1.6.0 h1:aetoXYr0Tv7xRU/V4B4IZJ2QcbtMUFoNb3ORp7TzIK4=
github.com/pelletier/go-toml v1.6.0/go.mod h1:5N711Q9dKgbdkxHL+MEfF31hpT7l0S0s/t2kKREewys=
@@ -175,7 +154,6 @@ github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAm
github.com/shibukawa/configdir v0.0.0-20170330084843-e180dbdc8da0 h1:Xuk8ma/ibJ1fOy4Ee11vHhUFHQNpHhrBneOCNHVXS5w=
github.com/shibukawa/configdir v0.0.0-20170330084843-e180dbdc8da0/go.mod h1:7AwjWCpdPhkSmNAgUv5C7EJ4AbmjEB3r047r3DXWu3Y=
github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
github.com/sirupsen/logrus v1.3.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
github.com/sirupsen/logrus v1.4.2 h1:SPIRibHv4MatM3XXNO2BJeFLZwZ2LvZgfQ5+UNI2im4=
github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d h1:zE9ykElWQ6/NYmHa3jpm/yHnI4xSofP+UP6SpjHcSeM=
@@ -184,17 +162,14 @@ github.com/smartystreets/goconvey v1.6.4 h1:fv0U8FUIMPNf1L9lnHLvLhgicrIVChEkdzIK
github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA=
github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM=
github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA=
github.com/spf13/afero v1.1.2 h1:m8/z1t7/fwjysjQRYbP0RD+bUIF/8tJwPdEZsI83ACI=
github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ=
github.com/spf13/afero v1.2.2 h1:5jhuqJyZCZf2JRofRvN/nIFgIWNzPa3/Vz8mYylgbWc=
github.com/spf13/afero v1.2.2/go.mod h1:9ZxEEn6pIJ8Rxe320qSDBk6AsU0r9pR7Q4OcevTdifk=
github.com/spf13/cast v1.3.0 h1:oget//CVOEoFewqQxwr0Ej5yjygnqGkvggSE/gB35Q8=
github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE=
github.com/spf13/jwalterweatherman v1.0.0 h1:XHEdyB+EcvlqZamSM4ZOMGlc93t6AcsBEu9Gc1vn7yk=
github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo=
github.com/spf13/jwalterweatherman v1.1.0 h1:ue6voC5bR5F8YxI5S67j9i582FU4Qvo2bmqnqMYADFk=
github.com/spf13/jwalterweatherman v1.1.0/go.mod h1:aNWZUN0dPAAO/Ljvb5BEdw96iTZ0EXowPYD95IqWIGo=
github.com/spf13/pflag v1.0.3 h1:zPAT6CGy6wXeQ7NtTnaTerfKOsV6V6F8agHXFiazDkg=
github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
@@ -229,7 +204,6 @@ golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnf
golang.org/x/crypto v0.0.0-20190219172222-a4c6cb3142f2/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20190506204251-e1dfcc566284/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4 h1:HuIa8hRrWRSrqYzx1qI49NNxhdi2PrY7gxVSq1JjLDc=
golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20191206172530-e9b2fee46413 h1:ULYEB3JvPRE/IfO+9uO7vKV/xzVTO7XPAwm8xbf4w2g=
golang.org/x/crypto v0.0.0-20191206172530-e9b2fee46413/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
@@ -244,7 +218,6 @@ golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn
golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190522155817-f3200d17e092/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20190724013045-ca1201d0de80 h1:Ao/3l156eZf2AW5wK8a7/smtodRU+gha3+BeqJ69lRk=
golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553 h1:efeOvDhwQ29Dj3SdAV/MJf8oukgn+8D8WgaCaRMchF8=
golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
@@ -264,7 +237,6 @@ golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5h
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e h1:D5TXcfTk7xF7hvieo4QErS3qqCB4teTffacDWr7CI+0=
golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191210023423-ac6580df4449 h1:gSbV7h1NRL2G1xTg/owz62CST1oJBmxy4QpMMregXVQ=
@@ -286,7 +258,6 @@ google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZi
google.golang.org/grpc v1.21.0/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM=
gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY=
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo=
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=

View File

@@ -105,7 +105,7 @@ func (c *CommitListBuilder) GetCommits(limit bool) ([]*Commit, error) {
// now we can split it up and turn it into commits
for _, line := range utils.SplitLines(log) {
commit := c.extractCommitFromLine(line)
_, unpushed := unpushedCommits[commit.Sha]
_, unpushed := unpushedCommits[commit.Sha[:8]]
commit.Status = map[bool]string{true: "unpushed", false: "pushed"}[unpushed]
commits = append(commits, commit)
}
@@ -298,7 +298,7 @@ func (c *CommitListBuilder) getMergeBase() (string, error) {
// to the remote branch of the current branch, a map is returned to ease look up
func (c *CommitListBuilder) getUnpushedCommits() map[string]bool {
pushables := map[string]bool{}
o, err := c.OSCommand.RunCommandWithOutput("git rev-list @{u}..HEAD --abbrev-commit")
o, err := c.OSCommand.RunCommandWithOutput("git rev-list @{u}..HEAD --abbrev-commit --abbrev=8")
if err != nil {
return pushables
}

View File

@@ -7,6 +7,7 @@ import (
"os/exec"
"path/filepath"
"regexp"
"strconv"
"strings"
"time"
@@ -177,7 +178,7 @@ func stashEntryFromLine(line string, index int) *StashEntry {
// GetStashEntryDiff stash diff
func (c *GitCommand) ShowStashEntryCmdStr(index int) string {
return fmt.Sprintf("git stash show -p --color stash@{%d}", index)
return fmt.Sprintf("git stash show -p --color=%s stash@{%d}", c.colorArg(), index)
}
// GetStatusFiles git status files
@@ -558,11 +559,11 @@ func (c *GitCommand) Ignore(filename string) error {
}
func (c *GitCommand) ShowCmdStr(sha string) string {
return fmt.Sprintf("git show --color --no-renames --stat -p %s", sha)
return fmt.Sprintf("git show --color=%s --no-renames --stat -p %s", c.colorArg(), sha)
}
func (c *GitCommand) GetBranchGraphCmdStr(branchName string) string {
return fmt.Sprintf("git log --graph --color --abbrev-commit --decorate --date=relative --pretty=medium %s", branchName)
return fmt.Sprintf("git log --graph --color=always --abbrev-commit --decorate --date=relative --pretty=medium %s", branchName)
}
// GetRemoteURL returns current repo remote url
@@ -591,7 +592,7 @@ func (c *GitCommand) Diff(file *File, plain bool, cached bool) string {
func (c *GitCommand) DiffCmdStr(file *File, plain bool, cached bool) string {
cachedArg := ""
trackedArg := "--"
colorArg := "--color"
colorArg := c.colorArg()
split := strings.Split(file.Name, " -> ") // in case of a renamed file we get the new filename
fileName := c.OSCommand.Quote(split[len(split)-1])
if cached {
@@ -601,10 +602,10 @@ func (c *GitCommand) DiffCmdStr(file *File, plain bool, cached bool) string {
trackedArg = "--no-index /dev/null"
}
if plain {
colorArg = ""
colorArg = "never"
}
return fmt.Sprintf("git diff --stat -p %s %s %s %s", colorArg, cachedArg, trackedArg, fileName)
return fmt.Sprintf("git diff --color=%s %s %s %s", colorArg, cachedArg, trackedArg, fileName)
}
func (c *GitCommand) ApplyPatch(patch string, flags ...string) error {
@@ -896,12 +897,12 @@ func (c *GitCommand) ShowCommitFile(commitSha, fileName string, plain bool) (str
}
func (c *GitCommand) ShowCommitFileCmdStr(commitSha, fileName string, plain bool) string {
colorArg := "--color"
colorArg := c.colorArg()
if plain {
colorArg = ""
colorArg = "never"
}
return fmt.Sprintf("git show --no-renames %s %s -- %s", colorArg, commitSha, fileName)
return fmt.Sprintf("git show --no-renames --color=%s %s -- %s", colorArg, commitSha, fileName)
}
// CheckoutFile checks out the file for the given commit
@@ -967,7 +968,7 @@ func (c *GitCommand) ResetSoft(ref string) error {
// DiffCommits show diff between commits
func (c *GitCommand) DiffCommits(sha1, sha2 string) (string, error) {
return c.OSCommand.RunCommandWithOutput("git diff --color --stat -p %s %s", sha1, sha2)
return c.OSCommand.RunCommandWithOutput("git diff --color=%s --stat -p %s %s", c.colorArg(), sha1, sha2)
}
// CreateFixupCommit creates a commit that fixes up a previous commit
@@ -1115,7 +1116,7 @@ func (c *GitCommand) GetReflogCommits() ([]*Commit, error) {
re := regexp.MustCompile(`(\w+).*HEAD@\{\d+\}: (.*)`)
for i, line := range lines {
match := re.FindStringSubmatch(line)
if len(match) == 1 {
if len(match) <= 1 {
continue
}
@@ -1128,3 +1129,37 @@ func (c *GitCommand) GetReflogCommits() ([]*Commit, error) {
return commits, nil
}
func (c *GitCommand) ConfiguredPager() string {
if os.Getenv("GIT_PAGER") != "" {
return os.Getenv("GIT_PAGER")
}
if os.Getenv("PAGER") != "" {
return os.Getenv("PAGER")
}
output, err := c.OSCommand.RunCommandWithOutput("git config --get-all core.pager")
if err != nil {
return ""
}
trimmedOutput := strings.TrimSpace(output)
return strings.Split(trimmedOutput, "\n")[0]
}
func (c *GitCommand) GetPager(width int) string {
useConfig := c.Config.GetUserConfig().GetBool("git.paging.useConfig")
if useConfig {
pager := c.ConfiguredPager()
return strings.Split(pager, "| less")[0]
}
templateValues := map[string]string{
"columnWidth": strconv.Itoa(width/2 - 6),
}
pagerTemplate := c.Config.GetUserConfig().GetString("git.paging.pager")
return utils.ResolvePlaceholderString(pagerTemplate, templateValues)
}
func (c *GitCommand) colorArg() string {
return c.Config.GetUserConfig().GetString("git.paging.colorArg")
}

View File

@@ -1449,7 +1449,7 @@ func TestGitCommandGetBranchGraph(t *testing.T) {
gitCmd := NewDummyGitCommand()
gitCmd.OSCommand.command = func(cmd string, args ...string) *exec.Cmd {
assert.EqualValues(t, "git", cmd)
assert.EqualValues(t, []string{"log", "--graph", "--color", "--abbrev-commit", "--decorate", "--date=relative", "--pretty=medium", "test"}, args)
assert.EqualValues(t, []string{"log", "--graph", "--color=always", "--abbrev-commit", "--decorate", "--date=relative", "--pretty=medium", "test"}, args)
return exec.Command("echo")
}
@@ -1473,7 +1473,7 @@ func TestGitCommandDiff(t *testing.T) {
"Default case",
func(cmd string, args ...string) *exec.Cmd {
assert.EqualValues(t, "git", cmd)
assert.EqualValues(t, []string{"diff", "--stat", "-p", "--color", "--", "test.txt"}, args)
assert.EqualValues(t, []string{"diff", "--color=", "--", "test.txt"}, args)
return exec.Command("echo")
},
@@ -1489,7 +1489,7 @@ func TestGitCommandDiff(t *testing.T) {
"cached",
func(cmd string, args ...string) *exec.Cmd {
assert.EqualValues(t, "git", cmd)
assert.EqualValues(t, []string{"diff", "--stat", "-p", "--color", "--cached", "--", "test.txt"}, args)
assert.EqualValues(t, []string{"diff", "--color=", "--cached", "--", "test.txt"}, args)
return exec.Command("echo")
},
@@ -1505,7 +1505,7 @@ func TestGitCommandDiff(t *testing.T) {
"plain",
func(cmd string, args ...string) *exec.Cmd {
assert.EqualValues(t, "git", cmd)
assert.EqualValues(t, []string{"diff", "--stat", "-p", "--", "test.txt"}, args)
assert.EqualValues(t, []string{"diff", "--color=never", "--", "test.txt"}, args)
return exec.Command("echo")
},
@@ -1521,7 +1521,7 @@ func TestGitCommandDiff(t *testing.T) {
"File not tracked and file has no staged changes",
func(cmd string, args ...string) *exec.Cmd {
assert.EqualValues(t, "git", cmd)
assert.EqualValues(t, []string{"diff", "--stat", "-p", "--color", "--no-index", "/dev/null", "test.txt"}, args)
assert.EqualValues(t, []string{"diff", "--color=", "--no-index", "/dev/null", "test.txt"}, args)
return exec.Command("echo")
},
@@ -1871,7 +1871,7 @@ func TestGitCommandShowCommitFile(t *testing.T) {
"hello.txt",
test.CreateMockCommand(t, []*test.CommandSwapper{
{
Expect: "git show --no-renames 123456 -- hello.txt",
Expect: "git show --no-renames --color=never 123456 -- hello.txt",
Replace: "echo -n hello",
},
}),

View File

@@ -401,3 +401,11 @@ func (c *OSCommand) PipeCommands(commandStrings ...string) error {
}
return nil
}
func Kill(cmd *exec.Cmd) error {
if cmd.Process == nil {
// somebody got to it before we were able to, poor bastard
return nil
}
return cmd.Process.Kill()
}

View File

@@ -5,6 +5,7 @@ import (
"strings"
"github.com/go-errors/errors"
"github.com/jesseduffield/lazygit/pkg/config"
)
// Service is a service that repository is on (Github, Bitbucket, ...)
@@ -26,27 +27,63 @@ type RepoInformation struct {
Repository string
}
func getServices() []*Service {
return []*Service{
{
Name: "github.com",
PullRequestURL: "https://github.com/%s/%s/compare/%s?expand=1",
},
{
Name: "bitbucket.org",
PullRequestURL: "https://bitbucket.org/%s/%s/pull-requests/new?source=%s&t=1",
},
{
Name: "gitlab.com",
PullRequestURL: "https://gitlab.com/%s/%s/merge_requests/new?merge_request[source_branch]=%s",
},
// NewService builds a Service based on the host type
func NewService(typeName string, repositoryDomain string, siteDomain string) *Service {
var service *Service
switch typeName {
case "github":
service = &Service{
Name: repositoryDomain,
PullRequestURL: fmt.Sprintf("https://%s%s", siteDomain, "/%s/%s/compare/%s?expand=1"),
}
case "bitbucket":
service = &Service{
Name: repositoryDomain,
PullRequestURL: fmt.Sprintf("https://%s%s", siteDomain, "/%s/%s/pull-requests/new?source=%s&t=1"),
}
case "gitlab":
service = &Service{
Name: repositoryDomain,
PullRequestURL: fmt.Sprintf("https://%s%s", siteDomain, "/%s/%s/merge_requests/new?merge_request[source_branch]=%s"),
}
}
return service
}
func getServices(config config.AppConfigurer) []*Service {
services := []*Service{
NewService("github", "github.com", "github.com"),
NewService("bitbucket", "bitbucket.org", "bitbucket.org"),
NewService("gitlab", "gitlab.com", "gitlab.com"),
}
configServices := config.GetUserConfig().GetStringMapString("services")
for repoDomain, typeAndDomain := range configServices {
splitData := strings.Split(typeAndDomain, ":")
if len(splitData) != 2 {
// TODO log this misconfiguration
continue
}
service := NewService(splitData[0], repoDomain, splitData[1])
if service == nil {
// TODO log this unsupported service
continue
}
services = append(services, service)
}
return services
}
// NewPullRequest creates new instance of PullRequest
func NewPullRequest(gitCommand *GitCommand) *PullRequest {
return &PullRequest{
GitServices: getServices(),
GitServices: getServices(gitCommand.Config),
GitCommand: gitCommand,
}
}
@@ -85,7 +122,7 @@ func getRepoInfoFromURL(url string) *RepoInformation {
if isHTTP {
splits := strings.Split(url, "/")
owner := splits[len(splits)-2]
owner := strings.Join(splits[3:len(splits)-1], "/")
repo := strings.TrimSuffix(splits[len(splits)-1], ".git")
return &RepoInformation{
@@ -96,8 +133,8 @@ func getRepoInfoFromURL(url string) *RepoInformation {
tmpSplit := strings.Split(url, ":")
splits := strings.Split(tmpSplit[1], "/")
owner := splits[0]
repo := strings.TrimSuffix(splits[1], ".git")
owner := strings.Join(splits[0:len(splits)-1], "/")
repo := strings.TrimSuffix(splits[len(splits)-1], ".git")
return &RepoInformation{
Owner: owner,

View File

@@ -147,6 +147,13 @@ func TestCreatePullRequest(t *testing.T) {
gitCommand := NewDummyGitCommand()
gitCommand.OSCommand.command = s.command
gitCommand.OSCommand.Config.GetUserConfig().Set("os.openLinkCommand", "open {{link}}")
gitCommand.Config.GetUserConfig().Set("services", map[string]string{
// valid configuration for a custom service URL
"git.work.com": "gitlab:code.work.com",
// invalid configurations for a custom service URL
"invalid.work.com": "noservice:invalid.work.com",
"noservice.work.com": "noservice.work.com",
})
dummyPullRequest := NewPullRequest(gitCommand)
s.test(dummyPullRequest.Create(s.branch))
})

View File

@@ -244,6 +244,7 @@ func GetDefaultConfig() []byte {
scrollPastBottom: true
mouseEvents: true
skipUnstageLineWarning: false
sidePanelWidth: 0.3333
theme:
lightTheme: false
activeBorderColor:
@@ -258,6 +259,9 @@ func GetDefaultConfig() []byte {
commitLength:
show: true
git:
paging:
colorArg: always
useConfig: false
merging:
manualCommit: false
skipHookPrefix: 'WIP'

View File

@@ -50,7 +50,7 @@ func (gui *Gui) handleCommitFileSelect(g *gocui.Gui, v *gocui.View) error {
cmd := gui.OSCommand.ExecutableFromString(
gui.GitCommand.ShowCommitFileCmdStr(commitFile.Sha, commitFile.Name, false),
)
if err := gui.newCmdTask("main", cmd); err != nil {
if err := gui.newPtyTask("main", cmd); err != nil {
gui.Log.Error(err)
}

View File

@@ -67,7 +67,7 @@ func (gui *Gui) handleCommitSelect(g *gocui.Gui, v *gocui.View) error {
cmd := gui.OSCommand.ExecutableFromString(
gui.GitCommand.ShowCmdStr(commit.Sha),
)
if err := gui.newCmdTask("main", cmd); err != nil {
if err := gui.newPtyTask("main", cmd); err != nil {
gui.Log.Error(err)
}

View File

@@ -62,7 +62,7 @@ func (gui *Gui) selectFile(alreadySelected bool) error {
gui.getSecondaryView().Title = gui.Tr.SLocalize("StagedChanges")
cmdStr := gui.GitCommand.DiffCmdStr(file, false, true)
cmd := gui.OSCommand.ExecutableFromString(cmdStr)
if err := gui.newCmdTask("secondary", cmd); err != nil {
if err := gui.newPtyTask("secondary", cmd); err != nil {
return err
}
} else {
@@ -76,7 +76,7 @@ func (gui *Gui) selectFile(alreadySelected bool) error {
cmdStr := gui.GitCommand.DiffCmdStr(file, false, !file.HasUnstagedChanges && file.HasStagedChanges)
cmd := gui.OSCommand.ExecutableFromString(cmdStr)
if err := gui.newCmdTask("main", cmd); err != nil {
if err := gui.newPtyTask("main", cmd); err != nil {
return err
}

View File

@@ -211,6 +211,9 @@ type guiState struct {
Searching searchingState
ScreenMode int
SideView *gocui.View
Ptmx *os.File
PrevMainWidth int
PrevMainHeight int
}
// for now the split view will always be on
@@ -247,6 +250,7 @@ func NewGui(log *logrus.Entry, gitCommand *commands.GitCommand, oSCommand *comma
},
ScreenMode: SCREEN_NORMAL,
SideView: nil,
Ptmx: nil,
}
gui := &Gui{
@@ -516,11 +520,13 @@ func (gui *Gui) layout(g *gocui.Gui) error {
_, _ = g.SetViewOnBottom("limit")
g.DeleteView("limit")
sidePanelWidthRatio := gui.Config.GetUserConfig().GetFloat64("gui.sidePanelWidth")
textColor := theme.GocuiDefaultTextColor
var leftSideWidth int
switch gui.State.ScreenMode {
case SCREEN_NORMAL:
leftSideWidth = width / 3
leftSideWidth = int(float64(width) * sidePanelWidthRatio)
case SCREEN_HALF:
leftSideWidth = width / 2
case SCREEN_FULL:
@@ -811,6 +817,15 @@ func (gui *Gui) layout(g *gocui.Gui) error {
}
}
mainViewWidth, mainViewHeight := gui.getMainView().Size()
if mainViewWidth != gui.State.PrevMainWidth || mainViewHeight != gui.State.PrevMainHeight {
gui.State.PrevMainWidth = mainViewWidth
gui.State.PrevMainHeight = mainViewHeight
if err := gui.onResize(); err != nil {
return err
}
}
// here is a good place log some stuff
// if you download humanlog and do tail -f development.log | humanlog
// this will let you see these branches as prettified json
@@ -942,7 +957,7 @@ func (gui *Gui) startBackgroundFetch() {
// Run setup the gui with keybindings and start the mainloop
func (gui *Gui) Run() error {
g, err := gocui.NewGui(gocui.OutputNormal, OverlappingEdges)
g, err := gocui.NewGui(gocui.Output256, OverlappingEdges)
if err != nil {
return err
}

View File

@@ -225,6 +225,7 @@ func (gui *Gui) GetInitialKeybindings() []*Binding {
Modifier: gocui.ModNone,
Handler: gui.scrollUpMain,
Alternative: "fn+up",
Description: gui.Tr.SLocalize("scrollUpMainPanel"),
},
{
ViewName: "",
@@ -232,6 +233,7 @@ func (gui *Gui) GetInitialKeybindings() []*Binding {
Modifier: gocui.ModNone,
Handler: gui.scrollDownMain,
Alternative: "fn+down",
Description: gui.Tr.SLocalize("scrollDownMainPanel"),
},
{
ViewName: "",
@@ -1013,7 +1015,7 @@ func (gui *Gui) GetInitialKeybindings() []*Binding {
Contexts: []string{"staging"},
Key: gui.getKey("universal.select"),
Modifier: gocui.ModNone,
Handler: gui.handleStageSelection,
Handler: gui.handleToggleStagedSelection,
Description: gui.Tr.SLocalize("StageSelection"),
},
{
@@ -1135,16 +1137,8 @@ func (gui *Gui) GetInitialKeybindings() []*Binding {
Contexts: []string{"patch-building"},
Key: gui.getKey("universal.select"),
Modifier: gocui.ModNone,
Handler: gui.handleAddSelectionToPatch,
Description: gui.Tr.SLocalize("StageSelection"),
},
{
ViewName: "main",
Contexts: []string{"patch-building"},
Key: gui.getKey("universal.remove"),
Modifier: gocui.ModNone,
Handler: gui.handleRemoveSelectionFromPatch,
Description: gui.Tr.SLocalize("ResetSelection"),
Handler: gui.handleToggleSelectionForPatch,
Description: gui.Tr.SLocalize("ToggleSelectionForPatch"),
},
{
ViewName: "main",

View File

@@ -220,6 +220,10 @@ func (gui *Gui) handleMouseScrollDown(g *gocui.Gui, v *gocui.View) error {
return gui.handleCycleLine(1)
}
func (gui *Gui) getSelectedCommitFileName() string {
return gui.State.CommitFiles[gui.State.Panels.CommitFiles.SelectedLine].Name
}
func (gui *Gui) refreshMainView() error {
state := gui.State.Panels.LineByLine
@@ -227,7 +231,7 @@ func (gui *Gui) refreshMainView() error {
// I'd prefer not to have knowledge of contexts using this file but I'm not sure
// how to get around this
if gui.State.MainContext == "patch-building" {
filename := gui.State.CommitFiles[gui.State.Panels.CommitFiles.SelectedLine].Name
filename := gui.getSelectedCommitFileName()
includedLineIndices = gui.GitCommand.PatchManager.GetFileIncLineIndices(filename)
}
colorDiff := state.PatchParser.Render(state.FirstLineIdx, state.LastLineIdx, includedLineIndices)

View File

@@ -2,6 +2,7 @@ package gui
import (
"github.com/jesseduffield/gocui"
"github.com/jesseduffield/lazygit/pkg/utils"
)
func (gui *Gui) refreshPatchBuildingPanel(selectedLineIdx int) error {
@@ -42,38 +43,24 @@ func (gui *Gui) refreshPatchBuildingPanel(selectedLineIdx int) error {
return nil
}
func (gui *Gui) handleAddSelectionToPatch(g *gocui.Gui, v *gocui.View) error {
func (gui *Gui) handleToggleSelectionForPatch(g *gocui.Gui, v *gocui.View) error {
state := gui.State.Panels.LineByLine
toggleFunc := gui.GitCommand.PatchManager.AddFileLineRange
filename := gui.getSelectedCommitFileName()
includedLineIndices := gui.GitCommand.PatchManager.GetFileIncLineIndices(filename)
currentLineIsStaged := utils.IncludesInt(includedLineIndices, state.SelectedLineIdx)
if currentLineIsStaged {
toggleFunc = gui.GitCommand.PatchManager.RemoveFileLineRange
}
// add range of lines to those set for the file
commitFile := gui.getSelectedCommitFile(gui.g)
if commitFile == nil {
return gui.renderString(gui.g, "commitFiles", gui.Tr.SLocalize("NoCommiteFiles"))
}
gui.GitCommand.PatchManager.AddFileLineRange(commitFile.Name, state.FirstLineIdx, state.LastLineIdx)
if err := gui.refreshCommitFilesView(); err != nil {
return err
}
if err := gui.refreshPatchBuildingPanel(-1); err != nil {
return err
}
return nil
}
func (gui *Gui) handleRemoveSelectionFromPatch(g *gocui.Gui, v *gocui.View) error {
state := gui.State.Panels.LineByLine
// add range of lines to those set for the file
commitFile := gui.getSelectedCommitFile(gui.g)
if commitFile == nil {
return gui.renderString(gui.g, "commitFiles", gui.Tr.SLocalize("NoCommiteFiles"))
}
gui.GitCommand.PatchManager.RemoveFileLineRange(commitFile.Name, state.FirstLineIdx, state.LastLineIdx)
toggleFunc(commitFile.Name, state.FirstLineIdx, state.LastLineIdx)
if err := gui.refreshCommitFilesView(); err != nil {
return err

74
pkg/gui/pty.go Normal file
View File

@@ -0,0 +1,74 @@
// +build !windows
package gui
import (
"os/exec"
"github.com/jesseduffield/pty"
)
func (gui *Gui) onResize() error {
if gui.State.Ptmx == nil {
return nil
}
mainView := gui.getMainView()
width, height := mainView.Size()
if err := pty.Setsize(gui.State.Ptmx, &pty.Winsize{Cols: uint16(width), Rows: uint16(height)}); err != nil {
return err
}
// TODO: handle resizing properly
return nil
}
// Some commands need to output for a terminal to active certain behaviour.
// For example, git won't invoke the GIT_PAGER env var unless it thinks it's
// talking to a terminal. We typically write cmd outputs straight to a view,
// which is just an io.Reader. the pty package lets us wrap a command in a
// pseudo-terminal meaning we'll get the behaviour we want from the underlying
// command.
func (gui *Gui) newPtyTask(viewName string, cmd *exec.Cmd) error {
width, _ := gui.getMainView().Size()
pager := gui.GitCommand.GetPager(width)
if pager == "" {
// if we're not using a custom pager we don't need to use a pty
return gui.newCmdTask(viewName, cmd)
}
cmd.Env = append(cmd.Env, "GIT_PAGER="+pager)
view, err := gui.g.View(viewName)
if err != nil {
return nil // swallowing for now
}
_, height := view.Size()
_, oy := view.Origin()
manager := gui.getManager(view)
ptmx, err := pty.Start(cmd)
if err != nil {
return err
}
gui.State.Ptmx = ptmx
onClose := func() {
ptmx.Close()
gui.State.Ptmx = nil
}
if err := gui.onResize(); err != nil {
return err
}
if err := manager.NewTask(manager.NewCmdTask(ptmx, cmd, height+oy+10, onClose)); err != nil {
return err
}
return nil
}

13
pkg/gui/pty_windows.go Normal file
View File

@@ -0,0 +1,13 @@
// +build windows
package gui
import "os/exec"
func (gui *Gui) onResize() error {
return nil
}
func (gui *Gui) newPtyTask(viewName string, cmd *exec.Cmd) error {
return gui.newCmdTask(viewName, cmd)
}

View File

@@ -41,7 +41,7 @@ func (gui *Gui) handleReflogCommitSelect(g *gocui.Gui, v *gocui.View) error {
cmd := gui.OSCommand.ExecutableFromString(
gui.GitCommand.ShowCmdStr(commit.Sha),
)
if err := gui.newCmdTask("main", cmd); err != nil {
if err := gui.newPtyTask("main", cmd); err != nil {
gui.Log.Error(err)
}

View File

@@ -99,26 +99,27 @@ func (gui *Gui) handleStagingEscape(g *gocui.Gui, v *gocui.View) error {
return gui.switchFocus(gui.g, nil, gui.getFilesView())
}
func (gui *Gui) handleStageSelection(g *gocui.Gui, v *gocui.View) error {
return gui.applySelectionWithPrompt(false)
func (gui *Gui) handleToggleStagedSelection(g *gocui.Gui, v *gocui.View) error {
state := gui.State.Panels.LineByLine
return gui.applySelection(state.SecondaryFocused)
}
func (gui *Gui) handleResetSelection(g *gocui.Gui, v *gocui.View) error {
return gui.applySelectionWithPrompt(true)
}
func (gui *Gui) applySelectionWithPrompt(reverse bool) error {
state := gui.State.Panels.LineByLine
if !reverse && state.SecondaryFocused {
return gui.createErrorPanel(gui.g, gui.Tr.SLocalize("CantStageStaged"))
} else if reverse && !state.SecondaryFocused && !gui.Config.GetUserConfig().GetBool("gui.skipUnstageLineWarning") {
return gui.createConfirmationPanel(gui.g, gui.getMainView(), false, "unstage lines", "Are you sure you want to unstage these lines? It is irreversible.\nTo disable this dialogue set the config key of 'gui.skipUnstageLineWarning' to true", func(*gocui.Gui, *gocui.View) error {
return gui.applySelection(reverse)
}, nil)
if state.SecondaryFocused {
// for backwards compatibility
return gui.applySelection(true)
}
return gui.applySelection(reverse)
if gui.Config.GetUserConfig().GetBool("gui.skipUnstageLineWarning") {
return gui.createConfirmationPanel(gui.g, gui.getMainView(), false, "unstage lines", "Are you sure you want to delete the selected lines (git reset)? It is irreversible.\nTo disable this dialogue set the config key of 'gui.skipUnstageLineWarning' to true", func(*gocui.Gui, *gocui.View) error {
return gui.applySelection(true)
}, nil)
} else {
return gui.applySelection(true)
}
}
func (gui *Gui) applySelection(reverse bool) error {

View File

@@ -41,7 +41,7 @@ func (gui *Gui) handleStashEntrySelect(g *gocui.Gui, v *gocui.View) error {
cmd := gui.OSCommand.ExecutableFromString(
gui.GitCommand.ShowStashEntryCmdStr(stashEntry.Index),
)
if err := gui.newCmdTask("main", cmd); err != nil {
if err := gui.newPtyTask("main", cmd); err != nil {
gui.Log.Error(err)
}

View File

@@ -18,7 +18,17 @@ func (gui *Gui) newCmdTask(viewName string, cmd *exec.Cmd) error {
manager := gui.getManager(view)
if err := manager.NewTask(manager.NewCmdTask(cmd, height+oy+10)); err != nil {
r, err := cmd.StdoutPipe()
if err != nil {
return err
}
cmd.Stderr = cmd.Stdout
if err := cmd.Start(); err != nil {
return err
}
if err := manager.NewTask(manager.NewCmdTask(r, cmd, height+oy+10, nil)); err != nil {
return err
}
@@ -69,7 +79,10 @@ func (gui *Gui) getManager(view *gocui.View) *tasks.ViewBufferManager {
view.Clear()
},
func() {
gui.g.Update(func(*gocui.Gui) error { return nil })
gui.g.Update(func(*gocui.Gui) error {
gui.Log.Warn("updating view")
return nil
})
})
gui.viewBufferManagerMap[view.Name()] = manager
}

View File

@@ -501,16 +501,19 @@ func addEnglish(i18nObject *i18n.Bundle) error {
Other: `select hunk`,
}, &i18n.Message{
ID: "StageSelection",
Other: `stage selection`,
Other: `toggle line staged / unstaged`,
}, &i18n.Message{
ID: "ResetSelection",
Other: `reset selection`,
Other: `delete change (git reset)`,
}, &i18n.Message{
ID: "ToggleDragSelect",
Other: `toggle drag select`,
}, &i18n.Message{
ID: "ToggleSelectHunk",
Other: `toggle select hunk`,
}, &i18n.Message{
ID: "ToggleSelectionForPatch",
Other: `add/remove line(s) to patch`,
},
&i18n.Message{
ID: "TogglePanel",
@@ -564,6 +567,54 @@ func addEnglish(i18nObject *i18n.Bundle) error {
}, &i18n.Message{
ID: "RebaseOptionsTitle",
Other: "Rebase Options",
}, &i18n.Message{
ID: "CommitMessageTitle",
Other: "Commit Message",
}, &i18n.Message{
ID: "Local-BranchesTitle",
Other: "Branches Tab",
}, &i18n.Message{
ID: "SearchTitle",
Other: "Search",
}, &i18n.Message{
ID: "TagsTitle",
Other: "Tags Tab",
}, &i18n.Message{
ID: "Branch-CommitsTitle",
Other: "Commits Tab",
}, &i18n.Message{
ID: "MenuTitle",
Other: "Menu",
}, &i18n.Message{
ID: "RemotesTitle",
Other: "Remotes Tab",
}, &i18n.Message{
ID: "CredentialsTitle",
Other: "Credentials",
}, &i18n.Message{
ID: "Remote-BranchesTitle",
Other: "Remote Branches (in Remotes tab)",
}, &i18n.Message{
ID: "Patch-BuildingTitle",
Other: "Patch Building",
}, &i18n.Message{
ID: "InformationTitle",
Other: "Information",
}, &i18n.Message{
ID: "SecondaryTitle",
Other: "Secondary",
}, &i18n.Message{
ID: "Reflog-CommitsTitle",
Other: "Reflog Tab",
}, &i18n.Message{
ID: "Title",
Other: "Title",
}, &i18n.Message{
ID: "GlobalTitle",
Other: "Global Keybindings",
}, &i18n.Message{
ID: "MerginTitle",
Other: "Mergin",
}, &i18n.Message{
ID: "ConflictsResolved",
Other: "all merge conflicts resolved. Continue?",
@@ -651,6 +702,12 @@ func addEnglish(i18nObject *i18n.Bundle) error {
}, &i18n.Message{
ID: "ScrollUp",
Other: "scroll up",
}, &i18n.Message{
ID: "scrollUpMainPanel",
Other: "scroll up main panel",
}, &i18n.Message{
ID: "scrollDownMainPanel",
Other: "scroll down main panel",
}, &i18n.Message{
ID: "AmendCommitTitle",
Other: "Amend Commit",
@@ -692,7 +749,7 @@ func addEnglish(i18nObject *i18n.Bundle) error {
Other: "view commit's files",
}, &i18n.Message{
ID: "CommitFilesTitle",
Other: "Commit files",
Other: "Commit Files",
}, &i18n.Message{
ID: "goBack",
Other: "go back",
@@ -951,6 +1008,12 @@ func addEnglish(i18nObject *i18n.Bundle) error {
}, &i18n.Message{
ID: "prevScreenMode",
Other: "prev screen mode",
}, &i18n.Message{
ID: "Panel",
Other: "Panel",
}, &i18n.Message{
ID: "Keybindings",
Other: "Keybindings",
},
)
}

View File

@@ -8,6 +8,7 @@ import (
"sync"
"time"
"github.com/jesseduffield/lazygit/pkg/commands"
"github.com/sirupsen/logrus"
)
@@ -45,27 +46,20 @@ func (m *ViewBufferManager) ReadLines(n int) {
}()
}
func (m *ViewBufferManager) NewCmdTask(cmd *exec.Cmd, linesToRead int) func(chan struct{}) error {
func (m *ViewBufferManager) NewCmdTask(r io.Reader, cmd *exec.Cmd, linesToRead int, onDone func()) func(chan struct{}) error {
return func(stop chan struct{}) error {
r, err := cmd.StdoutPipe()
if err != nil {
return err
}
cmd.Stderr = cmd.Stdout
if err := cmd.Start(); err != nil {
return err
}
go func() {
<-stop
if cmd.ProcessState == nil {
if err := kill(cmd); err != nil {
m.Log.Warn(err)
}
if err := commands.Kill(cmd); err != nil {
m.Log.Warn(err)
}
if onDone != nil {
onDone()
}
}()
loadingMutex := sync.Mutex{}
// not sure if it's the right move to redefine this or not
m.readLines = make(chan int, 1024)
@@ -82,11 +76,13 @@ func (m *ViewBufferManager) NewCmdTask(cmd *exec.Cmd, linesToRead int) func(chan
defer ticker.Stop()
select {
case <-ticker.C:
loadingMutex.Lock()
if !loaded {
m.beforeStart()
m.writer.Write([]byte("loading..."))
m.refreshView()
}
loadingMutex.Unlock()
case <-stop:
return
}
@@ -98,13 +94,16 @@ func (m *ViewBufferManager) NewCmdTask(cmd *exec.Cmd, linesToRead int) func(chan
case linesToRead := <-m.readLines:
for i := 0; i < linesToRead; i++ {
ok := scanner.Scan()
loadingMutex.Lock()
if !loaded {
m.beforeStart()
loaded = true
}
loadingMutex.Unlock()
select {
case <-stop:
m.refreshView()
break outer
default:
}
@@ -116,6 +115,7 @@ func (m *ViewBufferManager) NewCmdTask(cmd *exec.Cmd, linesToRead int) func(chan
}
m.refreshView()
case <-stop:
m.refreshView()
break outer
}
}
@@ -124,6 +124,12 @@ func (m *ViewBufferManager) NewCmdTask(cmd *exec.Cmd, linesToRead int) func(chan
m.Log.Warn(err)
}
m.refreshView()
if onDone != nil {
onDone()
}
close(done)
}()
@@ -141,7 +147,7 @@ func (t *ViewBufferManager) Close() {
return
}
c := make(chan struct{}, 1)
c := make(chan struct{})
go func() {
t.currentTask.Stop()
@@ -170,7 +176,10 @@ func (m *ViewBufferManager) NewTask(f func(stop chan struct{}) error) error {
m.waitingMutex.Lock()
defer m.waitingMutex.Unlock()
m.Log.Infof("done waiting")
if taskID < m.newTaskId {
m.Log.Infof("returning cos the task is obsolete")
return
}
@@ -216,13 +225,3 @@ func (t *Task) Stop() {
t.stopped = true
return
}
// kill kills a process
func kill(cmd *exec.Cmd) error {
if cmd.Process == nil {
// somebody got to it before we were able to, poor bastard
return nil
}
return cmd.Process.Kill()
}

View File

@@ -12,6 +12,7 @@ import (
"fmt"
"log"
"os"
"sort"
"strings"
"github.com/jesseduffield/lazygit/pkg/app"
@@ -60,33 +61,87 @@ func formatTitle(title string) string {
func formatBinding(binding *gui.Binding) string {
if binding.Alternative != "" {
return fmt.Sprintf(" <kbd>%s</kbd>: %s (%s)\n", binding.GetKey(), binding.Description, binding.Alternative)
return fmt.Sprintf(" <kbd>%s</kbd>: %s (%s)\n", gui.GetKeyDisplay(binding.Key), binding.Description, binding.Alternative)
}
return fmt.Sprintf(" <kbd>%s</kbd>: %s\n", binding.GetKey(), binding.Description)
return fmt.Sprintf(" <kbd>%s</kbd>: %s\n", gui.GetKeyDisplay(binding.Key), binding.Description)
}
func getBindingSections(mApp *app.App) []*bindingSection {
bindingSections := []*bindingSection{}
// TODO: add context-based keybindings
for _, binding := range mApp.Gui.GetInitialKeybindings() {
if binding.Description == "" {
continue
bindings := mApp.Gui.GetInitialKeybindings()
type contextAndViewType struct {
context string
viewName string
}
contextAndViewBindingMap := map[contextAndViewType][]*gui.Binding{}
for _, binding := range bindings {
contexts := []string{}
if len(binding.Contexts) == 0 {
contexts = append(contexts, "")
} else {
for _, context := range binding.Contexts {
contexts = append(contexts, context)
}
}
viewName := binding.ViewName
for _, context := range contexts {
key := contextAndViewType{context: context, viewName: binding.ViewName}
existing := contextAndViewBindingMap[key]
if existing == nil {
contextAndViewBindingMap[key] = []*gui.Binding{binding}
} else {
contextAndViewBindingMap[key] = append(contextAndViewBindingMap[key], binding)
}
}
}
type groupedBindingsType struct {
contextAndView contextAndViewType
bindings []*gui.Binding
}
groupedBindings := make([]groupedBindingsType, len(contextAndViewBindingMap))
for contextAndView, contextBindings := range contextAndViewBindingMap {
groupedBindings = append(groupedBindings, groupedBindingsType{contextAndView: contextAndView, bindings: contextBindings})
}
sort.Slice(groupedBindings, func(i, j int) bool {
first := groupedBindings[i].contextAndView
second := groupedBindings[j].contextAndView
if first.viewName == "" {
return true
}
if second.viewName == "" {
return false
}
return first.viewName < second.viewName || (first.viewName == second.viewName && first.context < second.context)
})
for _, group := range groupedBindings {
contextAndView := group.contextAndView
contextBindings := group.bindings
mApp.Log.Warn("viewname: " + contextAndView.viewName + ", context: " + contextAndView.context)
viewName := contextAndView.viewName
if viewName == "" {
viewName = "global"
}
title := localisedTitle(mApp, viewName)
bindingSections = addBinding(title, bindingSections, binding)
}
for contextName, contextBindings := range mApp.Gui.GetContextMap() {
translatedView := localisedTitle(mApp, contextBindings[0].ViewName)
translatedContextName := localisedTitle(mApp, contextName)
title := fmt.Sprintf("%s (%s)", translatedView, translatedContextName)
translatedView := localisedTitle(mApp, viewName)
var title string
if contextAndView.context == "" {
addendum := " " + mApp.Tr.SLocalize("Panel")
if viewName == "global" {
addendum = ""
}
title = fmt.Sprintf("%s%s", translatedView, addendum)
} else {
translatedContextName := localisedTitle(mApp, contextAndView.context)
title = fmt.Sprintf("%s %s (%s)", translatedView, mApp.Tr.SLocalize("Panel"), translatedContextName)
}
for _, binding := range contextBindings {
bindingSections = addBinding(title, bindingSections, binding)
@@ -117,7 +172,7 @@ func addBinding(title string, bindingSections []*bindingSection, binding *gui.Bi
}
func formatSections(mApp *app.App, bindingSections []*bindingSection) string {
content := fmt.Sprintf("# Lazygit %s\n", mApp.Tr.SLocalize("menu"))
content := fmt.Sprintf("# Lazygit %s\n", mApp.Tr.SLocalize("Keybindings"))
for _, section := range bindingSections {
content += formatTitle(section.title)

View File

@@ -152,13 +152,13 @@ func (ei *escapeInterpreter) outputNormal() error {
switch {
case p >= 30 && p <= 37:
ei.curFgColor = Attribute(p - 30 + 1)
ei.curFgColor |= Attribute(p - 30 + 1)
case p == 39:
ei.curFgColor = ColorDefault
ei.curFgColor |= ColorDefault
case p >= 40 && p <= 47:
ei.curBgColor = Attribute(p - 40 + 1)
ei.curBgColor |= Attribute(p - 40 + 1)
case p == 49:
ei.curBgColor = ColorDefault
ei.curBgColor |= ColorDefault
case p == 1:
ei.curFgColor |= AttrBold
case p == 4:

2
vendor/modules.txt vendored
View File

@@ -32,7 +32,7 @@ github.com/hashicorp/hcl/json/token
github.com/integrii/flaggy
# github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99
github.com/jbenet/go-context/io
# github.com/jesseduffield/gocui v0.3.1-0.20200224201655-5024a02682ed
# github.com/jesseduffield/gocui v0.3.1-0.20200301081700-d6e485450113
github.com/jesseduffield/gocui
# github.com/jesseduffield/pty v1.2.1
github.com/jesseduffield/pty