M cursive/src/main.rs +4 -129
@@ 11,38 11,23 @@ use ted_tui::{
self,
Cursive,
event::Event,
- view::View,
views::{
Canvas,
- LinearLayout,
- ListView,
- TextView,
- StackView,
- BoxView,
- Layer
+ LinearLayout
},
theme::{
Style,
ColorStyle
- },
- traits::{
- Finder,
- Identifiable,
- Boxable
}
},
views::{
self,
EditorView,
- LineNumbers,
- Line
+ LineNumbers
},
ted::{
buffer::Buffer,
- trie::{
- TrieState,
- SequenceTrie
- }
+ trie::SequenceTrie
},
plugin::Registry
};
@@ 122,7 107,7 @@ fn main() {
};
siv.add_fullscreen_layer(views::translate_keys(
- visualize_keymap(
+ views::visualize_keymap(
layout_default(
editor,
ColorStyle::tertiary()
@@ 167,113 152,3 @@ where S: 'static + Into<Style> {
layout.layout(size);
})
}
-
-fn visualize_keymap<V, C>(view: V, bindings: SequenceTrie<Event, C>) -> Canvas<StackView> where
- V: View,
- C: 'static + std::fmt::Display
-{
- let mut state = TrieState::new(bindings);
- let mut overlay: Option<BoxView<LinearLayout>> = Some(
- LinearLayout::vertical()
- .child(cursive::views::DummyView .full_height())
- .child(Line::horizontal() .full_width ())
- .child(Layer::new(ListView::new().with_id(ID_KEYMAP)).full_width ())
- .full_width()
- );
-
- const ID_KEYMAP: &str = "keymap";
- const ID_INNER : &str = "inner" ;
-
- Canvas::wrap(StackView::new()
- .fullscreen_layer(view
- .with_id(ID_INNER)
- .full_screen()
- )
- ).with_on_event(move |stack, event| {
- use std::mem::replace;
-
- let show = {
- let mut update_keymap = |keymap: &mut ListView| {
- match event {
- Event::WindowResize |
- Event::Refresh => {}
- Event::Mouse { .. } => {
- state.reset();
- keymap.clear();
- }
- Event::Char (_) |
- Event::CtrlChar (_) |
- Event::AltChar (_) |
- Event::Key (_) |
- Event::Shift (_) |
- Event::Alt (_) |
- Event::AltShift (_) |
- Event::Ctrl (_) |
- Event::CtrlShift(_) |
- Event::CtrlAlt (_) => {
- keymap.clear();
-
- /* XXX could make this quicker
- * by caching all possible lists
- * in another SequenceTrie */
- state.next(&event).is_some();
- let node = state.node();
- if !node.is_leaf() && !state.path().is_empty() {
- // Build the list for the current node.
-
- // sort submenus first
- let mut children = node.children_with_keys();
- children.sort_unstable_by_key(|(_, cmd)| cmd.is_leaf());
-
- let mut add_delim = children.len() > 0 && !children[0].1.is_leaf();
- for (event, cmd) in children {
- if add_delim && cmd.is_leaf() {
- keymap.add_delimiter();
- add_delim = false;
- }
-
- keymap.add_child(
- &bindings::stringify_event(event),
- TextView::new(if !cmd.is_leaf() { "…".to_owned() } else {
- format!("{}", cmd.value().expect("empty command"))
- })
- );
- }
- }
- }
- _ => {}
- }
-
- keymap.len() > 0
- };
-
- if let Some(ref mut layer) = overlay {
- layer.find_id(ID_KEYMAP, &mut update_keymap).unwrap()
- } else {
- stack.find_id(ID_KEYMAP, &mut update_keymap).unwrap()
- }
- };
-
- // Show or hide the overlay.
- if show && overlay.is_some() {
- stack.add_transparent_layer(
- replace(&mut overlay, None).unwrap()
- );
- }
- if !show && overlay.is_none() {
- replace(&mut overlay, Some(
- *stack.pop_layer().unwrap()
- .as_boxed_any()
- .downcast().unwrap()
- ));
- }
-
- // Forward the intercepted event.
- if show {
- /* The overlay is blocking the event from the inner view
- * so we need to separately fire it again. */
- stack.find_id(ID_INNER, |view: &mut V| view.on_event(event.clone()));
- }
- stack.on_event(event)
- })
-}
M cursive/src/views/mod.rs +131 -1
@@ 11,9 11,29 @@ pub use self::line::Line;
use {
keys,
+ bindings,
+ std::fmt::Display,
+ ted::trie::{
+ TrieState,
+ SequenceTrie
+ },
cursive::{
view::View,
- views::Canvas
+ views::{
+ Canvas,
+ StackView,
+ LinearLayout,
+ ListView,
+ BoxView,
+ Layer,
+ TextView
+ },
+ event::Event,
+ traits::{
+ Finder,
+ Identifiable,
+ Boxable
+ }
}
};
@@ 29,3 49,113 @@ pub fn translate_keys<V: View>(view: V)
})
})
}
+
+pub fn visualize_keymap<V, C>(view: V, bindings: SequenceTrie<Event, C>) -> Canvas<StackView> where
+ V: View,
+ C: 'static + Display
+{
+ const ID_KEYMAP: &str = "keymap";
+ const ID_INNER : &str = "inner" ;
+
+ let mut state = TrieState::new(bindings);
+ let mut overlay: Option<BoxView<LinearLayout>> = Some(
+ LinearLayout::vertical()
+ .child(cursive::views::DummyView .full_height())
+ .child(Line::horizontal() .full_width ())
+ .child(Layer::new(ListView::new().with_id(ID_KEYMAP)).full_width ())
+ .full_width()
+ );
+
+ Canvas::wrap(StackView::new()
+ .fullscreen_layer(view
+ .with_id(ID_INNER)
+ .full_screen()
+ )
+ ).with_on_event(move |stack, event| {
+ use std::mem::replace;
+
+ let show = {
+ let mut update_keymap = |keymap: &mut ListView| {
+ match event {
+ Event::WindowResize |
+ Event::Refresh => {}
+ Event::Mouse { .. } => {
+ state.reset();
+ keymap.clear();
+ }
+ Event::Char (_) |
+ Event::CtrlChar (_) |
+ Event::AltChar (_) |
+ Event::Key (_) |
+ Event::Shift (_) |
+ Event::Alt (_) |
+ Event::AltShift (_) |
+ Event::Ctrl (_) |
+ Event::CtrlShift(_) |
+ Event::CtrlAlt (_) => {
+ keymap.clear();
+
+ /* XXX could make this quicker
+ * by caching all possible lists
+ * in another SequenceTrie */
+ state.next(&event);
+ let node = state.node();
+ if !node.is_leaf() && !state.path().is_empty() {
+ // Build the list for the current node.
+
+ // sort submenus first
+ let mut children = node.children_with_keys();
+ children.sort_unstable_by_key(|(_, cmd)| cmd.is_leaf());
+
+ let mut add_delim = children.len() > 0 && !children[0].1.is_leaf();
+ for (event, cmd) in children {
+ if add_delim && cmd.is_leaf() {
+ keymap.add_delimiter();
+ add_delim = false;
+ }
+
+ keymap.add_child(
+ &bindings::stringify_event(event),
+ TextView::new(if !cmd.is_leaf() { "…".to_owned() } else {
+ format!("{}", cmd.value().expect("empty command"))
+ })
+ );
+ }
+ }
+ }
+ _ => {}
+ }
+
+ keymap.len() > 0
+ };
+
+ if let Some(ref mut layer) = overlay {
+ layer.find_id(ID_KEYMAP, &mut update_keymap).unwrap()
+ } else {
+ stack.find_id(ID_KEYMAP, &mut update_keymap).unwrap()
+ }
+ };
+
+ // Show or hide the overlay.
+ if show && overlay.is_some() {
+ stack.add_transparent_layer(
+ replace(&mut overlay, None).unwrap()
+ );
+ }
+ if !show && overlay.is_none() {
+ replace(&mut overlay, Some(
+ *stack.pop_layer().unwrap()
+ .as_boxed_any()
+ .downcast().unwrap()
+ ));
+ }
+
+ // Forward the intercepted event.
+ if show {
+ /* The overlay is blocking the event from the inner view
+ * so we need to separately fire it again. */
+ stack.find_id(ID_INNER, |view: &mut V| view.on_event(event.clone()));
+ }
+ stack.on_event(event)
+ })
+}