microsoft / vscode

Visual Studio Code
https://code.visualstudio.com
MIT License
160.9k stars 28.22k forks source link

SCM: Support keyboard shortcuts #24916

Open kgrossjo opened 7 years ago

kgrossjo commented 7 years ago

Steps to Reproduce:

  1. Open a project under git, with some changed files
  2. Ctrl-Shift-G to open the SCM view. It has a commit message at the top and a list of Changes below.
  3. Tab to go to the list of Changes.
  4. Cursor down until an interesting file is selected.

Now I can do Return to see a diff. After that, the file is highlighted and there are icons in the SCM view for reverting this file (curved arrow) or for staging it (plus sign).

But I can't find a keyboard shortcut for the "stage" icon. I tried Return, Ctrl-Return, Space, Ctrl-Space, S, Shift-S, the Plus key, Cmd-Down (because that opens a file in Explorer view), Cmd-Up, Cmd-Right, Cmd-Left.

I also tried Cmd-Shift-P to find the command, but it doesn't have a keyboard shortcut printed. I also tried to right-click the file, which gave me a context menu (with "stage" in it), again without keyboard shortcut.

joaomoreno commented 7 years ago

Try Shift F10 and then pick the desired action.

kgrossjo commented 7 years ago

Hm. F10 invokes a macOS action (to show all windows of the application), and Shift-F10 does the same but with slow motion animation.

But it provided a starting point: In the keyboard shortcuts I searched for F10, found the Shift-F10 command, and reassigned it to cmd-F10. So now when I'm in a text editor, I can use it and I get a nice context menu.

But the keyboard shortcut has "When editorTextFocus", and so it doesn't work in the SCM view.

