emacs-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: C-g while exiting the minibuffer


From: Stefan Monnier
Subject: Re: C-g while exiting the minibuffer
Date: Thu, 28 Nov 2013 14:22:04 -0500
User-agent: Gnus/5.13 (Gnus v5.13) Emacs/24.3.50 (gnu/linux)

> I still have hare/tortoise implementations of Fset_window_prev_buffers
> and Fset_window_next_buffers (for pure curiosity I attach the
> corresponding part of a larger patch here).  Chong didn't want to
> install them then because he considered it overengineering.  Installing
> them means select_window could safely modify these lists with quitting
> inhibited.

To tell you the truth, I'm not worried about the risk of non-termination
if we inhibit quit during record_buffer (even with the current code).
I do agree that if we did that, we might want to use a hare/tortoise
thingy to avoid inf-loops, but the main problem for me is whether we
want to inhibit quit or not and if we do, over which part of the code.

Generally we prefer not to inhibit quit, and instead we order statements
in such a way that any intermediate point is safe.  I'll probably
install a patch following this principle.

But the problem remains of what to do with a C-g interrupting a unwind
form: in the case of an Fset_window_configuration in an unwind form, the
intention is to make that "no matter what happens, we end up recovering
the original state", but a C-g at the wrong time will break this promise.

>  {
> -  return decode_window (window)->prev_buffers = prev_buffers;
> +  register struct window *w = decode_window (window);
> +
> +  if (NILP (prev_buffers))
> +    return w->prev_buffers = Qnil;
> +  else if (!CONSP (prev_buffers))
> +    return w->prev_buffers;
> +  else
> +    {
> +      /* Run cycle detection on prev_buffers.  */
> +      Lisp_Object tortoise, hare;
> +
> +      hare = tortoise = prev_buffers;
> +      while (CONSP (hare))
> +     {
> +       hare = XCDR (hare);
> +       if (!CONSP (hare))
> +         break;
> +
> +       hare = XCDR (hare);
> +       tortoise = XCDR (tortoise);
> +
> +       if (EQ (hare, tortoise))
> +         return w->prev_buffers;
> +     }
> +
> +      return w->prev_buffers = prev_buffers;
> +    }
>  }

comments:
- we used to have a "DOLIST" kind of macro which did the hare/tortoise
  thing in lisp.h.  Not sure what happened to it, but I'd rather use
  such a macro then duplicate the corresponding code wherever we have
  such a loop.
- checking cycles here gives us no guarantee since the caller can do

    (set-window-prev-buffers w bufs)
    (setcdr bufs bufs)

  and you again end up with a cycle in your window-prev-buffers.


-- Stefan



reply via email to

[Prev in Thread] Current Thread [Next in Thread]