mirror of https://github.com/helix-editor/helix
feat: implement buffer jumplist
j.a=":ab" j.d=":rb" j.0=":j 0" j.1=":j 1" j.2=":j 2" j.3=":j 3" j.4=":j 4"pull/13448/head
parent
b42e1d20d2
commit
46dfbd0991
|
@ -3141,6 +3141,7 @@ fn buffer_picker(cx: &mut Context) {
|
||||||
is_modified: bool,
|
is_modified: bool,
|
||||||
is_current: bool,
|
is_current: bool,
|
||||||
focused_at: std::time::Instant,
|
focused_at: std::time::Instant,
|
||||||
|
index_in_buffer_jumplist: Option<usize>,
|
||||||
}
|
}
|
||||||
|
|
||||||
let new_meta = |doc: &Document| BufferMeta {
|
let new_meta = |doc: &Document| BufferMeta {
|
||||||
|
@ -3149,6 +3150,11 @@ fn buffer_picker(cx: &mut Context) {
|
||||||
is_modified: doc.is_modified(),
|
is_modified: doc.is_modified(),
|
||||||
is_current: doc.id() == current,
|
is_current: doc.id() == current,
|
||||||
focused_at: doc.focused_at,
|
focused_at: doc.focused_at,
|
||||||
|
index_in_buffer_jumplist: cx
|
||||||
|
.editor
|
||||||
|
.buffer_jumplist
|
||||||
|
.iter()
|
||||||
|
.position(|id| id == &doc.id()),
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut items = cx
|
let mut items = cx
|
||||||
|
@ -3171,6 +3177,10 @@ fn buffer_picker(cx: &mut Context) {
|
||||||
if meta.is_current {
|
if meta.is_current {
|
||||||
flags.push('*');
|
flags.push('*');
|
||||||
}
|
}
|
||||||
|
if let Some(index) = meta.index_in_buffer_jumplist {
|
||||||
|
flags.push_str(&index.to_string());
|
||||||
|
}
|
||||||
|
|
||||||
flags.into()
|
flags.into()
|
||||||
}),
|
}),
|
||||||
PickerColumn::new("path", |meta: &BufferMeta, _| {
|
PickerColumn::new("path", |meta: &BufferMeta, _| {
|
||||||
|
|
|
@ -99,6 +99,51 @@ fn force_quit(cx: &mut compositor::Context, _args: Args, event: PromptEvent) ->
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn buffer_jump(cx: &mut compositor::Context, args: Args, event: PromptEvent) -> anyhow::Result<()> {
|
||||||
|
if event != PromptEvent::Validate {
|
||||||
|
return Ok(());
|
||||||
|
}
|
||||||
|
|
||||||
|
let pos: usize = args.first().unwrap_or("0").parse().unwrap_or(0);
|
||||||
|
if let Some(doc_id) = cx.editor.buffer_jumplist.get(pos) {
|
||||||
|
cx.editor.switch(*doc_id, Action::Replace);
|
||||||
|
}
|
||||||
|
|
||||||
|
return Ok(());
|
||||||
|
}
|
||||||
|
|
||||||
|
fn add_buffer_to_jumplist(
|
||||||
|
cx: &mut compositor::Context,
|
||||||
|
_args: Args,
|
||||||
|
event: PromptEvent,
|
||||||
|
) -> anyhow::Result<()> {
|
||||||
|
if event != PromptEvent::Validate {
|
||||||
|
return Ok(());
|
||||||
|
}
|
||||||
|
|
||||||
|
let current = view!(cx.editor).doc;
|
||||||
|
cx.editor.buffer_jumplist.push(current);
|
||||||
|
|
||||||
|
return Ok(());
|
||||||
|
}
|
||||||
|
|
||||||
|
fn remove_buffer_from_jumplist(
|
||||||
|
cx: &mut compositor::Context,
|
||||||
|
_args: Args,
|
||||||
|
event: PromptEvent,
|
||||||
|
) -> anyhow::Result<()> {
|
||||||
|
if event != PromptEvent::Validate {
|
||||||
|
return Ok(());
|
||||||
|
}
|
||||||
|
|
||||||
|
let current = view!(cx.editor).doc;
|
||||||
|
cx.editor
|
||||||
|
.buffer_jumplist
|
||||||
|
.retain(|doc_id| *doc_id != current);
|
||||||
|
|
||||||
|
return Ok(());
|
||||||
|
}
|
||||||
|
|
||||||
fn open(cx: &mut compositor::Context, args: Args, event: PromptEvent) -> anyhow::Result<()> {
|
fn open(cx: &mut compositor::Context, args: Args, event: PromptEvent) -> anyhow::Result<()> {
|
||||||
if event != PromptEvent::Validate {
|
if event != PromptEvent::Validate {
|
||||||
return Ok(());
|
return Ok(());
|
||||||
|
@ -2619,6 +2664,39 @@ pub const TYPABLE_COMMAND_LIST: &[TypableCommand] = &[
|
||||||
..Signature::DEFAULT
|
..Signature::DEFAULT
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
TypableCommand {
|
||||||
|
name: "jump-to-buffer",
|
||||||
|
aliases: &["j"],
|
||||||
|
doc: "Switch to a document buffer using its index in the buffer jumplist.",
|
||||||
|
fun: buffer_jump,
|
||||||
|
completer: CommandCompleter::all(completers::filename),
|
||||||
|
signature: Signature {
|
||||||
|
positionals: (1, None),
|
||||||
|
..Signature::DEFAULT
|
||||||
|
},
|
||||||
|
},
|
||||||
|
TypableCommand {
|
||||||
|
name: "add-buffer-to-jumplist",
|
||||||
|
aliases: &["ab"],
|
||||||
|
doc: "Add the current document buffer to the buffer jumplist.",
|
||||||
|
fun: add_buffer_to_jumplist,
|
||||||
|
completer: CommandCompleter::all(completers::filename),
|
||||||
|
signature: Signature {
|
||||||
|
positionals: (0, None),
|
||||||
|
..Signature::DEFAULT
|
||||||
|
},
|
||||||
|
},
|
||||||
|
TypableCommand {
|
||||||
|
name: "remove-buffer-from-jumplist",
|
||||||
|
aliases: &["rb"],
|
||||||
|
doc: "Remove the current document buffer from the buffer jumplist.",
|
||||||
|
fun: remove_buffer_from_jumplist,
|
||||||
|
completer: CommandCompleter::all(completers::filename),
|
||||||
|
signature: Signature {
|
||||||
|
positionals: (0, None),
|
||||||
|
..Signature::DEFAULT
|
||||||
|
},
|
||||||
|
},
|
||||||
TypableCommand {
|
TypableCommand {
|
||||||
name: "buffer-close",
|
name: "buffer-close",
|
||||||
aliases: &["bc", "bclose"],
|
aliases: &["bc", "bclose"],
|
||||||
|
|
|
@ -1123,6 +1123,9 @@ pub struct Editor {
|
||||||
|
|
||||||
pub mouse_down_range: Option<Range>,
|
pub mouse_down_range: Option<Range>,
|
||||||
pub cursor_cache: CursorCache,
|
pub cursor_cache: CursorCache,
|
||||||
|
|
||||||
|
/// Stores a manually curated list of document IDs for navigation.
|
||||||
|
pub buffer_jumplist: Vec<DocumentId>,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub type Motion = Box<dyn Fn(&mut Editor)>;
|
pub type Motion = Box<dyn Fn(&mut Editor)>;
|
||||||
|
@ -1245,6 +1248,7 @@ impl Editor {
|
||||||
handlers,
|
handlers,
|
||||||
mouse_down_range: None,
|
mouse_down_range: None,
|
||||||
cursor_cache: CursorCache::default(),
|
cursor_cache: CursorCache::default(),
|
||||||
|
buffer_jumplist: Vec::new(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1824,6 +1828,9 @@ impl Editor {
|
||||||
// This will also disallow any follow-up writes
|
// This will also disallow any follow-up writes
|
||||||
self.saves.remove(&doc_id);
|
self.saves.remove(&doc_id);
|
||||||
|
|
||||||
|
// Removes the document from the buffer jumplist when closed.
|
||||||
|
self.buffer_jumplist.retain(|doc| *doc != doc_id);
|
||||||
|
|
||||||
enum Action {
|
enum Action {
|
||||||
Close(ViewId),
|
Close(ViewId),
|
||||||
ReplaceDoc(ViewId, DocumentId),
|
ReplaceDoc(ViewId, DocumentId),
|
||||||
|
|
Loading…
Reference in New Issue