Compare commits

...
85 Commits
Author SHA1 Message Date
Jesse Duffield 0d5a410114 Update README.md 2025-09-06 17:11:27 +10:00
Jesse Duffield 0553c00f61 Update README.md 2025-09-06 16:56:50 +10:00
Jesse Duffield d65f638869 Update README.md 2025-09-06 16:51:31 +10:00
Jesse Duffield 2602426d43 README.md: Update Sponsors (#4795)
Automated changes by
[create-pull-request](https://github.com/peter-evans/create-pull-request)
GitHub action
2025-09-06 09:42:07 +10:00
github-actions[bot] a0af7403cc README.md: Update Sponsors 2025-09-05 17:00:11 +00:00
Stefan Haller 900d8be359 Add dev container feature as installation method to README (#4876)
### PR Description

Implements #4874
2025-09-05 18:59:58 +02:00
Henning Lorenzen 4c686fc66e Update README.md 2025-09-05 18:47:51 +02:00
Stefan Haller 2469420efd Update translations from Crowdin (#4873) 2025-09-05 10:50:09 +02:00
Stefan Haller d52ff052bb Update translations from crowdin 2025-09-05 10:47:51 +02:00
Stefan Haller c0805f117e Make it possible to rebind the Confirm keybinding (#4860)
### PR Description

Remapping `keybinding.universal.confirm` from `<enter>` to something
like `y` is currently impossible because the same keybinding is also
used to confirm prompts (e.g. "New branch") and the search prompt. Fix
this by hard-coding enter for those; it doesn't really make sense to use
any other key for prompts.

While at it, add separate bindings for `confirmMenu` and
`confirmSuggestion` for those who would like to have different keys for
these. Of these, `confirmMenu` could be a little tricky because menus
are sometimes used purely as a choice (e.g. in "Amend commit attribute"
or the global keybindings menu), in which case you might want to use
`<enter>`, but other times as a substitute for a confirmation (e.g. for
"Delete branch"), in which case you might want to remap to `y`. I don't
have a great idea what to do about that, to be honest. Feedback welcome.

In this PR we only take care of Confirm, which many people seem to be
concerned about. We might consider doing something similar for Esc, but
it seems less urgent, and I'm out of time now. 😄

This seemingly simple change required some serious refactoring under the
hood, so thorough testing would be good to ensure we didn't break
anything.

Closes #2611
Closes #2767
Closes #3471

Related: #2768
2025-09-05 10:46:33 +02:00
Stefan Haller b3a3410a1a Remove keybindings for menu items that are the same as the menu confirm key
This is needed when remapping the confirmMenu key to, say, "y", and there's a
menu that has an item with a "y" binding. This already worked correctly (confirm
takes precedence, as desired), but it's still confusing to see the item binding.
2025-09-05 10:42:04 +02:00
Stefan Haller b413710d8c Add separate keybindings for confirmMenu and confirmSuggestion
It seems useful to have the flexibility to remap "enter" in confirmations to
"y", but keep "enter" for menus and suggestions (even though we sometimes use
menus as confirmations, but it's still good to give users the choice).
2025-09-05 10:42:04 +02:00
Stefan Haller 81868de264 Hard-code "enter" for adding lines in integration tests
This one doesn't make a difference in practice because we don't remap the key in
tests, but if we would, then this would no longer work correctly. It's just more
correct this way.
2025-09-05 10:42:04 +02:00
Stefan Haller ea7050437d Fix <enter> keybinding for switching to a worktree
The universal.confirm keybinding is the wrong one to use for this, we want
universal.goInto instead. They are both bound to "enter" by default, but when
remapping confirm to "y" we don't want to use that for entering worktrees.
2025-09-05 10:42:04 +02:00
Stefan Haller 6303c64232 Hard-code "enter" for search prompt
Like with the previous commit, it doesn't make sense to use any other key than
enter for the search prompt.
2025-09-05 10:42:04 +02:00
Stefan Haller b006c83181 Hard-code "enter" for editable prompts
Rebinding the universal.confirm keybinding currently doesn't make sense, because
the rebound key would also be used for editable prompts, which means you would
only be able to bind it to a ctrl key (not "y", which is desirable for some
people), and also it would allow you to enter a line feed in a branch name.

Fix this by always using enter for editable prompts.
2025-09-05 10:42:04 +02:00
Stefan Haller 0a64e1abb3 Update cheatsheets for the previous commit
Done in a separate commit because the diff is already so long.
2025-09-05 10:42:03 +02:00
Stefan Haller 5a630aeda1 Refactor: add a separate Prompt view
So far, confirmations and prompts were handled by the same view, context, and
controller, with a bunch of conditional code based on whether the view is
editable. This was more or less ok so far, since it does save a little bit of
code duplication; however, now we need separate views, because we don't have
dynamic keybindings, but we want to map "confirm" to different keys in
confirmations (the "universal.confirm" user config) and prompts (hard-coded to
enter, because it doesn't make sense to customize it there).

It also allows us to get rid of the conditional code, which is a nice benefit;
and the code duplication is actually not *that* bad.
2025-09-05 10:42:03 +02:00
Stefan Haller 94aa1101c9 Fix rare crash in interactive rebase (merge command without comment) (#4872)
This fixes a crash in an interactive rebase when there's a merge command
in the rebase-todo file that doesn't have a comment. I don't know under
what circumstances this can happen; git itself doesn't produce these,
but it is theoretically possible for the user to do this manually by
doing `git rebase --edit-todo`, or third-party tools could do it too.

We had one user report a crash because of this, so it seems worth fixing
it.

Closes #4858.
2025-09-05 10:41:23 +02:00
Stefan Haller ffccfd6e42 Bump git-todo-parser
This fixes a crash in an interactive rebase when there's a merge command in the
rebase-todo file that doesn't have a comment. I don't know under what
circumstances this can happen; git itself doesn't produce these, but it is
theoretically possible for the user to do this manually by doing `git rebase
--edit-todo`, or third-party tools could do it too.

We had one user report a crash because of this, so it seems worth fixing it.
2025-09-05 10:37:20 +02:00
Stefan Haller 2bf2c38e9b docs(VISION): fix "Dicoverability" typo (#4866) 2025-09-03 09:29:49 +02:00
Ricardo Fernández Serrata 83f95bf8fe docs(VISION): fix "Dicoverability" typo 2025-09-03 00:52:38 -04:00
Stefan Haller be0d7a6e73 Log the hash of dropped stashes (#4850)
### PR Description

If you dropped/popped a stash accidentally, the logged hash can help
recover it more easily.

Supersedes #4847.
2025-08-26 14:02:43 +02:00
Stefan Haller 438f5c0eda Log hashes when dropping/popping stashes
If you dropped/popped a stash accidentally, the logged hash can help recover it
more easily.
2025-08-25 19:23:30 +02:00
Stefan Haller 5cb80b8635 Fix command log for stash commands
With the exception of Rename Stash, they would all just log "Stash".
2025-08-25 19:23:30 +02:00
Stefan Haller ee81a8e3c2 Add hash field to models.StashEntry 2025-08-25 19:23:30 +02:00
Stefan Haller 61d5b1646d Cleanup: bring stash loader test up to date
It didn't actually test how it parses the unix time stamps, and the test only
succeeded because the code is lenient against it missing.
2025-08-25 19:23:30 +02:00
Stefan Haller 5a6de1248f Fix dropping range selection of filtered stashes (#4849)
### PR Description

When filtering by file path, dropping a range selection of stashes would
drop the wrong ones if those stashes would be noncontiguous in the
unfiltered list.
2025-08-25 19:21:38 +02:00
Stefan Haller bf419abb8e Fix dropping a range of stashes in filtered mode
To fix the problem described in the previous commit, iterate backwards over the
stashes that we want to delete. This allows us to use their Index field.
2025-08-25 18:41:06 +02:00
Stefan Haller ef3e899f5b Add test demonstrating problem with dropping stashes in filtering mode
As can be seen from the test, it deletes the wrong stashes in this case, because
it assumes the selection is contiguous.
2025-08-25 15:56:39 +02:00
Stefan Haller a0f4614fdc Cleanup: remove unnecessary ToggleRangeSelect
The next RangeSelectDown actually cancels the sticky range select and turns it
into a non-sticky one.
2025-08-25 14:58:48 +02:00
Stefan Haller 1d65196136 Dont auto-forward branches that are checked out in another worktree (#4833)
### PR Description

This is similar to #2957, except that in that case it was about an
explicit fast-forward command, and we solved it by doing the
fast-forward in the other work-tree (so that it would fail if that
worktree had modified files, for example). In this case it is about the
relatively new auto-forward feature (added in v0.50, see #4493), and in
this case we fix it by not even trying to auto-forward any branches that
are checked out by other worktrees.
2025-08-20 10:45:24 +02:00
Stefan Haller 235ab15d7b Don't auto-forward branches that are checked out by another worktree 2025-08-20 10:43:19 +02:00
Stefan Haller 7130cb2947 Add test for auto-forwarding branches that are checked out by another worktree
The test shows that we are currently auto-forwarding branches even if they are
checked out by another worktree; this is quite bad, because when you switch to
that other worktree you'll see that the files that are touched by the fetched
commits are all modified (which we don't test here).
2025-08-20 10:43:19 +02:00
Stefan Haller 8beec9aacc Add a user config for using git's external diff command for paging (#4832)
### PR Description

This is similar to using lazygit's `Git.Paging.ExternalDiffCommand`
config, except that the command is configured in git. This can be done
either with git's `diff.external` config, or through `.gitattributes`,
so it gives a bit more flexibility.

We could consider removing the `Git.Paging.ExternalDiffCommand` config
now, because its functionality is covered by the new config. I decided
to keep it though, because I don't want to make this a breaking change,
and also because some users might want to have the external diff command
only in lazygit but not on the command line.
2025-08-20 10:42:37 +02:00
Stefan Haller 40e989467f Add a user config for using git's external diff command for paging
This is similar to using lazygit's Git.Paging.ExternalDiffCommand config, except
that the command is configured in git. This can be done either with git's
`diff.external` config, or through .gitattributes, so it gives a bit more
flexibility.
2025-08-20 10:39:55 +02:00
Stefan Haller 86934ce1af Remove the git.paging.useConfig option (#4837)
### PR Description

Many people don't understand what this means, which is apparent from the
amount of issues that got filed because of this. Let's get rid of it to
avoid this confusion. People will have to configure their pager twice if
they want to use it both on the command line and in lazygit, which I
think is not a big deal.

See
[here](https://github.com/jesseduffield/lazygit/issues/3704#issuecomment-2330772344)
for more rationale.

Closes #3704.
2025-08-20 10:39:21 +02:00
Stefan Haller 548244c0b7 Add breaking changes notice about git.paging.useConfig option 2025-08-19 11:54:54 +02:00
Stefan Haller 9657b4346f Remove the git.paging.useConfig option
Many people don't understand what this means, which is apparent from the amount
of issues that got filed because of this. Let's get rid of it to avoid this
confusion. People will have to configure their pager twice if they want to use
it both on the command line and in lazygit, which I think is not a big deal.
2025-08-19 10:43:28 +02:00
Stefan Haller 13f97fb259 Use external diff command in stashes panel (#4836)
### PR Description

When we added support for using external diff commands as pagers (mainly
to support difftastic as a pager) in #2868, we only supported this in
the files and commits panels, but not in the stashes panel. This was
forgotten in 6266e19623.
2025-08-19 09:53:50 +02:00
Stefan Haller 89d50fa229 Use external diff command in stashes panel
This was forgotten in 6266e19623.
2025-08-19 09:48:11 +02:00
Stefan Haller 0f785c434a Run label check workflow only on label events and open pr event (#4830)
## **PR Description**
- Currently, `check-required-label` only runs when commits are added to
a PR, even if a maintainer has added labels, so the CI status remains
red until a commit is pushed after labels are added by a maintainer.
- I updated the workflows to run `check-required-label` only on label
events(add/remove) or open PR event.
- This will make PR status updates more accurate, so authors will be
able to see that tests and lint are passing by just checking the PR
status, and maintainers will easily know if the PR is ready for review.
2025-08-18 07:44:43 +02:00
kyu08 e932ea24f2 Run label check workflow only on label events and open pr event 2025-08-18 07:40:38 +02:00
Stefan Haller 1639e17d4e Enhance PR/Issue templates readability (#4829) 2025-08-18 07:39:53 +02:00
kyu08 7853df0f25 Enhance PR/Issue templates readability 2025-08-18 07:37:46 +02:00
Stefan Haller 011ff853b8 Add "CopyToClipboard" command to ConfirmationController (#4810)
## **PR Description**

Sometimes, I want to copy the error message to clipboard to search
google or ask to LLM about the error message.

So I added CopyToClipboard command to `ConfirmationController` and I
have confirmed that this command copies the content of the window to the
clipboard.
2025-08-15 17:20:16 +02:00
kyu08 fc84b77db8 Run go generate ./... 2025-08-15 17:17:06 +02:00
kyu08 3fa5a8eddd Add "CopyToClipboard" command to ConfirmationController 2025-08-15 17:17:06 +02:00
Stefan Haller 0573529f8a Cleanup: remove unnecessary code in test
This was needed in an earlier version of the test, when we asserted the file
content in a more complicated way. It should have been removed in caca62b89e.
2025-08-15 17:17:06 +02:00
Stefan Haller deaa701d41 Update donation wording so that it's clear there's no strings attached (#4827) 2025-08-15 12:05:40 +02:00
Jesse Duffield 7ed946951f Update donation wording so that it's clear there's no strings attached 2025-08-15 19:51:50 +10:00
Stefan Haller 82daedb96d Add support for suspending LazyGit with Ctrl+Z on Unix systems (#4757)
## ✨ Add Ctrl+Z suspend support for LazyGit on Unix-like systems

### 📝 Summary

This PR adds support for suspending LazyGit when the user presses
`Ctrl+Z`, making it behave like common CLI tools (e.g., Vim, less,
htop):

* Pressing `Ctrl+Z` sends a `SIGTSTP` signal to suspend LazyGit.
* After resuming with `fg`, LazyGit redraws and continues working
without hanging.
* During suspension, background routines are paused to avoid running
while LazyGit is stopped.

### ✅ Motivation

Make LazyGit feel more native on Unix-like systems by supporting
standard terminal suspend/resume (Ctrl+Z / fg) behavior.

Closes #3906
2025-08-14 20:47:19 +02:00
Stefan Haller 4bc1ba22c1 Add a breaking changes notice for the changed keybinding 2025-08-14 20:42:21 +02:00
Stefan Haller 6322359392 Update cheatsheets, config docs, and schema 2025-08-14 20:42:20 +02:00
cowboy8625andStefan Haller 0f38d2d61e Implement suspending the app using ctrl-z
Co-authored-by: Stefan Haller <stefan@haller-berlin.de>
2025-08-14 20:41:46 +02:00
Stefan Haller af190ad280 Extract methods suspend/resume on Gui struct
These suspend/resume the gocui layer and pause/unpause background refreshes.
2025-08-14 20:40:44 +02:00
cowboy8625andStefan Haller 376ca65807 Rebind redo from <c-z> to Z
This frees up ctrl-z for suspend. Hopefully, redo is not such a frequently used
operation that the change annoys people.

Co-authored-by: Stefan Haller <stefan@haller-berlin.de>
2025-08-14 20:40:44 +02:00
Stefan Haller 5490e559a3 Cleanup: remove stale comment
This should have been removed in 8c574f888c, where I renamed it back to 'gui'
to fix a linter warning.
2025-08-14 20:40:44 +02:00
Stefan Haller bb17072ed8 Clean up build tags
- Remove old-style build tags (the +build syntax has become obsolete with 1.17)
- Remove redundant build tags from '*_windows.go' files
2025-08-14 20:40:44 +02:00
Stefan Haller 5b86716446 Improve display of "esc" keybinding in the keybindings status bar (#4819)
### PR Description

- For popup windows, the status bar would show `Confirm: <enter> |
Close/Cancel: <esc> | Cancel: <esc>`. Omit the second `<esc>`.
- Don't show the `<esc>` binding in other views when it doesn't do
anything.
- Change the text of the `<esc>` label to show what it does, based on
context. This is very helpful because esc can cancel all sorts of
things, and if several of these things are active at once, it is not
obvious which one will be cancelled first.

Supersedes #4808.
2025-08-14 18:02:07 +02:00
Stefan Haller da7121fa87 Don't append "Disabled: " to menu tooltip if disabled reason is empty
In some cases we set a disabled reason but leave the text empty, so that we
don't get an error toast when the item is invoked. In such a case it looks
awkward if there is a tooltip showing "Disabled: " with no following text.
2025-08-14 17:59:38 +02:00
Stefan Haller 0c0c32aec4 Show "Close/Cancel: <esc>" for menus like we do for confirmations
For many menus, just "Close" is fine, but some menus act more like confirmations
(e.g. the menu that appears when you cherry-pick and get conflicts); in this
case, it's good to make it more obvious that hitting esc cancels the whole
thing.
2025-08-14 17:59:38 +02:00
Stefan Haller aeff986450 Show context-specific labels for <esc> in staging and patch building view
Dismissing a range selection is handled by the global escape handler for all
list views, but not for the staging and patch building views, so we need to make
the esc description dynamic for these, too.
2025-08-14 17:59:38 +02:00
Stefan Haller 51066b14b1 Show escape binding for staging and patch building in the status bar 2025-08-14 17:59:38 +02:00
Stefan Haller 5f91b1b48e Move global escape handler to before the keybindings menu handler
The main reason for this is that sometimes the escape key is handled by a local
binding, in which case it appears before the '?' binding in the options status
bar, and other times it is handled by the global controller, in which case it
appeared after. Moving it to before the keybindings menu handler makes it appear
before '?' in both cases.

Also, if the window is too narrow to show all keybindings, the ones that don't
fit will be truncated, and in this case it is more important to show the esc
binding because of its context sensitivity.

This also moves the esc entry up a few positions in the keybindings menu, but I
don't think this matters much.
2025-08-14 17:59:38 +02:00
Stefan Haller a8e44dcea6 Show context-specific labels for the global <esc> binding
WHen several modes are active at the same time, it isn't totally obvious which
one will be cancelled first, so show this in the status bar.
2025-08-14 17:59:38 +02:00
Stefan Haller d8ea83704f Rename ModeStatus.Description to InfoLabel
It is styled and includes a "(Reset)" button, so it's really not a
general-purpose description, but very specific to the Information view.
2025-08-14 17:59:38 +02:00
Stefan Haller 7bf05dfca4 Avoid showing <esc> in options map when it doesn't do anything
The code duplication between Escape and EscapeEnabled is unfortunate, but I
don't see a better way to solve this.
2025-08-14 17:59:38 +02:00
Stefan Haller 0af439ddf5 Cleanup: remove dead code
Cancelling searching (as opposed to filtering) is handled by gocui.
2025-08-14 17:59:38 +02:00
Stefan Haller 4961c4b678 Avoid duplicate key bindings in options map
Sometimes there is a local and a global keybinding for the same key; if both are
configured to be shown in the options map, we should only show the local one
because it takes precedence. This happens for example for <esc> in a popup, or
for <esc> in the focused main view.

Note that this is also a problem in the keybindings menu, and we don't solve
that here.
2025-08-14 17:59:38 +02:00
Stefan Haller f2c2e80a5c Show "Exit back to side panel" in options status bar for focused main view
It's maybe not totally obvious, so let's show it.

Esc now appears twice in the status bar, because the global controller also
appends its generic "Cancel". We'll fix this in the next commit.
2025-08-14 17:59:38 +02:00
Stefan Haller d50e58559e Support Azure DevOps vs-ssh.visualstudio.com SSH remotes as hosting provider (#4822)
**PR Description**  
This PR adds support for parsing **legacy Azure DevOps SSH remotes**
that use the
`vs-ssh.visualstudio.com` host, which is still common in older
repositories or corporate setups.

This PR fixes issue #2667.

Previously, even if users mapped this host to the Azure DevOps provider
via
`configServiceDomains`, URL generation failed with:
```
Failed to parse repo information from url
```
because the Azure DevOps `ServiceDefinition` regex set did not include
this SSH format.

### Changes
- Added a new regex to `azdoServiceDef.regexStrings` to match:
  ```
  git@vs-ssh.visualstudio.com:v3/<org>/<project>/<repo>
  ```
- This allows `getRepoURLFromRemoteURL` to correctly extract `org`,
`project`, and `repo`
  for these remotes.
- Added a test case to `TestGetPullRequestURL` verifying that mapping  
`vs-ssh.visualstudio.com` → `azuredevops:dev.azure.com` produces the
correct PR URL.

### Example
With this config:
```yaml
services:
  'vs-ssh.visualstudio.com': 'azuredevops:dev.azure.com'
```
and remote:
```
git@vs-ssh.visualstudio.com:v3/myorg/myproject/myrepo
```
`GetPullRequestURL("feature/new", "")` now returns:
```
https://dev.azure.com/myorg/myproject/_git/myrepo/pullrequestcreate?sourceRef=feature%2Fnew
```

### Why
- Many users still have remotes in this legacy format.
- This change is **backward-compatible** and does not affect existing
supported remotes.
- It unblocks URL generation for PRs and commits without requiring users
to change their remotes.
- Fixes #2667
2025-08-14 15:23:38 +02:00
🚀 Niklas Arens a44af0685c fix(hosting_service): support Azure DevOps vs-ssh.visualstudio.com SSH remotes 2025-08-14 15:20:56 +02:00
🚀 Niklas Arens 8276d4a50a test: TDD - support Azure DevOps vs-ssh.visualstudio.com SSH remotes 2025-08-14 15:20:56 +02:00
Stefan Haller 0c0f53fa31 Allow filtering the keybindings menu by keybinding (#4821)
- **PR Description**

When filtering the keybindings menu using `/`, typing `@` filters by
keybinding.

Closes #4739.
2025-08-14 15:04:56 +02:00
Stefan Haller a08799ac15 Allow filterable contexts to customize the filter label 2025-08-14 15:02:48 +02:00
Stefan Haller 2ed11336b5 Allow filtering for keybindings by prepending filter string with '@' 2025-08-14 15:02:48 +02:00
Stefan Haller d52d5e6a9e Allow filtered lists to preprocess the filter string
An example for this can be seen in the next commit.

We make this a setter rather than an added constructor argument so that we don't
have to change all those contexts that don't want to make use of this.
2025-08-14 15:02:48 +02:00
Stefan Haller f1c07b3aed Strengthen text expectation
This assertion didn't test anything useful, given that the filtered view already
has two lines. This should have been adapted in 9f0b4d0000 when we added
section headers while filtering.
2025-08-14 15:02:48 +02:00
Stefan Haller 389ff29871 Fix right-alignment of divergence from base branch for branch checked out in a worktree (#4824)
- **PR Description**

We didn't take the worktree icon into account properly, so the
divergence indication was offset to the left by two characters in this
case.

I haven't used worktrees myself so far, so I didn't notice this before.
2025-08-14 14:30:51 +02:00
Stefan Haller e54a8b2ee7 Fix right-alignment of divergence from base branch for branch checked out in a worktree
We didn't take the worktree icon into account properly, so the divergence
indication was offset to the left by two characters in this case.
2025-08-14 14:28:11 +02:00
Stefan Haller 1e75aee37e Add installation with gah (#4820)
- **PR Description**

This PR adds to the documentation a way of installation using
[gah](https://github.com/marverix/gah/).

> gah is an GitHub Releases app installer, that does not require sudo.
It is a simple bash script that downloads the latest release of an app
from GitHub and installs it in `~/.local/bin`. It is designed to be used
with apps that are distributed as a single binary file.
2025-08-13 18:30:47 +02:00
Marek Sierociński 08db9b43be docs: Add installation with gah 2025-08-13 11:35:24 +02:00
Stefan Haller 28ef4a13d2 Pass only Git-tracked Go files to gofumpt (#4809)
## **PR Description**
The below error message is shown when executing `make format` when
`test/_results/demo/worktree_create_from_branches/actual/repo/src/shims.go`
exists (maybe executing integration test produces this file?).

```sh
$ make format
gofumpt -l -w .
test/_results/demo/worktree_create_from_branches/actual/repo/src/shims.go:1:20: expected 'package', found 'EOF'
make: *** [format] Error 2
```

I have confirmed it works without above error when I run `make format`
on this PR's branch.
2025-08-12 11:46:02 +02:00
kyu08 e9cc07d4d3 Pass only Git-tracked Go files to gofumpt 2025-08-12 09:05:08 +02:00
114 changed files with 1359 additions and 390 deletions
+11 -9
View File
@@ -6,10 +6,10 @@ labels: bug
assignees: ''
---
**Describe the bug**
### Describe the bug
A clear and concise description of what the bug is.
**To Reproduce**
### To Reproduce
Steps to reproduce the behavior:
1. Go to '...'
@@ -17,20 +17,22 @@ Steps to reproduce the behavior:
3. Scroll down to '....'
4. See error
**Expected behavior**
### Expected behavior
A clear and concise description of what you expected to happen.
**Screenshots**
### Screenshots
If applicable, add screenshots to help explain your problem.
**Version info:**
_Run `lazygit --version` and paste the result here_
_Run `git --version` and paste the result here_
### Version info:
**Additional context**
* _Run `lazygit --version` and paste the result here_
* _Run `git --version` and paste the result here_
### Additional context
Add any other context about the problem here.
**Note:** please try updating to the latest version or [manually building](https://github.com/jesseduffield/lazygit/#manual) the latest `master` to see if the issue still occurs.
> [!NOTE]
> Please try updating to the latest version or [manually building](https://github.com/jesseduffield/lazygit/#manual) the latest `master` to see if the issue still occurs.
<!--
If you want to try and debug this issue yourself, you can run `lazygit --debug` in one terminal panel and `lazygit --logs` in another to view the logs.
+4 -4
View File
@@ -7,8 +7,8 @@ assignees: ''
---
**Topic**
A clear and concise description of what you want to discuss
### Topic
A clear and concise description of what you want to discuss.
**Your thoughts**
What you have to say about the topic
### Your thoughts
What you have to say about the topic.
+4 -4
View File
@@ -6,16 +6,16 @@ labels: enhancement
assignees: ''
---
**Is your feature request related to a problem? Please describe.**
### Is your feature request related to a problem? Please describe.
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
**Describe the solution you'd like**
### Describe the solution you'd like
A clear and concise description of what you want to happen.
**Describe alternatives you've considered**
### Describe alternatives you've considered
A clear and concise description of any alternative solutions or features you've considered.
**Additional context**
### Additional context
Add any other context or screenshots about the feature request here.
<!--
+2 -2
View File
@@ -1,6 +1,6 @@
- **PR Description**
### PR Description
- **Please check if the PR fulfills these requirements**
### Please check if the PR fulfills these requirements
* [ ] Cheatsheets are up-to-date (run `go generate ./...`)
* [ ] Code has been formatted (see [here](https://github.com/jesseduffield/lazygit/blob/master/CONTRIBUTING.md#code-formatting))
@@ -0,0 +1,15 @@
name: Check Required Labels
on:
pull_request:
types: [opened, labeled, unlabeled]
jobs:
check-required-label:
runs-on: ubuntu-latest
steps:
- uses: mheap/github-action-required-labels@v5
with:
mode: exactly
count: 1
labels: "ignore-for-release, feature, enhancement, bug, maintenance, docs, i18n, performance"
-9
View File
@@ -175,15 +175,6 @@ jobs:
- name: errors
run: golangci-lint run
if: ${{ failure() }}
check-required-label:
runs-on: ubuntu-latest
if: github.ref != 'refs/heads/master'
steps:
- uses: mheap/github-action-required-labels@v5
with:
mode: exactly
count: 1
labels: "ignore-for-release, feature, enhancement, bug, maintenance, docs, i18n, performance"
upload-coverage:
# List all jobs that produce coverage files
needs: [unit-tests, integration-tests]
+3 -1
View File
@@ -34,9 +34,11 @@ test: unit-test integration-test-all
generate:
go generate ./...
# If you execute `gofumpt -l -w .`, it will format all Go files in the current directory, including `test/_results/*` files.
# We pass only Git-tracked Go files to gofumpt because we don't want to format the test results or get errors from it.
.PHONY: format
format:
gofumpt -l -w .
git ls-files '*.go' ':!vendor' | xargs gofumpt -l -w
.PHONY: lint
lint:
+26 -4
View File
File diff suppressed because one or more lines are too long
+1 -1
View File
@@ -8,7 +8,7 @@ Lazygit's vision is to be the most enjoyable UI for git.
There are seven (sometimes contradictory) design principles we follow:
- Dicoverability
- Discoverability
- Simplicity
- Safety
- Power
+7 -4
View File
@@ -303,12 +303,12 @@ git:
# ydiff -p cat -s --wrap --width={{columnWidth}}
pager: ""
# If 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).
useConfig: false
# e.g. 'difft --color=always'
externalDiffCommand: ""
# If true, Lazygit will use git's `diff.external` config for paging. The advantage over `externalDiffCommand` is that this can be configured per file type in .gitattributes; see https://git-scm.com/docs/gitattributes#_defining_an_external_diff_driver.
useExternalDiffGitConfig: false
# Config relating to committing
commit:
# If true, pass '--signoff' flag when committing
@@ -517,6 +517,7 @@ keybinding:
universal:
quit: q
quit-alt1: <c-c>
suspendApp: <c-z>
return: <esc>
quitWithoutChangingDirectory: Q
togglePanel: <tab>
@@ -556,6 +557,8 @@ keybinding:
select: <space>
goInto: <enter>
confirm: <enter>
confirmMenu: <enter>
confirmSuggestion: <enter>
confirmInEditor: <a-enter>
confirmInEditor-alt: <c-s>
remove: d
@@ -583,7 +586,7 @@ keybinding:
nextScreenMode: +
prevScreenMode: _
undo: z
redo: <c-z>
redo: Z
filteringMenu: <c-s>
diffingMenu: W
diffingMenu-alt: <c-e>
+11 -13
View File
@@ -10,7 +10,6 @@ Support does not extend to Windows users, because we're making use of a package
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`.
@@ -54,17 +53,6 @@ git:
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).
## Using external diff commands
Some diff tools can't work as a simple pager like the ones above do, because they need access to the entire diff, so just post-processing git's diff is not enough for them. The most notable example is probably [difftastic](https://difftastic.wilfred.me.uk).
@@ -77,7 +65,7 @@ git:
externalDiffCommand: difft --color=always
```
The `colorArg`, `pager`, and `useConfig` options are not used in this case.
The `colorArg` and `pager` options are not used in this case.
You can add whatever extra arguments you prefer for your difftool; for instance
@@ -86,3 +74,13 @@ git:
paging:
externalDiffCommand: difft --color=always --display=inline --syntax-highlight=off
```
Instead of setting this command in lazygit's `externalDiffCommand` config, you can also tell lazygit to use the external diff command that is configured in git itself (`diff.external`), by using
```yaml
git:
paging:
useExternalDiffGitConfig: true
```
This can be useful if you also want to use it for diffs on the command line, and it also has the advantage that you can configure it per file type in `.gitattributes`; see https://git-scm.com/docs/gitattributes#_defining_an_external_diff_driver.
+12 -3
View File
@@ -24,15 +24,16 @@ _Legend: `<c-b>` means ctrl+b, `<a-b>` means alt+b, `B` means shift+b_
| `` R `` | Refresh | Refresh the git state (i.e. run `git status`, `git branch`, etc in background to update the contents of panels). This does not run `git fetch`. |
| `` + `` | Next screen mode (normal/half/fullscreen) | |
| `` _ `` | Prev screen mode | |
| `` <esc> `` | Cancel | |
| `` ? `` | Open keybindings menu | |
| `` <c-s> `` | View filter options | View options for filtering the commit log, so that only commits matching the filter are shown. |
| `` W `` | View diffing options | View options relating to diffing two refs e.g. diffing against selected ref, entering ref to diff against, and reversing the diff direction. |
| `` <c-e> `` | View diffing options | View options relating to diffing two refs e.g. diffing against selected ref, entering ref to diff against, and reversing the diff direction. |
| `` q `` | Quit | |
| `` <esc> `` | Cancel | |
| `` <c-z> `` | Suspend the application | |
| `` <c-w> `` | Toggle whitespace | Toggle whether or not whitespace changes are shown in the diff view.<br><br>The default can be changed in the config file with the key 'git.ignoreWhitespaceInDiffView'. |
| `` z `` | Undo | The reflog will be used to determine what git command to run to undo the last git command. This does not include changes to the working tree; only commits are taken into consideration. |
| `` <c-z> `` | Redo | The reflog will be used to determine what git command to run to redo the last git command. This does not include changes to the working tree; only commits are taken into consideration. |
| `` Z `` | Redo | The reflog will be used to determine what git command to run to redo the last git command. This does not include changes to the working tree; only commits are taken into consideration. |
## List panel navigation
@@ -124,6 +125,7 @@ _Legend: `<c-b>` means ctrl+b, `<a-b>` means alt+b, `B` means shift+b_
|-----|--------|-------------|
| `` <enter> `` | Confirm | |
| `` <esc> `` | Close/Cancel | |
| `` <c-o> `` | Copy to clipboard | |
## Files
@@ -158,6 +160,13 @@ _Legend: `<c-b>` means ctrl+b, `<a-b>` means alt+b, `B` means shift+b_
| `` 0 `` | Focus main view | |
| `` / `` | Search the current view by text | |
## Input prompt
| Key | Action | Info |
|-----|--------|-------------|
| `` <enter> `` | Confirm | |
| `` <esc> `` | Close/Cancel | |
## Local branches
| Key | Action | Info |
@@ -256,7 +265,7 @@ _Legend: `<c-b>` means ctrl+b, `<a-b>` means alt+b, `B` means shift+b_
| Key | Action | Info |
|-----|--------|-------------|
| `` <enter> `` | Execute | |
| `` <esc> `` | Close | |
| `` <esc> `` | Close/Cancel | |
| `` / `` | Filter the current view by text | |
## Reflog
+32 -23
View File
@@ -24,15 +24,16 @@ _凡例:`<c-b>` はctrl+b、`<a-b>` はalt+b、`B` はshift+bを意味
| `` R `` | 更新 | Gitの状態を更新します(`git status`、`git branch`などをバックグラウンドで実行してパネルの内容を更新します)。これは`git fetch`を実行しません。 |
| `` + `` | 次の画面モード(通常/半分/全画面) | |
| `` _ `` | 前の画面モード | |
| `` <esc> `` | キャンセル | |
| `` ? `` | キーバインディングメニューを開く | |
| `` <c-s> `` | フィルターオプションを表示 | コミットログのフィルタリングオプションを表示し、フィルタに一致するコミットのみを表示します。 |
| `` W `` | 差分オプションを表示 | 2つのrefの差分に関連するオプションを表示します(例:選択したrefとの差分表示、差分を取るrefの入力、差分方向の反転など)。 |
| `` <c-e> `` | 差分オプションを表示 | 2つのrefの差分に関連するオプションを表示します(例:選択したrefとの差分表示、差分を取るrefの入力、差分方向の反転など)。 |
| `` q `` | 終了 | |
| `` <esc> `` | キャンセル | |
| `` <c-z> `` | Suspend the application | |
| `` <c-w> `` | 空白表示の切り替え | Toggle whether or not whitespace changes are shown in the diff view.<br><br>The default can be changed in the config file with the key 'git.ignoreWhitespaceInDiffView'. |
| `` z `` | 元に戻す | 最後のgitコマンドを元に戻すために実行するgitコマンドを決定するためにreflogが使用されます。これにはワーキングツリーへの変更は含まれません。コミットのみが考慮されます。 |
| `` <c-z> `` | やり直す | 最後のgitコマンドをやり直すために実行するgitコマンドを決定するためにreflogが使用されます。これにはワーキングツリーへの変更は含まれません。コミットのみが考慮されます。 |
| `` Z `` | やり直す | 最後のgitコマンドをやり直すために実行するgitコマンドを決定するためにreflogが使用されます。これにはワーキングツリーへの変更は含まれません。コミットのみが考慮されます。 |
## リストパネルのナビゲーション
@@ -51,6 +52,13 @@ _凡例:`<c-b>` はctrl+b、`<a-b>` はalt+b、`B` はshift+bを意味
| `` ] `` | 次のタブ | |
| `` [ `` | 前のタブ | |
## Input prompt
| Key | Action | Info |
|-----|--------|-------------|
| `` <enter> `` | 確認 | |
| `` <esc> `` | 閉じる/キャンセル | |
## コミット
| Key | Action | Info |
@@ -74,19 +82,19 @@ _凡例:`<c-b>` はctrl+b、`<a-b>` はalt+b、`B` はshift+bを意味
| `` B `` | リベース用のベースコミットとしてマーク | 次のリベース用のベースコミットを選択します。ブランチにリベースするとき、ベースコミットより上のコミットのみが持ち込まれます。これは `git rebase --onto` コマンドを使用します。 |
| `` A `` | 修正 | ステージされた変更でコミットを修正します。選択したコミットがHEADコミットの場合、これは `git commit --amend` を実行します。それ以外の場合、コミットはリベースを通じて修正されます。 |
| `` a `` | コミット属性を修正 | コミット作者の設定/リセットまたは共同作者の設定を行います。 |
| `` t `` | 元に戻す | 選択したコミットの変更を逆に適用する、リバートコミットを作成します。 |
| `` t `` | リバート | 選択したコミットの変更を逆に適用する、リバートコミットを作成します。 |
| `` T `` | コミットにタグを付ける | 選択したコミットを指すタグを新規作成します。タグ名とオプションの説明を入力するよう促されます。 |
| `` <c-l> `` | ログオプションを表示 | コミットログのオプションを表示します(例:並び順の変更、Gitグラフの非表示、Gitグラフ全体の表示)。 |
| `` <space> `` | チェックアウト(ブランチの切り替え) | 選択したコミットをデタッチドヘッド(特定のブランチに属さない状態)としてチェックアウトします。 |
| `` y `` | コミット属性をクリップボードにコピー | コミット属性をクリップボードにコピーします(例:ハッシュ、URL、差分、メッセージ、作者)。 |
| `` o `` | ブラウザでコミットを開く | |
| `` n `` | コミットから新しいブランチを作成 | |
| `` N `` | Move commits to new branch | Create a new branch and move the unpushed commits of the current branch to it. Useful if you meant to start new work and forgot to create a new branch first.<br><br>Note that this disregards the selection, the new branch is always created either from the main branch or stacked on top of the current branch (you get to choose which). |
| `` N `` | コミットを新しいブランチに移動 | Create a new branch and move the unpushed commits of the current branch to it. Useful if you meant to start new work and forgot to create a new branch first.<br><br>Note that this disregards the selection, the new branch is always created either from the main branch or stacked on top of the current branch (you get to choose which). |
| `` g `` | リセット | 選択した項目へのリセットオプション(ソフト/ミックス/ハード)を表示します。各リセットタイプの詳細は次の通りです:<br>- ソフトリセット:変更を保持し、ステージされた状態にします<br>- ミックスリセット:変更を保持し、ステージされていない状態にします<br>- ハードリセット:すべての変更を破棄します |
| `` C `` | コピー(チェリーピック) | コミットをコピーとしてマークします。ローカルコミットビューで `V` を押すと、コピーしたコミットをチェックアウトしたブランチにペースト(チェリーピック)できます。いつでも `<esc>` を押して選択をキャンセルできます。 |
| `` <c-t> `` | 外部差分ツールを開く(git difftool) | |
| `` * `` | 現在のブランチのコミットを選択 | |
| `` 0 `` | Focus main view | |
| `` 0 `` | メインビューにフォーカス | |
| `` <enter> `` | ファイルを表示 | |
| `` w `` | ワークツリーオプションを表示 | |
| `` / `` | 現在のビューをテキストで検索 | |
@@ -108,7 +116,7 @@ _凡例:`<c-b>` はctrl+b、`<a-b>` はalt+b、`B` はshift+bを意味
| `` ` `` | ファイルツリービューを切り替え | Toggle file view between flat and tree layout. Flat layout shows all file paths in a single list, tree layout groups files by directory.<br><br>The default can be changed in the config file with the key 'gui.showFileTree'. |
| `` - `` | すべてのファイルを折りたたむ | ファイルツリー内のすべてのディレクトリを折りたたみます |
| `` = `` | すべてのファイルを展開 | ファイルツリー内のすべてのディレクトリを展開します |
| `` 0 `` | Focus main view | |
| `` 0 `` | メインビューにフォーカス | |
| `` / `` | 現在のビューをテキストで検索 | |
## コミット概要
@@ -127,13 +135,13 @@ _凡例:`<c-b>` はctrl+b、`<a-b>` はalt+b、`B` はshift+bを意味
| `` y `` | コミット属性をクリップボードにコピー | コミット属性をクリップボードにコピーします(例:ハッシュ、URL、差分、メッセージ、作者)。 |
| `` o `` | ブラウザでコミットを開く | |
| `` n `` | コミットから新しいブランチを作成 | |
| `` N `` | Move commits to new branch | Create a new branch and move the unpushed commits of the current branch to it. Useful if you meant to start new work and forgot to create a new branch first.<br><br>Note that this disregards the selection, the new branch is always created either from the main branch or stacked on top of the current branch (you get to choose which). |
| `` N `` | コミットを新しいブランチに移動 | Create a new branch and move the unpushed commits of the current branch to it. Useful if you meant to start new work and forgot to create a new branch first.<br><br>Note that this disregards the selection, the new branch is always created either from the main branch or stacked on top of the current branch (you get to choose which). |
| `` g `` | リセット | 選択した項目へのリセットオプション(ソフト/ミックス/ハード)を表示します。各リセットタイプの詳細は次の通りです:<br>- ソフトリセット:変更を保持し、ステージされた状態にします<br>- ミックスリセット:変更を保持し、ステージされていない状態にします<br>- ハードリセット:すべての変更を破棄します |
| `` C `` | コピー(チェリーピック) | コミットをコピーとしてマークします。ローカルコミットビューで `V` を押すと、コピーしたコミットをチェックアウトしたブランチにペースト(チェリーピック)できます。いつでも `<esc>` を押して選択をキャンセルできます。 |
| `` <c-r> `` | コピーされた(チェリーピックされた)コミットの選択をリセット | |
| `` <c-t> `` | 外部差分ツールを開く(git difftool) | |
| `` * `` | 現在のブランチのコミットを選択 | |
| `` 0 `` | Focus main view | |
| `` 0 `` | メインビューにフォーカス | |
| `` <enter> `` | ファイルを表示 | |
| `` w `` | ワークツリーオプションを表示 | |
| `` / `` | 現在のビューをテキストで検索 | |
@@ -161,7 +169,7 @@ _凡例:`<c-b>` はctrl+b、`<a-b>` はalt+b、`B` はshift+bを意味
| `` d `` | 削除 | スタッシュリストからスタッシュエントリを削除します。 |
| `` n `` | 新しいブランチ | 選択したスタッシュエントリから新しいブランチを作成します。これは、スタッシュエントリが作成されたコミットをgitがチェックアウトし、そのコミットから新しいブランチを作成した後、スタッシュエントリを追加のコミットとして新しいブランチに適用することで機能します。 |
| `` r `` | スタッシュの名前を変更 | |
| `` 0 `` | Focus main view | |
| `` 0 `` | メインビューにフォーカス | |
| `` <enter> `` | ファイルを表示 | |
| `` w `` | ワークツリーオプションを表示 | |
| `` / `` | 現在のビューをテキストでフィルタリング | |
@@ -175,14 +183,14 @@ _凡例:`<c-b>` はctrl+b、`<a-b>` はalt+b、`B` はshift+bを意味
| `` u `` | 更新を確認 | |
| `` <enter> `` | 最近のリポジトリをチェックアウト | |
| `` a `` | ブランチログの表示モードを順に切り替え | |
| `` 0 `` | Focus main view | |
| `` 0 `` | メインビューにフォーカス | |
## セカンダリ
| Key | Action | Info |
|-----|--------|-------------|
| `` <tab> `` | ビューを切り替え | 他のビュー(ステージされた変更/ステージされていない変更)に切り替えます。 |
| `` <esc> `` | Exit back to side panel | |
| `` <esc> `` | サイドパネルに戻る | |
| `` / `` | 現在のビューをテキストで検索 | |
## タグ
@@ -196,7 +204,7 @@ _凡例:`<c-b>` はctrl+b、`<a-b>` はalt+b、`B` はshift+bを意味
| `` P `` | タグをプッシュ | 選択したタグをリモートにプッシュします。リモートを選択するよう促されます。 |
| `` g `` | リセット | 選択した項目へのリセットオプション(ソフト/ミックス/ハード)を表示します。各リセットタイプの詳細は次の通りです:<br>- ソフトリセット:変更を保持し、ステージされた状態にします<br>- ミックスリセット:変更を保持し、ステージされていない状態にします<br>- ハードリセット:すべての変更を破棄します |
| `` <c-t> `` | 外部差分ツールを開く(git difftool) | |
| `` 0 `` | Focus main view | |
| `` 0 `` | メインビューにフォーカス | |
| `` <enter> `` | コミットを表示 | |
| `` w `` | ワークツリーオプションを表示 | |
| `` / `` | 現在のビューをテキストでフィルタリング | |
@@ -231,7 +239,7 @@ _凡例:`<c-b>` はctrl+b、`<a-b>` はalt+b、`B` はshift+bを意味
| `` f `` | フェッチ | リモートから変更をフェッチします。 |
| `` - `` | すべてのファイルを折りたたむ | ファイルツリー内のすべてのディレクトリを折りたたみます |
| `` = `` | すべてのファイルを展開 | ファイルツリー内のすべてのディレクトリを展開します |
| `` 0 `` | Focus main view | |
| `` 0 `` | メインビューにフォーカス | |
| `` / `` | 現在のビューをテキストで検索 | |
## メインパネル(ステージング)
@@ -241,7 +249,7 @@ _凡例:`<c-b>` はctrl+b、`<a-b>` はalt+b、`B` はshift+bを意味
| `` <left> `` | 前のハンクに移動 | |
| `` <right> `` | 次のハンクに移動 | |
| `` v `` | 範囲選択を切り替え | |
| `` a `` | Toggle hunk selection | Toggle line-by-line vs. hunk selection mode. |
| `` a `` | ハンクの選択を切り替える | Toggle line-by-line vs. hunk selection mode. |
| `` <c-o> `` | 選択したテキストをクリップボードにコピー | |
| `` <space> `` | ステージ | 選択された部分のステージ / アンステージを切り替えます。 |
| `` d `` | 破棄 | ステージされていない変更が選択されている場合、`git reset`を使用して変更を破棄します。ステージされた変更が選択されている場合、変更をアンステージします。 |
@@ -263,7 +271,7 @@ _凡例:`<c-b>` はctrl+b、`<a-b>` はalt+b、`B` はshift+bを意味
| `` <left> `` | 前のハンクに移動 | |
| `` <right> `` | 次のハンクに移動 | |
| `` v `` | 範囲選択を切り替え | |
| `` a `` | Toggle hunk selection | Toggle line-by-line vs. hunk selection mode. |
| `` a `` | ハンクの選択を切り替える | Toggle line-by-line vs. hunk selection mode. |
| `` <c-o> `` | 選択したテキストをクリップボードにコピー | |
| `` o `` | ファイルを開く | デフォルトのアプリケーションでファイルを開きます。 |
| `` e `` | ファイルを編集 | 外部エディタでファイルを開きます。 |
@@ -294,7 +302,7 @@ _凡例:`<c-b>` はctrl+b、`<a-b>` はalt+b、`B` はshift+bを意味
| `` mouse wheel down (fn+up) `` | 下にスクロール | |
| `` mouse wheel up (fn+down) `` | 上にスクロール | |
| `` <tab> `` | ビューを切り替え | 他のビュー(ステージされた変更/ステージされていない変更)に切り替えます。 |
| `` <esc> `` | Exit back to side panel | |
| `` <esc> `` | サイドパネルに戻る | |
| `` / `` | 現在のビューをテキストで検索 | |
## メニュー
@@ -302,7 +310,7 @@ _凡例:`<c-b>` はctrl+b、`<a-b>` はalt+b、`B` はshift+bを意味
| Key | Action | Info |
|-----|--------|-------------|
| `` <enter> `` | 実行 | |
| `` <esc> `` | 閉じる | |
| `` <esc> `` | 閉じる/キャンセル | |
| `` / `` | 現在のビューをテキストでフィルタリング | |
## リフログ
@@ -314,13 +322,13 @@ _凡例:`<c-b>` はctrl+b、`<a-b>` はalt+b、`B` はshift+bを意味
| `` y `` | コミット属性をクリップボードにコピー | コミット属性をクリップボードにコピーします(例:ハッシュ、URL、差分、メッセージ、作者)。 |
| `` o `` | ブラウザでコミットを開く | |
| `` n `` | コミットから新しいブランチを作成 | |
| `` N `` | Move commits to new branch | Create a new branch and move the unpushed commits of the current branch to it. Useful if you meant to start new work and forgot to create a new branch first.<br><br>Note that this disregards the selection, the new branch is always created either from the main branch or stacked on top of the current branch (you get to choose which). |
| `` N `` | コミットを新しいブランチに移動 | Create a new branch and move the unpushed commits of the current branch to it. Useful if you meant to start new work and forgot to create a new branch first.<br><br>Note that this disregards the selection, the new branch is always created either from the main branch or stacked on top of the current branch (you get to choose which). |
| `` g `` | リセット | 選択した項目へのリセットオプション(ソフト/ミックス/ハード)を表示します。各リセットタイプの詳細は次の通りです:<br>- ソフトリセット:変更を保持し、ステージされた状態にします<br>- ミックスリセット:変更を保持し、ステージされていない状態にします<br>- ハードリセット:すべての変更を破棄します |
| `` C `` | コピー(チェリーピック) | コミットをコピーとしてマークします。ローカルコミットビューで `V` を押すと、コピーしたコミットをチェックアウトしたブランチにペースト(チェリーピック)できます。いつでも `<esc>` を押して選択をキャンセルできます。 |
| `` <c-r> `` | コピーされた(チェリーピックされた)コミットの選択をリセット | |
| `` <c-t> `` | 外部差分ツールを開く(git difftool) | |
| `` * `` | 現在のブランチのコミットを選択 | |
| `` 0 `` | Focus main view | |
| `` 0 `` | メインビューにフォーカス | |
| `` <enter> `` | コミットを表示 | |
| `` w `` | ワークツリーオプションを表示 | |
| `` / `` | 現在のビューをテキストでフィルタリング | |
@@ -350,7 +358,7 @@ _凡例:`<c-b>` はctrl+b、`<a-b>` はalt+b、`B` はshift+bを意味
| `` s `` | 並び順 | |
| `` g `` | リセット | 選択した項目へのリセットオプション(ソフト/ミックス/ハード)を表示します。各リセットタイプの詳細は次の通りです:<br>- ソフトリセット:変更を保持し、ステージされた状態にします<br>- ミックスリセット:変更を保持し、ステージされていない状態にします<br>- ハードリセット:すべての変更を破棄します |
| `` <c-t> `` | 外部差分ツールを開く(git difftool) | |
| `` 0 `` | Focus main view | |
| `` 0 `` | メインビューにフォーカス | |
| `` <enter> `` | コミットを表示 | |
| `` w `` | ワークツリーオプションを表示 | |
| `` / `` | 現在のビューをテキストでフィルタリング | |
@@ -363,12 +371,12 @@ _凡例:`<c-b>` はctrl+b、`<a-b>` はalt+b、`B` はshift+bを意味
| `` i `` | git-flowオプションを表示 | |
| `` <space> `` | チェックアウト(ブランチの切り替え) | 選択した項目をチェックアウトします。 |
| `` n `` | 新しいブランチ | |
| `` N `` | Move commits to new branch | Create a new branch and move the unpushed commits of the current branch to it. Useful if you meant to start new work and forgot to create a new branch first.<br><br>Note that this disregards the selection, the new branch is always created either from the main branch or stacked on top of the current branch (you get to choose which). |
| `` N `` | コミットを新しいブランチに移動 | Create a new branch and move the unpushed commits of the current branch to it. Useful if you meant to start new work and forgot to create a new branch first.<br><br>Note that this disregards the selection, the new branch is always created either from the main branch or stacked on top of the current branch (you get to choose which). |
| `` o `` | プルリクエストを作成 | |
| `` O `` | プルリクエスト作成オプションを表示 | |
| `` <c-y> `` | プルリクエストURLをクリップボードにコピー | |
| `` c `` | 名前でチェックアウト | 名前でチェックアウトします。入力ボックスに「-」を入力すると、最後のブランチをチェックアウトすることができます。 |
| `` - `` | Checkout previous branch | |
| `` - `` | 直前のブランチにチェックアウト | |
| `` F `` | 強制チェックアウト | 選択したブランチを強制的にチェックアウトします。これにより、選択したブランチをチェックアウトする前にワーキングディレクトリ内のすべてのローカル変更が破棄されます。 |
| `` d `` | 削除 | ローカル/リモートブランチの削除オプションを表示します。 |
| `` r `` | リベース | チェックアウトしたブランチを選択したブランチ上にリベースします。 |
@@ -380,7 +388,7 @@ _凡例:`<c-b>` はctrl+b、`<a-b>` はalt+b、`B` はshift+bを意味
| `` R `` | ブランチ名を変更 | |
| `` u `` | アップストリームオプションを表示 | ブランチのアップストリームに関連するオプションを表示します(例:アップストリームの設定/解除やアップストリームへのリセット)。 |
| `` <c-t> `` | 外部差分ツールを開く(git difftool) | |
| `` 0 `` | Focus main view | |
| `` 0 `` | メインビューにフォーカス | |
| `` <enter> `` | コミットを表示 | |
| `` w `` | ワークツリーオプションを表示 | |
| `` / `` | 現在のビューをテキストでフィルタリング | |
@@ -401,3 +409,4 @@ _凡例:`<c-b>` はctrl+b、`<a-b>` はalt+b、`B` はshift+bを意味
|-----|--------|-------------|
| `` <enter> `` | 確認 | |
| `` <esc> `` | 閉じる/キャンセル | |
| `` <c-o> `` | クリップボードにコピー | |
+12 -3
View File
@@ -24,15 +24,16 @@ _Legend: `<c-b>` means ctrl+b, `<a-b>` means alt+b, `B` means shift+b_
| `` R `` | 새로고침 | Refresh the git state (i.e. run `git status`, `git branch`, etc in background to update the contents of panels). This does not run `git fetch`. |
| `` + `` | 다음 스크린 모드 (normal/half/fullscreen) | |
| `` _ `` | 이전 스크린 모드 | |
| `` <esc> `` | 취소 | |
| `` ? `` | 매뉴 열기 | |
| `` <c-s> `` | View filter-by-path options | View options for filtering the commit log, so that only commits matching the filter are shown. |
| `` W `` | Diff 메뉴 열기 | View options relating to diffing two refs e.g. diffing against selected ref, entering ref to diff against, and reversing the diff direction. |
| `` <c-e> `` | Diff 메뉴 열기 | View options relating to diffing two refs e.g. diffing against selected ref, entering ref to diff against, and reversing the diff direction. |
| `` q `` | 종료 | |
| `` <esc> `` | 취소 | |
| `` <c-z> `` | Suspend the application | |
| `` <c-w> `` | 공백문자를 Diff 뷰에서 표시 여부 전환 | Toggle whether or not whitespace changes are shown in the diff view.<br><br>The default can be changed in the config file with the key 'git.ignoreWhitespaceInDiffView'. |
| `` z `` | 되돌리기 (reflog) (실험적) | The reflog will be used to determine what git command to run to undo the last git command. This does not include changes to the working tree; only commits are taken into consideration. |
| `` <c-z> `` | 다시 실행 (reflog) (실험적) | The reflog will be used to determine what git command to run to redo the last git command. This does not include changes to the working tree; only commits are taken into consideration. |
| `` Z `` | 다시 실행 (reflog) (실험적) | The reflog will be used to determine what git command to run to redo the last git command. This does not include changes to the working tree; only commits are taken into consideration. |
## List panel navigation
@@ -51,6 +52,13 @@ _Legend: `<c-b>` means ctrl+b, `<a-b>` means alt+b, `B` means shift+b_
| `` ] `` | 이전 탭 | |
| `` [ `` | 다음 탭 | |
## Input prompt
| Key | Action | Info |
|-----|--------|-------------|
| `` <enter> `` | 확인 | |
| `` <esc> `` | 닫기/취소 | |
## Reflog
| Key | Action | Info |
@@ -128,7 +136,7 @@ _Legend: `<c-b>` means ctrl+b, `<a-b>` means alt+b, `B` means shift+b_
| Key | Action | Info |
|-----|--------|-------------|
| `` <enter> `` | 실행 | |
| `` <esc> `` | 닫기 | |
| `` <esc> `` | 닫기/취소 | |
| `` / `` | Filter the current view by text | |
## 메인 패널 (Merging)
@@ -401,3 +409,4 @@ _Legend: `<c-b>` means ctrl+b, `<a-b>` means alt+b, `B` means shift+b_
|-----|--------|-------------|
| `` <enter> `` | 확인 | |
| `` <esc> `` | 닫기/취소 | |
| `` <c-o> `` | 클립보드에 복사 | |
+11 -2
View File
@@ -24,15 +24,16 @@ _Legend: `<c-b>` means ctrl+b, `<a-b>` means alt+b, `B` means shift+b_
| `` R `` | Verversen | Refresh the git state (i.e. run `git status`, `git branch`, etc in background to update the contents of panels). This does not run `git fetch`. |
| `` + `` | Volgende scherm modus (normaal/half/groot) | |
| `` _ `` | Vorige scherm modus | |
| `` <esc> `` | Annuleren | |
| `` ? `` | Open menu | |
| `` <c-s> `` | Bekijk scoping opties | View options for filtering the commit log, so that only commits matching the filter are shown. |
| `` W `` | Open diff menu | View options relating to diffing two refs e.g. diffing against selected ref, entering ref to diff against, and reversing the diff direction. |
| `` <c-e> `` | Open diff menu | View options relating to diffing two refs e.g. diffing against selected ref, entering ref to diff against, and reversing the diff direction. |
| `` q `` | Quit | |
| `` <esc> `` | Annuleren | |
| `` <c-z> `` | Suspend the application | |
| `` <c-w> `` | Toggle whitespace | Toggle whether or not whitespace changes are shown in the diff view.<br><br>The default can be changed in the config file with the key 'git.ignoreWhitespaceInDiffView'. |
| `` z `` | Ongedaan maken (via reflog) (experimenteel) | The reflog will be used to determine what git command to run to undo the last git command. This does not include changes to the working tree; only commits are taken into consideration. |
| `` <c-z> `` | Redo (via reflog) (experimenteel) | The reflog will be used to determine what git command to run to redo the last git command. This does not include changes to the working tree; only commits are taken into consideration. |
| `` Z `` | Redo (via reflog) (experimenteel) | The reflog will be used to determine what git command to run to redo the last git command. This does not include changes to the working tree; only commits are taken into consideration. |
## Lijstpaneel navigatie
@@ -90,6 +91,7 @@ _Legend: `<c-b>` means ctrl+b, `<a-b>` means alt+b, `B` means shift+b_
|-----|--------|-------------|
| `` <enter> `` | Bevestig | |
| `` <esc> `` | Sluiten | |
| `` <c-o> `` | Copy to clipboard | |
## Branches
@@ -188,6 +190,13 @@ _Legend: `<c-b>` means ctrl+b, `<a-b>` means alt+b, `B` means shift+b_
| `` w `` | View worktree options | |
| `` / `` | Start met zoeken | |
## Input prompt
| Key | Action | Info |
|-----|--------|-------------|
| `` <enter> `` | Bevestig | |
| `` <esc> `` | Sluiten | |
## Menu
| Key | Action | Info |
+12 -3
View File
@@ -24,15 +24,16 @@ _Legenda: `<c-b>` oznacza ctrl+b, `<a-b>` oznacza alt+b, `B` oznacza shift+b_
| `` R `` | Odśwież | Odśwież stan git (tj. uruchom `git status`, `git branch`, itp. w tle, aby zaktualizować zawartość paneli). To nie uruchamia `git fetch`. |
| `` + `` | Następny tryb ekranu (normalny/półpełny/pełnoekranowy) | |
| `` _ `` | Poprzedni tryb ekranu | |
| `` <esc> `` | Anuluj | |
| `` ? `` | Otwórz menu przypisań klawiszy | |
| `` <c-s> `` | Pokaż opcje filtrowania | Pokaż opcje filtrowania dziennika commitów, tak aby pokazywane były tylko commity pasujące do filtra. |
| `` W `` | Pokaż opcje różnicowania | Pokaż opcje dotyczące różnicowania dwóch refów, np. różnicowanie względem wybranego refa, wprowadzanie refa do różnicowania i odwracanie kierunku różnic. |
| `` <c-e> `` | Pokaż opcje różnicowania | Pokaż opcje dotyczące różnicowania dwóch refów, np. różnicowanie względem wybranego refa, wprowadzanie refa do różnicowania i odwracanie kierunku różnic. |
| `` q `` | Wyjdź | |
| `` <esc> `` | Anuluj | |
| `` <c-z> `` | Suspend the application | |
| `` <c-w> `` | Przełącz białe znaki | Toggle whether or not whitespace changes are shown in the diff view.<br><br>The default can be changed in the config file with the key 'git.ignoreWhitespaceInDiffView'. |
| `` z `` | Cofnij | Dziennik reflog zostanie użyty do określenia, jakie polecenie git należy uruchomić, aby cofnąć ostatnie polecenie git. Nie obejmuje to zmian w drzewie roboczym; brane są pod uwagę tylko commity. |
| `` <c-z> `` | Ponów | Dziennik reflog zostanie użyty do określenia, jakie polecenie git należy uruchomić, aby ponowić ostatnie polecenie git. Nie obejmuje to zmian w drzewie roboczym; brane są pod uwagę tylko commity. |
| `` Z `` | Ponów | Dziennik reflog zostanie użyty do określenia, jakie polecenie git należy uruchomić, aby ponowić ostatnie polecenie git. Nie obejmuje to zmian w drzewie roboczym; brane są pod uwagę tylko commity. |
## Nawigacja panelu listy
@@ -124,6 +125,13 @@ _Legenda: `<c-b>` oznacza ctrl+b, `<a-b>` oznacza alt+b, `B` oznacza shift+b_
| `` <esc> `` | Wyjdź z budowniczego niestandardowej łatki | |
| `` / `` | Szukaj w bieżącym widoku po tekście | |
## Input prompt
| Key | Action | Info |
|-----|--------|-------------|
| `` <enter> `` | Potwierdź | |
| `` <esc> `` | Zamknij/Anuluj | |
## Lokalne gałęzie
| Key | Action | Info |
@@ -159,7 +167,7 @@ _Legenda: `<c-b>` oznacza ctrl+b, `<a-b>` oznacza alt+b, `B` oznacza shift+b_
| Key | Action | Info |
|-----|--------|-------------|
| `` <enter> `` | Wykonaj | |
| `` <esc> `` | Zamknij | |
| `` <esc> `` | Zamknij/Anuluj | |
| `` / `` | Filtruj bieżący widok po tekście | |
## Panel główny (normalny)
@@ -216,6 +224,7 @@ _Legenda: `<c-b>` oznacza ctrl+b, `<a-b>` oznacza alt+b, `B` oznacza shift+b_
|-----|--------|-------------|
| `` <enter> `` | Potwierdź | |
| `` <esc> `` | Zamknij/Anuluj | |
| `` <c-o> `` | Kopiuj do schowka | |
## Pliki
+17 -8
View File
@@ -24,15 +24,16 @@ _Legend: `<c-b>` means ctrl+b, `<a-b>` means alt+b, `B` means shift+b_
| `` R `` | Atualizar | Atualize o estado do git (ou seja, execute `git status`, `git branch`, etc em segundo plano para atualizar o conteúdo de painéis). Isso não executa `git fetch`. |
| `` + `` | Next screen mode (normal/half/fullscreen) | |
| `` _ `` | Prev screen mode | |
| `` <esc> `` | Cancelar | |
| `` ? `` | Open keybindings menu | |
| `` <c-s> `` | View filter options | View options for filtering the commit log, so that only commits matching the filter are shown. |
| `` W `` | View diffing options | View options relating to diffing two refs e.g. diffing against selected ref, entering ref to diff against, and reversing the diff direction. |
| `` <c-e> `` | View diffing options | View options relating to diffing two refs e.g. diffing against selected ref, entering ref to diff against, and reversing the diff direction. |
| `` q `` | Sair | |
| `` <esc> `` | Cancelar | |
| `` <c-z> `` | Suspend the application | |
| `` <c-w> `` | Toggle whitespace | Toggle whether or not whitespace changes are shown in the diff view.<br><br>The default can be changed in the config file with the key 'git.ignoreWhitespaceInDiffView'. |
| `` z `` | Desfazer | O reflog será usado para determinar qual comando git para executar para desfazer o último comando git. Isto não inclui mudanças na árvore de trabalho; apenas compromissos são tidos em consideração. |
| `` <c-z> `` | Refazer | O reflog será usado para determinar qual comando git para executar para refazer o último comando git. Isto não inclui mudanças na árvore de trabalho; apenas compromissos são tidos em consideração. |
| `` Z `` | Refazer | O reflog será usado para determinar qual comando git para executar para refazer o último comando git. Isto não inclui mudanças na árvore de trabalho; apenas compromissos são tidos em consideração. |
## List panel navigation
@@ -92,12 +93,12 @@ _Legend: `<c-b>` means ctrl+b, `<a-b>` means alt+b, `B` means shift+b_
| `` i `` | Exibir opções do git-flow | |
| `` <space> `` | Verificar | Checar item selecionado |
| `` n `` | Nova branch | |
| `` N `` | Move commits to new branch | Create a new branch and move the unpushed commits of the current branch to it. Useful if you meant to start new work and forgot to create a new branch first.<br><br>Note that this disregards the selection, the new branch is always created either from the main branch or stacked on top of the current branch (you get to choose which). |
| `` N `` | Mover commits para uma nova branch | Create a new branch and move the unpushed commits of the current branch to it. Useful if you meant to start new work and forgot to create a new branch first.<br><br>Note that this disregards the selection, the new branch is always created either from the main branch or stacked on top of the current branch (you get to choose which). |
| `` o `` | Create pull request | |
| `` O `` | View create pull request options | |
| `` <c-y> `` | Copiar URL do pull request para área de transferência | |
| `` c `` | Checar por nome | Checar por nome. Na caixa de entrada você pode inserir '-' para trocar para a última branch |
| `` - `` | Checkout previous branch | |
| `` - `` | Checkout da branch anterior | |
| `` F `` | Forçar checagem | Forçar checagem da branch selecionada. Isso irá descartar todas as mudanças no seu diretório de trabalho antes cheque a branch selecionada |
| `` d `` | Apagar | Ver opções de exclusão para a branch local/remoto. |
| `` r `` | Refazer | Refazer a branch checada na branch selecionada |
@@ -183,7 +184,7 @@ _Legend: `<c-b>` means ctrl+b, `<a-b>` means alt+b, `B` means shift+b_
| `` y `` | Copy commit attribute to clipboard | Copy commit attribute to clipboard (e.g. hash, URL, diff, message, author). |
| `` o `` | Open commit in browser | |
| `` n `` | Create new branch off of commit | |
| `` N `` | Move commits to new branch | Create a new branch and move the unpushed commits of the current branch to it. Useful if you meant to start new work and forgot to create a new branch first.<br><br>Note that this disregards the selection, the new branch is always created either from the main branch or stacked on top of the current branch (you get to choose which). |
| `` N `` | Mover commits para uma nova branch | Create a new branch and move the unpushed commits of the current branch to it. Useful if you meant to start new work and forgot to create a new branch first.<br><br>Note that this disregards the selection, the new branch is always created either from the main branch or stacked on top of the current branch (you get to choose which). |
| `` g `` | Restaurar | Ver opções de redefinição (soft/mixed/hard) para redefinir para o item selecionado. |
| `` C `` | Copiar (cherry-pick) | Marcar commit como copiado. Então, dentro da visualização local de commits, você pode pressionar `V` para colar (cherry-pick) o(s) commit(s) copiado(s) em seu branch de check-out. A qualquer momento você pode pressionar `<esc>` para cancelar a seleção. |
| `` <c-t> `` | Abrir ferramenta de diff externa (git difftool) | |
@@ -199,6 +200,7 @@ _Legend: `<c-b>` means ctrl+b, `<a-b>` means alt+b, `B` means shift+b_
|-----|--------|-------------|
| `` <enter> `` | Confirmar | |
| `` <esc> `` | Fechar/Cancelar | |
| `` <c-o> `` | Copy to clipboard | |
## Etiquetas
@@ -216,12 +218,19 @@ _Legend: `<c-b>` means ctrl+b, `<a-b>` means alt+b, `B` means shift+b_
| `` w `` | View worktree options | |
| `` / `` | Filter the current view by text | |
## Input prompt
| Key | Action | Info |
|-----|--------|-------------|
| `` <enter> `` | Confirmar | |
| `` <esc> `` | Fechar/Cancelar | |
## Menu
| Key | Action | Info |
|-----|--------|-------------|
| `` <enter> `` | Executar | |
| `` <esc> `` | Fechar | |
| `` <esc> `` | Fechar/Cancelar | |
| `` / `` | Filter the current view by text | |
## Painel Principal (Normal)
@@ -296,7 +305,7 @@ _Legend: `<c-b>` means ctrl+b, `<a-b>` means alt+b, `B` means shift+b_
| `` y `` | Copy commit attribute to clipboard | Copy commit attribute to clipboard (e.g. hash, URL, diff, message, author). |
| `` o `` | Open commit in browser | |
| `` n `` | Create new branch off of commit | |
| `` N `` | Move commits to new branch | Create a new branch and move the unpushed commits of the current branch to it. Useful if you meant to start new work and forgot to create a new branch first.<br><br>Note that this disregards the selection, the new branch is always created either from the main branch or stacked on top of the current branch (you get to choose which). |
| `` N `` | Mover commits para uma nova branch | Create a new branch and move the unpushed commits of the current branch to it. Useful if you meant to start new work and forgot to create a new branch first.<br><br>Note that this disregards the selection, the new branch is always created either from the main branch or stacked on top of the current branch (you get to choose which). |
| `` g `` | Restaurar | Ver opções de redefinição (soft/mixed/hard) para redefinir para o item selecionado. |
| `` C `` | Copiar (cherry-pick) | Marcar commit como copiado. Então, dentro da visualização local de commits, você pode pressionar `V` para colar (cherry-pick) o(s) commit(s) copiado(s) em seu branch de check-out. A qualquer momento você pode pressionar `<esc>` para cancelar a seleção. |
| `` <c-r> `` | Reset copied (cherry-picked) commits selection | |
@@ -360,7 +369,7 @@ _Legend: `<c-b>` means ctrl+b, `<a-b>` means alt+b, `B` means shift+b_
| `` y `` | Copy commit attribute to clipboard | Copy commit attribute to clipboard (e.g. hash, URL, diff, message, author). |
| `` o `` | Open commit in browser | |
| `` n `` | Create new branch off of commit | |
| `` N `` | Move commits to new branch | Create a new branch and move the unpushed commits of the current branch to it. Useful if you meant to start new work and forgot to create a new branch first.<br><br>Note that this disregards the selection, the new branch is always created either from the main branch or stacked on top of the current branch (you get to choose which). |
| `` N `` | Mover commits para uma nova branch | Create a new branch and move the unpushed commits of the current branch to it. Useful if you meant to start new work and forgot to create a new branch first.<br><br>Note that this disregards the selection, the new branch is always created either from the main branch or stacked on top of the current branch (you get to choose which). |
| `` g `` | Restaurar | Ver opções de redefinição (soft/mixed/hard) para redefinir para o item selecionado. |
| `` C `` | Copiar (cherry-pick) | Marcar commit como copiado. Então, dentro da visualização local de commits, você pode pressionar `V` para colar (cherry-pick) o(s) commit(s) copiado(s) em seu branch de check-out. A qualquer momento você pode pressionar `<esc>` para cancelar a seleção. |
| `` <c-r> `` | Reset copied (cherry-picked) commits selection | |
+12 -3
View File
@@ -24,15 +24,16 @@ _Связки клавиш_
| `` R `` | Обновить | Refresh the git state (i.e. run `git status`, `git branch`, etc in background to update the contents of panels). This does not run `git fetch`. |
| `` + `` | Следующий режим экрана (нормальный/полуэкранный/полноэкранный) | |
| `` _ `` | Предыдущий режим экрана | |
| `` <esc> `` | Отменить | |
| `` ? `` | Открыть меню | |
| `` <c-s> `` | Просмотреть параметры фильтрации по пути | View options for filtering the commit log, so that only commits matching the filter are shown. |
| `` W `` | Открыть меню сравнении | View options relating to diffing two refs e.g. diffing against selected ref, entering ref to diff against, and reversing the diff direction. |
| `` <c-e> `` | Открыть меню сравнении | View options relating to diffing two refs e.g. diffing against selected ref, entering ref to diff against, and reversing the diff direction. |
| `` q `` | Выйти | |
| `` <esc> `` | Отменить | |
| `` <c-z> `` | Suspend the application | |
| `` <c-w> `` | Переключить отображение изменении пробелов в просмотрщике сравнении | Toggle whether or not whitespace changes are shown in the diff view.<br><br>The default can be changed in the config file with the key 'git.ignoreWhitespaceInDiffView'. |
| `` z `` | Отменить (через reflog) (экспериментальный) | Журнал ссылок (reflog) будет использоваться для определения того, какую команду git запустить, чтобы отменить последнюю команду git. Сюда не входят изменения в рабочем дереве; учитываются только коммиты. |
| `` <c-z> `` | Повторить (через reflog) (экспериментальный) | Журнал ссылок (reflog) будет использоваться для определения того, какую команду git нужно запустить, чтобы повторить последнюю команду git. Сюда не входят изменения в рабочем дереве; учитываются только коммиты. |
| `` Z `` | Повторить (через reflog) (экспериментальный) | Журнал ссылок (reflog) будет использоваться для определения того, какую команду git нужно запустить, чтобы повторить последнюю команду git. Сюда не входят изменения в рабочем дереве; учитываются только коммиты. |
## Навигация по панели списка
@@ -51,6 +52,13 @@ _Связки клавиш_
| `` ] `` | Следующая вкладка | |
| `` [ `` | Предыдущая вкладка | |
## Input prompt
| Key | Action | Info |
|-----|--------|-------------|
| `` <enter> `` | Подтвердить | |
| `` <esc> `` | Закрыть/отменить | |
## Worktrees
| Key | Action | Info |
@@ -227,7 +235,7 @@ _Связки клавиш_
| Key | Action | Info |
|-----|--------|-------------|
| `` <enter> `` | Выполнить | |
| `` <esc> `` | Закрыть | |
| `` <esc> `` | Закрыть/отменить | |
| `` / `` | Filter the current view by text | |
## Панель Подтверждения
@@ -236,6 +244,7 @@ _Связки клавиш_
|-----|--------|-------------|
| `` <enter> `` | Подтвердить | |
| `` <esc> `` | Закрыть/отменить | |
| `` <c-o> `` | Copy to clipboard | |
## Подкоммиты
+11 -2
View File
@@ -24,15 +24,16 @@ _图例:`<c-b>` 意味着ctrl+b, `<a-b>意味着Alt+b, `B` 意味着shift+b_
| `` R `` | 刷新 | 刷新git状态(即在后台上运行`git status`,`git branch`等命令以更新面板内容) 不会运行`git fetch` |
| `` + `` | 下一屏模式(正常/半屏/全屏) | |
| `` _ `` | 上一屏模式 | |
| `` <esc> `` | 取消 | |
| `` ? `` | 打开菜单 | |
| `` <c-s> `` | 查看按路径过滤选项 | 查看用于过滤提交日志的选项,以便仅显示与过滤器匹配的提交。 |
| `` W `` | 打开 diff 菜单 | 查看与比较两个引用相关的选项,例如与选定的 ref 进行比较,输入要比较的 ref,然后反转比较方向。 |
| `` <c-e> `` | 打开 diff 菜单 | 查看与比较两个引用相关的选项,例如与选定的 ref 进行比较,输入要比较的 ref,然后反转比较方向。 |
| `` q `` | 退出 | |
| `` <esc> `` | 取消 | |
| `` <c-z> `` | Suspend the application | |
| `` <c-w> `` | 切换是否在差异视图中显示空白字符差异 | Toggle whether or not whitespace changes are shown in the diff view.<br><br>The default can be changed in the config file with the key 'git.ignoreWhitespaceInDiffView'. |
| `` z `` | 撤销 | Reflog将用于确定运行哪个git命令来撤消最后一个git命令。这并不包括对工作树的更改,只考虑提交。 |
| `` <c-z> `` | 重做 | Reflog将用于确定运行哪个git命令来重做上一个git命令。这并不包括对工作树的更改,只考虑提交。 |
| `` Z `` | 重做 | Reflog将用于确定运行哪个git命令来重做上一个git命令。这并不包括对工作树的更改,只考虑提交。 |
## 列表面板导航
@@ -51,6 +52,13 @@ _图例:`<c-b>` 意味着ctrl+b, `<a-b>意味着Alt+b, `B` 意味着shift+b_
| `` ] `` | 下一个标签 | |
| `` [ `` | 上一个标签 | |
## Input prompt
| Key | Action | Info |
|-----|--------|-------------|
| `` <enter> `` | 确认 | |
| `` <esc> `` | 关闭 | |
## Reflog
| Key | Action | Info |
@@ -349,6 +357,7 @@ _图例:`<c-b>` 意味着ctrl+b, `<a-b>意味着Alt+b, `B` 意味着shift+b_
|-----|--------|-------------|
| `` <enter> `` | 确认 | |
| `` <esc> `` | 关闭 | |
| `` <c-o> `` | 复制到剪贴板 | |
## 菜单
+12 -3
View File
@@ -24,15 +24,16 @@ _說明:`<c-b>` 表示 Ctrl+B、`<a-b>` 表示 Alt+B,`B`表示 Shift+B
| `` R `` | 重新整理 | Refresh the git state (i.e. run `git status`, `git branch`, etc in background to update the contents of panels). This does not run `git fetch`. |
| `` + `` | 下一個螢幕模式(常規/半螢幕/全螢幕) | |
| `` _ `` | 上一個螢幕模式 | |
| `` <esc> `` | 取消 | |
| `` ? `` | 開啟選單 | |
| `` <c-s> `` | 檢視篩選路徑選項 | View options for filtering the commit log, so that only commits matching the filter are shown. |
| `` W `` | 開啟差異比較選單 | View options relating to diffing two refs e.g. diffing against selected ref, entering ref to diff against, and reversing the diff direction. |
| `` <c-e> `` | 開啟差異比較選單 | View options relating to diffing two refs e.g. diffing against selected ref, entering ref to diff against, and reversing the diff direction. |
| `` q `` | 結束 | |
| `` <esc> `` | 取消 | |
| `` <c-z> `` | Suspend the application | |
| `` <c-w> `` | 切換是否在差異檢視中顯示空格變更 | Toggle whether or not whitespace changes are shown in the diff view.<br><br>The default can be changed in the config file with the key 'git.ignoreWhitespaceInDiffView'. |
| `` z `` | 復原 | 將使用 reflog 確任 git 指令以復原。這不包括工作區更改;只考慮提交。 |
| `` <c-z> `` | 取消復原 | 將使用 reflog 確任 git 指令以重作。這不包括工作區更改;只考慮提交。 |
| `` Z `` | 取消復原 | 將使用 reflog 確任 git 指令以重作。這不包括工作區更改;只考慮提交。 |
## 移動
@@ -51,6 +52,13 @@ _說明:`<c-b>` 表示 Ctrl+B、`<a-b>` 表示 Alt+B,`B`表示 Shift+B
| `` ] `` | 下一個索引標籤 | |
| `` [ `` | 上一個索引標籤 | |
## Input prompt
| Key | Action | Info |
|-----|--------|-------------|
| `` <enter> `` | 確認 | |
| `` <esc> `` | 關閉/取消 | |
## 主面板 (補丁生成)
| Key | Action | Info |
@@ -119,7 +127,7 @@ _說明:`<c-b>` 表示 Ctrl+B、`<a-b>` 表示 Alt+B,`B`表示 Shift+B
| Key | Action | Info |
|-----|--------|-------------|
| `` <enter> `` | 執行 | |
| `` <esc> `` | 關閉 | |
| `` <esc> `` | 關閉/取消 | |
| `` / `` | 搜尋 | |
## 子提交
@@ -371,6 +379,7 @@ _說明:`<c-b>` 表示 Ctrl+B、`<a-b>` 表示 Alt+B,`B`表示 Shift+B
|-----|--------|-------------|
| `` <enter> `` | 確認 | |
| `` <esc> `` | 關閉/取消 | |
| `` <c-o> `` | 複製到剪貼簿 | |
## 遠端
+2 -2
View File
@@ -32,11 +32,12 @@ require (
github.com/sirupsen/logrus v1.9.3
github.com/spf13/afero v1.9.5
github.com/spkg/bom v0.0.0-20160624110644-59b7046e48ad
github.com/stefanhaller/git-todo-parser v0.0.7-0.20250429125209-dcf39e4641f5
github.com/stefanhaller/git-todo-parser v0.0.7-0.20250905083220-c50528f08304
github.com/stretchr/testify v1.10.0
github.com/xo/terminfo v0.0.0-20210125001918-ca9a967f8778
golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56
golang.org/x/sync v0.16.0
golang.org/x/sys v0.34.0
gopkg.in/ozeidan/fuzzy-patricia.v3 v3.0.0
gopkg.in/yaml.v3 v3.0.1
)
@@ -77,7 +78,6 @@ require (
github.com/xanzy/ssh-agent v0.3.3 // indirect
golang.org/x/crypto v0.37.0 // indirect
golang.org/x/net v0.39.0 // indirect
golang.org/x/sys v0.34.0 // indirect
golang.org/x/term v0.33.0 // indirect
golang.org/x/text v0.27.0 // indirect
gopkg.in/fsnotify.v1 v1.4.7 // indirect
+2 -2
View File
@@ -284,8 +284,8 @@ github.com/spf13/afero v1.9.5 h1:stMpOSZFs//0Lv29HduCmli3GUfpFoF3Y1Q/aXj/wVM=
github.com/spf13/afero v1.9.5/go.mod h1:UBogFpq8E9Hx+xc5CNTTEpTnuHVmXDwZcZcE1eb/UhQ=
github.com/spkg/bom v0.0.0-20160624110644-59b7046e48ad h1:fiWzISvDn0Csy5H0iwgAuJGQTUpVfEMJJd4nRFXogbc=
github.com/spkg/bom v0.0.0-20160624110644-59b7046e48ad/go.mod h1:qLr4V1qq6nMqFKkMo8ZTx3f+BZEkzsRUY10Xsm2mwU0=
github.com/stefanhaller/git-todo-parser v0.0.7-0.20250429125209-dcf39e4641f5 h1:ZCI0NPs0xXd00Ej9lX+wwbHjQDkstJa3kUbX7WCOF8I=
github.com/stefanhaller/git-todo-parser v0.0.7-0.20250429125209-dcf39e4641f5/go.mod h1:HFt9hGqMzgQ+gVxMKcvTvGaFz4Y0yYycqqAp2V3wcJY=
github.com/stefanhaller/git-todo-parser v0.0.7-0.20250905083220-c50528f08304 h1:bg+K3E0GYuqwTGaEfNrsZ0rH0Bw4p3EmPjk9Zjnua+w=
github.com/stefanhaller/git-todo-parser v0.0.7-0.20250905083220-c50528f08304/go.mod h1:HFt9hGqMzgQ+gVxMKcvTvGaFz4Y0yYycqqAp2V3wcJY=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v0.0.0-20161117074351-18a02ba4a312/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
+1
View File
@@ -116,6 +116,7 @@ func localisedTitle(tr *i18n.TranslationSet, str string) string {
"commitDescription": tr.CommitDescriptionTitle,
"commits": tr.CommitsTitle,
"confirmation": tr.ConfirmationTitle,
"prompt": tr.PromptTitle,
"information": tr.InformationTitle,
"main": tr.NormalTitle,
"patchBuilding": tr.PatchBuildingTitle,
+2 -1
View File
@@ -257,10 +257,11 @@ func (self *CommitCommands) ShowCmdObj(hash string, filterPaths []string) *oscom
contextSize := self.UserConfig().Git.DiffContextSize
extDiffCmd := self.UserConfig().Git.Paging.ExternalDiffCommand
useExtDiffGitConfig := self.UserConfig().Git.Paging.UseExternalDiffGitConfig
cmdArgs := NewGitCmd("show").
Config("diff.noprefix=false").
ConfigIf(extDiffCmd != "", "diff.external="+extDiffCmd).
ArgIfElse(extDiffCmd != "", "--ext-diff", "--no-ext-diff").
ArgIfElse(extDiffCmd != "" || useExtDiffGitConfig, "--ext-diff", "--no-ext-diff").
Arg("--submodule").
Arg("--color="+self.UserConfig().Git.Paging.ColorArg).
Arg(fmt.Sprintf("--unified=%d", contextSize)).
+11
View File
@@ -256,6 +256,7 @@ func TestCommitShowCmdObj(t *testing.T) {
similarityThreshold int
ignoreWhitespace bool
extDiffCmd string
useExtDiffGitConfig bool
expected []string
}
@@ -314,6 +315,15 @@ func TestCommitShowCmdObj(t *testing.T) {
extDiffCmd: "difft --color=always",
expected: []string{"-C", "/path/to/worktree", "-c", "diff.external=difft --color=always", "-c", "diff.noprefix=false", "show", "--ext-diff", "--submodule", "--color=always", "--unified=3", "--stat", "--decorate", "-p", "1234567890", "--find-renames=50%", "--"},
},
{
testName: "Show diff using git's external diff config",
filterPaths: []string{},
contextSize: 3,
similarityThreshold: 50,
ignoreWhitespace: false,
useExtDiffGitConfig: true,
expected: []string{"-C", "/path/to/worktree", "-c", "diff.noprefix=false", "show", "--ext-diff", "--submodule", "--color=always", "--unified=3", "--stat", "--decorate", "-p", "1234567890", "--find-renames=50%", "--"},
},
}
for _, s := range scenarios {
@@ -323,6 +333,7 @@ func TestCommitShowCmdObj(t *testing.T) {
userConfig.Git.IgnoreWhitespaceInDiffView = s.ignoreWhitespace
userConfig.Git.DiffContextSize = s.contextSize
userConfig.Git.RenameSimilarityThreshold = s.similarityThreshold
userConfig.Git.Paging.UseExternalDiffGitConfig = s.useExtDiffGitConfig
runner := oscommands.NewFakeRunner(t).ExpectGitArgs(s.expected, "", nil)
repoPaths := RepoPaths{
-6
View File
@@ -43,12 +43,6 @@ func (self *ConfigCommands) ConfiguredPager() string {
}
func (self *ConfigCommands) GetPager(width int) string {
useConfig := self.UserConfig().Git.Paging.UseConfig
if useConfig {
pager := self.ConfiguredPager()
return strings.Split(pager, "| less")[0]
}
templateValues := map[string]string{
"columnWidth": strconv.Itoa(width/2 - 6),
}
+2 -1
View File
@@ -21,13 +21,14 @@ func NewDiffCommands(gitCommon *GitCommon) *DiffCommands {
func (self *DiffCommands) DiffCmdObj(diffArgs []string) *oscommands.CmdObj {
extDiffCmd := self.UserConfig().Git.Paging.ExternalDiffCommand
useExtDiff := extDiffCmd != ""
useExtDiffGitConfig := self.UserConfig().Git.Paging.UseExternalDiffGitConfig
ignoreWhitespace := self.UserConfig().Git.IgnoreWhitespaceInDiffView
return self.cmd.New(
NewGitCmd("diff").
Config("diff.noprefix=false").
ConfigIf(useExtDiff, "diff.external="+extDiffCmd).
ArgIfElse(useExtDiff, "--ext-diff", "--no-ext-diff").
ArgIfElse(useExtDiff || useExtDiffGitConfig, "--ext-diff", "--no-ext-diff").
Arg("--submodule").
Arg(fmt.Sprintf("--color=%s", self.UserConfig().Git.Paging.ColorArg)).
ArgIf(ignoreWhitespace, "--ignore-all-space").
+5
View File
@@ -81,11 +81,16 @@ func (self *StashCommands) Hash(index int) (string, error) {
}
func (self *StashCommands) ShowStashEntryCmdObj(index int) *oscommands.CmdObj {
extDiffCmd := self.UserConfig().Git.Paging.ExternalDiffCommand
useExtDiffGitConfig := self.UserConfig().Git.Paging.UseExternalDiffGitConfig
// "-u" is the same as "--include-untracked", but the latter fails in older git versions for some reason
cmdArgs := NewGitCmd("stash").Arg("show").
Arg("-p").
Arg("--stat").
Arg("-u").
ConfigIf(extDiffCmd != "", "diff.external="+extDiffCmd).
ArgIfElse(extDiffCmd != "" || useExtDiffGitConfig, "--ext-diff", "--no-ext-diff").
Arg(fmt.Sprintf("--color=%s", self.UserConfig().Git.Paging.ColorArg)).
Arg(fmt.Sprintf("--unified=%d", self.UserConfig().Git.DiffContextSize)).
ArgIf(self.UserConfig().Git.IgnoreWhitespaceInDiffView, "--ignore-all-space").
+8 -2
View File
@@ -32,7 +32,7 @@ func (self *StashLoader) GetStashEntries(filterPath string) []*models.StashEntry
return self.getUnfilteredStashEntries()
}
cmdArgs := NewGitCmd("stash").Arg("list", "--name-only", "--pretty=%gd:%ct|%gs").ToArgv()
cmdArgs := NewGitCmd("stash").Arg("list", "--name-only", "--pretty=%gd:%H|%ct|%gs").ToArgv()
rawString, err := self.cmd.New(cmdArgs).DontLog().RunWithOutput()
if err != nil {
return self.getUnfilteredStashEntries()
@@ -66,7 +66,7 @@ outer:
}
func (self *StashLoader) getUnfilteredStashEntries() []*models.StashEntry {
cmdArgs := NewGitCmd("stash").Arg("list", "-z", "--pretty=%ct|%gs").ToArgv()
cmdArgs := NewGitCmd("stash").Arg("list", "-z", "--pretty=%H|%ct|%gs").ToArgv()
rawString, _ := self.cmd.New(cmdArgs).DontLog().RunWithOutput()
return lo.Map(utils.SplitNul(rawString), func(line string, index int) *models.StashEntry {
@@ -80,6 +80,12 @@ func stashEntryFromLine(line string, index int) *models.StashEntry {
Index: index,
}
hash, line, ok := strings.Cut(line, "|")
if !ok {
return model
}
model.Hash = hash
tstr, msg, ok := strings.Cut(line, "|")
if !ok {
return model
+19 -9
View File
@@ -1,7 +1,9 @@
package git_commands
import (
"fmt"
"testing"
"time"
"github.com/jesseduffield/lazygit/pkg/commands/models"
"github.com/jesseduffield/lazygit/pkg/commands/oscommands"
@@ -17,30 +19,38 @@ func TestGetStashEntries(t *testing.T) {
expectedStashEntries []*models.StashEntry
}
hoursAgo := time.Now().Unix() - 3*3600 - 1800
daysAgo := time.Now().Unix() - 3*3600*24 - 3600*12
scenarios := []scenario{
{
"No stash entries found",
"",
oscommands.NewFakeRunner(t).
ExpectGitArgs([]string{"stash", "list", "-z", "--pretty=%ct|%gs"}, "", nil),
ExpectGitArgs([]string{"stash", "list", "-z", "--pretty=%H|%ct|%gs"}, "", nil),
[]*models.StashEntry{},
},
{
"Several stash entries found",
"",
oscommands.NewFakeRunner(t).
ExpectGitArgs([]string{"stash", "list", "-z", "--pretty=%ct|%gs"},
"WIP on add-pkg-commands-test: 55c6af2 increase parallel build\x00WIP on master: bb86a3f update github template\x00",
nil,
),
ExpectGitArgs([]string{"stash", "list", "-z", "--pretty=%H|%ct|%gs"},
fmt.Sprintf("fa1afe1|%d|WIP on add-pkg-commands-test: 55c6af2 increase parallel build\x00deadbeef|%d|WIP on master: bb86a3f update github template\x00",
hoursAgo,
daysAgo,
), nil),
[]*models.StashEntry{
{
Index: 0,
Name: "WIP on add-pkg-commands-test: 55c6af2 increase parallel build",
Index: 0,
Name: "WIP on add-pkg-commands-test: 55c6af2 increase parallel build",
Recency: "3h",
Hash: "fa1afe1",
},
{
Index: 1,
Name: "WIP on master: bb86a3f update github template",
Index: 1,
Name: "WIP on master: bb86a3f update github template",
Recency: "3d",
Hash: "deadbeef",
},
},
},
+26 -4
View File
@@ -103,6 +103,8 @@ func TestStashStashEntryCmdObj(t *testing.T) {
contextSize uint64
similarityThreshold int
ignoreWhitespace bool
extDiffCmd string
useExtDiffGitConfig bool
expected []string
}
@@ -113,7 +115,7 @@ func TestStashStashEntryCmdObj(t *testing.T) {
contextSize: 3,
similarityThreshold: 50,
ignoreWhitespace: false,
expected: []string{"git", "-C", "/path/to/worktree", "stash", "show", "-p", "--stat", "-u", "--color=always", "--unified=3", "--find-renames=50%", "refs/stash@{5}"},
expected: []string{"git", "-C", "/path/to/worktree", "stash", "show", "-p", "--stat", "-u", "--no-ext-diff", "--color=always", "--unified=3", "--find-renames=50%", "refs/stash@{5}"},
},
{
testName: "Show diff with custom context size",
@@ -121,7 +123,7 @@ func TestStashStashEntryCmdObj(t *testing.T) {
contextSize: 77,
similarityThreshold: 50,
ignoreWhitespace: false,
expected: []string{"git", "-C", "/path/to/worktree", "stash", "show", "-p", "--stat", "-u", "--color=always", "--unified=77", "--find-renames=50%", "refs/stash@{5}"},
expected: []string{"git", "-C", "/path/to/worktree", "stash", "show", "-p", "--stat", "-u", "--no-ext-diff", "--color=always", "--unified=77", "--find-renames=50%", "refs/stash@{5}"},
},
{
testName: "Show diff with custom similarity threshold",
@@ -129,7 +131,25 @@ func TestStashStashEntryCmdObj(t *testing.T) {
contextSize: 3,
similarityThreshold: 33,
ignoreWhitespace: false,
expected: []string{"git", "-C", "/path/to/worktree", "stash", "show", "-p", "--stat", "-u", "--color=always", "--unified=3", "--find-renames=33%", "refs/stash@{5}"},
expected: []string{"git", "-C", "/path/to/worktree", "stash", "show", "-p", "--stat", "-u", "--no-ext-diff", "--color=always", "--unified=3", "--find-renames=33%", "refs/stash@{5}"},
},
{
testName: "Show diff with external diff command",
index: 5,
contextSize: 3,
similarityThreshold: 50,
ignoreWhitespace: false,
extDiffCmd: "difft --color=always",
expected: []string{"git", "-C", "/path/to/worktree", "-c", "diff.external=difft --color=always", "stash", "show", "-p", "--stat", "-u", "--ext-diff", "--color=always", "--unified=3", "--find-renames=50%", "refs/stash@{5}"},
},
{
testName: "Show diff using git's external diff config",
index: 5,
contextSize: 3,
similarityThreshold: 50,
ignoreWhitespace: false,
useExtDiffGitConfig: true,
expected: []string{"git", "-C", "/path/to/worktree", "stash", "show", "-p", "--stat", "-u", "--ext-diff", "--color=always", "--unified=3", "--find-renames=50%", "refs/stash@{5}"},
},
{
testName: "Default case",
@@ -137,7 +157,7 @@ func TestStashStashEntryCmdObj(t *testing.T) {
contextSize: 3,
similarityThreshold: 50,
ignoreWhitespace: true,
expected: []string{"git", "-C", "/path/to/worktree", "stash", "show", "-p", "--stat", "-u", "--color=always", "--unified=3", "--ignore-all-space", "--find-renames=50%", "refs/stash@{5}"},
expected: []string{"git", "-C", "/path/to/worktree", "stash", "show", "-p", "--stat", "-u", "--no-ext-diff", "--color=always", "--unified=3", "--ignore-all-space", "--find-renames=50%", "refs/stash@{5}"},
},
}
@@ -147,6 +167,8 @@ func TestStashStashEntryCmdObj(t *testing.T) {
userConfig.Git.IgnoreWhitespaceInDiffView = s.ignoreWhitespace
userConfig.Git.DiffContextSize = s.contextSize
userConfig.Git.RenameSimilarityThreshold = s.similarityThreshold
userConfig.Git.Paging.ExternalDiffCommand = s.extDiffCmd
userConfig.Git.Paging.UseExternalDiffGitConfig = s.useExtDiffGitConfig
repoPaths := RepoPaths{
worktreePath: "/path/to/worktree",
}
+4 -2
View File
@@ -267,10 +267,11 @@ func (self *WorkingTreeCommands) WorktreeFileDiffCmdObj(node models.IFile, plain
noIndex := !node.GetIsTracked() && !node.GetHasStagedChanges() && !cached && node.GetIsFile()
extDiffCmd := self.UserConfig().Git.Paging.ExternalDiffCommand
useExtDiff := extDiffCmd != "" && !plain
useExtDiffGitConfig := self.UserConfig().Git.Paging.UseExternalDiffGitConfig
cmdArgs := NewGitCmd("diff").
ConfigIf(useExtDiff, "diff.external="+extDiffCmd).
ArgIfElse(useExtDiff, "--ext-diff", "--no-ext-diff").
ArgIfElse(useExtDiff || useExtDiffGitConfig, "--ext-diff", "--no-ext-diff").
Arg("--submodule").
Arg(fmt.Sprintf("--unified=%d", contextSize)).
Arg(fmt.Sprintf("--color=%s", colorArg)).
@@ -304,11 +305,12 @@ func (self *WorkingTreeCommands) ShowFileDiffCmdObj(from string, to string, reve
extDiffCmd := self.UserConfig().Git.Paging.ExternalDiffCommand
useExtDiff := extDiffCmd != "" && !plain
useExtDiffGitConfig := self.UserConfig().Git.Paging.UseExternalDiffGitConfig
cmdArgs := NewGitCmd("diff").
Config("diff.noprefix=false").
ConfigIf(useExtDiff, "diff.external="+extDiffCmd).
ArgIfElse(useExtDiff, "--ext-diff", "--no-ext-diff").
ArgIfElse(useExtDiff || useExtDiffGitConfig, "--ext-diff", "--no-ext-diff").
Arg("--submodule").
Arg(fmt.Sprintf("--unified=%d", contextSize)).
Arg("--no-renames").
@@ -46,6 +46,7 @@ var azdoServiceDef = ServiceDefinition{
pullRequestURLIntoTargetBranch: "/pullrequestcreate?sourceRef={{.From}}&targetRef={{.To}}",
commitURL: "/commit/{{.CommitHash}}",
regexStrings: []string{
`^.+@vs-ssh\.visualstudio\.com[:/](?:v3/)?(?P<org>[^/]+)/(?P<project>[^/]+)/(?P<repo>[^/]+?)(?:\.git)?$`,
`^git@ssh.dev.azure.com.*/(?P<org>.*)/(?P<project>.*)/(?P<repo>.*?)(?:\.git)?$`,
`^https://.*@dev.azure.com/(?P<org>.*?)/(?P<project>.*?)/_git/(?P<repo>.*?)(?:\.git)?$`,
`^https://.*/(?P<org>.*?)/(?P<project>.*?)/_git/(?P<repo>.*?)(?:\.git)?$`,
@@ -223,6 +223,18 @@ func TestGetPullRequestURL(t *testing.T) {
assert.Equal(t, "https://mycompany.azuredevops.com/collection/myproject/_git/myrepo/pullrequestcreate?sourceRef=feature%2Fnew", url)
},
},
{
testName: "Opens a link to new pull request on Azure DevOps (legacy vs-ssh.visualstudio.com SSH) with mapping to dev.azure.com",
from: "feature/new",
remoteUrl: "git@vs-ssh.visualstudio.com:v3/myorg/myproject/myrepo",
configServiceDomains: map[string]string{
"vs-ssh.visualstudio.com": "azuredevops:dev.azure.com",
},
test: func(url string, err error) {
assert.NoError(t, err)
assert.Equal(t, "https://dev.azure.com/myorg/myproject/_git/myrepo/pullrequestcreate?sourceRef=feature%2Fnew", url)
},
},
{
testName: "Opens a link to new pull request on Bitbucket Server (SSH)",
from: "feature/new",
+1
View File
@@ -7,6 +7,7 @@ type StashEntry struct {
Index int
Recency string
Name string
Hash string
}
func (s *StashEntry) FullRefName() string {
@@ -1,5 +1,4 @@
//go:build !windows
// +build !windows
package oscommands
@@ -1,6 +1,3 @@
//go:build windows
// +build windows
package oscommands
import (
@@ -1,5 +1,4 @@
//go:build !windows
// +build !windows
package oscommands
@@ -1,5 +1,4 @@
//go:build !windows
// +build !windows
package oscommands
@@ -1,6 +1,3 @@
//go:build windows
// +build windows
package oscommands
import (
+1 -1
View File
@@ -865,7 +865,7 @@ keybinding:
nextScreenMode: +
prevScreenMode: _
undo: z
redo: <c-z>
redo: Z
filteringMenu: <c-s>
diffingMenu: W
diffingMenu-alt: <c-e>
-1
View File
@@ -1,5 +1,4 @@
//go:build !windows && !linux
// +build !windows,!linux
package config
+9 -4
View File
@@ -316,10 +316,10 @@ type PagingConfig struct {
// delta --dark --paging=never
// ydiff -p cat -s --wrap --width={{columnWidth}}
Pager PagerType `yaml:"pager"`
// If 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).
UseConfig bool `yaml:"useConfig"`
// e.g. 'difft --color=always'
ExternalDiffCommand string `yaml:"externalDiffCommand"`
// If true, Lazygit will use git's `diff.external` config for paging. The advantage over `externalDiffCommand` is that this can be configured per file type in .gitattributes; see https://git-scm.com/docs/gitattributes#_defining_an_external_diff_driver.
UseExternalDiffGitConfig bool `yaml:"useExternalDiffGitConfig"`
}
type CommitConfig struct {
@@ -390,6 +390,7 @@ type KeybindingConfig struct {
type KeybindingUniversalConfig struct {
Quit string `yaml:"quit"`
QuitAlt1 string `yaml:"quit-alt1"`
SuspendApp string `yaml:"suspendApp"`
Return string `yaml:"return"`
QuitWithoutChangingDirectory string `yaml:"quitWithoutChangingDirectory"`
TogglePanel string `yaml:"togglePanel"`
@@ -424,6 +425,8 @@ type KeybindingUniversalConfig struct {
Select string `yaml:"select"`
GoInto string `yaml:"goInto"`
Confirm string `yaml:"confirm"`
ConfirmMenu string `yaml:"confirmMenu"`
ConfirmSuggestion string `yaml:"confirmSuggestion"`
ConfirmInEditor string `yaml:"confirmInEditor"`
ConfirmInEditorAlt string `yaml:"confirmInEditor-alt"`
Remove string `yaml:"remove"`
@@ -796,7 +799,6 @@ func GetDefaultConfig() *UserConfig {
Paging: PagingConfig{
ColorArg: "always",
Pager: "",
UseConfig: false,
ExternalDiffCommand: "",
},
Commit: CommitConfig{
@@ -854,6 +856,7 @@ func GetDefaultConfig() *UserConfig {
Universal: KeybindingUniversalConfig{
Quit: "q",
QuitAlt1: "<c-c>",
SuspendApp: "<c-z>",
Return: "<esc>",
QuitWithoutChangingDirectory: "Q",
TogglePanel: "<tab>",
@@ -888,6 +891,8 @@ func GetDefaultConfig() *UserConfig {
Select: "<space>",
GoInto: "<enter>",
Confirm: "<enter>",
ConfirmMenu: "<enter>",
ConfirmSuggestion: "<enter>",
ConfirmInEditor: "<a-enter>",
ConfirmInEditorAlt: "<c-s>",
Remove: "d",
@@ -912,7 +917,7 @@ func GetDefaultConfig() *UserConfig {
NextScreenMode: "+",
PrevScreenMode: "_",
Undo: "z",
Redo: "<c-z>",
Redo: "Z",
FilteringMenu: "<c-s>",
DiffingMenu: "W",
DiffingMenuAlt: "<c-e>",
+4
View File
@@ -41,6 +41,7 @@ const (
MENU_CONTEXT_KEY types.ContextKey = "menu"
CONFIRMATION_CONTEXT_KEY types.ContextKey = "confirmation"
PROMPT_CONTEXT_KEY types.ContextKey = "prompt"
SEARCH_CONTEXT_KEY types.ContextKey = "search"
COMMIT_MESSAGE_CONTEXT_KEY types.ContextKey = "commitMessage"
COMMIT_DESCRIPTION_CONTEXT_KEY types.ContextKey = "commitDescription"
@@ -73,6 +74,7 @@ var AllContextKeys = []types.ContextKey{
MENU_CONTEXT_KEY,
CONFIRMATION_CONTEXT_KEY,
PROMPT_CONTEXT_KEY,
SEARCH_CONTEXT_KEY,
COMMIT_MESSAGE_CONTEXT_KEY,
SUBMODULES_CONTEXT_KEY,
@@ -106,6 +108,7 @@ type ContextTree struct {
CustomPatchBuilderSecondary types.Context
MergeConflicts *MergeConflictsContext
Confirmation *ConfirmationContext
Prompt *PromptContext
CommitMessage *CommitMessageContext
CommitDescription types.Context
CommandLog types.Context
@@ -141,6 +144,7 @@ func (self *ContextTree) Flatten() []types.Context {
self.Stash,
self.Menu,
self.Confirmation,
self.Prompt,
self.CommitMessage,
self.CommitDescription,
+15 -5
View File
@@ -12,9 +12,10 @@ import (
type FilteredList[T any] struct {
filteredIndices []int // if nil, we are not filtering
getList func() []T
getFilterFields func(T) []string
filter string
getList func() []T
getFilterFields func(T) []string
preprocessFilter func(string) string
filter string
mutex deadlock.Mutex
}
@@ -26,6 +27,10 @@ func NewFilteredList[T any](getList func() []T, getFilterFields func(T) []string
}
}
func (self *FilteredList[T]) SetPreprocessFilterFunc(preprocessFilter func(string) string) {
self.preprocessFilter = preprocessFilter
}
func (self *FilteredList[T]) GetFilter() string {
return self.filter
}
@@ -79,7 +84,12 @@ func (self *FilteredList[T]) applyFilter(useFuzzySearch bool) {
self.mutex.Lock()
defer self.mutex.Unlock()
if self.filter == "" {
filter := self.filter
if self.preprocessFilter != nil {
filter = self.preprocessFilter(filter)
}
if filter == "" {
self.filteredIndices = nil
} else {
source := &fuzzySource[T]{
@@ -87,7 +97,7 @@ func (self *FilteredList[T]) applyFilter(useFuzzySearch bool) {
getFilterFields: self.getFilterFields,
}
matches := utils.FindFrom(self.filter, source, useFuzzySearch)
matches := utils.FindFrom(filter, source, useFuzzySearch)
self.filteredIndices = lo.Map(matches, func(match fuzzy.Match, _ int) int {
return match.Index
})
@@ -1,5 +1,7 @@
package context
import "github.com/jesseduffield/lazygit/pkg/i18n"
type FilteredListViewModel[T HasID] struct {
*FilteredList[T]
*ListViewModel[T]
@@ -33,3 +35,8 @@ func (self *FilteredListViewModel[T]) ClearFilter() {
self.SetSelection(unfilteredIndex)
}
// Default implementation of most filterable contexts. Can be overridden if needed.
func (self *FilteredListViewModel[T]) FilterPrefix(tr *i18n.TranslationSet) string {
return tr.FilterPrefix
}
+39 -6
View File
@@ -2,10 +2,12 @@ package context
import (
"errors"
"strings"
"github.com/jesseduffield/lazygit/pkg/gui/keybindings"
"github.com/jesseduffield/lazygit/pkg/gui/style"
"github.com/jesseduffield/lazygit/pkg/gui/types"
"github.com/jesseduffield/lazygit/pkg/i18n"
"github.com/jesseduffield/lazygit/pkg/utils"
"github.com/samber/lo"
)
@@ -48,11 +50,12 @@ func NewMenuContext(
}
type MenuViewModel struct {
c *ContextCommon
menuItems []*types.MenuItem
prompt string
promptLines []string
columnAlignment []utils.Alignment
c *ContextCommon
menuItems []*types.MenuItem
prompt string
promptLines []string
columnAlignment []utils.Alignment
allowFilteringKeybindings bool
*FilteredListViewModel[*types.MenuItem]
}
@@ -62,11 +65,29 @@ func NewMenuViewModel(c *ContextCommon) *MenuViewModel {
c: c,
}
filterKeybindings := false
self.FilteredListViewModel = NewFilteredListViewModel(
func() []*types.MenuItem { return self.menuItems },
func(item *types.MenuItem) []string { return item.LabelColumns },
func(item *types.MenuItem) []string {
if filterKeybindings {
return []string{keybindings.LabelFromKey(item.Key)}
}
return item.LabelColumns
},
)
self.FilteredListViewModel.SetPreprocessFilterFunc(func(filter string) string {
if self.allowFilteringKeybindings && strings.HasPrefix(filter, "@") {
filterKeybindings = true
return filter[1:]
}
filterKeybindings = false
return filter
})
return self
}
@@ -92,6 +113,10 @@ func (self *MenuViewModel) SetPromptLines(promptLines []string) {
self.promptLines = promptLines
}
func (self *MenuViewModel) SetAllowFilteringKeybindings(allow bool) {
self.allowFilteringKeybindings = allow
}
// TODO: move into presentation package
func (self *MenuViewModel) GetDisplayStrings(_ int, _ int) [][]string {
menuItems := self.FilteredListViewModel.GetItems()
@@ -214,3 +239,11 @@ func (self *MenuContext) OnMenuPress(selectedItem *types.MenuItem) error {
func (self *MenuContext) RangeSelectEnabled() bool {
return false
}
func (self *MenuContext) FilterPrefix(tr *i18n.TranslationSet) string {
if self.allowFilteringKeybindings {
return tr.FilterPrefixMenu
}
return self.FilteredListViewModel.FilterPrefix(tr)
}
+30
View File
@@ -0,0 +1,30 @@
package context
import (
"github.com/jesseduffield/lazygit/pkg/gui/types"
)
type PromptContext struct {
*SimpleContext
c *ContextCommon
State ConfirmationContextState
}
var _ types.Context = (*PromptContext)(nil)
func NewPromptContext(
c *ContextCommon,
) *PromptContext {
return &PromptContext{
c: c,
SimpleContext: NewSimpleContext(NewBaseContext(NewBaseContextOpts{
View: c.Views().Prompt,
WindowName: "prompt",
Key: PROMPT_CONTEXT_KEY,
Kind: types.TEMPORARY_POPUP,
Focusable: true,
HasUncontrolledBounds: true,
})),
}
}
+1
View File
@@ -84,6 +84,7 @@ func NewContextTree(c *ContextCommon) *ContextTree {
c,
),
Confirmation: NewConfirmationContext(c),
Prompt: NewPromptContext(c),
CommitMessage: NewCommitMessageContext(c),
CommitDescription: NewSimpleContext(
NewBaseContext(NewBaseContextOpts{
+6
View File
@@ -109,6 +109,7 @@ func (gui *Gui) resetHelpersAndControllers() {
AmendHelper: helpers.NewAmendHelper(helperCommon, gpgHelper),
FixupHelper: helpers.NewFixupHelper(helperCommon),
Commits: commitsHelper,
SuspendResume: helpers.NewSuspendResumeHelper(helperCommon),
Snake: helpers.NewSnakeHelper(helperCommon),
Diff: diffHelper,
Repos: reposHelper,
@@ -192,6 +193,7 @@ func (gui *Gui) resetHelpersAndControllers() {
statusController := controllers.NewStatusController(common)
commandLogController := controllers.NewCommandLogController(common)
confirmationController := controllers.NewConfirmationController(common)
promptController := controllers.NewPromptController(common)
suggestionsController := controllers.NewSuggestionsController(common)
jumpToSideWindowController := controllers.NewJumpToSideWindowController(common, gui.handleNextTab)
@@ -398,6 +400,10 @@ func (gui *Gui) resetHelpersAndControllers() {
confirmationController,
)
controllers.AttachControllers(gui.State.Contexts.Prompt,
promptController,
)
controllers.AttachControllers(gui.State.Contexts.Suggestions,
suggestionsController,
)
+13 -36
View File
@@ -1,9 +1,6 @@
package controllers
import (
"fmt"
"github.com/jesseduffield/gocui"
"github.com/jesseduffield/lazygit/pkg/gui/context"
"github.com/jesseduffield/lazygit/pkg/gui/types"
)
@@ -39,38 +36,19 @@ func (self *ConfirmationController) GetKeybindings(opts types.KeybindingsOpts) [
DisplayOnScreen: true,
},
{
Key: opts.GetKey(opts.Config.Universal.TogglePanel),
Handler: func() error {
if len(self.c.Contexts().Suggestions.State.Suggestions) > 0 {
self.switchToSuggestions()
}
return nil
},
Key: opts.GetKey(opts.Config.Universal.CopyToClipboard),
Handler: self.handleCopyToClipboard,
Description: self.c.Tr.CopyToClipboardMenu,
DisplayOnScreen: true,
},
}
return bindings
}
func (self *ConfirmationController) GetMouseKeybindings(opts types.KeybindingsOpts) []*gocui.ViewMouseBinding {
return []*gocui.ViewMouseBinding{
{
ViewName: self.c.Contexts().Suggestions.GetViewName(),
FocusedView: self.c.Contexts().Confirmation.GetViewName(),
Key: gocui.MouseLeft,
Handler: func(gocui.ViewMouseBindingOpts) error {
self.switchToSuggestions()
// Let it fall through to the ListController's click handler so that
// the clicked line gets selected:
return gocui.ErrKeybindingNotHandled
},
},
}
}
func (self *ConfirmationController) GetOnFocusLost() func(types.OnFocusLostOpts) {
return func(types.OnFocusLostOpts) {
self.c.Helpers().Confirmation.DeactivateConfirmationPrompt()
self.c.Helpers().Confirmation.DeactivateConfirmation()
}
}
@@ -82,14 +60,13 @@ func (self *ConfirmationController) context() *context.ConfirmationContext {
return self.c.Contexts().Confirmation
}
func (self *ConfirmationController) switchToSuggestions() {
subtitle := ""
if self.c.State().GetRepoState().GetCurrentPopupOpts().HandleDeleteSuggestion != nil {
// We assume that whenever things are deletable, they
// are also editable, so we show both keybindings
subtitle = fmt.Sprintf(self.c.Tr.SuggestionsSubtitle,
self.c.UserConfig().Keybinding.Universal.Remove, self.c.UserConfig().Keybinding.Universal.Edit)
func (self *ConfirmationController) handleCopyToClipboard() error {
confirmationView := self.c.Views().Confirmation
text := confirmationView.Buffer()
if err := self.c.OS().CopyToClipboard(text); err != nil {
return err
}
self.c.Views().Suggestions.Subtitle = subtitle
self.c.Context().Replace(self.c.Contexts().Suggestions)
self.c.Toast(self.c.Tr.MessageCopiedToClipboard)
return nil
}
+35 -5
View File
@@ -58,6 +58,15 @@ func (self *GlobalController) GetKeybindings(opts types.KeybindingsOpts) []*type
Handler: opts.Guards.NoPopupPanel(self.prevScreenMode),
Description: self.c.Tr.PrevScreenMode,
},
{
Key: opts.GetKey(opts.Config.Universal.Return),
Modifier: gocui.ModNone,
Handler: self.escape,
Description: self.c.Tr.Cancel,
DescriptionFunc: self.escapeDescription,
GetDisabledReason: self.escapeEnabled,
DisplayOnScreen: true,
},
{
ViewName: "",
Key: opts.GetKey(opts.Config.Universal.OptionMenu),
@@ -115,11 +124,18 @@ func (self *GlobalController) GetKeybindings(opts types.KeybindingsOpts) []*type
Handler: self.quitWithoutChangingDirectory,
},
{
Key: opts.GetKey(opts.Config.Universal.Return),
Modifier: gocui.ModNone,
Handler: self.escape,
Description: self.c.Tr.Cancel,
DisplayOnScreen: true,
Key: opts.GetKey(opts.Config.Universal.SuspendApp),
Modifier: gocui.ModNone,
Handler: self.c.Helpers().SuspendResume.SuspendApp,
Description: self.c.Tr.SuspendApp,
GetDisabledReason: func() *types.DisabledReason {
if !self.c.Helpers().SuspendResume.CanSuspendApp() {
return &types.DisabledReason{
Text: self.c.Tr.CannotSuspendApp,
}
}
return nil
},
},
{
Key: opts.GetKey(opts.Config.Universal.ToggleWhitespaceInDiffView),
@@ -190,6 +206,20 @@ func (self *GlobalController) escape() error {
return (&QuitActions{c: self.c}).Escape()
}
func (self *GlobalController) escapeDescription() string {
return (&QuitActions{c: self.c}).EscapeDescription()
}
func (self *GlobalController) escapeEnabled() *types.DisabledReason {
if (&QuitActions{c: self.c}).EscapeEnabled() {
return nil
}
// The empty error text is intentional. We don't want to show an error
// toast for this, but only hide it from the options map.
return &types.DisabledReason{Text: ""}
}
func (self *GlobalController) toggleWhitespace() error {
return (&ToggleWhitespaceAction{c: self.c}).Call()
}
@@ -283,7 +283,9 @@ func (self *BranchesHelper) AutoForwardBranches() error {
updateCommands := ""
// The first branch is the currently checked out branch; skip it
for _, branch := range branches[1:] {
if branch.RemoteBranchStoredLocally() && (allBranches || lo.Contains(self.c.UserConfig().Git.MainBranches, branch.Name)) {
if branch.RemoteBranchStoredLocally() &&
!self.checkedOutByOtherWorktree(branch) &&
(allBranches || lo.Contains(self.c.UserConfig().Git.MainBranches, branch.Name)) {
isStrictlyBehind := branch.IsBehindForPull() && !branch.IsAheadForPull()
if isStrictlyBehind {
updateCommands += fmt.Sprintf("update %s %s %s\n", branch.FullRefName(), branch.FullUpstreamRefName(), branch.CommitHash)
@@ -46,17 +46,27 @@ func (self *ConfirmationHelper) wrappedPromptConfirmationFunction(cancel goConte
})
}
func (self *ConfirmationHelper) DeactivateConfirmationPrompt() {
func (self *ConfirmationHelper) DeactivateConfirmation() {
self.c.Mutexes().PopupMutex.Lock()
self.c.State().GetRepoState().SetCurrentPopupOpts(nil)
self.c.Mutexes().PopupMutex.Unlock()
self.c.Views().Confirmation.Visible = false
self.c.Views().Suggestions.Visible = false
self.clearConfirmationViewKeyBindings()
}
func (self *ConfirmationHelper) DeactivatePrompt() {
self.c.Mutexes().PopupMutex.Lock()
self.c.State().GetRepoState().SetCurrentPopupOpts(nil)
self.c.Mutexes().PopupMutex.Unlock()
self.c.Views().Prompt.Visible = false
self.c.Views().Suggestions.Visible = false
self.clearPromptViewKeyBindings()
}
func getMessageHeight(wrap bool, editable bool, message string, width int, tabWidth int) int {
wrappedLines, _, _ := utils.WrapViewLinesToWidth(wrap, editable, message, width, tabWidth)
return len(wrappedLines)
@@ -105,15 +115,28 @@ func (self *ConfirmationHelper) prepareConfirmationPanel(
opts types.ConfirmOpts,
) {
self.c.Views().Confirmation.Title = opts.Title
// for now we do not support wrapping in our editor
self.c.Views().Confirmation.Wrap = !opts.Editable
self.c.Views().Confirmation.FgColor = theme.GocuiDefaultTextColor
self.c.Views().Confirmation.Mask = runeForMask(opts.Mask)
self.c.Views().Confirmation.SetOrigin(0, 0)
suggestionsContext := self.c.Contexts().Suggestions
suggestionsContext.State.FindSuggestions = opts.FindSuggestionsFunc
self.c.ResetViewOrigin(self.c.Views().Confirmation)
self.c.SetViewContent(self.c.Views().Confirmation, style.AttrBold.Sprint(strings.TrimSpace(opts.Prompt)))
}
func (self *ConfirmationHelper) preparePromptPanel(
opts types.ConfirmOpts,
) {
self.c.Views().Prompt.Title = opts.Title
self.c.Views().Prompt.FgColor = theme.GocuiDefaultTextColor
self.c.Views().Prompt.Mask = runeForMask(opts.Mask)
self.c.Views().Prompt.SetOrigin(0, 0)
textArea := self.c.Views().Prompt.TextArea
textArea.Clear()
textArea.TypeString(opts.Prompt)
self.c.Views().Prompt.RenderTextArea()
if opts.FindSuggestionsFunc != nil {
suggestionsContext := self.c.Contexts().Suggestions
suggestionsContext.State.FindSuggestions = opts.FindSuggestionsFunc
suggestionsView := self.c.Views().Suggestions
suggestionsView.Wrap = false
suggestionsView.FgColor = theme.GocuiDefaultTextColor
@@ -150,44 +173,59 @@ func (self *ConfirmationHelper) CreatePopupPanel(ctx goContext.Context, opts typ
// remove any previous keybindings
self.clearConfirmationViewKeyBindings()
self.clearPromptViewKeyBindings()
self.prepareConfirmationPanel(
types.ConfirmOpts{
Title: opts.Title,
Prompt: opts.Prompt,
FindSuggestionsFunc: opts.FindSuggestionsFunc,
Editable: opts.Editable,
Mask: opts.Mask,
})
confirmationView := self.c.Views().Confirmation
confirmationView.Editable = opts.Editable
var context types.Context
if opts.Editable {
textArea := confirmationView.TextArea
textArea.Clear()
textArea.TypeString(opts.Prompt)
confirmationView.RenderTextArea()
} else {
self.c.ResetViewOrigin(confirmationView)
self.c.SetViewContent(confirmationView, style.AttrBold.Sprint(strings.TrimSpace(opts.Prompt)))
}
self.c.Contexts().Suggestions.State.FindSuggestions = opts.FindSuggestionsFunc
self.setKeyBindings(cancel, opts)
self.preparePromptPanel(
types.ConfirmOpts{
Title: opts.Title,
Prompt: opts.Prompt,
FindSuggestionsFunc: opts.FindSuggestionsFunc,
Mask: opts.Mask,
})
context = self.c.Contexts().Prompt
self.setPromptKeyBindings(cancel, opts)
} else {
if opts.FindSuggestionsFunc != nil {
panic("non-editable confirmation views do not support suggestions")
}
self.c.Contexts().Suggestions.State.FindSuggestions = nil
self.prepareConfirmationPanel(
types.ConfirmOpts{
Title: opts.Title,
Prompt: opts.Prompt,
})
context = self.c.Contexts().Confirmation
self.setConfirmationKeyBindings(cancel, opts)
}
self.c.Contexts().Suggestions.State.AllowEditSuggestion = opts.AllowEditSuggestion
self.c.State().GetRepoState().SetCurrentPopupOpts(&opts)
self.c.Context().Push(self.c.Contexts().Confirmation, types.OnFocusOpts{})
self.c.Context().Push(context, types.OnFocusOpts{})
}
func (self *ConfirmationHelper) setKeyBindings(cancel goContext.CancelFunc, opts types.CreatePopupPanelOpts) {
var onConfirm func() error
if opts.HandleConfirmPrompt != nil {
onConfirm = self.wrappedPromptConfirmationFunction(cancel, opts.HandleConfirmPrompt, func() string { return self.c.Views().Confirmation.TextArea.GetContent() })
} else {
onConfirm = self.wrappedConfirmationFunction(cancel, opts.HandleConfirm)
}
func (self *ConfirmationHelper) setConfirmationKeyBindings(cancel goContext.CancelFunc, opts types.CreatePopupPanelOpts) {
onConfirm := self.wrappedConfirmationFunction(cancel, opts.HandleConfirm)
onClose := self.wrappedConfirmationFunction(cancel, opts.HandleClose)
self.c.Contexts().Confirmation.State.OnConfirm = onConfirm
self.c.Contexts().Confirmation.State.OnClose = onClose
}
func (self *ConfirmationHelper) setPromptKeyBindings(cancel goContext.CancelFunc, opts types.CreatePopupPanelOpts) {
onConfirm := self.wrappedPromptConfirmationFunction(cancel, opts.HandleConfirmPrompt,
func() string { return self.c.Views().Prompt.TextArea.GetContent() })
onSuggestionConfirm := self.wrappedPromptConfirmationFunction(
cancel,
@@ -206,8 +244,8 @@ func (self *ConfirmationHelper) setKeyBindings(cancel goContext.CancelFunc, opts
return opts.HandleDeleteSuggestion(idx)
}
self.c.Contexts().Confirmation.State.OnConfirm = onConfirm
self.c.Contexts().Confirmation.State.OnClose = onClose
self.c.Contexts().Prompt.State.OnConfirm = onConfirm
self.c.Contexts().Prompt.State.OnClose = onClose
self.c.Contexts().Suggestions.State.OnConfirm = onSuggestionConfirm
self.c.Contexts().Suggestions.State.OnClose = onClose
self.c.Contexts().Suggestions.State.OnDeleteSuggestion = onDeleteSuggestion
@@ -217,6 +255,12 @@ func (self *ConfirmationHelper) clearConfirmationViewKeyBindings() {
noop := func() error { return nil }
self.c.Contexts().Confirmation.State.OnConfirm = noop
self.c.Contexts().Confirmation.State.OnClose = noop
}
func (self *ConfirmationHelper) clearPromptViewKeyBindings() {
noop := func() error { return nil }
self.c.Contexts().Prompt.State.OnConfirm = noop
self.c.Contexts().Prompt.State.OnClose = noop
self.c.Contexts().Suggestions.State.OnConfirm = noop
self.c.Contexts().Suggestions.State.OnClose = noop
self.c.Contexts().Suggestions.State.OnDeleteSuggestion = noop
@@ -238,8 +282,10 @@ func (self *ConfirmationHelper) ResizeCurrentPopupPanels() {
switch c {
case self.c.Contexts().Menu:
self.resizeMenu(parentPopupContext)
case self.c.Contexts().Confirmation, self.c.Contexts().Suggestions:
case self.c.Contexts().Confirmation:
self.resizeConfirmationPanel(parentPopupContext)
case self.c.Contexts().Prompt, self.c.Contexts().Suggestions:
self.resizePromptPanel(parentPopupContext)
case self.c.Contexts().CommitMessage, self.c.Contexts().CommitDescription:
self.ResizeCommitMessagePanels(parentPopupContext)
}
@@ -300,26 +346,30 @@ func (self *ConfirmationHelper) layoutMenuPrompt(contentWidth int) int {
}
func (self *ConfirmationHelper) resizeConfirmationPanel(parentPopupContext types.Context) {
panelWidth := self.getPopupPanelWidth()
contentWidth := panelWidth - 2 // minus 2 for the frame
confirmationView := self.c.Views().Confirmation
prompt := confirmationView.Buffer()
panelHeight := getMessageHeight(true, false, prompt, contentWidth, confirmationView.TabWidth)
x0, y0, x1, y1 := self.getPopupPanelDimensionsAux(panelWidth, panelHeight, parentPopupContext)
_, _ = self.c.GocuiGui().SetView(confirmationView.Name(), x0, y0, x1, y1, 0)
}
func (self *ConfirmationHelper) resizePromptPanel(parentPopupContext types.Context) {
suggestionsViewHeight := 0
if self.c.Views().Suggestions.Visible {
suggestionsViewHeight = 11
}
panelWidth := self.getPopupPanelWidth()
contentWidth := panelWidth - 2 // minus 2 for the frame
confirmationView := self.c.Views().Confirmation
prompt := confirmationView.Buffer()
wrap := true
editable := confirmationView.Editable
if editable {
prompt = confirmationView.TextArea.GetContent()
wrap = false
}
panelHeight := getMessageHeight(wrap, editable, prompt, contentWidth, confirmationView.TabWidth) + suggestionsViewHeight
promptView := self.c.Views().Prompt
prompt := promptView.TextArea.GetContent()
panelHeight := getMessageHeight(false, true, prompt, contentWidth, promptView.TabWidth) + suggestionsViewHeight
x0, y0, x1, y1 := self.getPopupPanelDimensionsAux(panelWidth, panelHeight, parentPopupContext)
confirmationViewBottom := y1 - suggestionsViewHeight
_, _ = self.c.GocuiGui().SetView(confirmationView.Name(), x0, y0, x1, confirmationViewBottom, 0)
promptViewBottom := y1 - suggestionsViewHeight
_, _ = self.c.GocuiGui().SetView(promptView.Name(), x0, y0, x1, promptViewBottom, 0)
suggestionsViewTop := confirmationViewBottom + 1
suggestionsViewTop := promptViewBottom + 1
_, _ = self.c.GocuiGui().SetView(self.c.Views().Suggestions.Name(), x0, suggestionsViewTop, x1, suggestionsViewTop+suggestionsViewHeight, 0)
}
@@ -348,7 +398,7 @@ func (self *ConfirmationHelper) IsPopupPanelFocused() bool {
func (self *ConfirmationHelper) TooltipForMenuItem(menuItem *types.MenuItem) string {
tooltip := menuItem.Tooltip
if menuItem.DisabledReason != nil {
if menuItem.DisabledReason != nil && menuItem.DisabledReason.Text != "" {
if tooltip != "" {
tooltip += "\n\n"
}
+1
View File
@@ -35,6 +35,7 @@ type Helpers struct {
AmendHelper *AmendHelper
FixupHelper *FixupHelper
Commits *CommitsHelper
SuspendResume *SuspendResumeHelper
Snake *SnakeHelper
// lives in context package because our contexts need it to render to main
Diff *DiffHelper
+30 -8
View File
@@ -40,7 +40,8 @@ func NewModeHelper(
type ModeStatus struct {
IsActive func() bool
Description func() string
InfoLabel func() string
CancelLabel func() string
Reset func() error
}
@@ -48,7 +49,7 @@ func (self *ModeHelper) Statuses() []ModeStatus {
return []ModeStatus{
{
IsActive: self.c.Modes().Diffing.Active,
Description: func() string {
InfoLabel: func() string {
return self.withResetButton(
fmt.Sprintf(
"%s %s",
@@ -58,18 +59,24 @@ func (self *ModeHelper) Statuses() []ModeStatus {
style.FgMagenta,
)
},
CancelLabel: func() string {
return self.c.Tr.CancelDiffingMode
},
Reset: self.diffHelper.ExitDiffMode,
},
{
IsActive: self.c.Git().Patch.PatchBuilder.Active,
Description: func() string {
InfoLabel: func() string {
return self.withResetButton(self.c.Tr.BuildingPatch, style.FgYellow.SetBold())
},
CancelLabel: func() string {
return self.c.Tr.ExitCustomPatchBuilder
},
Reset: self.patchBuildingHelper.Reset,
},
{
IsActive: self.c.Modes().Filtering.Active,
Description: func() string {
InfoLabel: func() string {
filterContent := lo.Ternary(self.c.Modes().Filtering.GetPath() != "", self.c.Modes().Filtering.GetPath(), self.c.Modes().Filtering.GetAuthor())
return self.withResetButton(
fmt.Sprintf(
@@ -80,21 +87,27 @@ func (self *ModeHelper) Statuses() []ModeStatus {
style.FgRed,
)
},
CancelLabel: func() string {
return self.c.Tr.ExitFilterMode
},
Reset: self.ExitFilterMode,
},
{
IsActive: self.c.Modes().MarkedBaseCommit.Active,
Description: func() string {
InfoLabel: func() string {
return self.withResetButton(
self.c.Tr.MarkedBaseCommitStatus,
style.FgCyan,
)
},
CancelLabel: func() string {
return self.c.Tr.CancelMarkedBaseCommit
},
Reset: self.mergeAndRebaseHelper.ResetMarkedBaseCommit,
},
{
IsActive: self.c.Modes().CherryPicking.Active,
Description: func() string {
InfoLabel: func() string {
copiedCount := len(self.c.Modes().CherryPicking.CherryPickedCommits)
text := self.c.Tr.CommitsCopied
if copiedCount == 1 {
@@ -110,27 +123,36 @@ func (self *ModeHelper) Statuses() []ModeStatus {
style.FgCyan,
)
},
CancelLabel: func() string {
return self.c.Tr.ResetCherryPickShort
},
Reset: self.cherryPickHelper.Reset,
},
{
IsActive: func() bool {
return !self.suppressRebasingMode && self.c.Git().Status.WorkingTreeState().Any()
},
Description: func() string {
InfoLabel: func() string {
workingTreeState := self.c.Git().Status.WorkingTreeState()
return self.withResetButton(
workingTreeState.Title(self.c.Tr), style.FgYellow,
)
},
CancelLabel: func() string {
return fmt.Sprintf(self.c.Tr.AbortTitle, self.c.Git().Status.WorkingTreeState().CommandName())
},
Reset: self.mergeAndRebaseHelper.AbortMergeOrRebaseWithConfirm,
},
{
IsActive: func() bool {
return self.c.Model().BisectInfo.Started()
},
Description: func() string {
InfoLabel: func() string {
return self.withResetButton(self.c.Tr.Bisect.Bisecting, style.FgGreen)
},
CancelLabel: func() string {
return self.c.Tr.Actions.ResetBisect
},
Reset: self.bisectHelper.Reset,
},
}
+2 -2
View File
@@ -35,7 +35,7 @@ func (self *SearchHelper) OpenFilterPrompt(context types.IFilterableContext) err
state.Context = context
self.searchPrefixView().SetContent(self.c.Tr.FilterPrefix)
self.searchPrefixView().SetContent(context.FilterPrefix(self.c.Tr))
promptView := self.promptView()
promptView.ClearTextArea()
self.OnPromptContentChanged("")
@@ -69,7 +69,7 @@ func (self *SearchHelper) DisplayFilterStatus(context types.IFilterableContext)
state.Context = context
searchString := context.GetFilter()
self.searchPrefixView().SetContent(self.c.Tr.FilterPrefix)
self.searchPrefixView().SetContent(context.FilterPrefix(self.c.Tr))
promptView := self.promptView()
keybindingConfig := self.c.UserConfig().Keybinding
@@ -0,0 +1,59 @@
//go:build !windows
package helpers
import (
"os"
"os/signal"
"syscall"
"github.com/sirupsen/logrus"
"golang.org/x/sys/unix"
)
func canSuspendApp() bool {
return true
}
func sendStopSignal() error {
return syscall.Kill(0, syscall.SIGSTOP)
}
// setForegroundPgrp sets the current process group as the foreground process group
// for the terminal, allowing the program to read input after resuming from suspension.
func setForegroundPgrp() error {
fd, err := unix.Open("/dev/tty", unix.O_RDWR, 0)
if err != nil {
return err
}
defer unix.Close(fd)
pgid := syscall.Getpgrp()
return unix.IoctlSetPointerInt(fd, unix.TIOCSPGRP, pgid)
}
func handleResumeSignal(log *logrus.Entry, onResume func() error) {
if err := setForegroundPgrp(); err != nil {
log.Warning(err)
return
}
if err := onResume(); err != nil {
log.Warning(err)
}
}
func installResumeSignalHandler(log *logrus.Entry, onResume func() error) {
go func() {
sigs := make(chan os.Signal, 1)
signal.Notify(sigs, syscall.SIGCONT)
for sig := range sigs {
switch sig {
case syscall.SIGCONT:
handleResumeSignal(log, onResume)
}
}
}()
}
@@ -0,0 +1,16 @@
package helpers
import (
"github.com/sirupsen/logrus"
)
func canSuspendApp() bool {
return false
}
func sendStopSignal() error {
return nil
}
func installResumeSignalHandler(log *logrus.Entry, onResume func() error) {
}
@@ -0,0 +1,31 @@
package helpers
type SuspendResumeHelper struct {
c *HelperCommon
}
func NewSuspendResumeHelper(c *HelperCommon) *SuspendResumeHelper {
return &SuspendResumeHelper{
c: c,
}
}
func (s *SuspendResumeHelper) CanSuspendApp() bool {
return canSuspendApp()
}
func (s *SuspendResumeHelper) SuspendApp() error {
if !canSuspendApp() {
return nil
}
if err := s.c.Suspend(); err != nil {
return err
}
return sendStopSignal()
}
func (s *SuspendResumeHelper) InstallResumeSignalHandler() {
installResumeSignalHandler(s.c.Log, s.c.Resume)
}
@@ -79,10 +79,10 @@ func (self *WindowArrangementHelper) GetWindowDimensions(informationStr string,
repoState := self.c.State().GetRepoState()
var searchPrefix string
if repoState.GetSearchState().SearchType() == types.SearchTypeSearch {
searchPrefix = self.c.Tr.SearchPrefix
if filterableContext, ok := repoState.GetSearchState().Context.(types.IFilterableContext); ok {
searchPrefix = filterableContext.FilterPrefix(self.c.Tr)
} else {
searchPrefix = self.c.Tr.FilterPrefix
searchPrefix = self.c.Tr.SearchPrefix
}
args := WindowArrangementArgs{
+4 -3
View File
@@ -39,9 +39,10 @@ func (self *MainViewController) GetKeybindings(opts types.KeybindingsOpts) []*ty
DisplayOnScreen: true,
},
{
Key: opts.GetKey(opts.Config.Universal.Return),
Handler: self.escape,
Description: self.c.Tr.ExitFocusedMainView,
Key: opts.GetKey(opts.Config.Universal.Return),
Handler: self.escape,
Description: self.c.Tr.ExitFocusedMainView,
DisplayOnScreen: true,
},
{
// overriding this because we want to read all of the task's output before we start searching
+2 -2
View File
@@ -38,7 +38,7 @@ func (self *MenuController) GetKeybindings(opts types.KeybindingsOpts) []*types.
GetDisabledReason: self.require(self.singleItemSelected()),
},
{
Key: opts.GetKey(opts.Config.Universal.Confirm),
Key: opts.GetKey(opts.Config.Universal.ConfirmMenu),
Handler: self.withItem(self.press),
GetDisabledReason: self.require(self.singleItemSelected()),
Description: self.c.Tr.Execute,
@@ -47,7 +47,7 @@ func (self *MenuController) GetKeybindings(opts types.KeybindingsOpts) []*types.
{
Key: opts.GetKey(opts.Config.Universal.Return),
Handler: self.close,
Description: self.c.Tr.Close,
Description: self.c.Tr.CloseCancel,
DisplayOnScreen: true,
},
}
+5 -4
View File
@@ -46,10 +46,11 @@ func (self *OptionsMenuAction) Call() error {
appendBindings(navigation, &types.MenuSection{Title: self.c.Tr.KeybindingsMenuSectionNavigation, Column: 1})
return self.c.Menu(types.CreateMenuOptions{
Title: self.c.Tr.Keybindings,
Items: menuItems,
HideCancel: true,
ColumnAlignment: []utils.Alignment{utils.AlignRight, utils.AlignLeft},
Title: self.c.Tr.Keybindings,
Items: menuItems,
HideCancel: true,
ColumnAlignment: []utils.Alignment{utils.AlignRight, utils.AlignLeft},
AllowFilteringKeybindings: true,
})
}
@@ -43,9 +43,11 @@ func (self *PatchBuildingController) GetKeybindings(opts types.KeybindingsOpts)
DisplayOnScreen: true,
},
{
Key: opts.GetKey(opts.Config.Universal.Return),
Handler: self.Escape,
Description: self.c.Tr.ExitCustomPatchBuilder,
Key: opts.GetKey(opts.Config.Universal.Return),
Handler: self.Escape,
Description: self.c.Tr.ExitCustomPatchBuilder,
DescriptionFunc: self.EscapeDescription,
DisplayOnScreen: true,
},
}
}
@@ -179,3 +181,18 @@ func (self *PatchBuildingController) Escape() error {
self.c.Helpers().PatchBuilding.Escape()
return nil
}
func (self *PatchBuildingController) EscapeDescription() string {
context := self.c.Contexts().CustomPatchBuilder
if state := context.GetState(); state != nil {
if state.SelectingRange() {
return self.c.Tr.DismissRangeSelect
}
if state.SelectingHunkEnabledByUser() {
return self.c.Tr.SelectLineByLine
}
}
return self.c.Tr.ExitCustomPatchBuilder
}
+95
View File
@@ -0,0 +1,95 @@
package controllers
import (
"fmt"
"github.com/jesseduffield/gocui"
"github.com/jesseduffield/lazygit/pkg/gui/context"
"github.com/jesseduffield/lazygit/pkg/gui/types"
)
type PromptController struct {
baseController
c *ControllerCommon
}
var _ types.IController = &PromptController{}
func NewPromptController(
c *ControllerCommon,
) *PromptController {
return &PromptController{
baseController: baseController{},
c: c,
}
}
func (self *PromptController) GetKeybindings(opts types.KeybindingsOpts) []*types.Binding {
bindings := []*types.Binding{
{
Key: gocui.KeyEnter,
Handler: func() error { return self.context().State.OnConfirm() },
Description: self.c.Tr.Confirm,
DisplayOnScreen: true,
},
{
Key: opts.GetKey(opts.Config.Universal.Return),
Handler: func() error { return self.context().State.OnClose() },
Description: self.c.Tr.CloseCancel,
DisplayOnScreen: true,
},
{
Key: opts.GetKey(opts.Config.Universal.TogglePanel),
Handler: func() error {
if len(self.c.Contexts().Suggestions.State.Suggestions) > 0 {
self.switchToSuggestions()
}
return nil
},
},
}
return bindings
}
func (self *PromptController) GetMouseKeybindings(opts types.KeybindingsOpts) []*gocui.ViewMouseBinding {
return []*gocui.ViewMouseBinding{
{
ViewName: self.c.Contexts().Suggestions.GetViewName(),
FocusedView: self.c.Contexts().Prompt.GetViewName(),
Key: gocui.MouseLeft,
Handler: func(gocui.ViewMouseBindingOpts) error {
self.switchToSuggestions()
// Let it fall through to the ListController's click handler so that
// the clicked line gets selected:
return gocui.ErrKeybindingNotHandled
},
},
}
}
func (self *PromptController) GetOnFocusLost() func(types.OnFocusLostOpts) {
return func(types.OnFocusLostOpts) {
self.c.Helpers().Confirmation.DeactivatePrompt()
}
}
func (self *PromptController) Context() types.Context {
return self.context()
}
func (self *PromptController) context() *context.PromptContext {
return self.c.Contexts().Prompt
}
func (self *PromptController) switchToSuggestions() {
subtitle := ""
if self.c.State().GetRepoState().GetCurrentPopupOpts().HandleDeleteSuggestion != nil {
// We assume that whenever things are deletable, they
// are also editable, so we show both keybindings
subtitle = fmt.Sprintf(self.c.Tr.SuggestionsSubtitle,
self.c.UserConfig().Keybinding.Universal.Remove, self.c.UserConfig().Keybinding.Universal.Edit)
}
self.c.Views().Suggestions.Subtitle = subtitle
self.c.Context().Replace(self.c.Contexts().Suggestions)
}
+80 -7
View File
@@ -48,6 +48,8 @@ func (self *QuitActions) confirmQuitDuringUpdate() error {
}
func (self *QuitActions) Escape() error {
// If you make changes to this function, be sure to update EscapeEnabled and EscapeDescription accordingly.
currentContext := self.c.Context().Current()
if listContext, ok := currentContext.(types.IListContext); ok {
@@ -58,17 +60,12 @@ func (self *QuitActions) Escape() error {
}
}
switch ctx := currentContext.(type) {
case types.IFilterableContext:
// Cancelling searching (as opposed to filtering) is handled by gocui
if ctx, ok := currentContext.(types.IFilterableContext); ok {
if ctx.IsFiltering() {
self.c.Helpers().Search.Cancel()
return nil
}
case types.ISearchableContext:
if ctx.IsSearching() {
self.c.Helpers().Search.Cancel()
return nil
}
}
parentContext := currentContext.GetParentContext()
@@ -95,3 +92,79 @@ func (self *QuitActions) Escape() error {
return nil
}
func (self *QuitActions) EscapeEnabled() bool {
currentContext := self.c.Context().Current()
if listContext, ok := currentContext.(types.IListContext); ok {
if listContext.GetList().IsSelectingRange() {
return true
}
}
if ctx, ok := currentContext.(types.IFilterableContext); ok {
if ctx.IsFiltering() {
return true
}
}
parentContext := currentContext.GetParentContext()
if parentContext != nil {
return true
}
for _, mode := range self.c.Helpers().Mode.Statuses() {
if mode.IsActive() {
return true
}
}
repoPathStack := self.c.State().GetRepoPathStack()
if !repoPathStack.IsEmpty() {
return true
}
if self.c.UserConfig().QuitOnTopLevelReturn {
return true
}
return false
}
func (self *QuitActions) EscapeDescription() string {
currentContext := self.c.Context().Current()
if listContext, ok := currentContext.(types.IListContext); ok {
if listContext.GetList().IsSelectingRange() {
return self.c.Tr.DismissRangeSelect
}
}
if ctx, ok := currentContext.(types.IFilterableContext); ok {
if ctx.IsFiltering() {
return self.c.Tr.ExitFilterMode
}
}
parentContext := currentContext.GetParentContext()
if parentContext != nil {
return self.c.Tr.ExitSubview
}
for _, mode := range self.c.Helpers().Mode.Statuses() {
if mode.IsActive() {
return mode.CancelLabel()
}
}
repoPathStack := self.c.State().GetRepoPathStack()
if !repoPathStack.IsEmpty() {
return self.c.Tr.BackToParentRepo
}
if self.c.UserConfig().QuitOnTopLevelReturn {
return self.c.Tr.Quit
}
return self.c.Tr.Cancel
}
@@ -24,7 +24,7 @@ func NewSearchPromptController(
func (self *SearchPromptController) GetKeybindings(opts types.KeybindingsOpts) []*types.Binding {
return []*types.Binding{
{
Key: opts.GetKey(opts.Config.Universal.Confirm),
Key: gocui.KeyEnter,
Modifier: gocui.ModNone,
Handler: self.confirm,
},
+19 -3
View File
@@ -68,9 +68,11 @@ func (self *StagingController) GetKeybindings(opts types.KeybindingsOpts) []*typ
Tooltip: self.c.Tr.EditFileTooltip,
},
{
Key: opts.GetKey(opts.Config.Universal.Return),
Handler: self.Escape,
Description: self.c.Tr.ReturnToFilesPanel,
Key: opts.GetKey(opts.Config.Universal.Return),
Handler: self.Escape,
Description: self.c.Tr.ReturnToFilesPanel,
DescriptionFunc: self.EscapeDescription,
DisplayOnScreen: true,
},
{
Key: opts.GetKey(opts.Config.Universal.TogglePanel),
@@ -178,6 +180,20 @@ func (self *StagingController) Escape() error {
return nil
}
func (self *StagingController) EscapeDescription() string {
if state := self.context.GetState(); state != nil {
if state.SelectingRange() {
return self.c.Tr.DismissRangeSelect
}
if state.SelectingHunkEnabledByUser() {
return self.c.Tr.SelectLineByLine
}
}
return self.c.Tr.ReturnToFilesPanel
}
func (self *StagingController) TogglePanel() error {
if self.otherContext.GetState() != nil {
self.c.Context().Push(self.otherContext, types.OnFocusOpts{})
+7 -6
View File
@@ -112,7 +112,7 @@ func (self *StashController) handleStashApply(stashEntry *models.StashEntry) err
Title: self.c.Tr.StashApply,
Prompt: self.c.Tr.SureApplyStashEntry,
HandleConfirm: func() error {
self.c.LogAction(self.c.Tr.Actions.Stash)
self.c.LogAction(self.c.Tr.Actions.ApplyStash)
err := self.c.Git().Stash.Apply(stashEntry.Index)
self.postStashRefresh()
if err != nil {
@@ -128,7 +128,8 @@ func (self *StashController) handleStashApply(stashEntry *models.StashEntry) err
func (self *StashController) handleStashPop(stashEntry *models.StashEntry) error {
pop := func() error {
self.c.LogAction(self.c.Tr.Actions.Stash)
self.c.LogAction(self.c.Tr.Actions.PopStash)
self.c.LogCommand("Popping stash "+stashEntry.Hash, false)
err := self.c.Git().Stash.Pop(stashEntry.Index)
self.postStashRefresh()
if err != nil {
@@ -160,10 +161,10 @@ func (self *StashController) handleStashDrop(stashEntries []*models.StashEntry)
Title: self.c.Tr.StashDrop,
Prompt: self.c.Tr.SureDropStashEntry,
HandleConfirm: func() error {
self.c.LogAction(self.c.Tr.Actions.Stash)
startIndex := stashEntries[0].Index
for range stashEntries {
err := self.c.Git().Stash.Drop(startIndex)
self.c.LogAction(self.c.Tr.Actions.DropStash)
for i := len(stashEntries) - 1; i >= 0; i-- {
self.c.LogCommand("Dropping stash "+stashEntries[i].Hash, false)
err := self.c.Git().Stash.Drop(stashEntries[i].Index)
self.c.Refresh(types.RefreshOptions{Scope: []types.RefreshableView{types.STASH}})
if err != nil {
return err
+11 -11
View File
@@ -32,7 +32,7 @@ func NewSuggestionsController(
func (self *SuggestionsController) GetKeybindings(opts types.KeybindingsOpts) []*types.Binding {
bindings := []*types.Binding{
{
Key: opts.GetKey(opts.Config.Universal.Confirm),
Key: opts.GetKey(opts.Config.Universal.ConfirmSuggestion),
Handler: func() error { return self.context().State.OnConfirm() },
GetDisabledReason: self.require(self.singleItemSelected()),
},
@@ -42,7 +42,7 @@ func (self *SuggestionsController) GetKeybindings(opts types.KeybindingsOpts) []
},
{
Key: opts.GetKey(opts.Config.Universal.TogglePanel),
Handler: self.switchToConfirmation,
Handler: self.switchToPrompt,
},
{
Key: opts.GetKey(opts.Config.Universal.Remove),
@@ -55,11 +55,11 @@ func (self *SuggestionsController) GetKeybindings(opts types.KeybindingsOpts) []
Handler: func() error {
if self.context().State.AllowEditSuggestion {
if selectedItem := self.c.Contexts().Suggestions.GetSelected(); selectedItem != nil {
self.c.Contexts().Confirmation.GetView().TextArea.Clear()
self.c.Contexts().Confirmation.GetView().TextArea.TypeString(selectedItem.Value)
self.c.Contexts().Confirmation.GetView().RenderTextArea()
self.c.Contexts().Prompt.GetView().TextArea.Clear()
self.c.Contexts().Prompt.GetView().TextArea.TypeString(selectedItem.Value)
self.c.Contexts().Prompt.GetView().RenderTextArea()
self.c.Contexts().Suggestions.RefreshSuggestions()
return self.switchToConfirmation()
return self.switchToPrompt()
}
}
return nil
@@ -73,26 +73,26 @@ func (self *SuggestionsController) GetKeybindings(opts types.KeybindingsOpts) []
func (self *SuggestionsController) GetMouseKeybindings(opts types.KeybindingsOpts) []*gocui.ViewMouseBinding {
return []*gocui.ViewMouseBinding{
{
ViewName: self.c.Contexts().Confirmation.GetViewName(),
ViewName: self.c.Contexts().Prompt.GetViewName(),
FocusedView: self.c.Contexts().Suggestions.GetViewName(),
Key: gocui.MouseLeft,
Handler: func(gocui.ViewMouseBindingOpts) error {
return self.switchToConfirmation()
return self.switchToPrompt()
},
},
}
}
func (self *SuggestionsController) switchToConfirmation() error {
func (self *SuggestionsController) switchToPrompt() error {
self.c.Views().Suggestions.Subtitle = ""
self.c.Views().Suggestions.Highlight = false
self.c.Context().Replace(self.c.Contexts().Confirmation)
self.c.Context().Replace(self.c.Contexts().Prompt)
return nil
}
func (self *SuggestionsController) GetOnFocusLost() func(types.OnFocusLostOpts) {
return func(types.OnFocusLostOpts) {
self.c.Helpers().Confirmation.DeactivateConfirmationPrompt()
self.c.Helpers().Confirmation.DeactivatePrompt()
}
}
+1 -1
View File
@@ -52,7 +52,7 @@ func (self *WorktreesController) GetKeybindings(opts types.KeybindingsOpts) []*t
DisplayOnScreen: true,
},
{
Key: opts.GetKey(opts.Config.Universal.Confirm),
Key: opts.GetKey(opts.Config.Universal.GoInto),
Handler: self.withItem(self.enter),
GetDisabledReason: self.require(self.singleItemSelected()),
},
-24
View File
@@ -90,60 +90,36 @@ func (gui *Gui) scrollDownSecondary() error {
}
func (gui *Gui) scrollUpConfirmationPanel() error {
if gui.Views.Confirmation.Editable {
return nil
}
gui.scrollUpView(gui.Views.Confirmation)
return nil
}
func (gui *Gui) scrollDownConfirmationPanel() error {
if gui.Views.Confirmation.Editable {
return nil
}
gui.scrollDownView(gui.Views.Confirmation)
return nil
}
func (gui *Gui) pageUpConfirmationPanel() error {
if gui.Views.Confirmation.Editable {
return nil
}
gui.Views.Confirmation.ScrollUp(gui.Contexts().Confirmation.GetViewTrait().PageDelta())
return nil
}
func (gui *Gui) pageDownConfirmationPanel() error {
if gui.Views.Confirmation.Editable {
return nil
}
gui.Views.Confirmation.ScrollDown(gui.Contexts().Confirmation.GetViewTrait().PageDelta())
return nil
}
func (gui *Gui) goToConfirmationPanelTop() error {
if gui.Views.Confirmation.Editable {
return gocui.ErrKeybindingNotHandled
}
gui.Views.Confirmation.ScrollUp(gui.Views.Confirmation.ViewLinesHeight())
return nil
}
func (gui *Gui) goToConfirmationPanelBottom() error {
if gui.Views.Confirmation.Editable {
return gocui.ErrKeybindingNotHandled
}
gui.Views.Confirmation.ScrollDown(gui.Views.Confirmation.ViewLinesHeight())
return nil
+23 -6
View File
@@ -697,7 +697,7 @@ func NewGui(
return gui.helpers.AppStatus.WithWaitingStatusSync(message, f)
},
func(message string, kind types.ToastKind) { gui.helpers.AppStatus.Toast(message, kind) },
func() string { return gui.Views.Confirmation.TextArea.GetContent() },
func() string { return gui.Views.Prompt.TextArea.GetContent() },
func() bool { return gui.c.InDemo() },
)
@@ -848,6 +848,8 @@ func (gui *Gui) Run(startArgs appTypes.StartArgs) error {
gui.BackgroundRoutineMgr.startBackgroundRoutines()
gui.Helpers().SuspendResume.InstallResumeSignalHandler()
gui.c.Log.Info("starting main loop")
// setting here so we can use it in layout.go
@@ -899,21 +901,36 @@ func (gui *Gui) runSubprocessWithSuspenseAndRefresh(subprocess *oscommands.CmdOb
return nil
}
func (gui *Gui) suspend() error {
if err := gui.g.Suspend(); err != nil {
return err
}
gui.BackgroundRoutineMgr.PauseBackgroundRefreshes(true)
return nil
}
func (gui *Gui) resume() error {
if err := gui.g.Resume(); err != nil {
return err
}
gui.BackgroundRoutineMgr.PauseBackgroundRefreshes(false)
return nil
}
// returns whether command exited without error or not
func (gui *Gui) runSubprocessWithSuspense(subprocess *oscommands.CmdObj) (bool, error) {
gui.Mutexes.SubprocessMutex.Lock()
defer gui.Mutexes.SubprocessMutex.Unlock()
if err := gui.g.Suspend(); err != nil {
if err := gui.suspend(); err != nil {
return false, err
}
gui.BackgroundRoutineMgr.PauseBackgroundRefreshes(true)
defer gui.BackgroundRoutineMgr.PauseBackgroundRefreshes(false)
cmdErr := gui.runSubprocess(subprocess)
if err := gui.g.Resume(); err != nil {
if err := gui.resume(); err != nil {
return false, err
}
+8
View File
@@ -42,6 +42,14 @@ func (self *guiCommon) RunSubprocess(cmdObj *oscommands.CmdObj) (bool, error) {
return self.gui.runSubprocessWithSuspense(cmdObj)
}
func (self *guiCommon) Suspend() error {
return self.gui.suspend()
}
func (self *guiCommon) Resume() error {
return self.gui.resume()
}
func (self *guiCommon) Context() types.IContextMgr {
return self.gui.State.ContextMgr
}
+1 -1
View File
@@ -10,7 +10,7 @@ import (
func (gui *Gui) informationStr() string {
if activeMode, ok := gui.helpers.Mode.GetActiveMode(); ok {
return activeMode.Description()
return activeMode.InfoLabel()
}
if gui.g.Mouse {
+2 -3
View File
@@ -75,7 +75,6 @@ func (gui *Gui) keybindingOpts() types.KeybindingsOpts {
}
}
// renaming receiver to 'self' to aid refactoring. Will probably end up moving all Gui handlers to this pattern eventually.
func (gui *Gui) GetInitialKeybindings() ([]*types.Binding, []*gocui.ViewMouseBinding) {
opts := gui.c.KeybindingsOpts()
@@ -508,11 +507,11 @@ func (gui *Gui) SetMouseKeybinding(binding *gocui.ViewMouseBinding) error {
!gocui.IsMouseScrollKey(opts.Key) {
// we ignore click events on views that aren't popup panels, when a popup panel is focused.
// Unless both the current view and the clicked-on view are either commit message or commit
// description, or a confirmation and the suggestions view, because we want to allow switching
// description, or a prompt and the suggestions view, because we want to allow switching
// between those two views by clicking.
isCommitMessageOrSuggestionsView := func(viewName string) bool {
return viewName == "commitMessage" || viewName == "commitDescription" ||
viewName == "confirmation" || viewName == "suggestions"
viewName == "prompt" || viewName == "suggestions"
}
if !isCommitMessageOrSuggestionsView(gui.currentViewName()) || !isCommitMessageOrSuggestionsView(binding.ViewName) {
return nil
+8
View File
@@ -3,6 +3,7 @@ package gui
import (
"fmt"
"github.com/jesseduffield/lazygit/pkg/gui/keybindings"
"github.com/jesseduffield/lazygit/pkg/gui/types"
"github.com/jesseduffield/lazygit/pkg/theme"
)
@@ -20,6 +21,7 @@ func (gui *Gui) createMenu(opts types.CreateMenuOptions) error {
}
maxColumnSize := 1
confirmKey := keybindings.GetKey(gui.c.UserConfig().Keybinding.Universal.ConfirmMenu)
for _, item := range opts.Items {
if item.LabelColumns == nil {
@@ -31,6 +33,11 @@ func (gui *Gui) createMenu(opts types.CreateMenuOptions) error {
}
maxColumnSize = max(maxColumnSize, len(item.LabelColumns))
// Remove all item keybindings that are the same as the confirm binding
if item.Key == confirmKey {
item.Key = nil
}
}
for _, item := range opts.Items {
@@ -43,6 +50,7 @@ func (gui *Gui) createMenu(opts types.CreateMenuOptions) error {
gui.State.Contexts.Menu.SetMenuItems(opts.Items, opts.ColumnAlignment)
gui.State.Contexts.Menu.SetPrompt(opts.Prompt)
gui.State.Contexts.Menu.SetAllowFilteringKeybindings(opts.AllowFilteringKeybindings)
gui.State.Contexts.Menu.SetSelection(0)
gui.Views.Menu.Title = opts.Title
+9 -1
View File
@@ -4,6 +4,7 @@ import (
"fmt"
"strings"
"github.com/jesseduffield/generics/set"
"github.com/jesseduffield/lazygit/pkg/gui/context"
"github.com/jesseduffield/lazygit/pkg/gui/controllers/helpers"
"github.com/jesseduffield/lazygit/pkg/gui/keybindings"
@@ -38,7 +39,14 @@ func (self *OptionsMapMgr) renderContextOptionsMap() {
currentContextBindings := currentContext.GetKeybindings(self.c.KeybindingsOpts())
globalBindings := self.c.Contexts().Global.GetKeybindings(self.c.KeybindingsOpts())
allBindings := append(currentContextBindings, globalBindings...)
currentContextKeys := set.NewFromSlice(
lo.Map(currentContextBindings, func(binding *types.Binding, _ int) types.Key {
return binding.Key
}))
allBindings := append(currentContextBindings, lo.Filter(globalBindings, func(b *types.Binding, _ int) bool {
return !currentContextKeys.Includes(b.Key)
})...)
bindingsToDisplay := lo.Filter(allBindings, func(binding *types.Binding, _ int) bool {
return binding.DisplayOnScreen && !binding.IsDisabled()
+2 -1
View File
@@ -71,10 +71,11 @@ func getBranchDisplayStrings(
if showCommitHash {
availableWidth -= utils.COMMIT_HASH_SHORT_SIZE + 1
}
paddingNeededForDivergence := availableWidth
if checkedOutByWorkTree {
availableWidth -= utils.StringWidth(worktreeIcon) + 1
}
paddingNeededForDivergence := availableWidth
if len(branchStatus) > 0 {
availableWidth -= utils.StringWidth(utils.Decolorise(branchStatus)) + 1
-1
View File
@@ -1,5 +1,4 @@
//go:build !windows
// +build !windows
package gui
-3
View File
@@ -1,6 +1,3 @@
//go:build windows
// +build windows
package gui
import (
+9 -5
View File
@@ -56,6 +56,9 @@ type IGuiCommon interface {
RunSubprocess(cmdObj *oscommands.CmdObj) (bool, error)
RunSubprocessAndRefresh(*oscommands.CmdObj) error
Suspend() error
Resume() error
Context() IContextMgr
ContextForKey(key ContextKey) Context
@@ -147,11 +150,12 @@ const (
)
type CreateMenuOptions struct {
Title string
Prompt string // a message that will be displayed above the menu options
Items []*MenuItem
HideCancel bool
ColumnAlignment []utils.Alignment
Title string
Prompt string // a message that will be displayed above the menu options
Items []*MenuItem
HideCancel bool
ColumnAlignment []utils.Alignment
AllowFilteringKeybindings bool
}
type CreatePopupPanelOpts struct {
+2
View File
@@ -4,6 +4,7 @@ import (
"github.com/jesseduffield/gocui"
"github.com/jesseduffield/lazygit/pkg/config"
"github.com/jesseduffield/lazygit/pkg/gui/patch_exploring"
"github.com/jesseduffield/lazygit/pkg/i18n"
"github.com/jesseduffield/lazygit/pkg/utils"
"github.com/sasha-s/go-deadlock"
)
@@ -130,6 +131,7 @@ type IFilterableContext interface {
ReApplyFilter(bool)
IsFiltering() bool
IsFilterableContext()
FilterPrefix(tr *i18n.TranslationSet) string
}
type ISearchableContext interface {
+1
View File
@@ -25,6 +25,7 @@ type Views struct {
Options *gocui.View
Confirmation *gocui.View
Prompt *gocui.View
Menu *gocui.View
CommitMessage *gocui.View
CommitDescription *gocui.View
+7 -1
View File
@@ -68,6 +68,7 @@ func (gui *Gui) orderedViewNameMappings() []viewNameMapping {
{viewPtr: &gui.Views.Menu, name: "menu"},
{viewPtr: &gui.Views.Suggestions, name: "suggestions"},
{viewPtr: &gui.Views.Confirmation, name: "confirmation"},
{viewPtr: &gui.Views.Prompt, name: "prompt"},
{viewPtr: &gui.Views.Tooltip, name: "tooltip"},
// this guy will cover everything else when it appears
@@ -127,9 +128,14 @@ func (gui *Gui) createAllViews() error {
gui.Views.CommitDescription.Editor = gocui.EditorFunc(gui.commitDescriptionEditor)
gui.Views.Confirmation.Visible = false
gui.Views.Confirmation.Editor = gocui.EditorFunc(gui.promptEditor)
gui.Views.Confirmation.Wrap = true
gui.Views.Confirmation.AutoRenderHyperLinks = true
gui.Views.Prompt.Visible = false
gui.Views.Prompt.Wrap = false // We don't want wrapping in one-line prompts
gui.Views.Prompt.Editable = true
gui.Views.Prompt.Editor = gocui.EditorFunc(gui.promptEditor)
gui.Views.Suggestions.Visible = false
gui.Views.Menu.Visible = false
+41 -2
View File
@@ -382,6 +382,8 @@ type TranslationSet struct {
ScrollUp string
ScrollUpMainWindow string
ScrollDownMainWindow string
SuspendApp string
CannotSuspendApp string
AmendCommitTitle string
AmendCommitPrompt string
AmendCommitWithConflictsMenuPrompt string
@@ -601,6 +603,7 @@ type TranslationSet struct {
RenameBranchWarning string
OpenKeybindingsMenu string
ResetCherryPick string
ResetCherryPickShort string
NextTab string
PrevTab string
CantUndoWhileRebasing string
@@ -608,6 +611,7 @@ type TranslationSet struct {
MustStashWarning string
MustStashTitle string
ConfirmationTitle string
PromptTitle string
PrevPage string
NextPage string
GotoTop string
@@ -634,6 +638,7 @@ type TranslationSet struct {
SwapDiff string
ViewDiffingOptions string
ViewDiffingOptionsTooltip string
CancelDiffingMode string
OpenCommandLogMenu string
OpenCommandLogMenuTooltip string
ShowingGitDiff string
@@ -671,6 +676,7 @@ type TranslationSet struct {
SubmoduleStashAndReset string
AndResetSubmodules string
EnterSubmoduleTooltip string
BackToParentRepo string
Enter string
CopySubmoduleNameToClipboard string
RemoveSubmodule string
@@ -699,6 +705,7 @@ type TranslationSet struct {
BulkSubmoduleOptions string
RunningCommand string
SubCommitsTitle string
ExitSubview string
SubmodulesTitle string
NavigationTitle string
SuggestionsCheatsheetTitle string
@@ -717,6 +724,7 @@ type TranslationSet struct {
CommitHasNoTags string
CommitHasNoMessageBody string
PatchCopiedToClipboard string
MessageCopiedToClipboard string
CopiedToClipboard string
ErrCannotEditDirectory string
ErrCannotCopyContentOfDirectory string
@@ -816,6 +824,7 @@ type TranslationSet struct {
SearchKeybindings string
SearchPrefix string
FilterPrefix string
FilterPrefixMenu string
ExitSearchMode string
ExitTextFilterMode string
Switch string
@@ -860,6 +869,7 @@ type TranslationSet struct {
MarkedBaseCommitStatus string
MarkAsBaseCommit string
MarkAsBaseCommitTooltip string
CancelMarkedBaseCommit string
MarkedCommitMarker string
FailedToOpenURL string
InvalidLazygitEditURL string
@@ -869,6 +879,7 @@ type TranslationSet struct {
QuickStartInteractiveRebaseTooltip string
CannotQuickStartInteractiveRebase string
ToggleRangeSelect string
DismissRangeSelect string
RangeSelectUp string
RangeSelectDown string
RangeSelectNotSupported string
@@ -1001,6 +1012,9 @@ type Actions struct {
UpdateRemote string
ApplyPatch string
Stash string
PopStash string
ApplyStash string
DropStash string
RenameStash string
RemoveSubmodule string
ResetSubmodule string
@@ -1049,10 +1063,12 @@ Thanks for using lazygit! Seriously you rock. Three things to share with you:
3) If you're using git, that makes you a programmer! With your help we can make
lazygit better, so consider becoming a contributor and joining the fun at
https://github.com/jesseduffield/lazygit
You can also sponsor me and tell me what to work on by clicking the donate
button at the bottom right.
Or even just star the repo to share the love!
4) If lazygit has made your life easier, you can say thanks by clicking the
donate button at the bottom right. Donation does not grant priority support,
but it is much appreciated.
Press {{confirmationKey}} to get started.
`
@@ -1348,6 +1364,7 @@ func EnglishTranslationSet() *TranslationSet {
DiscardSelection: `Discard`,
DiscardSelectionTooltip: "When unstaged change is selected, discard the change using `git reset`. When staged change is selected, unstage the change.",
ToggleRangeSelect: "Toggle range select",
DismissRangeSelect: "Dismiss range select",
ToggleSelectHunk: "Toggle hunk selection",
SelectHunk: "Select hunks",
SelectLineByLine: "Select line-by-line",
@@ -1448,6 +1465,8 @@ func EnglishTranslationSet() *TranslationSet {
ScrollUp: "Scroll up",
ScrollUpMainWindow: "Scroll up main window",
ScrollDownMainWindow: "Scroll down main window",
SuspendApp: "Suspend the application",
CannotSuspendApp: "Suspending the application is not supported on Windows",
AmendCommitTitle: "Amend commit",
AmendCommitPrompt: "Are you sure you want to amend this commit with your staged files?",
AmendCommitWithConflictsMenuPrompt: "WARNING: you are about to amend the last finished commit with your resolved conflicts. This is very unlikely to be what you want at this point. More likely, you simply want to continue the rebase instead.\n\nDo you still want to amend the previous commit?",
@@ -1666,6 +1685,7 @@ func EnglishTranslationSet() *TranslationSet {
RenameBranchWarning: "This branch is tracking a remote. This action will only rename the local branch name, not the name of the remote branch. Continue?",
OpenKeybindingsMenu: "Open keybindings menu",
ResetCherryPick: "Reset copied (cherry-picked) commits selection",
ResetCherryPickShort: "Reset copied commits",
NextTab: "Next tab",
PrevTab: "Previous tab",
CantUndoWhileRebasing: "Can't undo while rebasing",
@@ -1673,6 +1693,7 @@ func EnglishTranslationSet() *TranslationSet {
MustStashWarning: "Pulling a patch out into the index requires stashing and unstashing your changes. If something goes wrong, you'll be able to access your files from the stash. Continue?",
MustStashTitle: "Must stash",
ConfirmationTitle: "Confirmation panel",
PromptTitle: "Input prompt",
PrevPage: "Previous page",
NextPage: "Next page",
GotoTop: "Scroll to top",
@@ -1699,6 +1720,7 @@ func EnglishTranslationSet() *TranslationSet {
SwapDiff: "Reverse diff direction",
ViewDiffingOptions: "View diffing options",
ViewDiffingOptionsTooltip: "View options relating to diffing two refs e.g. diffing against selected ref, entering ref to diff against, and reversing the diff direction.",
CancelDiffingMode: "Cancel diffing mode",
// the actual view is the extras view which I intend to give more tabs in future but for now we'll only mention the command log part
OpenCommandLogMenu: "View command log options",
OpenCommandLogMenuTooltip: "View options for the command log e.g. show/hide the command log and focus the command log.",
@@ -1738,6 +1760,7 @@ func EnglishTranslationSet() *TranslationSet {
AndResetSubmodules: "And reset submodules",
Enter: "Enter",
EnterSubmoduleTooltip: "Enter submodule. After entering the submodule, you can press `{{.escape}}` to escape back to the parent repo.",
BackToParentRepo: "Back to parent repo",
CopySubmoduleNameToClipboard: "Copy submodule name to clipboard",
RemoveSubmodule: "Remove submodule",
RemoveSubmodulePrompt: "Are you sure you want to remove submodule '%s' and its corresponding directory? This is irreversible.",
@@ -1765,6 +1788,7 @@ func EnglishTranslationSet() *TranslationSet {
BulkSubmoduleOptions: "Bulk submodule options",
RunningCommand: "Running command",
SubCommitsTitle: "Sub-commits",
ExitSubview: "Exit subview",
SubmodulesTitle: "Submodules",
NavigationTitle: "List panel navigation",
SuggestionsCheatsheetTitle: "Suggestions",
@@ -1782,6 +1806,7 @@ func EnglishTranslationSet() *TranslationSet {
CommitHasNoTags: "Commit has no tags",
CommitHasNoMessageBody: "Commit has no message body",
PatchCopiedToClipboard: "Patch copied to clipboard",
MessageCopiedToClipboard: "Message copied to clipboard",
CopiedToClipboard: "copied to clipboard",
ErrCannotEditDirectory: "Cannot edit directories: you can only edit individual files",
ErrCannotCopyContentOfDirectory: "Cannot copy content of directories: you can only copy content of individual files",
@@ -1881,6 +1906,7 @@ func EnglishTranslationSet() *TranslationSet {
SearchKeybindings: "%s: Next match, %s: Previous match, %s: Exit search mode",
SearchPrefix: "Search: ",
FilterPrefix: "Filter: ",
FilterPrefixMenu: "Filter (prepend '@' to filter keybindings): ",
WorktreesTitle: "Worktrees",
WorktreeTitle: "Worktree",
Switch: "Switch",
@@ -1923,6 +1949,7 @@ func EnglishTranslationSet() *TranslationSet {
MarkedBaseCommitStatus: "Marked a base commit for rebase",
MarkAsBaseCommit: "Mark as base commit for rebase",
MarkAsBaseCommitTooltip: "Select a base commit for the next rebase. When you rebase onto a branch, only commits above the base commit will be brought across. This uses the `git rebase --onto` command.",
CancelMarkedBaseCommit: "Cancel marked base commit",
MarkedCommitMarker: "↑↑↑ Will rebase from here ↑↑↑",
FailedToOpenURL: "Failed to open URL %s\n\nError: %v",
InvalidLazygitEditURL: "Invalid lazygit-edit URL format: %s",
@@ -2028,6 +2055,9 @@ func EnglishTranslationSet() *TranslationSet {
UpdateRemote: "Update remote",
ApplyPatch: "Apply patch",
Stash: "Stash",
PopStash: "Pop stash",
ApplyStash: "Apply stash",
DropStash: "Drop stash",
RenameStash: "Rename stash",
RemoveSubmodule: "Remove submodule",
ResetSubmodule: "Reset submodule",
@@ -2140,6 +2170,15 @@ git:
gui:
useHunkModeInStagingView: false
`,
"0.55.0": `- The 'redo' command, which used to be bound to ctrl-z, is now bound to shift-Z instead. This is because ctrl-z is now used for suspending the application; it is a commonly known keybinding for that in the Linux world. If you want to revert this change, you can do so by adding the following to your config:
keybinding:
universal:
suspendApp: <disabled>
redo: <c-z>
- The 'git.paging.useConfig' option has been removed. If you were relying on it to configure your pager, you'll have to explicitly set the pager again using the git.paging.pager' option.
`,
},
}
+24 -2
View File
@@ -126,6 +126,7 @@
"ForceCheckoutTooltip": "選択したブランチを強制的にチェックアウトします。これにより、選択したブランチをチェックアウトする前にワーキングディレクトリ内のすべてのローカル変更が破棄されます。",
"CheckoutByName": "名前でチェックアウト",
"CheckoutByNameTooltip": "名前でチェックアウトします。入力ボックスに「-」を入力すると、最後のブランチをチェックアウトすることができます。",
"CheckoutPreviousBranch": "直前のブランチにチェックアウト",
"RemoteBranchCheckoutTitle": "{{.branchName}}をチェックアウト",
"RemoteBranchCheckoutPrompt": "このブランチをどのようにチェックアウトしますか?",
"CheckoutTypeNewBranch": "新しいローカルブランチ",
@@ -134,6 +135,9 @@
"CheckoutTypeDetachedHeadTooltip": "リモートブランチをデタッチドヘッド(特定のブランチに属さない状態)としてチェックアウトします。これは、一時的にブランチをテストするだけで継続的な作業をする予定がない場合に便利です。後でそこからローカルブランチを作成することもできます。",
"NewBranch": "新しいブランチ",
"NewBranchFromStashTooltip": "選択したスタッシュエントリから新しいブランチを作成します。これは、スタッシュエントリが作成されたコミットをgitがチェックアウトし、そのコミットから新しいブランチを作成した後、スタッシュエントリを追加のコミットとして新しいブランチに適用することで機能します。",
"MoveCommitsToNewBranch": "コミットを新しいブランチに移動",
"MoveCommitsToNewBranchFromBaseItem": "ベースブランチから新規ブランチ (%s)",
"CannotMoveCommitsNoUnpushedCommits": "新しいブランチに移動するプッシュされていないコミットはありません",
"NoBranchesThisRepo": "このリポジトリにはブランチがありません",
"CommitWithoutMessageErr": "コミットメッセージなしでコミットすることはできません",
"Close": "閉じる",
@@ -151,7 +155,7 @@
"PickCommitTooltip": "選択したコミットをピックするようにマークします(リベース中)。これは、リベースを続行すると、コミットが保持されることを意味します。",
"Pick": "ピック",
"Edit": "編集",
"Revert": "元に戻す",
"Revert": "リバート",
"RevertCommitTooltip": "選択したコミットの変更を逆に適用する、リバートコミットを作成します。",
"Reword": "メッセージ変更",
"CommitRewordTooltip": "選択したコミットのメッセージを変更します。",
@@ -230,7 +234,6 @@
"ConfirmQuitDuringUpdate": "更新が進行中です。本当に終了してよろしいですか?",
"MergeToolTitle": "マージツール",
"MergeToolPrompt": "`git mergetool`を開いてもよろしいですか?",
"IntroPopupMessage": "\nlazygitをご利用いただきありがとうございます。以下の3点をご案内します:\n\n 1) lazygitの機能を詳しく知りたい方は、こちらのビデオをご覧ください:\n https://youtu.be/CPLdltN7wgE\n\n 2) 最新のリリースノートもぜひご確認ください:\n https://github.com/jesseduffield/lazygit/releases\n\n 3) lazygitはみなさんの協力でより良くなります。開発に参加して\n 一緒にlazygitを改善していただければ幸いです:\n https://github.com/jesseduffield/lazygit\n また、右下の寄付ボタンからプロジェクトを支援したり、\n 開発の方向性についてご意見いただくこともできます。もちろん、リポジトリに\n スターを付けるだけでも大きな励みになります!\n\n開始するには{{confirmationKey}}を押してください。\n",
"NonReloadableConfigWarningTitle": "設定が変更されました",
"NonReloadableConfigWarning": "以下の設定が変更されましたが、変更はすぐには反映されません。変更を反映するには、lazygitを終了して再起動してください:\n\n{{configs}}",
"GitconfigParseErr": "引用符で囲まれていない'\\'文字が存在するため、Gogitがgitconfigファイルの解析に失敗しました。これらを削除することで問題が解決するはずです。",
@@ -242,6 +245,7 @@
"IgnoreFile": ".gitignoreに追加",
"ExcludeFile": ".git/info/excludeに追加",
"RefreshFiles": "ファイルを更新",
"FocusMainView": "メインビューにフォーカス",
"Merge": "マージ",
"RegularMerge": "通常のマージ",
"MergeBranchTooltip": "選択した項目を現在のブランチにマージするためのオプションを表示します(通常のマージ、スカッシュマージ)",
@@ -263,6 +267,9 @@
"StageSelectionTooltip": "選択された部分のステージ / アンステージを切り替えます。",
"DiscardSelection": "破棄",
"DiscardSelectionTooltip": "ステージされていない変更が選択されている場合、`git reset`を使用して変更を破棄します。ステージされた変更が選択されている場合、変更をアンステージします。",
"ToggleSelectHunk": "ハンクの選択を切り替える",
"SelectHunk": "ハンクを選択",
"SelectLineByLine": "1行ずつ選択",
"ToggleSelectionForPatch": "パッチ内の行を切り替え",
"EditHunk": "ハンクを編集",
"EditHunkTooltip": "選択したハンクを外部エディタで編集します。",
@@ -281,11 +288,13 @@
"ViewMergeRebaseOptionsTooltip": "現在のマージ/リベースを中止/継続/スキップするオプションを表示します。",
"ViewMergeOptions": "マージオプションを表示",
"ViewRebaseOptions": "リベースオプションを表示",
"ViewRevertOptions": "リバートオプションを表示",
"NotMergingOrRebasing": "現在リベースもマージも行っていません",
"AlreadyRebasing": "リベース中はこのアクションを実行できません",
"RecentRepos": "最近のリポジトリ",
"MergeOptionsTitle": "マージオプション",
"RebaseOptionsTitle": "リベースオプション",
"RevertOptionsTitle": "リバートオプション",
"CommitSummaryTitle": "コミット概要",
"CommitDescriptionTitle": "コミット詳細",
"CommitDescriptionSubTitle": "{{.togglePanelKeyBinding}} でフォーカスを切り替え、{{.commitMenuKeybinding}} でメニューを開く",
@@ -317,9 +326,14 @@
"PullRequestNoUpstream": "アップストリームのないブランチに対してプルリクエストを開くことはできません",
"ErrorOccurred": "エラーが発生しました!以下でイシューを作成してください:",
"ConflictLabel": "コンフリクト",
"PendingCherryPicksSectionHeader": "保留中のチェリーピック",
"PendingRevertsSectionHeader": "保留中のリバート",
"CommitsSectionHeader": "コミット",
"YouDied": "やられた!",
"RewordNotSupported": "リベースの対話モード中のコミットの変更(reword)は現在サポートされていません",
"ChangingThisActionIsNotAllowed": "この種類のリベース TODO エントリの変更は許可されていません",
"NotAllowedMidCherryPickOrRevert": "チェリーピックまたはリバートの際にはこのアクションは許可されていません",
"PickIsOnlyAllowedDuringRebase": "このアクションはリベース中にのみ許可されています",
"DroppingMergeRequiresSingleSelection": "マージコミットを削除するには単一の項目を選択する必要があります",
"CherryPickCopy": "コピー(チェリーピック)",
"CherryPickCopyTooltip": "コミットをコピーとしてマークします。ローカルコミットビューで `{{.paste}}` を押すと、コピーしたコミットをチェックアウトしたブランチにペースト(チェリーピック)できます。いつでも `{{.escape}}` を押して選択をキャンセルできます。",
@@ -360,6 +374,8 @@
"MergingStatus": "マージ中",
"LowercaseRebasingStatus": "リベース中",
"LowercaseMergingStatus": "マージ中",
"LowercaseCherryPickingStatus": "チェリーピック中",
"LowercaseRevertingStatus": "リバート中",
"AmendingStatus": "修正中",
"CherryPickingStatus": "チェリーピック中",
"UndoingStatus": "取り消し中",
@@ -369,6 +385,7 @@
"RewordingStatus": "修正中",
"RevertingStatus": "リバート中",
"CreatingFixupCommitStatus": "fixupコミット作成中",
"MovingCommitsToNewBranchStatus": "コミットを新しいブランチに移動",
"CommitFiles": "コミットファイル",
"SubCommitsDynamicTitle": "コミット (%s)",
"CommitFilesDynamicTitle": "差分ファイル (%s)",
@@ -382,12 +399,14 @@
"DiscardFileChangesTitle": "ファイルの変更を破棄",
"DiscardFileChangesPrompt": "このコミットから選択したファイルの変更を削除してよろしいですか?\n\nこのアクションはリベースを開始し、これらのファイル変更を元に戻します。後続のコミットがこれらの変更に依存している場合、コンフリクトを解決する必要があるかもしれないことに注意してください。\n注意:これにより、アクティブなカスタムパッチもリセットされます。",
"DisabledForGPG": "GPGを使用しているユーザーには利用できない機能です。\n\nパスフレーズエージェント(gpg-agentなど)を使用して署名時にパスフレーズを入力しなくても済むようにしている場合は、lazygitの設定ファイルに\n\ngit:\n overrideGpg: true\n\nを追加することでこの機能を有効にできます。",
"CreateRepo": "Gitリポジトリがありません。新しいgitリポジトリを作成しますか? (y/N): ",
"BareRepo": "ベアリポジトリでLazygitを開こうとしましたが、Lazygitはまだベアリポジトリをサポートしていません。最近のリポジトリを開いてよろしいですか? (y/n) ",
"InitialBranch": "ブランチ名(gitのデフォルトの場合は空のままにしてください): ",
"NoRecentRepositories": "Lazygitはgitリポジトリで開く必要があります。有効な最近のリポジトリはありません。終了します。",
"IncorrectNotARepository": "'notARepository'の値が正しくありません。'prompt'、'create'、'skip'、または'quit'のいずれかである必要があります。",
"AutoStashTitle": "自動スタッシュ?",
"AutoStashPrompt": "変更を持ち越すにはスタッシュとポップを行う必要があります。自動的に行ってよろしいですか? (enter/esc)",
"AutoStashForReverting": "リバートのために自動的にスタッシュします",
"Discard": "破棄",
"DiscardChangesTitle": "変更を破棄",
"DiscardFileChangesTooltip": "選択したファイルの変更を破棄するオプションを表示します。",
@@ -460,6 +479,7 @@
"EnterCommitFile": "ファイルに入る / ディレクトリの折りたたみを切り替える",
"EnterCommitFileTooltip": "ファイルが選択されている場合、そのファイルに入ってカスタムパッチに個々の行を追加/削除できます。ディレクトリが選択されている場合、ディレクトリを切り替えます。",
"ExitCustomPatchBuilder": "カスタムパッチビルダーを終了",
"ExitFocusedMainView": "サイドパネルに戻る",
"EnterUpstream": "アップストリームを '<リモート> <ブランチ名>' 形式で入力",
"InvalidUpstream": "無効なアップストリームです。'<リモート> <ブランチ名>' 形式である必要があります",
"NewRemote": "新しいリモート",
@@ -611,6 +631,7 @@
"CreateNewBranchFromCommit": "コミットから新しいブランチを作成",
"BuildingPatch": "パッチを作成中",
"ViewCommits": "コミットを表示",
"MinGitVersionError": "Git バージョンは %s以上である必要があります。git バージョンをアップグレードしてください。",
"RunningCustomCommandStatus": "カスタムコマンドを実行中",
"SubmoduleStashAndReset": "未コミットのサブモジュールの変更をスタッシュして更新",
"AndResetSubmodules": "サブモジュールをリセット",
@@ -710,6 +731,7 @@
"OpenCommitInBrowser": "ブラウザでコミットを開く",
"ViewBisectOptions": "bisectオプションを表示",
"ConfirmRevertCommit": "{{.selectedCommit}} をリバートしてよろしいですか?",
"ConfirmRevertCommitRange": "選択したコミットをリバートしてよろしいですか?",
"RewordInEditorTitle": "エディタで修正",
"RewordInEditorPrompt": "このコミットをエディタで修正してよろしいですか?",
"CheckoutAutostashPrompt": "'%s' をチェックアウトしてよろしいですか?必要に応じて自動スタッシュが実行されます。",
-1
View File
@@ -119,7 +119,6 @@
"ConfirmQuitDuringUpdate": "현재 업데이트를 진행 중입니다.종료하시겠습니까?",
"MergeToolTitle": "병합 도구",
"MergeToolPrompt": "정말로 `git mergetool`을 여시겠습니까?",
"IntroPopupMessage": "\nlazygit!를 이용해주셔서 감사합니다. Seriously you rock. Three things to share with you:\n\n 1) lazygit의 기능에 대해 알아보려면 다음 비디오를 참조하세요.\n https://youtu.be/CPLdltN7wgE\n\n 2) 다음 사이트에서 최신 릴리스 노트를 읽어보세요.:\n https://github.com/jesseduffield/lazygit/releases\n\n 3) 만약 당신이 Git을 사용한다면, 그것은 당신을 프로그래머로 만들 것입니다!\n\t 당신의 도움으로 우리는 lazygit을 더 좋게 만들 수 있습니다, 그러니 기여자가 되는 것을 고려해보세요. 그리고 재미에 참여하세요:\n https://github.com/jesseduffield/lazygit\n 또한 오른쪽 하단의 기부 버튼을 클릭하여 저를 후원하고 작업할 내용을 알려주실 수 있습니다.\n 또는 저장소에 스타를 눌러 사랑을 공유할 수도 있습니다!\n",
"GitconfigParseErr": "따옴표로 묶이지 않은 '\\' 문자가 있어서 Gogit이 gitconfig 파일을 분석하지 못했습니다. 이를 제거하면 문제가 해결됩니다.",
"EditFile": "파일 편집",
"OpenFile": "파일 닫기",
-1
View File
@@ -82,7 +82,6 @@
"OnLatestVersionErr": "Je hebt al de laatste versie",
"MajorVersionErr": "Nieuwe versie ({{.newVersion}}) is niet backwards compatibele vergeleken met de huidige versie ({{.currentVersion}})",
"CouldNotFindBinaryErr": "Kon geen binary vinden op {{.url}}",
"IntroPopupMessage": "Bedankt voor het gebruik maken van lazygit! 2 dingen die je moet weten:\n\n1) Als je meer van lazygit zijn features wilt leren bekijk dan deze video:\n https://youtu.be/CPLdltN7wgE\n\n2) Als je git gebruikt, ben je een programmeur! Met jouw hulp kunnen we lazygit verbeteren, dus overweeg om een ​​donateur te worden en mee te doen aan het plezier op\n https://github.com/jesseduffield/lazygit",
"GitconfigParseErr": "Gogit kon je gitconfig bestand niet goed parsen door de aanwezigheid van losstaande '\\' tekens. Het weghalen van deze tekens zou het probleem moeten oplossen. ",
"EditFile": "Verander bestand",
"OpenFile": "Open bestand",
+9 -1
View File
@@ -64,11 +64,13 @@
"CopyFileDiffTooltip": "Se existirem itens preparados, este comando considera apenas eles",
"CopySelectedDiff": "Diferença do arquivo selecionado",
"CopyAllFilesDiff": "Diferença de todos os arquivos",
"CopyFileContent": "Conteúdo do arquivo selecionado",
"NoContentToCopyError": "Nada para copiar",
"FileNameCopiedToast": "No do arquivo copiado para a área de transferência",
"FilePathCopiedToast": "Caminho do arquivo copiado para a área de transferência",
"FileDiffCopiedToast": "Diferença do arquivo copiado para a área de transferência ",
"AllFilesDiffCopiedToast": "Todos os arquivos diferentes foram copiados para a área de transferência",
"FileContentCopiedToast": "Conteúdo do arquivo copiado para a área de transferência",
"FilterStagedFiles": "Mostrar somente os arquivos em staging",
"FilterUnstagedFiles": "Mostrar somente arquivos que não estão em staging",
"FilterTrackedFiles": "Mostrar apenas arquivos rastreados",
@@ -118,6 +120,7 @@
"ForceCheckoutTooltip": "Forçar checagem da branch selecionada. Isso irá descartar todas as mudanças no seu diretório de trabalho antes cheque a branch selecionada ",
"CheckoutByName": "Checar por nome",
"CheckoutByNameTooltip": "Checar por nome. Na caixa de entrada você pode inserir '-' para trocar para a última branch ",
"CheckoutPreviousBranch": "Checkout da branch anterior",
"RemoteBranchCheckoutTitle": "Checar {{.branchName}}",
"RemoteBranchCheckoutPrompt": "Como você gostaria de checar essa branch?",
"CheckoutTypeNewBranch": "Nova branch local",
@@ -126,6 +129,9 @@
"CheckoutTypeDetachedHeadTooltip": "Checar a branch remota como um HEAD desanexado, que pode ser útil se você apenas quer para testar a branch, mas não trabalha nela você mesmo. Você ainda pode criar um branch remoto a partir dela depois",
"NewBranch": "Nova branch",
"NewBranchFromStashTooltip": "Criar um novo ramo a partir da entrada de lixo selecionada. Isso funciona verificando o commit do qual a entrada de lixo foi criada, criar um novo branch a partir desse commit e, em seguida, aplicar a entrada de lixo ao novo branch como um commit adicional.",
"MoveCommitsToNewBranch": "Mover commits para uma nova branch",
"MoveCommitsToNewBranchFromBaseItem": "Nova branch da branch base (%s)",
"MoveCommitsToNewBranchStackedItem": "Novo branch empilhado na branch atual (%s)",
"NoBranchesThisRepo": "Nenhuma branch para esse repositório",
"CommitWithoutMessageErr": "Você não pode dar commit sem uma mensagem de commit",
"Close": "Fechar",
@@ -221,7 +227,6 @@
"ConfirmQuitDuringUpdate": "Uma atualização está em andamento. Tem certeza que deseja sair?",
"MergeToolTitle": "Ferramenta de mesclagem",
"MergeToolPrompt": "Tem certeza de que deseja abrir o `git mergetool`?",
"IntroPopupMessage": "\nObrigado por usar lazygit! Sério, você rock. Três coisas para compartilhar com você:\n\n 1) Se quiser aprender sobre os recursos do lazygit, assista a este vid:\n https://youtu. e/CPLdltN7wgE\n\n 2) Não deixe de ler as últimas notas de lançamento em:\n https://github. um/jesseduffield/lazygit/releases\n\n 3) Se você estiver usando um git, isso o torna um programador! Com a sua ajuda, podemos fazer\n lazygit melhor, então considere se tornar um colaborador e se junte à diversão no\n https://github. om/jesseduffield/lazygit\n Você também pode me patrocinar e me dizer no que trabalhar clicando no botão\n de doar na parte inferior direita.\n Ou até mesmo apenas adicionar estrela no repositório para compartilhar o amor!\n",
"NonReloadableConfigWarningTitle": "Configuração alterada",
"NonReloadableConfigWarning": "As seguintes configurações foram alteradas, mas a mudança não tem efeito imediatamente. Encerre e reinicie o lazygit para que as mudanças tenham efeito:\n\n{{configs}}",
"GitconfigParseErr": "Gogit falhou ao analisar seu arquivo gitconfig devido à presença de caracteres '\\' não citados. Removendo-os deve corrigir o problema.",
@@ -306,6 +311,8 @@
"FwdCommitsToPush": "Não é possível encaminhar um branch com commits para fazer push",
"PullRequestNoUpstream": "Não é possível abrir uma pull request para um branch sem upstream",
"ErrorOccurred": "Ocorreu um erro! Por favor, crie um problema em",
"ConflictLabel": "CONFLITO",
"CommitsSectionHeader": "Commits",
"YouDied": "VOCÊ MORREU!",
"RewordNotSupported": "Reredacção de commits enquanto rebasing interativamente não é suportado atualmente",
"ChangingThisActionIsNotAllowed": "Não é permitido alterar este tipo de rebase de tarefas",
@@ -357,6 +364,7 @@
"CommittingStatus": "Commitando",
"RevertingStatus": "revertendo",
"CreatingFixupCommitStatus": "Criando commit de correção",
"MovingCommitsToNewBranchStatus": "Mover commits para uma nova branch",
"CommitFiles": "Commit arquivos",
"SubCommitsDynamicTitle": "Commits (%s)",
"CommitFilesDynamicTitle": "Arquivos diff (%s)",
-1
View File
@@ -124,7 +124,6 @@
"ConfirmQuitDuringUpdate": "Выполняется обновление. Вы уверены, что хотите выйти?",
"MergeToolTitle": "Инструмент слияния",
"MergeToolPrompt": "Вы уверены, что хотите открыть `git mergetool`?",
"IntroPopupMessage": "\nБлагодарю за использование lazygit! Серьёзно, вы просто супер. Три вещи, которыми я хочу поделиться:\n\n 1) Чтобы узнать о возможностях lazygit, посмотрите это видео:\n https://youtu.be/CPLdltN7wgE\n\n 2) Обязательно ознакомьтесь с последними примечаниями к выпуску перейдя по ссылке:\n https://github.com/jesseduffield/lazygit/releases\n\n 3) Используете git? Значит Вы программист! С Вашей помощью мы можем сделать lazygit лучше,\n станьте участником и присоединиться к веселью в\n https://github.com/jesseduffield/lazygit\n Вы также можете поддержать меня и рассказать, над чем мне ещё стоит поработать,\n нажав на кнопку \"Поддержать\" в правом нижнем углу.\n Или поделиться любовь просто добавив репозиторий в избранные.\n",
"GitconfigParseErr": "Gogit не удалось проанализировать ваш файл gitconfig из-за наличия символов «\\» без кавычек. Их удаление должно решить проблему.",
"EditFile": "Редактировать файл",
"OpenFile": "Открыть файл",
-1
View File
@@ -230,7 +230,6 @@
"ConfirmQuitDuringUpdate": "当前正在更新中,您确定要退出吗?",
"MergeToolTitle": "合并工具",
"MergeToolPrompt": "确定要打开 `git mergetool` 吗?",
"IntroPopupMessage": "\n感谢使用 lazygit!您真的太棒了。下面几点您可能会感兴趣:\n\n 1) 观看此视频,快速了解 lazygit 的功能:\n https://youtu.be/CPLdltN7wgE\n\n 2) 记得看看最新发行说明:\n https://github.com/jesseduffield/lazygit/releases\n\n 3) 使用 git 说明您是一位程序员!您可以和我们一起让 lazygit 变得更好。\n 考虑为本项目做些贡献吧:\n https://github.com/jesseduffield/lazygit\n 您也可以直接赞助,并告诉我哪里需要改进,点右下角的捐赠按钮就好了。\n 哪怕只是给仓库点个星星也很棒!\n",
"NonReloadableConfigWarningTitle": "配置已更改",
"NonReloadableConfigWarning": "以下配置设置已更改,但更改不会立即生效。请退出并重新启动lazygit以使更改生效:\n\n{{configs}}",
"GitconfigParseErr": "由于存在未加引号的'\\'字符,因此 Gogit 无法解析您的 gitconfig 文件。删除它们应该可以解决问题。",
-1
View File
@@ -154,7 +154,6 @@
"ConfirmQuitDuringUpdate": "正在進行更新,是否結束?",
"MergeToolTitle": "合併工具",
"MergeToolPrompt": "是否開啟 'git mergetool'?",
"IntroPopupMessage": "\n感謝使用 lazygit!這裡有一些資源可供參考:\n\n 1) 📺lazygit 教學📺:\n https://youtu.be/CPLdltN7wgE\n\n 2) 📣發佈說明📣:\n https://github.com/jesseduffield/lazygit/releases\n\n 3) 💖如果你想要貢獻一份心力你可以💖:\n 改進 lazygit 原始碼:https://github.com/jesseduffield/lazygit\n 按右下角的捐款斗內我們\n 或單純添加 lazygit 到你的 star 清單內以增加曝光度都能大力的幫助我們!\n",
"GitconfigParseErr": "Gogit 無法解析你的 gitconfig 檔案,因為存在未引用的 '\\' 字符,刪除它們應該可以解決這個問題。",
"EditFile": "編輯檔案",
"EditFileTooltip": "使用外部編輯器開啟",
-1
View File
@@ -1,5 +1,4 @@
//go:build !windows
// +build !windows
package clients
@@ -27,7 +27,7 @@ func (self *CommitDescriptionPanelDriver) SwitchToSummary() *CommitMessagePanelD
}
func (self *CommitDescriptionPanelDriver) AddNewline() *CommitDescriptionPanelDriver {
self.t.pressFast(self.t.keys.Universal.Confirm)
self.t.pressFast("<enter>")
return self
}
+1 -1
View File
@@ -21,7 +21,7 @@ func (self *MenuDriver) Title(expected *TextMatcher) *MenuDriver {
func (self *MenuDriver) Confirm() *MenuDriver {
self.checkNecessaryChecksCompleted()
self.getViewDriver().PressEnter()
self.getViewDriver().Press(self.t.keys.Universal.ConfirmMenu)
return self
}
+8 -3
View File
@@ -13,7 +13,7 @@ func (self *Popup) Confirmation() *ConfirmationDriver {
func (self *Popup) inConfirm() {
self.t.assertWithRetries(func() (bool, string) {
currentView := self.t.gui.CurrentContext().GetView()
return currentView.Name() == "confirmation" && !currentView.Editable, "Expected confirmation popup to be focused"
return currentView.Name() == "confirmation", "Expected confirmation popup to be focused"
})
}
@@ -26,7 +26,7 @@ func (self *Popup) Prompt() *PromptDriver {
func (self *Popup) inPrompt() {
self.t.assertWithRetries(func() (bool, string) {
currentView := self.t.gui.CurrentContext().GetView()
return currentView.Name() == "confirmation" && currentView.Editable, "Expected prompt popup to be focused"
return currentView.Name() == "prompt", "Expected prompt popup to be focused"
})
}
@@ -36,11 +36,16 @@ func (self *Popup) Alert() *AlertDriver {
return &AlertDriver{t: self.t}
}
func (self *AlertDriver) Tap(f func()) *AlertDriver {
self.getViewDriver().Tap(f)
return self
}
func (self *Popup) inAlert() {
// basically the same thing as a confirmation popup with the current implementation
self.t.assertWithRetries(func() (bool, string) {
currentView := self.t.gui.CurrentContext().GetView()
return currentView.Name() == "confirmation" && !currentView.Editable, "Expected alert popup to be focused"
return currentView.Name() == "confirmation", "Expected alert popup to be focused"
})
}
+3 -3
View File
@@ -6,7 +6,7 @@ type PromptDriver struct {
}
func (self *PromptDriver) getViewDriver() *ViewDriver {
return self.t.Views().Confirmation()
return self.t.Views().Prompt()
}
// asserts that the popup has the expected title
@@ -72,7 +72,7 @@ func (self *PromptDriver) ConfirmFirstSuggestion() {
self.t.Views().Suggestions().
IsFocused().
SelectedLineIdx(0).
PressEnter()
Press(self.t.keys.Universal.ConfirmSuggestion)
}
func (self *PromptDriver) ConfirmSuggestion(matcher *TextMatcher) {
@@ -80,7 +80,7 @@ func (self *PromptDriver) ConfirmSuggestion(matcher *TextMatcher) {
self.t.Views().Suggestions().
IsFocused().
NavigateToLine(matcher).
PressEnter()
Press(self.t.keys.Universal.ConfirmSuggestion)
}
func (self *PromptDriver) DeleteSuggestion(matcher *TextMatcher) *PromptDriver {
+4
View File
@@ -128,6 +128,10 @@ func (self *Views) Confirmation() *ViewDriver {
return self.regularView("confirmation")
}
func (self *Views) Prompt() *ViewDriver {
return self.regularView("prompt")
}
func (self *Views) CommitMessage() *ViewDriver {
return self.regularView("commitMessage")
}

Some files were not shown because too many files have changed in this diff Show More