summaryrefslogtreecommitdiff
path: root/helix-term
diff options
context:
space:
mode:
authorBlaž Hrastnik2020-12-21 07:23:05 +0000
committerBlaž Hrastnik2020-12-21 07:26:22 +0000
commit3d3295bb759994d4fbf328c126678f63e0c38d4f (patch)
treeca93396f3fa0c42a8c6f0c2277f41b1d344fe791 /helix-term
parentea502c8665332932b2311df3852b5ac8df6509af (diff)
ui: buffer picker on ctrl-b
Diffstat (limited to 'helix-term')
-rw-r--r--helix-term/src/commands.rs85
-rw-r--r--helix-term/src/compositor.rs4
-rw-r--r--helix-term/src/keymap.rs1
-rw-r--r--helix-term/src/ui/mod.rs28
-rw-r--r--helix-term/src/ui/picker.rs10
-rw-r--r--helix-term/src/ui/prompt.rs10
6 files changed, 91 insertions, 47 deletions
diff --git a/helix-term/src/commands.rs b/helix-term/src/commands.rs
index 7722eca5..b4b64249 100644
--- a/helix-term/src/commands.rs
+++ b/helix-term/src/commands.rs
@@ -297,9 +297,11 @@ pub fn split_selection(cx: &mut Context) {
},
);
- cx.callback = Some(Box::new(move |compositor: &mut Compositor| {
- compositor.push(Box::new(prompt));
- }));
+ cx.callback = Some(Box::new(
+ move |compositor: &mut Compositor, editor: &mut Editor| {
+ compositor.push(Box::new(prompt));
+ },
+ ));
}
pub fn split_selection_on_newline(cx: &mut Context) {
@@ -399,12 +401,13 @@ pub fn append_mode(cx: &mut Context) {
// TODO: I, A, o and O can share a lot of the primitives.
pub fn command_mode(cx: &mut Context) {
- cx.callback = Some(Box::new(|compositor: &mut Compositor| {
- let prompt = Prompt::new(
- ":".to_owned(),
- |_input: &str| {
- // TODO: i need this duplicate list right now to avoid borrow checker issues
- let command_list = vec![
+ cx.callback = Some(Box::new(
+ |compositor: &mut Compositor, editor: &mut Editor| {
+ let prompt = Prompt::new(
+ ":".to_owned(),
+ |_input: &str| {
+ // TODO: i need this duplicate list right now to avoid borrow checker issues
+ let command_list = vec![
String::from("q"),
String::from("aaa"),
String::from("bbb"),
@@ -437,37 +440,49 @@ pub fn command_mode(cx: &mut Context) {
String::from("ddd"),
String::from("eee"),
];
- command_list
- .into_iter()
- .filter(|command| command.contains(_input))
- .collect()
- }, // completion
- |editor: &mut Editor, input: &str, event: PromptEvent| {
- if event != PromptEvent::Validate {
- return;
- }
+ command_list
+ .into_iter()
+ .filter(|command| command.contains(_input))
+ .collect()
+ }, // completion
+ |editor: &mut Editor, input: &str, event: PromptEvent| {
+ if event != PromptEvent::Validate {
+ return;
+ }
- let parts = input.split_ascii_whitespace().collect::<Vec<&str>>();
+ let parts = input.split_ascii_whitespace().collect::<Vec<&str>>();
- match parts.as_slice() {
- &["q"] => editor.should_close = true,
- &["o", path] => {
- // TODO: make view()/view_mut() always contain a view.
- let size = editor.view().unwrap().size;
- editor.open(path.into(), size);
+ match parts.as_slice() {
+ &["q"] => editor.should_close = true,
+ &["o", path] => {
+ // TODO: make view()/view_mut() always contain a view.
+ let size = editor.view().unwrap().size;
+ editor.open(path.into(), size);
+ }
+ _ => (),
}
- _ => (),
- }
- },
- );
- compositor.push(Box::new(prompt));
- }));
+ },
+ );
+ compositor.push(Box::new(prompt));
+ },
+ ));
}
pub fn file_picker(cx: &mut Context) {
- cx.callback = Some(Box::new(|compositor: &mut Compositor| {
- let picker = ui::file_picker("./");
- compositor.push(Box::new(picker));
- }));
+ cx.callback = Some(Box::new(
+ |compositor: &mut Compositor, editor: &mut Editor| {
+ let picker = ui::file_picker("./");
+ compositor.push(Box::new(picker));
+ },
+ ));
+}
+
+pub fn buffer_picker(cx: &mut Context) {
+ cx.callback = Some(Box::new(
+ |compositor: &mut Compositor, editor: &mut Editor| {
+ let picker = ui::buffer_picker(&editor.views, editor.focus);
+ compositor.push(Box::new(picker));
+ },
+ ));
}
// calculate line numbers for each selection range
diff --git a/helix-term/src/compositor.rs b/helix-term/src/compositor.rs
index f0d94dbc..b1b92a71 100644
--- a/helix-term/src/compositor.rs
+++ b/helix-term/src/compositor.rs
@@ -19,7 +19,7 @@ use smol::Executor;
use tui::buffer::Buffer as Surface;
use tui::layout::Rect;
-pub type Callback = Box<dyn FnOnce(&mut Compositor)>;
+pub type Callback = Box<dyn FnOnce(&mut Compositor, &mut Editor)>;
// --> EventResult should have a callback that takes a context with methods like .popup(),
// .prompt() etc. That way we can abstract it from the renderer.
@@ -128,7 +128,7 @@ impl Compositor {
if let Some(layer) = self.layers.last_mut() {
return match layer.handle_event(event, cx) {
EventResult::Consumed(Some(callback)) => {
- callback(self);
+ callback(self, cx.editor);
true
}
EventResult::Consumed(None) => true,
diff --git a/helix-term/src/keymap.rs b/helix-term/src/keymap.rs
index a31676e4..c1677847 100644
--- a/helix-term/src/keymap.rs
+++ b/helix-term/src/keymap.rs
@@ -185,6 +185,7 @@ pub fn default() -> Keymaps {
vec![ctrl!('d')] => commands::half_page_down,
vec![ctrl!('p')] => commands::file_picker,
+ vec![ctrl!('b')] => commands::buffer_picker,
),
Mode::Insert => hashmap!(
vec![Key {
diff --git a/helix-term/src/ui/mod.rs b/helix-term/src/ui/mod.rs
index b778f531..f9480dd4 100644
--- a/helix-term/src/ui/mod.rs
+++ b/helix-term/src/ui/mod.rs
@@ -15,7 +15,7 @@ pub fn text_color() -> Style {
Style::default().fg(Color::Rgb(219, 191, 239)) // lilac
}
-use std::path::PathBuf;
+use std::path::{Path, PathBuf};
pub fn file_picker(root: &str) -> Picker<PathBuf> {
use ignore::Walk;
// TODO: determine root based on git root
@@ -38,7 +38,7 @@ pub fn file_picker(root: &str) -> Picker<PathBuf> {
files.take(MAX).collect(),
|path: &PathBuf| {
// format_fn
- path.strip_prefix("./").unwrap().to_str().unwrap() // TODO: render paths without ./
+ path.strip_prefix("./").unwrap().to_str().unwrap()
},
|editor: &mut Editor, path: &PathBuf| {
let size = editor.view().unwrap().size;
@@ -46,3 +46,27 @@ pub fn file_picker(root: &str) -> Picker<PathBuf> {
},
)
}
+
+use helix_view::View;
+pub fn buffer_picker(views: &[View], current: usize) -> Picker<(Option<PathBuf>, usize)> {
+ use helix_view::Editor;
+ Picker::new(
+ views
+ .iter()
+ .enumerate()
+ .map(|(i, view)| (view.doc.relative_path().map(Path::to_path_buf), i))
+ .collect(),
+ |(path, index): &(Option<PathBuf>, usize)| {
+ // format_fn
+ match path {
+ Some(path) => path.to_str().unwrap(),
+ None => "[NEW]",
+ }
+ },
+ |editor: &mut Editor, &(_, index): &(Option<PathBuf>, usize)| {
+ if index < editor.views.len() {
+ editor.focus = index;
+ }
+ },
+ )
+}
diff --git a/helix-term/src/ui/picker.rs b/helix-term/src/ui/picker.rs
index 0a12cff9..94eec2eb 100644
--- a/helix-term/src/ui/picker.rs
+++ b/helix-term/src/ui/picker.rs
@@ -123,10 +123,12 @@ impl<T> Component for Picker<T> {
_ => return EventResult::Ignored,
};
- let close_fn = EventResult::Consumed(Some(Box::new(|compositor: &mut Compositor| {
- // remove the layer
- compositor.pop();
- })));
+ let close_fn = EventResult::Consumed(Some(Box::new(
+ |compositor: &mut Compositor, editor: &mut Editor| {
+ // remove the layer
+ compositor.pop();
+ },
+ )));
match key_event {
// KeyEvent {
diff --git a/helix-term/src/ui/prompt.rs b/helix-term/src/ui/prompt.rs
index 58efd560..7abc08c2 100644
--- a/helix-term/src/ui/prompt.rs
+++ b/helix-term/src/ui/prompt.rs
@@ -167,10 +167,12 @@ impl Component for Prompt {
_ => return EventResult::Ignored,
};
- let close_fn = EventResult::Consumed(Some(Box::new(|compositor: &mut Compositor| {
- // remove the layer
- compositor.pop();
- })));
+ let close_fn = EventResult::Consumed(Some(Box::new(
+ |compositor: &mut Compositor, editor: &mut Editor| {
+ // remove the layer
+ compositor.pop();
+ },
+ )));
match event {
KeyEvent {