From 7a9db951829d37447a414f03802297f4b43e02a6 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Kangwook=20Lee=20=28=EC=9D=B4=EA=B0=95=EC=9A=B1=29?=
 <pbzweihander@gmail.com>
Date: Tue, 7 Sep 2021 23:22:39 +0900
Subject: [PATCH] Add command to extend to line start or end (#717)

---
 helix-term/src/commands.rs | 39 ++++++++++++++++++++++++++++++++------
 helix-term/src/keymap.rs   |  4 ++--
 2 files changed, 35 insertions(+), 8 deletions(-)

diff --git a/helix-term/src/commands.rs b/helix-term/src/commands.rs
index 2fbed6b3..38e65537 100644
--- a/helix-term/src/commands.rs
+++ b/helix-term/src/commands.rs
@@ -252,6 +252,9 @@ impl Command {
         // TODO: different description ?
         goto_line_end_newline, "Goto line end",
         goto_first_nonwhitespace, "Goto first non-blank in line",
+        extend_to_line_start, "Extend to line start",
+        extend_to_line_end, "Extend to line end",
+        extend_to_line_end_newline, "Extend to line end",
         signature_help, "Show signature help",
         insert_tab, "Insert tab char",
         insert_newline, "Insert newline char",
@@ -407,7 +410,7 @@ fn extend_line_down(cx: &mut Context) {
     move_impl(cx, move_vertically, Direction::Forward, Movement::Extend)
 }
 
-fn goto_line_end(cx: &mut Context) {
+fn goto_line_end_impl(cx: &mut Context, movement: Movement) {
     let (view, doc) = current!(cx.editor);
     let text = doc.text().slice(..);
 
@@ -418,12 +421,20 @@ fn goto_line_end(cx: &mut Context) {
         let pos = graphemes::prev_grapheme_boundary(text, line_end_char_index(&text, line))
             .max(line_start);
 
-        range.put_cursor(text, pos, doc.mode == Mode::Select)
+        range.put_cursor(text, pos, movement == Movement::Extend)
     });
     doc.set_selection(view.id, selection);
 }
 
-fn goto_line_end_newline(cx: &mut Context) {
+fn goto_line_end(cx: &mut Context) {
+    goto_line_end_impl(cx, Movement::Move)
+}
+
+fn extend_to_line_end(cx: &mut Context) {
+    goto_line_end_impl(cx, Movement::Extend)
+}
+
+fn goto_line_end_newline_impl(cx: &mut Context, movement: Movement) {
     let (view, doc) = current!(cx.editor);
     let text = doc.text().slice(..);
 
@@ -431,12 +442,20 @@ fn goto_line_end_newline(cx: &mut Context) {
         let line = range.cursor_line(text);
         let pos = line_end_char_index(&text, line);
 
-        range.put_cursor(text, pos, doc.mode == Mode::Select)
+        range.put_cursor(text, pos, movement == Movement::Extend)
     });
     doc.set_selection(view.id, selection);
 }
 
-fn goto_line_start(cx: &mut Context) {
+fn goto_line_end_newline(cx: &mut Context) {
+    goto_line_end_newline_impl(cx, Movement::Move)
+}
+
+fn extend_to_line_end_newline(cx: &mut Context) {
+    goto_line_end_newline_impl(cx, Movement::Extend)
+}
+
+fn goto_line_start_impl(cx: &mut Context, movement: Movement) {
     let (view, doc) = current!(cx.editor);
     let text = doc.text().slice(..);
 
@@ -445,11 +464,19 @@ fn goto_line_start(cx: &mut Context) {
 
         // adjust to start of the line
         let pos = text.line_to_char(line);
-        range.put_cursor(text, pos, doc.mode == Mode::Select)
+        range.put_cursor(text, pos, movement == Movement::Extend)
     });
     doc.set_selection(view.id, selection);
 }
 
+fn goto_line_start(cx: &mut Context) {
+    goto_line_start_impl(cx, Movement::Move)
+}
+
+fn extend_to_line_start(cx: &mut Context) {
+    goto_line_start_impl(cx, Movement::Extend)
+}
+
 fn goto_first_nonwhitespace(cx: &mut Context) {
     let (view, doc) = current!(cx.editor);
     let text = doc.text().slice(..);
diff --git a/helix-term/src/keymap.rs b/helix-term/src/keymap.rs
index aa60482d..1b9d87b5 100644
--- a/helix-term/src/keymap.rs
+++ b/helix-term/src/keymap.rs
@@ -592,8 +592,8 @@ impl Default for Keymaps {
             "T" => extend_till_prev_char,
             "F" => extend_prev_char,
 
-            "home" => goto_line_start,
-            "end" => goto_line_end,
+            "home" => extend_to_line_start,
+            "end" => extend_to_line_end,
             "esc" => exit_select_mode,
 
             "v" => normal_mode,