On 25-Jun-15, Nikolay Pavlov wrote:
> 2015-06-21 21:17 GMT+03:00 Olaf Dabrunz <[email protected]>:
> > On 21-Jun-15, Manuel Ortega wrote:
> >> Doing ":h diffoff" gives:
> >>
> >> The ":diffoff" command resets the relevant options to the values they
> >> had when using |:diffsplit|, |:diffpatch| , |:diffthis|. or starting Vim
> >> in diff mode.  Otherwise they are set to their default value:
> >>
> >>     'diff'          off
> >>     'scrollbind'    off
> >>     'cursorbind'    off
> >>     'scrollopt'     without "hor"
> >>     'wrap'          on
> >>     'foldmethod'    "manual"
> >>     'foldcolumn'    0
> >>
> >> What this doesn't tell you is that :diffoff will perform this resetting
> >> under more circumstances than mentioned, namely if diff mode was already
> >> off; but in this circumstance, the resetting is both unexpected and
> >> undesirable.
> >
> > This is intentional.  There have been discussions and patches touching
> > this:
> >
> >     [PATCH] :diffoff should not change settings for non-diff windows
> >     Lech Lorens
> >     https://groups.google.com/forum/#!topic/vim_dev/UEqB5ppy49g
> >
> >     [patch] diffoff! does not check &diff in current window
> >     Charles Cooper
> >     https://groups.google.com/forum/#!topic/vim_dev/IOvSxDIJIqY
> >
> > The documentation for 'diffoff' was updated in 7.4.490:
> >
> >     :diffo[ff]      Switch off diff mode for the current window.  Resets
> >                     related options also when 'diff' was not set.
> >
> > ':diffoff' works even when the current window does not have 'diff' set,
> > because people tend to ':set nodiff', and only then remember to
> > ':diffoff' to get rid of the other settings made by ':diffthis'.
> >
> >> Specifically, if you forget that diff mode is already off and you do
> >> :diffoff a second time, you will lose &scrollbind, &foldmethod, &wrap,
> >> etc if you had them set to something other than those defaults.  This is
> >> really annoying.  I kept wondering what happened to my folds!
> >> Sometimes I had &scrollbind on outside of diff mode, and I lost it after
> >> inadvertently doing a second :diffoff.
> >
> > So the problem seems to be that ':diffoff' forgets about the saved
> > values when it is used the first time, so on the second ':diffoff' it
> > restores the defaults.
> >
> > The patch below changes this so that the saved settings are never
> > forgotten.  And with the patch they get updated whenever ':diffthis' or
> > friends are used on a window that is not yet in 'diff' mode.
> >
> > So a second ':diffthis' in a diff window does not overwrite the settings
> > saved when entering diff mode.  And a second ':diffoff' restores the
> > settings that were saved the last time when this window entered diff
> > mode.
> >
> > A second ':diffoff' can of course still lose settings that you made
> > after the first ':diffoff'.  But I do not see a simple solution for
> > that.  Maybe you can live with that.
> >
> > No documentation in the patch, because in my understanding the current
> > docs seem to imply this behavior:
> >
> >     The ":diffoff" command resets the relevant options to the values
> >     they had when using |:diffsplit|, |:diffpatch| , |:diffthis|. or
> >     starting Vim in diff mode.  Otherwise they are set to their default
> >     value:
> >
> >
> > With the patch, ':diffoff' will only restore the defaults if the window
> > has never been in a diff.
> >
> > Question to the list: should ':diffoff' *ever* restore default settings?
> >
> > Maybe it is better to only restore settings that have been saved before,
> > when entering diff mode at some point, if that has happened at all.
> >
> > Because if the window was never switched to diff mode, why should
> > ':diffoff' restore settings that have never been changed by diff mode,
> > and then to some arbitrary defaults?  Better leave these settings
> > untouched in that case?
> 
> In addition to windows that have never been in diff mode there are
> windows which have never been in *non-diff* mode: i.e. first window
> obtained using `vim -d` (command
> 
>     vim -u NONE -i NONE -N --cmd 'au FileType * :echomsg "diff:"
> &diff' --cmd 'filetype plugin indent on' --cmd 'echomsg "diffinit:"
> join(map(range(1, winnr("$")), "getwinvar(v:val, \"&diff\")"))' -d
> /tmp/a.py /tmp/b.py
> 
> or (assuming /tmp/a.py and /tmp/b.py are already present) (no, BufNew,
> BufEnter and BufAdd are either not launched at all (!) or are launched
> too late (BufEnter))
> 
>     vim -u NONE -i NONE -N --cmd 'au BufRead * :echomsg "diff:" &diff'
> --cmd 'echomsg "diffinit:" join(map(range(1, winnr("$")),
> "getwinvar(v:val, \"&diff\")"))' -d /tmp/a.py /tmp/b.py
> 
> will show you that first window was created immediately and with &diff
> already on, second window is created later and &diff is set to zero at
> least when file is read and also then when filetype plugins are
> sourced after detecting filetype).
> 
> Note: only *one* window has this property, and only when using vimdiff
> (via explicit -d switch in my example). Window created with :diffsplit
> is also created in non-diff mode which continues at least until
> filetype plugins are sourced.

Still, the settings for this window are saved:

    src/main.c:560:

        /* Set the 'diff' option now, so that it can be checked for in a .vimrc
         * file.  There is no buffer yet though. */
        if (params.diff_mode)
            diff_win_options(firstwin, FALSE);

So even for this window we can restore saved settings.  In this case,
the saved settings are probably similarly harmful or harmless as default
settings in :diffoff are.

I tested :diffoff in a 'vi -d <file1> <file2>' with the no-defaults
patch for :diffoff applied.  (Also before sending it to the list.)
:diffoff works in both windows.

Window 1:

    :set diff? fdm? fdc? scb? crb? wrap?
    nodiff
      foldmethod=manual
      foldcolumn=0
    noscrollbind
    nocursorbind
      wrap

Window 2:

    :set diff? fdm? fdc? scb? crb? wrap?
    nodiff
      foldmethod=marker
      foldcolumn=0
    noscrollbind
    nocursorbind
      wrap

> >> It's pretty easy to be lulled into thinking you need a :diffoff.  If you
> >> see a bunch of closed folds, you might think that's because you just
> >> resolved the last difference, and now it's time to turn diff mode off.
> 
> If you have resolved all differences you will not see a bunch of
> closed folds. There will be *one* fold per window, exactly one and, at
> least, in two adjacent windows. I do not see how this makes lulling
> easy, at all. Also &foldcolumn needs to be equal to 2 (or whatever
> setting in &diffopt) on regular basis because this thing is very
> notable.

Yes.

This leaves user error as a reason for using :diffoff a second time.

So the patch would only make :diffoff somewhat safer to use.

> >> I'm very much hoping that someone who knows how vim code works can make
> >> a patch so that :diffoff will only do that resetting if diff mode was ON
> >> when :diffoff was called.
> >>
> >> -Manny
> >
> >
> > --- a/src/diff.c        2015-04-11 08:33:38.074355329 +0200
> > +++ b/src/diff.c        2015-06-21 19:59:39.856293311 +0200
> > @@ -1138,32 +1138,34 @@ diff_win_options(wp, addbuf)
> >      curwin = old_curwin;
> >  # endif
> >
> > -    wp->w_p_diff = TRUE;
> > -
> >      /* Use 'scrollbind' and 'cursorbind' when available */
> >  #ifdef FEAT_SCROLLBIND
> > -    if (!wp->w_p_diff_saved)
> > +    if (!wp->w_p_diff)
> >         wp->w_p_scb_save = wp->w_p_scb;
> >      wp->w_p_scb = TRUE;
> >  #endif
> >  #ifdef FEAT_CURSORBIND
> > -    if (!wp->w_p_diff_saved)
> > +    if (!wp->w_p_diff)
> >         wp->w_p_crb_save = wp->w_p_crb;
> >      wp->w_p_crb = TRUE;
> >  #endif
> > -    if (!wp->w_p_diff_saved)
> > +    if (!wp->w_p_diff)
> >         wp->w_p_wrap_save = wp->w_p_wrap;
> >      wp->w_p_wrap = FALSE;
> >  # ifdef FEAT_FOLDING
> >      curwin = wp;
> >      curbuf = curwin->w_buffer;
> > -    if (!wp->w_p_diff_saved)
> > +    if (!wp->w_p_diff)
> > +    {
> > +       if (wp->w_p_diff_saved)
> > +           free_string_option(wp->w_p_fdm_save);
> >         wp->w_p_fdm_save = vim_strsave(wp->w_p_fdm);
> > +    }
> >      set_string_option_direct((char_u *)"fdm", -1, (char_u *)"diff",
> >                                                        OPT_LOCAL|OPT_FREE, 
> > 0);
> >      curwin = old_curwin;
> >      curbuf = curwin->w_buffer;
> > -    if (!wp->w_p_diff_saved)
> > +    if (!wp->w_p_diff)
> >      {
> >         wp->w_p_fdc_save = wp->w_p_fdc;
> >         wp->w_p_fen_save = wp->w_p_fen;
> > @@ -1183,6 +1185,8 @@ diff_win_options(wp, addbuf)
> >      /* Saved the current values, to be restored in ex_diffoff(). */
> >      wp->w_p_diff_saved = TRUE;
> >
> > +    wp->w_p_diff = TRUE;
> > +
> >      if (addbuf)
> >         diff_buf_add(wp->w_buffer);
> >      redraw_win_later(wp, NOT_VALID);
> > @@ -1226,8 +1230,7 @@ ex_diffoff(eap)
> >             if (wp->w_p_diff_saved)
> >             {
> >                 free_string_option(wp->w_p_fdm);
> > -               wp->w_p_fdm = wp->w_p_fdm_save;
> > -               wp->w_p_fdm_save = empty_option;
> > +               wp->w_p_fdm = vim_strsave(wp->w_p_fdm_save);
> >             }
> >             else
> >                 set_string_option_direct((char_u *)"fdm", -1,
> > @@ -1255,8 +1258,6 @@ ex_diffoff(eap)
> >  #endif
> >             /* Note: 'sbo' is not restored, it's a global option. */
> >             diff_buf_adjust(wp);
> > -
> > -           wp->w_p_diff_saved = FALSE;
> >         }
> >  #ifdef FEAT_SCROLLBIND
> >         diffwin |= wp->w_p_diff;
> >
> > --
> > Olaf Dabrunz (oda <at> fctrace.org)
> >
> > --
> > --
> > You received this message from the "vim_dev" maillist.
> > Do not top-post! Type your reply below the text you are replying to.
> > For more information, visit http://www.vim.org/maillist.php
> >
> > ---
> > You received this message because you are subscribed to the Google Groups 
> > "vim_dev" group.
> > To unsubscribe from this group and stop receiving emails from it, send an 
> > email to [email protected].
> > For more options, visit https://groups.google.com/d/optout.
> 
> -- 
> -- 
> You received this message from the "vim_dev" maillist.
> Do not top-post! Type your reply below the text you are replying to.
> For more information, visit http://www.vim.org/maillist.php
> 
> --- 
> You received this message because you are subscribed to the Google Groups 
> "vim_dev" group.
> To unsubscribe from this group and stop receiving emails from it, send an 
> email to [email protected].
> For more options, visit https://groups.google.com/d/optout.

-- 
Olaf Dabrunz (oda <at> fctrace.org)

-- 
-- 
You received this message from the "vim_dev" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php

--- 
You received this message because you are subscribed to the Google Groups 
"vim_dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
For more options, visit https://groups.google.com/d/optout.

Raspunde prin e-mail lui