mirror of https://github.com/helix-editor/helix
Merge 1157263f3f
into 362e97e927
commit
8eec1e8d40
|
@ -3,6 +3,9 @@
|
||||||
| `:quit`, `:q` | Close the current view. |
|
| `:quit`, `:q` | Close the current view. |
|
||||||
| `:quit!`, `:q!` | Force close the current view, ignoring unsaved changes. |
|
| `:quit!`, `:q!` | Force close the current view, ignoring unsaved changes. |
|
||||||
| `:open`, `:o`, `:edit`, `:e` | Open a file from disk into the current view. |
|
| `:open`, `:o`, `:edit`, `:e` | Open a file from disk into the current view. |
|
||||||
|
| `:jump-to-buffer`, `:j` | Switch to a document buffer using its index in the buffer jumplist. |
|
||||||
|
| `:add-buffer-to-jumplist`, `:ab` | Add the current document buffer to the buffer jumplist. |
|
||||||
|
| `:remove-buffer-from-jumplist`, `:rb` | Remove the current document buffer from the buffer jumplist. |
|
||||||
| `:buffer-close`, `:bc`, `:bclose` | Close the current buffer. |
|
| `:buffer-close`, `:bc`, `:bclose` | Close the current buffer. |
|
||||||
| `:buffer-close!`, `:bc!`, `:bclose!` | Close the current buffer forcefully, ignoring unsaved changes. |
|
| `:buffer-close!`, `:bc!`, `:bclose!` | Close the current buffer forcefully, ignoring unsaved changes. |
|
||||||
| `:buffer-close-others`, `:bco`, `:bcloseother` | Close all buffers but the currently focused one. |
|
| `:buffer-close-others`, `:bco`, `:bcloseother` | Close all buffers but the currently focused one. |
|
||||||
|
|
|
@ -3145,6 +3145,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 {
|
||||||
|
@ -3153,6 +3154,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
|
||||||
|
@ -3175,6 +3181,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(());
|
||||||
|
@ -2615,6 +2660,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"],
|
||||||
|
|
|
@ -1133,6 +1133,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)>;
|
||||||
|
@ -1255,6 +1258,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(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1843,6 +1847,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