From 07fe4a6a40b4a3e3dd45a8e9f7e7c20a2124bd73 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: Sat, 4 Sep 2021 22:30:32 +0900
Subject: [PATCH] Add commands that extends to long words (#706)

---
 helix-term/src/commands.rs | 42 ++++++++++++++++++++++++++++++++++++++
 helix-term/src/keymap.rs   |  3 +++
 2 files changed, 45 insertions(+)

diff --git a/helix-term/src/commands.rs b/helix-term/src/commands.rs
index 116f39bd..dfbfe1d5 100644
--- a/helix-term/src/commands.rs
+++ b/helix-term/src/commands.rs
@@ -180,6 +180,9 @@ impl Command {
         move_next_long_word_end, "Move to end of next long word",
         extend_next_word_start, "Extend to beginning of next word",
         extend_prev_word_start, "Extend to beginning of previous word",
+        extend_next_long_word_start, "Extend to beginning of next long word",
+        extend_prev_long_word_start, "Extend to beginning of previous long word",
+        extend_next_long_word_end, "Extend to end of next long word",
         extend_next_word_end, "Extend to end of next word",
         find_till_char, "Move till next occurance of char",
         find_next_char, "Move to next occurance of char",
@@ -622,6 +625,45 @@ fn extend_next_word_end(cx: &mut Context) {
     doc.set_selection(view.id, selection);
 }
 
+fn extend_next_long_word_start(cx: &mut Context) {
+    let count = cx.count();
+    let (view, doc) = current!(cx.editor);
+    let text = doc.text().slice(..);
+
+    let selection = doc.selection(view.id).clone().transform(|range| {
+        let word = movement::move_next_long_word_start(text, range, count);
+        let pos = word.cursor(text);
+        range.put_cursor(text, pos, true)
+    });
+    doc.set_selection(view.id, selection);
+}
+
+fn extend_prev_long_word_start(cx: &mut Context) {
+    let count = cx.count();
+    let (view, doc) = current!(cx.editor);
+    let text = doc.text().slice(..);
+
+    let selection = doc.selection(view.id).clone().transform(|range| {
+        let word = movement::move_prev_long_word_start(text, range, count);
+        let pos = word.cursor(text);
+        range.put_cursor(text, pos, true)
+    });
+    doc.set_selection(view.id, selection);
+}
+
+fn extend_next_long_word_end(cx: &mut Context) {
+    let count = cx.count();
+    let (view, doc) = current!(cx.editor);
+    let text = doc.text().slice(..);
+
+    let selection = doc.selection(view.id).clone().transform(|range| {
+        let word = movement::move_next_long_word_end(text, range, count);
+        let pos = word.cursor(text);
+        range.put_cursor(text, pos, true)
+    });
+    doc.set_selection(view.id, selection);
+}
+
 #[inline]
 fn find_char_impl<F>(cx: &mut Context, search_fn: F, inclusive: bool, extend: bool)
 where
diff --git a/helix-term/src/keymap.rs b/helix-term/src/keymap.rs
index 71ac01a9..a936dccc 100644
--- a/helix-term/src/keymap.rs
+++ b/helix-term/src/keymap.rs
@@ -527,6 +527,9 @@ impl Default for Keymaps {
             "w" => extend_next_word_start,
             "b" => extend_prev_word_start,
             "e" => extend_next_word_end,
+            "W" => extend_next_long_word_start,
+            "B" => extend_prev_long_word_start,
+            "E" => extend_next_long_word_end,
 
             "t" => extend_till_char,
             "f" => extend_next_char,