From 0e48ade448937b84f60cb57d13aa9851e2eb3976 Mon Sep 17 00:00:00 2001 From: Jason Woofenden Date: Fri, 25 Mar 2016 17:48:58 -0400 Subject: [PATCH] up/down keys remember orig x past short lines --- editor.coffee | 136 +++++++++++++++++++++++++++++++-------------------------- 1 file changed, 75 insertions(+), 61 deletions(-) diff --git a/editor.coffee b/editor.coffee index 73d863e..1b2503e 100644 --- a/editor.coffee +++ b/editor.coffee @@ -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' -- 1.7.10.4