JasonWoof Got questions, comments, patches, etc.? Contact Jason Woofenden
up/down keys remember orig x past short lines
authorJason Woofenden <jason@jasonwoof.com>
Fri, 25 Mar 2016 21:48:58 +0000 (17:48 -0400)
committerJason Woofenden <jason@jasonwoof.com>
Fri, 25 Mar 2016 21:54:10 +0000 (17:54 -0400)
editor.coffee

index 73d863e..1b2503e 100644 (file)
@@ -371,6 +371,71 @@ find_prev_cursor_position = (tree, cursor) ->
                return false
        return found # maybe null
 
+find_up_cursor_position = (tree, cursor, ideal_x) ->
+       new_cursor = cursor
+       # go prev until we're higher on y axis
+       while new_cursor.y >= cursor.y
+               new_cursor = find_prev_cursor_position tree, new_cursor
+               return null unless new_cursor?
+       # done early if we're already left of old cursor position
+       if new_cursor.x <= ideal_x
+               return new_cursor
+       target_y = new_cursor.y
+       # search leftward, until we find the closest position
+       # new_cursor is the prev-most position we've checked
+       # prev_cursor is the older value, so it's not as prev as new_cursor
+       while new_cursor.x > ideal_x and new_cursor.y is target_y
+               prev_cursor = new_cursor
+               new_cursor = find_prev_cursor_position tree, new_cursor
+               break unless new_cursor?
+       # move cursor to prev_cursor or new_cursor
+       if new_cursor?
+               if new_cursor.y is target_y
+                       # both valid, and on the same line, use closest
+                       if (ideal_x - new_cursor.x) < (prev_cursor.x - ideal_x)
+                               return new_cursor
+                       else
+                               return prev_cursor
+               else
+                       # new_cursor on wrong line, use prev_cursor
+                       return prev_cursor
+       else
+               # can't go any further prev, use prev_cursor
+               return prev_cursor
+
+find_down_cursor_position = (tree, cursor, ideal_x) ->
+       new_cursor = cursor
+       # go next until we move on the y axis
+       while new_cursor.y <= cursor.y
+               new_cursor = find_next_cursor_position tree, new_cursor
+               return null unless new_cursor?
+       # done early if we're already right of old cursor position
+       if new_cursor.x >= ideal_x
+               # this would be strange, but could happen due to runaround
+               return new_cursor
+       target_y = new_cursor.y
+       # search rightward, until we find the closest position
+       # new_cursor is the next-most position we've checked
+       # prev_cursor is the older value, so it's not as next as new_cursor
+       while new_cursor.x < ideal_x and new_cursor.y is target_y
+               prev_cursor = new_cursor
+               new_cursor = find_next_cursor_position tree, new_cursor
+               break unless new_cursor?
+       # move cursor to prev_cursor or new_cursor
+       if new_cursor?
+               if new_cursor.y is target_y
+                       # both valid, and on the same line, use closest
+                       if (new_cursor.x - ideal_x) < (ideal_x - prev_cursor.x)
+                               return new_cursor
+                       else
+                               return prev_cursor
+               else
+                       # new_cursor on wrong line, use prev_cursor
+                       return prev_cursor
+       else
+               # can't go any further prev, use prev_cursor
+               return prev_cursor
+
 xy_to_cursor = (tree, xy) ->
        for n in tree
                if n.type is 'tag' or n.type is 'text'
@@ -612,6 +677,7 @@ class PeachHTML5Editor
                @cursor = null
                @cursor_el = null
                @cursor_visible = false
+               @cursor_ideal_x = null
                @poll_for_blur_timeout = null
                opt_fragment = @options.fragment ? true
                @parser_opts = {}
@@ -826,37 +892,11 @@ class PeachHTML5Editor
                                return false
                        when KEY_UP
                                if @cursor?