I also searched the reference documentation to see if there is a "When" setting (I think it's called "context"?) that I can use to trigger when the SCM view has focus. But I've not been able to find it.

The issue was closed, but for me, it's not resolved yet. @joaomoreno is it okay with you to reopen this ticket?

joaomoreno commented 7 years ago

Absolutely.

Yeah that keybinding is only valid for the editor, not the list widget. You should use Fn-F10, though. Does that work for you?

kgrossjo commented 7 years ago

Fn-F10 mutes the loudspeakers. Fn-Shift-F10 seems to do the same.

By now, it's starting to look as if these actions aren't possible via the keyboard. There is an action for "git add" that I can activate via cmd-shift-P, but that one seems to apply to the currently focused editor, not to the file that's selected in the SCM view.

Thanks for your help, @joaomoreno I really appreciate it. I wish I could be more positive in my messages.

joaomoreno commented 7 years ago

No worries @kgrossjo. We should definitely get this story better.

cleidigh commented 7 years ago

@kgrossjo @joaomoreno I think my PR #24860 addresses this albeit without a specific shortcut. it allows The Tab Key to be used to get to the ad and stage icons on the focused line/file without having to press Enter to select the line which would open the diff in the editor.

yetithefoot commented 6 years ago

I came from Sublime Text. I'm using GitSavvy plugin for ST, which implements great user experience working with git via shortcuts. It would be possible to implement similar experience via VS Code keybindings, but I can find specific actions and options to specify when scope for scm viewlet. Appreciate any help.

https://cloud.githubusercontent.com/assets/5016978/6704171/2f236466-cd02-11e4-9b7d-22cc880b5e9d.png

franciscolourenco commented 6 years ago

Gitsavvy is by far the best git staging experience I've tried so far. The only thing I'm missing in VSCode at the moment.

staging

Some of the features missing:

AB1908 commented 6 years ago

I similarly came from Atom where you can press Enter on the focused file to Stage/Unstage it. It would be great to have a keyboard shortcut for this. Perhaps we could create a keybinding since the command to stage a file is already in the command palette?

LFDM commented 6 years ago

I used an own fork of VSCode for the last to years, where I heavily modified this panel to work in the following way (worth noting that this was also all heavy inspired by vim keybindings):

j would also select the group headers like "Changes" - pressing a there would stage all changed files, or unstage all files when you have "Staged Changes" focused.

So the regular flow is for example like this:

alt+g to open. j j j to jump to the file I want, a to stage the file, a to stage the next file, a to stage the next file, i to start writing the commit message, ctrl+enter to commit.

It's blazingly quick and super convenient. Definitely something I am missing from regular VSCode.

kgrossjo commented 6 years ago

It turns out that quite a few things have changed, usability is much improved. It's still possible to do better, though.

Say I'm in a project that has a git repo and some files are changed ("unstaged changes" in git status).

ctrl-shift-g opens the SCM view, the commit message field is focused. I can do tab to go to the list of files ("Changes"), then j to the file I want, then tab tab tab to focus the "+" icon, then space to add the file to the list of "Staged Changes".

But the SCM view has lost focus, so I have to ctrl-shift-g again, which focuses the commit message field. From there, I can tab to the list of files, then j my way down over all the files I've already staged down to the unstaged changes, to the file I want.

I feel that it would be nice if, after hitting space to execute the "+" action to move the file to the list of staged changes, the SCM view retained focus, and perhaps the first unstaged file could have focus, or one file down from the one I "+"-ed, or one file up from the one I "+"-ed.

I also like the approach presented by @LFDM in his comment from a few hours ago. That after ctrl-shift-g, the list of files has focus, and that there is a key to move focus to the commit message.

simkimsia commented 5 years ago

I tried this but didn't work as well.

image

WOuld be good if there's a clear way on how to set the when expression for scm view is in focus

electrovir commented 4 years ago

Is this dead? :slightly_frowning_face: Reviewing commits that touch many files in VS Code is a very slow experience right now...

CombeeMike commented 4 years ago

Since my feature request #50434 has been closed as a duplicate of #24389 which then has been merged with this one, I'd like to stress here that a dedicated command (with shortcut) to open the next file with changes in the currently open diff view would improve my VCS/GIT workflow tremendously (as described in #50434)!

Some additional thoughts:

Workaround using AHK

In the meantime I managed to workaround this by using some AHK script which is bound to a global Windows hotkey:

; ======================================================================================================================
; Select the next or previous item relative to the current selection in the "changed items" list and open the diff
; editor
; ======================================================================================================================
SelectNextOrPrev(SelNext)
{
  Send ^+m   ; Ctrl+Shift+m -> Open "Source Control" panel
  Send {Tab} ; Go to list of changed files

  ; Select next or prev file in list
  If (SelNext == True)
    Send {Down}
  Else
    Send {Up}

  Send {Enter} ; Show diff editor
}

; ======================================================================================================================
; Select the first item in the "changed items" list and open the diff editor
; ======================================================================================================================
SelectFirst()
{
  Send ^+m          ; Ctrl+Shift+m -> Open "Source Control" panel
  Send {Esc}        ; Remove focus from input box
  Send {Home}       ; Set active item to the parent of the input box
  Send {Down}{Down} ; Select first item in list
  Send {Enter}      ; Show diff editor
}

; ======================================================================================================================
; Main
; ======================================================================================================================
If WinActive("ahk_exe Code.exe")
{
  arg = %1% ; Accepted values for command line arg0: "f" = Show first, "n" = Show next, "p" = Show prev
  If (arg = "f")
    SelectFirst()
  Else
    SelectNextOrPrev(arg = "n")
}
Else
{
  MsgBox, Not in VSCode!
}

This works pretty well for me so far but I'm sure that there are situations where this doesn't work as expected. E.g. I know that the script to select the first item in the list doesn't work, when the "changes" list is collapsed etc.

johndevedu commented 3 years ago

This has been bugging me for a while. Finally came up w/ a solution that works pretty well. TL:DR instead of navigating through each file one by one in the SCM panel, get all files open (requires GitLens extension) then review one file at a time -> close tab when done.

  1. Close all tabs (optional, but cleaner experience for me)
  2. Use GitLens: Open All Changes (with difftool). I have difftool connected to VSCode. { "key": "alt+numpad6", "command": "gitlens.externalDiffAll" }
  3. Show Next Change / Show Previous Change { "key": "alt+numpad3", "command": "workbench.action.compareEditor.nextChange", "when": "textCompareEditorVisible" }
  4. Once done reviewing each file, close tab
  5. Repeat steps 1-4 for other files until all files complete.
PurplProto commented 2 years ago

Sadly this still seems like quite a pain point for many 😢.

Not a perfect solution but the current way I manage to keep my hands on the keyboard without any fancy extensions or forked Code builds is rather long-winded although, it works-ish:

  1. Focus the SCM panel using Ctrl+Shift+G G (I believe Git Lens changes this from the default)
  2. Use the arrow keys to highlight a change in the list
  3. Press Space to open the diff, or Enter if I want to focus the editor to scroll the file or use Alt+F5
  4. When happy with reviewing the changes, use Ctrl+Shift+G G to focus the SCM panel again
  5. Press Tab to focus the actions section on the file
  6. Press LeftArrow to highlight the stage button
  7. Press Space to stage the change
  8. Repeat 2-6 as many times as required
  9. Press PgUp to highlight the commit message box
  10. Press either Space or Enter to focus the message box
  11. Type your commit message
  12. Press Ctrl+Enter to commit

Note, from step 9 you can press Shift+Tab to lose focus of the commit message box and return to having the SCM panel focused so you can stage/unstage files again.

dannypernik commented 2 years ago

Can we call a vote on this one?

AB1908 commented 2 years ago

Apologies in advance for not contributing meaningfully but I've since shifted to vim for writing commit messages since the terminal is a simple enough binding away. Hope y'all find a resolution though!

wjandrea commented 1 year ago

I tried this but didn't work as well.

image

WOuld be good if there's a clear way on how to set the when expression for scm view is in focus

@simkimsia git.stageChange doesn't seem to do anything. It's not available in the command palette when focused on the SCM, editor, or a diff, so I'm not sure how it's supposed to be used. Maybe it's available in some other context?

But anyway, I think you want to use focusedView == "workbench.scm" instead of activeViewlet == "workbench.view.scm" so that the shortcut only works when the SCM is focused, not just when it's visible as a viewlet. (Personally, I actually pinned mine to the other side (like in Atom), which makes it not a viewlet.)

Tantol commented 6 months ago

I used an own fork of VSCode for the last to years, where I heavily modified this panel to work in the following way (worth noting that this was also all heavy inspired by vim keybindings):

* When you open the SCM view, the input field is NOT focused, we instead are directly focused at the first unstaged file (I use `alt+g` to open the SCM view.

* `j` and `k` allows to navigate through the list of files

* `a` adds the file to the staged changes, if its already staged it unstages

* `u` undos changes to a file

* `d` diffs the file

* `i` jumps to the input field to write the commit message

* `esc` jumps out of the input field back to the file list.

* `ctrl/cmd+enter` commits it.

j would also select the group headers like "Changes" - pressing a there would stage all changed files, or unstage all files when you have "Staged Changes" focused.

So the regular flow is for example like this:

alt+g to open. j j j to jump to the file I want, a to stage the file, a to stage the next file, a to stage the next file, i to start writing the commit message, ctrl+enter to commit.

It's blazingly quick and super convenient. Definitely something I am missing from regular VSCode.

This functionality is what I need to replace lazygit

mawid6 commented 4 months ago

I tried this but didn't work as well.

image

WOuld be good if there's a clear way on how to set the when expression for scm view is in focus

Yeah, this feels like a bug to me.

I dont understand how to set the stage and unstage actions to be executed, if possible. I also have tried focusedView == "workbench.scm", and other combinations with different key bindings (for me, plus and minus would seem logical, for instance), and two things to notice:

  1. The bindings show up in the context menu, as if they should be working. See this screenshot:

image

  1. Using the binding, and enabling & viewing the keybinding log (thanks @wjandrea), I see that the binding is working and it is in fact invoking git.stage. But, git.stage fails to handle the event and fails silently.

I intentionally used ctrl+-, which "zooms out", but if I am in the source control panel with this binding defined, it does not zoom out. This seems to me that the binding actually works, it catches the keypress combo and likely tries to start the command but something is amiss with the unstage command - it might be expecting some other context, or whatever. But something is hindering unstage from executing.

image

git.stage fails when invoked via key binding from the scm panel. Why?

git.stage can be invoked in three ways from the scm panel (using a mouse, invoking from context menu, using keyboard or mouse and using a keyboard), of which two work. One is the by far most common (using a mouse). The second way works (using a keyboard with the context menu). The third fails (when invoked using a keyboard shortcut).

So, more explicitly, if git.stage is invoked:

  1. after selecting a file using the mouse - works ✅ 👍 . This will also show the file changes in the editor (atleast in my setup).
  2. after shifting focus to scm panel & navigating with arrows and bringing up the context menu with e g context key and then selecting command - works ✅ 👍 . This will not show the changes in the editor, but does work.
  3. after shifting focus to scm panel & navigating with arrows and using a keyboard binding - fails 👎 ❌ .

Might it be that some context is lacking when the event is invoked via keyboard binding and file is in focus in the panel?

Well, it is a bug. I hope it can be fixed.

wjandrea commented 4 months ago

@mawid6 Use the command Developer: Toggle Keyboard Shortcuts Troubleshooting to see what's really going on

mawid6 commented 4 months ago

Thanks alot for the tip @wjandrea! I was not aware of that -so far, I am staying away from vs code development... :-) However, the log helped me further pin down the problem and confirm my hypothesis above: git.stage command is in fact being invoked, but it does not handle the event properly, but instead fails silently.

I will update my comment above, transforming it from a hypothesis to a statement and a further hypothesis on what is wrong.

dannypernik commented 4 months ago

@mawid6 do you think it would be worth creating a new issue that references this one in order to bring more attention to it?This issue is much broader in scope than what you've identified. We're approaching 7 years in the making here.

mawid6 commented 4 months ago

@dannypernik well, to be fair, it seems like they could solve the OP problem if they fixed so that we can access the SCM commands (whereof stage was in focus for the OP) from the panel. However, I think I might create a new issue to bring attention to it. That makes sense. Thanks.