mirror of
https://github.com/jesseduffield/lazygit.git
synced 2026-10-02 03:56:45 -04:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
91f6630907 | ||
|
|
60085cf679 | ||
|
|
389480b8fc | ||
|
|
b5c4f78e9d | ||
|
|
59b0e2d70a | ||
|
|
39bd1a4628 | ||
|
|
1c1445c896 | ||
|
|
1e8ade2431 | ||
|
|
a990fbc3eb | ||
|
|
e5574e7fe5 | ||
|
|
6c8a924fad | ||
|
|
64706257ca | ||
|
|
6183d92315 | ||
|
|
31823a7405 | ||
|
|
85ddd623f6 | ||
|
|
9212dda9c3 | ||
|
|
93d7b37c8d | ||
|
|
8470bcd71d | ||
|
|
3aab37611a | ||
|
|
8fbcc36331 | ||
|
|
dadb646252 | ||
|
|
0227b93409 | ||
|
|
b0ec0821d5 | ||
|
|
13a7806cac | ||
|
|
41c76fb748 | ||
|
|
ac0c3b9f92 | ||
|
|
1be0ff8da7 | ||
|
|
2169b5109f | ||
|
|
4a2292a53c | ||
|
|
7df4b736cf | ||
|
|
e47ad846c4 | ||
|
|
8f68ac2129 | ||
|
|
1ea2825a54 | ||
|
|
19146d61b1 | ||
|
|
e541b809ce | ||
|
|
6ca08c6519 | ||
|
|
b43540820b | ||
|
|
3d57da71eb | ||
|
|
0130fd3666 | ||
|
|
395afc4a8d | ||
|
|
31e201ca52 | ||
|
|
0abd7ad6be | ||
|
|
b3522c48d9 | ||
|
|
0fc58a7986 | ||
|
|
54241d8ab9 | ||
|
|
355f1615ab | ||
|
|
113252b0ae | ||
|
|
1cd7d14029 | ||
|
|
87c2fb6a4a | ||
|
|
9912998bb7 | ||
|
|
e223d3d8de | ||
|
|
ec31fc4cc7 | ||
|
|
3ce2b9b79a | ||
|
|
a79182e50d | ||
|
|
6f4c595dde | ||
|
|
0eb3090ad6 | ||
|
|
6ea25bd259 | ||
|
|
fe5f087f9c | ||
|
|
79299be3b2 | ||
|
|
4c9b620bd0 | ||
|
|
a7508a5dfd | ||
|
|
1a3d765c4c | ||
|
|
4058c71ca0 | ||
|
|
3fc22a6010 | ||
|
|
a9fe0b8000 | ||
|
|
5af7b0235e | ||
|
|
bf946200e9 | ||
|
|
890cc87724 |
@@ -1,62 +0,0 @@
|
|||||||
version: 2
|
|
||||||
jobs:
|
|
||||||
build:
|
|
||||||
docker:
|
|
||||||
- image: circleci/golang:1.13
|
|
||||||
environment:
|
|
||||||
GO111MODULE: "on"
|
|
||||||
working_directory: /go/src/github.com/jesseduffield/lazygit
|
|
||||||
steps:
|
|
||||||
- checkout
|
|
||||||
- run:
|
|
||||||
name: Run gofmt -s
|
|
||||||
command: |
|
|
||||||
if [ $(find . ! -path "./vendor/*" -name "*.go" -exec gofmt -s -d {} \;|wc -l) -gt 0 ]; then
|
|
||||||
find . ! -path "./vendor/*" -name "*.go" -exec gofmt -s -d {} \;
|
|
||||||
exit 1;
|
|
||||||
fi
|
|
||||||
- restore_cache:
|
|
||||||
keys:
|
|
||||||
- pkg-cache-{{ checksum "go.sum" }}-v5
|
|
||||||
- run:
|
|
||||||
name: Run tests
|
|
||||||
command: |
|
|
||||||
./test.sh
|
|
||||||
- run:
|
|
||||||
name: Push on codecov result
|
|
||||||
command: |
|
|
||||||
bash <(curl -s https://codecov.io/bash)
|
|
||||||
- run:
|
|
||||||
name: Compile project on every platform
|
|
||||||
command: |
|
|
||||||
go get github.com/mitchellh/gox
|
|
||||||
GOFLAGS=-mod=vendor gox -parallel 10 -os "linux freebsd netbsd windows" -osarch "darwin/i386 darwin/amd64"
|
|
||||||
- save_cache:
|
|
||||||
key: pkg-cache-{{ checksum "go.sum" }}-v5
|
|
||||||
paths:
|
|
||||||
- ~/.cache/go-build
|
|
||||||
|
|
||||||
release:
|
|
||||||
docker:
|
|
||||||
- image: circleci/golang:1.13
|
|
||||||
working_directory: /go/src/github.com/jesseduffield/lazygit
|
|
||||||
steps:
|
|
||||||
- checkout
|
|
||||||
- run:
|
|
||||||
name: Run gorelease
|
|
||||||
command: |
|
|
||||||
curl -sL https://git.io/goreleaser | bash
|
|
||||||
|
|
||||||
workflows:
|
|
||||||
version: 2
|
|
||||||
build:
|
|
||||||
jobs:
|
|
||||||
- build
|
|
||||||
release:
|
|
||||||
jobs:
|
|
||||||
- release:
|
|
||||||
filters:
|
|
||||||
tags:
|
|
||||||
only: /v[0-9]+(\.[0-9]+)*/
|
|
||||||
branches:
|
|
||||||
ignore: /.*/
|
|
||||||
@@ -0,0 +1,34 @@
|
|||||||
|
name: Continuous Delivery
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
tags:
|
||||||
|
- 'v*'
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
cd:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- name: Checkout code
|
||||||
|
uses: actions/checkout@v2
|
||||||
|
with:
|
||||||
|
fetch-depth: 0
|
||||||
|
- name: Setup Go
|
||||||
|
uses: actions/setup-go@v1
|
||||||
|
with:
|
||||||
|
go-version: 1.14.x
|
||||||
|
- name: Run goreleaser
|
||||||
|
uses: goreleaser/goreleaser-action@v1
|
||||||
|
with:
|
||||||
|
args: release --rm-dist
|
||||||
|
env:
|
||||||
|
GITHUB_TOKEN: ${{secrets.GITHUB_API_TOKEN}}
|
||||||
|
- name: Get tag
|
||||||
|
id: tag
|
||||||
|
uses: dawidd6/action-get-tag@v1
|
||||||
|
- name: Bump Homebrew
|
||||||
|
uses: dawidd6/action-homebrew-bump-formula@v1
|
||||||
|
with:
|
||||||
|
token: ${{secrets.GITHUB_API_TOKEN}}
|
||||||
|
formula: lazygit
|
||||||
|
url: "https://github.com/${{github.repository}}/archive/${{steps.tag.outputs.tag}}.tar.gz"
|
||||||
@@ -0,0 +1,37 @@
|
|||||||
|
name: Continuous Integration
|
||||||
|
|
||||||
|
on: push
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
ci:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
env:
|
||||||
|
GOFLAGS: -mod=vendor
|
||||||
|
steps:
|
||||||
|
- name: Checkout code
|
||||||
|
uses: actions/checkout@v2
|
||||||
|
- name: Setup Go
|
||||||
|
uses: actions/setup-go@v1
|
||||||
|
with:
|
||||||
|
go-version: 1.14.x
|
||||||
|
- name: Cache build
|
||||||
|
uses: actions/cache@v1
|
||||||
|
with:
|
||||||
|
path: ~/.cache/go-build
|
||||||
|
key: ${{runner.os}}-go-${{hashFiles('**/go.sum')}}
|
||||||
|
restore-keys: |
|
||||||
|
${{runner.os}}-go-
|
||||||
|
- name: Format code
|
||||||
|
run: |
|
||||||
|
if [ $(find . ! -path "./vendor/*" -name "*.go" -exec gofmt -s -d {} \;|wc -l) -gt 0 ]; then
|
||||||
|
find . ! -path "./vendor/*" -name "*.go" -exec gofmt -s -d {} \;
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
- name: Test code
|
||||||
|
run: |
|
||||||
|
./test.sh
|
||||||
|
- name: Build binaries
|
||||||
|
run: |
|
||||||
|
go get github.com/mitchellh/gox
|
||||||
|
export PATH="$(go env GOPATH)/bin:$PATH"
|
||||||
|
gox -parallel 4 -os "linux freebsd netbsd windows" -osarch "darwin/i386 darwin/amd64"
|
||||||
@@ -13,6 +13,9 @@ builds:
|
|||||||
- arm
|
- arm
|
||||||
- arm64
|
- arm64
|
||||||
- 386
|
- 386
|
||||||
|
ignore:
|
||||||
|
- goos: freebsd
|
||||||
|
goarch: arm64
|
||||||
# Default is `-s -w -X main.version={{.Version}} -X main.commit={{.Commit}} -X main.date={{.Date}}`.
|
# Default is `-s -w -X main.version={{.Version}} -X main.commit={{.Commit}} -X main.date={{.Date}}`.
|
||||||
ldflags:
|
ldflags:
|
||||||
- -s -w -X main.version={{.Version}} -X main.commit={{.Commit}} -X main.date={{.Date}} -X main.buildSource=binaryRelease
|
- -s -w -X main.version={{.Version}} -X main.commit={{.Commit}} -X main.date={{.Date}} -X main.buildSource=binaryRelease
|
||||||
|
|||||||
+2
-2
@@ -2,12 +2,12 @@
|
|||||||
# docker build -t lazygit .
|
# docker build -t lazygit .
|
||||||
# docker run -it lazygit:latest /bin/sh -l
|
# docker run -it lazygit:latest /bin/sh -l
|
||||||
|
|
||||||
FROM golang:1.13-alpine3.10
|
FROM golang:1.14-alpine3.11
|
||||||
WORKDIR /go/src/github.com/jesseduffield/lazygit/
|
WORKDIR /go/src/github.com/jesseduffield/lazygit/
|
||||||
COPY ./ .
|
COPY ./ .
|
||||||
RUN CGO_ENABLED=0 GOOS=linux go build
|
RUN CGO_ENABLED=0 GOOS=linux go build
|
||||||
|
|
||||||
FROM alpine:3.10
|
FROM alpine:3.11
|
||||||
RUN apk add -U git xdg-utils
|
RUN apk add -U git xdg-utils
|
||||||
WORKDIR /go/src/github.com/jesseduffield/lazygit/
|
WORKDIR /go/src/github.com/jesseduffield/lazygit/
|
||||||
COPY --from=0 /go/src/github.com/jesseduffield/lazygit /go/src/github.com/jesseduffield/lazygit
|
COPY --from=0 /go/src/github.com/jesseduffield/lazygit /go/src/github.com/jesseduffield/lazygit
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
# lazygit [](https://circleci.com/gh/jesseduffield/lazygit) [](https://codecov.io/gh/jesseduffield/lazygit) [](https://goreportcard.com/report/github.com/jesseduffield/lazygit) [](https://golangci.com) [](http://godoc.org/github.com/jesseduffield/lazygit) []()
|
# lazygit  [](https://goreportcard.com/report/github.com/jesseduffield/lazygit) [](https://golangci.com) [](http://godoc.org/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.
|
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.
|
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
|
## Installation
|
||||||
|
|
||||||
### Homebrew
|
### 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.
|
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:
|
Tap:
|
||||||
|
|
||||||
```
|
```
|
||||||
brew install jesseduffield/lazygit/lazygit
|
brew install jesseduffield/lazygit/lazygit
|
||||||
```
|
```
|
||||||
@@ -38,8 +40,10 @@ brew install lazygit
|
|||||||
```
|
```
|
||||||
|
|
||||||
### MacPorts
|
### MacPorts
|
||||||
|
|
||||||
Latest version built from github releases.
|
Latest version built from github releases.
|
||||||
Tap:
|
Tap:
|
||||||
|
|
||||||
```
|
```
|
||||||
sudo port install lazygit
|
sudo port install lazygit
|
||||||
```
|
```
|
||||||
@@ -63,6 +67,17 @@ They follow upstream latest releases
|
|||||||
```sh
|
```sh
|
||||||
sudo xbps-install -S lazygit
|
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
|
### 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
|
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.
|
and the git version which builds from the most recent commit.
|
||||||
|
|
||||||
- Stable: https://aur.archlinux.org/packages/lazygit/
|
- Stable: <https://aur.archlinux.org/packages/lazygit/>
|
||||||
- Development: https://aur.archlinux.org/packages/lazygit-git/
|
- Development: <https://aur.archlinux.org/packages/lazygit-git/>
|
||||||
|
|
||||||
Instruction of how to install AUR content can be found here:
|
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
|
### Fedora and CentOS 7
|
||||||
|
|
||||||
@@ -88,7 +103,7 @@ sudo dnf install lazygit
|
|||||||
|
|
||||||
### Conda
|
### 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
|
```sh
|
||||||
conda install -c conda-forge lazygit
|
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)
|
- Rebase Magic tutorial [here](https://youtu.be/4XaToVut_hs)
|
||||||
- List of keybindings
|
- List of keybindings
|
||||||
[here](/docs/keybindings).
|
[here](/docs/keybindings).
|
||||||
|
|
||||||
## Changing Directory On Exit
|
## 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):
|
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()
|
lg()
|
||||||
{
|
{
|
||||||
@@ -137,8 +153,17 @@ lg()
|
|||||||
fi
|
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`.
|
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
|
## Cool features
|
||||||
|
|
||||||
- Adding files easily
|
- Adding files easily
|
||||||
|
|||||||
+34
-12
@@ -1,17 +1,18 @@
|
|||||||
# User Config:
|
# User Config
|
||||||
|
|
||||||
Default path for the config file:
|
Default path for the config file:
|
||||||
|
|
||||||
* Linux: `~/.config/jesseduffield/lazygit/config.yml`
|
* Linux: `~/.config/jesseduffield/lazygit/config.yml`
|
||||||
* MacOS: `~/Library/Application Support/jesseduffield/lazygit/config.yml`
|
* MacOS: `~/Library/Application Support/jesseduffield/lazygit/config.yml`
|
||||||
|
|
||||||
## Default:
|
## Default
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
gui:
|
gui:
|
||||||
# stuff relating to the UI
|
# stuff relating to the UI
|
||||||
scrollHeight: 2 # how many lines you scroll by
|
scrollHeight: 2 # how many lines you scroll by
|
||||||
scrollPastBottom: true # enable scrolling past the bottom
|
scrollPastBottom: true # enable scrolling past the bottom
|
||||||
|
sidePanelWidth: 0.3333 # number from 0 to 1
|
||||||
theme:
|
theme:
|
||||||
lightTheme: false # For terminals with a light background
|
lightTheme: false # For terminals with a light background
|
||||||
activeBorderColor:
|
activeBorderColor:
|
||||||
@@ -28,6 +29,9 @@ Default path for the config file:
|
|||||||
mouseEvents: true
|
mouseEvents: true
|
||||||
skipUnstageLineWarning: false
|
skipUnstageLineWarning: false
|
||||||
git:
|
git:
|
||||||
|
paging:
|
||||||
|
colorArg: always
|
||||||
|
useConfig: false
|
||||||
merging:
|
merging:
|
||||||
# only applicable to unix users
|
# only applicable to unix users
|
||||||
manualCommit: false
|
manualCommit: false
|
||||||
@@ -124,6 +128,7 @@ Default path for the config file:
|
|||||||
tagCommit: 'T'
|
tagCommit: 'T'
|
||||||
toggleDiffCommit: 'i'
|
toggleDiffCommit: 'i'
|
||||||
checkoutCommit: '<space>'
|
checkoutCommit: '<space>'
|
||||||
|
resetCherryPick: '<c-R>'
|
||||||
stash:
|
stash:
|
||||||
popStash: 'g'
|
popStash: 'g'
|
||||||
commitFiles:
|
commitFiles:
|
||||||
@@ -136,30 +141,30 @@ Default path for the config file:
|
|||||||
undo: 'z'
|
undo: 'z'
|
||||||
```
|
```
|
||||||
|
|
||||||
## Platform Defaults:
|
## Platform Defaults
|
||||||
|
|
||||||
### Windows:
|
### Windows
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
os:
|
os:
|
||||||
openCommand: 'cmd /c "start "" {{filename}}"'
|
openCommand: 'cmd /c "start "" {{filename}}"'
|
||||||
```
|
```
|
||||||
|
|
||||||
### Linux:
|
### Linux
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
os:
|
os:
|
||||||
openCommand: 'sh -c "xdg-open {{filename}} >/dev/null"'
|
openCommand: 'sh -c "xdg-open {{filename}} >/dev/null"'
|
||||||
```
|
```
|
||||||
|
|
||||||
### OSX:
|
### OSX
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
os:
|
os:
|
||||||
openCommand: 'open {{filename}}'
|
openCommand: 'open {{filename}}'
|
||||||
```
|
```
|
||||||
|
|
||||||
### Recommended Config Values:
|
### Recommended Config Values
|
||||||
|
|
||||||
for users of VSCode
|
for users of VSCode
|
||||||
|
|
||||||
@@ -168,7 +173,7 @@ for users of VSCode
|
|||||||
openCommand: 'code -r {{filename}}'
|
openCommand: 'code -r {{filename}}'
|
||||||
```
|
```
|
||||||
|
|
||||||
## Color Attributes:
|
## Color Attributes
|
||||||
|
|
||||||
For color attributes you can choose an array of attributes (with max one color attribute)
|
For color attributes you can choose an array of attributes (with max one color attribute)
|
||||||
The available attributes are:
|
The available attributes are:
|
||||||
@@ -186,7 +191,7 @@ The available attributes are:
|
|||||||
- reverse # useful for high-contrast
|
- reverse # useful for high-contrast
|
||||||
- underline
|
- 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
|
If you have issues with a light terminal theme where you can't read / see the text add these settings
|
||||||
|
|
||||||
@@ -203,15 +208,16 @@ If you have issues with a light terminal theme where you can't read / see the te
|
|||||||
- blue
|
- blue
|
||||||
```
|
```
|
||||||
|
|
||||||
## Example Coloring:
|
## Example Coloring
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
## Keybindings:
|
## Keybindings
|
||||||
|
|
||||||
For all possible keybinding options, check [Custom_Keybinding.md](https://github.com/jesseduffield/lazygit/blob/master/docs/keybindings/Custom_Keybinding.md)
|
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
|
```yaml
|
||||||
keybinding:
|
keybinding:
|
||||||
universal:
|
universal:
|
||||||
@@ -238,3 +244,19 @@ For all possible keybinding options, check [Custom_Keybinding.md](https://github
|
|||||||
viewGitFlowOptions: 'I'
|
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`
|
||||||
|
|||||||
@@ -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
|
||||||
|
```
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
## Diff-so-fancy
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
git:
|
||||||
|
paging:
|
||||||
|
colorArg: always
|
||||||
|
pager: diff-so-fancy
|
||||||
|
```
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
## 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}}
|
||||||
|
```
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
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).
|
||||||
@@ -1,47 +1,22 @@
|
|||||||
# Lazygit menu
|
# Lazygit Keybindings
|
||||||
|
|
||||||
## Global
|
## Global Keybindings
|
||||||
|
|
||||||
<pre>
|
<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>m</kbd>: view merge/rebase options
|
||||||
<kbd>ctrl+p</kbd>: view custom patch options
|
<kbd>ctrl+p</kbd>: view custom patch options
|
||||||
<kbd>P</kbd>: push
|
<kbd>P</kbd>: push
|
||||||
<kbd>p</kbd>: pull
|
<kbd>p</kbd>: pull
|
||||||
<kbd>R</kbd>: refresh
|
<kbd>R</kbd>: refresh
|
||||||
|
<kbd>x</kbd>: open menu
|
||||||
|
<kbd>+</kbd>: next screen mode (normal/half/fullscreen)
|
||||||
|
<kbd>_</kbd>: prev screen mode
|
||||||
|
<kbd>:</kbd>: execute custom command
|
||||||
</pre>
|
</pre>
|
||||||
|
|
||||||
## Status
|
## Branches Panel (Branches Tab)
|
||||||
|
|
||||||
<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
|
|
||||||
|
|
||||||
<pre>
|
<pre>
|
||||||
<kbd>space</kbd>: checkout
|
<kbd>space</kbd>: checkout
|
||||||
@@ -50,12 +25,68 @@
|
|||||||
<kbd>F</kbd>: force checkout
|
<kbd>F</kbd>: force checkout
|
||||||
<kbd>n</kbd>: new branch
|
<kbd>n</kbd>: new branch
|
||||||
<kbd>d</kbd>: delete 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>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>f</kbd>: fast-forward this branch from its upstream
|
||||||
|
<kbd>g</kbd>: view reset options
|
||||||
|
<kbd>R</kbd>: rename branch
|
||||||
|
<kbd>/</kbd>: start search
|
||||||
</pre>
|
</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
|
||||||
|
<kbd>/</kbd>: start search
|
||||||
|
</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
|
||||||
|
<kbd>/</kbd>: start search
|
||||||
|
</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
|
||||||
|
<kbd>/</kbd>: start search
|
||||||
|
</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
|
||||||
|
<kbd>/</kbd>: start search
|
||||||
|
</pre>
|
||||||
|
|
||||||
|
## Commits Panel
|
||||||
|
|
||||||
|
<pre>
|
||||||
|
<kbd>/</kbd>: start search
|
||||||
|
</pre>
|
||||||
|
|
||||||
|
## Commits Panel (Commits Tab)
|
||||||
|
|
||||||
<pre>
|
<pre>
|
||||||
<kbd>s</kbd>: squash down
|
<kbd>s</kbd>: squash down
|
||||||
@@ -76,46 +107,42 @@
|
|||||||
<kbd>C</kbd>: copy commit range (cherry-pick)
|
<kbd>C</kbd>: copy commit range (cherry-pick)
|
||||||
<kbd>v</kbd>: paste commits (cherry-pick)
|
<kbd>v</kbd>: paste commits (cherry-pick)
|
||||||
<kbd>enter</kbd>: view commit's files
|
<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>
|
</pre>
|
||||||
|
|
||||||
## Stash
|
## Commits Panel (Reflog Tab)
|
||||||
|
|
||||||
<pre>
|
<pre>
|
||||||
<kbd>space</kbd>: apply
|
<kbd>space</kbd>: checkout commit
|
||||||
<kbd>g</kbd>: pop
|
<kbd>g</kbd>: view reset options
|
||||||
<kbd>d</kbd>: drop
|
|
||||||
</pre>
|
</pre>
|
||||||
|
|
||||||
## Commit files
|
## Files Panel
|
||||||
|
|
||||||
<pre>
|
<pre>
|
||||||
<kbd>esc</kbd>: go back
|
<kbd>c</kbd>: commit changes
|
||||||
<kbd>c</kbd>: checkout file
|
<kbd>w</kbd>: commit changes without pre-commit hook
|
||||||
<kbd>d</kbd>: discard this commit's changes to this file
|
<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>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
|
||||||
|
<kbd>/</kbd>: start search
|
||||||
</pre>
|
</pre>
|
||||||
|
|
||||||
## Main (Normal)
|
## Main Panel (Merging)
|
||||||
|
|
||||||
<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)
|
|
||||||
|
|
||||||
<pre>
|
<pre>
|
||||||
<kbd>esc</kbd>: return to files panel
|
<kbd>esc</kbd>: return to files panel
|
||||||
@@ -127,3 +154,71 @@
|
|||||||
<kbd>▼</kbd>: select bottom hunk
|
<kbd>▼</kbd>: select bottom hunk
|
||||||
<kbd>z</kbd>: undo
|
<kbd>z</kbd>: undo
|
||||||
</pre>
|
</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>: add/remove line(s) to patch
|
||||||
|
<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>: toggle line staged / unstaged
|
||||||
|
<kbd>d</kbd>: delete change (git reset)
|
||||||
|
<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>
|
||||||
|
|
||||||
|
## Menu Panel
|
||||||
|
|
||||||
|
<pre>
|
||||||
|
<kbd>esc</kbd>: close menu
|
||||||
|
<kbd>q</kbd>: close menu
|
||||||
|
<kbd>/</kbd>: start search
|
||||||
|
</pre>
|
||||||
|
|
||||||
|
## Stash Panel
|
||||||
|
|
||||||
|
<pre>
|
||||||
|
<kbd>space</kbd>: apply
|
||||||
|
<kbd>g</kbd>: pop
|
||||||
|
<kbd>d</kbd>: drop
|
||||||
|
<kbd>/</kbd>: start search
|
||||||
|
</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>
|
||||||
|
|||||||
@@ -1,46 +1,22 @@
|
|||||||
# Lazygit menu
|
# Lazygit Keybindings
|
||||||
|
|
||||||
## Global
|
## Global
|
||||||
|
|
||||||
<pre>
|
<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>m</kbd>: bekijk merge/rebase opties
|
||||||
|
<kbd>ctrl+p</kbd>: view custom patch options
|
||||||
<kbd>P</kbd>: push
|
<kbd>P</kbd>: push
|
||||||
<kbd>p</kbd>: pull
|
<kbd>p</kbd>: pull
|
||||||
<kbd>R</kbd>: verversen
|
<kbd>R</kbd>: verversen
|
||||||
|
<kbd>x</kbd>: open menu
|
||||||
|
<kbd>+</kbd>: next screen mode (normal/half/fullscreen)
|
||||||
|
<kbd>_</kbd>: prev screen mode
|
||||||
|
<kbd>:</kbd>: voor aangepast commando uit
|
||||||
</pre>
|
</pre>
|
||||||
|
|
||||||
## Status
|
## Branches Panel (Branches Tab)
|
||||||
|
|
||||||
<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
|
|
||||||
|
|
||||||
<pre>
|
<pre>
|
||||||
<kbd>space</kbd>: uitchecken
|
<kbd>space</kbd>: uitchecken
|
||||||
@@ -51,10 +27,66 @@
|
|||||||
<kbd>d</kbd>: verwijder branch
|
<kbd>d</kbd>: verwijder branch
|
||||||
<kbd>r</kbd>: rebase branch
|
<kbd>r</kbd>: rebase branch
|
||||||
<kbd>M</kbd>: merge in met huidige checked out 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>f</kbd>: fast-forward this branch from its upstream
|
||||||
|
<kbd>g</kbd>: bekijk reset opties
|
||||||
|
<kbd>R</kbd>: rename branch
|
||||||
|
<kbd>/</kbd>: start search
|
||||||
</pre>
|
</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
|
||||||
|
<kbd>/</kbd>: start search
|
||||||
|
</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
|
||||||
|
<kbd>/</kbd>: start search
|
||||||
|
</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
|
||||||
|
<kbd>/</kbd>: start search
|
||||||
|
</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
|
||||||
|
<kbd>/</kbd>: start search
|
||||||
|
</pre>
|
||||||
|
|
||||||
|
## Commits Panel
|
||||||
|
|
||||||
|
<pre>
|
||||||
|
<kbd>/</kbd>: start search
|
||||||
|
</pre>
|
||||||
|
|
||||||
|
## Commits Panel (Commits Tab)
|
||||||
|
|
||||||
<pre>
|
<pre>
|
||||||
<kbd>s</kbd>: squash beneden
|
<kbd>s</kbd>: squash beneden
|
||||||
@@ -75,39 +107,42 @@
|
|||||||
<kbd>C</kbd>: kopiëer commit reeks (cherry-pick)
|
<kbd>C</kbd>: kopiëer commit reeks (cherry-pick)
|
||||||
<kbd>v</kbd>: plak commits (cherry-pick)
|
<kbd>v</kbd>: plak commits (cherry-pick)
|
||||||
<kbd>enter</kbd>: bekijk gecommite bestanden
|
<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>
|
</pre>
|
||||||
|
|
||||||
## Stash
|
## Commits Panel (Reflog Tab)
|
||||||
|
|
||||||
<pre>
|
<pre>
|
||||||
<kbd>space</kbd>: toepassen
|
<kbd>space</kbd>: checkout commit
|
||||||
<kbd>g</kbd>: pop
|
<kbd>g</kbd>: bekijk reset opties
|
||||||
<kbd>d</kbd>: drop
|
|
||||||
</pre>
|
</pre>
|
||||||
|
|
||||||
## Commit bestanden
|
## Bestanden Panel
|
||||||
|
|
||||||
<pre>
|
<pre>
|
||||||
<kbd>esc</kbd>: ga terug
|
<kbd>c</kbd>: Commit veranderingen
|
||||||
<kbd>c</kbd>: bestand uitchecken
|
<kbd>w</kbd>: commit veranderingen zonder pre-commit hook
|
||||||
<kbd>d</kbd>: uitsluit deze commit zijn veranderingen aan dit bestand
|
<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>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
|
||||||
|
<kbd>/</kbd>: start search
|
||||||
</pre>
|
</pre>
|
||||||
|
|
||||||
## Hoofd (Stage Lines/Hunks)
|
## Hoofd Panel (Merging)
|
||||||
|
|
||||||
<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)
|
|
||||||
|
|
||||||
<pre>
|
<pre>
|
||||||
<kbd>esc</kbd>: ga terug naar het bestanden paneel
|
<kbd>esc</kbd>: ga terug naar het bestanden paneel
|
||||||
@@ -120,9 +155,70 @@
|
|||||||
<kbd>z</kbd>: ongedaan maken
|
<kbd>z</kbd>: ongedaan maken
|
||||||
</pre>
|
</pre>
|
||||||
|
|
||||||
## Hoofd (Normaal)
|
## Hoofd Panel (Normaal)
|
||||||
|
|
||||||
<pre>
|
<pre>
|
||||||
<kbd>PgDn</kbd>: scroll omlaag (fn+up)
|
<kbd> ̄</kbd>: scroll omlaag (fn+up)
|
||||||
<kbd>PgUp</kbd>: scroll omhoog (fn+down)
|
<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>: add/remove line(s) to patch
|
||||||
|
<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>: toggle line staged / unstaged
|
||||||
|
<kbd>d</kbd>: delete change (git reset)
|
||||||
|
<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>
|
||||||
|
|
||||||
|
## Menu Panel
|
||||||
|
|
||||||
|
<pre>
|
||||||
|
<kbd>esc</kbd>: close menu
|
||||||
|
<kbd>q</kbd>: close menu
|
||||||
|
<kbd>/</kbd>: start search
|
||||||
|
</pre>
|
||||||
|
|
||||||
|
## Stash Panel
|
||||||
|
|
||||||
|
<pre>
|
||||||
|
<kbd>space</kbd>: toepassen
|
||||||
|
<kbd>g</kbd>: pop
|
||||||
|
<kbd>d</kbd>: drop
|
||||||
|
<kbd>/</kbd>: start search
|
||||||
|
</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>
|
</pre>
|
||||||
|
|||||||
@@ -1,46 +1,22 @@
|
|||||||
# Lazygit menu
|
# Lazygit Keybindings
|
||||||
|
|
||||||
## Globalne
|
## Globalne
|
||||||
|
|
||||||
<pre>
|
<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>m</kbd>: view merge/rebase options
|
||||||
|
<kbd>ctrl+p</kbd>: view custom patch options
|
||||||
<kbd>P</kbd>: push
|
<kbd>P</kbd>: push
|
||||||
<kbd>p</kbd>: pull
|
<kbd>p</kbd>: pull
|
||||||
<kbd>R</kbd>: odśwież
|
<kbd>R</kbd>: odśwież
|
||||||
|
<kbd>x</kbd>: open menu
|
||||||
|
<kbd>+</kbd>: next screen mode (normal/half/fullscreen)
|
||||||
|
<kbd>_</kbd>: prev screen mode
|
||||||
|
<kbd>:</kbd>: execute custom command
|
||||||
</pre>
|
</pre>
|
||||||
|
|
||||||
## Status
|
## Gałęzie Panel (Branches Tab)
|
||||||
|
|
||||||
<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
|
|
||||||
|
|
||||||
<pre>
|
<pre>
|
||||||
<kbd>space</kbd>: przełącz
|
<kbd>space</kbd>: przełącz
|
||||||
@@ -51,10 +27,66 @@
|
|||||||
<kbd>d</kbd>: usuń gałąź
|
<kbd>d</kbd>: usuń gałąź
|
||||||
<kbd>r</kbd>: rebase branch
|
<kbd>r</kbd>: rebase branch
|
||||||
<kbd>M</kbd>: scal do obecnej gałęzi
|
<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>f</kbd>: fast-forward this branch from its upstream
|
||||||
|
<kbd>g</kbd>: view reset options
|
||||||
|
<kbd>R</kbd>: rename branch
|
||||||
|
<kbd>/</kbd>: start search
|
||||||
</pre>
|
</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
|
||||||
|
<kbd>/</kbd>: start search
|
||||||
|
</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
|
||||||
|
<kbd>/</kbd>: start search
|
||||||
|
</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
|
||||||
|
<kbd>/</kbd>: start search
|
||||||
|
</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
|
||||||
|
<kbd>/</kbd>: start search
|
||||||
|
</pre>
|
||||||
|
|
||||||
|
## Commity Panel
|
||||||
|
|
||||||
|
<pre>
|
||||||
|
<kbd>/</kbd>: start search
|
||||||
|
</pre>
|
||||||
|
|
||||||
|
## Commity Panel (Commits Tab)
|
||||||
|
|
||||||
<pre>
|
<pre>
|
||||||
<kbd>s</kbd>: ściśnij w dół
|
<kbd>s</kbd>: ściśnij w dół
|
||||||
@@ -75,46 +107,42 @@
|
|||||||
<kbd>C</kbd>: copy commit range (cherry-pick)
|
<kbd>C</kbd>: copy commit range (cherry-pick)
|
||||||
<kbd>v</kbd>: paste commits (cherry-pick)
|
<kbd>v</kbd>: paste commits (cherry-pick)
|
||||||
<kbd>enter</kbd>: view commit's files
|
<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>
|
</pre>
|
||||||
|
|
||||||
## Schowek
|
## Commity Panel (Reflog Tab)
|
||||||
|
|
||||||
<pre>
|
<pre>
|
||||||
<kbd>space</kbd>: zastosuj
|
<kbd>space</kbd>: checkout commit
|
||||||
<kbd>g</kbd>: wyciągnij
|
<kbd>g</kbd>: view reset options
|
||||||
<kbd>d</kbd>: porzuć
|
|
||||||
</pre>
|
</pre>
|
||||||
|
|
||||||
## Commit files
|
## Pliki Panel
|
||||||
|
|
||||||
<pre>
|
<pre>
|
||||||
<kbd>esc</kbd>: go back
|
<kbd>c</kbd>: commituj zmiany
|
||||||
<kbd>c</kbd>: checkout file
|
<kbd>w</kbd>: commit changes without pre-commit hook
|
||||||
<kbd>d</kbd>: discard this commit's changes to this file
|
<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>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
|
||||||
|
<kbd>/</kbd>: start search
|
||||||
</pre>
|
</pre>
|
||||||
|
|
||||||
## Main (Normal)
|
## Main Panel (Merging)
|
||||||
|
|
||||||
<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)
|
|
||||||
|
|
||||||
<pre>
|
<pre>
|
||||||
<kbd>esc</kbd>: wróć do panelu plików
|
<kbd>esc</kbd>: wróć do panelu plików
|
||||||
@@ -126,3 +154,71 @@
|
|||||||
<kbd>▼</kbd>: select bottom hunk
|
<kbd>▼</kbd>: select bottom hunk
|
||||||
<kbd>z</kbd>: undo
|
<kbd>z</kbd>: undo
|
||||||
</pre>
|
</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>: add/remove line(s) to patch
|
||||||
|
<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>: toggle line staged / unstaged
|
||||||
|
<kbd>d</kbd>: delete change (git reset)
|
||||||
|
<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>
|
||||||
|
|
||||||
|
## Menu Panel
|
||||||
|
|
||||||
|
<pre>
|
||||||
|
<kbd>esc</kbd>: close menu
|
||||||
|
<kbd>q</kbd>: close menu
|
||||||
|
<kbd>/</kbd>: start search
|
||||||
|
</pre>
|
||||||
|
|
||||||
|
## Schowek Panel
|
||||||
|
|
||||||
|
<pre>
|
||||||
|
<kbd>space</kbd>: zastosuj
|
||||||
|
<kbd>g</kbd>: wyciągnij
|
||||||
|
<kbd>d</kbd>: porzuć
|
||||||
|
<kbd>/</kbd>: start search
|
||||||
|
</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>
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
module github.com/jesseduffield/lazygit
|
module github.com/jesseduffield/lazygit
|
||||||
|
|
||||||
go 1.13
|
go 1.14
|
||||||
|
|
||||||
require (
|
require (
|
||||||
github.com/cloudfoundry/jibber_jabber v0.0.0-20151120183258-bcc4c8345a21
|
github.com/cloudfoundry/jibber_jabber v0.0.0-20151120183258-bcc4c8345a21
|
||||||
@@ -11,9 +11,8 @@ require (
|
|||||||
github.com/golang/protobuf v1.3.2 // indirect
|
github.com/golang/protobuf v1.3.2 // indirect
|
||||||
github.com/google/go-cmp v0.3.1 // indirect
|
github.com/google/go-cmp v0.3.1 // indirect
|
||||||
github.com/integrii/flaggy v1.4.0
|
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.20200309001002-7765949e1c8a
|
||||||
github.com/jesseduffield/pty v1.2.1
|
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/jesseduffield/termbox-go v0.0.0-20200130214842-1d31d1faa3c9 // indirect
|
||||||
github.com/kardianos/osext v0.0.0-20190222173326-2bc1f35cddc0
|
github.com/kardianos/osext v0.0.0-20190222173326-2bc1f35cddc0
|
||||||
github.com/konsorten/go-windows-terminal-sequences v1.0.2 // indirect
|
github.com/konsorten/go-windows-terminal-sequences v1.0.2 // indirect
|
||||||
@@ -21,6 +20,7 @@ require (
|
|||||||
github.com/mattn/go-isatty v0.0.11 // indirect
|
github.com/mattn/go-isatty v0.0.11 // indirect
|
||||||
github.com/mattn/go-runewidth v0.0.8
|
github.com/mattn/go-runewidth v0.0.8
|
||||||
github.com/mgutz/str v1.2.0
|
github.com/mgutz/str v1.2.0
|
||||||
|
github.com/mitchellh/gox v1.0.1 // indirect
|
||||||
github.com/nicksnyder/go-i18n/v2 v2.0.3
|
github.com/nicksnyder/go-i18n/v2 v2.0.3
|
||||||
github.com/onsi/ginkgo v1.10.3 // indirect
|
github.com/onsi/ginkgo v1.10.3 // indirect
|
||||||
github.com/onsi/gomega v1.7.1 // indirect
|
github.com/onsi/gomega v1.7.1 // indirect
|
||||||
|
|||||||
@@ -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/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/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.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.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||||
github.com/golang/protobuf v1.3.2 h1:6nsPYzhq5kReh6QImI3k5qWzO4PEbvbIW2cwSfR/6xs=
|
github.com/golang/protobuf v1.3.2 h1:6nsPYzhq5kReh6QImI3k5qWzO4PEbvbIW2cwSfR/6xs=
|
||||||
github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||||
@@ -69,6 +68,8 @@ github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoA
|
|||||||
github.com/grpc-ecosystem/go-grpc-middleware v1.0.0/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs=
|
github.com/grpc-ecosystem/go-grpc-middleware v1.0.0/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs=
|
||||||
github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk=
|
github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk=
|
||||||
github.com/grpc-ecosystem/grpc-gateway v1.9.0/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY=
|
github.com/grpc-ecosystem/grpc-gateway v1.9.0/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY=
|
||||||
|
github.com/hashicorp/go-version v1.0.0 h1:21MVWPKDphxa7ineQQTrCU5brh7OuVVAzGOCnnCPtE8=
|
||||||
|
github.com/hashicorp/go-version v1.0.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA=
|
||||||
github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4=
|
github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4=
|
||||||
github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ=
|
github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ=
|
||||||
github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI=
|
github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI=
|
||||||
@@ -77,28 +78,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/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 h1:BQSFePA1RWJOlocH6Fxy8MmwDt+yVQYULKfN0RoTN8A=
|
||||||
github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99/go.mod h1:1lJo3i6rXxKeerYnT8Nvf0QmHCRC1n8sfWVwXF2Frvo=
|
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.20200301081700-d6e485450113 h1:jHZRVJUWsU8HaQ0crocz0i0BkpOqFLDJEO/AtBp+Ecs=
|
||||||
github.com/jesseduffield/gocui v0.3.1-0.20191116013947-b13bda319532/go.mod h1:2RtZznzYKt8RLRwvFiSkXjU0Ei8WwHdubgnlaYH47dw=
|
github.com/jesseduffield/gocui v0.3.1-0.20200301081700-d6e485450113/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.20200309001002-7765949e1c8a h1:JSORQue6V4bMppr22dtUuYX+w79cgupo66PcGZ9ijlU=
|
||||||
github.com/jesseduffield/gocui v0.3.1-0.20200112025325-6c933915c351/go.mod h1:2RtZznzYKt8RLRwvFiSkXjU0Ei8WwHdubgnlaYH47dw=
|
github.com/jesseduffield/gocui v0.3.1-0.20200309001002-7765949e1c8a/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/pty v1.2.1 h1:7xYBiwNH0PpWqC8JmvrPq1a/ksNqyCavzWu9pbBGYWI=
|
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/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 h1:iBBk1lhFwjwJw//J2m1yyz9S368GeXQTpMVACTyQMh0=
|
||||||
github.com/jesseduffield/termbox-go v0.0.0-20200130214842-1d31d1faa3c9/go.mod h1:anMibpZtqNxjDbxrcDEAwSdaJ37vyUeM1f/M4uekib4=
|
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=
|
github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI=
|
||||||
@@ -112,7 +97,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/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/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q=
|
||||||
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
|
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.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 h1:DB17ag19krx9CFsz4o3enTrPXyIXCl+2iCXH/aMAp9s=
|
||||||
github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
|
github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
|
||||||
@@ -130,8 +114,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.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 h1:FxPOTFNqGkuDUGi3H/qkUbQO4ZiBa2brKq5r0l8TGeM=
|
||||||
github.com/mattn/go-isatty v0.0.11/go.mod h1:PhnuNfih5lzO57/f3n+odYbM4JtupLOxQOAqxQCu2WE=
|
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 h1:3tS41NlGYSmhhe/8fhGRzc+z3AYCw1Fe1WAyLuujKs0=
|
||||||
github.com/mattn/go-runewidth v0.0.8/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI=
|
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=
|
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
|
||||||
@@ -139,6 +121,10 @@ github.com/mgutz/str v1.2.0 h1:4IzWSdIz9qPQWLfKZ0rJcV0jcUDpxvP4JVZ4GXQyvSw=
|
|||||||
github.com/mgutz/str v1.2.0/go.mod h1:w1v0ofgLaJdoD0HpQ3fycxKD1WtxpjSo151pK/31q6w=
|
github.com/mgutz/str v1.2.0/go.mod h1:w1v0ofgLaJdoD0HpQ3fycxKD1WtxpjSo151pK/31q6w=
|
||||||
github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y=
|
github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y=
|
||||||
github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
|
github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
|
||||||
|
github.com/mitchellh/gox v1.0.1 h1:x0jD3dcHk9a9xPSDN6YEL4xL6Qz0dvNYm8yZqui5chI=
|
||||||
|
github.com/mitchellh/gox v1.0.1/go.mod h1:ED6BioOGXMswlXa2zxfh/xdd5QhwYliBFn9V18Ap4z4=
|
||||||
|
github.com/mitchellh/iochan v1.0.0 h1:C+X3KsSTLFVBr/tK1eYN/vs4rJcvsiLU338UhYPJWeY=
|
||||||
|
github.com/mitchellh/iochan v1.0.0/go.mod h1:JwYml1nuB7xOzsp52dPpHFffvOCDupsG0QubkSMEySY=
|
||||||
github.com/mitchellh/mapstructure v1.1.2 h1:fmNYVwqnSfB9mZU6OS2O6GsXM+wcskZDuKQzvN1EDeE=
|
github.com/mitchellh/mapstructure v1.1.2 h1:fmNYVwqnSfB9mZU6OS2O6GsXM+wcskZDuKQzvN1EDeE=
|
||||||
github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
|
github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
|
||||||
github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
|
github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
|
||||||
@@ -151,7 +137,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 h1:K0jcRCwNQM3vFGh1ppMtDh/+7ApJrjldlX8fA0jDTLQ=
|
||||||
github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY=
|
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-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.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 h1:aetoXYr0Tv7xRU/V4B4IZJ2QcbtMUFoNb3ORp7TzIK4=
|
||||||
github.com/pelletier/go-toml v1.6.0/go.mod h1:5N711Q9dKgbdkxHL+MEfF31hpT7l0S0s/t2kKREewys=
|
github.com/pelletier/go-toml v1.6.0/go.mod h1:5N711Q9dKgbdkxHL+MEfF31hpT7l0S0s/t2kKREewys=
|
||||||
@@ -175,7 +160,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 h1:Xuk8ma/ibJ1fOy4Ee11vHhUFHQNpHhrBneOCNHVXS5w=
|
||||||
github.com/shibukawa/configdir v0.0.0-20170330084843-e180dbdc8da0/go.mod h1:7AwjWCpdPhkSmNAgUv5C7EJ4AbmjEB3r047r3DXWu3Y=
|
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.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 h1:SPIRibHv4MatM3XXNO2BJeFLZwZ2LvZgfQ5+UNI2im4=
|
||||||
github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
|
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=
|
github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d h1:zE9ykElWQ6/NYmHa3jpm/yHnI4xSofP+UP6SpjHcSeM=
|
||||||
@@ -184,17 +168,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/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/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/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.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ=
|
||||||
github.com/spf13/afero v1.2.2 h1:5jhuqJyZCZf2JRofRvN/nIFgIWNzPa3/Vz8mYylgbWc=
|
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/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 h1:oget//CVOEoFewqQxwr0Ej5yjygnqGkvggSE/gB35Q8=
|
||||||
github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE=
|
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.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo=
|
||||||
github.com/spf13/jwalterweatherman v1.1.0 h1:ue6voC5bR5F8YxI5S67j9i582FU4Qvo2bmqnqMYADFk=
|
github.com/spf13/jwalterweatherman v1.1.0 h1:ue6voC5bR5F8YxI5S67j9i582FU4Qvo2bmqnqMYADFk=
|
||||||
github.com/spf13/jwalterweatherman v1.1.0/go.mod h1:aNWZUN0dPAAO/Ljvb5BEdw96iTZ0EXowPYD95IqWIGo=
|
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.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 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
|
||||||
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
|
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
|
||||||
@@ -229,7 +210,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-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-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-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-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 h1:ULYEB3JvPRE/IfO+9uO7vKV/xzVTO7XPAwm8xbf4w2g=
|
||||||
golang.org/x/crypto v0.0.0-20191206172530-e9b2fee46413/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
golang.org/x/crypto v0.0.0-20191206172530-e9b2fee46413/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||||
@@ -244,7 +224,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-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-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-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-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 h1:efeOvDhwQ29Dj3SdAV/MJf8oukgn+8D8WgaCaRMchF8=
|
||||||
golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||||
@@ -264,7 +243,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-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-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-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-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-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20191210023423-ac6580df4449 h1:gSbV7h1NRL2G1xTg/owz62CST1oJBmxy4QpMMregXVQ=
|
golang.org/x/sys v0.0.0-20191210023423-ac6580df4449 h1:gSbV7h1NRL2G1xTg/owz62CST1oJBmxy4QpMMregXVQ=
|
||||||
@@ -286,7 +264,6 @@ google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZi
|
|||||||
google.golang.org/grpc v1.21.0/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM=
|
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/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 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-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 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo=
|
||||||
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||||
|
|||||||
@@ -4,7 +4,6 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"log"
|
"log"
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
|
||||||
"runtime"
|
"runtime"
|
||||||
|
|
||||||
"github.com/go-errors/errors"
|
"github.com/go-errors/errors"
|
||||||
@@ -20,11 +19,6 @@ var (
|
|||||||
buildSource = "unknown"
|
buildSource = "unknown"
|
||||||
)
|
)
|
||||||
|
|
||||||
func projectPath(path string) string {
|
|
||||||
gopath := os.Getenv("GOPATH")
|
|
||||||
return filepath.FromSlash(gopath + "/src/github.com/jesseduffield/lazygit/" + path)
|
|
||||||
}
|
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
flaggy.DefaultParser.ShowVersionWithVersionFlag = false
|
flaggy.DefaultParser.ShowVersionWithVersionFlag = false
|
||||||
|
|
||||||
|
|||||||
@@ -3,8 +3,10 @@ package commands
|
|||||||
// Branch : A git branch
|
// Branch : A git branch
|
||||||
// duplicating this for now
|
// duplicating this for now
|
||||||
type Branch struct {
|
type Branch struct {
|
||||||
Name string
|
Name string
|
||||||
Recency string
|
Recency string
|
||||||
Pushables string
|
Pushables string
|
||||||
Pullables string
|
Pullables string
|
||||||
|
UpstreamName string
|
||||||
|
Head bool
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,8 +7,6 @@ import (
|
|||||||
"github.com/jesseduffield/lazygit/pkg/utils"
|
"github.com/jesseduffield/lazygit/pkg/utils"
|
||||||
|
|
||||||
"github.com/sirupsen/logrus"
|
"github.com/sirupsen/logrus"
|
||||||
|
|
||||||
"gopkg.in/src-d/go-git.v4/plumbing"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// context:
|
// context:
|
||||||
@@ -36,113 +34,105 @@ func NewBranchListBuilder(log *logrus.Entry, gitCommand *GitCommand) (*BranchLis
|
|||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b *BranchListBuilder) obtainCurrentBranch() *Branch {
|
func (b *BranchListBuilder) obtainCurrentBranchName() string {
|
||||||
branchName, err := b.GitCommand.CurrentBranchName()
|
branchName, err := b.GitCommand.CurrentBranchName()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err.Error())
|
panic(err.Error())
|
||||||
}
|
}
|
||||||
|
return branchName
|
||||||
return &Branch{Name: strings.TrimSpace(branchName)}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b *BranchListBuilder) obtainReflogBranches() []*Branch {
|
func (b *BranchListBuilder) obtainBranches() []*Branch {
|
||||||
branches := make([]*Branch, 0)
|
cmdStr := `git branch --format="%(HEAD)|%(refname:short)|%(upstream:short)|%(upstream:track)"`
|
||||||
// if we directly put this string in RunCommandWithOutput the compiler complains because it thinks it's a format string
|
output, err := b.GitCommand.OSCommand.RunCommandWithOutput(cmdStr)
|
||||||
unescaped := "git reflog --date=relative --pretty='%gd|%gs' --grep-reflog='checkout: moving' HEAD"
|
|
||||||
rawString, err := b.GitCommand.OSCommand.RunCommandWithOutput(unescaped)
|
|
||||||
if err != nil {
|
|
||||||
return branches
|
|
||||||
}
|
|
||||||
|
|
||||||
branchLines := utils.SplitLines(rawString)
|
|
||||||
for _, line := range branchLines {
|
|
||||||
recency, branchName := branchInfoFromLine(line)
|
|
||||||
if branchName == "" {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
branch := &Branch{Name: branchName, Recency: recency}
|
|
||||||
branches = append(branches, branch)
|
|
||||||
}
|
|
||||||
return uniqueByName(branches)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (b *BranchListBuilder) obtainSafeBranches() []*Branch {
|
|
||||||
branches := make([]*Branch, 0)
|
|
||||||
|
|
||||||
bIter, err := b.GitCommand.Repo.Branches()
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
bIter.ForEach(func(b *plumbing.Reference) error {
|
|
||||||
name := b.Name().Short()
|
trimmedOutput := strings.TrimSpace(output)
|
||||||
branches = append(branches, &Branch{Name: name})
|
outputLines := strings.Split(trimmedOutput, "\n")
|
||||||
return nil
|
branches := make([]*Branch, len(outputLines))
|
||||||
})
|
for i, line := range outputLines {
|
||||||
|
split := strings.Split(line, SEPARATION_CHAR)
|
||||||
|
|
||||||
|
name := split[1]
|
||||||
|
branches[i] = &Branch{
|
||||||
|
Name: name,
|
||||||
|
Pullables: "?",
|
||||||
|
Pushables: "?",
|
||||||
|
Head: split[0] == "*",
|
||||||
|
}
|
||||||
|
upstreamName := split[2]
|
||||||
|
if upstreamName == "" {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
branches[i].UpstreamName = upstreamName
|
||||||
|
|
||||||
|
track := split[3]
|
||||||
|
re := regexp.MustCompile(`ahead (\d+)`)
|
||||||
|
match := re.FindStringSubmatch(track)
|
||||||
|
if len(match) > 1 {
|
||||||
|
branches[i].Pushables = match[1]
|
||||||
|
} else {
|
||||||
|
branches[i].Pushables = "0"
|
||||||
|
}
|
||||||
|
|
||||||
|
re = regexp.MustCompile(`behind (\d+)`)
|
||||||
|
match = re.FindStringSubmatch(track)
|
||||||
|
if len(match) > 1 {
|
||||||
|
branches[i].Pullables = match[1]
|
||||||
|
} else {
|
||||||
|
branches[i].Pullables = "0"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return branches
|
return branches
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b *BranchListBuilder) appendNewBranches(finalBranches, newBranches, existingBranches []*Branch, included bool) []*Branch {
|
|
||||||
for _, newBranch := range newBranches {
|
|
||||||
if included == branchIncluded(newBranch.Name, existingBranches) {
|
|
||||||
finalBranches = append(finalBranches, newBranch)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return finalBranches
|
|
||||||
}
|
|
||||||
|
|
||||||
func sanitisedReflogName(reflogBranch *Branch, safeBranches []*Branch) string {
|
|
||||||
for _, safeBranch := range safeBranches {
|
|
||||||
if strings.ToLower(safeBranch.Name) == strings.ToLower(reflogBranch.Name) {
|
|
||||||
return safeBranch.Name
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return reflogBranch.Name
|
|
||||||
}
|
|
||||||
|
|
||||||
// Build the list of branches for the current repo
|
// Build the list of branches for the current repo
|
||||||
func (b *BranchListBuilder) Build() []*Branch {
|
func (b *BranchListBuilder) Build() []*Branch {
|
||||||
branches := make([]*Branch, 0)
|
currentBranchName := b.obtainCurrentBranchName()
|
||||||
head := b.obtainCurrentBranch()
|
branches := b.obtainBranches()
|
||||||
safeBranches := b.obtainSafeBranches()
|
|
||||||
|
|
||||||
reflogBranches := b.obtainReflogBranches()
|
reflogBranches := b.obtainReflogBranches()
|
||||||
for i, reflogBranch := range reflogBranches {
|
|
||||||
reflogBranches[i].Name = sanitisedReflogName(reflogBranch, safeBranches)
|
// loop through reflog branches. If there is a match, merge them, then remove it from the branches and keep it in the reflog branches
|
||||||
|
branchesWithRecency := make([]*Branch, 0)
|
||||||
|
outer:
|
||||||
|
for _, reflogBranch := range reflogBranches {
|
||||||
|
for j, branch := range branches {
|
||||||
|
if branch.Head {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if strings.EqualFold(reflogBranch.Name, branch.Name) {
|
||||||
|
branch.Recency = reflogBranch.Recency
|
||||||
|
branchesWithRecency = append(branchesWithRecency, branch)
|
||||||
|
branches = append(branches[0:j], branches[j+1:]...)
|
||||||
|
continue outer
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
branches = b.appendNewBranches(branches, reflogBranches, safeBranches, true)
|
branches = append(branchesWithRecency, branches...)
|
||||||
branches = b.appendNewBranches(branches, safeBranches, branches, false)
|
|
||||||
|
|
||||||
if len(branches) == 0 || branches[0].Name != head.Name {
|
if len(branches) == 0 {
|
||||||
branches = append([]*Branch{head}, branches...)
|
branches = append([]*Branch{{Name: currentBranchName}}, branches...)
|
||||||
}
|
}
|
||||||
|
|
||||||
branches[0].Recency = " *"
|
for i, branch := range branches {
|
||||||
|
if branch.Head {
|
||||||
|
branch.Name = currentBranchName
|
||||||
|
branch.Recency = " *"
|
||||||
|
branches = append(branches[0:i], branches[i+1:]...)
|
||||||
|
branches = append([]*Branch{branch}, branches...)
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return branches
|
return branches
|
||||||
}
|
}
|
||||||
|
|
||||||
func branchIncluded(branchName string, branches []*Branch) bool {
|
|
||||||
for _, existingBranch := range branches {
|
|
||||||
if strings.ToLower(existingBranch.Name) == strings.ToLower(branchName) {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
func uniqueByName(branches []*Branch) []*Branch {
|
|
||||||
finalBranches := make([]*Branch, 0)
|
|
||||||
for _, branch := range branches {
|
|
||||||
if branchIncluded(branch.Name, finalBranches) {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
finalBranches = append(finalBranches, branch)
|
|
||||||
}
|
|
||||||
return finalBranches
|
|
||||||
}
|
|
||||||
|
|
||||||
// A line will have the form '10 days ago master' so we need to strip out the
|
// A line will have the form '10 days ago master' so we need to strip out the
|
||||||
// useful information from that into timeNumber, timeUnit, and branchName
|
// useful information from that into timeNumber, timeUnit, and branchName
|
||||||
func branchInfoFromLine(line string) (string, string) {
|
func branchInfoFromLine(line string) (string, string) {
|
||||||
@@ -172,3 +162,30 @@ func abbreviatedTimeUnit(timeUnit string) string {
|
|||||||
}
|
}
|
||||||
return timeUnitMap[timeUnit]
|
return timeUnitMap[timeUnit]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (b *BranchListBuilder) obtainReflogBranches() []*Branch {
|
||||||
|
branches := make([]*Branch, 0)
|
||||||
|
// if we directly put this string in RunCommandWithOutput the compiler complains because it thinks it's a format string
|
||||||
|
unescaped := "git reflog --date=relative --pretty='%gd|%gs' --grep-reflog='checkout: moving' HEAD"
|
||||||
|
rawString, err := b.GitCommand.OSCommand.RunCommandWithOutput(unescaped)
|
||||||
|
if err != nil {
|
||||||
|
return branches
|
||||||
|
}
|
||||||
|
|
||||||
|
branchNameMap := map[string]bool{}
|
||||||
|
|
||||||
|
branchLines := utils.SplitLines(rawString)
|
||||||
|
for _, line := range branchLines {
|
||||||
|
recency, branchName := branchInfoFromLine(line)
|
||||||
|
if branchName == "" {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if _, ok := branchNameMap[branchName]; ok {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
branchNameMap[branchName] = true
|
||||||
|
branch := &Branch{Name: branchName, Recency: recency}
|
||||||
|
branches = append(branches, branch)
|
||||||
|
}
|
||||||
|
return branches
|
||||||
|
}
|
||||||
|
|||||||
@@ -105,7 +105,7 @@ func (c *CommitListBuilder) GetCommits(limit bool) ([]*Commit, error) {
|
|||||||
// now we can split it up and turn it into commits
|
// now we can split it up and turn it into commits
|
||||||
for _, line := range utils.SplitLines(log) {
|
for _, line := range utils.SplitLines(log) {
|
||||||
commit := c.extractCommitFromLine(line)
|
commit := c.extractCommitFromLine(line)
|
||||||
_, unpushed := unpushedCommits[commit.Sha]
|
_, unpushed := unpushedCommits[commit.Sha[:8]]
|
||||||
commit.Status = map[bool]string{true: "unpushed", false: "pushed"}[unpushed]
|
commit.Status = map[bool]string{true: "unpushed", false: "pushed"}[unpushed]
|
||||||
commits = append(commits, commit)
|
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
|
// to the remote branch of the current branch, a map is returned to ease look up
|
||||||
func (c *CommitListBuilder) getUnpushedCommits() map[string]bool {
|
func (c *CommitListBuilder) getUnpushedCommits() map[string]bool {
|
||||||
pushables := 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 {
|
if err != nil {
|
||||||
return pushables
|
return pushables
|
||||||
}
|
}
|
||||||
|
|||||||
+53
-14
@@ -7,6 +7,7 @@ import (
|
|||||||
"os/exec"
|
"os/exec"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"regexp"
|
"regexp"
|
||||||
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
@@ -177,7 +178,7 @@ func stashEntryFromLine(line string, index int) *StashEntry {
|
|||||||
|
|
||||||
// GetStashEntryDiff stash diff
|
// GetStashEntryDiff stash diff
|
||||||
func (c *GitCommand) ShowStashEntryCmdStr(index int) string {
|
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
|
// GetStatusFiles git status files
|
||||||
@@ -326,8 +327,8 @@ func (c *GitCommand) ResetToCommit(sha string, strength string) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// NewBranch create new branch
|
// NewBranch create new branch
|
||||||
func (c *GitCommand) NewBranch(name string) error {
|
func (c *GitCommand) NewBranch(name string, baseBranch string) error {
|
||||||
return c.OSCommand.RunCommand("git checkout -b %s", name)
|
return c.OSCommand.RunCommand("git checkout -b %s %s", name, baseBranch)
|
||||||
}
|
}
|
||||||
|
|
||||||
// CurrentBranchName is a function.
|
// CurrentBranchName is a function.
|
||||||
@@ -342,7 +343,7 @@ func (c *GitCommand) CurrentBranchName() (string, error) {
|
|||||||
match := re.FindStringSubmatch(output)
|
match := re.FindStringSubmatch(output)
|
||||||
branchName = match[1]
|
branchName = match[1]
|
||||||
}
|
}
|
||||||
return utils.TrimTrailingNewline(branchName), nil
|
return strings.TrimSpace(branchName), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// DeleteBranch delete branch
|
// DeleteBranch delete branch
|
||||||
@@ -558,11 +559,11 @@ func (c *GitCommand) Ignore(filename string) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (c *GitCommand) ShowCmdStr(sha string) string {
|
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 {
|
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
|
// 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 {
|
func (c *GitCommand) DiffCmdStr(file *File, plain bool, cached bool) string {
|
||||||
cachedArg := ""
|
cachedArg := ""
|
||||||
trackedArg := "--"
|
trackedArg := "--"
|
||||||
colorArg := "--color"
|
colorArg := c.colorArg()
|
||||||
split := strings.Split(file.Name, " -> ") // in case of a renamed file we get the new filename
|
split := strings.Split(file.Name, " -> ") // in case of a renamed file we get the new filename
|
||||||
fileName := c.OSCommand.Quote(split[len(split)-1])
|
fileName := c.OSCommand.Quote(split[len(split)-1])
|
||||||
if cached {
|
if cached {
|
||||||
@@ -601,10 +602,10 @@ func (c *GitCommand) DiffCmdStr(file *File, plain bool, cached bool) string {
|
|||||||
trackedArg = "--no-index /dev/null"
|
trackedArg = "--no-index /dev/null"
|
||||||
}
|
}
|
||||||
if plain {
|
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 {
|
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 {
|
func (c *GitCommand) ShowCommitFileCmdStr(commitSha, fileName string, plain bool) string {
|
||||||
colorArg := "--color"
|
colorArg := c.colorArg()
|
||||||
if plain {
|
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
|
// 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
|
// DiffCommits show diff between commits
|
||||||
func (c *GitCommand) DiffCommits(sha1, sha2 string) (string, error) {
|
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
|
// 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+\}: (.*)`)
|
re := regexp.MustCompile(`(\w+).*HEAD@\{\d+\}: (.*)`)
|
||||||
for i, line := range lines {
|
for i, line := range lines {
|
||||||
match := re.FindStringSubmatch(line)
|
match := re.FindStringSubmatch(line)
|
||||||
if len(match) == 1 {
|
if len(match) <= 1 {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1128,3 +1129,41 @@ func (c *GitCommand) GetReflogCommits() ([]*Commit, error) {
|
|||||||
|
|
||||||
return commits, nil
|
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")
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *GitCommand) RenameBranch(oldName string, newName string) error {
|
||||||
|
return c.OSCommand.RunCommand("git branch --move %s %s", oldName, newName)
|
||||||
|
}
|
||||||
|
|||||||
@@ -636,12 +636,12 @@ func TestGitCommandNewBranch(t *testing.T) {
|
|||||||
gitCmd := NewDummyGitCommand()
|
gitCmd := NewDummyGitCommand()
|
||||||
gitCmd.OSCommand.command = func(cmd string, args ...string) *exec.Cmd {
|
gitCmd.OSCommand.command = func(cmd string, args ...string) *exec.Cmd {
|
||||||
assert.EqualValues(t, "git", cmd)
|
assert.EqualValues(t, "git", cmd)
|
||||||
assert.EqualValues(t, []string{"checkout", "-b", "test"}, args)
|
assert.EqualValues(t, []string{"checkout", "-b", "test", "master"}, args)
|
||||||
|
|
||||||
return exec.Command("echo")
|
return exec.Command("echo")
|
||||||
}
|
}
|
||||||
|
|
||||||
assert.NoError(t, gitCmd.NewBranch("test"))
|
assert.NoError(t, gitCmd.NewBranch("test", "master"))
|
||||||
}
|
}
|
||||||
|
|
||||||
// TestGitCommandDeleteBranch is a function.
|
// TestGitCommandDeleteBranch is a function.
|
||||||
@@ -1449,7 +1449,7 @@ func TestGitCommandGetBranchGraph(t *testing.T) {
|
|||||||
gitCmd := NewDummyGitCommand()
|
gitCmd := NewDummyGitCommand()
|
||||||
gitCmd.OSCommand.command = func(cmd string, args ...string) *exec.Cmd {
|
gitCmd.OSCommand.command = func(cmd string, args ...string) *exec.Cmd {
|
||||||
assert.EqualValues(t, "git", 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")
|
return exec.Command("echo")
|
||||||
}
|
}
|
||||||
@@ -1473,7 +1473,7 @@ func TestGitCommandDiff(t *testing.T) {
|
|||||||
"Default case",
|
"Default case",
|
||||||
func(cmd string, args ...string) *exec.Cmd {
|
func(cmd string, args ...string) *exec.Cmd {
|
||||||
assert.EqualValues(t, "git", 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")
|
return exec.Command("echo")
|
||||||
},
|
},
|
||||||
@@ -1489,7 +1489,7 @@ func TestGitCommandDiff(t *testing.T) {
|
|||||||
"cached",
|
"cached",
|
||||||
func(cmd string, args ...string) *exec.Cmd {
|
func(cmd string, args ...string) *exec.Cmd {
|
||||||
assert.EqualValues(t, "git", 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")
|
return exec.Command("echo")
|
||||||
},
|
},
|
||||||
@@ -1505,7 +1505,7 @@ func TestGitCommandDiff(t *testing.T) {
|
|||||||
"plain",
|
"plain",
|
||||||
func(cmd string, args ...string) *exec.Cmd {
|
func(cmd string, args ...string) *exec.Cmd {
|
||||||
assert.EqualValues(t, "git", 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")
|
return exec.Command("echo")
|
||||||
},
|
},
|
||||||
@@ -1521,7 +1521,7 @@ func TestGitCommandDiff(t *testing.T) {
|
|||||||
"File not tracked and file has no staged changes",
|
"File not tracked and file has no staged changes",
|
||||||
func(cmd string, args ...string) *exec.Cmd {
|
func(cmd string, args ...string) *exec.Cmd {
|
||||||
assert.EqualValues(t, "git", 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")
|
return exec.Command("echo")
|
||||||
},
|
},
|
||||||
@@ -1871,7 +1871,7 @@ func TestGitCommandShowCommitFile(t *testing.T) {
|
|||||||
"hello.txt",
|
"hello.txt",
|
||||||
test.CreateMockCommand(t, []*test.CommandSwapper{
|
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",
|
Replace: "echo -n hello",
|
||||||
},
|
},
|
||||||
}),
|
}),
|
||||||
@@ -2130,7 +2130,7 @@ func TestGitCommandSkipEditorCommand(t *testing.T) {
|
|||||||
)
|
)
|
||||||
})
|
})
|
||||||
|
|
||||||
cmd.RunSkipEditorCommand("true")
|
_ = cmd.RunSkipEditorCommand("true")
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestFindDotGitDir(t *testing.T) {
|
func TestFindDotGitDir(t *testing.T) {
|
||||||
|
|||||||
@@ -401,3 +401,11 @@ func (c *OSCommand) PipeCommands(commandStrings ...string) error {
|
|||||||
}
|
}
|
||||||
return nil
|
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()
|
||||||
|
}
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/go-errors/errors"
|
"github.com/go-errors/errors"
|
||||||
|
"github.com/jesseduffield/lazygit/pkg/config"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Service is a service that repository is on (Github, Bitbucket, ...)
|
// Service is a service that repository is on (Github, Bitbucket, ...)
|
||||||
@@ -26,27 +27,63 @@ type RepoInformation struct {
|
|||||||
Repository string
|
Repository string
|
||||||
}
|
}
|
||||||
|
|
||||||
func getServices() []*Service {
|
// NewService builds a Service based on the host type
|
||||||
return []*Service{
|
func NewService(typeName string, repositoryDomain string, siteDomain string) *Service {
|
||||||
{
|
var service *Service
|
||||||
Name: "github.com",
|
|
||||||
PullRequestURL: "https://github.com/%s/%s/compare/%s?expand=1",
|
switch typeName {
|
||||||
},
|
case "github":
|
||||||
{
|
service = &Service{
|
||||||
Name: "bitbucket.org",
|
Name: repositoryDomain,
|
||||||
PullRequestURL: "https://bitbucket.org/%s/%s/pull-requests/new?source=%s&t=1",
|
PullRequestURL: fmt.Sprintf("https://%s%s", siteDomain, "/%s/%s/compare/%s?expand=1"),
|
||||||
},
|
}
|
||||||
{
|
case "bitbucket":
|
||||||
Name: "gitlab.com",
|
service = &Service{
|
||||||
PullRequestURL: "https://gitlab.com/%s/%s/merge_requests/new?merge_request[source_branch]=%s",
|
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
|
// NewPullRequest creates new instance of PullRequest
|
||||||
func NewPullRequest(gitCommand *GitCommand) *PullRequest {
|
func NewPullRequest(gitCommand *GitCommand) *PullRequest {
|
||||||
return &PullRequest{
|
return &PullRequest{
|
||||||
GitServices: getServices(),
|
GitServices: getServices(gitCommand.Config),
|
||||||
GitCommand: gitCommand,
|
GitCommand: gitCommand,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -85,7 +122,7 @@ func getRepoInfoFromURL(url string) *RepoInformation {
|
|||||||
|
|
||||||
if isHTTP {
|
if isHTTP {
|
||||||
splits := strings.Split(url, "/")
|
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")
|
repo := strings.TrimSuffix(splits[len(splits)-1], ".git")
|
||||||
|
|
||||||
return &RepoInformation{
|
return &RepoInformation{
|
||||||
@@ -96,8 +133,8 @@ func getRepoInfoFromURL(url string) *RepoInformation {
|
|||||||
|
|
||||||
tmpSplit := strings.Split(url, ":")
|
tmpSplit := strings.Split(url, ":")
|
||||||
splits := strings.Split(tmpSplit[1], "/")
|
splits := strings.Split(tmpSplit[1], "/")
|
||||||
owner := splits[0]
|
owner := strings.Join(splits[0:len(splits)-1], "/")
|
||||||
repo := strings.TrimSuffix(splits[1], ".git")
|
repo := strings.TrimSuffix(splits[len(splits)-1], ".git")
|
||||||
|
|
||||||
return &RepoInformation{
|
return &RepoInformation{
|
||||||
Owner: owner,
|
Owner: owner,
|
||||||
|
|||||||
@@ -147,6 +147,13 @@ func TestCreatePullRequest(t *testing.T) {
|
|||||||
gitCommand := NewDummyGitCommand()
|
gitCommand := NewDummyGitCommand()
|
||||||
gitCommand.OSCommand.command = s.command
|
gitCommand.OSCommand.command = s.command
|
||||||
gitCommand.OSCommand.Config.GetUserConfig().Set("os.openLinkCommand", "open {{link}}")
|
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)
|
dummyPullRequest := NewPullRequest(gitCommand)
|
||||||
s.test(dummyPullRequest.Create(s.branch))
|
s.test(dummyPullRequest.Create(s.branch))
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -244,6 +244,7 @@ func GetDefaultConfig() []byte {
|
|||||||
scrollPastBottom: true
|
scrollPastBottom: true
|
||||||
mouseEvents: true
|
mouseEvents: true
|
||||||
skipUnstageLineWarning: false
|
skipUnstageLineWarning: false
|
||||||
|
sidePanelWidth: 0.3333
|
||||||
theme:
|
theme:
|
||||||
lightTheme: false
|
lightTheme: false
|
||||||
activeBorderColor:
|
activeBorderColor:
|
||||||
@@ -258,6 +259,9 @@ func GetDefaultConfig() []byte {
|
|||||||
commitLength:
|
commitLength:
|
||||||
show: true
|
show: true
|
||||||
git:
|
git:
|
||||||
|
paging:
|
||||||
|
colorArg: always
|
||||||
|
useConfig: false
|
||||||
merging:
|
merging:
|
||||||
manualCommit: false
|
manualCommit: false
|
||||||
skipHookPrefix: 'WIP'
|
skipHookPrefix: 'WIP'
|
||||||
@@ -330,6 +334,7 @@ keybinding:
|
|||||||
checkoutBranchByName: 'c'
|
checkoutBranchByName: 'c'
|
||||||
forceCheckoutBranch: 'F'
|
forceCheckoutBranch: 'F'
|
||||||
rebaseBranch: 'r'
|
rebaseBranch: 'r'
|
||||||
|
renameBranch: 'R'
|
||||||
mergeIntoCurrentBranch: 'M'
|
mergeIntoCurrentBranch: 'M'
|
||||||
viewGitFlowOptions: 'i'
|
viewGitFlowOptions: 'i'
|
||||||
fastForward: 'f'
|
fastForward: 'f'
|
||||||
@@ -355,6 +360,7 @@ keybinding:
|
|||||||
tagCommit: 'T'
|
tagCommit: 'T'
|
||||||
toggleDiffCommit: 'i'
|
toggleDiffCommit: 'i'
|
||||||
checkoutCommit: '<space>'
|
checkoutCommit: '<space>'
|
||||||
|
resetCherryPick: '<c-R>'
|
||||||
stash:
|
stash:
|
||||||
popStash: 'g'
|
popStash: 'g'
|
||||||
commitFiles:
|
commitFiles:
|
||||||
|
|||||||
@@ -66,9 +66,7 @@ func (gui *Gui) WithWaitingStatus(name string, f func() error) error {
|
|||||||
if appStatus == "" {
|
if appStatus == "" {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if err := gui.renderString(gui.g, "appStatus", appStatus); err != nil {
|
gui.renderString(gui.g, "appStatus", appStatus)
|
||||||
gui.Log.Warn(err)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
|
||||||
|
|||||||
+63
-42
@@ -40,12 +40,7 @@ func (gui *Gui) handleBranchSelect(g *gocui.Gui, v *gocui.View) error {
|
|||||||
return gui.newStringTask("main", gui.Tr.SLocalize("NoBranchesThisRepo"))
|
return gui.newStringTask("main", gui.Tr.SLocalize("NoBranchesThisRepo"))
|
||||||
}
|
}
|
||||||
branch := gui.getSelectedBranch()
|
branch := gui.getSelectedBranch()
|
||||||
if err := gui.focusPoint(0, gui.State.Panels.Branches.SelectedLine, len(gui.State.Branches), v); err != nil {
|
v.FocusPoint(0, gui.State.Panels.Branches.SelectedLine)
|
||||||
return err
|
|
||||||
}
|
|
||||||
if err := gui.RenderSelectedBranchUpstreamDifferences(); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
cmd := gui.OSCommand.ExecutableFromString(
|
cmd := gui.OSCommand.ExecutableFromString(
|
||||||
gui.GitCommand.GetBranchGraphCmdStr(branch.Name),
|
gui.GitCommand.GetBranchGraphCmdStr(branch.Name),
|
||||||
@@ -56,24 +51,6 @@ func (gui *Gui) handleBranchSelect(g *gocui.Gui, v *gocui.View) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (gui *Gui) RenderSelectedBranchUpstreamDifferences() error {
|
|
||||||
return gui.newTask("branches", func(stop chan struct{}) error {
|
|
||||||
branch := gui.getSelectedBranch()
|
|
||||||
branch.Pushables, branch.Pullables = gui.GitCommand.GetBranchUpstreamDifferenceCount(branch.Name)
|
|
||||||
|
|
||||||
select {
|
|
||||||
case <-stop:
|
|
||||||
return nil
|
|
||||||
default:
|
|
||||||
}
|
|
||||||
|
|
||||||
branchesView := gui.getBranchesView()
|
|
||||||
displayStrings := presentation.GetBranchListDisplayStrings(gui.State.Branches, gui.currentViewName() == "branches", gui.State.Panels.Branches.SelectedLine)
|
|
||||||
gui.renderDisplayStrings(branchesView, displayStrings)
|
|
||||||
return nil
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// gui.refreshStatus is called at the end of this because that's when we can
|
// gui.refreshStatus is called at the end of this because that's when we can
|
||||||
// be sure there is a state.Branches array to pick the current branch from
|
// be sure there is a state.Branches array to pick the current branch from
|
||||||
func (gui *Gui) refreshBranches(g *gocui.Gui) error {
|
func (gui *Gui) refreshBranches(g *gocui.Gui) error {
|
||||||
@@ -108,9 +85,8 @@ func (gui *Gui) renderLocalBranchesWithSelection() error {
|
|||||||
branchesView := gui.getBranchesView()
|
branchesView := gui.getBranchesView()
|
||||||
|
|
||||||
gui.refreshSelectedLine(&gui.State.Panels.Branches.SelectedLine, len(gui.State.Branches))
|
gui.refreshSelectedLine(&gui.State.Panels.Branches.SelectedLine, len(gui.State.Branches))
|
||||||
if err := gui.RenderSelectedBranchUpstreamDifferences(); err != nil {
|
displayStrings := presentation.GetBranchListDisplayStrings(gui.State.Branches, gui.State.ScreenMode != SCREEN_NORMAL)
|
||||||
return err
|
gui.renderDisplayStrings(branchesView, displayStrings)
|
||||||
}
|
|
||||||
if gui.g.CurrentView() == branchesView {
|
if gui.g.CurrentView() == branchesView {
|
||||||
if err := gui.handleBranchSelect(gui.g, branchesView); err != nil {
|
if err := gui.handleBranchSelect(gui.g, branchesView); err != nil {
|
||||||
return err
|
return err
|
||||||
@@ -161,7 +137,7 @@ func (gui *Gui) handleForceCheckout(g *gocui.Gui, v *gocui.View) error {
|
|||||||
title := gui.Tr.SLocalize("ForceCheckoutBranch")
|
title := gui.Tr.SLocalize("ForceCheckoutBranch")
|
||||||
return gui.createConfirmationPanel(g, v, true, title, message, func(g *gocui.Gui, v *gocui.View) error {
|
return gui.createConfirmationPanel(g, v, true, title, message, func(g *gocui.Gui, v *gocui.View) error {
|
||||||
if err := gui.GitCommand.Checkout(branch.Name, true); err != nil {
|
if err := gui.GitCommand.Checkout(branch.Name, true); err != nil {
|
||||||
gui.createErrorPanel(g, err.Error())
|
_ = gui.createErrorPanel(g, err.Error())
|
||||||
}
|
}
|
||||||
return gui.refreshSidePanels(g)
|
return gui.refreshSidePanels(g)
|
||||||
}, nil)
|
}, nil)
|
||||||
@@ -205,10 +181,9 @@ func (gui *Gui) handleCheckoutRef(ref string) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (gui *Gui) handleCheckoutByName(g *gocui.Gui, v *gocui.View) error {
|
func (gui *Gui) handleCheckoutByName(g *gocui.Gui, v *gocui.View) error {
|
||||||
gui.createPromptPanel(g, v, gui.Tr.SLocalize("BranchName")+":", "", func(g *gocui.Gui, v *gocui.View) error {
|
return gui.createPromptPanel(g, v, gui.Tr.SLocalize("BranchName")+":", "", func(g *gocui.Gui, v *gocui.View) error {
|
||||||
return gui.handleCheckoutRef(gui.trimmedContent(v))
|
return gui.handleCheckoutRef(gui.trimmedContent(v))
|
||||||
})
|
})
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (gui *Gui) getCheckedOutBranch() *commands.Branch {
|
func (gui *Gui) getCheckedOutBranch() *commands.Branch {
|
||||||
@@ -220,31 +195,31 @@ func (gui *Gui) getCheckedOutBranch() *commands.Branch {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (gui *Gui) handleNewBranch(g *gocui.Gui, v *gocui.View) error {
|
func (gui *Gui) handleNewBranch(g *gocui.Gui, v *gocui.View) error {
|
||||||
branch := gui.getCheckedOutBranch()
|
branch := gui.getSelectedBranch()
|
||||||
|
if branch == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
message := gui.Tr.TemplateLocalize(
|
message := gui.Tr.TemplateLocalize(
|
||||||
"NewBranchNameBranchOff",
|
"NewBranchNameBranchOff",
|
||||||
Teml{
|
Teml{
|
||||||
"branchName": branch.Name,
|
"branchName": branch.Name,
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
gui.createPromptPanel(g, v, message, "", func(g *gocui.Gui, v *gocui.View) error {
|
return gui.createPromptPanel(g, v, message, "", func(g *gocui.Gui, v *gocui.View) error {
|
||||||
if err := gui.GitCommand.NewBranch(gui.trimmedContent(v)); err != nil {
|
if err := gui.GitCommand.NewBranch(gui.trimmedContent(v), branch.Name); err != nil {
|
||||||
|
return gui.createErrorPanel(g, err.Error())
|
||||||
|
}
|
||||||
|
if err := gui.refreshSidePanels(g); err != nil {
|
||||||
return gui.createErrorPanel(g, err.Error())
|
return gui.createErrorPanel(g, err.Error())
|
||||||
}
|
}
|
||||||
gui.refreshSidePanels(g)
|
|
||||||
return gui.handleBranchSelect(g, v)
|
return gui.handleBranchSelect(g, v)
|
||||||
})
|
})
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (gui *Gui) handleDeleteBranch(g *gocui.Gui, v *gocui.View) error {
|
func (gui *Gui) handleDeleteBranch(g *gocui.Gui, v *gocui.View) error {
|
||||||
return gui.deleteBranch(g, v, false)
|
return gui.deleteBranch(g, v, false)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (gui *Gui) handleForceDeleteBranch(g *gocui.Gui, v *gocui.View) error {
|
|
||||||
return gui.deleteBranch(g, v, true)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (gui *Gui) deleteBranch(g *gocui.Gui, v *gocui.View, force bool) error {
|
func (gui *Gui) deleteBranch(g *gocui.Gui, v *gocui.View, force bool) error {
|
||||||
selectedBranch := gui.getSelectedBranch()
|
selectedBranch := gui.getSelectedBranch()
|
||||||
if selectedBranch == nil {
|
if selectedBranch == nil {
|
||||||
@@ -378,7 +353,7 @@ func (gui *Gui) handleFastForward(g *gocui.Gui, v *gocui.View) error {
|
|||||||
if err := gui.GitCommand.FastForward(branch.Name, remoteName, remoteBranchName); err != nil {
|
if err := gui.GitCommand.FastForward(branch.Name, remoteName, remoteBranchName); err != nil {
|
||||||
_ = gui.createErrorPanel(gui.g, err.Error())
|
_ = gui.createErrorPanel(gui.g, err.Error())
|
||||||
}
|
}
|
||||||
_ = gui.RenderSelectedBranchUpstreamDifferences()
|
_ = gui.refreshBranches(gui.g)
|
||||||
}
|
}
|
||||||
|
|
||||||
_ = gui.closeConfirmationPrompt(gui.g, true)
|
_ = gui.closeConfirmationPrompt(gui.g, true)
|
||||||
@@ -397,7 +372,9 @@ func (gui *Gui) onBranchesTabClick(tabIndex int) error {
|
|||||||
func (gui *Gui) switchBranchesPanelContext(context string) error {
|
func (gui *Gui) switchBranchesPanelContext(context string) error {
|
||||||
branchesView := gui.getBranchesView()
|
branchesView := gui.getBranchesView()
|
||||||
branchesView.Context = context
|
branchesView.Context = context
|
||||||
gui.onSearchEscape()
|
if err := gui.onSearchEscape(); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
contextTabIndexMap := map[string]int{
|
contextTabIndexMap := map[string]int{
|
||||||
"local-branches": 0,
|
"local-branches": 0,
|
||||||
@@ -408,7 +385,13 @@ func (gui *Gui) switchBranchesPanelContext(context string) error {
|
|||||||
|
|
||||||
branchesView.TabIndex = contextTabIndexMap[context]
|
branchesView.TabIndex = contextTabIndexMap[context]
|
||||||
|
|
||||||
switch context {
|
return gui.refreshBranchesViewWithSelection()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (gui *Gui) refreshBranchesViewWithSelection() error {
|
||||||
|
branchesView := gui.getBranchesView()
|
||||||
|
|
||||||
|
switch branchesView.Context {
|
||||||
case "local-branches":
|
case "local-branches":
|
||||||
return gui.renderLocalBranchesWithSelection()
|
return gui.renderLocalBranchesWithSelection()
|
||||||
case "remotes":
|
case "remotes":
|
||||||
@@ -458,3 +441,41 @@ func (gui *Gui) onBranchesPanelSearchSelect(selectedLine int) error {
|
|||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (gui *Gui) handleRenameBranch(g *gocui.Gui, v *gocui.View) error {
|
||||||
|
branch := gui.getSelectedBranch()
|
||||||
|
if branch == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
promptForNewName := func() error {
|
||||||
|
return gui.createPromptPanel(g, v, gui.Tr.SLocalize("NewBranchNamePrompt")+" "+branch.Name+":", "", func(g *gocui.Gui, v *gocui.View) error {
|
||||||
|
newName := gui.trimmedContent(v)
|
||||||
|
if err := gui.GitCommand.RenameBranch(branch.Name, newName); err != nil {
|
||||||
|
return gui.createErrorPanel(gui.g, err.Error())
|
||||||
|
}
|
||||||
|
// need to checkout so that the branch shows up in our reflog and therefore
|
||||||
|
// doesn't get lost among all the other branches when we switch to something else
|
||||||
|
if err := gui.GitCommand.Checkout(newName, false); err != nil {
|
||||||
|
return gui.createErrorPanel(gui.g, err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
return gui.refreshBranches(gui.g)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// I could do an explicit check here for whether the branch is tracking a remote branch
|
||||||
|
// but if we've selected it we'll already know that via Pullables and Pullables.
|
||||||
|
// Bit of a hack but I'm lazy.
|
||||||
|
notTrackingRemote := branch.Pullables == "?"
|
||||||
|
if notTrackingRemote {
|
||||||
|
return promptForNewName()
|
||||||
|
}
|
||||||
|
return gui.createConfirmationPanel(gui.g, v, true, gui.Tr.SLocalize("renameBranch"), gui.Tr.SLocalize("RenameBranchWarning"), func(_g *gocui.Gui, _v *gocui.View) error {
|
||||||
|
return promptForNewName()
|
||||||
|
}, nil)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (gui *Gui) currentBranch() *commands.Branch {
|
||||||
|
return gui.State.Branches[0]
|
||||||
|
}
|
||||||
|
|||||||
@@ -36,21 +36,20 @@ func (gui *Gui) handleCommitFileSelect(g *gocui.Gui, v *gocui.View) error {
|
|||||||
|
|
||||||
commitFile := gui.getSelectedCommitFile(g)
|
commitFile := gui.getSelectedCommitFile(g)
|
||||||
if commitFile == nil {
|
if commitFile == nil {
|
||||||
return gui.renderString(g, "commitFiles", gui.Tr.SLocalize("NoCommiteFiles"))
|
gui.renderString(g, "commitFiles", gui.Tr.SLocalize("NoCommiteFiles"))
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := gui.refreshSecondaryPatchPanel(); err != nil {
|
if err := gui.refreshSecondaryPatchPanel(); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := gui.focusPoint(0, gui.State.Panels.CommitFiles.SelectedLine, len(gui.State.CommitFiles), v); err != nil {
|
v.FocusPoint(0, gui.State.Panels.CommitFiles.SelectedLine)
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
cmd := gui.OSCommand.ExecutableFromString(
|
cmd := gui.OSCommand.ExecutableFromString(
|
||||||
gui.GitCommand.ShowCommitFileCmdStr(commitFile.Sha, commitFile.Name, false),
|
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)
|
gui.Log.Error(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -132,7 +131,8 @@ func (gui *Gui) handleToggleFileForPatch(g *gocui.Gui, v *gocui.View) error {
|
|||||||
|
|
||||||
commitFile := gui.getSelectedCommitFile(g)
|
commitFile := gui.getSelectedCommitFile(g)
|
||||||
if commitFile == nil {
|
if commitFile == nil {
|
||||||
return gui.renderString(g, "commitFiles", gui.Tr.SLocalize("NoCommiteFiles"))
|
gui.renderString(g, "commitFiles", gui.Tr.SLocalize("NoCommiteFiles"))
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
toggleTheFile := func() error {
|
toggleTheFile := func() error {
|
||||||
@@ -187,7 +187,8 @@ func (gui *Gui) enterCommitFile(selectedLineIdx int) error {
|
|||||||
|
|
||||||
commitFile := gui.getSelectedCommitFile(gui.g)
|
commitFile := gui.getSelectedCommitFile(gui.g)
|
||||||
if commitFile == nil {
|
if commitFile == nil {
|
||||||
return gui.renderString(gui.g, "commitFiles", gui.Tr.SLocalize("NoCommiteFiles"))
|
gui.renderString(gui.g, "commitFiles", gui.Tr.SLocalize("NoCommiteFiles"))
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
enterTheFile := func(selectedLineIdx int) error {
|
enterTheFile := func(selectedLineIdx int) error {
|
||||||
|
|||||||
@@ -52,7 +52,7 @@ func (gui *Gui) handleCommitConfirm(g *gocui.Gui, v *gocui.View) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (gui *Gui) handleCommitClose(g *gocui.Gui, v *gocui.View) error {
|
func (gui *Gui) handleCommitClose(g *gocui.Gui, v *gocui.View) error {
|
||||||
g.SetViewOnBottom("commitMessage")
|
_, _ = g.SetViewOnBottom("commitMessage")
|
||||||
return gui.switchFocus(g, v, gui.getFilesView())
|
return gui.switchFocus(g, v, gui.getFilesView())
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -68,7 +68,8 @@ func (gui *Gui) handleCommitFocused(g *gocui.Gui, v *gocui.View) error {
|
|||||||
"keyBindConfirm": "enter",
|
"keyBindConfirm": "enter",
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
return gui.renderString(g, "options", message)
|
gui.renderString(g, "options", message)
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (gui *Gui) getBufferLength(view *gocui.View) string {
|
func (gui *Gui) getBufferLength(view *gocui.View) string {
|
||||||
|
|||||||
+14
-60
@@ -3,8 +3,6 @@ package gui
|
|||||||
import (
|
import (
|
||||||
"strconv"
|
"strconv"
|
||||||
|
|
||||||
"github.com/go-errors/errors"
|
|
||||||
|
|
||||||
"github.com/jesseduffield/gocui"
|
"github.com/jesseduffield/gocui"
|
||||||
"github.com/jesseduffield/lazygit/pkg/commands"
|
"github.com/jesseduffield/lazygit/pkg/commands"
|
||||||
"github.com/jesseduffield/lazygit/pkg/gui/presentation"
|
"github.com/jesseduffield/lazygit/pkg/gui/presentation"
|
||||||
@@ -55,9 +53,7 @@ func (gui *Gui) handleCommitSelect(g *gocui.Gui, v *gocui.View) error {
|
|||||||
return gui.newStringTask("main", gui.Tr.SLocalize("NoCommitsThisBranch"))
|
return gui.newStringTask("main", gui.Tr.SLocalize("NoCommitsThisBranch"))
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := gui.focusPoint(0, gui.State.Panels.Commits.SelectedLine, len(gui.State.Commits), v); err != nil {
|
v.FocusPoint(0, gui.State.Panels.Commits.SelectedLine)
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
// if specific diff mode is on, don't show diff
|
// if specific diff mode is on, don't show diff
|
||||||
if gui.State.Panels.Commits.SpecificDiffMode {
|
if gui.State.Panels.Commits.SpecificDiffMode {
|
||||||
@@ -67,7 +63,7 @@ func (gui *Gui) handleCommitSelect(g *gocui.Gui, v *gocui.View) error {
|
|||||||
cmd := gui.OSCommand.ExecutableFromString(
|
cmd := gui.OSCommand.ExecutableFromString(
|
||||||
gui.GitCommand.ShowCmdStr(commit.Sha),
|
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)
|
gui.Log.Error(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -77,7 +73,7 @@ func (gui *Gui) handleCommitSelect(g *gocui.Gui, v *gocui.View) error {
|
|||||||
func (gui *Gui) refreshCommits(g *gocui.Gui) error {
|
func (gui *Gui) refreshCommits(g *gocui.Gui) error {
|
||||||
g.Update(func(*gocui.Gui) error {
|
g.Update(func(*gocui.Gui) error {
|
||||||
// I think this is here for the sake of some kind of rebasing thing
|
// I think this is here for the sake of some kind of rebasing thing
|
||||||
gui.refreshStatus(g)
|
_ = gui.refreshStatus(g)
|
||||||
|
|
||||||
if err := gui.refreshCommitsWithLimit(); err != nil {
|
if err := gui.refreshCommitsWithLimit(); err != nil {
|
||||||
return err
|
return err
|
||||||
@@ -121,28 +117,6 @@ func (gui *Gui) refreshCommitsWithLimit() error {
|
|||||||
|
|
||||||
// specific functions
|
// specific functions
|
||||||
|
|
||||||
func (gui *Gui) handleResetToCommit(g *gocui.Gui, commitView *gocui.View) error {
|
|
||||||
return gui.createConfirmationPanel(g, commitView, true, gui.Tr.SLocalize("ResetToCommit"), gui.Tr.SLocalize("SureResetThisCommit"), func(g *gocui.Gui, v *gocui.View) error {
|
|
||||||
commit := gui.getSelectedCommit(g)
|
|
||||||
if commit == nil {
|
|
||||||
panic(errors.New(gui.Tr.SLocalize("NoCommitsThisBranch")))
|
|
||||||
}
|
|
||||||
|
|
||||||
if err := gui.GitCommand.ResetToCommit(commit.Sha, "mixed"); err != nil {
|
|
||||||
return gui.createErrorPanel(g, err.Error())
|
|
||||||
}
|
|
||||||
if err := gui.refreshCommits(g); err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
if err := gui.refreshFiles(); err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
gui.resetOrigin(commitView)
|
|
||||||
gui.State.Panels.Commits.SelectedLine = 0
|
|
||||||
return gui.handleCommitSelect(g, commitView)
|
|
||||||
}, nil)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (gui *Gui) handleCommitSquashDown(g *gocui.Gui, v *gocui.View) error {
|
func (gui *Gui) handleCommitSquashDown(g *gocui.Gui, v *gocui.View) error {
|
||||||
if len(gui.State.Commits) <= 1 {
|
if len(gui.State.Commits) <= 1 {
|
||||||
return gui.createErrorPanel(g, gui.Tr.SLocalize("YouNoCommitsToSquash"))
|
return gui.createErrorPanel(g, gui.Tr.SLocalize("YouNoCommitsToSquash"))
|
||||||
@@ -156,23 +130,12 @@ func (gui *Gui) handleCommitSquashDown(g *gocui.Gui, v *gocui.View) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
gui.createConfirmationPanel(g, v, true, gui.Tr.SLocalize("Squash"), gui.Tr.SLocalize("SureSquashThisCommit"), func(g *gocui.Gui, v *gocui.View) error {
|
return gui.createConfirmationPanel(g, v, true, gui.Tr.SLocalize("Squash"), gui.Tr.SLocalize("SureSquashThisCommit"), func(g *gocui.Gui, v *gocui.View) error {
|
||||||
return gui.WithWaitingStatus(gui.Tr.SLocalize("SquashingStatus"), func() error {
|
return gui.WithWaitingStatus(gui.Tr.SLocalize("SquashingStatus"), func() error {
|
||||||
err := gui.GitCommand.InteractiveRebase(gui.State.Commits, gui.State.Panels.Commits.SelectedLine, "squash")
|
err := gui.GitCommand.InteractiveRebase(gui.State.Commits, gui.State.Panels.Commits.SelectedLine, "squash")
|
||||||
return gui.handleGenericMergeCommandResult(err)
|
return gui.handleGenericMergeCommandResult(err)
|
||||||
})
|
})
|
||||||
}, nil)
|
}, nil)
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: move to files panel
|
|
||||||
func (gui *Gui) anyUnStagedChanges(files []*commands.File) bool {
|
|
||||||
for _, file := range files {
|
|
||||||
if file.Tracked && file.HasUnstagedChanges {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (gui *Gui) handleCommitFixup(g *gocui.Gui, v *gocui.View) error {
|
func (gui *Gui) handleCommitFixup(g *gocui.Gui, v *gocui.View) error {
|
||||||
@@ -188,13 +151,12 @@ func (gui *Gui) handleCommitFixup(g *gocui.Gui, v *gocui.View) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
gui.createConfirmationPanel(g, v, true, gui.Tr.SLocalize("Fixup"), gui.Tr.SLocalize("SureFixupThisCommit"), func(g *gocui.Gui, v *gocui.View) error {
|
return gui.createConfirmationPanel(g, v, true, gui.Tr.SLocalize("Fixup"), gui.Tr.SLocalize("SureFixupThisCommit"), func(g *gocui.Gui, v *gocui.View) error {
|
||||||
return gui.WithWaitingStatus(gui.Tr.SLocalize("FixingStatus"), func() error {
|
return gui.WithWaitingStatus(gui.Tr.SLocalize("FixingStatus"), func() error {
|
||||||
err := gui.GitCommand.InteractiveRebase(gui.State.Commits, gui.State.Panels.Commits.SelectedLine, "fixup")
|
err := gui.GitCommand.InteractiveRebase(gui.State.Commits, gui.State.Panels.Commits.SelectedLine, "fixup")
|
||||||
return gui.handleGenericMergeCommandResult(err)
|
return gui.handleGenericMergeCommandResult(err)
|
||||||
})
|
})
|
||||||
}, nil)
|
}, nil)
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (gui *Gui) handleRenameCommit(g *gocui.Gui, v *gocui.View) error {
|
func (gui *Gui) handleRenameCommit(g *gocui.Gui, v *gocui.View) error {
|
||||||
@@ -264,21 +226,6 @@ func (gui *Gui) handleMidRebaseCommand(action string) (bool, error) {
|
|||||||
return true, gui.refreshCommits(gui.g)
|
return true, gui.refreshCommits(gui.g)
|
||||||
}
|
}
|
||||||
|
|
||||||
// handleMoveTodoDown like handleMidRebaseCommand but for moving an item up in the todo list
|
|
||||||
func (gui *Gui) handleMoveTodoDown(index int) (bool, error) {
|
|
||||||
selectedCommit := gui.State.Commits[index]
|
|
||||||
if selectedCommit.Status != "rebasing" {
|
|
||||||
return false, nil
|
|
||||||
}
|
|
||||||
if gui.State.Commits[index+1].Status != "rebasing" {
|
|
||||||
return true, nil
|
|
||||||
}
|
|
||||||
if err := gui.GitCommand.MoveTodoDown(index); err != nil {
|
|
||||||
return true, gui.createErrorPanel(gui.g, err.Error())
|
|
||||||
}
|
|
||||||
return true, gui.refreshCommits(gui.g)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (gui *Gui) handleCommitDelete(g *gocui.Gui, v *gocui.View) error {
|
func (gui *Gui) handleCommitDelete(g *gocui.Gui, v *gocui.View) error {
|
||||||
applied, err := gui.handleMidRebaseCommand("drop")
|
applied, err := gui.handleMidRebaseCommand("drop")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -504,7 +451,7 @@ func (gui *Gui) setDiffMode() {
|
|||||||
v.Title = gui.Tr.SLocalize("CommitsTitle")
|
v.Title = gui.Tr.SLocalize("CommitsTitle")
|
||||||
}
|
}
|
||||||
|
|
||||||
gui.refreshCommits(gui.g)
|
_ = gui.refreshCommits(gui.g)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (gui *Gui) hasCommit(commits []*commands.Commit, target string) (int, bool) {
|
func (gui *Gui) hasCommit(commits []*commands.Commit, target string) (int, bool) {
|
||||||
@@ -623,7 +570,9 @@ func (gui *Gui) onCommitsTabClick(tabIndex int) error {
|
|||||||
func (gui *Gui) switchCommitsPanelContext(context string) error {
|
func (gui *Gui) switchCommitsPanelContext(context string) error {
|
||||||
commitsView := gui.getCommitsView()
|
commitsView := gui.getCommitsView()
|
||||||
commitsView.Context = context
|
commitsView.Context = context
|
||||||
gui.onSearchEscape()
|
if err := gui.onSearchEscape(); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
contextTabIndexMap := map[string]int{
|
contextTabIndexMap := map[string]int{
|
||||||
"branch-commits": 0,
|
"branch-commits": 0,
|
||||||
@@ -693,3 +642,8 @@ func (gui *Gui) handleOpenSearchForCommitsPanel(g *gocui.Gui, v *gocui.View) err
|
|||||||
|
|
||||||
return gui.handleOpenSearch(gui.g, v)
|
return gui.handleOpenSearch(gui.g, v)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (gui *Gui) handleResetCherryPick(g *gocui.Gui, v *gocui.View) error {
|
||||||
|
gui.State.CherryPickedCommits = []*commands.Commit{}
|
||||||
|
return gui.refreshCommits(gui.g)
|
||||||
|
}
|
||||||
|
|||||||
@@ -122,9 +122,7 @@ func (gui *Gui) createPopupPanel(g *gocui.Gui, currentView *gocui.View, title, p
|
|||||||
}()
|
}()
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := gui.renderString(g, "confirmation", prompt); err != nil {
|
gui.renderString(g, "confirmation", prompt)
|
||||||
return err
|
|
||||||
}
|
|
||||||
return gui.setKeyBindings(g, handleConfirm, handleClose, returnFocusOnClose)
|
return gui.setKeyBindings(g, handleConfirm, handleClose, returnFocusOnClose)
|
||||||
})
|
})
|
||||||
return nil
|
return nil
|
||||||
@@ -151,19 +149,13 @@ func (gui *Gui) setKeyBindings(g *gocui.Gui, handleConfirm, handleClose func(*go
|
|||||||
"keyBindConfirm": "enter",
|
"keyBindConfirm": "enter",
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
if err := gui.renderString(g, "options", actions); err != nil {
|
gui.renderString(g, "options", actions)
|
||||||
return err
|
|
||||||
}
|
|
||||||
if err := g.SetKeybinding("confirmation", nil, gocui.KeyEnter, gocui.ModNone, gui.wrappedConfirmationFunction(handleConfirm, returnFocusOnClose)); err != nil {
|
if err := g.SetKeybinding("confirmation", nil, gocui.KeyEnter, gocui.ModNone, gui.wrappedConfirmationFunction(handleConfirm, returnFocusOnClose)); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
return g.SetKeybinding("confirmation", nil, gocui.KeyEsc, gocui.ModNone, gui.wrappedConfirmationFunction(handleClose, returnFocusOnClose))
|
return g.SetKeybinding("confirmation", nil, gocui.KeyEsc, gocui.ModNone, gui.wrappedConfirmationFunction(handleClose, returnFocusOnClose))
|
||||||
}
|
}
|
||||||
|
|
||||||
func (gui *Gui) createMessagePanel(g *gocui.Gui, currentView *gocui.View, title, prompt string) error {
|
|
||||||
return gui.createPopupPanel(g, currentView, title, prompt, false, true, false, nil, nil)
|
|
||||||
}
|
|
||||||
|
|
||||||
// createSpecificErrorPanel allows you to create an error popup, specifying the
|
// createSpecificErrorPanel allows you to create an error popup, specifying the
|
||||||
// view to be focused when the user closes the popup, and a boolean specifying
|
// view to be focused when the user closes the popup, and a boolean specifying
|
||||||
// whether we will log the error. If the message may include a user password,
|
// whether we will log the error. If the message may include a user password,
|
||||||
|
|||||||
@@ -16,5 +16,4 @@ func (gui *Gui) changeMainViewsContext(context string) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
gui.State.MainContext = context
|
gui.State.MainContext = context
|
||||||
return
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -82,7 +82,8 @@ func (gui *Gui) handleCredentialsViewFocused(g *gocui.Gui, v *gocui.View) error
|
|||||||
"keyBindConfirm": "enter",
|
"keyBindConfirm": "enter",
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
return gui.renderString(g, "options", message)
|
gui.renderString(g, "options", message)
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// HandleCredentialsPopup handles the views after executing a command that might ask for credentials
|
// HandleCredentialsPopup handles the views after executing a command that might ask for credentials
|
||||||
|
|||||||
@@ -23,11 +23,13 @@ type fileWatcher struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func NewFileWatcher(log *logrus.Entry) *fileWatcher {
|
func NewFileWatcher(log *logrus.Entry) *fileWatcher {
|
||||||
watcher, err := fsnotify.NewWatcher()
|
// TODO: get this going again, and ensure we don't see any crashes from it
|
||||||
log.Error(err)
|
|
||||||
return &fileWatcher{
|
return &fileWatcher{
|
||||||
Disabled: true,
|
Disabled: true,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
watcher, err := fsnotify.NewWatcher()
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error(err)
|
log.Error(err)
|
||||||
return &fileWatcher{
|
return &fileWatcher{
|
||||||
|
|||||||
+26
-38
@@ -37,9 +37,7 @@ func (gui *Gui) selectFile(alreadySelected bool) error {
|
|||||||
return gui.newStringTask("main", gui.Tr.SLocalize("NoChangedFiles"))
|
return gui.newStringTask("main", gui.Tr.SLocalize("NoChangedFiles"))
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := gui.focusPoint(0, gui.State.Panels.Files.SelectedLine, len(gui.State.Files), gui.getFilesView()); err != nil {
|
gui.getFilesView().FocusPoint(0, gui.State.Panels.Files.SelectedLine)
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
if file.HasInlineMergeConflicts {
|
if file.HasInlineMergeConflicts {
|
||||||
gui.getMainView().Title = gui.Tr.SLocalize("MergeConflictsTitle")
|
gui.getMainView().Title = gui.Tr.SLocalize("MergeConflictsTitle")
|
||||||
@@ -62,7 +60,7 @@ func (gui *Gui) selectFile(alreadySelected bool) error {
|
|||||||
gui.getSecondaryView().Title = gui.Tr.SLocalize("StagedChanges")
|
gui.getSecondaryView().Title = gui.Tr.SLocalize("StagedChanges")
|
||||||
cmdStr := gui.GitCommand.DiffCmdStr(file, false, true)
|
cmdStr := gui.GitCommand.DiffCmdStr(file, false, true)
|
||||||
cmd := gui.OSCommand.ExecutableFromString(cmdStr)
|
cmd := gui.OSCommand.ExecutableFromString(cmdStr)
|
||||||
if err := gui.newCmdTask("secondary", cmd); err != nil {
|
if err := gui.newPtyTask("secondary", cmd); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@@ -76,7 +74,7 @@ func (gui *Gui) selectFile(alreadySelected bool) error {
|
|||||||
|
|
||||||
cmdStr := gui.GitCommand.DiffCmdStr(file, false, !file.HasUnstagedChanges && file.HasStagedChanges)
|
cmdStr := gui.GitCommand.DiffCmdStr(file, false, !file.HasUnstagedChanges && file.HasStagedChanges)
|
||||||
cmd := gui.OSCommand.ExecutableFromString(cmdStr)
|
cmd := gui.OSCommand.ExecutableFromString(cmdStr)
|
||||||
if err := gui.newCmdTask("main", cmd); err != nil {
|
if err := gui.newPtyTask("main", cmd); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -188,9 +186,12 @@ func (gui *Gui) handleFilePress(g *gocui.Gui, v *gocui.View) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if file.HasUnstagedChanges {
|
if file.HasUnstagedChanges {
|
||||||
gui.GitCommand.StageFile(file.Name)
|
err = gui.GitCommand.StageFile(file.Name)
|
||||||
} else {
|
} else {
|
||||||
gui.GitCommand.UnStageFile(file.Name, file.Tracked)
|
err = gui.GitCommand.UnStageFile(file.Name, file.Tracked)
|
||||||
|
}
|
||||||
|
if err != nil {
|
||||||
|
return gui.createErrorPanel(gui.g, err.Error())
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := gui.refreshFiles(); err != nil {
|
if err := gui.refreshFiles(); err != nil {
|
||||||
@@ -268,9 +269,7 @@ func (gui *Gui) handleWIPCommitPress(g *gocui.Gui, filesView *gocui.View) error
|
|||||||
return gui.createErrorPanel(gui.g, gui.Tr.SLocalize("SkipHookPrefixNotConfigured"))
|
return gui.createErrorPanel(gui.g, gui.Tr.SLocalize("SkipHookPrefixNotConfigured"))
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := gui.renderString(g, "commitMessage", skipHookPreifx); err != nil {
|
gui.renderString(g, "commitMessage", skipHookPreifx)
|
||||||
return err
|
|
||||||
}
|
|
||||||
if err := gui.getCommitMessageView().SetCursor(len(skipHookPreifx), 0); err != nil {
|
if err := gui.getCommitMessageView().SetCursor(len(skipHookPreifx), 0); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@@ -284,8 +283,14 @@ func (gui *Gui) handleCommitPress(g *gocui.Gui, filesView *gocui.View) error {
|
|||||||
}
|
}
|
||||||
commitMessageView := gui.getCommitMessageView()
|
commitMessageView := gui.getCommitMessageView()
|
||||||
g.Update(func(g *gocui.Gui) error {
|
g.Update(func(g *gocui.Gui) error {
|
||||||
g.SetViewOnTop("commitMessage")
|
if _, err := g.SetViewOnTop("commitMessage"); err != nil {
|
||||||
gui.switchFocus(g, filesView, commitMessageView)
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := gui.switchFocus(g, filesView, commitMessageView); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
gui.RenderCommitLength()
|
gui.RenderCommitLength()
|
||||||
return nil
|
return nil
|
||||||
})
|
})
|
||||||
@@ -394,24 +399,20 @@ func (gui *Gui) catSelectedFile(g *gocui.Gui) (string, error) {
|
|||||||
|
|
||||||
func (gui *Gui) handlePullFiles(g *gocui.Gui, v *gocui.View) error {
|
func (gui *Gui) handlePullFiles(g *gocui.Gui, v *gocui.View) error {
|
||||||
// if we have no upstream branch we need to set that first
|
// if we have no upstream branch we need to set that first
|
||||||
_, pullables := gui.GitCommand.GetCurrentBranchUpstreamDifferenceCount()
|
currentBranch := gui.currentBranch()
|
||||||
currentBranchName, err := gui.GitCommand.CurrentBranchName()
|
if currentBranch.Pullables == "?" {
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
if pullables == "?" {
|
|
||||||
// see if we have this branch in our config with an upstream
|
// see if we have this branch in our config with an upstream
|
||||||
conf, err := gui.GitCommand.Repo.Config()
|
conf, err := gui.GitCommand.Repo.Config()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return gui.createErrorPanel(gui.g, err.Error())
|
return gui.createErrorPanel(gui.g, err.Error())
|
||||||
}
|
}
|
||||||
for branchName, branch := range conf.Branches {
|
for branchName, branch := range conf.Branches {
|
||||||
if branchName == currentBranchName {
|
if branchName == currentBranch.Name {
|
||||||
return gui.pullFiles(v, fmt.Sprintf("%s %s", branch.Remote, branchName))
|
return gui.pullFiles(v, fmt.Sprintf("%s %s", branch.Remote, branchName))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return gui.createPromptPanel(g, v, gui.Tr.SLocalize("EnterUpstream"), "origin/"+currentBranchName, func(g *gocui.Gui, v *gocui.View) error {
|
return gui.createPromptPanel(g, v, gui.Tr.SLocalize("EnterUpstream"), "origin/"+currentBranch.Name, func(g *gocui.Gui, v *gocui.View) error {
|
||||||
upstream := gui.trimmedContent(v)
|
upstream := gui.trimmedContent(v)
|
||||||
if err := gui.GitCommand.SetUpstreamBranch(upstream); err != nil {
|
if err := gui.GitCommand.SetUpstreamBranch(upstream); err != nil {
|
||||||
errorMessage := err.Error()
|
errorMessage := err.Error()
|
||||||
@@ -462,28 +463,24 @@ func (gui *Gui) pushWithForceFlag(g *gocui.Gui, v *gocui.View, force bool, upstr
|
|||||||
|
|
||||||
func (gui *Gui) pushFiles(g *gocui.Gui, v *gocui.View) error {
|
func (gui *Gui) pushFiles(g *gocui.Gui, v *gocui.View) error {
|
||||||
// if we have pullables we'll ask if the user wants to force push
|
// if we have pullables we'll ask if the user wants to force push
|
||||||
_, pullables := gui.GitCommand.GetCurrentBranchUpstreamDifferenceCount()
|
currentBranch := gui.currentBranch()
|
||||||
currentBranchName, err := gui.GitCommand.CurrentBranchName()
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
if pullables == "?" {
|
if currentBranch.Pullables == "?" {
|
||||||
// see if we have this branch in our config with an upstream
|
// see if we have this branch in our config with an upstream
|
||||||
conf, err := gui.GitCommand.Repo.Config()
|
conf, err := gui.GitCommand.Repo.Config()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return gui.createErrorPanel(gui.g, err.Error())
|
return gui.createErrorPanel(gui.g, err.Error())
|
||||||
}
|
}
|
||||||
for branchName, branch := range conf.Branches {
|
for branchName, branch := range conf.Branches {
|
||||||
if branchName == currentBranchName {
|
if branchName == currentBranch.Name {
|
||||||
return gui.pushWithForceFlag(g, v, false, "", fmt.Sprintf("%s %s", branch.Remote, branchName))
|
return gui.pushWithForceFlag(g, v, false, "", fmt.Sprintf("%s %s", branch.Remote, branchName))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return gui.createPromptPanel(g, v, gui.Tr.SLocalize("EnterUpstream"), "origin "+currentBranchName, func(g *gocui.Gui, v *gocui.View) error {
|
return gui.createPromptPanel(g, v, gui.Tr.SLocalize("EnterUpstream"), "origin "+currentBranch.Name, func(g *gocui.Gui, v *gocui.View) error {
|
||||||
return gui.pushWithForceFlag(g, v, false, gui.trimmedContent(v), "")
|
return gui.pushWithForceFlag(g, v, false, gui.trimmedContent(v), "")
|
||||||
})
|
})
|
||||||
} else if pullables == "0" {
|
} else if currentBranch.Pullables == "0" {
|
||||||
return gui.pushWithForceFlag(g, v, false, "", "")
|
return gui.pushWithForceFlag(g, v, false, "", "")
|
||||||
}
|
}
|
||||||
return gui.createConfirmationPanel(g, v, true, gui.Tr.SLocalize("ForcePush"), gui.Tr.SLocalize("ForcePushPrompt"), func(g *gocui.Gui, v *gocui.View) error {
|
return gui.createConfirmationPanel(g, v, true, gui.Tr.SLocalize("ForcePush"), gui.Tr.SLocalize("ForcePushPrompt"), func(g *gocui.Gui, v *gocui.View) error {
|
||||||
@@ -509,15 +506,6 @@ func (gui *Gui) handleSwitchToMerge(g *gocui.Gui, v *gocui.View) error {
|
|||||||
return gui.refreshMergePanel()
|
return gui.refreshMergePanel()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (gui *Gui) handleAbortMerge(g *gocui.Gui, v *gocui.View) error {
|
|
||||||
if err := gui.GitCommand.AbortMerge(); err != nil {
|
|
||||||
return gui.createErrorPanel(g, err.Error())
|
|
||||||
}
|
|
||||||
gui.createMessagePanel(g, v, "", gui.Tr.SLocalize("MergeAborted"))
|
|
||||||
gui.refreshStatus(g)
|
|
||||||
return gui.refreshFiles()
|
|
||||||
}
|
|
||||||
|
|
||||||
func (gui *Gui) openFile(filename string) error {
|
func (gui *Gui) openFile(filename string) error {
|
||||||
if err := gui.OSCommand.OpenFile(filename); err != nil {
|
if err := gui.OSCommand.OpenFile(filename); err != nil {
|
||||||
return gui.createErrorPanel(gui.g, err.Error())
|
return gui.createErrorPanel(gui.g, err.Error())
|
||||||
|
|||||||
+50
-27
@@ -24,7 +24,6 @@ import (
|
|||||||
"github.com/jesseduffield/gocui"
|
"github.com/jesseduffield/gocui"
|
||||||
"github.com/jesseduffield/lazygit/pkg/commands"
|
"github.com/jesseduffield/lazygit/pkg/commands"
|
||||||
"github.com/jesseduffield/lazygit/pkg/config"
|
"github.com/jesseduffield/lazygit/pkg/config"
|
||||||
"github.com/jesseduffield/lazygit/pkg/gui/presentation"
|
|
||||||
"github.com/jesseduffield/lazygit/pkg/i18n"
|
"github.com/jesseduffield/lazygit/pkg/i18n"
|
||||||
"github.com/jesseduffield/lazygit/pkg/tasks"
|
"github.com/jesseduffield/lazygit/pkg/tasks"
|
||||||
"github.com/jesseduffield/lazygit/pkg/theme"
|
"github.com/jesseduffield/lazygit/pkg/theme"
|
||||||
@@ -81,7 +80,7 @@ type Gui struct {
|
|||||||
GitCommand *commands.GitCommand
|
GitCommand *commands.GitCommand
|
||||||
OSCommand *commands.OSCommand
|
OSCommand *commands.OSCommand
|
||||||
SubProcess *exec.Cmd
|
SubProcess *exec.Cmd
|
||||||
State guiState
|
State *guiState
|
||||||
Config config.AppConfigurer
|
Config config.AppConfigurer
|
||||||
Tr *i18n.Localizer
|
Tr *i18n.Localizer
|
||||||
Errors SentinelErrors
|
Errors SentinelErrors
|
||||||
@@ -211,6 +210,10 @@ type guiState struct {
|
|||||||
Searching searchingState
|
Searching searchingState
|
||||||
ScreenMode int
|
ScreenMode int
|
||||||
SideView *gocui.View
|
SideView *gocui.View
|
||||||
|
Ptmx *os.File
|
||||||
|
PrevMainWidth int
|
||||||
|
PrevMainHeight int
|
||||||
|
OldInformation string
|
||||||
}
|
}
|
||||||
|
|
||||||
// for now the split view will always be on
|
// for now the split view will always be on
|
||||||
@@ -218,7 +221,7 @@ type guiState struct {
|
|||||||
// NewGui builds a new gui handler
|
// NewGui builds a new gui handler
|
||||||
func NewGui(log *logrus.Entry, gitCommand *commands.GitCommand, oSCommand *commands.OSCommand, tr *i18n.Localizer, config config.AppConfigurer, updater *updates.Updater) (*Gui, error) {
|
func NewGui(log *logrus.Entry, gitCommand *commands.GitCommand, oSCommand *commands.OSCommand, tr *i18n.Localizer, config config.AppConfigurer, updater *updates.Updater) (*Gui, error) {
|
||||||
|
|
||||||
initialState := guiState{
|
initialState := &guiState{
|
||||||
Files: make([]*commands.File, 0),
|
Files: make([]*commands.File, 0),
|
||||||
PreviousView: "files",
|
PreviousView: "files",
|
||||||
Commits: make([]*commands.Commit, 0),
|
Commits: make([]*commands.Commit, 0),
|
||||||
@@ -247,6 +250,7 @@ func NewGui(log *logrus.Entry, gitCommand *commands.GitCommand, oSCommand *comma
|
|||||||
},
|
},
|
||||||
ScreenMode: SCREEN_NORMAL,
|
ScreenMode: SCREEN_NORMAL,
|
||||||
SideView: nil,
|
SideView: nil,
|
||||||
|
Ptmx: nil,
|
||||||
}
|
}
|
||||||
|
|
||||||
gui := &Gui{
|
gui := &Gui{
|
||||||
@@ -274,6 +278,10 @@ func (gui *Gui) nextScreenMode(g *gocui.Gui, v *gocui.View) error {
|
|||||||
if err := gui.refreshCommitsViewWithSelection(); err != nil {
|
if err := gui.refreshCommitsViewWithSelection(); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
// same with branches
|
||||||
|
if err := gui.refreshBranchesViewWithSelection(); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@@ -284,6 +292,10 @@ func (gui *Gui) prevScreenMode(g *gocui.Gui, v *gocui.View) error {
|
|||||||
if err := gui.refreshCommitsViewWithSelection(); err != nil {
|
if err := gui.refreshCommitsViewWithSelection(); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
// same with branches
|
||||||
|
if err := gui.refreshBranchesViewWithSelection(); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@@ -377,15 +389,11 @@ func (gui *Gui) onFocusLost(v *gocui.View, newView *gocui.View) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
if v.IsSearching() && newView.Name() != "search" {
|
if v.IsSearching() && newView.Name() != "search" {
|
||||||
gui.onSearchEscape()
|
if err := gui.onSearchEscape(); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
}
|
}
|
||||||
switch v.Name() {
|
switch v.Name() {
|
||||||
case "branches":
|
|
||||||
if v.Context == "local-branches" {
|
|
||||||
// This stops the branches panel from showing the upstream/downstream changes to the selected branch, when it loses focus
|
|
||||||
displayStrings := presentation.GetBranchListDisplayStrings(gui.State.Branches, false, -1)
|
|
||||||
gui.renderDisplayStrings(gui.getBranchesView(), displayStrings)
|
|
||||||
}
|
|
||||||
case "main":
|
case "main":
|
||||||
// if we have lost focus to a first-class panel, we need to do some cleanup
|
// if we have lost focus to a first-class panel, we need to do some cleanup
|
||||||
gui.changeMainViewsContext("normal")
|
gui.changeMainViewsContext("normal")
|
||||||
@@ -487,6 +495,9 @@ func (gui *Gui) layout(g *gocui.Gui) error {
|
|||||||
donate := color.New(color.FgMagenta, color.Underline).Sprint(gui.Tr.SLocalize("Donate"))
|
donate := color.New(color.FgMagenta, color.Underline).Sprint(gui.Tr.SLocalize("Donate"))
|
||||||
information = donate + " " + information
|
information = donate + " " + information
|
||||||
}
|
}
|
||||||
|
if len(gui.State.CherryPickedCommits) > 0 {
|
||||||
|
information = utils.ColoredString(fmt.Sprintf("%d commits copied", len(gui.State.CherryPickedCommits)), color.FgCyan)
|
||||||
|
}
|
||||||
|
|
||||||
minimumHeight := 9
|
minimumHeight := 9
|
||||||
minimumWidth := 10
|
minimumWidth := 10
|
||||||
@@ -514,13 +525,15 @@ func (gui *Gui) layout(g *gocui.Gui) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
_, _ = g.SetViewOnBottom("limit")
|
_, _ = g.SetViewOnBottom("limit")
|
||||||
g.DeleteView("limit")
|
_ = g.DeleteView("limit")
|
||||||
|
|
||||||
|
sidePanelWidthRatio := gui.Config.GetUserConfig().GetFloat64("gui.sidePanelWidth")
|
||||||
|
|
||||||
textColor := theme.GocuiDefaultTextColor
|
textColor := theme.GocuiDefaultTextColor
|
||||||
var leftSideWidth int
|
var leftSideWidth int
|
||||||
switch gui.State.ScreenMode {
|
switch gui.State.ScreenMode {
|
||||||
case SCREEN_NORMAL:
|
case SCREEN_NORMAL:
|
||||||
leftSideWidth = width / 3
|
leftSideWidth = int(float64(width) * sidePanelWidthRatio)
|
||||||
case SCREEN_HALF:
|
case SCREEN_HALF:
|
||||||
leftSideWidth = width / 2
|
leftSideWidth = width / 2
|
||||||
case SCREEN_FULL:
|
case SCREEN_FULL:
|
||||||
@@ -532,7 +545,6 @@ func (gui *Gui) layout(g *gocui.Gui) error {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
panelSplitX := width - 1
|
|
||||||
mainPanelLeft := leftSideWidth + 1
|
mainPanelLeft := leftSideWidth + 1
|
||||||
mainPanelRight := width - 1
|
mainPanelRight := width - 1
|
||||||
secondaryPanelLeft := width - 1
|
secondaryPanelLeft := width - 1
|
||||||
@@ -541,7 +553,7 @@ func (gui *Gui) layout(g *gocui.Gui) error {
|
|||||||
if gui.State.SplitMainPanel {
|
if gui.State.SplitMainPanel {
|
||||||
if gui.State.ScreenMode == SCREEN_FULL {
|
if gui.State.ScreenMode == SCREEN_FULL {
|
||||||
mainPanelLeft = 0
|
mainPanelLeft = 0
|
||||||
panelSplitX = width/2 - 4
|
panelSplitX := width/2 - 4
|
||||||
mainPanelRight = panelSplitX
|
mainPanelRight = panelSplitX
|
||||||
secondaryPanelLeft = panelSplitX + 1
|
secondaryPanelLeft = panelSplitX + 1
|
||||||
} else if width < 220 {
|
} else if width < 220 {
|
||||||
@@ -552,7 +564,7 @@ func (gui *Gui) layout(g *gocui.Gui) error {
|
|||||||
units := 5
|
units := 5
|
||||||
leftSideWidth = width / units
|
leftSideWidth = width / units
|
||||||
mainPanelLeft = leftSideWidth + 1
|
mainPanelLeft = leftSideWidth + 1
|
||||||
panelSplitX = (1 + ((units - 1) / 2)) * width / units
|
panelSplitX := (1 + ((units - 1) / 2)) * width / units
|
||||||
mainPanelRight = panelSplitX
|
mainPanelRight = panelSplitX
|
||||||
secondaryPanelLeft = panelSplitX + 1
|
secondaryPanelLeft = panelSplitX + 1
|
||||||
}
|
}
|
||||||
@@ -687,7 +699,7 @@ func (gui *Gui) layout(g *gocui.Gui) error {
|
|||||||
if err.Error() != "unknown view" {
|
if err.Error() != "unknown view" {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
g.SetViewOnBottom("commitMessage")
|
_, _ = g.SetViewOnBottom("commitMessage")
|
||||||
commitMessageView.Title = gui.Tr.SLocalize("CommitMessage")
|
commitMessageView.Title = gui.Tr.SLocalize("CommitMessage")
|
||||||
commitMessageView.FgColor = textColor
|
commitMessageView.FgColor = textColor
|
||||||
commitMessageView.Editable = true
|
commitMessageView.Editable = true
|
||||||
@@ -752,22 +764,25 @@ func (gui *Gui) layout(g *gocui.Gui) error {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if v, err := g.SetView("information", optionsVersionBoundary-1, height-2, width, height, 0); err != nil {
|
informationView, err := g.SetView("information", optionsVersionBoundary-1, height-2, width, height, 0)
|
||||||
|
if err != nil {
|
||||||
if err.Error() != "unknown view" {
|
if err.Error() != "unknown view" {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
v.BgColor = gocui.ColorDefault
|
informationView.BgColor = gocui.ColorDefault
|
||||||
v.FgColor = gocui.ColorGreen
|
informationView.FgColor = gocui.ColorGreen
|
||||||
v.Frame = false
|
informationView.Frame = false
|
||||||
if err := gui.renderString(g, "information", information); err != nil {
|
gui.renderString(g, "information", information)
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
// doing this here because it'll only happen once
|
// doing this here because it'll only happen once
|
||||||
if err := gui.onInitialViewsCreation(); err != nil {
|
if err := gui.onInitialViewsCreation(); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if gui.State.OldInformation != information {
|
||||||
|
gui.setViewContent(g, informationView, information)
|
||||||
|
gui.State.OldInformation = information
|
||||||
|
}
|
||||||
|
|
||||||
if gui.g.CurrentView() == nil {
|
if gui.g.CurrentView() == nil {
|
||||||
if _, err := gui.g.SetCurrentView(gui.getFilesView().Name()); err != nil {
|
if _, err := gui.g.SetCurrentView(gui.getFilesView().Name()); err != nil {
|
||||||
@@ -806,7 +821,14 @@ func (gui *Gui) layout(g *gocui.Gui) error {
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
// check if the selected line is now out of view and if so refocus it
|
// check if the selected line is now out of view and if so refocus it
|
||||||
if err := gui.focusPoint(0, listView.selectedLine, listView.lineCount, listView.view); err != nil {
|
listView.view.FocusPoint(0, listView.selectedLine)
|
||||||
|
}
|
||||||
|
|
||||||
|
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
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -894,7 +916,8 @@ func (gui *Gui) fetch(g *gocui.Gui, v *gocui.View, canAskForCredentials bool) (u
|
|||||||
_ = gui.createConfirmationPanel(g, v, true, gui.Tr.SLocalize("Error"), coloredMessage, close, close)
|
_ = gui.createConfirmationPanel(g, v, true, gui.Tr.SLocalize("Error"), coloredMessage, close, close)
|
||||||
}
|
}
|
||||||
|
|
||||||
gui.refreshStatus(g)
|
_ = gui.refreshStatus(g)
|
||||||
|
|
||||||
return unamePassOpend, err
|
return unamePassOpend, err
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -903,7 +926,7 @@ func (gui *Gui) renderGlobalOptions() error {
|
|||||||
fmt.Sprintf("%s/%s", gui.getKeyDisplay("universal.scrollUpMain"), gui.getKeyDisplay("universal.scrollDownMain")): gui.Tr.SLocalize("scroll"),
|
fmt.Sprintf("%s/%s", gui.getKeyDisplay("universal.scrollUpMain"), gui.getKeyDisplay("universal.scrollDownMain")): gui.Tr.SLocalize("scroll"),
|
||||||
fmt.Sprintf("%s %s %s %s", gui.getKeyDisplay("universal.prevBlock"), gui.getKeyDisplay("universal.nextBlock"), gui.getKeyDisplay("universal.prevItem"), gui.getKeyDisplay("universal.nextItem")): gui.Tr.SLocalize("navigate"),
|
fmt.Sprintf("%s %s %s %s", gui.getKeyDisplay("universal.prevBlock"), gui.getKeyDisplay("universal.nextBlock"), gui.getKeyDisplay("universal.prevItem"), gui.getKeyDisplay("universal.nextItem")): gui.Tr.SLocalize("navigate"),
|
||||||
fmt.Sprintf("%s/%s", gui.getKeyDisplay("universal.return"), gui.getKeyDisplay("universal.quit")): gui.Tr.SLocalize("close"),
|
fmt.Sprintf("%s/%s", gui.getKeyDisplay("universal.return"), gui.getKeyDisplay("universal.quit")): gui.Tr.SLocalize("close"),
|
||||||
fmt.Sprintf("%s", gui.getKeyDisplay("universal.optionMenu")): gui.Tr.SLocalize("menu"),
|
gui.getKeyDisplay("universal.optionMenu"): gui.Tr.SLocalize("menu"),
|
||||||
"1-5": gui.Tr.SLocalize("jump"),
|
"1-5": gui.Tr.SLocalize("jump"),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@@ -942,7 +965,7 @@ func (gui *Gui) startBackgroundFetch() {
|
|||||||
|
|
||||||
// Run setup the gui with keybindings and start the mainloop
|
// Run setup the gui with keybindings and start the mainloop
|
||||||
func (gui *Gui) Run() error {
|
func (gui *Gui) Run() error {
|
||||||
g, err := gocui.NewGui(gocui.OutputNormal, OverlappingEdges)
|
g, err := gocui.NewGui(gocui.Output256, OverlappingEdges)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|||||||
+46
-32
@@ -162,15 +162,15 @@ func (gui *Gui) getKeyDisplay(name string) string {
|
|||||||
func GetKeyDisplay(key interface{}) string {
|
func GetKeyDisplay(key interface{}) string {
|
||||||
keyInt := 0
|
keyInt := 0
|
||||||
|
|
||||||
switch key.(type) {
|
switch key := key.(type) {
|
||||||
case rune:
|
case rune:
|
||||||
keyInt = int(key.(rune))
|
keyInt = int(key)
|
||||||
case gocui.Key:
|
case gocui.Key:
|
||||||
value, ok := keyMapReversed[key.(gocui.Key)]
|
value, ok := keyMapReversed[key]
|
||||||
if ok {
|
if ok {
|
||||||
return value
|
return value
|
||||||
}
|
}
|
||||||
keyInt = int(key.(gocui.Key))
|
keyInt = int(key)
|
||||||
}
|
}
|
||||||
|
|
||||||
return string(keyInt)
|
return string(keyInt)
|
||||||
@@ -225,6 +225,7 @@ func (gui *Gui) GetInitialKeybindings() []*Binding {
|
|||||||
Modifier: gocui.ModNone,
|
Modifier: gocui.ModNone,
|
||||||
Handler: gui.scrollUpMain,
|
Handler: gui.scrollUpMain,
|
||||||
Alternative: "fn+up",
|
Alternative: "fn+up",
|
||||||
|
Description: gui.Tr.SLocalize("scrollUpMainPanel"),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
ViewName: "",
|
ViewName: "",
|
||||||
@@ -232,6 +233,7 @@ func (gui *Gui) GetInitialKeybindings() []*Binding {
|
|||||||
Modifier: gocui.ModNone,
|
Modifier: gocui.ModNone,
|
||||||
Handler: gui.scrollDownMain,
|
Handler: gui.scrollDownMain,
|
||||||
Alternative: "fn+down",
|
Alternative: "fn+down",
|
||||||
|
Description: gui.Tr.SLocalize("scrollDownMainPanel"),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
ViewName: "",
|
ViewName: "",
|
||||||
@@ -293,10 +295,11 @@ func (gui *Gui) GetInitialKeybindings() []*Binding {
|
|||||||
Description: gui.Tr.SLocalize("refresh"),
|
Description: gui.Tr.SLocalize("refresh"),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
ViewName: "",
|
ViewName: "",
|
||||||
Key: gui.getKey("universal.optionMenu"),
|
Key: gui.getKey("universal.optionMenu"),
|
||||||
Modifier: gocui.ModNone,
|
Modifier: gocui.ModNone,
|
||||||
Handler: gui.handleCreateOptionsMenu,
|
Handler: gui.handleCreateOptionsMenu,
|
||||||
|
Description: gui.Tr.SLocalize("openMenu"),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
ViewName: "",
|
ViewName: "",
|
||||||
@@ -566,6 +569,14 @@ func (gui *Gui) GetInitialKeybindings() []*Binding {
|
|||||||
Handler: gui.handleCreateResetToBranchMenu,
|
Handler: gui.handleCreateResetToBranchMenu,
|
||||||
Description: gui.Tr.SLocalize("viewResetOptions"),
|
Description: gui.Tr.SLocalize("viewResetOptions"),
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
ViewName: "branches",
|
||||||
|
Contexts: []string{"local-branches"},
|
||||||
|
Key: gui.getKey("branches.renameBranch"),
|
||||||
|
Modifier: gocui.ModNone,
|
||||||
|
Handler: gui.handleRenameBranch,
|
||||||
|
Description: gui.Tr.SLocalize("renameBranch"),
|
||||||
|
},
|
||||||
{
|
{
|
||||||
ViewName: "branches",
|
ViewName: "branches",
|
||||||
Contexts: []string{"tags"},
|
Contexts: []string{"tags"},
|
||||||
@@ -655,10 +666,11 @@ func (gui *Gui) GetInitialKeybindings() []*Binding {
|
|||||||
Handler: gui.handlePrevCommitsTab,
|
Handler: gui.handlePrevCommitsTab,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
ViewName: "commits",
|
ViewName: "commits",
|
||||||
Key: gui.getKey("universal.startSearch"),
|
Key: gui.getKey("universal.startSearch"),
|
||||||
Modifier: gocui.ModNone,
|
Modifier: gocui.ModNone,
|
||||||
Handler: gui.handleOpenSearchForCommitsPanel,
|
Handler: gui.handleOpenSearchForCommitsPanel,
|
||||||
|
Description: gui.Tr.SLocalize("startSearch"),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
ViewName: "commits",
|
ViewName: "commits",
|
||||||
@@ -828,6 +840,14 @@ func (gui *Gui) GetInitialKeybindings() []*Binding {
|
|||||||
Handler: gui.handleTagCommit,
|
Handler: gui.handleTagCommit,
|
||||||
Description: gui.Tr.SLocalize("tagCommit"),
|
Description: gui.Tr.SLocalize("tagCommit"),
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
ViewName: "commits",
|
||||||
|
Contexts: []string{"branch-commits"},
|
||||||
|
Key: gui.getKey("commits.resetCherryPick"),
|
||||||
|
Modifier: gocui.ModNone,
|
||||||
|
Handler: gui.handleResetCherryPick,
|
||||||
|
Description: gui.Tr.SLocalize("resetCherryPick"),
|
||||||
|
},
|
||||||
{
|
{
|
||||||
ViewName: "commits",
|
ViewName: "commits",
|
||||||
Contexts: []string{"reflog-commits"},
|
Contexts: []string{"reflog-commits"},
|
||||||
@@ -890,16 +910,18 @@ func (gui *Gui) GetInitialKeybindings() []*Binding {
|
|||||||
Handler: gui.handleCloseCredentialsView,
|
Handler: gui.handleCloseCredentialsView,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
ViewName: "menu",
|
ViewName: "menu",
|
||||||
Key: gui.getKey("universal.return"),
|
Key: gui.getKey("universal.return"),
|
||||||
Modifier: gocui.ModNone,
|
Modifier: gocui.ModNone,
|
||||||
Handler: gui.handleMenuClose,
|
Handler: gui.handleMenuClose,
|
||||||
|
Description: gui.Tr.SLocalize("closeMenu"),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
ViewName: "menu",
|
ViewName: "menu",
|
||||||
Key: gui.getKey("universal.quit"),
|
Key: gui.getKey("universal.quit"),
|
||||||
Modifier: gocui.ModNone,
|
Modifier: gocui.ModNone,
|
||||||
Handler: gui.handleMenuClose,
|
Handler: gui.handleMenuClose,
|
||||||
|
Description: gui.Tr.SLocalize("closeMenu"),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
ViewName: "information",
|
ViewName: "information",
|
||||||
@@ -1013,7 +1035,7 @@ func (gui *Gui) GetInitialKeybindings() []*Binding {
|
|||||||
Contexts: []string{"staging"},
|
Contexts: []string{"staging"},
|
||||||
Key: gui.getKey("universal.select"),
|
Key: gui.getKey("universal.select"),
|
||||||
Modifier: gocui.ModNone,
|
Modifier: gocui.ModNone,
|
||||||
Handler: gui.handleStageSelection,
|
Handler: gui.handleToggleStagedSelection,
|
||||||
Description: gui.Tr.SLocalize("StageSelection"),
|
Description: gui.Tr.SLocalize("StageSelection"),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -1135,16 +1157,8 @@ func (gui *Gui) GetInitialKeybindings() []*Binding {
|
|||||||
Contexts: []string{"patch-building"},
|
Contexts: []string{"patch-building"},
|
||||||
Key: gui.getKey("universal.select"),
|
Key: gui.getKey("universal.select"),
|
||||||
Modifier: gocui.ModNone,
|
Modifier: gocui.ModNone,
|
||||||
Handler: gui.handleAddSelectionToPatch,
|
Handler: gui.handleToggleSelectionForPatch,
|
||||||
Description: gui.Tr.SLocalize("StageSelection"),
|
Description: gui.Tr.SLocalize("ToggleSelectionForPatch"),
|
||||||
},
|
|
||||||
{
|
|
||||||
ViewName: "main",
|
|
||||||
Contexts: []string{"patch-building"},
|
|
||||||
Key: gui.getKey("universal.remove"),
|
|
||||||
Modifier: gocui.ModNone,
|
|
||||||
Handler: gui.handleRemoveSelectionFromPatch,
|
|
||||||
Description: gui.Tr.SLocalize("ResetSelection"),
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
ViewName: "main",
|
ViewName: "main",
|
||||||
@@ -1460,7 +1474,7 @@ func (gui *Gui) GetInitialKeybindings() []*Binding {
|
|||||||
|
|
||||||
// we need a specific keybinding for the commits panel beacuse it usually lazyloads commits
|
// we need a specific keybinding for the commits panel beacuse it usually lazyloads commits
|
||||||
if listView.viewName != "commits" {
|
if listView.viewName != "commits" {
|
||||||
bindings = append(bindings, &Binding{ViewName: listView.viewName, Contexts: []string{listView.context}, Key: gui.getKey("universal.startSearch"), Modifier: gocui.ModNone, Handler: gui.handleOpenSearch})
|
bindings = append(bindings, &Binding{ViewName: listView.viewName, Contexts: []string{listView.context}, Key: gui.getKey("universal.startSearch"), Modifier: gocui.ModNone, Handler: gui.handleOpenSearch, Description: gui.Tr.SLocalize("startSearch")})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -88,7 +88,8 @@ func (gui *Gui) refreshLineByLinePanel(diff string, secondaryDiff string, second
|
|||||||
}
|
}
|
||||||
|
|
||||||
gui.g.Update(func(*gocui.Gui) error {
|
gui.g.Update(func(*gocui.Gui) error {
|
||||||
return gui.setViewContent(gui.g, gui.getSecondaryView(), secondaryPatchParser.Render(-1, -1, nil))
|
gui.setViewContent(gui.g, gui.getSecondaryView(), secondaryPatchParser.Render(-1, -1, nil))
|
||||||
|
return nil
|
||||||
})
|
})
|
||||||
|
|
||||||
return false, nil
|
return false, nil
|
||||||
@@ -220,6 +221,10 @@ func (gui *Gui) handleMouseScrollDown(g *gocui.Gui, v *gocui.View) error {
|
|||||||
return gui.handleCycleLine(1)
|
return gui.handleCycleLine(1)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (gui *Gui) getSelectedCommitFileName() string {
|
||||||
|
return gui.State.CommitFiles[gui.State.Panels.CommitFiles.SelectedLine].Name
|
||||||
|
}
|
||||||
|
|
||||||
func (gui *Gui) refreshMainView() error {
|
func (gui *Gui) refreshMainView() error {
|
||||||
state := gui.State.Panels.LineByLine
|
state := gui.State.Panels.LineByLine
|
||||||
|
|
||||||
@@ -227,7 +232,7 @@ func (gui *Gui) refreshMainView() error {
|
|||||||
// I'd prefer not to have knowledge of contexts using this file but I'm not sure
|
// I'd prefer not to have knowledge of contexts using this file but I'm not sure
|
||||||
// how to get around this
|
// how to get around this
|
||||||
if gui.State.MainContext == "patch-building" {
|
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)
|
includedLineIndices = gui.GitCommand.PatchManager.GetFileIncLineIndices(filename)
|
||||||
}
|
}
|
||||||
colorDiff := state.PatchParser.Render(state.FirstLineIdx, state.LastLineIdx, includedLineIndices)
|
colorDiff := state.PatchParser.Render(state.FirstLineIdx, state.LastLineIdx, includedLineIndices)
|
||||||
@@ -237,7 +242,8 @@ func (gui *Gui) refreshMainView() error {
|
|||||||
mainView.Wrap = false
|
mainView.Wrap = false
|
||||||
|
|
||||||
gui.g.Update(func(*gocui.Gui) error {
|
gui.g.Update(func(*gocui.Gui) error {
|
||||||
return gui.setViewContent(gui.g, gui.getMainView(), colorDiff)
|
gui.setViewContent(gui.g, gui.getMainView(), colorDiff)
|
||||||
|
return nil
|
||||||
})
|
})
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
|
|||||||
@@ -17,7 +17,8 @@ type menuItem struct {
|
|||||||
// list panel functions
|
// list panel functions
|
||||||
|
|
||||||
func (gui *Gui) handleMenuSelect(g *gocui.Gui, v *gocui.View) error {
|
func (gui *Gui) handleMenuSelect(g *gocui.Gui, v *gocui.View) error {
|
||||||
return gui.focusPoint(0, gui.State.Panels.Menu.SelectedLine, gui.State.MenuItemCount, v)
|
v.FocusPoint(0, gui.State.Panels.Menu.SelectedLine)
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// specific functions
|
// specific functions
|
||||||
|
|||||||
+12
-6
@@ -151,13 +151,19 @@ func (gui *Gui) handlePopFileSnapshot(g *gocui.Gui, v *gocui.View) error {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
ioutil.WriteFile(gitFile.Name, []byte(prevContent), 0644)
|
if err := ioutil.WriteFile(gitFile.Name, []byte(prevContent), 0644); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
return gui.refreshMergePanel()
|
return gui.refreshMergePanel()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (gui *Gui) handlePickHunk(g *gocui.Gui, v *gocui.View) error {
|
func (gui *Gui) handlePickHunk(g *gocui.Gui, v *gocui.View) error {
|
||||||
conflict := gui.State.Panels.Merging.Conflicts[gui.State.Panels.Merging.ConflictIndex]
|
conflict := gui.State.Panels.Merging.Conflicts[gui.State.Panels.Merging.ConflictIndex]
|
||||||
gui.pushFileSnapshot(g)
|
if err := gui.pushFileSnapshot(g); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
pick := "bottom"
|
pick := "bottom"
|
||||||
if gui.State.Panels.Merging.ConflictTop {
|
if gui.State.Panels.Merging.ConflictTop {
|
||||||
pick = "top"
|
pick = "top"
|
||||||
@@ -178,7 +184,9 @@ func (gui *Gui) handlePickHunk(g *gocui.Gui, v *gocui.View) error {
|
|||||||
|
|
||||||
func (gui *Gui) handlePickBothHunks(g *gocui.Gui, v *gocui.View) error {
|
func (gui *Gui) handlePickBothHunks(g *gocui.Gui, v *gocui.View) error {
|
||||||
conflict := gui.State.Panels.Merging.Conflicts[gui.State.Panels.Merging.ConflictIndex]
|
conflict := gui.State.Panels.Merging.Conflicts[gui.State.Panels.Merging.ConflictIndex]
|
||||||
gui.pushFileSnapshot(g)
|
if err := gui.pushFileSnapshot(g); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
err := gui.resolveConflict(g, conflict, "both")
|
err := gui.resolveConflict(g, conflict, "both")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
@@ -215,9 +223,7 @@ func (gui *Gui) refreshMergePanel() error {
|
|||||||
|
|
||||||
mainView := gui.getMainView()
|
mainView := gui.getMainView()
|
||||||
mainView.Wrap = false
|
mainView.Wrap = false
|
||||||
if err := gui.setViewContent(gui.g, mainView, content); err != nil {
|
gui.setViewContent(gui.g, mainView, content)
|
||||||
return err
|
|
||||||
}
|
|
||||||
gui.Log.Warn("scrolling to conflict")
|
gui.Log.Warn("scrolling to conflict")
|
||||||
if err := gui.scrollToConflict(gui.g); err != nil {
|
if err := gui.scrollToConflict(gui.g); err != nil {
|
||||||
return err
|
return err
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ package gui
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/jesseduffield/gocui"
|
"github.com/jesseduffield/gocui"
|
||||||
|
"github.com/jesseduffield/lazygit/pkg/utils"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (gui *Gui) refreshPatchBuildingPanel(selectedLineIdx int) error {
|
func (gui *Gui) refreshPatchBuildingPanel(selectedLineIdx int) error {
|
||||||
@@ -17,7 +18,8 @@ func (gui *Gui) refreshPatchBuildingPanel(selectedLineIdx int) error {
|
|||||||
// get diff from commit file that's currently selected
|
// get diff from commit file that's currently selected
|
||||||
commitFile := gui.getSelectedCommitFile(gui.g)
|
commitFile := gui.getSelectedCommitFile(gui.g)
|
||||||
if commitFile == nil {
|
if commitFile == nil {
|
||||||
return gui.renderString(gui.g, "commitFiles", gui.Tr.SLocalize("NoCommiteFiles"))
|
gui.renderString(gui.g, "commitFiles", gui.Tr.SLocalize("NoCommiteFiles"))
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
diff, err := gui.GitCommand.ShowCommitFile(commitFile.Sha, commitFile.Name, true)
|
diff, err := gui.GitCommand.ShowCommitFile(commitFile.Sha, commitFile.Name, true)
|
||||||
@@ -42,38 +44,25 @@ func (gui *Gui) refreshPatchBuildingPanel(selectedLineIdx int) error {
|
|||||||
return nil
|
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
|
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
|
// add range of lines to those set for the file
|
||||||
commitFile := gui.getSelectedCommitFile(gui.g)
|
commitFile := gui.getSelectedCommitFile(gui.g)
|
||||||
if commitFile == nil {
|
if commitFile == nil {
|
||||||
return gui.renderString(gui.g, "commitFiles", gui.Tr.SLocalize("NoCommiteFiles"))
|
gui.renderString(gui.g, "commitFiles", gui.Tr.SLocalize("NoCommiteFiles"))
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
gui.GitCommand.PatchManager.AddFileLineRange(commitFile.Name, state.FirstLineIdx, state.LastLineIdx)
|
toggleFunc(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)
|
|
||||||
|
|
||||||
if err := gui.refreshCommitFilesView(); err != nil {
|
if err := gui.refreshCommitFilesView(); err != nil {
|
||||||
return err
|
return err
|
||||||
@@ -105,7 +94,8 @@ func (gui *Gui) refreshSecondaryPatchPanel() error {
|
|||||||
secondaryView.Wrap = false
|
secondaryView.Wrap = false
|
||||||
|
|
||||||
gui.g.Update(func(*gocui.Gui) error {
|
gui.g.Update(func(*gocui.Gui) error {
|
||||||
return gui.setViewContent(gui.g, gui.getSecondaryView(), gui.GitCommand.PatchManager.RenderAggregatedPatchColored(false))
|
gui.setViewContent(gui.g, gui.getSecondaryView(), gui.GitCommand.PatchManager.RenderAggregatedPatchColored(false))
|
||||||
|
return nil
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
gui.State.SplitMainPanel = false
|
gui.State.SplitMainPanel = false
|
||||||
|
|||||||
@@ -10,25 +10,38 @@ import (
|
|||||||
"github.com/jesseduffield/lazygit/pkg/utils"
|
"github.com/jesseduffield/lazygit/pkg/utils"
|
||||||
)
|
)
|
||||||
|
|
||||||
func GetBranchListDisplayStrings(branches []*commands.Branch, isFocused bool, selectedLine int) [][]string {
|
func GetBranchListDisplayStrings(branches []*commands.Branch, fullDescription bool) [][]string {
|
||||||
lines := make([][]string, len(branches))
|
lines := make([][]string, len(branches))
|
||||||
|
|
||||||
for i := range branches {
|
for i := range branches {
|
||||||
showUpstreamDifferences := isFocused && i == selectedLine
|
lines[i] = getBranchDisplayStrings(branches[i], fullDescription)
|
||||||
lines[i] = getBranchDisplayStrings(branches[i], showUpstreamDifferences)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return lines
|
return lines
|
||||||
}
|
}
|
||||||
|
|
||||||
// getBranchDisplayStrings returns the display string of branch
|
// getBranchDisplayStrings returns the display string of branch
|
||||||
func getBranchDisplayStrings(b *commands.Branch, showUpstreamDifferences bool) []string {
|
func getBranchDisplayStrings(b *commands.Branch, fullDescription bool) []string {
|
||||||
displayName := utils.ColoredString(b.Name, GetBranchColor(b.Name))
|
displayName := utils.ColoredString(b.Name, GetBranchColor(b.Name))
|
||||||
if showUpstreamDifferences && b.Pushables != "" && b.Pullables != "" {
|
if b.Pushables != "" && b.Pullables != "" && b.Pushables != "?" && b.Pullables != "?" {
|
||||||
displayName = fmt.Sprintf("%s ↑%s↓%s", displayName, b.Pushables, b.Pullables)
|
trackColor := color.FgYellow
|
||||||
|
if b.Pushables == "0" && b.Pullables == "0" {
|
||||||
|
trackColor = color.FgGreen
|
||||||
|
}
|
||||||
|
track := utils.ColoredString(fmt.Sprintf("↑%s↓%s", b.Pushables, b.Pullables), trackColor)
|
||||||
|
displayName = fmt.Sprintf("%s %s", displayName, track)
|
||||||
}
|
}
|
||||||
|
|
||||||
return []string{b.Recency, displayName}
|
recencyColor := color.FgCyan
|
||||||
|
if b.Recency == " *" {
|
||||||
|
recencyColor = color.FgGreen
|
||||||
|
}
|
||||||
|
|
||||||
|
if fullDescription {
|
||||||
|
return []string{utils.ColoredString(b.Recency, recencyColor), displayName, utils.ColoredString(b.UpstreamName, color.FgYellow)}
|
||||||
|
}
|
||||||
|
|
||||||
|
return []string{utils.ColoredString(b.Recency, recencyColor), displayName}
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetBranchColor branch color
|
// GetBranchColor branch color
|
||||||
|
|||||||
@@ -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
|
||||||
|
}
|
||||||
@@ -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)
|
||||||
|
}
|
||||||
@@ -17,11 +17,11 @@ func (gui *Gui) handleCreateRebaseOptionsMenu(g *gocui.Gui, v *gocui.View) error
|
|||||||
menuItems := make([]*menuItem, len(options))
|
menuItems := make([]*menuItem, len(options))
|
||||||
for i, option := range options {
|
for i, option := range options {
|
||||||
// note to self. Never, EVER, close over loop variables in a function
|
// note to self. Never, EVER, close over loop variables in a function
|
||||||
innerOption := option
|
option := option
|
||||||
menuItems[i] = &menuItem{
|
menuItems[i] = &menuItem{
|
||||||
displayString: innerOption,
|
displayString: option,
|
||||||
onPress: func() error {
|
onPress: func() error {
|
||||||
return gui.genericMergeCommand(innerOption)
|
return gui.genericMergeCommand(option)
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -34,14 +34,12 @@ func (gui *Gui) handleReflogCommitSelect(g *gocui.Gui, v *gocui.View) error {
|
|||||||
if commit == nil {
|
if commit == nil {
|
||||||
return gui.newStringTask("main", "No reflog history")
|
return gui.newStringTask("main", "No reflog history")
|
||||||
}
|
}
|
||||||
if err := gui.focusPoint(0, gui.State.Panels.ReflogCommits.SelectedLine, len(gui.State.ReflogCommits), v); err != nil {
|
v.FocusPoint(0, gui.State.Panels.ReflogCommits.SelectedLine)
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
cmd := gui.OSCommand.ExecutableFromString(
|
cmd := gui.OSCommand.ExecutableFromString(
|
||||||
gui.GitCommand.ShowCmdStr(commit.Sha),
|
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)
|
gui.Log.Error(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -38,10 +38,7 @@ func (gui *Gui) handleRemoteBranchSelect(g *gocui.Gui, v *gocui.View) error {
|
|||||||
return gui.newStringTask("main", "No branches for this remote")
|
return gui.newStringTask("main", "No branches for this remote")
|
||||||
}
|
}
|
||||||
|
|
||||||
gui.focusPoint(0, gui.State.Panels.Menu.SelectedLine, gui.State.MenuItemCount, v)
|
v.FocusPoint(0, gui.State.Panels.RemoteBranches.SelectedLine)
|
||||||
if err := gui.focusPoint(0, gui.State.Panels.RemoteBranches.SelectedLine, len(gui.State.RemoteBranches), v); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
branchName := fmt.Sprintf("%s/%s", remote.Name, remoteBranch.Name)
|
branchName := fmt.Sprintf("%s/%s", remote.Name, remoteBranch.Name)
|
||||||
|
|
||||||
|
|||||||
@@ -39,9 +39,7 @@ func (gui *Gui) handleRemoteSelect(g *gocui.Gui, v *gocui.View) error {
|
|||||||
if remote == nil {
|
if remote == nil {
|
||||||
return gui.newStringTask("main", "No remotes")
|
return gui.newStringTask("main", "No remotes")
|
||||||
}
|
}
|
||||||
if err := gui.focusPoint(0, gui.State.Panels.Remotes.SelectedLine, len(gui.State.Remotes), v); err != nil {
|
v.FocusPoint(0, gui.State.Panels.Remotes.SelectedLine)
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
return gui.newStringTask("main", fmt.Sprintf("%s\nUrls:\n%s", utils.ColoredString(remote.Name, color.FgGreen), strings.Join(remote.Urls, "\n")))
|
return gui.newStringTask("main", fmt.Sprintf("%s\nUrls:\n%s", utils.ColoredString(remote.Name, color.FgGreen), strings.Join(remote.Urls, "\n")))
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -23,7 +23,10 @@ func (gui *Gui) createResetMenu(ref string) error {
|
|||||||
return gui.createErrorPanel(gui.g, err.Error())
|
return gui.createErrorPanel(gui.g, err.Error())
|
||||||
}
|
}
|
||||||
|
|
||||||
gui.switchCommitsPanelContext("branch-commits")
|
if err := gui.switchCommitsPanelContext("branch-commits"); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
gui.State.Panels.Commits.SelectedLine = 0
|
gui.State.Panels.Commits.SelectedLine = 0
|
||||||
gui.State.Panels.ReflogCommits.SelectedLine = 0
|
gui.State.Panels.ReflogCommits.SelectedLine = 0
|
||||||
|
|
||||||
@@ -33,6 +36,9 @@ func (gui *Gui) createResetMenu(ref string) error {
|
|||||||
if err := gui.refreshFiles(); err != nil {
|
if err := gui.refreshFiles(); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
if err := gui.refreshBranches(gui.g); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
if err := gui.resetOrigin(gui.getCommitsView()); err != nil {
|
if err := gui.resetOrigin(gui.getCommitsView()); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,14 +12,19 @@ func (gui *Gui) handleOpenSearch(g *gocui.Gui, v *gocui.View) error {
|
|||||||
gui.State.Searching.isSearching = true
|
gui.State.Searching.isSearching = true
|
||||||
gui.State.Searching.view = v
|
gui.State.Searching.view = v
|
||||||
gui.renderString(gui.g, "search", "")
|
gui.renderString(gui.g, "search", "")
|
||||||
gui.switchFocus(gui.g, v, gui.getSearchView())
|
if err := gui.switchFocus(gui.g, v, gui.getSearchView()); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (gui *Gui) handleSearch(g *gocui.Gui, v *gocui.View) error {
|
func (gui *Gui) handleSearch(g *gocui.Gui, v *gocui.View) error {
|
||||||
gui.State.Searching.searchString = gui.getSearchView().Buffer()
|
gui.State.Searching.searchString = gui.getSearchView().Buffer()
|
||||||
gui.switchFocus(gui.g, nil, gui.State.Searching.view)
|
if err := gui.switchFocus(gui.g, nil, gui.State.Searching.view); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
if err := gui.State.Searching.view.Search(gui.State.Searching.searchString); err != nil {
|
if err := gui.State.Searching.view.Search(gui.State.Searching.searchString); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@@ -85,7 +90,5 @@ func (gui *Gui) handleSearchEscape(g *gocui.Gui, v *gocui.View) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
gui.onSearchEscape()
|
return gui.onSearchEscape()
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
|||||||
+14
-21
@@ -99,26 +99,27 @@ func (gui *Gui) handleStagingEscape(g *gocui.Gui, v *gocui.View) error {
|
|||||||
return gui.switchFocus(gui.g, nil, gui.getFilesView())
|
return gui.switchFocus(gui.g, nil, gui.getFilesView())
|
||||||
}
|
}
|
||||||
|
|
||||||
func (gui *Gui) handleStageSelection(g *gocui.Gui, v *gocui.View) error {
|
func (gui *Gui) handleToggleStagedSelection(g *gocui.Gui, v *gocui.View) error {
|
||||||
return gui.applySelectionWithPrompt(false)
|
state := gui.State.Panels.LineByLine
|
||||||
|
|
||||||
|
return gui.applySelection(state.SecondaryFocused)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (gui *Gui) handleResetSelection(g *gocui.Gui, v *gocui.View) error {
|
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
|
state := gui.State.Panels.LineByLine
|
||||||
|
|
||||||
if !reverse && state.SecondaryFocused {
|
if state.SecondaryFocused {
|
||||||
return gui.createErrorPanel(gui.g, gui.Tr.SLocalize("CantStageStaged"))
|
// for backwards compatibility
|
||||||
} else if reverse && !state.SecondaryFocused && !gui.Config.GetUserConfig().GetBool("gui.skipUnstageLineWarning") {
|
return gui.applySelection(true)
|
||||||
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)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
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 {
|
func (gui *Gui) applySelection(reverse bool) error {
|
||||||
@@ -158,11 +159,3 @@ func (gui *Gui) applySelection(reverse bool) error {
|
|||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (gui *Gui) handleMouseDownSecondaryWhileStaging(g *gocui.Gui, v *gocui.View) error {
|
|
||||||
state := gui.State.Panels.LineByLine
|
|
||||||
|
|
||||||
state.SecondaryFocused = !state.SecondaryFocused
|
|
||||||
|
|
||||||
return gui.refreshStagingPanel(false, -1)
|
|
||||||
}
|
|
||||||
|
|||||||
+10
-8
@@ -34,14 +34,12 @@ func (gui *Gui) handleStashEntrySelect(g *gocui.Gui, v *gocui.View) error {
|
|||||||
if stashEntry == nil {
|
if stashEntry == nil {
|
||||||
return gui.newStringTask("main", gui.Tr.SLocalize("NoStashEntries"))
|
return gui.newStringTask("main", gui.Tr.SLocalize("NoStashEntries"))
|
||||||
}
|
}
|
||||||
if err := gui.focusPoint(0, gui.State.Panels.Stash.SelectedLine, len(gui.State.StashEntries), v); err != nil {
|
v.FocusPoint(0, gui.State.Panels.Stash.SelectedLine)
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
cmd := gui.OSCommand.ExecutableFromString(
|
cmd := gui.OSCommand.ExecutableFromString(
|
||||||
gui.GitCommand.ShowStashEntryCmdStr(stashEntry.Index),
|
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)
|
gui.Log.Error(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -97,9 +95,11 @@ func (gui *Gui) stashDo(g *gocui.Gui, v *gocui.View, method string) error {
|
|||||||
return gui.createErrorPanel(g, errorMessage)
|
return gui.createErrorPanel(g, errorMessage)
|
||||||
}
|
}
|
||||||
if err := gui.GitCommand.StashDo(stashEntry.Index, method); err != nil {
|
if err := gui.GitCommand.StashDo(stashEntry.Index, method); err != nil {
|
||||||
gui.createErrorPanel(g, err.Error())
|
return gui.createErrorPanel(g, err.Error())
|
||||||
|
}
|
||||||
|
if err := gui.refreshStashEntries(g); err != nil {
|
||||||
|
return gui.createErrorPanel(g, err.Error())
|
||||||
}
|
}
|
||||||
gui.refreshStashEntries(g)
|
|
||||||
return gui.refreshFiles()
|
return gui.refreshFiles()
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -109,9 +109,11 @@ func (gui *Gui) handleStashSave(stashFunc func(message string) error) error {
|
|||||||
}
|
}
|
||||||
return gui.createPromptPanel(gui.g, gui.getFilesView(), gui.Tr.SLocalize("StashChanges"), "", func(g *gocui.Gui, v *gocui.View) error {
|
return gui.createPromptPanel(gui.g, gui.getFilesView(), gui.Tr.SLocalize("StashChanges"), "", func(g *gocui.Gui, v *gocui.View) error {
|
||||||
if err := stashFunc(gui.trimmedContent(v)); err != nil {
|
if err := stashFunc(gui.trimmedContent(v)); err != nil {
|
||||||
gui.createErrorPanel(g, err.Error())
|
return gui.createErrorPanel(g, err.Error())
|
||||||
|
}
|
||||||
|
if err := gui.refreshStashEntries(g); err != nil {
|
||||||
|
return gui.createErrorPanel(g, err.Error())
|
||||||
}
|
}
|
||||||
gui.refreshStashEntries(g)
|
|
||||||
return gui.refreshFiles()
|
return gui.refreshFiles()
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|||||||
+10
-1
@@ -22,11 +22,20 @@ func (gui *Gui) refreshStatus(g *gocui.Gui) error {
|
|||||||
// contents end up cleared
|
// contents end up cleared
|
||||||
g.Update(func(*gocui.Gui) error {
|
g.Update(func(*gocui.Gui) error {
|
||||||
v.Clear()
|
v.Clear()
|
||||||
|
// TODO: base this off of the current branch
|
||||||
state.pushables, state.pullables = gui.GitCommand.GetCurrentBranchUpstreamDifferenceCount()
|
state.pushables, state.pullables = gui.GitCommand.GetCurrentBranchUpstreamDifferenceCount()
|
||||||
if err := gui.updateWorkTreeState(); err != nil {
|
if err := gui.updateWorkTreeState(); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
status := fmt.Sprintf("↑%s↓%s", state.pushables, state.pullables)
|
|
||||||
|
trackColor := color.FgYellow
|
||||||
|
if state.pushables == "0" && state.pullables == "0" {
|
||||||
|
trackColor = color.FgGreen
|
||||||
|
} else if state.pushables == "?" && state.pullables == "?" {
|
||||||
|
trackColor = color.FgRed
|
||||||
|
}
|
||||||
|
|
||||||
|
status := utils.ColoredString(fmt.Sprintf("↑%s↓%s", state.pushables, state.pullables), trackColor)
|
||||||
branches := gui.State.Branches
|
branches := gui.State.Branches
|
||||||
|
|
||||||
if gui.State.WorkingTreeState != "normal" {
|
if gui.State.WorkingTreeState != "normal" {
|
||||||
|
|||||||
@@ -34,9 +34,7 @@ func (gui *Gui) handleTagSelect(g *gocui.Gui, v *gocui.View) error {
|
|||||||
if tag == nil {
|
if tag == nil {
|
||||||
return gui.newStringTask("main", "No tags")
|
return gui.newStringTask("main", "No tags")
|
||||||
}
|
}
|
||||||
if err := gui.focusPoint(0, gui.State.Panels.Tags.SelectedLine, len(gui.State.Tags), v); err != nil {
|
v.FocusPoint(0, gui.State.Panels.Tags.SelectedLine)
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
cmd := gui.OSCommand.ExecutableFromString(
|
cmd := gui.OSCommand.ExecutableFromString(
|
||||||
gui.GitCommand.GetBranchGraphCmdStr(tag.Name),
|
gui.GitCommand.GetBranchGraphCmdStr(tag.Name),
|
||||||
@@ -57,7 +55,7 @@ func (gui *Gui) refreshTags() error {
|
|||||||
gui.State.Tags = tags
|
gui.State.Tags = tags
|
||||||
|
|
||||||
if gui.getBranchesView().Context == "tags" {
|
if gui.getBranchesView().Context == "tags" {
|
||||||
gui.renderTagsWithSelection()
|
return gui.renderTagsWithSelection()
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
|
|||||||
@@ -18,7 +18,17 @@ func (gui *Gui) newCmdTask(viewName string, cmd *exec.Cmd) error {
|
|||||||
|
|
||||||
manager := gui.getManager(view)
|
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
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -49,7 +59,8 @@ func (gui *Gui) newStringTask(viewName string, str string) error {
|
|||||||
manager := gui.getManager(view)
|
manager := gui.getManager(view)
|
||||||
|
|
||||||
f := func(stop chan struct{}) error {
|
f := func(stop chan struct{}) error {
|
||||||
return gui.renderString(gui.g, viewName, str)
|
gui.renderString(gui.g, viewName, str)
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := manager.NewTask(f); err != nil {
|
if err := manager.NewTask(f); err != nil {
|
||||||
@@ -69,7 +80,10 @@ func (gui *Gui) getManager(view *gocui.View) *tasks.ViewBufferManager {
|
|||||||
view.Clear()
|
view.Clear()
|
||||||
},
|
},
|
||||||
func() {
|
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
|
gui.viewBufferManagerMap[view.Name()] = manager
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-3
@@ -47,9 +47,7 @@ func (gui *Gui) startUpdating(newVersion string) {
|
|||||||
func (gui *Gui) onUpdateFinish(err error) error {
|
func (gui *Gui) onUpdateFinish(err error) error {
|
||||||
gui.State.Updating = false
|
gui.State.Updating = false
|
||||||
gui.statusManager.removeStatus("updating")
|
gui.statusManager.removeStatus("updating")
|
||||||
if err := gui.renderString(gui.g, "appStatus", ""); err != nil {
|
gui.renderString(gui.g, "appStatus", "")
|
||||||
return err
|
|
||||||
}
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return gui.createErrorPanel(gui.g, "Update failed: "+err.Error())
|
return gui.createErrorPanel(gui.g, "Update failed: "+err.Error())
|
||||||
}
|
}
|
||||||
|
|||||||
+6
-33
@@ -218,25 +218,18 @@ func (gui *Gui) resetOrigin(v *gocui.View) error {
|
|||||||
return v.SetOrigin(0, 0)
|
return v.SetOrigin(0, 0)
|
||||||
}
|
}
|
||||||
|
|
||||||
// if the cursor down past the last item, move it to the last line
|
|
||||||
func (gui *Gui) focusPoint(cx int, cy int, lineCount int, v *gocui.View) error {
|
|
||||||
v.FocusPoint(cx, cy)
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (gui *Gui) cleanString(s string) string {
|
func (gui *Gui) cleanString(s string) string {
|
||||||
output := string(bom.Clean([]byte(s)))
|
output := string(bom.Clean([]byte(s)))
|
||||||
return utils.NormalizeLinefeeds(output)
|
return utils.NormalizeLinefeeds(output)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (gui *Gui) setViewContent(g *gocui.Gui, v *gocui.View, s string) error {
|
func (gui *Gui) setViewContent(g *gocui.Gui, v *gocui.View, s string) {
|
||||||
v.Clear()
|
v.Clear()
|
||||||
fmt.Fprint(v, gui.cleanString(s))
|
fmt.Fprint(v, gui.cleanString(s))
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// renderString resets the origin of a view and sets its content
|
// renderString resets the origin of a view and sets its content
|
||||||
func (gui *Gui) renderString(g *gocui.Gui, viewName, s string) error {
|
func (gui *Gui) renderString(g *gocui.Gui, viewName, s string) {
|
||||||
g.Update(func(*gocui.Gui) error {
|
g.Update(func(*gocui.Gui) error {
|
||||||
v, err := g.View(viewName)
|
v, err := g.View(viewName)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -248,9 +241,9 @@ func (gui *Gui) renderString(g *gocui.Gui, viewName, s string) error {
|
|||||||
if err := v.SetCursor(0, 0); err != nil {
|
if err := v.SetCursor(0, 0); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
return gui.setViewContent(gui.g, v, s)
|
gui.setViewContent(gui.g, v, s)
|
||||||
|
return nil
|
||||||
})
|
})
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (gui *Gui) optionsMapToString(optionsMap map[string]string) string {
|
func (gui *Gui) optionsMapToString(optionsMap map[string]string) string {
|
||||||
@@ -263,7 +256,8 @@ func (gui *Gui) optionsMapToString(optionsMap map[string]string) string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (gui *Gui) renderOptionsMap(optionsMap map[string]string) error {
|
func (gui *Gui) renderOptionsMap(optionsMap map[string]string) error {
|
||||||
return gui.renderString(gui.g, "options", gui.optionsMapToString(optionsMap))
|
gui.renderString(gui.g, "options", gui.optionsMapToString(optionsMap))
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: refactor properly
|
// TODO: refactor properly
|
||||||
@@ -349,22 +343,6 @@ func (gui *Gui) resizePopupPanel(g *gocui.Gui, v *gocui.View) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
// generalFocusLine takes a lineNumber to focus, and a bottomLine to ensure we can see
|
|
||||||
func (gui *Gui) generalFocusLine(lineNumber int, bottomLine int, v *gocui.View) error {
|
|
||||||
_, height := v.Size()
|
|
||||||
overScroll := bottomLine - height + 1
|
|
||||||
if overScroll < 0 {
|
|
||||||
overScroll = 0
|
|
||||||
}
|
|
||||||
if err := v.SetOrigin(0, overScroll); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
if err := v.SetCursor(0, lineNumber-overScroll); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (gui *Gui) changeSelectedLine(line *int, total int, change int) {
|
func (gui *Gui) changeSelectedLine(line *int, total int, change int) {
|
||||||
// TODO: find out why we're doing this
|
// TODO: find out why we're doing this
|
||||||
if *line == -1 {
|
if *line == -1 {
|
||||||
@@ -409,11 +387,6 @@ func (gui *Gui) renderPanelOptions() error {
|
|||||||
return gui.renderGlobalOptions()
|
return gui.renderGlobalOptions()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (gui *Gui) handleFocusView(g *gocui.Gui, v *gocui.View) error {
|
|
||||||
_, err := gui.g.SetCurrentView(v.Name())
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
func (gui *Gui) isPopupPanel(viewName string) bool {
|
func (gui *Gui) isPopupPanel(viewName string) bool {
|
||||||
return viewName == "commitMessage" || viewName == "credentials" || viewName == "confirmation" || viewName == "menu"
|
return viewName == "commitMessage" || viewName == "credentials" || viewName == "confirmation" || viewName == "menu"
|
||||||
}
|
}
|
||||||
|
|||||||
+87
-3
@@ -501,16 +501,19 @@ func addEnglish(i18nObject *i18n.Bundle) error {
|
|||||||
Other: `select hunk`,
|
Other: `select hunk`,
|
||||||
}, &i18n.Message{
|
}, &i18n.Message{
|
||||||
ID: "StageSelection",
|
ID: "StageSelection",
|
||||||
Other: `stage selection`,
|
Other: `toggle line staged / unstaged`,
|
||||||
}, &i18n.Message{
|
}, &i18n.Message{
|
||||||
ID: "ResetSelection",
|
ID: "ResetSelection",
|
||||||
Other: `reset selection`,
|
Other: `delete change (git reset)`,
|
||||||
}, &i18n.Message{
|
}, &i18n.Message{
|
||||||
ID: "ToggleDragSelect",
|
ID: "ToggleDragSelect",
|
||||||
Other: `toggle drag select`,
|
Other: `toggle drag select`,
|
||||||
}, &i18n.Message{
|
}, &i18n.Message{
|
||||||
ID: "ToggleSelectHunk",
|
ID: "ToggleSelectHunk",
|
||||||
Other: `toggle select hunk`,
|
Other: `toggle select hunk`,
|
||||||
|
}, &i18n.Message{
|
||||||
|
ID: "ToggleSelectionForPatch",
|
||||||
|
Other: `add/remove line(s) to patch`,
|
||||||
},
|
},
|
||||||
&i18n.Message{
|
&i18n.Message{
|
||||||
ID: "TogglePanel",
|
ID: "TogglePanel",
|
||||||
@@ -564,6 +567,54 @@ func addEnglish(i18nObject *i18n.Bundle) error {
|
|||||||
}, &i18n.Message{
|
}, &i18n.Message{
|
||||||
ID: "RebaseOptionsTitle",
|
ID: "RebaseOptionsTitle",
|
||||||
Other: "Rebase Options",
|
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{
|
}, &i18n.Message{
|
||||||
ID: "ConflictsResolved",
|
ID: "ConflictsResolved",
|
||||||
Other: "all merge conflicts resolved. Continue?",
|
Other: "all merge conflicts resolved. Continue?",
|
||||||
@@ -651,6 +702,12 @@ func addEnglish(i18nObject *i18n.Bundle) error {
|
|||||||
}, &i18n.Message{
|
}, &i18n.Message{
|
||||||
ID: "ScrollUp",
|
ID: "ScrollUp",
|
||||||
Other: "scroll up",
|
Other: "scroll up",
|
||||||
|
}, &i18n.Message{
|
||||||
|
ID: "scrollUpMainPanel",
|
||||||
|
Other: "scroll up main panel",
|
||||||
|
}, &i18n.Message{
|
||||||
|
ID: "scrollDownMainPanel",
|
||||||
|
Other: "scroll down main panel",
|
||||||
}, &i18n.Message{
|
}, &i18n.Message{
|
||||||
ID: "AmendCommitTitle",
|
ID: "AmendCommitTitle",
|
||||||
Other: "Amend Commit",
|
Other: "Amend Commit",
|
||||||
@@ -692,7 +749,7 @@ func addEnglish(i18nObject *i18n.Bundle) error {
|
|||||||
Other: "view commit's files",
|
Other: "view commit's files",
|
||||||
}, &i18n.Message{
|
}, &i18n.Message{
|
||||||
ID: "CommitFilesTitle",
|
ID: "CommitFilesTitle",
|
||||||
Other: "Commit files",
|
Other: "Commit Files",
|
||||||
}, &i18n.Message{
|
}, &i18n.Message{
|
||||||
ID: "goBack",
|
ID: "goBack",
|
||||||
Other: "go back",
|
Other: "go back",
|
||||||
@@ -951,6 +1008,33 @@ func addEnglish(i18nObject *i18n.Bundle) error {
|
|||||||
}, &i18n.Message{
|
}, &i18n.Message{
|
||||||
ID: "prevScreenMode",
|
ID: "prevScreenMode",
|
||||||
Other: "prev screen mode",
|
Other: "prev screen mode",
|
||||||
|
}, &i18n.Message{
|
||||||
|
ID: "startSearch",
|
||||||
|
Other: "start search",
|
||||||
|
}, &i18n.Message{
|
||||||
|
ID: "Panel",
|
||||||
|
Other: "Panel",
|
||||||
|
}, &i18n.Message{
|
||||||
|
ID: "Keybindings",
|
||||||
|
Other: "Keybindings",
|
||||||
|
}, &i18n.Message{
|
||||||
|
ID: "renameBranch",
|
||||||
|
Other: "rename branch",
|
||||||
|
}, &i18n.Message{
|
||||||
|
ID: "NewBranchNamePrompt",
|
||||||
|
Other: "Enter new branch name for branch",
|
||||||
|
}, &i18n.Message{
|
||||||
|
ID: "RenameBranchWarning",
|
||||||
|
Other: "This branch is tracking a remote. This action will only rename the local branch name, not the name of the remote branch. Continue?",
|
||||||
|
}, &i18n.Message{
|
||||||
|
ID: "openMenu",
|
||||||
|
Other: "open menu",
|
||||||
|
}, &i18n.Message{
|
||||||
|
ID: "closeMenu",
|
||||||
|
Other: "close menu",
|
||||||
|
}, &i18n.Message{
|
||||||
|
ID: "resetCherryPick",
|
||||||
|
Other: "reset cherry-picked (copied) commits selection",
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
+27
-30
@@ -8,6 +8,7 @@ import (
|
|||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/jesseduffield/lazygit/pkg/commands"
|
||||||
"github.com/sirupsen/logrus"
|
"github.com/sirupsen/logrus"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -22,7 +23,6 @@ type Task struct {
|
|||||||
|
|
||||||
type ViewBufferManager struct {
|
type ViewBufferManager struct {
|
||||||
writer io.Writer
|
writer io.Writer
|
||||||
waitingTask *Task
|
|
||||||
currentTask *Task
|
currentTask *Task
|
||||||
waitingMutex sync.Mutex
|
waitingMutex sync.Mutex
|
||||||
taskIDMutex sync.Mutex
|
taskIDMutex sync.Mutex
|
||||||
@@ -45,27 +45,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 {
|
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() {
|
go func() {
|
||||||
<-stop
|
<-stop
|
||||||
if cmd.ProcessState == nil {
|
if err := commands.Kill(cmd); err != nil {
|
||||||
if err := kill(cmd); err != nil {
|
m.Log.Warn(err)
|
||||||
m.Log.Warn(err)
|
}
|
||||||
}
|
if onDone != nil {
|
||||||
|
onDone()
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
|
||||||
|
loadingMutex := sync.Mutex{}
|
||||||
|
|
||||||
// not sure if it's the right move to redefine this or not
|
// not sure if it's the right move to redefine this or not
|
||||||
m.readLines = make(chan int, 1024)
|
m.readLines = make(chan int, 1024)
|
||||||
|
|
||||||
@@ -82,11 +75,13 @@ func (m *ViewBufferManager) NewCmdTask(cmd *exec.Cmd, linesToRead int) func(chan
|
|||||||
defer ticker.Stop()
|
defer ticker.Stop()
|
||||||
select {
|
select {
|
||||||
case <-ticker.C:
|
case <-ticker.C:
|
||||||
|
loadingMutex.Lock()
|
||||||
if !loaded {
|
if !loaded {
|
||||||
m.beforeStart()
|
m.beforeStart()
|
||||||
m.writer.Write([]byte("loading..."))
|
_, _ = m.writer.Write([]byte("loading..."))
|
||||||
m.refreshView()
|
m.refreshView()
|
||||||
}
|
}
|
||||||
|
loadingMutex.Unlock()
|
||||||
case <-stop:
|
case <-stop:
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -98,13 +93,16 @@ func (m *ViewBufferManager) NewCmdTask(cmd *exec.Cmd, linesToRead int) func(chan
|
|||||||
case linesToRead := <-m.readLines:
|
case linesToRead := <-m.readLines:
|
||||||
for i := 0; i < linesToRead; i++ {
|
for i := 0; i < linesToRead; i++ {
|
||||||
ok := scanner.Scan()
|
ok := scanner.Scan()
|
||||||
|
loadingMutex.Lock()
|
||||||
if !loaded {
|
if !loaded {
|
||||||
m.beforeStart()
|
m.beforeStart()
|
||||||
loaded = true
|
loaded = true
|
||||||
}
|
}
|
||||||
|
loadingMutex.Unlock()
|
||||||
|
|
||||||
select {
|
select {
|
||||||
case <-stop:
|
case <-stop:
|
||||||
|
m.refreshView()
|
||||||
break outer
|
break outer
|
||||||
default:
|
default:
|
||||||
}
|
}
|
||||||
@@ -112,10 +110,11 @@ func (m *ViewBufferManager) NewCmdTask(cmd *exec.Cmd, linesToRead int) func(chan
|
|||||||
m.refreshView()
|
m.refreshView()
|
||||||
break outer
|
break outer
|
||||||
}
|
}
|
||||||
m.writer.Write(append(scanner.Bytes(), []byte("\n")...))
|
_, _ = m.writer.Write(append(scanner.Bytes(), []byte("\n")...))
|
||||||
}
|
}
|
||||||
m.refreshView()
|
m.refreshView()
|
||||||
case <-stop:
|
case <-stop:
|
||||||
|
m.refreshView()
|
||||||
break outer
|
break outer
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -124,6 +123,12 @@ func (m *ViewBufferManager) NewCmdTask(cmd *exec.Cmd, linesToRead int) func(chan
|
|||||||
m.Log.Warn(err)
|
m.Log.Warn(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
m.refreshView()
|
||||||
|
|
||||||
|
if onDone != nil {
|
||||||
|
onDone()
|
||||||
|
}
|
||||||
|
|
||||||
close(done)
|
close(done)
|
||||||
}()
|
}()
|
||||||
|
|
||||||
@@ -141,7 +146,7 @@ func (t *ViewBufferManager) Close() {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
c := make(chan struct{}, 1)
|
c := make(chan struct{})
|
||||||
|
|
||||||
go func() {
|
go func() {
|
||||||
t.currentTask.Stop()
|
t.currentTask.Stop()
|
||||||
@@ -170,7 +175,10 @@ func (m *ViewBufferManager) NewTask(f func(stop chan struct{}) error) error {
|
|||||||
|
|
||||||
m.waitingMutex.Lock()
|
m.waitingMutex.Lock()
|
||||||
defer m.waitingMutex.Unlock()
|
defer m.waitingMutex.Unlock()
|
||||||
|
|
||||||
|
m.Log.Infof("done waiting")
|
||||||
if taskID < m.newTaskId {
|
if taskID < m.newTaskId {
|
||||||
|
m.Log.Infof("returning cos the task is obsolete")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -214,15 +222,4 @@ func (t *Task) Stop() {
|
|||||||
<-t.notifyStopped
|
<-t.notifyStopped
|
||||||
t.Log.Info("received notifystopped message")
|
t.Log.Info("received notifystopped message")
|
||||||
t.stopped = true
|
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()
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -196,8 +196,6 @@ func TestDisplayArraysAligned(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
type myStruct struct{}
|
|
||||||
|
|
||||||
// TestGetPaddedDisplayStrings is a function.
|
// TestGetPaddedDisplayStrings is a function.
|
||||||
func TestGetPaddedDisplayStrings(t *testing.T) {
|
func TestGetPaddedDisplayStrings(t *testing.T) {
|
||||||
type scenario struct {
|
type scenario struct {
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"log"
|
"log"
|
||||||
"os"
|
"os"
|
||||||
|
"sort"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/jesseduffield/lazygit/pkg/app"
|
"github.com/jesseduffield/lazygit/pkg/app"
|
||||||
@@ -60,33 +61,85 @@ func formatTitle(title string) string {
|
|||||||
|
|
||||||
func formatBinding(binding *gui.Binding) string {
|
func formatBinding(binding *gui.Binding) string {
|
||||||
if binding.Alternative != "" {
|
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 {
|
func getBindingSections(mApp *app.App) []*bindingSection {
|
||||||
bindingSections := []*bindingSection{}
|
bindingSections := []*bindingSection{}
|
||||||
|
|
||||||
// TODO: add context-based keybindings
|
bindings := mApp.Gui.GetInitialKeybindings()
|
||||||
for _, binding := range mApp.Gui.GetInitialKeybindings() {
|
|
||||||
if binding.Description == "" {
|
type contextAndViewType struct {
|
||||||
continue
|
context string
|
||||||
|
viewName string
|
||||||
|
}
|
||||||
|
|
||||||
|
contextAndViewBindingMap := map[contextAndViewType][]*gui.Binding{}
|
||||||
|
|
||||||
|
for _, binding := range bindings {
|
||||||
|
contexts := []string{}
|
||||||
|
if len(binding.Contexts) == 0 {
|
||||||
|
contexts = append(contexts, "")
|
||||||
|
} else {
|
||||||
|
contexts = append(contexts, binding.Contexts...)
|
||||||
}
|
}
|
||||||
|
|
||||||
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 == "" {
|
if viewName == "" {
|
||||||
viewName = "global"
|
viewName = "global"
|
||||||
}
|
}
|
||||||
title := localisedTitle(mApp, viewName)
|
translatedView := localisedTitle(mApp, viewName)
|
||||||
|
var title string
|
||||||
bindingSections = addBinding(title, bindingSections, binding)
|
if contextAndView.context == "" {
|
||||||
}
|
addendum := " " + mApp.Tr.SLocalize("Panel")
|
||||||
|
if viewName == "global" {
|
||||||
for contextName, contextBindings := range mApp.Gui.GetContextMap() {
|
addendum = ""
|
||||||
translatedView := localisedTitle(mApp, contextBindings[0].ViewName)
|
}
|
||||||
translatedContextName := localisedTitle(mApp, contextName)
|
title = fmt.Sprintf("%s%s", translatedView, addendum)
|
||||||
title := fmt.Sprintf("%s (%s)", translatedView, translatedContextName)
|
} else {
|
||||||
|
translatedContextName := localisedTitle(mApp, contextAndView.context)
|
||||||
|
title = fmt.Sprintf("%s %s (%s)", translatedView, mApp.Tr.SLocalize("Panel"), translatedContextName)
|
||||||
|
}
|
||||||
|
|
||||||
for _, binding := range contextBindings {
|
for _, binding := range contextBindings {
|
||||||
bindingSections = addBinding(title, bindingSections, binding)
|
bindingSections = addBinding(title, bindingSections, binding)
|
||||||
@@ -117,7 +170,7 @@ func addBinding(title string, bindingSections []*bindingSection, binding *gui.Bi
|
|||||||
}
|
}
|
||||||
|
|
||||||
func formatSections(mApp *app.App, bindingSections []*bindingSection) string {
|
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 {
|
for _, section := range bindingSections {
|
||||||
content += formatTitle(section.title)
|
content += formatTitle(section.title)
|
||||||
|
|||||||
+4
-4
@@ -152,13 +152,13 @@ func (ei *escapeInterpreter) outputNormal() error {
|
|||||||
|
|
||||||
switch {
|
switch {
|
||||||
case p >= 30 && p <= 37:
|
case p >= 30 && p <= 37:
|
||||||
ei.curFgColor = Attribute(p - 30 + 1)
|
ei.curFgColor |= Attribute(p - 30 + 1)
|
||||||
case p == 39:
|
case p == 39:
|
||||||
ei.curFgColor = ColorDefault
|
ei.curFgColor |= ColorDefault
|
||||||
case p >= 40 && p <= 47:
|
case p >= 40 && p <= 47:
|
||||||
ei.curBgColor = Attribute(p - 40 + 1)
|
ei.curBgColor |= Attribute(p - 40 + 1)
|
||||||
case p == 49:
|
case p == 49:
|
||||||
ei.curBgColor = ColorDefault
|
ei.curBgColor |= ColorDefault
|
||||||
case p == 1:
|
case p == 1:
|
||||||
ei.curFgColor |= AttrBold
|
ei.curFgColor |= AttrBold
|
||||||
case p == 4:
|
case p == 4:
|
||||||
|
|||||||
+24
-3
@@ -10,6 +10,7 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
|
"unicode"
|
||||||
|
|
||||||
"github.com/go-errors/errors"
|
"github.com/go-errors/errors"
|
||||||
|
|
||||||
@@ -466,18 +467,38 @@ func (v *View) Rewind() {
|
|||||||
v.readOffset = 0
|
v.readOffset = 0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func containsUpcaseChar(str string) bool {
|
||||||
|
for _, ch := range str {
|
||||||
|
if unicode.IsUpper(ch) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
func (v *View) updateSearchPositions() {
|
func (v *View) updateSearchPositions() {
|
||||||
if v.searcher.searchString != "" {
|
if v.searcher.searchString != "" {
|
||||||
|
var normalizeRune func(r rune) rune
|
||||||
|
var normalizedSearchStr string
|
||||||
|
// if we have any uppercase characters we'll do a case-sensitive search
|
||||||
|
if containsUpcaseChar(v.searcher.searchString) {
|
||||||
|
normalizedSearchStr = v.searcher.searchString
|
||||||
|
normalizeRune = func(r rune) rune { return r }
|
||||||
|
} else {
|
||||||
|
normalizedSearchStr = strings.ToLower(v.searcher.searchString)
|
||||||
|
normalizeRune = unicode.ToLower
|
||||||
|
}
|
||||||
|
|
||||||
v.searcher.searchPositions = []cellPos{}
|
v.searcher.searchPositions = []cellPos{}
|
||||||
for y, line := range v.lines {
|
for y, line := range v.lines {
|
||||||
lineLoop:
|
lineLoop:
|
||||||
for x, _ := range line {
|
for x, _ := range line {
|
||||||
if line[x].chr == rune(v.searcher.searchString[0]) {
|
if normalizeRune(line[x].chr) == rune(normalizedSearchStr[0]) {
|
||||||
for offset := 1; offset < len(v.searcher.searchString); offset++ {
|
for offset := 1; offset < len(normalizedSearchStr); offset++ {
|
||||||
if len(line)-1 < x+offset {
|
if len(line)-1 < x+offset {
|
||||||
continue lineLoop
|
continue lineLoop
|
||||||
}
|
}
|
||||||
if line[x+offset].chr != rune(v.searcher.searchString[offset]) {
|
if normalizeRune(line[x+offset].chr) != rune(normalizedSearchStr[offset]) {
|
||||||
continue lineLoop
|
continue lineLoop
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Vendored
+45
-1
@@ -1,4 +1,5 @@
|
|||||||
# github.com/cloudfoundry/jibber_jabber v0.0.0-20151120183258-bcc4c8345a21
|
# github.com/cloudfoundry/jibber_jabber v0.0.0-20151120183258-bcc4c8345a21
|
||||||
|
## explicit
|
||||||
github.com/cloudfoundry/jibber_jabber
|
github.com/cloudfoundry/jibber_jabber
|
||||||
# github.com/davecgh/go-spew v1.1.1
|
# github.com/davecgh/go-spew v1.1.1
|
||||||
github.com/davecgh/go-spew/spew
|
github.com/davecgh/go-spew/spew
|
||||||
@@ -10,13 +11,21 @@ github.com/emirpasic/gods/trees
|
|||||||
github.com/emirpasic/gods/trees/binaryheap
|
github.com/emirpasic/gods/trees/binaryheap
|
||||||
github.com/emirpasic/gods/utils
|
github.com/emirpasic/gods/utils
|
||||||
# github.com/fatih/color v1.7.0
|
# github.com/fatih/color v1.7.0
|
||||||
|
## explicit
|
||||||
github.com/fatih/color
|
github.com/fatih/color
|
||||||
# github.com/fsnotify/fsnotify v1.4.7
|
# github.com/fsnotify/fsnotify v1.4.7
|
||||||
|
## explicit
|
||||||
github.com/fsnotify/fsnotify
|
github.com/fsnotify/fsnotify
|
||||||
# github.com/go-errors/errors v1.0.1
|
# github.com/go-errors/errors v1.0.1
|
||||||
|
## explicit
|
||||||
github.com/go-errors/errors
|
github.com/go-errors/errors
|
||||||
# github.com/golang-collections/collections v0.0.0-20130729185459-604e922904d3
|
# github.com/golang-collections/collections v0.0.0-20130729185459-604e922904d3
|
||||||
|
## explicit
|
||||||
github.com/golang-collections/collections/stack
|
github.com/golang-collections/collections/stack
|
||||||
|
# github.com/golang/protobuf v1.3.2
|
||||||
|
## explicit
|
||||||
|
# github.com/google/go-cmp v0.3.1
|
||||||
|
## explicit
|
||||||
# github.com/hashicorp/hcl v1.0.0
|
# github.com/hashicorp/hcl v1.0.0
|
||||||
github.com/hashicorp/hcl
|
github.com/hashicorp/hcl
|
||||||
github.com/hashicorp/hcl/hcl/ast
|
github.com/hashicorp/hcl/hcl/ast
|
||||||
@@ -29,61 +38,86 @@ github.com/hashicorp/hcl/json/parser
|
|||||||
github.com/hashicorp/hcl/json/scanner
|
github.com/hashicorp/hcl/json/scanner
|
||||||
github.com/hashicorp/hcl/json/token
|
github.com/hashicorp/hcl/json/token
|
||||||
# github.com/integrii/flaggy v1.4.0
|
# github.com/integrii/flaggy v1.4.0
|
||||||
|
## explicit
|
||||||
github.com/integrii/flaggy
|
github.com/integrii/flaggy
|
||||||
# github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99
|
# github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99
|
||||||
github.com/jbenet/go-context/io
|
github.com/jbenet/go-context/io
|
||||||
# github.com/jesseduffield/gocui v0.3.1-0.20200224201655-5024a02682ed
|
# github.com/jesseduffield/gocui v0.3.1-0.20200309001002-7765949e1c8a
|
||||||
|
## explicit
|
||||||
github.com/jesseduffield/gocui
|
github.com/jesseduffield/gocui
|
||||||
# github.com/jesseduffield/pty v1.2.1
|
# github.com/jesseduffield/pty v1.2.1
|
||||||
|
## explicit
|
||||||
github.com/jesseduffield/pty
|
github.com/jesseduffield/pty
|
||||||
# github.com/jesseduffield/termbox-go v0.0.0-20200130214842-1d31d1faa3c9
|
# github.com/jesseduffield/termbox-go v0.0.0-20200130214842-1d31d1faa3c9
|
||||||
|
## explicit
|
||||||
github.com/jesseduffield/termbox-go
|
github.com/jesseduffield/termbox-go
|
||||||
# github.com/kardianos/osext v0.0.0-20190222173326-2bc1f35cddc0
|
# github.com/kardianos/osext v0.0.0-20190222173326-2bc1f35cddc0
|
||||||
|
## explicit
|
||||||
github.com/kardianos/osext
|
github.com/kardianos/osext
|
||||||
# github.com/kevinburke/ssh_config v0.0.0-20190725054713-01f96b0aa0cd
|
# github.com/kevinburke/ssh_config v0.0.0-20190725054713-01f96b0aa0cd
|
||||||
github.com/kevinburke/ssh_config
|
github.com/kevinburke/ssh_config
|
||||||
# github.com/konsorten/go-windows-terminal-sequences v1.0.2
|
# github.com/konsorten/go-windows-terminal-sequences v1.0.2
|
||||||
|
## explicit
|
||||||
github.com/konsorten/go-windows-terminal-sequences
|
github.com/konsorten/go-windows-terminal-sequences
|
||||||
# github.com/magiconair/properties v1.8.1
|
# github.com/magiconair/properties v1.8.1
|
||||||
github.com/magiconair/properties
|
github.com/magiconair/properties
|
||||||
# github.com/mattn/go-colorable v0.1.4
|
# github.com/mattn/go-colorable v0.1.4
|
||||||
|
## explicit
|
||||||
github.com/mattn/go-colorable
|
github.com/mattn/go-colorable
|
||||||
# github.com/mattn/go-isatty v0.0.11
|
# github.com/mattn/go-isatty v0.0.11
|
||||||
|
## explicit
|
||||||
github.com/mattn/go-isatty
|
github.com/mattn/go-isatty
|
||||||
# github.com/mattn/go-runewidth v0.0.8
|
# github.com/mattn/go-runewidth v0.0.8
|
||||||
|
## explicit
|
||||||
github.com/mattn/go-runewidth
|
github.com/mattn/go-runewidth
|
||||||
# github.com/mgutz/str v1.2.0
|
# github.com/mgutz/str v1.2.0
|
||||||
|
## explicit
|
||||||
github.com/mgutz/str
|
github.com/mgutz/str
|
||||||
# github.com/mitchellh/go-homedir v1.1.0
|
# github.com/mitchellh/go-homedir v1.1.0
|
||||||
github.com/mitchellh/go-homedir
|
github.com/mitchellh/go-homedir
|
||||||
|
# github.com/mitchellh/gox v1.0.1
|
||||||
|
## explicit
|
||||||
# github.com/mitchellh/mapstructure v1.1.2
|
# github.com/mitchellh/mapstructure v1.1.2
|
||||||
github.com/mitchellh/mapstructure
|
github.com/mitchellh/mapstructure
|
||||||
# github.com/nicksnyder/go-i18n/v2 v2.0.3
|
# github.com/nicksnyder/go-i18n/v2 v2.0.3
|
||||||
|
## explicit
|
||||||
github.com/nicksnyder/go-i18n/v2/i18n
|
github.com/nicksnyder/go-i18n/v2/i18n
|
||||||
github.com/nicksnyder/go-i18n/v2/internal
|
github.com/nicksnyder/go-i18n/v2/internal
|
||||||
github.com/nicksnyder/go-i18n/v2/internal/plural
|
github.com/nicksnyder/go-i18n/v2/internal/plural
|
||||||
|
# github.com/onsi/ginkgo v1.10.3
|
||||||
|
## explicit
|
||||||
|
# github.com/onsi/gomega v1.7.1
|
||||||
|
## explicit
|
||||||
# github.com/pelletier/go-toml v1.6.0
|
# github.com/pelletier/go-toml v1.6.0
|
||||||
|
## explicit
|
||||||
github.com/pelletier/go-toml
|
github.com/pelletier/go-toml
|
||||||
# github.com/pmezard/go-difflib v1.0.0
|
# github.com/pmezard/go-difflib v1.0.0
|
||||||
github.com/pmezard/go-difflib/difflib
|
github.com/pmezard/go-difflib/difflib
|
||||||
# github.com/sergi/go-diff v1.0.0
|
# github.com/sergi/go-diff v1.0.0
|
||||||
github.com/sergi/go-diff/diffmatchpatch
|
github.com/sergi/go-diff/diffmatchpatch
|
||||||
# github.com/shibukawa/configdir v0.0.0-20170330084843-e180dbdc8da0
|
# github.com/shibukawa/configdir v0.0.0-20170330084843-e180dbdc8da0
|
||||||
|
## explicit
|
||||||
github.com/shibukawa/configdir
|
github.com/shibukawa/configdir
|
||||||
# github.com/sirupsen/logrus v1.4.2
|
# github.com/sirupsen/logrus v1.4.2
|
||||||
|
## explicit
|
||||||
github.com/sirupsen/logrus
|
github.com/sirupsen/logrus
|
||||||
# github.com/spf13/afero v1.2.2
|
# github.com/spf13/afero v1.2.2
|
||||||
|
## explicit
|
||||||
github.com/spf13/afero
|
github.com/spf13/afero
|
||||||
github.com/spf13/afero/mem
|
github.com/spf13/afero/mem
|
||||||
# github.com/spf13/cast v1.3.0
|
# github.com/spf13/cast v1.3.0
|
||||||
github.com/spf13/cast
|
github.com/spf13/cast
|
||||||
# github.com/spf13/jwalterweatherman v1.1.0
|
# github.com/spf13/jwalterweatherman v1.1.0
|
||||||
|
## explicit
|
||||||
github.com/spf13/jwalterweatherman
|
github.com/spf13/jwalterweatherman
|
||||||
# github.com/spf13/pflag v1.0.5
|
# github.com/spf13/pflag v1.0.5
|
||||||
|
## explicit
|
||||||
github.com/spf13/pflag
|
github.com/spf13/pflag
|
||||||
# github.com/spf13/viper v1.6.1
|
# github.com/spf13/viper v1.6.1
|
||||||
|
## explicit
|
||||||
github.com/spf13/viper
|
github.com/spf13/viper
|
||||||
# github.com/spkg/bom v0.0.0-20160624110644-59b7046e48ad
|
# github.com/spkg/bom v0.0.0-20160624110644-59b7046e48ad
|
||||||
|
## explicit
|
||||||
github.com/spkg/bom
|
github.com/spkg/bom
|
||||||
# github.com/src-d/gcfg v1.4.0
|
# github.com/src-d/gcfg v1.4.0
|
||||||
github.com/src-d/gcfg
|
github.com/src-d/gcfg
|
||||||
@@ -91,14 +125,17 @@ github.com/src-d/gcfg/scanner
|
|||||||
github.com/src-d/gcfg/token
|
github.com/src-d/gcfg/token
|
||||||
github.com/src-d/gcfg/types
|
github.com/src-d/gcfg/types
|
||||||
# github.com/stretchr/testify v1.4.0
|
# github.com/stretchr/testify v1.4.0
|
||||||
|
## explicit
|
||||||
github.com/stretchr/testify/assert
|
github.com/stretchr/testify/assert
|
||||||
# github.com/subosito/gotenv v1.2.0
|
# github.com/subosito/gotenv v1.2.0
|
||||||
github.com/subosito/gotenv
|
github.com/subosito/gotenv
|
||||||
# github.com/tcnksm/go-gitconfig v0.1.2
|
# github.com/tcnksm/go-gitconfig v0.1.2
|
||||||
|
## explicit
|
||||||
github.com/tcnksm/go-gitconfig
|
github.com/tcnksm/go-gitconfig
|
||||||
# github.com/xanzy/ssh-agent v0.2.1
|
# github.com/xanzy/ssh-agent v0.2.1
|
||||||
github.com/xanzy/ssh-agent
|
github.com/xanzy/ssh-agent
|
||||||
# golang.org/x/crypto v0.0.0-20191206172530-e9b2fee46413
|
# golang.org/x/crypto v0.0.0-20191206172530-e9b2fee46413
|
||||||
|
## explicit
|
||||||
golang.org/x/crypto/cast5
|
golang.org/x/crypto/cast5
|
||||||
golang.org/x/crypto/chacha20
|
golang.org/x/crypto/chacha20
|
||||||
golang.org/x/crypto/curve25519
|
golang.org/x/crypto/curve25519
|
||||||
@@ -116,20 +153,25 @@ golang.org/x/crypto/ssh
|
|||||||
golang.org/x/crypto/ssh/agent
|
golang.org/x/crypto/ssh/agent
|
||||||
golang.org/x/crypto/ssh/knownhosts
|
golang.org/x/crypto/ssh/knownhosts
|
||||||
# golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553
|
# golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553
|
||||||
|
## explicit
|
||||||
golang.org/x/net/context
|
golang.org/x/net/context
|
||||||
golang.org/x/net/internal/socks
|
golang.org/x/net/internal/socks
|
||||||
golang.org/x/net/proxy
|
golang.org/x/net/proxy
|
||||||
# golang.org/x/sys v0.0.0-20191210023423-ac6580df4449
|
# golang.org/x/sys v0.0.0-20191210023423-ac6580df4449
|
||||||
|
## explicit
|
||||||
golang.org/x/sys/cpu
|
golang.org/x/sys/cpu
|
||||||
golang.org/x/sys/unix
|
golang.org/x/sys/unix
|
||||||
golang.org/x/sys/windows
|
golang.org/x/sys/windows
|
||||||
# golang.org/x/text v0.3.2
|
# golang.org/x/text v0.3.2
|
||||||
|
## explicit
|
||||||
golang.org/x/text/internal/language
|
golang.org/x/text/internal/language
|
||||||
golang.org/x/text/internal/language/compact
|
golang.org/x/text/internal/language/compact
|
||||||
golang.org/x/text/internal/tag
|
golang.org/x/text/internal/tag
|
||||||
golang.org/x/text/language
|
golang.org/x/text/language
|
||||||
golang.org/x/text/transform
|
golang.org/x/text/transform
|
||||||
golang.org/x/text/unicode/norm
|
golang.org/x/text/unicode/norm
|
||||||
|
# gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15
|
||||||
|
## explicit
|
||||||
# gopkg.in/ini.v1 v1.51.0
|
# gopkg.in/ini.v1 v1.51.0
|
||||||
gopkg.in/ini.v1
|
gopkg.in/ini.v1
|
||||||
# gopkg.in/src-d/go-billy.v4 v4.3.2
|
# gopkg.in/src-d/go-billy.v4 v4.3.2
|
||||||
@@ -139,6 +181,7 @@ gopkg.in/src-d/go-billy.v4/helper/polyfill
|
|||||||
gopkg.in/src-d/go-billy.v4/osfs
|
gopkg.in/src-d/go-billy.v4/osfs
|
||||||
gopkg.in/src-d/go-billy.v4/util
|
gopkg.in/src-d/go-billy.v4/util
|
||||||
# gopkg.in/src-d/go-git.v4 v4.13.1
|
# gopkg.in/src-d/go-git.v4 v4.13.1
|
||||||
|
## explicit
|
||||||
gopkg.in/src-d/go-git.v4
|
gopkg.in/src-d/go-git.v4
|
||||||
gopkg.in/src-d/go-git.v4/config
|
gopkg.in/src-d/go-git.v4/config
|
||||||
gopkg.in/src-d/go-git.v4/internal/revision
|
gopkg.in/src-d/go-git.v4/internal/revision
|
||||||
@@ -183,4 +226,5 @@ gopkg.in/src-d/go-git.v4/utils/merkletrie/noder
|
|||||||
# gopkg.in/warnings.v0 v0.1.2
|
# gopkg.in/warnings.v0 v0.1.2
|
||||||
gopkg.in/warnings.v0
|
gopkg.in/warnings.v0
|
||||||
# gopkg.in/yaml.v2 v2.2.7
|
# gopkg.in/yaml.v2 v2.2.7
|
||||||
|
## explicit
|
||||||
gopkg.in/yaml.v2
|
gopkg.in/yaml.v2
|
||||||
|
|||||||
Reference in New Issue
Block a user