-                                       new_cursor = @cursor
-                                       # go prev until we're higher on y axis
-                                       while new_cursor.y >= @cursor.y
-                                               new_cursor = find_prev_cursor_position @tree, new_cursor
-                                               return false unless new_cursor?
-                                       # done early if we're already left of old cursor position
-                                       if new_cursor.x <= @cursor.x
-                                               @move_cursor new_cursor
-                                               return false
-                                       target_y = new_cursor.y
-                                       # search leftward, until we find the closest position
-                                       # new_cursor is the prev-most position we've checked
-                                       # prev_cursor is the older value, so it's not as prev as new_cursor
-                                       while new_cursor.x > @cursor.x and new_cursor.y is target_y
-                                               prev_cursor = new_cursor
-                                               new_cursor = find_prev_cursor_position @tree, new_cursor
-                                               break unless new_cursor?
-                                       # move cursor to prev_cursor or new_cursor
+                                       new_cursor = find_up_cursor_position @tree, @cursor, @cursor_ideal_x
                                        if new_cursor?
-                                               if new_cursor.y is target_y
-                                                       # both valid, and on the same line, use closest
-                                                       if (@cursor.x - new_cursor.x) < (prev_cursor.x - @cursor.x)
-                                                               @move_cursor new_cursor
-                                                       else
-                                                               @move_cursor prev_cursor
-                                               else
-                                                       # new_cursor on wrong line, use prev_cursor
-                                                       @move_cursor prev_cursor
-                                       else
-                                               # can't go any further prev, use prev_cursor
-                                               @move_cursor prev_cursor
+                                               saved_ideal_x = @cursor_ideal_x
+                                               @move_cursor new_cursor
+                                               @cursor_ideal_x = saved_ideal_x
                                else
                                        # move cursor to first position in document
                                        new_cursor = first_cursor_position @tree
@@ -865,38 +905,11 @@ class PeachHTML5Editor
                                return false
                        when KEY_DOWN
                                if @cursor?
-                                       new_cursor = @cursor
-                                       # go next until we move on the y axis
-                                       while new_cursor.y <= @cursor.y
-                                               new_cursor = find_next_cursor_position @tree, new_cursor
-                                               return false unless new_cursor?
-                                       # done early if we're already right of old cursor position
-                                       if new_cursor.x >= @cursor.x
-                                               # this would be strange, but could happen due to runaround
-                                               @move_cursor new_cursor
-                                               return false
-                                       target_y = new_cursor.y
-                                       # search rightward, until we find the closest position
-                                       # new_cursor is the next-most position we've checked
-                                       # prev_cursor is the older value, so it's not as next as new_cursor
-                                       while new_cursor.x < @cursor.x and new_cursor.y is target_y
-                                               prev_cursor = new_cursor
-                                               new_cursor = find_next_cursor_position @tree, new_cursor
-                                               break unless new_cursor?
-                                       # move cursor to prev_cursor or new_cursor
+                                       new_cursor = find_down_cursor_position @tree, @cursor, @cursor_ideal_x
                                        if new_cursor?
-                                               if new_cursor.y is target_y
-                                                       # both valid, and on the same line, use closest
-                                                       if (new_cursor.x - @cursor.x) < (@cursor.x - prev_cursor.x)
-                                                               @move_cursor new_cursor
-                                                       else
-                                                               @move_cursor prev_cursor
-                                               else
-                                                       # new_cursor on wrong line, use prev_cursor
-                                                       @move_cursor prev_cursor
-                                       else
-                                               # can't go any further prev, use prev_cursor
-                                               @move_cursor prev_cursor
+                                               saved_ideal_x = @cursor_ideal_x
+                                               @move_cursor new_cursor
+                                               @cursor_ideal_x = saved_ideal_x
                                else
                                        # move cursor to first position in document
                                        new_cursor = last_cursor_position @tree
@@ -1073,6 +1086,7 @@ class PeachHTML5Editor
                @cursor = null
                @annotate null
        move_cursor: (cursor) ->
+               @cursor_ideal_x = cursor.x
                @cursor = cursor
                unless @cursor_visible
                        @cursor_el = domify @outer_idoc, div: id: 'cursor'