diff --git a/helix-term/src/commands.rs b/helix-term/src/commands.rs
index 4c04b0a2..c1471cef 100644
--- a/helix-term/src/commands.rs
+++ b/helix-term/src/commands.rs
@@ -1953,3 +1953,50 @@ pub fn space_mode(cx: &mut Context) {
         }
     })
 }
+
+pub fn view_mode(cx: &mut Context) {
+    cx.on_next_key(move |cx, event| {
+        if let KeyEvent {
+            code: KeyCode::Char(ch),
+            ..
+        } = event
+        {
+            // if lock, call cx again
+            // TODO: temporarily show VIE in the mode list
+            match ch {
+                // center
+                'z' | 'c'
+                // top
+                | 't'
+                // bottom
+                | 'b' => {
+                    let (view, doc) = cx.current();
+                    let pos = doc.selection(view.id).cursor();
+                    // TODO: extract this centering into a function to share with _goto?
+                    let line = doc.text().char_to_line(pos);
+
+                    let relative = match ch {
+                        'z' | 'c' => view.area.height as usize / 2,
+                        't' => 0,
+                        'b' => view.area.height as usize,
+                        _ => unreachable!()
+                    };
+                    view.first_line = line.saturating_sub(relative);
+                }
+                'm' => {
+                    let (view, doc) = cx.current();
+                    let pos = doc.selection(view.id).cursor();
+                    let pos = coords_at_pos(doc.text().slice(..), pos);
+
+                    const OFFSET: usize = 7; // gutters
+                    view.first_col = pos.col.saturating_sub((view.area.width as usize - OFFSET) / 2);
+                },
+                'h' => (),
+                'j' => scroll(cx, 1, Direction::Forward),
+                'k' => scroll(cx, 1, Direction::Backward),
+                'l' => (),
+                _ => (),
+            }
+        }
+    })
+}
diff --git a/helix-term/src/keymap.rs b/helix-term/src/keymap.rs
index 26b2b5fe..a1d483c7 100644
--- a/helix-term/src/keymap.rs
+++ b/helix-term/src/keymap.rs
@@ -263,6 +263,7 @@ pub fn default() -> Keymaps {
         // ctrl!('s') => commands::save_selection,
 
         key!(' ') => commands::space_mode,
+        key!('z') => commands::view_mode,
     );
     // TODO: decide whether we want normal mode to also be select mode (kakoune-like), or whether
     // we keep this separate select mode. More keys can fit into normal mode then, but it's weird