aboutsummaryrefslogtreecommitdiffstats
path: root/content_scripts
diff options
context:
space:
mode:
authorStephen Blott2015-01-27 05:30:13 +0000
committerStephen Blott2015-01-27 05:30:13 +0000
commit0f205f2c672773eef4fc5d7637195e3f6d7d75f6 (patch)
treef15eb1952c953d164eb6bf60ed7f7c544abdaf65 /content_scripts
parent8d33db411b556b37a8b0d54aba507440cfc51e0a (diff)
downloadvimium-0f205f2c672773eef4fc5d7637195e3f6d7d75f6.tar.bz2
Visual/edit modes: better word-movement/"w".
Diffstat (limited to 'content_scripts')
-rw-r--r--content_scripts/mode_visual_edit.coffee41
1 files changed, 32 insertions, 9 deletions
diff --git a/content_scripts/mode_visual_edit.coffee b/content_scripts/mode_visual_edit.coffee
index 73f154bb..48c5f47f 100644
--- a/content_scripts/mode_visual_edit.coffee
+++ b/content_scripts/mode_visual_edit.coffee
@@ -70,6 +70,31 @@ class Movement extends MaintainCount
paste: (callback) ->
chrome.runtime.sendMessage handler: "pasteFromClipboard", (response) -> callback response
+ # Return a value which changes whenever the selection changes, regardless of whether the selection is
+ # collapsed or not.
+ hashSelection: ->
+ [ @element?.selectionStart, @selection.toString().length ].join "/"
+
+ # Call a function. Return true if the selection changed as a side effect, false otherwise.
+ selectionChanged: (func) ->
+ before = @hashSelection()
+ func()
+ console.log before, @hashSelection()
+ @hashSelection() != before
+
+ # Run a movement. The single movement argument can be a string of the form "direction amount", e.g.
+ # "forward word", or a list, e.g. [ "forward", "word" ].
+ runMovement: (movement) ->
+ movement = movement.split(" ") if typeof movement == "string"
+ console.log movement.join " "
+ @selection.modify @alterMethod, movement...
+
+ # Run a sequence of movements, stopping if a movement fails to change the selection.
+ runMovements: (movements...) ->
+ for movement in movements
+ return false unless @selectionChanged => @runMovement movement
+ true
+
# Swap the anchor node/offset and the focus node/offset.
reverseSelection: ->
element = document.activeElement
@@ -91,12 +116,6 @@ class Movement extends MaintainCount
which = if direction == forward then "start" else "end"
@selection.extend original["#{which}Container"], original["#{which}Offset"]
- # Run a movement command. The single movement argument can be a string of the form "direction amount", e.g.
- # "forward word", or a list, e.g. [ "forward", "word" ].
- runMovement: (movement) ->
- movement = movement.split(" ") if typeof movement == "string"
- @selection.modify @alterMethod, movement...
-
# Try to move one character in "direction". Return 1, -1 or 0, indicating whether the selection got bigger,
# or smaller, or is unchanged.
moveInDirection: (direction) ->
@@ -115,9 +134,13 @@ class Movement extends MaintainCount
return if 0 < success then direction else @opposite[direction]
backward
- # An approximation of the vim "w" movement.
- moveForwardWord: (direction) ->
- @runMovement movement for movement in [ "forward word", "forward word", "backward word" ]
+ # An approximation of the vim "w" movement; only ever used in the forward direction. The extra character
+ # movements at the end allow us to also get to the end of the very-last word.
+ moveForwardWord: () ->
+ # First, move to the end of the preceding word...
+ if @runMovements "forward character", "backward word", "forward word"
+ # And then to the start of the following word...
+ @runMovements "forward word", "forward character", "backward character", "backward word"
collapseSelection: ->
if 0 < @selection.toString().length