git: Fix project diff shortcuts (#26045)
Release Notes: - git: Fix keyboard shortcut display in project diff view
This commit is contained in:
parent
ad94642e83
commit
85211889e5
16 changed files with 108 additions and 233 deletions
|
@ -370,10 +370,10 @@
|
||||||
"ctrl-shift-v": "markdown::OpenPreview",
|
"ctrl-shift-v": "markdown::OpenPreview",
|
||||||
"ctrl-alt-shift-c": "editor::DisplayCursorNames",
|
"ctrl-alt-shift-c": "editor::DisplayCursorNames",
|
||||||
"ctrl-alt-y": "git::ToggleStaged",
|
"ctrl-alt-y": "git::ToggleStaged",
|
||||||
"alt-y": ["git::StageAndNext", { "whole_excerpt": false }],
|
"alt-y": "git::StageAndNext",
|
||||||
"alt-shift-y": ["git::UnstageAndNext", { "whole_excerpt": false }],
|
"alt-shift-y": "git::UnstageAndNext",
|
||||||
"alt-.": ["editor::GoToHunk", { "center_cursor": true }],
|
"alt-.": "editor::GoToHunk",
|
||||||
"alt-,": ["editor::GoToPreviousHunk", { "center_cursor": true }]
|
"alt-,": "editor::GoToPreviousHunk"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -564,8 +564,8 @@
|
||||||
"shift-enter": "editor::ExpandExcerpts",
|
"shift-enter": "editor::ExpandExcerpts",
|
||||||
"ctrl-alt-enter": "editor::OpenExcerptsSplit",
|
"ctrl-alt-enter": "editor::OpenExcerptsSplit",
|
||||||
"ctrl-shift-e": "pane::RevealInProjectPanel",
|
"ctrl-shift-e": "pane::RevealInProjectPanel",
|
||||||
"ctrl-f8": ["editor::GoToHunk", { "center_cursor": true }],
|
"ctrl-f8": "editor::GoToHunk",
|
||||||
"ctrl-shift-f8": ["editor::GoToPreviousHunk", { "center_cursor": true }],
|
"ctrl-shift-f8": "editor::GoToPreviousHunk",
|
||||||
"ctrl-enter": "assistant::InlineAssist",
|
"ctrl-enter": "assistant::InlineAssist",
|
||||||
"ctrl-:": "editor::ToggleInlayHints"
|
"ctrl-:": "editor::ToggleInlayHints"
|
||||||
}
|
}
|
||||||
|
@ -739,7 +739,7 @@
|
||||||
"tab": "git_panel::FocusEditor",
|
"tab": "git_panel::FocusEditor",
|
||||||
"shift-tab": "git_panel::FocusEditor",
|
"shift-tab": "git_panel::FocusEditor",
|
||||||
"escape": "git_panel::ToggleFocus",
|
"escape": "git_panel::ToggleFocus",
|
||||||
"ctrl-enter": "git::Commit",
|
"ctrl-enter": "git::ShowCommitEditor",
|
||||||
"alt-enter": "menu::SecondaryConfirm"
|
"alt-enter": "menu::SecondaryConfirm"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -753,7 +753,7 @@
|
||||||
{
|
{
|
||||||
"context": "GitDiff > Editor",
|
"context": "GitDiff > Editor",
|
||||||
"bindings": {
|
"bindings": {
|
||||||
"ctrl-enter": "git::Commit"
|
"ctrl-enter": "git::ShowCommitEditor"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -766,14 +766,6 @@
|
||||||
"alt-up": "git_panel::FocusChanges"
|
"alt-up": "git_panel::FocusChanges"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"context": "GitCommit > Editor",
|
|
||||||
"use_key_equivalents": true,
|
|
||||||
"bindings": {
|
|
||||||
"enter": "editor::Newline",
|
|
||||||
"ctrl-enter": "git::Commit"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"context": "CollabPanel && not_editing",
|
"context": "CollabPanel && not_editing",
|
||||||
"bindings": {
|
"bindings": {
|
||||||
|
|
|
@ -142,8 +142,8 @@
|
||||||
"cmd-;": "editor::ToggleLineNumbers",
|
"cmd-;": "editor::ToggleLineNumbers",
|
||||||
"cmd-alt-z": "git::Restore",
|
"cmd-alt-z": "git::Restore",
|
||||||
"cmd-alt-y": "git::ToggleStaged",
|
"cmd-alt-y": "git::ToggleStaged",
|
||||||
"cmd-y": ["git::StageAndNext", { "whole_excerpt": false }],
|
"cmd-y": "git::StageAndNext",
|
||||||
"cmd-shift-y": ["git::UnstageAndNext", { "whole_excerpt": false }],
|
"cmd-shift-y": "git::UnstageAndNext",
|
||||||
"cmd-'": "editor::ToggleSelectedDiffHunks",
|
"cmd-'": "editor::ToggleSelectedDiffHunks",
|
||||||
"cmd-\"": "editor::ExpandAllDiffHunks",
|
"cmd-\"": "editor::ExpandAllDiffHunks",
|
||||||
"cmd-alt-g b": "editor::ToggleGitBlame",
|
"cmd-alt-g b": "editor::ToggleGitBlame",
|
||||||
|
@ -659,8 +659,8 @@
|
||||||
"shift-enter": "editor::ExpandExcerpts",
|
"shift-enter": "editor::ExpandExcerpts",
|
||||||
"cmd-alt-enter": "editor::OpenExcerptsSplit",
|
"cmd-alt-enter": "editor::OpenExcerptsSplit",
|
||||||
"cmd-shift-e": "pane::RevealInProjectPanel",
|
"cmd-shift-e": "pane::RevealInProjectPanel",
|
||||||
"cmd-f8": ["editor::GoToHunk", { "center_cursor": true }],
|
"cmd-f8": "editor::GoToHunk",
|
||||||
"cmd-shift-f8": ["editor::GoToPreviousHunk", { "center_cursor": true }],
|
"cmd-shift-f8": "editor::GoToPreviousHunk",
|
||||||
"ctrl-enter": "assistant::InlineAssist",
|
"ctrl-enter": "assistant::InlineAssist",
|
||||||
"ctrl-:": "editor::ToggleInlayHints"
|
"ctrl-:": "editor::ToggleInlayHints"
|
||||||
}
|
}
|
||||||
|
@ -760,14 +760,14 @@
|
||||||
"tab": "git_panel::FocusEditor",
|
"tab": "git_panel::FocusEditor",
|
||||||
"shift-tab": "git_panel::FocusEditor",
|
"shift-tab": "git_panel::FocusEditor",
|
||||||
"escape": "git_panel::ToggleFocus",
|
"escape": "git_panel::ToggleFocus",
|
||||||
"cmd-enter": "git::Commit"
|
"cmd-enter": "git::ShowCommitEditor"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"context": "GitDiff > Editor",
|
"context": "GitDiff > Editor",
|
||||||
"use_key_equivalents": true,
|
"use_key_equivalents": true,
|
||||||
"bindings": {
|
"bindings": {
|
||||||
"cmd-enter": "git::Commit"
|
"cmd-enter": "git::ShowCommitEditor"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|
|
@ -42,8 +42,8 @@
|
||||||
"ctrl-alt-shift-b": "editor::GoToTypeDefinitionSplit",
|
"ctrl-alt-shift-b": "editor::GoToTypeDefinitionSplit",
|
||||||
"f2": "editor::GoToDiagnostic",
|
"f2": "editor::GoToDiagnostic",
|
||||||
"shift-f2": "editor::GoToPreviousDiagnostic",
|
"shift-f2": "editor::GoToPreviousDiagnostic",
|
||||||
"ctrl-alt-shift-down": ["editor::GoToHunk", { "center_cursor": true }],
|
"ctrl-alt-shift-down": "editor::GoToHunk",
|
||||||
"ctrl-alt-shift-up": ["editor::GoToPreviousHunk", { "center_cursor": true }],
|
"ctrl-alt-shift-up": "editor::GoToPreviousHunk",
|
||||||
"ctrl-alt-z": "git::Restore",
|
"ctrl-alt-z": "git::Restore",
|
||||||
"ctrl-home": "editor::MoveToBeginning",
|
"ctrl-home": "editor::MoveToBeginning",
|
||||||
"ctrl-end": "editor::MoveToEnd",
|
"ctrl-end": "editor::MoveToEnd",
|
||||||
|
|
|
@ -43,8 +43,8 @@
|
||||||
"ctrl-f12": "editor::GoToDefinitionSplit",
|
"ctrl-f12": "editor::GoToDefinitionSplit",
|
||||||
"shift-f12": "editor::FindAllReferences",
|
"shift-f12": "editor::FindAllReferences",
|
||||||
"ctrl-shift-f12": "editor::FindAllReferences",
|
"ctrl-shift-f12": "editor::FindAllReferences",
|
||||||
"ctrl-.": ["editor::GoToHunk", { "center_cursor": true }],
|
"ctrl-.": "editor::GoToHunk",
|
||||||
"ctrl-,": ["editor::GoToPreviousHunk", { "center_cursor": true }],
|
"ctrl-,": "editor::GoToPreviousHunk",
|
||||||
"ctrl-k ctrl-u": "editor::ConvertToUpperCase",
|
"ctrl-k ctrl-u": "editor::ConvertToUpperCase",
|
||||||
"ctrl-k ctrl-l": "editor::ConvertToLowerCase",
|
"ctrl-k ctrl-l": "editor::ConvertToLowerCase",
|
||||||
"shift-alt-m": "markdown::OpenPreviewToTheSide",
|
"shift-alt-m": "markdown::OpenPreviewToTheSide",
|
||||||
|
|
|
@ -40,8 +40,8 @@
|
||||||
"cmd-alt-shift-b": "editor::GoToTypeDefinitionSplit",
|
"cmd-alt-shift-b": "editor::GoToTypeDefinitionSplit",
|
||||||
"f2": "editor::GoToDiagnostic",
|
"f2": "editor::GoToDiagnostic",
|
||||||
"shift-f2": "editor::GoToPreviousDiagnostic",
|
"shift-f2": "editor::GoToPreviousDiagnostic",
|
||||||
"ctrl-alt-shift-down": ["editor::GoToHunk", { "center_cursor": true }],
|
"ctrl-alt-shift-down": "editor::GoToHunk",
|
||||||
"ctrl-alt-shift-up": ["editor::GoToPreviousHunk", { "center_cursor": true }],
|
"ctrl-alt-shift-up": "editor::GoToPreviousHunk",
|
||||||
"cmd-home": "editor::MoveToBeginning",
|
"cmd-home": "editor::MoveToBeginning",
|
||||||
"cmd-end": "editor::MoveToEnd",
|
"cmd-end": "editor::MoveToEnd",
|
||||||
"cmd-shift-home": "editor::SelectToBeginning",
|
"cmd-shift-home": "editor::SelectToBeginning",
|
||||||
|
|
|
@ -44,8 +44,8 @@
|
||||||
"alt-cmd-down": "editor::GoToDefinition",
|
"alt-cmd-down": "editor::GoToDefinition",
|
||||||
"ctrl-alt-cmd-down": "editor::GoToDefinitionSplit",
|
"ctrl-alt-cmd-down": "editor::GoToDefinitionSplit",
|
||||||
"alt-shift-cmd-down": "editor::FindAllReferences",
|
"alt-shift-cmd-down": "editor::FindAllReferences",
|
||||||
"ctrl-.": ["editor::GoToHunk", { "center_cursor": true }],
|
"ctrl-.": "editor::GoToHunk",
|
||||||
"ctrl-,": ["editor::GoToPreviousHunk", { "center_cursor": true }],
|
"ctrl-,": "editor::GoToPreviousHunk",
|
||||||
"cmd-k cmd-u": "editor::ConvertToUpperCase",
|
"cmd-k cmd-u": "editor::ConvertToUpperCase",
|
||||||
"cmd-k cmd-l": "editor::ConvertToLowerCase",
|
"cmd-k cmd-l": "editor::ConvertToLowerCase",
|
||||||
"cmd-shift-j": "editor::JoinLines",
|
"cmd-shift-j": "editor::JoinLines",
|
||||||
|
|
|
@ -238,8 +238,8 @@
|
||||||
"] x": "vim::SelectSmallerSyntaxNode",
|
"] x": "vim::SelectSmallerSyntaxNode",
|
||||||
"] d": "editor::GoToDiagnostic",
|
"] d": "editor::GoToDiagnostic",
|
||||||
"[ d": "editor::GoToPreviousDiagnostic",
|
"[ d": "editor::GoToPreviousDiagnostic",
|
||||||
"] c": ["editor::GoToHunk", { "center_cursor": true }],
|
"] c": "editor::GoToHunk",
|
||||||
"[ c": ["editor::GoToPreviousHunk", { "center_cursor": true }],
|
"[ c": "editor::GoToPreviousHunk",
|
||||||
"g c": "vim::PushToggleComments"
|
"g c": "vim::PushToggleComments"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -448,7 +448,10 @@
|
||||||
"d": "vim::CurrentLine",
|
"d": "vim::CurrentLine",
|
||||||
"s": "vim::PushDeleteSurrounds",
|
"s": "vim::PushDeleteSurrounds",
|
||||||
"o": "editor::ToggleSelectedDiffHunks", // "d o"
|
"o": "editor::ToggleSelectedDiffHunks", // "d o"
|
||||||
"p": "git::Restore" // "d p"
|
"shift-o": "git::ToggleStaged",
|
||||||
|
"p": "git::Restore", // "d p"
|
||||||
|
"u": "git::StageAndNext", // "d u"
|
||||||
|
"shift-u": "git::UnstageAndNext" // "d shift-u"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|
|
@ -196,20 +196,6 @@ pub struct DeleteToPreviousWordStart {
|
||||||
pub ignore_newlines: bool,
|
pub ignore_newlines: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(PartialEq, Clone, Deserialize, Default, JsonSchema)]
|
|
||||||
#[serde(deny_unknown_fields)]
|
|
||||||
pub struct GoToHunk {
|
|
||||||
#[serde(default)]
|
|
||||||
pub center_cursor: bool,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(PartialEq, Clone, Deserialize, Default, JsonSchema)]
|
|
||||||
#[serde(deny_unknown_fields)]
|
|
||||||
pub struct GoToPreviousHunk {
|
|
||||||
#[serde(default)]
|
|
||||||
pub center_cursor: bool,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(PartialEq, Clone, Deserialize, Default, JsonSchema)]
|
#[derive(PartialEq, Clone, Deserialize, Default, JsonSchema)]
|
||||||
pub struct FoldAtLevel(pub u32);
|
pub struct FoldAtLevel(pub u32);
|
||||||
|
|
||||||
|
@ -240,8 +226,6 @@ impl_actions!(
|
||||||
ExpandExcerptsDown,
|
ExpandExcerptsDown,
|
||||||
ExpandExcerptsUp,
|
ExpandExcerptsUp,
|
||||||
FoldAt,
|
FoldAt,
|
||||||
GoToHunk,
|
|
||||||
GoToPreviousHunk,
|
|
||||||
HandleInput,
|
HandleInput,
|
||||||
MoveDownByLines,
|
MoveDownByLines,
|
||||||
MovePageDown,
|
MovePageDown,
|
||||||
|
@ -323,6 +307,8 @@ gpui::actions!(
|
||||||
GoToDefinition,
|
GoToDefinition,
|
||||||
GoToDefinitionSplit,
|
GoToDefinitionSplit,
|
||||||
GoToDiagnostic,
|
GoToDiagnostic,
|
||||||
|
GoToHunk,
|
||||||
|
GoToPreviousHunk,
|
||||||
GoToImplementation,
|
GoToImplementation,
|
||||||
GoToImplementationSplit,
|
GoToImplementationSplit,
|
||||||
GoToPreviousDiagnostic,
|
GoToPreviousDiagnostic,
|
||||||
|
|
|
@ -73,7 +73,7 @@ use futures::{
|
||||||
};
|
};
|
||||||
use fuzzy::StringMatchCandidate;
|
use fuzzy::StringMatchCandidate;
|
||||||
|
|
||||||
use ::git::{status::FileStatus, Restore};
|
use ::git::Restore;
|
||||||
use code_context_menus::{
|
use code_context_menus::{
|
||||||
AvailableCodeAction, CodeActionContents, CodeActionsItem, CodeActionsMenu, CodeContextMenu,
|
AvailableCodeAction, CodeActionContents, CodeActionsItem, CodeActionsMenu, CodeContextMenu,
|
||||||
CompletionsMenu, ContextMenuOrigin,
|
CompletionsMenu, ContextMenuOrigin,
|
||||||
|
@ -11488,14 +11488,13 @@ impl Editor {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn go_to_next_hunk(&mut self, action: &GoToHunk, window: &mut Window, cx: &mut Context<Self>) {
|
fn go_to_next_hunk(&mut self, _: &GoToHunk, window: &mut Window, cx: &mut Context<Self>) {
|
||||||
let snapshot = self.snapshot(window, cx);
|
let snapshot = self.snapshot(window, cx);
|
||||||
let selection = self.selections.newest::<Point>(cx);
|
let selection = self.selections.newest::<Point>(cx);
|
||||||
self.go_to_hunk_after_or_before_position(
|
self.go_to_hunk_after_or_before_position(
|
||||||
&snapshot,
|
&snapshot,
|
||||||
selection.head(),
|
selection.head(),
|
||||||
true,
|
Direction::Next,
|
||||||
action.center_cursor,
|
|
||||||
window,
|
window,
|
||||||
cx,
|
cx,
|
||||||
);
|
);
|
||||||
|
@ -11505,12 +11504,11 @@ impl Editor {
|
||||||
&mut self,
|
&mut self,
|
||||||
snapshot: &EditorSnapshot,
|
snapshot: &EditorSnapshot,
|
||||||
position: Point,
|
position: Point,
|
||||||
after: bool,
|
direction: Direction,
|
||||||
scroll_center: bool,
|
|
||||||
window: &mut Window,
|
window: &mut Window,
|
||||||
cx: &mut Context<Editor>,
|
cx: &mut Context<Editor>,
|
||||||
) -> Option<MultiBufferDiffHunk> {
|
) -> Option<MultiBufferDiffHunk> {
|
||||||
let hunk = if after {
|
let hunk = if direction == Direction::Next {
|
||||||
self.hunk_after_position(snapshot, position)
|
self.hunk_after_position(snapshot, position)
|
||||||
} else {
|
} else {
|
||||||
self.hunk_before_position(snapshot, position)
|
self.hunk_before_position(snapshot, position)
|
||||||
|
@ -11518,11 +11516,7 @@ impl Editor {
|
||||||
|
|
||||||
if let Some(hunk) = &hunk {
|
if let Some(hunk) = &hunk {
|
||||||
let destination = Point::new(hunk.row_range.start.0, 0);
|
let destination = Point::new(hunk.row_range.start.0, 0);
|
||||||
let autoscroll = if scroll_center {
|
let autoscroll = Autoscroll::center();
|
||||||
Autoscroll::center()
|
|
||||||
} else {
|
|
||||||
Autoscroll::fit()
|
|
||||||
};
|
|
||||||
|
|
||||||
self.unfold_ranges(&[destination..destination], false, false, cx);
|
self.unfold_ranges(&[destination..destination], false, false, cx);
|
||||||
self.change_selections(Some(autoscroll), window, cx, |s| {
|
self.change_selections(Some(autoscroll), window, cx, |s| {
|
||||||
|
@ -11552,7 +11546,7 @@ impl Editor {
|
||||||
|
|
||||||
fn go_to_prev_hunk(
|
fn go_to_prev_hunk(
|
||||||
&mut self,
|
&mut self,
|
||||||
action: &GoToPreviousHunk,
|
_: &GoToPreviousHunk,
|
||||||
window: &mut Window,
|
window: &mut Window,
|
||||||
cx: &mut Context<Self>,
|
cx: &mut Context<Self>,
|
||||||
) {
|
) {
|
||||||
|
@ -11561,8 +11555,7 @@ impl Editor {
|
||||||
self.go_to_hunk_after_or_before_position(
|
self.go_to_hunk_after_or_before_position(
|
||||||
&snapshot,
|
&snapshot,
|
||||||
selection.head(),
|
selection.head(),
|
||||||
false,
|
Direction::Prev,
|
||||||
action.center_cursor,
|
|
||||||
window,
|
window,
|
||||||
cx,
|
cx,
|
||||||
);
|
);
|
||||||
|
@ -13639,20 +13632,20 @@ impl Editor {
|
||||||
|
|
||||||
pub fn stage_and_next(
|
pub fn stage_and_next(
|
||||||
&mut self,
|
&mut self,
|
||||||
action: &::git::StageAndNext,
|
_: &::git::StageAndNext,
|
||||||
window: &mut Window,
|
window: &mut Window,
|
||||||
cx: &mut Context<Self>,
|
cx: &mut Context<Self>,
|
||||||
) {
|
) {
|
||||||
self.do_stage_or_unstage_and_next(true, action.whole_excerpt, window, cx);
|
self.do_stage_or_unstage_and_next(true, window, cx);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn unstage_and_next(
|
pub fn unstage_and_next(
|
||||||
&mut self,
|
&mut self,
|
||||||
action: &::git::UnstageAndNext,
|
_: &::git::UnstageAndNext,
|
||||||
window: &mut Window,
|
window: &mut Window,
|
||||||
cx: &mut Context<Self>,
|
cx: &mut Context<Self>,
|
||||||
) {
|
) {
|
||||||
self.do_stage_or_unstage_and_next(false, action.whole_excerpt, window, cx);
|
self.do_stage_or_unstage_and_next(false, window, cx);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn stage_or_unstage_diff_hunks(
|
pub fn stage_or_unstage_diff_hunks(
|
||||||
|
@ -13674,102 +13667,33 @@ impl Editor {
|
||||||
fn do_stage_or_unstage_and_next(
|
fn do_stage_or_unstage_and_next(
|
||||||
&mut self,
|
&mut self,
|
||||||
stage: bool,
|
stage: bool,
|
||||||
whole_excerpt: bool,
|
|
||||||
window: &mut Window,
|
window: &mut Window,
|
||||||
cx: &mut Context<Self>,
|
cx: &mut Context<Self>,
|
||||||
) {
|
) {
|
||||||
let mut ranges = self.selections.disjoint_anchor_ranges().collect::<Vec<_>>();
|
let ranges = self.selections.disjoint_anchor_ranges().collect::<Vec<_>>();
|
||||||
|
|
||||||
if ranges.iter().any(|range| range.start != range.end) {
|
if ranges.iter().any(|range| range.start != range.end) {
|
||||||
self.stage_or_unstage_diff_hunks(stage, &ranges[..], window, cx);
|
self.stage_or_unstage_diff_hunks(stage, &ranges[..], window, cx);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if !whole_excerpt {
|
let snapshot = self.snapshot(window, cx);
|
||||||
let snapshot = self.snapshot(window, cx);
|
let newest_range = self.selections.newest::<Point>(cx).range();
|
||||||
let newest_range = self.selections.newest::<Point>(cx).range();
|
|
||||||
|
|
||||||
let run_twice = snapshot
|
let run_twice = snapshot
|
||||||
.hunks_for_ranges([newest_range])
|
.hunks_for_ranges([newest_range])
|
||||||
.first()
|
.first()
|
||||||
.is_some_and(|hunk| {
|
.is_some_and(|hunk| {
|
||||||
let next_line = Point::new(hunk.row_range.end.0 + 1, 0);
|
let next_line = Point::new(hunk.row_range.end.0 + 1, 0);
|
||||||
self.hunk_after_position(&snapshot, next_line)
|
self.hunk_after_position(&snapshot, next_line)
|
||||||
.is_some_and(|other| other.row_range == hunk.row_range)
|
.is_some_and(|other| other.row_range == hunk.row_range)
|
||||||
});
|
});
|
||||||
|
|
||||||
if run_twice {
|
if run_twice {
|
||||||
self.go_to_next_hunk(
|
self.go_to_next_hunk(&GoToHunk, window, cx);
|
||||||
&GoToHunk {
|
|
||||||
center_cursor: true,
|
|
||||||
},
|
|
||||||
window,
|
|
||||||
cx,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
} else if !self.buffer().read(cx).is_singleton() {
|
|
||||||
self.stage_or_unstage_diff_hunks(stage, &ranges[..], window, cx);
|
|
||||||
|
|
||||||
if let Some((excerpt_id, buffer, range)) = self.active_excerpt(cx) {
|
|
||||||
if buffer.read(cx).is_empty() {
|
|
||||||
let buffer = buffer.read(cx);
|
|
||||||
let Some(file) = buffer.file() else {
|
|
||||||
return;
|
|
||||||
};
|
|
||||||
let project_path = project::ProjectPath {
|
|
||||||
worktree_id: file.worktree_id(cx),
|
|
||||||
path: file.path().clone(),
|
|
||||||
};
|
|
||||||
let Some(project) = self.project.as_ref() else {
|
|
||||||
return;
|
|
||||||
};
|
|
||||||
|
|
||||||
let Some(repo) = project.read(cx).git_store().read(cx).active_repository()
|
|
||||||
else {
|
|
||||||
return;
|
|
||||||
};
|
|
||||||
|
|
||||||
repo.update(cx, |repo, cx| {
|
|
||||||
let Some(repo_path) = repo.project_path_to_repo_path(&project_path) else {
|
|
||||||
return;
|
|
||||||
};
|
|
||||||
let Some(status) = repo.repository_entry.status_for_path(&repo_path) else {
|
|
||||||
return;
|
|
||||||
};
|
|
||||||
if stage && status.status == FileStatus::Untracked {
|
|
||||||
repo.stage_entries(vec![repo_path], cx)
|
|
||||||
.detach_and_log_err(cx);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
ranges = vec![multi_buffer::Anchor::range_in_buffer(
|
|
||||||
excerpt_id,
|
|
||||||
buffer.read(cx).remote_id(),
|
|
||||||
range,
|
|
||||||
)];
|
|
||||||
self.stage_or_unstage_diff_hunks(stage, &ranges[..], window, cx);
|
|
||||||
let snapshot = self.buffer().read(cx).snapshot(cx);
|
|
||||||
let mut point = ranges.last().unwrap().end.to_point(&snapshot);
|
|
||||||
if point.row < snapshot.max_row().0 {
|
|
||||||
point.row += 1;
|
|
||||||
point.column = 0;
|
|
||||||
point = snapshot.clip_point(point, Bias::Right);
|
|
||||||
self.change_selections(Some(Autoscroll::top_relative(6)), window, cx, |s| {
|
|
||||||
s.select_ranges([point..point]);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
self.stage_or_unstage_diff_hunks(stage, &ranges[..], window, cx);
|
self.stage_or_unstage_diff_hunks(stage, &ranges[..], window, cx);
|
||||||
self.go_to_next_hunk(
|
self.go_to_next_hunk(&GoToHunk, window, cx);
|
||||||
&GoToHunk {
|
|
||||||
center_cursor: true,
|
|
||||||
},
|
|
||||||
window,
|
|
||||||
cx,
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn do_stage_or_unstage(
|
fn do_stage_or_unstage(
|
||||||
|
|
|
@ -11413,7 +11413,7 @@ async fn test_go_to_hunk(executor: BackgroundExecutor, cx: &mut TestAppContext)
|
||||||
cx.update_editor(|editor, window, cx| {
|
cx.update_editor(|editor, window, cx| {
|
||||||
//Wrap around the bottom of the buffer
|
//Wrap around the bottom of the buffer
|
||||||
for _ in 0..3 {
|
for _ in 0..3 {
|
||||||
editor.go_to_next_hunk(&GoToHunk::default(), window, cx);
|
editor.go_to_next_hunk(&GoToHunk, window, cx);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -11435,7 +11435,7 @@ async fn test_go_to_hunk(executor: BackgroundExecutor, cx: &mut TestAppContext)
|
||||||
cx.update_editor(|editor, window, cx| {
|
cx.update_editor(|editor, window, cx| {
|
||||||
//Wrap around the top of the buffer
|
//Wrap around the top of the buffer
|
||||||
for _ in 0..2 {
|
for _ in 0..2 {
|
||||||
editor.go_to_prev_hunk(&GoToPreviousHunk::default(), window, cx);
|
editor.go_to_prev_hunk(&GoToPreviousHunk, window, cx);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -11455,7 +11455,7 @@ async fn test_go_to_hunk(executor: BackgroundExecutor, cx: &mut TestAppContext)
|
||||||
);
|
);
|
||||||
|
|
||||||
cx.update_editor(|editor, window, cx| {
|
cx.update_editor(|editor, window, cx| {
|
||||||
editor.go_to_prev_hunk(&GoToPreviousHunk::default(), window, cx);
|
editor.go_to_prev_hunk(&GoToPreviousHunk, window, cx);
|
||||||
});
|
});
|
||||||
|
|
||||||
cx.assert_editor_state(
|
cx.assert_editor_state(
|
||||||
|
@ -11474,7 +11474,7 @@ async fn test_go_to_hunk(executor: BackgroundExecutor, cx: &mut TestAppContext)
|
||||||
);
|
);
|
||||||
|
|
||||||
cx.update_editor(|editor, window, cx| {
|
cx.update_editor(|editor, window, cx| {
|
||||||
editor.go_to_prev_hunk(&GoToPreviousHunk::default(), window, cx);
|
editor.go_to_prev_hunk(&GoToPreviousHunk, window, cx);
|
||||||
});
|
});
|
||||||
|
|
||||||
cx.assert_editor_state(
|
cx.assert_editor_state(
|
||||||
|
@ -11494,7 +11494,7 @@ async fn test_go_to_hunk(executor: BackgroundExecutor, cx: &mut TestAppContext)
|
||||||
|
|
||||||
cx.update_editor(|editor, window, cx| {
|
cx.update_editor(|editor, window, cx| {
|
||||||
for _ in 0..2 {
|
for _ in 0..2 {
|
||||||
editor.go_to_prev_hunk(&GoToPreviousHunk::default(), window, cx);
|
editor.go_to_prev_hunk(&GoToPreviousHunk, window, cx);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -11518,7 +11518,7 @@ async fn test_go_to_hunk(executor: BackgroundExecutor, cx: &mut TestAppContext)
|
||||||
});
|
});
|
||||||
|
|
||||||
cx.update_editor(|editor, window, cx| {
|
cx.update_editor(|editor, window, cx| {
|
||||||
editor.go_to_next_hunk(&GoToHunk::default(), window, cx);
|
editor.go_to_next_hunk(&GoToHunk, window, cx);
|
||||||
});
|
});
|
||||||
|
|
||||||
cx.assert_editor_state(
|
cx.assert_editor_state(
|
||||||
|
@ -13525,7 +13525,7 @@ async fn test_toggle_selected_diff_hunks(executor: BackgroundExecutor, cx: &mut
|
||||||
executor.run_until_parked();
|
executor.run_until_parked();
|
||||||
|
|
||||||
cx.update_editor(|editor, window, cx| {
|
cx.update_editor(|editor, window, cx| {
|
||||||
editor.go_to_next_hunk(&GoToHunk::default(), window, cx);
|
editor.go_to_next_hunk(&GoToHunk, window, cx);
|
||||||
editor.toggle_selected_diff_hunks(&ToggleSelectedDiffHunks, window, cx);
|
editor.toggle_selected_diff_hunks(&ToggleSelectedDiffHunks, window, cx);
|
||||||
});
|
});
|
||||||
executor.run_until_parked();
|
executor.run_until_parked();
|
||||||
|
@ -13547,7 +13547,7 @@ async fn test_toggle_selected_diff_hunks(executor: BackgroundExecutor, cx: &mut
|
||||||
|
|
||||||
cx.update_editor(|editor, window, cx| {
|
cx.update_editor(|editor, window, cx| {
|
||||||
for _ in 0..2 {
|
for _ in 0..2 {
|
||||||
editor.go_to_next_hunk(&GoToHunk::default(), window, cx);
|
editor.go_to_next_hunk(&GoToHunk, window, cx);
|
||||||
editor.toggle_selected_diff_hunks(&ToggleSelectedDiffHunks, window, cx);
|
editor.toggle_selected_diff_hunks(&ToggleSelectedDiffHunks, window, cx);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -13570,7 +13570,7 @@ async fn test_toggle_selected_diff_hunks(executor: BackgroundExecutor, cx: &mut
|
||||||
);
|
);
|
||||||
|
|
||||||
cx.update_editor(|editor, window, cx| {
|
cx.update_editor(|editor, window, cx| {
|
||||||
editor.go_to_next_hunk(&GoToHunk::default(), window, cx);
|
editor.go_to_next_hunk(&GoToHunk, window, cx);
|
||||||
editor.toggle_selected_diff_hunks(&ToggleSelectedDiffHunks, window, cx);
|
editor.toggle_selected_diff_hunks(&ToggleSelectedDiffHunks, window, cx);
|
||||||
});
|
});
|
||||||
executor.run_until_parked();
|
executor.run_until_parked();
|
||||||
|
|
|
@ -42,6 +42,7 @@ use gpui::{
|
||||||
SharedString, Size, StatefulInteractiveElement, Style, Styled, Subscription, TextRun,
|
SharedString, Size, StatefulInteractiveElement, Style, Styled, Subscription, TextRun,
|
||||||
TextStyleRefinement, Window,
|
TextStyleRefinement, Window,
|
||||||
};
|
};
|
||||||
|
use inline_completion::Direction;
|
||||||
use itertools::Itertools;
|
use itertools::Itertools;
|
||||||
use language::{
|
use language::{
|
||||||
language_settings::{
|
language_settings::{
|
||||||
|
@ -8906,7 +8907,7 @@ fn diff_hunk_controls(
|
||||||
move |window, cx| {
|
move |window, cx| {
|
||||||
Tooltip::for_action_in(
|
Tooltip::for_action_in(
|
||||||
"Next Hunk",
|
"Next Hunk",
|
||||||
&GoToHunk::default(),
|
&GoToHunk,
|
||||||
&focus_handle,
|
&focus_handle,
|
||||||
window,
|
window,
|
||||||
cx,
|
cx,
|
||||||
|
@ -8921,7 +8922,11 @@ fn diff_hunk_controls(
|
||||||
let position =
|
let position =
|
||||||
hunk_range.end.to_point(&snapshot.buffer_snapshot);
|
hunk_range.end.to_point(&snapshot.buffer_snapshot);
|
||||||
editor.go_to_hunk_after_or_before_position(
|
editor.go_to_hunk_after_or_before_position(
|
||||||
&snapshot, position, true, true, window, cx,
|
&snapshot,
|
||||||
|
position,
|
||||||
|
Direction::Next,
|
||||||
|
window,
|
||||||
|
cx,
|
||||||
);
|
);
|
||||||
editor.expand_selected_diff_hunks(cx);
|
editor.expand_selected_diff_hunks(cx);
|
||||||
});
|
});
|
||||||
|
@ -8938,7 +8943,7 @@ fn diff_hunk_controls(
|
||||||
move |window, cx| {
|
move |window, cx| {
|
||||||
Tooltip::for_action_in(
|
Tooltip::for_action_in(
|
||||||
"Previous Hunk",
|
"Previous Hunk",
|
||||||
&GoToPreviousHunk::default(),
|
&GoToPreviousHunk,
|
||||||
&focus_handle,
|
&focus_handle,
|
||||||
window,
|
window,
|
||||||
cx,
|
cx,
|
||||||
|
@ -8953,7 +8958,11 @@ fn diff_hunk_controls(
|
||||||
let point =
|
let point =
|
||||||
hunk_range.start.to_point(&snapshot.buffer_snapshot);
|
hunk_range.start.to_point(&snapshot.buffer_snapshot);
|
||||||
editor.go_to_hunk_after_or_before_position(
|
editor.go_to_hunk_after_or_before_position(
|
||||||
&snapshot, point, false, true, window, cx,
|
&snapshot,
|
||||||
|
point,
|
||||||
|
Direction::Prev,
|
||||||
|
window,
|
||||||
|
cx,
|
||||||
);
|
);
|
||||||
editor.expand_selected_diff_hunks(cx);
|
editor.expand_selected_diff_hunks(cx);
|
||||||
});
|
});
|
||||||
|
|
|
@ -36,23 +36,15 @@ pub struct Push {
|
||||||
pub options: Option<PushOptions>,
|
pub options: Option<PushOptions>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Copy, Clone, PartialEq, Deserialize, JsonSchema)]
|
impl_actions!(git, [Push]);
|
||||||
pub struct StageAndNext {
|
|
||||||
pub whole_excerpt: bool,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, Copy, Clone, PartialEq, Deserialize, JsonSchema)]
|
|
||||||
pub struct UnstageAndNext {
|
|
||||||
pub whole_excerpt: bool,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl_actions!(git, [Push, StageAndNext, UnstageAndNext]);
|
|
||||||
|
|
||||||
actions!(
|
actions!(
|
||||||
git,
|
git,
|
||||||
[
|
[
|
||||||
// per-hunk
|
// per-hunk
|
||||||
ToggleStaged,
|
ToggleStaged,
|
||||||
|
StageAndNext,
|
||||||
|
UnstageAndNext,
|
||||||
// per-file
|
// per-file
|
||||||
StageFile,
|
StageFile,
|
||||||
UnstageFile,
|
UnstageFile,
|
||||||
|
|
|
@ -812,10 +812,8 @@ impl Render for ProjectDiffToolbar {
|
||||||
el.child(
|
el.child(
|
||||||
Button::new("stage", "Stage")
|
Button::new("stage", "Stage")
|
||||||
.tooltip(Tooltip::for_action_title_in(
|
.tooltip(Tooltip::for_action_title_in(
|
||||||
"Stage",
|
"Stage and go to next hunk",
|
||||||
&StageAndNext {
|
&StageAndNext,
|
||||||
whole_excerpt: false,
|
|
||||||
},
|
|
||||||
&focus_handle,
|
&focus_handle,
|
||||||
))
|
))
|
||||||
// don't actually disable the button so it's mashable
|
// don't actually disable the button so it's mashable
|
||||||
|
@ -825,22 +823,14 @@ impl Render for ProjectDiffToolbar {
|
||||||
Color::Disabled
|
Color::Disabled
|
||||||
})
|
})
|
||||||
.on_click(cx.listener(|this, _, window, cx| {
|
.on_click(cx.listener(|this, _, window, cx| {
|
||||||
this.dispatch_action(
|
this.dispatch_action(&StageAndNext, window, cx)
|
||||||
&StageAndNext {
|
|
||||||
whole_excerpt: false,
|
|
||||||
},
|
|
||||||
window,
|
|
||||||
cx,
|
|
||||||
)
|
|
||||||
})),
|
})),
|
||||||
)
|
)
|
||||||
.child(
|
.child(
|
||||||
Button::new("unstage", "Unstage")
|
Button::new("unstage", "Unstage")
|
||||||
.tooltip(Tooltip::for_action_title_in(
|
.tooltip(Tooltip::for_action_title_in(
|
||||||
"Unstage",
|
"Unstage and go to next hunk",
|
||||||
&UnstageAndNext {
|
&UnstageAndNext,
|
||||||
whole_excerpt: false,
|
|
||||||
},
|
|
||||||
&focus_handle,
|
&focus_handle,
|
||||||
))
|
))
|
||||||
.color(if button_states.unstage {
|
.color(if button_states.unstage {
|
||||||
|
@ -849,13 +839,7 @@ impl Render for ProjectDiffToolbar {
|
||||||
Color::Disabled
|
Color::Disabled
|
||||||
})
|
})
|
||||||
.on_click(cx.listener(|this, _, window, cx| {
|
.on_click(cx.listener(|this, _, window, cx| {
|
||||||
this.dispatch_action(
|
this.dispatch_action(&UnstageAndNext, window, cx)
|
||||||
&UnstageAndNext {
|
|
||||||
whole_excerpt: false,
|
|
||||||
},
|
|
||||||
window,
|
|
||||||
cx,
|
|
||||||
)
|
|
||||||
})),
|
})),
|
||||||
)
|
)
|
||||||
}),
|
}),
|
||||||
|
@ -869,20 +853,12 @@ impl Render for ProjectDiffToolbar {
|
||||||
.shape(ui::IconButtonShape::Square)
|
.shape(ui::IconButtonShape::Square)
|
||||||
.tooltip(Tooltip::for_action_title_in(
|
.tooltip(Tooltip::for_action_title_in(
|
||||||
"Go to previous hunk",
|
"Go to previous hunk",
|
||||||
&GoToPreviousHunk {
|
&GoToPreviousHunk,
|
||||||
center_cursor: false,
|
|
||||||
},
|
|
||||||
&focus_handle,
|
&focus_handle,
|
||||||
))
|
))
|
||||||
.disabled(!button_states.prev_next)
|
.disabled(!button_states.prev_next)
|
||||||
.on_click(cx.listener(|this, _, window, cx| {
|
.on_click(cx.listener(|this, _, window, cx| {
|
||||||
this.dispatch_action(
|
this.dispatch_action(&GoToPreviousHunk, window, cx)
|
||||||
&GoToPreviousHunk {
|
|
||||||
center_cursor: true,
|
|
||||||
},
|
|
||||||
window,
|
|
||||||
cx,
|
|
||||||
)
|
|
||||||
})),
|
})),
|
||||||
)
|
)
|
||||||
.child(
|
.child(
|
||||||
|
@ -890,20 +866,12 @@ impl Render for ProjectDiffToolbar {
|
||||||
.shape(ui::IconButtonShape::Square)
|
.shape(ui::IconButtonShape::Square)
|
||||||
.tooltip(Tooltip::for_action_title_in(
|
.tooltip(Tooltip::for_action_title_in(
|
||||||
"Go to next hunk",
|
"Go to next hunk",
|
||||||
&GoToHunk {
|
&GoToHunk,
|
||||||
center_cursor: false,
|
|
||||||
},
|
|
||||||
&focus_handle,
|
&focus_handle,
|
||||||
))
|
))
|
||||||
.disabled(!button_states.prev_next)
|
.disabled(!button_states.prev_next)
|
||||||
.on_click(cx.listener(|this, _, window, cx| {
|
.on_click(cx.listener(|this, _, window, cx| {
|
||||||
this.dispatch_action(
|
this.dispatch_action(&GoToHunk, window, cx)
|
||||||
&GoToHunk {
|
|
||||||
center_cursor: true,
|
|
||||||
},
|
|
||||||
window,
|
|
||||||
cx,
|
|
||||||
)
|
|
||||||
})),
|
})),
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
|
|
@ -182,18 +182,8 @@ impl Render for QuickActionBar {
|
||||||
.action("Next Problem", Box::new(GoToDiagnostic))
|
.action("Next Problem", Box::new(GoToDiagnostic))
|
||||||
.action("Previous Problem", Box::new(GoToPreviousDiagnostic))
|
.action("Previous Problem", Box::new(GoToPreviousDiagnostic))
|
||||||
.separator()
|
.separator()
|
||||||
.action(
|
.action("Next Hunk", Box::new(GoToHunk))
|
||||||
"Next Hunk",
|
.action("Previous Hunk", Box::new(GoToPreviousHunk))
|
||||||
Box::new(GoToHunk {
|
|
||||||
center_cursor: true,
|
|
||||||
}),
|
|
||||||
)
|
|
||||||
.action(
|
|
||||||
"Previous Hunk",
|
|
||||||
Box::new(GoToPreviousHunk {
|
|
||||||
center_cursor: true,
|
|
||||||
}),
|
|
||||||
)
|
|
||||||
.separator()
|
.separator()
|
||||||
.action("Move Line Up", Box::new(MoveLineUp))
|
.action("Move Line Up", Box::new(MoveLineUp))
|
||||||
.action("Move Line Down", Box::new(MoveLineDown))
|
.action("Move Line Down", Box::new(MoveLineDown))
|
||||||
|
|
|
@ -10,6 +10,12 @@ To preview the docs locally you will need to install [mdBook](https://rust-lang.
|
||||||
mdbook serve docs
|
mdbook serve docs
|
||||||
```
|
```
|
||||||
|
|
||||||
|
Before committing, verify that the docs are formatted in the way prettier expects with:
|
||||||
|
|
||||||
|
```
|
||||||
|
cd docs && pnpm dlx prettier@3.5.0 . --write && cd ..
|
||||||
|
```
|
||||||
|
|
||||||
## Preprocessor
|
## Preprocessor
|
||||||
|
|
||||||
We have a custom mdbook preprocessor for interfacing with our crates (`crates/docs_preprocessor`).
|
We have a custom mdbook preprocessor for interfacing with our crates (`crates/docs_preprocessor`).
|
||||||
|
|
|
@ -72,10 +72,15 @@ The following commands use the language server to help you navigate and refactor
|
||||||
|
|
||||||
### Git
|
### Git
|
||||||
|
|
||||||
| Command | Default Shortcut |
|
| Command | Default Shortcut |
|
||||||
| ------------------------- | ---------------- |
|
| ------------------------------- | ---------------- |
|
||||||
| Go to next git change | `] c` |
|
| Go to next git change | `] c` |
|
||||||
| Go to previous git change | `[ c` |
|
| Go to previous git change | `[ c` |
|
||||||
|
| Expand diff hunk | `d o` |
|
||||||
|
| Toggle staged | `d O` |
|
||||||
|
| Stage and next (in diff view) | `d u` |
|
||||||
|
| Unstage and next (in diff view) | `d U` |
|
||||||
|
| Restore change | `d p` |
|
||||||
|
|
||||||
### Treesitter
|
### Treesitter
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue