Hi

The EOL tracking seems to be a bit broken at the moment but I don't
think this is right either, it should work like emacs - when you go to
the end of a line, that column becomes sticky. So with:

xx
abcdef
abc

If you go to the second line and then press C-e to move to th end, then
press up, the cursor should be on the d. If you press up again it should
be at the end of the first line, but then pressing down again should
move it back to the d.

At the moment tmux seems to do something completely weird but pretty
sure I intended it to work like emacs...


On Wed, Jun 12, 2013 at 02:17:58AM -0400, Ben Boeckel wrote:
> When the EOL command is used, vim tracks that the EOL is the cursor
> position, not the cursor that the EOL happened to occur on for the line
> where the motion was given. To keep track of this, an EOL flag is added
> to indicate this state. Most motions will clear this state, but a few
> such as block mode toggle, up, down and right (on the last line)
> preserve this state.
> 
> This change has the biggest impact on the block selection mode and
> navigation (the cursor "sticks" to the end of the line rather than a
> column when moving up and down). Block selection mode already has a "end
> of screen" state, so no extra state is tracked for it.
> ---
>  window-copy.c | 39 ++++++++++++++++++++++++++++++++++-----
>  1 file changed, 34 insertions(+), 5 deletions(-)
> 
> diff --git a/window-copy.c b/window-copy.c
> index 325c29f..ee6a2e8 100644
> --- a/window-copy.c
> +++ b/window-copy.c
> @@ -131,6 +131,7 @@ struct window_copy_mode_data {
>       u_int           sely;
>  
>       u_int           rectflag; /* are we in rectangle copy mode? */
> +     u_int           eolflag; /* are we at the end of the line? */
>  
>       u_int           cx;
>       u_int           cy;
> @@ -169,6 +170,7 @@ window_copy_init(struct window_pane *wp)
>       data->backing_written = 0;
>  
>       data->rectflag = 0;
> +     data->eolflag = 0;
>  
>       data->inputtype = WINDOW_COPY_OFF;
>       data->inputprompt = NULL;
> @@ -365,11 +367,18 @@ window_copy_key(struct window_pane *wp, struct session 
> *sess, int key)
>       const char                      *word_separators;
>       struct window_copy_mode_data    *data = wp->modedata;
>       struct screen                   *s = &data->screen;
> -     u_int                            n;
> +     u_int                            n, old_eolflag;
>       int                              np, keys;
>       enum mode_key_cmd                cmd;
>       const char                      *arg;
>  
> +     /* By default, all motions break the cursor from the sticky "eol"
> +      * position. Only select commands preserve the state (up, down, the eol
> +      * motion itself and right (which may clear it on its own). These
> +      * commands should restore the eolflag as needed. */
> +     old_eolflag = data->eolflag;
> +     data->eolflag = 0;
> +
>       np = data->numprefix;
>       if (np <= 0)
>               np = 1;
> @@ -420,22 +429,29 @@ window_copy_key(struct window_pane *wp, struct session 
> *sess, int key)
>                       window_copy_cursor_left(wp);
>               break;
>       case MODEKEYCOPY_RIGHT:
> +             /* If the EOL flag needs clearing, window_copy_cursor_right
> +              * clears it. */
> +             data->eolflag = old_eolflag;
>               for (; np != 0; np--)
>                       window_copy_cursor_right(wp);
>               break;
>       case MODEKEYCOPY_UP:
> +             data->eolflag = old_eolflag;
>               for (; np != 0; np--)
>                       window_copy_cursor_up(wp, 0);
>               break;
>       case MODEKEYCOPY_DOWN:
> +             data->eolflag = old_eolflag;
>               for (; np != 0; np--)
>                       window_copy_cursor_down(wp, 0);
>               break;
>       case MODEKEYCOPY_SCROLLUP:
> +             data->eolflag = old_eolflag;
>               for (; np != 0; np--)
>                       window_copy_cursor_up(wp, 1);
>               break;
>       case MODEKEYCOPY_SCROLLDOWN:
> +             data->eolflag = old_eolflag;
>               for (; np != 0; np--)
>                       window_copy_cursor_down(wp, 1);
>               break;
> @@ -559,6 +575,7 @@ window_copy_key(struct window_pane *wp, struct session 
> *sess, int key)
>               window_copy_cursor_back_to_indentation(wp);
>               break;
>       case MODEKEYCOPY_ENDOFLINE:
> +             data->eolflag = 1;
>               window_copy_cursor_end_of_line(wp);
>               break;
>       case MODEKEYCOPY_NEXTSPACE:
> @@ -707,6 +724,7 @@ window_copy_key(struct window_pane *wp, struct session 
> *sess, int key)
>               }
>               break;
>       case MODEKEYCOPY_RECTANGLETOGGLE:
> +             data->eolflag = old_eolflag;
>               window_copy_rectangle_toggle(wp);
>               break;
>       default:
> @@ -1600,8 +1618,13 @@ window_copy_cursor_end_of_line(struct window_pane *wp)
>       px = window_copy_find_length(wp, py);
>  
>       if (data->cx == px) {
> -             if (data->screen.sel.flag && data->rectflag)
> +             if (data->screen.sel.flag && data->rectflag) {
>                       px = screen_size_x(back_s);
> +                     /* The flag is reset here since we're not on the
> +                      * end-of-line as defined by the text, but rather by
> +                      * the screen. */
> +                     data->eolflag = 0;
> +             }
>               if (gd->linedata[py].flags & GRID_LINE_WRAPPED) {
>                       while (py < gd->sy + gd->hsize &&
>                           gd->linedata[py].flags & GRID_LINE_WRAPPED) {
> @@ -1660,8 +1683,10 @@ window_copy_cursor_right(struct window_pane *wp)
>  
>               /* If there is no line after the current line, there
>                * is no need to move to the start of the line. */
> -             if (data->cy != py)
> +             if (data->cy != py) {
> +                     data->eolflag = 0;
>                       window_copy_cursor_start_of_line(wp);
> +             }
>       } else {
>               window_copy_update_cursor(wp, data->cx + 1, data->cy);
>               if (window_copy_update_selection(wp))
> @@ -1702,7 +1727,9 @@ window_copy_cursor_up(struct window_pane *wp, int 
> scroll_only)
>               }
>       }
>  
> -     if (!data->screen.sel.flag || !data->rectflag) {
> +     if (data->eolflag)
> +             window_copy_cursor_end_of_line(wp);
> +     else if (!data->screen.sel.flag || !data->rectflag) {
>               py = screen_hsize(data->backing) + data->cy - data->oy;
>               px = window_copy_find_length(wp, py);
>               if ((data->cx >= data->lastsx && data->cx != px) ||
> @@ -1736,7 +1763,9 @@ window_copy_cursor_down(struct window_pane *wp, int 
> scroll_only)
>                       window_copy_redraw_lines(wp, data->cy - 1, 2);
>       }
>  
> -     if (!data->screen.sel.flag || !data->rectflag) {
> +     if (data->eolflag)
> +             window_copy_cursor_end_of_line(wp);
> +     else if (!data->screen.sel.flag || !data->rectflag) {
>               py = screen_hsize(data->backing) + data->cy - data->oy;
>               px = window_copy_find_length(wp, py);
>               if ((data->cx >= data->lastsx && data->cx != px) ||
> -- 
> 1.8.2.1
> 
> 
> ------------------------------------------------------------------------------
> This SF.net email is sponsored by Windows:
> 
> Build for Windows Store.
> 
> http://p.sf.net/sfu/windows-dev2dev
> _______________________________________________
> tmux-users mailing list
> tmux-users@lists.sourceforge.net
> https://lists.sourceforge.net/lists/listinfo/tmux-users

------------------------------------------------------------------------------
This SF.net email is sponsored by Windows:

Build for Windows Store.

http://p.sf.net/sfu/windows-dev2dev
_______________________________________________
tmux-users mailing list
tmux-users@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/tmux-users

Reply via email to