mirror of
https://github.com/extrawurst/gitui.git
synced 2024-11-22 11:03:25 +03:00
add fuzzy finder in branch list (#1658)
* add branch_find_popup * capital F for fetch in branchlist, f for find * add command info of return closes #1350
This commit is contained in:
parent
a921ab543b
commit
3a6f292bf5
20
src/app.rs
20
src/app.rs
@ -2,7 +2,7 @@ use crate::{
|
||||
accessors,
|
||||
cmdbar::CommandBar,
|
||||
components::{
|
||||
event_pump, AppOption, BlameFileComponent,
|
||||
event_pump, AppOption, BlameFileComponent, BranchFindPopup,
|
||||
BranchListComponent, CommandBlocking, CommandInfo,
|
||||
CommitComponent, CompareCommitsComponent, Component,
|
||||
ConfirmComponent, CreateBranchComponent, DrawableComponent,
|
||||
@ -73,6 +73,7 @@ pub struct App {
|
||||
external_editor_popup: ExternalEditorComponent,
|
||||
revision_files_popup: RevisionFilesPopup,
|
||||
find_file_popup: FileFindPopup,
|
||||
branch_find_popup: BranchFindPopup,
|
||||
push_popup: PushComponent,
|
||||
push_tags_popup: PushTagsComponent,
|
||||
pull_popup: PullComponent,
|
||||
@ -273,6 +274,11 @@ impl App {
|
||||
theme.clone(),
|
||||
key_config.clone(),
|
||||
),
|
||||
branch_find_popup: BranchFindPopup::new(
|
||||
&queue,
|
||||
theme.clone(),
|
||||
key_config.clone(),
|
||||
),
|
||||
do_quit: QuitState::None,
|
||||
cmdbar: RefCell::new(CommandBar::new(
|
||||
theme.clone(),
|
||||
@ -578,6 +584,7 @@ impl App {
|
||||
self,
|
||||
[
|
||||
find_file_popup,
|
||||
branch_find_popup,
|
||||
msg,
|
||||
reset,
|
||||
commit,
|
||||
@ -629,6 +636,7 @@ impl App {
|
||||
rename_branch_popup,
|
||||
revision_files_popup,
|
||||
find_file_popup,
|
||||
branch_find_popup,
|
||||
push_popup,
|
||||
push_tags_popup,
|
||||
pull_popup,
|
||||
@ -892,6 +900,11 @@ impl App {
|
||||
flags
|
||||
.insert(NeedsUpdate::ALL | NeedsUpdate::COMMANDS);
|
||||
}
|
||||
InternalEvent::OpenBranchFinder(branches) => {
|
||||
self.branch_find_popup.open(branches)?;
|
||||
flags
|
||||
.insert(NeedsUpdate::ALL | NeedsUpdate::COMMANDS);
|
||||
}
|
||||
InternalEvent::OptionSwitched(o) => {
|
||||
match o {
|
||||
AppOption::StatusShowUntracked => {
|
||||
@ -912,6 +925,11 @@ impl App {
|
||||
flags
|
||||
.insert(NeedsUpdate::ALL | NeedsUpdate::COMMANDS);
|
||||
}
|
||||
InternalEvent::BranchFinderChanged(idx) => {
|
||||
self.select_branch_popup.branch_finder_update(idx)?;
|
||||
flags
|
||||
.insert(NeedsUpdate::ALL | NeedsUpdate::COMMANDS);
|
||||
}
|
||||
InternalEvent::OpenPopup(popup) => {
|
||||
self.open_popup(popup)?;
|
||||
flags
|
||||
|
339
src/components/branch_find_popup.rs
Normal file
339
src/components/branch_find_popup.rs
Normal file
@ -0,0 +1,339 @@
|
||||
use super::{
|
||||
visibility_blocking, CommandBlocking, CommandInfo, Component,
|
||||
DrawableComponent, EventState, ScrollType, TextInputComponent,
|
||||
};
|
||||
use crate::{
|
||||
keys::{key_match, SharedKeyConfig},
|
||||
queue::{InternalEvent, Queue},
|
||||
string_utils::trim_length_left,
|
||||
strings,
|
||||
ui::{self, style::SharedTheme},
|
||||
};
|
||||
use anyhow::Result;
|
||||
use crossterm::event::Event;
|
||||
use fuzzy_matcher::FuzzyMatcher;
|
||||
use ratatui::{
|
||||
backend::Backend,
|
||||
layout::{Constraint, Direction, Layout, Margin, Rect},
|
||||
text::{Span, Spans},
|
||||
widgets::{Block, Borders, Clear},
|
||||
Frame,
|
||||
};
|
||||
use std::borrow::Cow;
|
||||
|
||||
pub struct BranchFindPopup {
|
||||
queue: Queue,
|
||||
visible: bool,
|
||||
find_text: TextInputComponent,
|
||||
query: Option<String>,
|
||||
theme: SharedTheme,
|
||||
branches: Vec<String>,
|
||||
selection: usize,
|
||||
selected_index: Option<usize>,
|
||||
branches_filtered: Vec<(usize, Vec<usize>)>,
|
||||
key_config: SharedKeyConfig,
|
||||
}
|
||||
|
||||
impl BranchFindPopup {
|
||||
///
|
||||
pub fn new(
|
||||
queue: &Queue,
|
||||
theme: SharedTheme,
|
||||
key_config: SharedKeyConfig,
|
||||
) -> Self {
|
||||
let mut find_text = TextInputComponent::new(
|
||||
theme.clone(),
|
||||
key_config.clone(),
|
||||
"",
|
||||
"start typing..",
|
||||
false,
|
||||
);
|
||||
find_text.embed();
|
||||
|
||||
Self {
|
||||
queue: queue.clone(),
|
||||
visible: false,
|
||||
query: None,
|
||||
find_text,
|
||||
theme,
|
||||
branches: Vec::new(),
|
||||
branches_filtered: Vec::new(),
|
||||
selected_index: None,
|
||||
key_config,
|
||||
selection: 0,
|
||||
}
|
||||
}
|
||||
|
||||
fn update_query(&mut self) {
|
||||
if self.find_text.get_text().is_empty() {
|
||||
self.set_query(None);
|
||||
} else if self
|
||||
.query
|
||||
.as_ref()
|
||||
.map_or(true, |q| q != self.find_text.get_text())
|
||||
{
|
||||
self.set_query(Some(
|
||||
self.find_text.get_text().to_string(),
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
fn set_query(&mut self, query: Option<String>) {
|
||||
self.query = query;
|
||||
|
||||
self.branches_filtered.clear();
|
||||
|
||||
if let Some(q) = &self.query {
|
||||
let matcher =
|
||||
fuzzy_matcher::skim::SkimMatcherV2::default();
|
||||
|
||||
let mut branches = self
|
||||
.branches
|
||||
.iter()
|
||||
.enumerate()
|
||||
.filter_map(|a| {
|
||||
matcher
|
||||
.fuzzy_indices(a.1, q)
|
||||
.map(|(score, indices)| (score, a.0, indices))
|
||||
})
|
||||
.collect::<Vec<(_, _, _)>>();
|
||||
|
||||
branches.sort_by(|(score1, _, _), (score2, _, _)| {
|
||||
score2.cmp(score1)
|
||||
});
|
||||
|
||||
self.branches_filtered.extend(
|
||||
branches.into_iter().map(|entry| (entry.1, entry.2)),
|
||||
);
|
||||
}
|
||||
|
||||
self.selection = 0;
|
||||
self.refresh_selection();
|
||||
}
|
||||
|
||||
fn refresh_selection(&mut self) {
|
||||
let selection =
|
||||
self.branches_filtered.get(self.selection).map(|a| a.0);
|
||||
|
||||
if self.selected_index != selection {
|
||||
self.selected_index = selection;
|
||||
|
||||
let idx = self.selected_index;
|
||||
self.queue.push(InternalEvent::BranchFinderChanged(idx));
|
||||
}
|
||||
}
|
||||
|
||||
pub fn open(&mut self, branches: Vec<String>) -> Result<()> {
|
||||
self.show()?;
|
||||
self.find_text.show()?;
|
||||
self.find_text.set_text(String::new());
|
||||
self.query = None;
|
||||
if self.branches != branches {
|
||||
self.branches = branches;
|
||||
}
|
||||
self.update_query();
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn move_selection(&mut self, move_type: ScrollType) -> bool {
|
||||
let new_selection = match move_type {
|
||||
ScrollType::Up => self.selection.saturating_sub(1),
|
||||
ScrollType::Down => self.selection.saturating_add(1),
|
||||
_ => self.selection,
|
||||
};
|
||||
|
||||
let new_selection = new_selection
|
||||
.clamp(0, self.branches_filtered.len().saturating_sub(1));
|
||||
|
||||
if new_selection != self.selection {
|
||||
self.selection = new_selection;
|
||||
self.refresh_selection();
|
||||
return true;
|
||||
}
|
||||
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
impl DrawableComponent for BranchFindPopup {
|
||||
fn draw<B: Backend>(
|
||||
&self,
|
||||
f: &mut Frame<B>,
|
||||
area: Rect,
|
||||
) -> Result<()> {
|
||||
if self.is_visible() {
|
||||
const MAX_SIZE: (u16, u16) = (50, 20);
|
||||
|
||||
let any_hits = !self.branches_filtered.is_empty();
|
||||
|
||||
let area = ui::centered_rect_absolute(
|
||||
MAX_SIZE.0, MAX_SIZE.1, area,
|
||||
);
|
||||
|
||||
let area = if any_hits {
|
||||
area
|
||||
} else {
|
||||
Layout::default()
|
||||
.direction(Direction::Vertical)
|
||||
.constraints(
|
||||
[
|
||||
Constraint::Length(3),
|
||||
Constraint::Percentage(100),
|
||||
]
|
||||
.as_ref(),
|
||||
)
|
||||
.split(area)[0]
|
||||
};
|
||||
|
||||
f.render_widget(Clear, area);
|
||||
f.render_widget(
|
||||
Block::default()
|
||||
.borders(Borders::all())
|
||||
.style(self.theme.title(true))
|
||||
.title(Span::styled(
|
||||
strings::POPUP_TITLE_FUZZY_FIND,
|
||||
self.theme.title(true),
|
||||
)),
|
||||
area,
|
||||
);
|
||||
|
||||
let chunks = Layout::default()
|
||||
.direction(Direction::Vertical)
|
||||
.constraints(
|
||||
[
|
||||
Constraint::Length(1),
|
||||
Constraint::Percentage(100),
|
||||
]
|
||||
.as_ref(),
|
||||
)
|
||||
.split(area.inner(&Margin {
|
||||
horizontal: 1,
|
||||
vertical: 1,
|
||||
}));
|
||||
|
||||
self.find_text.draw(f, chunks[0])?;
|
||||
|
||||
if any_hits {
|
||||
let title =
|
||||
format!("Hits: {}", self.branches_filtered.len());
|
||||
|
||||
let height = usize::from(chunks[1].height);
|
||||
let width = usize::from(chunks[1].width);
|
||||
|
||||
let items = self
|
||||
.branches_filtered
|
||||
.iter()
|
||||
.take(height)
|
||||
.map(|(idx, indicies)| {
|
||||
let selected = self
|
||||
.selected_index
|
||||
.map_or(false, |index| index == *idx);
|
||||
let full_text = trim_length_left(
|
||||
&self.branches[*idx],
|
||||
width,
|
||||
);
|
||||
Spans::from(
|
||||
full_text
|
||||
.char_indices()
|
||||
.map(|(c_idx, c)| {
|
||||
Span::styled(
|
||||
Cow::from(c.to_string()),
|
||||
self.theme.text(
|
||||
selected,
|
||||
indicies.contains(&c_idx),
|
||||
),
|
||||
)
|
||||
})
|
||||
.collect::<Vec<_>>(),
|
||||
)
|
||||
});
|
||||
|
||||
ui::draw_list_block(
|
||||
f,
|
||||
chunks[1],
|
||||
Block::default()
|
||||
.title(Span::styled(
|
||||
title,
|
||||
self.theme.title(true),
|
||||
))
|
||||
.borders(Borders::TOP),
|
||||
items,
|
||||
);
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
impl Component for BranchFindPopup {
|
||||
fn commands(
|
||||
&self,
|
||||
out: &mut Vec<CommandInfo>,
|
||||
force_all: bool,
|
||||
) -> CommandBlocking {
|
||||
if self.is_visible() || force_all {
|
||||
out.push(CommandInfo::new(
|
||||
strings::commands::scroll_popup(&self.key_config),
|
||||
true,
|
||||
true,
|
||||
));
|
||||
|
||||
out.push(CommandInfo::new(
|
||||
strings::commands::close_fuzzy_finder(
|
||||
&self.key_config,
|
||||
),
|
||||
true,
|
||||
true,
|
||||
));
|
||||
}
|
||||
|
||||
visibility_blocking(self)
|
||||
}
|
||||
|
||||
fn event(
|
||||
&mut self,
|
||||
event: &crossterm::event::Event,
|
||||
) -> Result<EventState> {
|
||||
if self.is_visible() {
|
||||
if let Event::Key(key) = event {
|
||||
if key_match(key, self.key_config.keys.exit_popup)
|
||||
|| key_match(key, self.key_config.keys.enter)
|
||||
{
|
||||
self.hide();
|
||||
} else if key_match(
|
||||
key,
|
||||
self.key_config.keys.popup_down,
|
||||
) {
|
||||
self.move_selection(ScrollType::Down);
|
||||
} else if key_match(
|
||||
key,
|
||||
self.key_config.keys.popup_up,
|
||||
) {
|
||||
self.move_selection(ScrollType::Up);
|
||||
}
|
||||
}
|
||||
|
||||
if self.find_text.event(event)?.is_consumed() {
|
||||
self.update_query();
|
||||
}
|
||||
|
||||
return Ok(EventState::Consumed);
|
||||
}
|
||||
|
||||
Ok(EventState::NotConsumed)
|
||||
}
|
||||
|
||||
fn is_visible(&self) -> bool {
|
||||
self.visible
|
||||
}
|
||||
|
||||
fn hide(&mut self) {
|
||||
self.visible = false;
|
||||
}
|
||||
|
||||
fn show(&mut self) -> Result<()> {
|
||||
self.visible = true;
|
||||
Ok(())
|
||||
}
|
||||
}
|
@ -25,7 +25,7 @@ use asyncgit::{
|
||||
},
|
||||
AsyncGitNotification,
|
||||
};
|
||||
use crossterm::event::Event;
|
||||
use crossterm::event::{Event, KeyEvent};
|
||||
use ratatui::{
|
||||
backend::Backend,
|
||||
layout::{
|
||||
@ -206,6 +206,12 @@ impl Component for BranchListComponent {
|
||||
self.has_remotes,
|
||||
!self.local,
|
||||
));
|
||||
|
||||
out.push(CommandInfo::new(
|
||||
strings::commands::find_branch(&self.key_config),
|
||||
true,
|
||||
true,
|
||||
));
|
||||
}
|
||||
visibility_blocking(self)
|
||||
}
|
||||
@ -218,37 +224,11 @@ impl Component for BranchListComponent {
|
||||
}
|
||||
|
||||
if let Event::Key(e) = ev {
|
||||
if key_match(e, self.key_config.keys.exit_popup) {
|
||||
self.hide();
|
||||
} else if key_match(e, self.key_config.keys.move_down) {
|
||||
return self
|
||||
.move_selection(ScrollType::Up)
|
||||
.map(Into::into);
|
||||
} else if key_match(e, self.key_config.keys.move_up) {
|
||||
return self
|
||||
.move_selection(ScrollType::Down)
|
||||
.map(Into::into);
|
||||
} else if key_match(e, self.key_config.keys.page_down) {
|
||||
return self
|
||||
.move_selection(ScrollType::PageDown)
|
||||
.map(Into::into);
|
||||
} else if key_match(e, self.key_config.keys.page_up) {
|
||||
return self
|
||||
.move_selection(ScrollType::PageUp)
|
||||
.map(Into::into);
|
||||
} else if key_match(e, self.key_config.keys.home) {
|
||||
return self
|
||||
.move_selection(ScrollType::Home)
|
||||
.map(Into::into);
|
||||
} else if key_match(e, self.key_config.keys.end) {
|
||||
return self
|
||||
.move_selection(ScrollType::End)
|
||||
.map(Into::into);
|
||||
} else if key_match(e, self.key_config.keys.tab_toggle) {
|
||||
self.local = !self.local;
|
||||
self.check_remotes();
|
||||
self.update_branches()?;
|
||||
} else if key_match(e, self.key_config.keys.enter) {
|
||||
if self.move_event(e)?.is_consumed() {
|
||||
return Ok(EventState::Consumed);
|
||||
}
|
||||
|
||||
if key_match(e, self.key_config.keys.enter) {
|
||||
try_or_popup!(
|
||||
self,
|
||||
"switch branch error:",
|
||||
@ -302,7 +282,7 @@ impl Component for BranchListComponent {
|
||||
),
|
||||
));
|
||||
}
|
||||
} else if key_match(e, self.key_config.keys.pull)
|
||||
} else if key_match(e, self.key_config.keys.fetch)
|
||||
&& !self.local && self.has_remotes
|
||||
{
|
||||
self.queue.push(InternalEvent::FetchRemotes);
|
||||
@ -312,6 +292,14 @@ impl Component for BranchListComponent {
|
||||
) {
|
||||
//do not consume if its the more key
|
||||
return Ok(EventState::NotConsumed);
|
||||
} else if key_match(e, self.key_config.keys.branch_find) {
|
||||
let branches = self
|
||||
.branches
|
||||
.iter()
|
||||
.map(|b| b.name.clone())
|
||||
.collect();
|
||||
self.queue
|
||||
.push(InternalEvent::OpenBranchFinder(branches));
|
||||
}
|
||||
}
|
||||
|
||||
@ -355,6 +343,41 @@ impl BranchListComponent {
|
||||
}
|
||||
}
|
||||
|
||||
fn move_event(&mut self, e: &KeyEvent) -> Result<EventState> {
|
||||
if key_match(e, self.key_config.keys.exit_popup) {
|
||||
self.hide();
|
||||
} else if key_match(e, self.key_config.keys.move_down) {
|
||||
return self
|
||||
.move_selection(ScrollType::Up)
|
||||
.map(Into::into);
|
||||
} else if key_match(e, self.key_config.keys.move_up) {
|
||||
return self
|
||||
.move_selection(ScrollType::Down)
|
||||
.map(Into::into);
|
||||
} else if key_match(e, self.key_config.keys.page_down) {
|
||||
return self
|
||||
.move_selection(ScrollType::PageDown)
|
||||
.map(Into::into);
|
||||
} else if key_match(e, self.key_config.keys.page_up) {
|
||||
return self
|
||||
.move_selection(ScrollType::PageUp)
|
||||
.map(Into::into);
|
||||
} else if key_match(e, self.key_config.keys.home) {
|
||||
return self
|
||||
.move_selection(ScrollType::Home)
|
||||
.map(Into::into);
|
||||
} else if key_match(e, self.key_config.keys.end) {
|
||||
return self
|
||||
.move_selection(ScrollType::End)
|
||||
.map(Into::into);
|
||||
} else if key_match(e, self.key_config.keys.tab_toggle) {
|
||||
self.local = !self.local;
|
||||
self.check_remotes();
|
||||
self.update_branches()?;
|
||||
}
|
||||
Ok(EventState::NotConsumed)
|
||||
}
|
||||
|
||||
///
|
||||
pub fn open(&mut self) -> Result<()> {
|
||||
self.show()?;
|
||||
@ -363,6 +386,16 @@ impl BranchListComponent {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn branch_finder_update(
|
||||
&mut self,
|
||||
idx: Option<usize>,
|
||||
) -> Result<()> {
|
||||
if let Some(idx) = idx {
|
||||
self.set_selection(idx.try_into()?)?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn check_remotes(&mut self) {
|
||||
if !self.local && self.visible {
|
||||
self.has_remotes =
|
||||
|
@ -283,17 +283,16 @@ impl Component for FileFindPopup {
|
||||
force_all: bool,
|
||||
) -> CommandBlocking {
|
||||
if self.is_visible() || force_all {
|
||||
out.push(
|
||||
CommandInfo::new(
|
||||
strings::commands::close_popup(&self.key_config),
|
||||
true,
|
||||
true,
|
||||
)
|
||||
.order(1),
|
||||
);
|
||||
out.push(CommandInfo::new(
|
||||
strings::commands::scroll_popup(&self.key_config),
|
||||
true,
|
||||
true,
|
||||
));
|
||||
|
||||
out.push(CommandInfo::new(
|
||||
strings::commands::scroll(&self.key_config),
|
||||
strings::commands::close_fuzzy_finder(
|
||||
&self.key_config,
|
||||
),
|
||||
true,
|
||||
true,
|
||||
));
|
||||
|
@ -1,4 +1,5 @@
|
||||
mod blame_file;
|
||||
mod branch_find_popup;
|
||||
mod branchlist;
|
||||
mod changes;
|
||||
mod command;
|
||||
@ -36,6 +37,7 @@ mod utils;
|
||||
|
||||
pub use self::status_tree::StatusTreeComponent;
|
||||
pub use blame_file::{BlameFileComponent, BlameFileOpen};
|
||||
pub use branch_find_popup::BranchFindPopup;
|
||||
pub use branchlist::BranchListComponent;
|
||||
pub use changes::ChangesComponent;
|
||||
pub use command::{CommandInfo, CommandText};
|
||||
|
@ -103,6 +103,7 @@ pub struct KeysList {
|
||||
pub push: GituiKeyEvent,
|
||||
pub open_file_tree: GituiKeyEvent,
|
||||
pub file_find: GituiKeyEvent,
|
||||
pub branch_find: GituiKeyEvent,
|
||||
pub force_push: GituiKeyEvent,
|
||||
pub fetch: GituiKeyEvent,
|
||||
pub pull: GituiKeyEvent,
|
||||
@ -191,6 +192,7 @@ impl Default for KeysList {
|
||||
abort_merge: GituiKeyEvent::new(KeyCode::Char('A'), KeyModifiers::SHIFT),
|
||||
open_file_tree: GituiKeyEvent::new(KeyCode::Char('F'), KeyModifiers::SHIFT),
|
||||
file_find: GituiKeyEvent::new(KeyCode::Char('f'), KeyModifiers::empty()),
|
||||
branch_find: GituiKeyEvent::new(KeyCode::Char('f'), KeyModifiers::empty()),
|
||||
stage_unstage_item: GituiKeyEvent::new(KeyCode::Enter, KeyModifiers::empty()),
|
||||
tag_annotate: GituiKeyEvent::new(KeyCode::Char('a'), KeyModifiers::CONTROL),
|
||||
view_submodules: GituiKeyEvent::new(KeyCode::Char('S'), KeyModifiers::SHIFT),
|
||||
|
@ -113,8 +113,12 @@ pub enum InternalEvent {
|
||||
///
|
||||
OpenFileFinder(Vec<TreeFile>),
|
||||
///
|
||||
OpenBranchFinder(Vec<String>),
|
||||
///
|
||||
FileFinderChanged(Option<PathBuf>),
|
||||
///
|
||||
BranchFinderChanged(Option<usize>),
|
||||
///
|
||||
FetchRemotes,
|
||||
///
|
||||
OpenPopup(StackablePopupOpen),
|
||||
|
@ -450,6 +450,16 @@ pub mod commands {
|
||||
CMD_GROUP_GENERAL,
|
||||
)
|
||||
}
|
||||
pub fn find_branch(key_config: &SharedKeyConfig) -> CommandText {
|
||||
CommandText::new(
|
||||
format!(
|
||||
"Find [{}]",
|
||||
key_config.get_hint(key_config.keys.branch_find)
|
||||
),
|
||||
"find branch in list",
|
||||
CMD_GROUP_GENERAL,
|
||||
)
|
||||
}
|
||||
pub fn toggle_tabs_direct(
|
||||
key_config: &SharedKeyConfig,
|
||||
) -> CommandText {
|
||||
@ -683,6 +693,19 @@ pub mod commands {
|
||||
CMD_GROUP_DIFF,
|
||||
)
|
||||
}
|
||||
pub fn close_fuzzy_finder(
|
||||
key_config: &SharedKeyConfig,
|
||||
) -> CommandText {
|
||||
CommandText::new(
|
||||
format!(
|
||||
"Close [{}{}]",
|
||||
key_config.get_hint(key_config.keys.exit_popup),
|
||||
key_config.get_hint(key_config.keys.enter),
|
||||
),
|
||||
"close fuzzy finder",
|
||||
CMD_GROUP_GENERAL,
|
||||
)
|
||||
}
|
||||
pub fn close_popup(key_config: &SharedKeyConfig) -> CommandText {
|
||||
CommandText::new(
|
||||
format!(
|
||||
@ -693,6 +716,17 @@ pub mod commands {
|
||||
CMD_GROUP_GENERAL,
|
||||
)
|
||||
}
|
||||
pub fn scroll_popup(key_config: &SharedKeyConfig) -> CommandText {
|
||||
CommandText::new(
|
||||
format!(
|
||||
"Scroll [{}{}]",
|
||||
key_config.get_hint(key_config.keys.popup_down),
|
||||
key_config.get_hint(key_config.keys.popup_up),
|
||||
),
|
||||
"scroll up or down in popup",
|
||||
CMD_GROUP_GENERAL,
|
||||
)
|
||||
}
|
||||
pub fn close_msg(key_config: &SharedKeyConfig) -> CommandText {
|
||||
CommandText::new(
|
||||
format!(
|
||||
@ -1555,7 +1589,7 @@ pub mod commands {
|
||||
CommandText::new(
|
||||
format!(
|
||||
"Fetch [{}]",
|
||||
key_config.get_hint(key_config.keys.pull),
|
||||
key_config.get_hint(key_config.keys.fetch),
|
||||
),
|
||||
"fetch/prune",
|
||||
CMD_GROUP_BRANCHES,
|
||||
|
Loading…
Reference in New Issue
Block a user