tui: move keymap visualization from main to views
2 files changed, 135 insertions(+), 130 deletions(-)

M cursive/src/main.rs
M cursive/src/views/mod.rs
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)
+    })
+}