+ on_page_up_key: (e) ->
+ scroll_amount = @wrap2_height - breathing_room
+ # scroll up a page
+ @wrap2.scrollTop = Math.max 0, @wrap2.scrollTop - scroll_amount
+ # note: if cursor innacuracy causes it no not be within new scroll,
+ # @move_cursor will adjust the scroll a bit.
+ if @cursor?
+ # move cursor up approximately scroll_amount
+ was = @cursor
+ y_target = @cursor.y - scroll_amount
+ y_min = Math.min y_target, @wrap2.scrollTop
+ y_max = Math.min y_target, @wrap2.scrollTop - scroll_amount
+ y_target = Math.min y_target, y_max
+ y_target = Math.max y_target, y_min
+ loop
+ cur = find_up_cursor_position @tree, was, @cursor_ideal_x
+ break unless cur?
+ break if cur.y <= y_target
+ was = cur
+ if was is @cursor
+ if cur?
+ new_cursor = cur
+ else
+ # should this move the cursor to the beginning of the line?
+ new_cursor = null
+ else
+ if cur?
+ # both valid, pick best
+ if cur.y < y_min
+ new_cursor = was
+ else if was.y > y_max
+ new_cursor = cur
+ else if cur.y - y_target < y_target - was.y
+ new_cursor = cur
+ else
+ new_cursor = was
+ else
+ new_cursor = was
+ if new_cursor?
+ saved_ideal_x = @cursor_ideal_x
+ @move_cursor new_cursor
+ @cursor_ideal_x = saved_ideal_x
+ return