diff --git a/helix-view/src/commands.rs b/helix-view/src/commands.rs
index 1d8d851e..0b985dc6 100644
--- a/helix-view/src/commands.rs
+++ b/helix-view/src/commands.rs
@@ -133,22 +133,60 @@ pub fn move_file_end(view: &mut View, _count: usize) {
     view.state.mode = Mode::Normal;
 }
 
+pub fn check_cursor_in_view(view: &mut View) -> bool {
+    let cursor = view.state.selection().cursor();
+    let line = view.state.doc().char_to_line(cursor) as u16;
+    let document_end = view.first_line + view.size.1.saturating_sub(1) - 1;
+    let padding = 5u16;
+
+    if (line > document_end.saturating_sub(padding)) | (line < view.first_line + padding) {
+        return false;
+    }
+    true
+}
+
 pub fn page_up(view: &mut View, _count: usize) {
+    let text = &view.state.doc;
     view.first_line = view.first_line.saturating_sub(view.size.1);
-    view.state.selection = Selection::single(view.first_line as usize, view.first_line as usize);
+
+    view.state.selection = Selection::single(
+        text.line_to_char(view.first_line as usize),
+        text.line_to_char(view.first_line as usize),
+    );
 }
 
 pub fn page_down(view: &mut View, _count: usize) {
+    let text = &view.state.doc;
     view.first_line += view.size.1;
-    view.state.selection = Selection::single(view.first_line as usize, view.first_line as usize);
+
+    view.state.selection = Selection::single(
+        text.line_to_char(view.first_line as usize),
+        text.line_to_char(view.first_line as usize),
+    );
 }
 
 pub fn half_page_up(view: &mut View, _count: usize) {
     view.first_line = view.first_line.saturating_sub(view.size.1 / 2);
+
+    if !check_cursor_in_view(view) {
+        let text = &view.state.doc;
+        view.state.selection = Selection::single(
+            text.line_to_char(view.first_line as usize),
+            text.line_to_char(view.first_line as usize),
+        );
+    }
 }
 
 pub fn half_page_down(view: &mut View, _count: usize) {
     view.first_line += view.size.1 / 2;
+
+    if !check_cursor_in_view(view) {
+        let text = &view.state.doc;
+        view.state.selection = Selection::single(
+            text.line_to_char(view.first_line as usize),
+            text.line_to_char(view.first_line as usize),
+        );
+    }
 }
 // avoid select by default by having a visual mode switch that makes movements into selects
 
diff --git a/helix-view/src/keymap.rs b/helix-view/src/keymap.rs
index 27176423..72fc0e79 100644
--- a/helix-view/src/keymap.rs
+++ b/helix-view/src/keymap.rs
@@ -108,6 +108,15 @@ macro_rules! shift {
     };
 }
 
+macro_rules! ctrl {
+    ($ch:expr) => {
+        Key {
+            code: KeyCode::Char($ch),
+            modifiers: Modifiers::CONTROL,
+        }
+    };
+}
+
 pub fn default() -> Keymaps {
     hashmap!(
         state::Mode::Normal =>
@@ -148,8 +157,8 @@ pub fn default() -> Keymaps {
                     code: KeyCode::PageDown,
                     modifiers: Modifiers::NONE
                 }] => commands::page_down,
-                vec![shift!('u')] => commands::half_page_up,
-                vec![shift!('d')] => commands::half_page_down,
+                vec![ctrl!('u')] => commands::half_page_up,
+                vec![ctrl!('d')] => commands::half_page_down,
             ),
             state::Mode::Insert => hashmap!(
                 vec![Key {