unofficial mirror of emacs-devel@gnu.org 
 help / color / mirror / code / Atom feed
* Shift selection using interactive spec
@ 2008-03-13 23:29 Chong Yidong
  2008-03-14  0:44 ` Thomas Lord
  2008-03-14  4:06 ` Dan Nicolaescu
  0 siblings, 2 replies; 167+ messages in thread
From: Chong Yidong @ 2008-03-13 23:29 UTC (permalink / raw)
  To: emacs-devel

Here is a prototype for implementing shift-selection using a new
interactive spec code, `^'.  It uses transient-mark-mode's `only'
setting as suggested by Miles and Johan.

I haven't changed all the movement commands, just enough of them to
play around with the shift selection.  (left, right, up, down, etc).

Currently, M-F doesn't DTRT, but this appears to be due to an existing
bug (feature?): if there is no mapping for M-F, Emacs 22 translates it
to M-f, while Emacs 23 translates it to f.  I haven't tracked down
where this change was made.

A few observations:

Firstly, if we adopt this approach, we have to work around the fact
that read_key_sequence automatically attempts translates unbound key
sequences by trying to shift them (e.g., changing S-right to right).
Here, I create a new global variable
this_command_keys_shift_translated, which is set to 1 by
read_key_sequence when it does this translation.  This tells
Fcall_interactively that the activating key sequence is indeed
shifted, regardless of what this_command_keys says.

The present code probably doesn't handle shifting/shifting properly
when Fread_key_sequence is called from Lisp, but that is easily
remedied.

Secondly, there are two C level functions, direct_output_forward_char
and direct_output_forward_char, which are called instead of
forward_char and backward_char if certain conditions are met.  This is
a redisplay optimization.  To get this to work, we must avoid using
these functions when appropriate.  In the present code, I don't call
them when this_command_keys_shift_translated is non-zero, but this may
need more analysis.

Thirdly, I'm not too happy about the variable separation in this code.
Here, callint.c pulls in this_command_keys_shift_translated and
this_single_command_key_start from keyboard.c, Qonly from frame.h,
Qidentity from casefiddle.c, and it needs to call intern ("shift") on
each invokation to get the symbol for `shift'.  If we end up going
with this approach, maybe someone could suggest a way to clean up
these variables.

Comments are welcome.


*** trunk/src/callint.c.~1.161.~	2008-02-21 11:10:47.000000000 -0500
--- trunk/src/callint.c	2008-03-13 18:48:05.000000000 -0400
***************
*** 121,128 ****
  If the string begins with `@', then Emacs searches the key sequence
   which invoked the command for its first mouse click (or any other
   event which specifies a window), and selects that window before
!  reading any arguments.  You may use both `@' and `*'; they are
!  processed in the order that they appear.
  usage: (interactive ARGS)  */)
       (args)
       Lisp_Object args;
--- 121,132 ----
  If the string begins with `@', then Emacs searches the key sequence
   which invoked the command for its first mouse click (or any other
   event which specifies a window), and selects that window before
!  reading any arguments.
! If the string begins with `^', and the key sequence which invoked the
!  command contains the shift modifier, then Emacs activates Transient
!  Mark Mode temporarily for this command.
! You may use `@', `*', and `^' together; they are processed in the
!  order that they appear.
  usage: (interactive ARGS)  */)
       (args)
       Lisp_Object args;
***************
*** 244,249 ****
--- 248,258 ----
      }
  }
  
+ extern int this_command_keys_shift_translated;
+ extern int this_single_command_key_start;
+ extern Lisp_Object Qonly;
+ extern Lisp_Object Qidentity;
+ 
  DEFUN ("call-interactively", Fcall_interactively, Scall_interactively, 1, 3, 0,
         doc: /* Call FUNCTION, reading args according to its interactive calling specs.
  Return the value FUNCTION returns.
***************
*** 423,428 ****
--- 432,469 ----
        /* Ignore this for semi-compatibility with Lucid.  */
        else if (*string == '-')
  	string++;
+       else if (*string == '^')
+ 	{
+ 	  Lisp_Object *key = XVECTOR (this_command_keys)->contents
+ 	    + this_single_command_key_start;
+ 	  Lisp_Object *key_max = XVECTOR (this_command_keys)->contents
+ 	    + this_command_key_count;
+ 	  Lisp_Object shift = intern ("shift");
+ 	  int shifted = this_command_keys_shift_translated;
+ 
+ 	  if (!shifted)
+ 	    for (; key < key_max; ++key)
+ 	      {
+ 		if (SYMBOLP (*key))
+ 		  shifted = !NILP (Fmemq (shift,
+ 					  Fget (*key, Qevent_symbol_elements)));
+ 		if (!shifted)
+ 		  break;
+ 	      }
+ 
+ 	  if (shifted)
+ 	    {
+ 	      Lisp_Object push_mark_call[4] = { intern ("push-mark"),
+ 	  					Qnil, Qnil, Qt };
+ 	      if (!EQ (Vtransient_mark_mode, Qidentity))
+ 	  	Ffuncall (4, push_mark_call);
+ 	      if (EQ (Vtransient_mark_mode, Qidentity)
+ 	  	  || NILP (Vtransient_mark_mode))
+ 	  	Vtransient_mark_mode = Qonly;
+ 	    }
+ 
+ 	  string++;
+ 	}
        else if (*string == '@')
  	{
  	  Lisp_Object event, tem;
*** trunk/src/keyboard.c.~1.947.~	2008-02-25 11:04:08.000000000 -0500
--- trunk/src/keyboard.c	2008-03-13 18:49:38.000000000 -0400
***************
*** 132,137 ****
--- 132,142 ----
  Lisp_Object raw_keybuf;
  int raw_keybuf_count;
  
+ /* This is non-zero if the present key sequence was obtained by
+    unshifting a key sequence (i.e. changing an upper-case letter to
+    lower-case or a shifted function key to an unshifted one).  */
+ int this_command_keys_shift_translated;
+ 
  #define GROW_RAW_KEYBUF							\
   if (raw_keybuf_count == XVECTOR (raw_keybuf)->size)			\
     raw_keybuf = larger_vector (raw_keybuf, raw_keybuf_count * 2, Qnil)  \
***************
*** 1648,1653 ****
--- 1653,1659 ----
        Vthis_command = Qnil;
        real_this_command = Qnil;
        Vthis_original_command = Qnil;
+       this_command_keys_shift_translated = 0;
  
        /* Read next key sequence; i gets its length.  */
        i = read_key_sequence (keybuf, sizeof keybuf / sizeof keybuf[0],
***************
*** 1761,1767 ****
  
  	      /* Recognize some common commands in common situations and
  		 do them directly.  */
! 	      if (EQ (Vthis_command, Qforward_char) && PT < ZV)
  		{
                    struct Lisp_Char_Table *dp
  		    = window_display_table (XWINDOW (selected_window));
--- 1767,1774 ----
  
  	      /* Recognize some common commands in common situations and
  		 do them directly.  */
! 	      if (EQ (Vthis_command, Qforward_char) && PT < ZV
! 		  && !this_command_keys_shift_translated)
  		{
                    struct Lisp_Char_Table *dp
  		    = window_display_table (XWINDOW (selected_window));
***************
*** 1801,1807 ****
  		    direct_output_forward_char (1);
  		  goto directly_done;
  		}
! 	      else if (EQ (Vthis_command, Qbackward_char) && PT > BEGV)
  		{
                    struct Lisp_Char_Table *dp
  		    = window_display_table (XWINDOW (selected_window));
--- 1808,1815 ----
  		    direct_output_forward_char (1);
  		  goto directly_done;
  		}
! 	      else if (EQ (Vthis_command, Qbackward_char) && PT > BEGV
! 		       && !this_command_keys_shift_translated)
  		{
                    struct Lisp_Char_Table *dp
  		    = window_display_table (XWINDOW (selected_window));
***************
*** 9194,9199 ****
--- 9202,9212 ----
    /* Likewise, for key_translation_map and input-decode-map.  */
    volatile keyremap keytran, indec;
  
+   /* If we are trying to map a key by unshifting it (i.e. changing an
+      upper-case letter to lower-case or a shifted function key to an
+      unshifted one), then we set this to != 0.  */
+   volatile int shift_translated = 0;
+ 
    /* If we receive a `switch-frame' or `select-window' event in the middle of
       a key sequence, we put it off for later.
       While we're reading, we keep the event here.  */
***************
*** 10113,10118 ****
--- 10126,10133 ----
  	  keybuf[t - 1] = new_key;
  	  mock_input = max (t, mock_input);
  
+ 	  shift_translated = 1;
+ 
  	  goto replay_sequence;
  	}
        /* If KEY is not defined in any of the keymaps,
***************
*** 10154,10159 ****
--- 10169,10176 ----
  	      fkey.start = fkey.end = 0;
  	      keytran.start = keytran.end = 0;
  
+ 	      shift_translated = 1;
+ 
  	      goto replay_sequence;
  	    }
  	}
***************
*** 10191,10196 ****
--- 10208,10215 ----
      }
  
  
+   if (shift_translated && read_key_sequence_cmd)
+     this_command_keys_shift_translated = 1;
  
    UNGCPRO;
    return t;
*** trunk/src/cmds.c.~1.102.~	2008-02-01 13:47:24.000000000 -0500
--- trunk/src/cmds.c	2008-03-13 13:36:57.000000000 -0400
***************
*** 56,62 ****
    return make_number (PT + XINT (n));
  }
  
! DEFUN ("forward-char", Fforward_char, Sforward_char, 0, 1, "p",
         doc: /* Move point right N characters (left if N is negative).
  On reaching end of buffer, stop and signal error.  */)
       (n)
--- 56,62 ----
    return make_number (PT + XINT (n));
  }
  
! DEFUN ("forward-char", Fforward_char, Sforward_char, 0, 1, "^p",
         doc: /* Move point right N characters (left if N is negative).
  On reaching end of buffer, stop and signal error.  */)
       (n)
***************
*** 92,98 ****
    return Qnil;
  }
  
! DEFUN ("backward-char", Fbackward_char, Sbackward_char, 0, 1, "p",
         doc: /* Move point left N characters (right if N is negative).
  On attempt to pass beginning or end of buffer, stop and signal error.  */)
       (n)
--- 92,98 ----
    return Qnil;
  }
  
! DEFUN ("backward-char", Fbackward_char, Sbackward_char, 0, 1, "^p",
         doc: /* Move point left N characters (right if N is negative).
  On attempt to pass beginning or end of buffer, stop and signal error.  */)
       (n)
*** trunk/lisp/simple.el.~1.905.~	2008-03-10 21:57:09.000000000 -0400
--- trunk/lisp/simple.el	2008-03-13 13:39:17.000000000 -0400
***************
*** 3651,3657 ****
  If you are thinking of using this in a Lisp program, consider
  using `forward-line' instead.  It is usually easier to use
  and more reliable (no dependence on goal column, etc.)."
!   (interactive "p\np")
    (or arg (setq arg 1))
    (if (and next-line-add-newlines (= arg 1))
        (if (save-excursion (end-of-line) (eobp))
--- 3651,3657 ----
  If you are thinking of using this in a Lisp program, consider
  using `forward-line' instead.  It is usually easier to use
  and more reliable (no dependence on goal column, etc.)."
!   (interactive "^p\np")
    (or arg (setq arg 1))
    (if (and next-line-add-newlines (= arg 1))
        (if (save-excursion (end-of-line) (eobp))
***************
*** 3684,3690 ****
  If you are thinking of using this in a Lisp program, consider using
  `forward-line' with a negative argument instead.  It is usually easier
  to use and more reliable (no dependence on goal column, etc.)."
!   (interactive "p\np")
    (or arg (setq arg 1))
    (if (interactive-p)
        (condition-case nil
--- 3684,3690 ----
  If you are thinking of using this in a Lisp program, consider using
  `forward-line' with a negative argument instead.  It is usually easier
  to use and more reliable (no dependence on goal column, etc.)."
!   (interactive "^p\np")
    (or arg (setq arg 1))
    (if (interactive-p)
        (condition-case nil
***************
*** 4307,4313 ****
  (defun backward-word (&optional arg)
    "Move backward until encountering the beginning of a word.
  With argument, do this that many times."
!   (interactive "p")
    (forward-word (- (or arg 1))))
  
  (defun mark-word (&optional arg allow-extend)
--- 4307,4313 ----
  (defun backward-word (&optional arg)
    "Move backward until encountering the beginning of a word.
  With argument, do this that many times."
!   (interactive "^p")
    (forward-word (- (or arg 1))))
  
  (defun mark-word (&optional arg allow-extend)




^ permalink raw reply	[flat|nested] 167+ messages in thread

* Re: Shift selection using interactive spec
  2008-03-14  0:44 ` Thomas Lord
@ 2008-03-14  0:10   ` David Kastrup
  2008-03-14  1:22     ` Thomas Lord
  0 siblings, 1 reply; 167+ messages in thread
From: David Kastrup @ 2008-03-14  0:10 UTC (permalink / raw)
  To: Thomas Lord; +Cc: Chong Yidong, emacs-devel

Thomas Lord <lord@emf.net> writes:

> A problem (in my view) with such an approach
> is that transient mark mode has the wrong semantics
> to implement shift-marking.
>
> Transient mark mode is just about the appearance
> of the display -- whether or not the current region
> is highlighted.

Uh, no.  It is also about whether or not the current region is actively
modifying a number of commands.

> Shift-marking and other kinds of popular-style marking
> are about more than display -- it's about marks that go away
> by default, unless you keep them.

That's what the "transient" in "transient-mark-mode" is about.  Look it
up in a dictionary.  It has to be transient because it modifies the
behavior of many commands, and thus you want it deactivated as soon as
it may no longer be relevant.

-- 
David Kastrup, Kriemhildstr. 15, 44793 Bochum




^ permalink raw reply	[flat|nested] 167+ messages in thread

* Re: Shift selection using interactive spec
  2008-03-13 23:29 Shift selection using interactive spec Chong Yidong
@ 2008-03-14  0:44 ` Thomas Lord
  2008-03-14  0:10   ` David Kastrup
  2008-03-14  4:06 ` Dan Nicolaescu
  1 sibling, 1 reply; 167+ messages in thread
From: Thomas Lord @ 2008-03-14  0:44 UTC (permalink / raw)
  To: Chong Yidong; +Cc: emacs-devel

A problem (in my view) with such an approach
is that transient mark mode has the wrong semantics
to implement shift-marking.

Transient mark mode is just about the appearance
of the display -- whether or not the current region
is highlighted.

Shift-marking and other kinds of popular-style marking
are about more than display -- it's about marks that go away
by default, unless you keep them.   You go into shift-mark
mode and that sets a "tentative mark".  Some commands keep
the tentative mark in place but, by default, most commands
automatically discard it.  It's gone without a trace.  Poof.

Sure, it's nice if the display reflects where tentative marks are
but the key thing is a mark that will be quickly discarded
unless the user takes (further) explicit action.

Many other applications feature *only* tentative marks --
they lack a "mark stack".  Emacs is fancier for having a
mark stack but note that the two ideas are complementary:
it makes sense to have an Emacs-style mark stack in which
the top entry can be toggled between "tentative" and
not tentative.

If you are familiar with HP-style calculators, like the HP-41...
tentative marks in emacs would work like result values stored
in register 0.   I.e., if you type "5 enter 7 enter +" then "12"
is left in register 0 but it could be described as a "tentative
12" because if you next type anything other than "enter" (or
similar) the "12" will be automatically discarded.  That's a
tentative stack value.

For example, suppose you are cutting and pasting between
two regions of a file, widely separated.  So, you have a mark
set and use C-x C-x to move back and forth between them (being
too lazy to set registers to those points ).   But, now you want
to mark some region in one part, C-xC-x to the other, mark
a region to replace, cut out the replaced stuff and drop in the
new stuff.   Good luck not getting confused about the state
of your mark stack if you aren't concentrating on it.

With tentative marks, though,  you go to one region, set a
tentative mark, copy out the stuff you want to paste elsewhere,
silently discard the tentative mark and C-xC-x to where you want
to paste, and there you go.   (This also points out that it might be
nice if yanking set a tentative rather than a full mark.  Ditto for
major motion commands like moving to the beginning of a buffer.)

Really, the exit stairs from my soapbox on this topic are around here
somewhere.  I'm sure I'll find them soon. :-)

-t



-t




Chong Yidong wrote:
> Here is a prototype for implementing shift-selection using a new
> interactive spec code, `^'.  It uses transient-mark-mode's `only'
> setting as suggested by Miles and Johan.
>
> I haven't changed all the movement commands, just enough of them to
> play around with the shift selection.  (left, right, up, down, etc).
>
> Currently, M-F doesn't DTRT, but this appears to be due to an existing
> bug (feature?): if there is no mapping for M-F, Emacs 22 translates it
> to M-f, while Emacs 23 translates it to f.  I haven't tracked down
> where this change was made.
>
> A few observations:
>
> Firstly, if we adopt this approach, we have to work around the fact
> that read_key_sequence automatically attempts translates unbound key
> sequences by trying to shift them (e.g., changing S-right to right).
> Here, I create a new global variable
> this_command_keys_shift_translated, which is set to 1 by
> read_key_sequence when it does this translation.  This tells
> Fcall_interactively that the activating key sequence is indeed
> shifted, regardless of what this_command_keys says.
>
> The present code probably doesn't handle shifting/shifting properly
> when Fread_key_sequence is called from Lisp, but that is easily
> remedied.
>
> Secondly, there are two C level functions, direct_output_forward_char
> and direct_output_forward_char, which are called instead of
> forward_char and backward_char if certain conditions are met.  This is
> a redisplay optimization.  To get this to work, we must avoid using
> these functions when appropriate.  In the present code, I don't call
> them when this_command_keys_shift_translated is non-zero, but this may
> need more analysis.
>
> Thirdly, I'm not too happy about the variable separation in this code.
> Here, callint.c pulls in this_command_keys_shift_translated and
> this_single_command_key_start from keyboard.c, Qonly from frame.h,
> Qidentity from casefiddle.c, and it needs to call intern ("shift") on
> each invokation to get the symbol for `shift'.  If we end up going
> with this approach, maybe someone could suggest a way to clean up
> these variables.
>
> Comments are welcome.
>
>
> *** trunk/src/callint.c.~1.161.~	2008-02-21 11:10:47.000000000 -0500
> --- trunk/src/callint.c	2008-03-13 18:48:05.000000000 -0400
> ***************
> *** 121,128 ****
>   If the string begins with `@', then Emacs searches the key sequence
>    which invoked the command for its first mouse click (or any other
>    event which specifies a window), and selects that window before
> !  reading any arguments.  You may use both `@' and `*'; they are
> !  processed in the order that they appear.
>   usage: (interactive ARGS)  */)
>        (args)
>        Lisp_Object args;
> --- 121,132 ----
>   If the string begins with `@', then Emacs searches the key sequence
>    which invoked the command for its first mouse click (or any other
>    event which specifies a window), and selects that window before
> !  reading any arguments.
> ! If the string begins with `^', and the key sequence which invoked the
> !  command contains the shift modifier, then Emacs activates Transient
> !  Mark Mode temporarily for this command.
> ! You may use `@', `*', and `^' together; they are processed in the
> !  order that they appear.
>   usage: (interactive ARGS)  */)
>        (args)
>        Lisp_Object args;
> ***************
> *** 244,249 ****
> --- 248,258 ----
>       }
>   }
>   
> + extern int this_command_keys_shift_translated;
> + extern int this_single_command_key_start;
> + extern Lisp_Object Qonly;
> + extern Lisp_Object Qidentity;
> + 
>   DEFUN ("call-interactively", Fcall_interactively, Scall_interactively, 1, 3, 0,
>          doc: /* Call FUNCTION, reading args according to its interactive calling specs.
>   Return the value FUNCTION returns.
> ***************
> *** 423,428 ****
> --- 432,469 ----
>         /* Ignore this for semi-compatibility with Lucid.  */
>         else if (*string == '-')
>   	string++;
> +       else if (*string == '^')
> + 	{
> + 	  Lisp_Object *key = XVECTOR (this_command_keys)->contents
> + 	    + this_single_command_key_start;
> + 	  Lisp_Object *key_max = XVECTOR (this_command_keys)->contents
> + 	    + this_command_key_count;
> + 	  Lisp_Object shift = intern ("shift");
> + 	  int shifted = this_command_keys_shift_translated;
> + 
> + 	  if (!shifted)
> + 	    for (; key < key_max; ++key)
> + 	      {
> + 		if (SYMBOLP (*key))
> + 		  shifted = !NILP (Fmemq (shift,
> + 					  Fget (*key, Qevent_symbol_elements)));
> + 		if (!shifted)
> + 		  break;
> + 	      }
> + 
> + 	  if (shifted)
> + 	    {
> + 	      Lisp_Object push_mark_call[4] = { intern ("push-mark"),
> + 	  					Qnil, Qnil, Qt };
> + 	      if (!EQ (Vtransient_mark_mode, Qidentity))
> + 	  	Ffuncall (4, push_mark_call);
> + 	      if (EQ (Vtransient_mark_mode, Qidentity)
> + 	  	  || NILP (Vtransient_mark_mode))
> + 	  	Vtransient_mark_mode = Qonly;
> + 	    }
> + 
> + 	  string++;
> + 	}
>         else if (*string == '@')
>   	{
>   	  Lisp_Object event, tem;
> *** trunk/src/keyboard.c.~1.947.~	2008-02-25 11:04:08.000000000 -0500
> --- trunk/src/keyboard.c	2008-03-13 18:49:38.000000000 -0400
> ***************
> *** 132,137 ****
> --- 132,142 ----
>   Lisp_Object raw_keybuf;
>   int raw_keybuf_count;
>   
> + /* This is non-zero if the present key sequence was obtained by
> +    unshifting a key sequence (i.e. changing an upper-case letter to
> +    lower-case or a shifted function key to an unshifted one).  */
> + int this_command_keys_shift_translated;
> + 
>   #define GROW_RAW_KEYBUF							\
>    if (raw_keybuf_count == XVECTOR (raw_keybuf)->size)			\
>      raw_keybuf = larger_vector (raw_keybuf, raw_keybuf_count * 2, Qnil)  \
> ***************
> *** 1648,1653 ****
> --- 1653,1659 ----
>         Vthis_command = Qnil;
>         real_this_command = Qnil;
>         Vthis_original_command = Qnil;
> +       this_command_keys_shift_translated = 0;
>   
>         /* Read next key sequence; i gets its length.  */
>         i = read_key_sequence (keybuf, sizeof keybuf / sizeof keybuf[0],
> ***************
> *** 1761,1767 ****
>   
>   	      /* Recognize some common commands in common situations and
>   		 do them directly.  */
> ! 	      if (EQ (Vthis_command, Qforward_char) && PT < ZV)
>   		{
>                     struct Lisp_Char_Table *dp
>   		    = window_display_table (XWINDOW (selected_window));
> --- 1767,1774 ----
>   
>   	      /* Recognize some common commands in common situations and
>   		 do them directly.  */
> ! 	      if (EQ (Vthis_command, Qforward_char) && PT < ZV
> ! 		  && !this_command_keys_shift_translated)
>   		{
>                     struct Lisp_Char_Table *dp
>   		    = window_display_table (XWINDOW (selected_window));
> ***************
> *** 1801,1807 ****
>   		    direct_output_forward_char (1);
>   		  goto directly_done;
>   		}
> ! 	      else if (EQ (Vthis_command, Qbackward_char) && PT > BEGV)
>   		{
>                     struct Lisp_Char_Table *dp
>   		    = window_display_table (XWINDOW (selected_window));
> --- 1808,1815 ----
>   		    direct_output_forward_char (1);
>   		  goto directly_done;
>   		}
> ! 	      else if (EQ (Vthis_command, Qbackward_char) && PT > BEGV
> ! 		       && !this_command_keys_shift_translated)
>   		{
>                     struct Lisp_Char_Table *dp
>   		    = window_display_table (XWINDOW (selected_window));
> ***************
> *** 9194,9199 ****
> --- 9202,9212 ----
>     /* Likewise, for key_translation_map and input-decode-map.  */
>     volatile keyremap keytran, indec;
>   
> +   /* If we are trying to map a key by unshifting it (i.e. changing an
> +      upper-case letter to lower-case or a shifted function key to an
> +      unshifted one), then we set this to != 0.  */
> +   volatile int shift_translated = 0;
> + 
>     /* If we receive a `switch-frame' or `select-window' event in the middle of
>        a key sequence, we put it off for later.
>        While we're reading, we keep the event here.  */
> ***************
> *** 10113,10118 ****
> --- 10126,10133 ----
>   	  keybuf[t - 1] = new_key;
>   	  mock_input = max (t, mock_input);
>   
> + 	  shift_translated = 1;
> + 
>   	  goto replay_sequence;
>   	}
>         /* If KEY is not defined in any of the keymaps,
> ***************
> *** 10154,10159 ****
> --- 10169,10176 ----
>   	      fkey.start = fkey.end = 0;
>   	      keytran.start = keytran.end = 0;
>   
> + 	      shift_translated = 1;
> + 
>   	      goto replay_sequence;
>   	    }
>   	}
> ***************
> *** 10191,10196 ****
> --- 10208,10215 ----
>       }
>   
>   
> +   if (shift_translated && read_key_sequence_cmd)
> +     this_command_keys_shift_translated = 1;
>   
>     UNGCPRO;
>     return t;
> *** trunk/src/cmds.c.~1.102.~	2008-02-01 13:47:24.000000000 -0500
> --- trunk/src/cmds.c	2008-03-13 13:36:57.000000000 -0400
> ***************
> *** 56,62 ****
>     return make_number (PT + XINT (n));
>   }
>   
> ! DEFUN ("forward-char", Fforward_char, Sforward_char, 0, 1, "p",
>          doc: /* Move point right N characters (left if N is negative).
>   On reaching end of buffer, stop and signal error.  */)
>        (n)
> --- 56,62 ----
>     return make_number (PT + XINT (n));
>   }
>   
> ! DEFUN ("forward-char", Fforward_char, Sforward_char, 0, 1, "^p",
>          doc: /* Move point right N characters (left if N is negative).
>   On reaching end of buffer, stop and signal error.  */)
>        (n)
> ***************
> *** 92,98 ****
>     return Qnil;
>   }
>   
> ! DEFUN ("backward-char", Fbackward_char, Sbackward_char, 0, 1, "p",
>          doc: /* Move point left N characters (right if N is negative).
>   On attempt to pass beginning or end of buffer, stop and signal error.  */)
>        (n)
> --- 92,98 ----
>     return Qnil;
>   }
>   
> ! DEFUN ("backward-char", Fbackward_char, Sbackward_char, 0, 1, "^p",
>          doc: /* Move point left N characters (right if N is negative).
>   On attempt to pass beginning or end of buffer, stop and signal error.  */)
>        (n)
> *** trunk/lisp/simple.el.~1.905.~	2008-03-10 21:57:09.000000000 -0400
> --- trunk/lisp/simple.el	2008-03-13 13:39:17.000000000 -0400
> ***************
> *** 3651,3657 ****
>   If you are thinking of using this in a Lisp program, consider
>   using `forward-line' instead.  It is usually easier to use
>   and more reliable (no dependence on goal column, etc.)."
> !   (interactive "p\np")
>     (or arg (setq arg 1))
>     (if (and next-line-add-newlines (= arg 1))
>         (if (save-excursion (end-of-line) (eobp))
> --- 3651,3657 ----
>   If you are thinking of using this in a Lisp program, consider
>   using `forward-line' instead.  It is usually easier to use
>   and more reliable (no dependence on goal column, etc.)."
> !   (interactive "^p\np")
>     (or arg (setq arg 1))
>     (if (and next-line-add-newlines (= arg 1))
>         (if (save-excursion (end-of-line) (eobp))
> ***************
> *** 3684,3690 ****
>   If you are thinking of using this in a Lisp program, consider using
>   `forward-line' with a negative argument instead.  It is usually easier
>   to use and more reliable (no dependence on goal column, etc.)."
> !   (interactive "p\np")
>     (or arg (setq arg 1))
>     (if (interactive-p)
>         (condition-case nil
> --- 3684,3690 ----
>   If you are thinking of using this in a Lisp program, consider using
>   `forward-line' with a negative argument instead.  It is usually easier
>   to use and more reliable (no dependence on goal column, etc.)."
> !   (interactive "^p\np")
>     (or arg (setq arg 1))
>     (if (interactive-p)
>         (condition-case nil
> ***************
> *** 4307,4313 ****
>   (defun backward-word (&optional arg)
>     "Move backward until encountering the beginning of a word.
>   With argument, do this that many times."
> !   (interactive "p")
>     (forward-word (- (or arg 1))))
>   
>   (defun mark-word (&optional arg allow-extend)
> --- 4307,4313 ----
>   (defun backward-word (&optional arg)
>     "Move backward until encountering the beginning of a word.
>   With argument, do this that many times."
> !   (interactive "^p")
>     (forward-word (- (or arg 1))))
>   
>   (defun mark-word (&optional arg allow-extend)
>
>
>
>   





^ permalink raw reply	[flat|nested] 167+ messages in thread

* Re: Shift selection using interactive spec
  2008-03-14  0:10   ` David Kastrup
@ 2008-03-14  1:22     ` Thomas Lord
  2008-03-14  9:46       ` David Kastrup
  0 siblings, 1 reply; 167+ messages in thread
From: Thomas Lord @ 2008-03-14  1:22 UTC (permalink / raw)
  To: David Kastrup; +Cc: Chong Yidong, emacs-devel

[-- Attachment #1: Type: text/plain, Size: 2649 bytes --]

David Kastrup wrote:
> Thomas Lord <lord@emf.net> writes:
>
>   
>> A problem (in my view) with such an approach
>> is that transient mark mode has the wrong semantics
>> to implement shift-marking.
>>
>> Transient mark mode is just about the appearance
>> of the display -- whether or not the current region
>> is highlighted.
>>     
>
> Uh, no.  It is also about whether or not the current region is actively
> modifying a number of commands.
>   
Sorry.  Yes, oddly, transient mark mode does that.  It makes
little sense to me.

I'm proposing adding a "tentative" flag to the top entry of the
mark stack --- if set, that entry tends to be discarded.

Transient mark mode, as you correctly point out, seems to
add a "usable" flag.  If not set, that entry is there but the user
is forbidden from using it.   Strange thing to do.


Another way to think about tentative marks is to think
that, in addition to the mark stack, there is a separate piece
of dynamic state that holds at most 1 mark -- call it "that point".
So, maybe not a "tentative flag" but just a separate, per-buffer,
"tentative mark" variable.     The user, with a gesture like
shifting a motion command, sets that tentative mark.   Most
commands will set that variable back to nil but, while it's
set, if the last command was reached by unshifting the keysequence
then keep the tentative mark;  or if the last command explicitly
set some flag then keep the tentative mark;  (otherwise set
it to nil).

In the emacs command set, the "tentative mark" is just another
"pronoun" so to speak.   Emacs already has markers as one kind
of noun and a mark-stack as a fancy kind of pronoun that
contextually names some list of markers..... this adds another
pronoun for a distinguished marker.  

In contrast, tentative-mark-mode (aside from just modifying
display) adds this whole new "user concept" of "active vs. deactivated"
marks.



>   
>> Shift-marking and other kinds of popular-style marking
>> are about more than display -- it's about marks that go away
>> by default, unless you keep them.
>>     
>
> That's what the "transient" in "transient-mark-mode" is about.  Look it
> up in a dictionary.  It has to be transient because it modifies the
> behavior of many commands, and thus you want it deactivated as soon as
> it may no longer be relevant.
>
>   

Please don't be snarky.   I don't spell well.  I am quite literate, I think.
I chose the word "tentative" precisely to draw a subtle distinction from
"transient" regarding their ordinary english meanings as good analogies for
the technical distinction I was drawing.  I'm sorry to have to say so but
I am insulted.

-t


[-- Attachment #2: Type: text/html, Size: 3548 bytes --]

^ permalink raw reply	[flat|nested] 167+ messages in thread

* Re: Shift selection using interactive spec
  2008-03-13 23:29 Shift selection using interactive spec Chong Yidong
  2008-03-14  0:44 ` Thomas Lord
@ 2008-03-14  4:06 ` Dan Nicolaescu
  2008-03-14 14:26   ` Kim F. Storm
  1 sibling, 1 reply; 167+ messages in thread
From: Dan Nicolaescu @ 2008-03-14  4:06 UTC (permalink / raw)
  To: Chong Yidong; +Cc: emacs-devel

Chong Yidong <cyd@stupidchicken.com> writes:

  > Comments are welcome.

Seems to work fine.  Adding ^ to move-beginning/end-of-line made S-home
and S-end work too.

The expected behavior for S-prior/next is to move the point to the
beginning/end of the buffer when the distance is less than a page.
How is that going to be handled?

How about mark-whole-buffer?

Thanks for taking care of this!




^ permalink raw reply	[flat|nested] 167+ messages in thread

* Re: Shift selection using interactive spec
  2008-03-14  1:22     ` Thomas Lord
@ 2008-03-14  9:46       ` David Kastrup
  2008-03-14 10:01         ` Johan Bockgård
  2008-03-14 11:11         ` Thomas Lord
  0 siblings, 2 replies; 167+ messages in thread
From: David Kastrup @ 2008-03-14  9:46 UTC (permalink / raw)
  To: Thomas Lord; +Cc: Chong Yidong, emacs-devel

Thomas Lord <lord@emf.net> writes:

> Please don't be snarky.  I don't spell well.  I am quite literate, I
> think.  I chose the word "tentative" precisely to draw a subtle
> distinction from "transient" regarding their ordinary english meanings
> as good analogies for the technical distinction I was drawing.  I'm
> sorry to have to say so but I am insulted.

I have to say that nothing so far indicates that your proposed
"tentative mark" would differ from the current behavior of "transient
marks".  Instead, you express your surprise that "transient marks"
behave like you would consider proper for "tentative marks".

It's not even a reinvention, but a renaming of the wheel that you are
apparently calling for, and I have yet to see the difference you are
aiming for from the current behavior.

-- 
David Kastrup, Kriemhildstr. 15, 44793 Bochum




^ permalink raw reply	[flat|nested] 167+ messages in thread

* Re: Shift selection using interactive spec
  2008-03-14  9:46       ` David Kastrup
@ 2008-03-14 10:01         ` Johan Bockgård
  2008-03-14 10:30           ` David Kastrup
  2008-03-14 11:18           ` Thomas Lord
  2008-03-14 11:11         ` Thomas Lord
  1 sibling, 2 replies; 167+ messages in thread
From: Johan Bockgård @ 2008-03-14 10:01 UTC (permalink / raw)
  To: emacs-devel

David Kastrup <dak@gnu.org> writes:

> It's not even a reinvention, but a renaming of the wheel that you are
> apparently calling for, and I have yet to see the difference you are
> aiming for from the current behavior.

I think the idea is that the mark should evaporate when the highlighting
goes away.  (It's like, you know, "transient".)

-- 
Johan Bockgård





^ permalink raw reply	[flat|nested] 167+ messages in thread

* Re: Shift selection using interactive spec
  2008-03-14 10:01         ` Johan Bockgård
@ 2008-03-14 10:30           ` David Kastrup
  2008-03-14 11:18           ` Thomas Lord
  1 sibling, 0 replies; 167+ messages in thread
From: David Kastrup @ 2008-03-14 10:30 UTC (permalink / raw)
  To: emacs-devel

bojohan+news@dd.chalmers.se (Johan Bockgård) writes:

> David Kastrup <dak@gnu.org> writes:
>
>> It's not even a reinvention, but a renaming of the wheel that you are
>> apparently calling for, and I have yet to see the difference you are
>> aiming for from the current behavior.
>
> I think the idea is that the mark should evaporate when the highlighting
> goes away.  (It's like, you know, "transient".)

But that's what transient-mark-mode does.  There are ways to resuscitate
it explicitly, but that can hardly be a problem.

-- 
David Kastrup, Kriemhildstr. 15, 44793 Bochum




^ permalink raw reply	[flat|nested] 167+ messages in thread

* Re: Shift selection using interactive spec
  2008-03-14 11:11         ` Thomas Lord
@ 2008-03-14 10:42           ` David Kastrup
  2008-03-14 11:36             ` Thomas Lord
  2008-03-14 11:50             ` Thomas Lord
  0 siblings, 2 replies; 167+ messages in thread
From: David Kastrup @ 2008-03-14 10:42 UTC (permalink / raw)
  To: Thomas Lord; +Cc: Chong Yidong, emacs-devel

Thomas Lord <lord@emf.net> writes:

> David Kastrup wrote:
>
>> I have to say that nothing so far indicates that your proposed
>> "tentative mark" would differ from the current behavior of "transient
>> marks".
>
> Um.  Ok, take a buffer of text.  M-x transient-mark-mode.  Set a mark.
> Move a bit with C-n.  Now hit G-g.
>
> The region is now "deactivated," sure.   But type C-xC-x:
> the mark you set is still there.  A *tentative* mark would
> be completely wiped out by the C-g.

That is basically just a matter of semantics.  The command "C-x C-x" can
be thought of as setting the mark at point, and moving point where a
mark had been last.

> I've described why about 3 times already.  Tentative marks always go
> away unless the user uses a key-sequence that preserves them or the
> command the user invokes is a rare variety that explicitly preserves
> it.

So the "advantage" of your "tentative mark" would be that "C-x C-x" now
beeps and does nothing.  What does that buy the user?

> (I think if you look back at history you'll discover that
> transient-mark-mode was actually a mistake.  It was
> in effect a crude attempt to hack around the lack of
> "tentative marks".   People were confused but were happy
> that transient-mark-mode seemed to mostly highlight regions
> and mostly work like other GUIs, at least in simple cases).
> Tentative marks capture the familiar semantics much more
> precisely than transient ones.

By making it impossible to recreate a mark where one had been last time?
What's the advantage in providing strictly less functionality?

> Having looked at it more closely now, I would even suggest that
> transient-mark-mode be deprecated (as in dis-recommended for use and
> of low priority for compatibility, going forward).)

I don't get your point.  You basically want to remove functionality and
sell this as an advantage under a different name.

-- 
David Kastrup, Kriemhildstr. 15, 44793 Bochum




^ permalink raw reply	[flat|nested] 167+ messages in thread

* Re: Shift selection using interactive spec
  2008-03-14  9:46       ` David Kastrup
  2008-03-14 10:01         ` Johan Bockgård
@ 2008-03-14 11:11         ` Thomas Lord
  2008-03-14 10:42           ` David Kastrup
  1 sibling, 1 reply; 167+ messages in thread
From: Thomas Lord @ 2008-03-14 11:11 UTC (permalink / raw)
  To: David Kastrup; +Cc: Chong Yidong, emacs-devel

David Kastrup wrote:
> Thomas Lord <lord@emf.net> writes:
>
>   
>> Please don't be snarky.  I don't spell well.  I am quite literate, I
>> think.  I chose the word "tentative" precisely to draw a subtle
>> distinction from "transient" regarding their ordinary english meanings
>> as good analogies for the technical distinction I was drawing.  I'm
>> sorry to have to say so but I am insulted.
>>     
>
> I have to say that nothing so far indicates that your proposed
> "tentative mark" would differ from the current behavior of "transient
> marks".  

Um.    Ok, take a buffer of text.   M-x transient-mark-mode.
Set a mark.   Move a bit with C-n.  Now hit G-g.

The region is now "deactivated," sure.   But type C-xC-x:
the mark you set is still there.  A *tentative* mark would
be completely wiped out by the C-g.   I've described why
about 3 times already.   Tentative marks always go away
unless the user uses a key-sequence that preserves them or
the command the user invokes is a rare variety that explicitly
preserves it.

(I think if you look back at history you'll discover that
transient-mark-mode was actually a mistake.  It was
in effect a crude attempt to hack around the lack of
"tentative marks".   People were confused but were happy
that transient-mark-mode seemed to mostly highlight regions
and mostly work like other GUIs, at least in simple cases).
Tentative marks capture the familiar semantics much more
precisely than transient ones.   Having looked at it more
closely now, I would even suggest that transient-mark-mode
be deprecated (as in dis-recommended for use and of low
priority for compatibility, going forward).)


-t





^ permalink raw reply	[flat|nested] 167+ messages in thread

* Re: Shift selection using interactive spec
  2008-03-14 10:01         ` Johan Bockgård
  2008-03-14 10:30           ` David Kastrup
@ 2008-03-14 11:18           ` Thomas Lord
  1 sibling, 0 replies; 167+ messages in thread
From: Thomas Lord @ 2008-03-14 11:18 UTC (permalink / raw)
  To: emacs-devel

[-- Attachment #1: Type: text/plain, Size: 1298 bytes --]

Johan Bockgård wrote:
> David Kastrup <dak@gnu.org> writes:
>
>   
>> It's not even a reinvention, but a renaming of the wheel that you are
>> apparently calling for, and I have yet to see the difference you are
>> aiming for from the current behavior.
>>     
>
> I think the idea is that the mark should evaporate when the highlighting
> goes away.  (It's like, you know, "transient".)
>   


Yes, that's right.  Except that "tentative" is a better word than 
"'transient".

If it's tentative, then maybe it's not going to last -- it can 
completely go
away.   That's "tentative".

"Transient" means "passing through".   A transient mark can come and go
-- transience means only that it wanders between "active" and "deactivated".


"Transient mark" is a good name for a transient mark -- it reflects its
nature.  Sometimes it's around.  Sometimes it's not.   But it's always
somewhere until explicitly removed.

"Tentative mark" is a good name for the functionality people seem to
be groping towards.   It reflects the nature of the semantics found in other
applications and that, serendipitously, fits in with mark stacks in a 
natural
way.   I think that once upon a time someone tried to come up with
tentative marks and missed, coming up with transient mark mode as an
approximation.


-t


[-- Attachment #2: Type: text/html, Size: 1877 bytes --]

^ permalink raw reply	[flat|nested] 167+ messages in thread

* Re: Shift selection using interactive spec
  2008-03-14 10:42           ` David Kastrup
@ 2008-03-14 11:36             ` Thomas Lord
  2008-03-14 11:50             ` Thomas Lord
  1 sibling, 0 replies; 167+ messages in thread
From: Thomas Lord @ 2008-03-14 11:36 UTC (permalink / raw)
  To: David Kastrup; +Cc: Chong Yidong, emacs-devel

[-- Attachment #1: Type: text/plain, Size: 3289 bytes --]

David Kastrup wrote:
>
>> Um.  Ok, take a buffer of text.  M-x transient-mark-mode.  Set a mark.
>> Move a bit with C-n.  Now hit G-g.
>>
>> The region is now "deactivated," sure.   But type C-xC-x:
>> the mark you set is still there.  A *tentative* mark would
>> be completely wiped out by the C-g.
>>     
>
> That is basically just a matter of semantics.


"Basically?"   Yes, the semantics of the command set is the topic.

I think you are trying to brush aside the real differences between
two approaches by saying it's "*just* semantics" (emphasis added).
But that's circular.   The two approaches are *defined* in terms of
their differing semantics.



>   The command "C-x C-x" can
> be thought of as setting the mark at point, and moving point where a
> mark had been last.
>
>   

And that means that the user's model of emacs is that emacs remembers
that that mark existed.   The user's model of Emacs' state is pretty 
tricky:  there's
"selected frame" and "current window" and "current minor modes" and etc.
But the state model that user's have to (one way or another) have a mental
map of -- at least the state model is orderly.

Tentative marks modify the base-line state-model of emacs only a tiny bit.
User's get a new "pronoun" (the tentative mark) to assign bindings to or to
refer to.   It's a very "context specific" pronoun in that it tends to 
become
unbound by default.

Transient marks modify the base-line state-model of emacs by a large
amount.   Commands that used to unconditionally work on "the region"
now have to work on the region only if the "activated" flag is set.  The
user is not just temporarily naming some point -- as with a tentative 
mark --
but is instead having to keep track of a new, buffer-local boolean variable.

So, tentative marks are cleaner.   It's just icing on the cake that,
aside from being cleaner from an Emacs perspective, they *also* happen
to be a more perfect emulation of what those "other GUIs" do.

-t




>> I've described why about 3 times already.  Tentative marks always go
>> away unless the user uses a key-sequence that preserves them or the
>> command the user invokes is a rare variety that explicitly preserves
>> it.
>>     
>
> So the "advantage" of your "tentative mark" would be that "C-x C-x" now
> beeps and does nothing.  What does that buy the user?
>
>   
>> (I think if you look back at history you'll discover that
>> transient-mark-mode was actually a mistake.  It was
>> in effect a crude attempt to hack around the lack of
>> "tentative marks".   People were confused but were happy
>> that transient-mark-mode seemed to mostly highlight regions
>> and mostly work like other GUIs, at least in simple cases).
>> Tentative marks capture the familiar semantics much more
>> precisely than transient ones.
>>     
>
> By making it impossible to recreate a mark where one had been last time?
> What's the advantage in providing strictly less functionality?
>
>   
>> Having looked at it more closely now, I would even suggest that
>> transient-mark-mode be deprecated (as in dis-recommended for use and
>> of low priority for compatibility, going forward).)
>>     
>
> I don't get your point.  You basically want to remove functionality and
> sell this as an advantage under a different name.
>
>   


[-- Attachment #2: Type: text/html, Size: 4277 bytes --]

^ permalink raw reply	[flat|nested] 167+ messages in thread

* Re: Shift selection using interactive spec
  2008-03-14 11:50             ` Thomas Lord
@ 2008-03-14 11:39               ` David Kastrup
  2008-03-14 18:41                 ` Thomas Lord
  0 siblings, 1 reply; 167+ messages in thread
From: David Kastrup @ 2008-03-14 11:39 UTC (permalink / raw)
  To: Thomas Lord; +Cc: Chong Yidong, emacs-devel

Thomas Lord <lord@emf.net> writes:

> David Kastrup wrote:
>
>
>
>         Tentative marks capture the familiar semantics much more
>         precisely than transient ones.
>
>     By making it impossible to recreate a mark where one had been last time?
>     What's the advantage in providing strictly less functionality?
>
> Tentative marks do *not* make it impossible to recreate a
> mark where one had been last time.

So what's your complaint about C-x C-x?

> They do imply that "recreatable" tentative marks are stored
> someplace else besides the mark stack.

C-x C-x does not push onto the mark stack.

> Tentative marks are by definition not precious so
> I don't know that you'd want to put much effort into saving
> them but you could always keep, maybe the most recent
> one or two if you have commands that would want to restore them.

What's the advantage to what is already there?  Can you present a
sequence of operations or keypresses where your scheme would provide an
advantage?  What advantage?

-- 
David Kastrup, Kriemhildstr. 15, 44793 Bochum




^ permalink raw reply	[flat|nested] 167+ messages in thread

* Re: Shift selection using interactive spec
  2008-03-14 10:42           ` David Kastrup
  2008-03-14 11:36             ` Thomas Lord
@ 2008-03-14 11:50             ` Thomas Lord
  2008-03-14 11:39               ` David Kastrup
  1 sibling, 1 reply; 167+ messages in thread
From: Thomas Lord @ 2008-03-14 11:50 UTC (permalink / raw)
  To: David Kastrup; +Cc: Chong Yidong, emacs-devel

[-- Attachment #1: Type: text/plain, Size: 1278 bytes --]

David Kastrup wrote:
>
>> Tentative marks capture the familiar semantics much more
>> precisely than transient ones.
>>     
>
> By making it impossible to recreate a mark where one had been last time?
> What's the advantage in providing strictly less functionality?
>   


Tentative marks do *not* make it impossible to recreate a
mark where one had been last time.

They do imply that "recreatable" tentative marks are stored
someplace else besides the mark stack.

Tentative marks are by definition not precious so
I don't know that you'd want to put much effort into saving
them but you could always keep, maybe the most recent
one or two if you have commands that would want to restore them.





>   
>> Having looked at it more closely now, I would even suggest that
>> transient-mark-mode be deprecated (as in dis-recommended for use and
>> of low priority for compatibility, going forward).)
>>     
>
> I don't get your point.  You basically want to remove functionality and
> sell this as an advantage under a different name.
>
>   



Not quite but, for the sake of argument, let's say, sure.

The quality of a program is a measure less of its quantity of features,
and more of its parsimony of relevant features.  If you know what I mean.
Wink wink.  Nod nod.

-t


[-- Attachment #2: Type: text/html, Size: 1970 bytes --]

^ permalink raw reply	[flat|nested] 167+ messages in thread

* Re: Shift selection using interactive spec
  2008-03-14  4:06 ` Dan Nicolaescu
@ 2008-03-14 14:26   ` Kim F. Storm
  2008-03-14 14:32     ` Chong Yidong
  0 siblings, 1 reply; 167+ messages in thread
From: Kim F. Storm @ 2008-03-14 14:26 UTC (permalink / raw)
  To: Dan Nicolaescu; +Cc: Chong Yidong, emacs-devel

Dan Nicolaescu <dann@ics.uci.edu> writes:

> Chong Yidong <cyd@stupidchicken.com> writes:
>
>   > Comments are welcome.
>
> Seems to work fine.  Adding ^ to move-beginning/end-of-line made S-home
> and S-end work too.
>
> The expected behavior for S-prior/next is to move the point to the
> beginning/end of the buffer when the distance is less than a page.
> How is that going to be handled?
>
> How about mark-whole-buffer?
>
> Thanks for taking care of this!

I haven't had time to look at your patch, but it seems ok.

But let me repeat my question:

What if a movement command uses a lisp form rather than a string as
interactive spec?  

Then, how do you do the equivalent of '^' in that case?


-- 
Kim F. Storm <storm@cua.dk> http://www.cua.dk





^ permalink raw reply	[flat|nested] 167+ messages in thread

* Re: Shift selection using interactive spec
  2008-03-14 14:26   ` Kim F. Storm
@ 2008-03-14 14:32     ` Chong Yidong
  2008-03-14 14:53       ` Kim F. Storm
  2008-03-14 15:54       ` Stefan Monnier
  0 siblings, 2 replies; 167+ messages in thread
From: Chong Yidong @ 2008-03-14 14:32 UTC (permalink / raw)
  To: Kim F. Storm; +Cc: Dan Nicolaescu, emacs-devel

storm@cua.dk (Kim F. Storm) writes:

> What if a movement command uses a lisp form rather than a string as
> interactive spec?  
>
> Then, how do you do the equivalent of '^' in that case?

Is there any movement command that uses a lisp form spec?  If these
are sufficiently rare, the command itself could simply be modified
directly.

Not that the @ and * interactive specs would also have problems with
interactive specs that are lisp forms.




^ permalink raw reply	[flat|nested] 167+ messages in thread

* Re: Shift selection using interactive spec
  2008-03-14 14:32     ` Chong Yidong
@ 2008-03-14 14:53       ` Kim F. Storm
  2008-03-14 16:19         ` David Kastrup
  2008-03-14 15:54       ` Stefan Monnier
  1 sibling, 1 reply; 167+ messages in thread
From: Kim F. Storm @ 2008-03-14 14:53 UTC (permalink / raw)
  To: Chong Yidong; +Cc: Dan Nicolaescu, emacs-devel

Chong Yidong <cyd@stupidchicken.com> writes:

> storm@cua.dk (Kim F. Storm) writes:
>
>> What if a movement command uses a lisp form rather than a string as
>> interactive spec?  
>>
>> Then, how do you do the equivalent of '^' in that case?
>
> Is there any movement command that uses a lisp form spec?  

Maybe not trivial commands, but I think a solution should not
be limited to only trivial commands...

>                                                            If these
> are sufficiently rare, the command itself could simply be modified
> directly.

Then we need to make this_command_keys_shift_translated available
to lisp.  

Maybe better would be to simply put the relevant code (below) into a
DEFUN that could be called from such commands (and from
Fcall_interactively of course).


+       else if (*string == '^')
+ 	{
+ 	  Lisp_Object *key = XVECTOR (this_command_keys)->contents
+ 	    + this_single_command_key_start;
+ 	  Lisp_Object *key_max = XVECTOR (this_command_keys)->contents
+ 	    + this_command_key_count;
+ 	  Lisp_Object shift = intern ("shift");
+ 	  int shifted = this_command_keys_shift_translated;
+ 
+ 	  if (!shifted)
+ 	    for (; key < key_max; ++key)
+ 	      {
+ 		if (SYMBOLP (*key))
+ 		  shifted = !NILP (Fmemq (shift,
+ 					  Fget (*key, Qevent_symbol_elements)));
+ 		if (!shifted)
+ 		  break;
+ 	      }
+ 
+ 	  if (shifted)
+ 	    {
+ 	      Lisp_Object push_mark_call[4] = { intern ("push-mark"),
+ 	  					Qnil, Qnil, Qt };
+ 	      if (!EQ (Vtransient_mark_mode, Qidentity))
+ 	  	Ffuncall (4, push_mark_call);
+ 	      if (EQ (Vtransient_mark_mode, Qidentity)
+ 	  	  || NILP (Vtransient_mark_mode))
+ 	  	Vtransient_mark_mode = Qonly;
+ 	    }
+ 
+ 	  string++;
+ 	}

>
> Not that the @ and * interactive specs would also have problems with
> interactive specs that are lisp forms.


-- 
Kim F. Storm <storm@cua.dk> http://www.cua.dk





^ permalink raw reply	[flat|nested] 167+ messages in thread

* Re: Shift selection using interactive spec
  2008-03-14 14:32     ` Chong Yidong
  2008-03-14 14:53       ` Kim F. Storm
@ 2008-03-14 15:54       ` Stefan Monnier
  2008-03-14 16:09         ` Drew Adams
  2008-03-14 20:52         ` Chong Yidong
  1 sibling, 2 replies; 167+ messages in thread
From: Stefan Monnier @ 2008-03-14 15:54 UTC (permalink / raw)
  To: Chong Yidong; +Cc: Dan Nicolaescu, emacs-devel, Kim F. Storm

>> What if a movement command uses a lisp form rather than a string as
>> interactive spec?  
>> 
>> Then, how do you do the equivalent of '^' in that case?

> Is there any movement command that uses a lisp form spec?  If these
> are sufficiently rare, the command itself could simply be modified
> directly.

> Not that the @ and * interactive specs would also have problems with
> interactive specs that are lisp forms.

*Any* letter in `interactive' should have a simple Elisp equivalent.
I suggest you write the code directly in an elisp function to start
with, and then call that function from callint.c.


        Stefan




^ permalink raw reply	[flat|nested] 167+ messages in thread

* RE: Shift selection using interactive spec
  2008-03-14 15:54       ` Stefan Monnier
@ 2008-03-14 16:09         ` Drew Adams
  2008-03-14 20:52         ` Chong Yidong
  1 sibling, 0 replies; 167+ messages in thread
From: Drew Adams @ 2008-03-14 16:09 UTC (permalink / raw)
  To: 'Stefan Monnier', 'Chong Yidong'
  Cc: 'Dan Nicolaescu', 'Kim F. Storm', emacs-devel

> *Any* letter in `interactive' should have a simple Elisp equivalent.

Amen.





^ permalink raw reply	[flat|nested] 167+ messages in thread

* Re: Shift selection using interactive spec
  2008-03-14 14:53       ` Kim F. Storm
@ 2008-03-14 16:19         ` David Kastrup
  0 siblings, 0 replies; 167+ messages in thread
From: David Kastrup @ 2008-03-14 16:19 UTC (permalink / raw)
  To: Kim F. Storm; +Cc: Chong Yidong, Dan Nicolaescu, emacs-devel

storm@cua.dk (Kim F. Storm) writes:

> Chong Yidong <cyd@stupidchicken.com> writes:
>
>> storm@cua.dk (Kim F. Storm) writes:
>>
>>> What if a movement command uses a lisp form rather than a string as
>>> interactive spec?  
>>>
>>> Then, how do you do the equivalent of '^' in that case?
>>
>> Is there any movement command that uses a lisp form spec?  
>
> Maybe not trivial commands, but I think a solution should not
> be limited to only trivial commands...

Mouse events are often bound to computed interactive forms.  Those have
no name.

-- 
David Kastrup, Kriemhildstr. 15, 44793 Bochum




^ permalink raw reply	[flat|nested] 167+ messages in thread

* Re: Shift selection using interactive spec
  2008-03-14 11:39               ` David Kastrup
@ 2008-03-14 18:41                 ` Thomas Lord
  0 siblings, 0 replies; 167+ messages in thread
From: Thomas Lord @ 2008-03-14 18:41 UTC (permalink / raw)
  To: David Kastrup; +Cc: Chong Yidong, emacs-devel

[-- Attachment #1: Type: text/plain, Size: 2622 bytes --]

David Kastrup wrote:
>>  strictly less functionality?
>>
>> Tentative marks do *not* make it impossible to recreate a
>> mark where one had been last time.
>>     
>
> So what's your complaint about C-x C-x?
>   

In t-m-m?  For the purpose of shift-select?   It's that the
marker being "reactivated" by C-x C-x shouldn't be on
the mark stack at all.



>   
>> They do imply that "recreatable" tentative marks are stored
>> someplace else besides the mark stack.
>>     
>
> C-x C-x does not push onto the mark stack.
>
>   

Right.   By the time it is run, the mistake is already made -- the marker
in question has already been pushed.

Here is an interaction script that shows what shift-marking should
do:

      a) start with a big buffer of text (e.g. COPYING).
      b) Set a mark somewhere in the file using C-@  -- this is "the mark"
      c) Navigate away.   No highlighting should happen.  C-x C-x
          should swap the point and mark, as usual.
      d) While navigated away, put the point at the start of some word
           and type M-C-S-f.    The entire word should now be selected
           between the point and a *transient* mark.
       e) Kill-region (C-w).   The selected word is now gone.  So is
           the *transient* mark.
       f) C-x C-x C-y   -- the word you killed should now be
           inserted at "the mark" from step b


For a user, that means you can set marks and reliably return to
them using C-@ and C-x C-x or C-u C-@ but you can *also*
just use all of your familiar "shift-select" gestures for simple
edits -- the two concepts work side by side rather than one trying
to emulate the other.



>> Tentative marks are by definition not precious so
>> I don't know that you'd want to put much effort into saving
>> them but you could always keep, maybe the most recent
>> one or two if you have commands that would want to restore them.
>>     
>
> What's the advantage to what is already there?  Can you present a
> sequence of operations or keypresses where your scheme would provide an
> advantage?  What advantage?
>
>   

The above (a..f) is one such example.  The key thing is that tentative marks
give you one level of additional selection without perturbing the 
traditional
mark stack.

Another way to look at it is to think about what shift-marking means
in most GUIs.   Most GUIs support shift-marking.    If you start marking
some region it's highlighted but then if you do anything that cancels
that selection, the selection is simply gone and the application is back to
its original state -- no trace of the former region.     That's a good 
default.




-t


[-- Attachment #2: Type: text/html, Size: 4108 bytes --]

^ permalink raw reply	[flat|nested] 167+ messages in thread

* Re: Shift selection using interactive spec
  2008-03-14 15:54       ` Stefan Monnier
  2008-03-14 16:09         ` Drew Adams
@ 2008-03-14 20:52         ` Chong Yidong
  2008-03-14 20:59           ` David Kastrup
  2008-03-15  0:56           ` Stefan Monnier
  1 sibling, 2 replies; 167+ messages in thread
From: Chong Yidong @ 2008-03-14 20:52 UTC (permalink / raw)
  To: Stefan Monnier; +Cc: Dan Nicolaescu, emacs-devel, Kim F. Storm

Stefan Monnier <monnier@iro.umontreal.ca> writes:

>>> What if a movement command uses a lisp form rather than a string as
>>> interactive spec?  
>>> 
>>> Then, how do you do the equivalent of '^' in that case?
>
>> Is there any movement command that uses a lisp form spec?  If these
>> are sufficiently rare, the command itself could simply be modified
>> directly.
>
>> Not that the @ and * interactive specs would also have problems with
>> interactive specs that are lisp forms.
>
> *Any* letter in `interactive' should have a simple Elisp equivalent.
> I suggest you write the code directly in an elisp function to start
> with, and then call that function from callint.c.

The way I see it, there are a few ways we can go with this.

1. Add a new code LETTER for interactive specs, e.g. t

   This provides an argument that is t if the command was called by
   shift translation.  In other words, read_key_sequence couldn't find
   a keybinding for the entered key sequence, so it tried removing the
   shift modifier and found the binding to this command.

   Then we modify the motion commands to accept the additional
   argument, e.g.:

   (forward-char &optional N) -> (forward-char &optional N shift-select)

   The body of each motion command is then changed to DTRT with the
   new argument.

   With this approach, there is the least amount of magic going on,
   but adding an argument to all motion commands may cause disruption
   and incompatibilities.  How much disruption remains unclear to me.

1a. As above, but make the letter activate so long as the keybinding
    contains a shift (i.e. even if the command was found with a direct
    keybinding.)

2. Don't bother with interactive spec.  Provide a built-in function
   that says whether a command has been run using shift translation.
   Call it, e.g.,

      this-single-command-keys-shift-translated

   Directly modify the body of each motion command to call
   this-single-command-keys-shift-translated and DTRT.

2a. As above, but also for direct keybindings with the shift modifier.
    (This is the idea that Stefan has been pushing.)

3. Use a non-letter interactive code, analogous to @ and *, that
   causes Fcall_interactively to perform the handling of
   transient-mark-mode automagically.  This was the code I showed.
   Because it's a non-letter code, we don't need to change the
   argument list.  This approach needs the least new code, and might
   be less disruptive, but it's obviously a little magical.

3a. As above, but also for direct keybindings with the shift modifier.




^ permalink raw reply	[flat|nested] 167+ messages in thread

* Re: Shift selection using interactive spec
  2008-03-14 20:52         ` Chong Yidong
@ 2008-03-14 20:59           ` David Kastrup
  2008-03-14 21:08             ` Chong Yidong
  2008-03-15  0:56           ` Stefan Monnier
  1 sibling, 1 reply; 167+ messages in thread
From: David Kastrup @ 2008-03-14 20:59 UTC (permalink / raw)
  To: Chong Yidong; +Cc: Dan Nicolaescu, Stefan Monnier, Kim F. Storm, emacs-devel

Chong Yidong <cyd@stupidchicken.com> writes:

> 3. Use a non-letter interactive code, analogous to @ and *, that
>    causes Fcall_interactively to perform the handling of
>    transient-mark-mode automagically.  This was the code I showed.
>    Because it's a non-letter code, we don't need to change the
>    argument list.  This approach needs the least new code, and might
>    be less disruptive, but it's obviously a little magical.
>
> 3a. As above, but also for direct keybindings with the shift modifier.

3 has my vote.  I am not sure about the meaning or implications of 3a.

-- 
David Kastrup, Kriemhildstr. 15, 44793 Bochum




^ permalink raw reply	[flat|nested] 167+ messages in thread

* Re: Shift selection using interactive spec
  2008-03-14 20:59           ` David Kastrup
@ 2008-03-14 21:08             ` Chong Yidong
  0 siblings, 0 replies; 167+ messages in thread
From: Chong Yidong @ 2008-03-14 21:08 UTC (permalink / raw)
  To: David Kastrup; +Cc: Dan Nicolaescu, Stefan Monnier, Kim F. Storm, emacs-devel

David Kastrup <dak@gnu.org> writes:

>> 3. Use a non-letter interactive code, analogous to @ and *, that
>>    causes Fcall_interactively to perform the handling of
>>    transient-mark-mode automagically.  This was the code I showed.
>>    Because it's a non-letter code, we don't need to change the
>>    argument list.  This approach needs the least new code, and might
>>    be less disruptive, but it's obviously a little magical.
>>
>> 3a. As above, but also for direct keybindings with the shift modifier.
>
> 3 has my vote.  I am not sure about the meaning or implications of 3a.


If you type `S-right', read_key_sequence tries to find a keybinding
for `S-right'.  If is none, it automatically tries `right', which in
this case is bound to forward-char.  So `S-right', translated to
`right', runs foward-char.

If you bind `S-right' to some other command, this translation won't
occur: `S-right' runs that new command.

That's what I mean by shift translation.  It raises the orthogonal
issue of whether we want to tie shift-selection to this shift
translation business.  Or do we simply activate it when there is a
shift modifier present in the keybinding?

My inclination is toward the former, but this issue is subtle and
needs more analysis.




^ permalink raw reply	[flat|nested] 167+ messages in thread

* Re: Shift selection using interactive spec
  2008-03-14 20:52         ` Chong Yidong
  2008-03-14 20:59           ` David Kastrup
@ 2008-03-15  0:56           ` Stefan Monnier
  2008-03-15  2:02             ` Chong Yidong
  1 sibling, 1 reply; 167+ messages in thread
From: Stefan Monnier @ 2008-03-15  0:56 UTC (permalink / raw)
  To: Chong Yidong; +Cc: Dan Nicolaescu, emacs-devel, Kim F. Storm

>> *Any* letter in `interactive' should have a simple Elisp equivalent.
         ^^^^^^
          char

> 3. Use a non-letter interactive code, analogous to @ and *, that
>    causes Fcall_interactively to perform the handling of
>    transient-mark-mode automagically.  This was the code I showed.
>    Because it's a non-letter code, we don't need to change the
>    argument list.  This approach needs the least new code, and might
>    be less disruptive, but it's obviously a little magical.

> 3a. As above, but also for direct keybindings with the shift modifier.

That's clearly the intention I had, except I don't care if it is also
provided as a char for string interactive specs.  First and foremost it
should be an elisp function that people can call at the beginning of
their function, just like they can call `barf-if-buffer-read-only'.

Then we can provide a special char in `interactive' strings for those
commands that currently don't use an elisp interactive spec.

Then we can tweak the code of that function to decide how it should
behave when the command is bound to a shifted key.


        Stefan




^ permalink raw reply	[flat|nested] 167+ messages in thread

* Re: Shift selection using interactive spec
  2008-03-15  0:56           ` Stefan Monnier
@ 2008-03-15  2:02             ` Chong Yidong
  2008-03-15  3:31               ` Stefan Monnier
  0 siblings, 1 reply; 167+ messages in thread
From: Chong Yidong @ 2008-03-15  2:02 UTC (permalink / raw)
  To: Stefan Monnier; +Cc: Dan Nicolaescu, emacs-devel, Kim F. Storm

Stefan Monnier <monnier@iro.umontreal.ca> writes:

> First and foremost it should be an elisp function that people can
> call at the beginning of their function, just like they can call
> `barf-if-buffer-read-only'.
>
> Then we can provide a special char in `interactive' strings for those
> commands that currently don't use an elisp interactive spec.
>
> Then we can tweak the code of that function to decide how it should
> behave when the command is bound to a shifted key.

So we define (i) an elisp function called, say,
shift-translation-handler, and (ii) a new interactive code that says
to call shift-translation-handler when a command is activated through
a shift translated keybinding.

Is this what you mean?




^ permalink raw reply	[flat|nested] 167+ messages in thread

* Re: Shift selection using interactive spec
  2008-03-15  2:02             ` Chong Yidong
@ 2008-03-15  3:31               ` Stefan Monnier
  2008-03-15 14:07                 ` Chong Yidong
  2008-03-16  2:33                 ` Richard Stallman
  0 siblings, 2 replies; 167+ messages in thread
From: Stefan Monnier @ 2008-03-15  3:31 UTC (permalink / raw)
  To: Chong Yidong; +Cc: Dan Nicolaescu, emacs-devel, Kim F. Storm

>> First and foremost it should be an elisp function that people can
>> call at the beginning of their function, just like they can call
>> `barf-if-buffer-read-only'.
>> 
>> Then we can provide a special char in `interactive' strings for those
>> commands that currently don't use an elisp interactive spec.
>> 
>> Then we can tweak the code of that function to decide how it should
>> behave when the command is bound to a shifted key.

> So we define (i) an elisp function called, say,
> shift-translation-handler, and (ii) a new interactive code that says
> to call shift-translation-handler when a command is activated through
> a shift translated keybinding.

No: the function is called every time.  *All* the work is done by the
elisp function.


        Stefan




^ permalink raw reply	[flat|nested] 167+ messages in thread

* Re: Shift selection using interactive spec
  2008-03-15  3:31               ` Stefan Monnier
@ 2008-03-15 14:07                 ` Chong Yidong
  2008-03-15 15:07                   ` Stefan Monnier
  2008-03-15 17:16                   ` Shift selection using interactive spec Kim F. Storm
  2008-03-16  2:33                 ` Richard Stallman
  1 sibling, 2 replies; 167+ messages in thread
From: Chong Yidong @ 2008-03-15 14:07 UTC (permalink / raw)
  To: Stefan Monnier; +Cc: Dan Nicolaescu, emacs-devel, Kim F. Storm

Stefan Monnier <monnier@iro.umontreal.ca> writes:

>> So we define (i) an elisp function called, say,
>> shift-translation-handler, and (ii) a new interactive code that says
>> to call shift-translation-handler when a command is activated through
>> a shift translated keybinding.
>
> No: the function is called every time.  *All* the work is done by the
> elisp function.

I think it would be more elegant to split this up into two pieces: a
variable this-single-command-shift-translated that says whether shift
translation occurred, and a function shift-translation-handler that
temporarily sets transient mark mode.  Both would be available to
elisp programs.

The new interactive spec code ^ would then call
shift-translation-handler if this-single-command-shift-translated is
non-nil, but elisp programs could accomplish this just as easily via
(if this-single-command-shift-translated ...).

This could also make it easier to handle the possibility that certain
commands might want to accomodate shift selection, but need to handle
it differently than the default.




^ permalink raw reply	[flat|nested] 167+ messages in thread

* Re: Shift selection using interactive spec
  2008-03-15 14:07                 ` Chong Yidong
@ 2008-03-15 15:07                   ` Stefan Monnier
  2008-03-15 17:11                     ` Chong Yidong
  2008-03-15 17:16                   ` Shift selection using interactive spec Kim F. Storm
  1 sibling, 1 reply; 167+ messages in thread
From: Stefan Monnier @ 2008-03-15 15:07 UTC (permalink / raw)
  To: Chong Yidong; +Cc: Dan Nicolaescu, emacs-devel, Kim F. Storm

>>> So we define (i) an elisp function called, say,
>>> shift-translation-handler, and (ii) a new interactive code that says
>>> to call shift-translation-handler when a command is activated through
>>> a shift translated keybinding.
>> 
>> No: the function is called every time.  *All* the work is done by the
>> elisp function.

> I think it would be more elegant to split this up into two pieces: a
> variable this-single-command-shift-translated that says whether shift
> translation occurred, and a function shift-translation-handler that
> temporarily sets transient mark mode.  Both would be available to
> elisp programs.

Yes, that part is fine.

> The new interactive spec code ^ would then call
> shift-translation-handler if this-single-command-shift-translated is
> non-nil, but elisp programs could accomplish this just as easily via
> (if this-single-command-shift-translated ...).

No, the `if' test should be done inside the function.

> This could also make it easier to handle the possibility that certain
> commands might want to accomodate shift selection, but need to handle
> it differently than the default.

We'll cross that bridge if/when we get to it.


        Stefan




^ permalink raw reply	[flat|nested] 167+ messages in thread

* Re: Shift selection using interactive spec
  2008-03-15 15:07                   ` Stefan Monnier
@ 2008-03-15 17:11                     ` Chong Yidong
  2008-03-15 20:52                       ` Stefan Monnier
  0 siblings, 1 reply; 167+ messages in thread
From: Chong Yidong @ 2008-03-15 17:11 UTC (permalink / raw)
  To: Stefan Monnier; +Cc: Dan Nicolaescu, emacs-devel, Kim F. Storm

Stefan Monnier <monnier@iro.umontreal.ca> writes:

>> I think it would be more elegant to split this up into two pieces: a
>> variable this-single-command-shift-translated that says whether shift
>> translation occurred, and a function shift-translation-handler that
>> temporarily sets transient mark mode.  Both would be available to
>> elisp programs.
>
> Yes, that part is fine.
>
>> The new interactive spec code ^ would then call
>> shift-translation-handler if this-single-command-shift-translated is
>> non-nil, but elisp programs could accomplish this just as easily via
>> (if this-single-command-shift-translated ...).
>
> No, the `if' test should be done inside the function.

What is the rationale for this?  It seems clear that

  "Extend the temporary region highlighting for the next command"

is a neater and more self-contained task for a function than

  "Extend the temporary region highlighting for the next command, but
   only if this-single-command-shift-translated is non-nil; otherwise,
   do nothing"

If it makes you happy, we could obviously provide both functions.
Shrug.




^ permalink raw reply	[flat|nested] 167+ messages in thread

* Re: Shift selection using interactive spec
  2008-03-15 14:07                 ` Chong Yidong
  2008-03-15 15:07                   ` Stefan Monnier
@ 2008-03-15 17:16                   ` Kim F. Storm
  2008-03-15 20:59                     ` Thomas Lord
                                       ` (2 more replies)
  1 sibling, 3 replies; 167+ messages in thread
From: Kim F. Storm @ 2008-03-15 17:16 UTC (permalink / raw)
  To: Chong Yidong; +Cc: Dan Nicolaescu, Stefan Monnier, emacs-devel

Chong Yidong <cyd@stupidchicken.com> writes:

> Stefan Monnier <monnier@iro.umontreal.ca> writes:
>
>>> So we define (i) an elisp function called, say,
>>> shift-translation-handler, and (ii) a new interactive code that says
>>> to call shift-translation-handler when a command is activated through
>>> a shift translated keybinding.
>>
>> No: the function is called every time.  *All* the work is done by the
>> elisp function.
>
> I think it would be more elegant to split this up into two pieces: a
> variable this-single-command-shift-translated that says whether shift
> translation occurred, and a function shift-translation-handler that
> temporarily sets transient mark mode.  Both would be available to
> elisp programs.
>
> The new interactive spec code ^ would then call
> shift-translation-handler if this-single-command-shift-translated is
> non-nil, but elisp programs could accomplish this just as easily via
> (if this-single-command-shift-translated ...).
>
> This could also make it easier to handle the possibility that certain
> commands might want to accomodate shift selection, but need to handle
> it differently than the default.

I like this approach.

Now, before you settle on a solution, maybe you should also consider
how to handle the delete-selection-mode in a sensible way without
using the current pre-command-hook + command property approach.

Of course, since shift-select is promoted to a standard feature by
modifying the relevant commands, we can just take the same approach
with delete-selection-mode, i.e. modify the relevant commands to
simply honour delsel mode.

-- 
Kim F. Storm <storm@cua.dk> http://www.cua.dk





^ permalink raw reply	[flat|nested] 167+ messages in thread

* Re: Shift selection using interactive spec
  2008-03-15 17:11                     ` Chong Yidong
@ 2008-03-15 20:52                       ` Stefan Monnier
  2008-03-15 21:45                         ` Thomas Lord
  2008-03-15 22:01                         ` shift-select harmony Thomas Lord
  0 siblings, 2 replies; 167+ messages in thread
From: Stefan Monnier @ 2008-03-15 20:52 UTC (permalink / raw)
  To: Chong Yidong; +Cc: Dan Nicolaescu, emacs-devel, Kim F. Storm

>>> I think it would be more elegant to split this up into two pieces: a
>>> variable this-single-command-shift-translated that says whether shift
>>> translation occurred, and a function shift-translation-handler that
>>> temporarily sets transient mark mode.  Both would be available to
>>> elisp programs.
>> 
>> Yes, that part is fine.
>> 
>>> The new interactive spec code ^ would then call
>>> shift-translation-handler if this-single-command-shift-translated is
>>> non-nil, but elisp programs could accomplish this just as easily via
>>> (if this-single-command-shift-translated ...).
>> 
>> No, the `if' test should be done inside the function.

> What is the rationale for this?  It seems clear that

Calling the function just means "I'm a movement command and would like
to follow the new select-on-shift behavior".

Then the function can decide on what actually happens when.

>   "Extend the temporary region highlighting for the next command"

> is a neater and more self-contained task for a function than

>   "Extend the temporary region highlighting for the next command, but
>    only if this-single-command-shift-translated is non-nil; otherwise,
>    do nothing"

The docstring of the function would be more like

  "Handle the mark selection for movement commands."


-- Stefan




^ permalink raw reply	[flat|nested] 167+ messages in thread

* Re: Shift selection using interactive spec
  2008-03-15 17:16                   ` Shift selection using interactive spec Kim F. Storm
@ 2008-03-15 20:59                     ` Thomas Lord
  2008-03-16 23:31                       ` Alan Mackenzie
  2008-03-15 21:08                     ` Thomas Lord
  2008-03-16 14:40                     ` Shift selection using interactive spec Chong Yidong
  2 siblings, 1 reply; 167+ messages in thread
From: Thomas Lord @ 2008-03-15 20:59 UTC (permalink / raw)
  To: Kim F. Storm; +Cc: Chong Yidong, Dan Nicolaescu, Stefan Monnier, emacs-devel

Kim F. Storm wrote:
> Now, before you settle on a solution, maybe you should also consider
> how to handle the delete-selection-mode in a sensible way without
> using the current pre-command-hook + command property approach.
>   

Tentative marks simplify that too:

Suppose there is a global variable, tenative-mark,
which is always either nil or a mark.

The ordinary mark stack also exists.

The region between tenative-mark and point is
called the tentative-region.

save-excursion should save and restore the value
of tentative-mark, setting it to nil when running
its body.

Low level functions (in C) that insert text into
a buffer should unconditionally delete the tentative
region first, if there is one, and set tentative-mark
to nil.  Conceptually, this is a generalization of the
notion of a "point".  A point is an index naming
a theoretical "space between" two adjacent
characters in a buffer, or the space at the beginning
or end of buffer.   A "tentative region" is like
having a pseudo-point which indicates a conceptual
"space between" in a hypothetical buffer that results
from deleting the contents of the tentative region.


That is the essential functionality that
delete-selection-mode is aiming for but, by adding
the concept of a tentative-mark, that essential
functionality is simplified enough that it can
reasonably be built-in as unconditional behavior
of a few insertion commands.

There should be a a second and third variable:
maybe-preserved-tentative-mark and preserved-tentative-mark.
These are, again, either nil or a mark.   These are used
to control which commands preserve the tentative
mark vs. which set it back to nil (the default behavior):

When a command returns to a command loop, the
value of preserved-tentative-mark should be copied
to tentative-mark, unconditionally.  Both maybe-preserved-... and
preserved-... should be set to nil.    So, by default,
commands implicitly "clear" the tentative mark.

Before a command loop invokes a command, it
should first copy tenative-mark to maybe-preserved-...
That way, if a command wants to preserve the tentative
mark if it is already present (the default interpretation of
"shifted keysequences") then it can simply copy
maybe-preserved-...  to preserved-tentative-mark.
When the command returns, that saved mark will be
copied back to tentative-mark.

The function ensure-shifted-mode does this:

   if tentative-mark is nil,
     create a marker at the point
     set tentative-mark and maybe-preserved-... to that marker
   return

The function (call-interactively-preserving-transient 'X)
does:

    ensure-shifted-mode
    copy maybe-preserved-... to preserved-...
    call 'X interactively
    return

The command treat-as-shifted-sequence does this:

    unshift the invoking sequence
    push the new sequence back to input
    read a complete key sequence, selecting a command X
    call-interactively-preserving-transient X
    return

So, treat-as-shifted-sequence is a reasonable default binding
for shifted control and meta-keys or common sequences of
those, at least for users who want shift-select to happen.

The function returned by (treated-as-shifted-function 'X)
does this:

    call-interactively-preserving-transient 'X

and can be used to create bindings for key-sequences
that should enter "shift select mode" but that aren't
handled by default bindings to treat-as-shifted-sequence

I guess that the command yank would need to be modified.
I think that the modified version is simply

  copy maybe-preserved-... to preserved-...
  yank as before

Probably there are a small number of similar commands.

Another category of commands that will initially
behave oddly until modified are commands that
modify the buffer mainly elsewhere from the current
point.    replace-string is a decent example.   Those
can be fixed-on-demand to be:

    set transient-mark, maybe-preserved-..., and preserved-...
      all to nil
    behave as before

The display code can (or should unconditionally?)
highlight the transient region.

So, for example...

S-M-C-f, presumably invokes treat-as-shfited-sequence
and so selects the following word as part of the transient
region.   Repeating that extends the region.

Right-arrow, not invoking treat-as-shifted-.... implicitly
cancels the transient region.

On the other hand, typing 'x' ultimately calls a low-level
insert function with no save-excursion between the command
loop and that call.   That insertion automatically deletes
the transient region before inserting the x.

So, those basic things work right.

Similarly, instead of typing 'x', I can invoke the modified
yank.  If no transient-mark was set yank behaves as it
does today.   If a transient-mark is set, and so
maybe-... was set when the command was invoked,
then yank both (implicitly) deletes the transient region
*and* preserves the transient mark (so the pasted content
is the new content of the transient region).

What about something tricky like replace-string?   Using
only the above rules, with all of their unconditional properties,
they'll do something kind of dumb:  at their first "insert"
that happens to be outside of any save-excursion they'll
delete everything from the transient-mark (if present) to
the point.   A small core of those has to be fixed from the
start.   Obscure cases can be fixed on demand with a
one-line fix.  Either:

      (nilify-transient)  ; sets all three variables to nil
      (old-code)

or

     (ignoring-transient . old-code) ; save-excursion and nilify 
transient for body

My *guess* is that the second choice is nicer most times but that
both are handy to have.


So:

three new variables
one new display feature (clone of an existing feature)
a couple unconditional variable copies in the command loop
a few new functions
unconditionally delete the transient region in some C code
modify some core functions like yank and replace-string
fix obscure commands that work similarly to yank or replace-string on-demand
lots and lots of code that doesn't have to be modified at all
a very simple "state machine" model of the behavior
a behavior that highly agrees with "all those other GUIs"


For extra special featurefulness, you could build on that
by adding a "transient region ring" -- a circular buffer that
remembers the last N transient regions whenever some
command nillifies the transient region at the top level.
A "remembered" transient region is a pair of marks:
the transient-mark and a marker at what was then the
point.

N should probably be small but the idea is that recent
transient regions are cached so that if the region is
accidentally cleared by some command then a user
can likely restore it, easily.

So, in terms of "pronouns" again -- "addressing modes"
for users -- the mark stack gives you a set of pronouns
for recursing while the transient region ring gives
you augmented short-term memory about "fat cursors".

I'm really surprised, as I've been led to think about
these features by the recent discussion, just exactly
how complementary "GUI-style shift-select" and
Emacs' user model and command interaction loop
turn out to be.   They fit together like hand and glove,
if only Emacs will actually implement it that way.

I'm one of those users who is both an Emacs power user
*and* make pretty heavy use of GUI-style apps.   I constantly
have the low-level frustration of how selection, cut, paste,
etc. work differently between these environments:  often typing
or mousing into some app as if it were Emacs or into Emacs as
if it were some other app.   So, I feel pretty viscerally the
pain that work on shift selection is trying to address.  

I'm pretty convinced the little state machine model
I've been developing here is a really good model for the
desired functionality.   So, I'm skeptical that all the hair
of trying to use transient-mark-mode for this stuff is
a good idea.

-t





^ permalink raw reply	[flat|nested] 167+ messages in thread

* Re: Shift selection using interactive spec
  2008-03-15 17:16                   ` Shift selection using interactive spec Kim F. Storm
  2008-03-15 20:59                     ` Thomas Lord
@ 2008-03-15 21:08                     ` Thomas Lord
  2008-03-16  0:27                       ` Chong Yidong
  2008-03-16 14:40                     ` Shift selection using interactive spec Chong Yidong
  2 siblings, 1 reply; 167+ messages in thread
From: Thomas Lord @ 2008-03-15 21:08 UTC (permalink / raw)
  To: Kim F. Storm; +Cc: Chong Yidong, Dan Nicolaescu, Stefan Monnier, emacs-devel

I just want to add that shift-marking is really important
and that thinking about reducing it to a familiar state
machine is valuable, if it can be done:

This is one of the #1 user interface *obstacles*
for new Emacs users who have experience in typical
GUI apps.   If Emacs *can*, in a natural way, offer
such users *exactly what they expect* then that is
probably worth doing!

It's icing on the cake that these features would fit
in very nicely with the traditional Emacs command
set, benefiting "power users" at least as much as
GUI-corrupted-newbies.

There is an opportunity here, in my opinion, to
make Emacs a lot more approachable, to many
more people, without needing the kind of
"you're using Emacs... but not really" indirections
of things like VI modes, transient-mark-mode,
etc.     Transient-mark-mode and delete-mode
seem to me to have, in retrospect, been mistakes
that tried unsuccessfully to work around the
absence of the three special variables that I described.
(Had they been successes, probably they could have
been enabled by default.)

-t





^ permalink raw reply	[flat|nested] 167+ messages in thread

* Re: Shift selection using interactive spec
  2008-03-15 20:52                       ` Stefan Monnier
@ 2008-03-15 21:45                         ` Thomas Lord
  2008-03-16 14:15                           ` Chong Yidong
  2008-03-15 22:01                         ` shift-select harmony Thomas Lord
  1 sibling, 1 reply; 167+ messages in thread
From: Thomas Lord @ 2008-03-15 21:45 UTC (permalink / raw)
  To: Stefan Monnier; +Cc: Chong Yidong, Dan Nicolaescu, Kim F. Storm, emacs-devel

[-- Attachment #1: Type: text/plain, Size: 1977 bytes --]

Stefan Monnier wrote:
> Calling the function just means "I'm a movement command and would like
> to follow the new select-on-shift behavior".
>   

It's a red herring to think in terms of movement commands.

For example, if C-t invokes transpose-chars then,
by default, S-C-t should also invoke transpose-chars
but override the default and make the new default to
preserve the transient mark.   S-C-f S-C-f S-C-t S-C-f
makes one modification to the buffer and leaves a
transient region of three characters.   (Hopefully
transpose-chars is already coded so as to make
its buffer changes under save-excursion.)



> Then the function can decide on what actually happens when.
>
>   

The default behavior is to remove the transient region.

The default treatment of a shift sequence with no other binding
is to run the unshifted sequence, but keep the transient region
(by default).

A tiny minority of commands need to behave differently
from that but that minority isn't identical to "motion commands"
and that minority isn't treated homogenously (e.g., yank and
replace-string are both exceptions but they are different kinds of
exceptions).





>>   "Extend the temporary region highlighting for the next command"
>>     
>
>   
>> is a neater and more self-contained task for a function than
>>     
>
>   
>>   "Extend the temporary region highlighting for the next command, but
>>    only if this-single-command-shift-translated is non-nil; otherwise,
>>    do nothing"
>>     
>
>   

That's true but it can be even simpler than that by
setting the defaults properly, with regard to the
right model of select-shift state.


> The docstring of the function would be more like
>
>   "Handle the mark selection for movement commands."
>
>   

"Movement commands" isn't the right concept.   The decision
to extend or not extend the transient region is more a matter of
how a command is invoked than what it does, usually.   (Again,
commands like yank are exceptions).

-t



[-- Attachment #2: Type: text/html, Size: 3091 bytes --]

^ permalink raw reply	[flat|nested] 167+ messages in thread

* shift-select harmony
  2008-03-15 20:52                       ` Stefan Monnier
  2008-03-15 21:45                         ` Thomas Lord
@ 2008-03-15 22:01                         ` Thomas Lord
  2008-03-15 23:38                           ` Thomas Lord
  1 sibling, 1 reply; 167+ messages in thread
From: Thomas Lord @ 2008-03-15 22:01 UTC (permalink / raw)
  To: Stefan Monnier; +Cc: Chong Yidong, Dan Nicolaescu, Kim F. Storm, emacs-devel

I was thinking about a test-case of the shift-select
design I proposed.   Consider a hypothetical
"yank-as-s-exp" command.   It:

     inserts '(' at the point
     yanks
     inserts ')' at the point

Such a command could be created as a keyboard
macro, for example.

With my design, and a naively coded yank-as-s-exp
what happens?

The insert of '(' deletes a transient region, if one
is present.   The yank yanks but also sets a variable
preserved-transient-mark.   The ')' redundantly
deletes the (now empty) transient region.  Upon
return, consulting the variable preserved-..., the
command loop restores the transient mark so, in
the end, the new s-exp is left selected as the transient
region.

Such an example doesn't absolutely prove that my
design is the right one.   Perhaps there are natural,
hard to locate-and-fix counter-examples of
how the new variables would break existing code.
Kudos for anyone can think of such exceptions ahead
of running into them in practice.

But, such an example does strengthen the hypothesis
that my design is a good one:  that I've succeeded at
marrying the traditional model of Emacs' "dynamic
state" to an extension of that model that provides selection
behavior more like popular GUI apps. 

There is a "harmony" between my proposed design
and the traditional Emacs model.  It "DTRT" by
default in what seems to be the default case.  It leaves
a pretty small number of cases to be dealt with by hand.

The original mistake (of transient-....) was, again,
in trying to use the current mark rather than creating
the concept of a transient mark.   It's a very old mistake.
I can understand the confusion that results.  But... I
think what I'm suggesting fixes that confusion and if
it doesn't I'd really appreciate a concise, lucid explanation
of why.   The current effort seems to still suffer under
that original mistake.

-t





^ permalink raw reply	[flat|nested] 167+ messages in thread

* Re: shift-select harmony
  2008-03-15 22:01                         ` shift-select harmony Thomas Lord
@ 2008-03-15 23:38                           ` Thomas Lord
  0 siblings, 0 replies; 167+ messages in thread
From: Thomas Lord @ 2008-03-15 23:38 UTC (permalink / raw)
  To: Thomas Lord
  Cc: Chong Yidong, Dan Nicolaescu, emacs-devel, Stefan Monnier,
	Kim F. Storm

There's yet-another way to see the three-variable
idea.   I admit that this is an esoteric way to look
at the problem and solution but it is  a productive
way to look at it:

Think of something *like* Emacs but with this
difference:  instead of a "point" in the dynamic
state, the alterna-Emacs would have a "region".

What Emacs currently thinks of as the point
is, in alterna-Emacs, a pair of points where
the car of that pair is called the tentative mark
and the cdr is called the point (and more or less
coincides with the current notion of point).

In alterna-Emacs, there is no such thing as "insert".
There are commands called "insert[-*]" but what they
really do is replace the entire region -- not just the
point.

Well, alterna-Emacs is a superset of current
Emacs.   Current Emacs is a system in which
there exist no commands or primitive functions
that can be used  to construct a non-empty
current-region.    In current Emacs, the
tentative mark and the point always happen
to be the same.

The new functionality that is desired is a
systematic way to for users to define the
tentative mark separately from the point --
to create non-empty "current regions"
for primitives to use.

That's not a very big change, *afaict*, and
how it can be done is what I outlined in the
last couple of messages.

-t





^ permalink raw reply	[flat|nested] 167+ messages in thread

* Re: Shift selection using interactive spec
  2008-03-15 21:08                     ` Thomas Lord
@ 2008-03-16  0:27                       ` Chong Yidong
  2008-03-16  1:37                         ` Thomas Lord
  0 siblings, 1 reply; 167+ messages in thread
From: Chong Yidong @ 2008-03-16  0:27 UTC (permalink / raw)
  To: Thomas Lord; +Cc: Dan Nicolaescu, emacs-devel, Stefan Monnier, Kim F. Storm

Thomas Lord <lord@emf.net> writes:

> I just want to add that shift-marking is really important
> and that thinking about reducing it to a familiar state
> machine is valuable, if it can be done:
>
> This is one of the #1 user interface *obstacles*
> for new Emacs users who have experience in typical
> GUI apps.   If Emacs *can*, in a natural way, offer
> such users *exactly what they expect* then that is
> probably worth doing!

Yes.  If we implement shift-selection by default, it would provide
newbies with a default way to select text that comes with visual
highlighting.  I think it might not be necessary to change the default
for transient mark mode if we do this.




^ permalink raw reply	[flat|nested] 167+ messages in thread

* Re: Shift selection using interactive spec
  2008-03-16  0:27                       ` Chong Yidong
@ 2008-03-16  1:37                         ` Thomas Lord
  2008-03-16  9:09                           ` Mathias Dahl
  2008-03-16 18:40                           ` Shift selection using interactive spec Stefan Monnier
  0 siblings, 2 replies; 167+ messages in thread
From: Thomas Lord @ 2008-03-16  1:37 UTC (permalink / raw)
  To: Chong Yidong; +Cc: Dan Nicolaescu, Stefan Monnier, Kim F. Storm, emacs-devel

Chong Yidong wrote:
>  I think it might not be necessary to change the default
> for transient mark mode if we do this.
>   

The problem with trying to force-fit transient mark mode for
this purpose is that it tries to equivocate the traditional Emacs
current mark with the beginning of a "shift-selected" region.

That's a problem because the current mark in Emacs doesn't
traditionally behave anything like the beginning of a "shift-selected"
region.  It's a force fit, at best.   The addition (by transient-mark-mode)
of an "activated/de-activated" flag is a crude *approximation*
of what users expect, in a situation where no approximating is
necessary.   For example, a "right arrow" key-press should simply
*forget*, more or less entirely, the marker at the start of the
highlighted region.    That's the default behavior if tentative mark
functionality is added but it's functionality that would require
yet more elisp code if transient-mark-mode were to catch up with
it.

What users expect, in the traditional GUI paradigm, is a kind of
mark that doesn't toggle between "activated" and "deactivated" but,
rather, is always active when present but which commands tend to
cause to go away entirely.   Let's dub that "the mistake".  The
mistake is adding an "active" flag instead of a separate tentative
mark.

It's *because* of the mistake that, for example, Stefan is now
positing the existence of a formal category of "motion commands"
that have to be modified to call a function that dynamically
asserts that they are motion commands.    That hair is not necessary
if you add the simple mechanism of a tentative mark instead of
trying to force fit the hairy mechanisms of transient mark mode.

The "fat cursor" concept (a region, rather than a simple point)
is what those other applications actually do.   It's what user's
expect.   It's what "tentative mark" implements.   It's perfectly
harmonious with traditional Emacs.   It simply *is* TRT.

Transient-mark-mode is *similar* to TRT for many command
sequences but hairier to implement,
hairier to extend, and doesn't correspond to any user expectation but
only to what seemed easy enough to do to its implementor.

T-m-m was a *mistake* and now you guys seem to want
to double down on that bad bet.

-t


>
>
>   





^ permalink raw reply	[flat|nested] 167+ messages in thread

* Re: Shift selection using interactive spec
  2008-03-15  3:31               ` Stefan Monnier
  2008-03-15 14:07                 ` Chong Yidong
@ 2008-03-16  2:33                 ` Richard Stallman
  1 sibling, 0 replies; 167+ messages in thread
From: Richard Stallman @ 2008-03-16  2:33 UTC (permalink / raw)
  To: Stefan Monnier; +Cc: cyd, dann, storm, emacs-devel

    > So we define (i) an elisp function called, say,
    > shift-translation-handler, and (ii) a new interactive code that says
    > to call shift-translation-handler when a command is activated through
    > a shift translated keybinding.

    No: the function is called every time.  *All* the work is done by the
    elisp function.

Which proposal are you saying that about?




^ permalink raw reply	[flat|nested] 167+ messages in thread

* Re: Shift selection using interactive spec
  2008-03-16  1:37                         ` Thomas Lord
@ 2008-03-16  9:09                           ` Mathias Dahl
  2008-03-16 14:21                             ` Chong Yidong
  2008-03-16 16:34                             ` Dear lazyweb (Re: Shift selection using interactive spec) Thomas Lord
  2008-03-16 18:40                           ` Shift selection using interactive spec Stefan Monnier
  1 sibling, 2 replies; 167+ messages in thread
From: Mathias Dahl @ 2008-03-16  9:09 UTC (permalink / raw)
  To: Chong Yidong, Dan Nicolaescu, Stefan Monnier, Kim F. Storm,
	emacs-devel
  Cc: Thomas Lord

    The problem with trying to force-fit transient mark mode for this
    purpose is that it tries to equivocate the traditional Emacs current
    mark with the beginning of a "shift-selected" region.

    [snip]

    T-m-m was a *mistake* and now you guys seem to want
    to double down on that bad bet.

Is anyone looking into Thomas' ideas at all?  As far as I can see the
only response he has got is from David and, from what I can remember,
they seemed to mostly miscommunicate.

To me it seems like most people are rushing forward on this matter,
seemingly (granted, from my quite uninformed viewpoint) trying to "bolt
on" this shift-select functionality in some quite complicated manner,
while Thomas present some new interesting (to me at least, I do not
know enough on this subject to see if it has any real merits)
ideas that at least sound much simpler.

Could at least someone with a lot of knowledge in this area at least
refute the ideas with good arguments, it does not strike me as very
polite to just ignore people with different ideas like this. It seems he has
put in quite some thinking on this one.

Excuse me if this has already been discussed by others and I have
simply missed seeing it.

/Mathias




^ permalink raw reply	[flat|nested] 167+ messages in thread

* Re: Shift selection using interactive spec
@ 2008-03-16 12:58 Robert J. Chassell
  0 siblings, 0 replies; 167+ messages in thread
From: Robert J. Chassell @ 2008-03-16 12:58 UTC (permalink / raw)
  To: emacs-devel

As far as I can see, `transient-mark-mode' is a misnomer for
`transient-activated-region'.

The region that `C-x C-x' runs (exchange-point-and-mark) is not
normally highighted since that would leave highlighting when people
navigate with marks.  

You will note that `exchange-point-and-mark' does not turn on
`transient-mark-mode'; only `exchange-point-and-mark' with a prefix
argument does.  The command set-mark-command with a prefix argument
not only pops the mark, it does not show highlighting even when
`transient-mark-mode' is on.

It is a good idea to highlight non-standard activated regions with a
different color than a turned-on `transient-mark-mode' produces since
people cannot simply look a word ahead or look at a whole buffer to
see such an activated region.


    Today's GNU Emacs CVS snapshot, Sun, 2008 Mar 16  10:46 UTC
    GNU Emacs 23.0.60.22 (i686-pc-linux-gnu, GTK+ Version 2.12.5)
    started with

         src/emacs --q -nbc

-- 
    Robert J. Chassell                          GnuPG Key ID: 004B4AC8
    bob@rattlesnake.com                         bob@gnu.org
    http://www.rattlesnake.com                  http://www.teak.cc




^ permalink raw reply	[flat|nested] 167+ messages in thread

* Re: Shift selection using interactive spec
  2008-03-15 21:45                         ` Thomas Lord
@ 2008-03-16 14:15                           ` Chong Yidong
  2008-03-16 14:37                             ` Lennart Borgman (gmail)
  0 siblings, 1 reply; 167+ messages in thread
From: Chong Yidong @ 2008-03-16 14:15 UTC (permalink / raw)
  To: Thomas Lord; +Cc: Dan Nicolaescu, Stefan Monnier, Kim F. Storm, emacs-devel

Thomas Lord <lord@emf.net> writes:

> It's a red herring to think in terms of movement commands.
>
> For example, if C-t invokes transpose-chars then,
> by default, S-C-t should also invoke transpose-chars
> but override the default and make the new default to
> preserve the transient mark.   S-C-f S-C-f S-C-t S-C-f
> makes one modification to the buffer and leaves a
> transient region of three characters.   (Hopefully
> transpose-chars is already coded so as to make
> its buffer changes under save-excursion.)

It wouldn't be wise to make such a wide-ranging change in the behavior
of Emacs.  Since certain existing modes bind keys to shift modifiers,
we should not make it a general rule that a shift-something keybinding
changes the selecion.

The movement commands can be treated as a special case, for entirely
pragmatic reasons.  It helps that the shift modified versions of the
keybindings are typically unbound.




^ permalink raw reply	[flat|nested] 167+ messages in thread

* Re: Shift selection using interactive spec
  2008-03-16  9:09                           ` Mathias Dahl
@ 2008-03-16 14:21                             ` Chong Yidong
  2008-03-16 16:56                               ` Thomas Lord
  2008-03-16 16:34                             ` Dear lazyweb (Re: Shift selection using interactive spec) Thomas Lord
  1 sibling, 1 reply; 167+ messages in thread
From: Chong Yidong @ 2008-03-16 14:21 UTC (permalink / raw)
  To: Mathias Dahl
  Cc: Thomas Lord, Dan Nicolaescu, emacs-devel, Stefan Monnier,
	Kim F. Storm

"Mathias Dahl" <mathias.dahl@gmail.com> writes:

> Is anyone looking into Thomas' ideas at all?  As far as I can see the
> only response he has got is from David and, from what I can remember,
> they seemed to mostly miscommunicate.

I am still thinking about them.  As far as I can tell, what he is
suggesting is not straightfoward to implement.




^ permalink raw reply	[flat|nested] 167+ messages in thread

* Re: Shift selection using interactive spec
  2008-03-16 14:15                           ` Chong Yidong
@ 2008-03-16 14:37                             ` Lennart Borgman (gmail)
  0 siblings, 0 replies; 167+ messages in thread
From: Lennart Borgman (gmail) @ 2008-03-16 14:37 UTC (permalink / raw)
  To: Chong Yidong
  Cc: Thomas Lord, Dan Nicolaescu, emacs-devel, Stefan Monnier,
	Kim F. Storm

Chong Yidong wrote:
> Thomas Lord <lord@emf.net> writes:
> 
>> It's a red herring to think in terms of movement commands.
>>
>> For example, if C-t invokes transpose-chars then,
>> by default, S-C-t should also invoke transpose-chars
>> but override the default and make the new default to
>> preserve the transient mark.   S-C-f S-C-f S-C-t S-C-f
>> makes one modification to the buffer and leaves a
>> transient region of three characters.   (Hopefully
>> transpose-chars is already coded so as to make
>> its buffer changes under save-excursion.)
> 
> It wouldn't be wise to make such a wide-ranging change in the behavior
> of Emacs.  Since certain existing modes bind keys to shift modifiers,
> we should not make it a general rule that a shift-something keybinding
> changes the selecion.
> 
> The movement commands can be treated as a special case, for entirely
> pragmatic reasons.  It helps that the shift modified versions of the
> keybindings are typically unbound.

Perhaps it can be detected automatically if the command was a movement 
command (ie did not change the buffer)? The the change would be much 
less wide-ranging.




^ permalink raw reply	[flat|nested] 167+ messages in thread

* Re: Shift selection using interactive spec
  2008-03-15 17:16                   ` Shift selection using interactive spec Kim F. Storm
  2008-03-15 20:59                     ` Thomas Lord
  2008-03-15 21:08                     ` Thomas Lord
@ 2008-03-16 14:40                     ` Chong Yidong
  2008-03-16 15:04                       ` Lennart Borgman (gmail)
  2008-03-17  0:54                       ` Chong Yidong
  2 siblings, 2 replies; 167+ messages in thread
From: Chong Yidong @ 2008-03-16 14:40 UTC (permalink / raw)
  To: Kim F. Storm; +Cc: Dan Nicolaescu, Stefan Monnier, emacs-devel

storm@cua.dk (Kim F. Storm) writes:

> Now, before you settle on a solution, maybe you should also consider
> how to handle the delete-selection-mode in a sensible way without
> using the current pre-command-hook + command property approach.
>
> Of course, since shift-select is promoted to a standard feature by
> modifying the relevant commands, we can just take the same approach
> with delete-selection-mode, i.e. modify the relevant commands to
> simply honour delsel mode.

There are two possible behaviors:

1. If transient mark mode is on, activating shift selection should
resets and activates the mark, and the first unshifted command should
then return transient mark mode to its original non-nil value.  Thus
shift selection "stacks" on top of transient mark mode.  I am not
certain if there is a clean way to do this.  Maybe allow
transient-mark-mode to take the form of a list?  Any suggestions?

2. Shift selection commands activate the mark if it is not active, and
extends the region if the mark is activate.  Thus [S-right right
right] would do the same thing as [S-right S-right S-right].  This
would be rather easy to implement.  Though this behavior sounds
strange, it actually mirrors the way mouse selection currently works
in transient-mark-mode.




^ permalink raw reply	[flat|nested] 167+ messages in thread

* Re: Shift selection using interactive spec
  2008-03-16 14:40                     ` Shift selection using interactive spec Chong Yidong
@ 2008-03-16 15:04                       ` Lennart Borgman (gmail)
  2008-03-16 17:13                         ` Thomas Lord
  2008-03-17  0:54                       ` Chong Yidong
  1 sibling, 1 reply; 167+ messages in thread
From: Lennart Borgman (gmail) @ 2008-03-16 15:04 UTC (permalink / raw)
  To: Chong Yidong; +Cc: Dan Nicolaescu, emacs-devel, Stefan Monnier, Kim F. Storm

Chong Yidong wrote:
> storm@cua.dk (Kim F. Storm) writes:
> 
>> Now, before you settle on a solution, maybe you should also consider
>> how to handle the delete-selection-mode in a sensible way without
>> using the current pre-command-hook + command property approach.
>>
>> Of course, since shift-select is promoted to a standard feature by
>> modifying the relevant commands, we can just take the same approach
>> with delete-selection-mode, i.e. modify the relevant commands to
>> simply honour delsel mode.
> 
> There are two possible behaviors:
> 
> 1. If transient mark mode is on, activating shift selection should
> resets and activates the mark, and the first unshifted command should
> then return transient mark mode to its original non-nil value.  Thus
> shift selection "stacks" on top of transient mark mode.  I am not
> certain if there is a clean way to do this.  Maybe allow
> transient-mark-mode to take the form of a list?  Any suggestions?

I have right now no suggestion on the implementation, but a comment on 
the behaviour.

This sounds like the behaviour most users would expect from their 
experience in other application. I agree with Thomas that this 
congruence is desirable.

But I think there also must be ways to easily and permanently escape the 
deactivation. For some bindings there is no way to get a shifted 
binding. (An example of this is using % in Viper to move to the opposite 
parenthesis.)

> 2. Shift selection commands activate the mark if it is not active, and
> extends the region if the mark is activate.  Thus [S-right right
> right] would do the same thing as [S-right S-right S-right].  This
> would be rather easy to implement.  Though this behavior sounds
> strange, it actually mirrors the way mouse selection currently works
> in transient-mark-mode.

Such behaviour would be a disaster for manu users, especially new users 
that are used to 1 above.




^ permalink raw reply	[flat|nested] 167+ messages in thread

* Dear lazyweb (Re: Shift selection using interactive spec)
  2008-03-16  9:09                           ` Mathias Dahl
  2008-03-16 14:21                             ` Chong Yidong
@ 2008-03-16 16:34                             ` Thomas Lord
  1 sibling, 0 replies; 167+ messages in thread
From: Thomas Lord @ 2008-03-16 16:34 UTC (permalink / raw)
  To: Mathias Dahl
  Cc: Chong Yidong, Dan Nicolaescu, emacs-devel, Stefan Monnier,
	Kim F. Storm

Mathias Dahl wrote:
> Is anyone looking into Thomas' ideas at all? 
>   

Thank you.

I have a research question I'd like to suggest to anyone who
might be interested and the question and who, unlike me,
is not feeling too lazy at the moment to do some research
about the question.

Very simply:

How does Open Office implement shift select?

What variables control shift select in Open Office?  What APIs?
"How do they do that?"

The point of the question is that Open Office's behavior
is probably a pretty good example of "what user's expect".

I don't know what the outcome of researching this question
will be.   Maybe the OO implementation is an ad hoc mess
and will just add to the confusion.   Or, maybe, they have a
very clean model of it that will reward the question asked
with new clarity.

(Because the universe tends towards the cruel and ironic,
probably it will turn out that OO sets a flag for many
commands, defining a category of "motion commands",
and does it all with the moral equivalent of hairy pre- and
post- command magic -- exactly what Emacs should *not*
do -- but there is some chance that OO happens to do it
some clean and illuminating way.)

-t





^ permalink raw reply	[flat|nested] 167+ messages in thread

* Re: Shift selection using interactive spec
  2008-03-16 14:21                             ` Chong Yidong
@ 2008-03-16 16:56                               ` Thomas Lord
  0 siblings, 0 replies; 167+ messages in thread
From: Thomas Lord @ 2008-03-16 16:56 UTC (permalink / raw)
  To: Chong Yidong
  Cc: Dan Nicolaescu, emacs-devel, Stefan Monnier, Kim F. Storm,
	Mathias Dahl

Chong Yidong wrote:
> I am still thinking about them.  As far as I can tell, what he is
> suggesting is not straightfoward to implement.
>   


In what way, specifically?   It is true that it's been a long
time since I've hacked Emacs C code and only a little
bit less of a long time since I hacked in the guts of
elisp code so it certainly is possible that I'm missing something
obvious that makes my idea unworkable.    But, if so, what
specifically?

-t






^ permalink raw reply	[flat|nested] 167+ messages in thread

* Re: Shift selection using interactive spec
  2008-03-16 15:04                       ` Lennart Borgman (gmail)
@ 2008-03-16 17:13                         ` Thomas Lord
  0 siblings, 0 replies; 167+ messages in thread
From: Thomas Lord @ 2008-03-16 17:13 UTC (permalink / raw)
  To: Lennart Borgman (gmail)
  Cc: Chong Yidong, Dan Nicolaescu, Stefan Monnier, Kim F. Storm,
	emacs-devel

Lennart Borgman (gmail) wrote:
>
> But I think there also must be ways to easily and permanently escape 
> the deactivation. For some bindings there is no way to get a shifted 
> binding. (An example of this is using % in Viper to move to the 
> opposite parenthesis.)

In other words, you want a "shift-select-mode" lock -- like "caps lock"
but for shift select?

In the three-variable model, when a command returns, the
command loop does:

  (setq tentative-mark preserved-tentative-mark)

Adding shift-mode-lock support changes that to:

  (if shift-mode-lock
    (setq preserved-tentative-mark maybe-preserved-tentative-mark))
  (setq tentative-mark perserved-tentative-mark)





>
>> 2. Shift selection commands activate the mark if it is not active, and
>> extends the region if the mark is activate.  Thus [S-right right
>> right] would do the same thing as [S-right S-right S-right].  This
>> would be rather easy to implement.  Though this behavior sounds
>> strange, it actually mirrors the way mouse selection currently works
>> in transient-mark-mode.
>
> Such behaviour would be a disaster for manu users, especially new 
> users that are used to 1 above.
>
>
>


"Disaster" is a well chosen word, there.   Using arrow keys to
cancel a tentative mark is actually part of "how people use"
shift select.   It's a gesture that gets built-in to muscle memory.

-t





^ permalink raw reply	[flat|nested] 167+ messages in thread

* Re: Shift selection using interactive spec
  2008-03-16  1:37                         ` Thomas Lord
  2008-03-16  9:09                           ` Mathias Dahl
@ 2008-03-16 18:40                           ` Stefan Monnier
  2008-03-16 21:00                             ` Thomas Lord
  1 sibling, 1 reply; 167+ messages in thread
From: Stefan Monnier @ 2008-03-16 18:40 UTC (permalink / raw)
  To: Thomas Lord; +Cc: Chong Yidong, Dan Nicolaescu, Kim F. Storm, emacs-devel

> That's a problem because the current mark in Emacs doesn't
> traditionally behave anything like the beginning of a "shift-selected"
> region.  It's a force fit, at best.   The addition (by transient-mark-mode)
> of an "activated/de-activated" flag is a crude *approximation*
> of what users expect, in a situation where no approximating is
> necessary.   For example, a "right arrow" key-press should simply
> *forget*, more or less entirely, the marker at the start of the
> highlighted region.    That's the default behavior if tentative mark
> functionality is added but it's functionality that would require
> yet more elisp code if transient-mark-mode were to catch up with
> it.

I do not follow you, Tom: how would the right arrow magically forget
your tentative mark?  In what way is that different from setting
mark-active to nil?  I have the strong impression that you do not know
what is the "temporary" form of transient-mark-mode" (this is
a transient-mark-mode that's activated until the region is "consumed")
and neither do you know about the "only" form of transient-mark-mode
(that is a form of transient-mark-mode which is deactivated after the
very next command).

> What users expect, in the traditional GUI paradigm, is a kind of
> mark that doesn't toggle between "activated" and "deactivated" but,
> rather, is always active when present but which commands tend to
> cause to go away entirely.   Let's dub that "the mistake".  The
> mistake is adding an "active" flag instead of a separate tentative
> mark.

In what way is it different, really?  The problem is how/when to
activate/set it and how/when to deactivate/unset it.  Whether it's
a flag or a mark makes no difference.

> It's *because* of the mistake that, for example, Stefan is now
> positing the existence of a formal category of "motion commands"
> that have to be modified to call a function that dynamically
> asserts that they are motion commands.

??? The notion of "motion commands" is needed because the behavior we
want is "when a motion command is bound to a non-shifted key but is
activated via the shifted of that key, we want the motion to select
a region".

Try it in your typical GUI editor: S-arrow will select a region, but S-a
will just insert an upper-case A.

I.e. this need is 100% unrelated to the way the selected region is
implemented and when/how it gets de-selected.


        Stefan




^ permalink raw reply	[flat|nested] 167+ messages in thread

* Re: Shift selection using interactive spec
  2008-03-16 21:00                             ` Thomas Lord
@ 2008-03-16 20:45                               ` Thien-Thi Nguyen
  2008-03-16 21:46                                 ` Thomas Lord
  2008-03-16 23:04                               ` Lennart Borgman (gmail)
                                                 ` (2 subsequent siblings)
  3 siblings, 1 reply; 167+ messages in thread
From: Thien-Thi Nguyen @ 2008-03-16 20:45 UTC (permalink / raw)
  To: Thomas Lord; +Cc: emacs-devel

() Thomas Lord <lord@emf.net>
() Sun, 16 Mar 2008 14:00:03 -0700

   three variable system, most commands DTRT by default, even if
   they remain ignorant of the three variables.

Do you mean to say "three state"?  To me, three (non-boolean)
variables implies many many states.  Even if they are all
boolean, that would mean eight states, ie, a lot of hair.

thi




^ permalink raw reply	[flat|nested] 167+ messages in thread

* Re: Shift selection using interactive spec
  2008-03-16 18:40                           ` Shift selection using interactive spec Stefan Monnier
@ 2008-03-16 21:00                             ` Thomas Lord
  2008-03-16 20:45                               ` Thien-Thi Nguyen
                                                 ` (3 more replies)
  0 siblings, 4 replies; 167+ messages in thread
From: Thomas Lord @ 2008-03-16 21:00 UTC (permalink / raw)
  To: Stefan Monnier; +Cc: Chong Yidong, Dan Nicolaescu, emacs-devel, Kim F. Storm

[-- Attachment #1: Type: text/plain, Size: 9661 bytes --]

Stefan Monnier wrote:
> I do not follow you, Tom: how would the right arrow magically forget
> your tentative mark? 


There are three, per-buffer variables:

    tentative-mark:
        the "other side" (besides the point) of the current,
        shift-selected region, as far as primitive operations
        on buffers are concerned.    The tenative-mark, if not
        nil, combines with the point to create a "fat cursor" --
        e.g., primitive insertion operations delete the contents
        of the fat cursor before inserting.

    maybe-preserved-tentative-mark:
        The value of tentative-mark as last observed by the
        user.  That is, before every interactive command
        invocation, the value of tentative-mark is unconditionally
        copied to become the value of maybe-preserved-....

    preserved-tentative-mark:
         The value that, in the opinion of the currently running
         command, should become the value of transient-mark
         after the command completes.   By default, this is nil.
         Command loops, when interactively invoked commands
         return, unconditionally copy the value of perserved-tentative-mark
         to tentative-mark.

So, suppose I type S-right-arrow, invoking shift-select mode.
That invokes a generic function -- let's dub it treat-as-shifted-sequence.
That function creates a marker at the point and sets 
preserved-tentative-mark
to that new marker.   Then it looks up what the unshifted sequence 
right-arrow
is bound to and runs that command.   That command (forward-char) is
ignorant of the three variables so it doesn't change them at all.   When
control returns to the command loop, the value of preserved-tentative-mark
is copied to tentative-mark -- so now there is a tentative-mark (start of a
shift-mark region) set.

Typing S-right-arrow again has almost the same effect.   Instead of
creating a new marker, the generic function treat-as-shifted-sequence
notices that, this time, maybe-preserved-tentative-mark is non-nil.
Rather than create a new mark, it just copies that value to preserved-....
So, the tentative mark (start of shift region) is preserved.

But then you type just right-arrow, with no shift.   When invoked,
tentative-mark and maybe-preserved-.... are still both set to that
original mark, but preserved-tentative-mark has its default value of
nil.   The right arrow binding (forward char) is still ignorant of those
three variables.   It changes nothing.   When control returns to the
command loop, preserved-... (which is bound to nil) is copied to
tentative-mark






>  In what way is that different from setting
> mark-active to nil?  

There are two aspects to the answer:  cleanliness and
semantics.

Cleanliness: the three variable proposal needs a *tiny bit*
of new code in the C part of Emacs.   In exchange, it
doesn't need transitive-mark or delete-mark... elisp code
at all (because the default behaviors are better).

Cleanliness again:  In the three variable system, most
commands DTRT by default, even if they remain ignorant
of the three variables.

Semantics:  the three variable model is sensitive to
"cycle phases" in user interaction.   maybe-perserved-...
is a reliable source of the value of the tentative mark as
of the time the user last saw it.    preserved-.... is
how function control what the value of the tentative
mark will be when the user next sees it.   tentative-mark
itself is the value honored by primitives.    Making
those distinctions has a side effect: the default behaviors
comes out correctly, for free, and the non-default
behaviors are trivial to implement in generic ways.
In contrast, just having a binary distinction between
an active and inactive mark means having to make those
other distinctions harder to implement -- lots of functions
have to be modified because that's the only way left
to make those distinctions.   It's *why* you're ending up
thinking about distinguishing "motion commands" and
the like.   Maybe the simple form is just: "I dunno. 
The three-variable implementation is just cleaner.
It happens to hit a sweet spot that way.   It just *is*."



> I have the strong impression that you do not know
> what is the "temporary" form of transient-mark-mode" (this is
> a transient-mark-mode that's activated until the region is "consumed")
>   
You are right that I don't know about that.  I poked around in simple.el
a little to see if I could find what you meant but I didn't.  So, please 
point
me to the code.

That aside, first you had to invent "motion" commands, and now there
is another category of commands that are "consuming" commands.  Ugh.
This proliferation of categories is the price for using a binary "active"
flag rather than the three-variable system.    How are those categories
supposed to compose, anyway?   That is, if I call a "consuming" command
as a function, does that make my command also "consuming"?    This seems
fragile and hard to control.


> and neither do you know about the "only" form of transient-mark-mode
> (that is a form of transient-mark-mode which is deactivated after the
> very next command).
>
>   

You keep misunderstanding me.   I understand (enough) about how transient
mark mode models "activation".   What I'm saying in response to that design,
not in ignorance of it, is that "activation" is the wrong model and that 
the
three-variable model is the model users are thinking of.   And the three 
variable
model seems to come out cleanly in code.   And the three variable model 
extends
and complements the traditional Emacs mark stack.

There's a funny bit in the Emacs documentation:

     Novice Emacs Lisp programmers often try to use the mark for the wrong
     purposes.  The mark saves a location for the user's convenience.
     Most editing commands should not alter the mark.

I'm not, by a long shot, calling you a novice.   Really.   But the
admonishment of that bit in the documentation applies to this
problem in a subtle way.

The marker (not mark but marker) which is set when a user is
shift-selecting:  it does not, in GUIs, act like a "location [saved] for
the user's convenience".    Yes, it's a saved location.  Yes, it's a 
convenience
feature.   But commands don't actually *use* that marker in the same
way that they use traditional Emacs *marks*.

The boolean "active" flag is an attempt to turn the top of the
traditional mark stack into a discriminated union.   When that flag is
set, the marker on the top of the mark stack is supposed to behave
"like the beginning of a shift-selected-region".   But that's ugly and
complicated because it changes the model that commands are "used to"
about what the mark stack means.  The mark stack is a saved location
for the user to pop back to -- except when it isn't because it's a saved
location for the very different behavior of a shift-selected region.

The three-variable model -- the concept of a "fat cursor" that is
sensitive to the cycle phases of interaction -- is exactly what all those
other GUI programs do and it is quite consonant with traditional Emacs.
It's a much simpler approach.


>> What users expect, in the traditional GUI paradigm, is a kind of
>> mark that doesn't toggle between "activated" and "deactivated" but,
>> rather, is always active when present but which commands tend to
>> cause to go away entirely.   Let's dub that "the mistake".  The
>> mistake is adding an "active" flag instead of a separate tentative
>> mark.
>>     
>
> In what way is it different, really?  The problem is how/when to
> activate/set it and how/when to deactivate/unset it.  Whether it's
> a flag or a mark makes no difference.
>
>   

It makes a difference in terms of the amount of existing code that
needs to be modified.   In the three variable system, most existing
code can remain ignorant of the three variables -- TRT happens by
default.



>> It's *because* of the mistake that, for example, Stefan is now
>> positing the existence of a formal category of "motion commands"
>> that have to be modified to call a function that dynamically
>> asserts that they are motion commands.
>>     
>
> ??? The notion of "motion commands" is needed because the behavior we
> want is "when a motion command is bound to a non-shifted key but is
> activated via the shifted of that key, we want the motion to select
> a region".
>   

Better (more consistent, simpler) is:  "when a command is bound to a 
non-shifted
key but is invoked via a shifted sequence, we want the shift-select 
region to
remain active during that command".   There's no need to talk about 
"motion".



> Try it in your typical GUI editor: S-arrow will select a region, but S-a
> will just insert an upper-case A.
>   

That's different.   S-A (at least conceptually) has a non-default 
binding.  It doesn't,
by default, "insert 'a' and be in shift-select mode".  

Not many modes have "hyper" bindings.   A good test for a design might 
be how
easy it is for eccentric users to say "Ok, I want 'shift-select' 
functionality but, in Emacs,
I'd prefer it via the hyper key, not the shift key".   So, H-S-A would, 
very reasonably,
insert an upper case 'A' and be in shift-select mode.

(I was thinking, personally, that I might use a foot pedal for 
shift-select mode.)
> I.e. this need is 100% unrelated to the way the selected region is
> implemented and when/how it gets de-selected.
>
>   

It's true that a traditional mark stack plus a binary variable can be used
to emulate the three-variable solution.   However, that emulation requires
far broader and more conceptually dissonant changes than the three variable
solution.

-t






>         Stefan
>
>
>
>   


[-- Attachment #2: Type: text/html, Size: 12825 bytes --]

^ permalink raw reply	[flat|nested] 167+ messages in thread

* Re: Shift selection using interactive spec
  2008-03-16 21:46                                 ` Thomas Lord
@ 2008-03-16 21:24                                   ` Thien-Thi Nguyen
  2008-03-16 22:27                                     ` Thomas Lord
  0 siblings, 1 reply; 167+ messages in thread
From: Thien-Thi Nguyen @ 2008-03-16 21:24 UTC (permalink / raw)
  To: Thomas Lord; +Cc: emacs-devel

() Thomas Lord <lord@emf.net>
() Sun, 16 Mar 2008 14:46:17 -0700

   Under "nominal operating conditions" if any two or three of the
   variables are bound to marker, they are bound to the *same*
   marker.

   I agree that 8 is a suspiciously large number for something
   like this and I encourage people to find a really solid
   refutation of my idea.  Please keep trying.  But... 8 in and of
   itself is not quite a refutation.

Eight is an invitation for you to join in the refutation process.
If i could dedicate more time to this, i would start by looking at
weird cases, outside "nominal operating conditions".  But alas...

thi




^ permalink raw reply	[flat|nested] 167+ messages in thread

* Re: Shift selection using interactive spec
  2008-03-16 20:45                               ` Thien-Thi Nguyen
@ 2008-03-16 21:46                                 ` Thomas Lord
  2008-03-16 21:24                                   ` Thien-Thi Nguyen
  0 siblings, 1 reply; 167+ messages in thread
From: Thomas Lord @ 2008-03-16 21:46 UTC (permalink / raw)
  To: Thien-Thi Nguyen; +Cc: emacs-devel

Thien-Thi Nguyen wrote:
> () Thomas Lord <lord@emf.net>
> () Sun, 16 Mar 2008 14:00:03 -0700
>
>    three variable system, most commands DTRT by default, even if
>    they remain ignorant of the three variables.
>
> Do you mean to say "three state"?  To me, three (non-boolean)
> variables implies many many states. 


There are three variables.  Each bound either to nil or a marker.
Under "nominal operating conditions" if any two or three of the
variables are bound to marker, they are bound to the *same*
marker.

So, normally, there are 8 possible states.   And that sounds
hopelessly hairy because 8 *is* a ridiculously large number.
Except that when you look at how they actually work,
it's 8 states in one sense, but in a deeper sense it's a set
of three, orthogonal, binary states:

   Was tentative-mark set when this command was invoked?
      That's maybe-preserved-tentative-mark

   Should tentative-mark be set when this command is done?
     That's preserved-tentative-mark

    Should primitives recognize that there is a tentative mark,
    e.g. by deleting the selected region before any insertion?
       That's tentative-mark.




>  Even if they are all
> boolean, that would mean eight states, ie, a lot of hair.
>
>   

I agree that 8 is a suspiciously large number for something
like this and I encourage people to find a really solid refutation
of my idea.   Please keep trying.   But... 8 in and of itself is
not quite a refutation.

The eight states partition nicely into those three, orthogonal,
binary states.   Those states very simply refer to specific points
in time during the phases of a command cycle.   There's 8, sure,
but really, it's just three, kinda-separate, individually trivial things.

But yes: 8 is a big number and good spotting.   That is
a direction in which to be skeptical, I agree.

-t





> thi
>
>
>
>   





^ permalink raw reply	[flat|nested] 167+ messages in thread

* Re: Shift selection using interactive spec
  2008-03-16 21:24                                   ` Thien-Thi Nguyen
@ 2008-03-16 22:27                                     ` Thomas Lord
  0 siblings, 0 replies; 167+ messages in thread
From: Thomas Lord @ 2008-03-16 22:27 UTC (permalink / raw)
  To: Thien-Thi Nguyen; +Cc: emacs-devel

Thien-Thi Nguyen wrote:
> Eight is an invitation for you to join in the refutation process.
>
>   

Thank you.   I think I am already there, actually.  And I'm not having
much success at finding a refutation

-t






^ permalink raw reply	[flat|nested] 167+ messages in thread

* Re: Shift selection using interactive spec
  2008-03-16 21:00                             ` Thomas Lord
  2008-03-16 20:45                               ` Thien-Thi Nguyen
@ 2008-03-16 23:04                               ` Lennart Borgman (gmail)
  2008-03-16 23:17                                 ` Lennart Borgman (gmail)
  2008-03-17  0:46                                 ` Thomas Lord
  2008-03-16 23:35                               ` Stephen J. Turnbull
  2008-03-17  2:21                               ` Stefan Monnier
  3 siblings, 2 replies; 167+ messages in thread
From: Lennart Borgman (gmail) @ 2008-03-16 23:04 UTC (permalink / raw)
  To: Thomas Lord
  Cc: Chong Yidong, Dan Nicolaescu, Stefan Monnier, Kim F. Storm,
	emacs-devel

Thomas Lord wrote:
> Stefan Monnier wrote:
>> I do not follow you, Tom: how would the right arrow magically forget
>> your tentative mark? 
> 
> 
> There are three, per-buffer variables:
> 
>     tentative-mark:
>         the "other side" (besides the point) of the current,
>         shift-selected region, as far as primitive operations
>         on buffers are concerned.    The tenative-mark, if not
>         nil, combines with the point to create a "fat cursor" --
>         e.g., primitive insertion operations delete the contents
>         of the fat cursor before inserting.
> 
>     maybe-preserved-tentative-mark:
>         The value of tentative-mark as last observed by the
>         user.  That is, before every interactive command
>         invocation, the value of tentative-mark is unconditionally
>         copied to become the value of maybe-preserved-....
> 
>     preserved-tentative-mark:
>          The value that, in the opinion of the currently running
>          command, should become the value of transient-mark
>          after the command completes.   By default, this is nil.
>          Command loops, when interactively invoked commands
>          return, unconditionally copy the value of perserved-tentative-mark
>          to tentative-mark.
> 
> So, suppose I type S-right-arrow, invoking shift-select mode.
> That invokes a generic function -- let's dub it treat-as-shifted-sequence.
> That function creates a marker at the point and sets 
> preserved-tentative-mark
> to that new marker.   Then it looks up what the unshifted sequence 
> right-arrow
> is bound to and runs that command.   That command (forward-char) is
> ignorant of the three variables so it doesn't change them at all.   When
> control returns to the command loop, the value of preserved-tentative-mark
> is copied to tentative-mark -- so now there is a tentative-mark (start of a
> shift-mark region) set.
> 
> Typing S-right-arrow again has almost the same effect.   Instead of
> creating a new marker, the generic function treat-as-shifted-sequence
> notices that, this time, maybe-preserved-tentative-mark is non-nil.
> Rather than create a new mark, it just copies that value to preserved-....
> So, the tentative mark (start of shift region) is preserved.
> 
> But then you type just right-arrow, with no shift.   When invoked,
> tentative-mark and maybe-preserved-.... are still both set to that
> original mark, but preserved-tentative-mark has its default value of
> nil.   The right arrow binding (forward char) is still ignorant of those
> three variables.   It changes nothing.   When control returns to the
> command loop, preserved-... (which is bound to nil) is copied to
> tentative-mark

I translate it to something like this in elisp code:

;;;; pre-pre
;;   treat-as-shifted:
(setq maybe-preserved-tm tm)
(if shifted
     (setq preserved-tm
           (if tm tm (make-marker)))
   (setq preserved-tm nil))

;;;; run unshifted command + hooks
;; Neither maybe-preserved-tm or preserved-tm
;; are touched here (maybe not even known)

;;;; post-post
;;
(if buffer-was-changed
     (setq preserved-tm nil)
   (unless preserved-tm
     (when user-wants-it
       (setq preserved-tm maybe-preserved-tm))))
(setq tm preserved-tm)


>>  In what way is that different from setting
>> mark-active to nil?  
> 
> There are two aspects to the answer:  cleanliness and
> semantics.
> 
> Cleanliness: the three variable proposal needs a *tiny bit*
> of new code in the C part of Emacs.   In exchange, it
> doesn't need transitive-mark or delete-mark... elisp code
> at all (because the default behaviors are better).
> 
> Cleanliness again:  In the three variable system, most
> commands DTRT by default, even if they remain ignorant
> of the three variables.
> 
> Semantics:  the three variable model is sensitive to
> "cycle phases" in user interaction.   maybe-perserved-...
> is a reliable source of the value of the tentative mark as
> of the time the user last saw it.    preserved-.... is
> how function control what the value of the tentative
> mark will be when the user next sees it.   tentative-mark
> itself is the value honored by primitives.    Making
> those distinctions has a side effect: the default behaviors
> comes out correctly, for free, and the non-default
> behaviors are trivial to implement in generic ways.
> In contrast, just having a binary distinction between
> an active and inactive mark means having to make those
> other distinctions harder to implement -- lots of functions
> have to be modified because that's the only way left
> to make those distinctions.   It's *why* you're ending up
> thinking about distinguishing "motion commands" and
> the like.   Maybe the simple form is just: "I dunno. 
> The three-variable implementation is just cleaner.
> It happens to hit a sweet spot that way.   It just *is*."





^ permalink raw reply	[flat|nested] 167+ messages in thread

* Re: Shift selection using interactive spec
  2008-03-16 23:04                               ` Lennart Borgman (gmail)
@ 2008-03-16 23:17                                 ` Lennart Borgman (gmail)
  2008-03-17  0:46                                 ` Thomas Lord
  1 sibling, 0 replies; 167+ messages in thread
From: Lennart Borgman (gmail) @ 2008-03-16 23:17 UTC (permalink / raw)
  To: Thomas Lord
  Cc: Chong Yidong, Dan Nicolaescu, emacs-devel, Stefan Monnier,
	Kim F. Storm

Lennart Borgman (gmail) wrote:
> I translate it to something like this in elisp code:
> 
> ;;;; pre-pre
> ;;   treat-as-shifted:
> (setq maybe-preserved-tm tm)
> (if shifted
>     (setq preserved-tm
>           (if tm tm (make-marker)))
>   (setq preserved-tm nil))
> 
> ;;;; run unshifted command + hooks
> ;; Neither maybe-preserved-tm or preserved-tm
> ;; are touched here (maybe not even known)
> 
> ;;;; post-post
> ;;
> (if buffer-was-changed
>     (setq preserved-tm nil)
>   (unless preserved-tm
>     (when user-wants-it
>       (setq preserved-tm maybe-preserved-tm))))
> (setq tm preserved-tm)


Sorry for bad translation. This is probably better. (Remember 
translation always includes some mind reading too)


;;;; pre-pre
;;   treat-as-shifted:
(setq maybe-preserved-tm tm)
(if shifted
     (setq preserved-tm
           (if tm tm (make-marker)))
   (setq preserved-tm nil))

;;;; run unshifted command + hooks
;;
;; maybe-preserved-tm is not touched here, but
;; preserved-tm might be set to nil, for example
;; by some copy command.

;;;; post-post
(when buffer-was-changed
   (setq preserved-tm nil))
(unless preserved-tm
   (when user-wants-tm
     (setq preserved-tm maybe-preserved-tm)))
(setq tm preserved-tm)




^ permalink raw reply	[flat|nested] 167+ messages in thread

* Re: Shift selection using interactive spec
  2008-03-15 20:59                     ` Thomas Lord
@ 2008-03-16 23:31                       ` Alan Mackenzie
  0 siblings, 0 replies; 167+ messages in thread
From: Alan Mackenzie @ 2008-03-16 23:31 UTC (permalink / raw)
  To: Thomas Lord
  Cc: Chong Yidong, Dan Nicolaescu, emacs-devel, Stefan Monnier,
	Kim F. Storm

Hi, Thomas!

On Sat, Mar 15, 2008 at 01:59:25PM -0700, Thomas Lord wrote:

[ .... ]

> The region between tenative-mark and point is called the
> tentative-region.

> save-excursion should save and restore the value of tentative-mark,
> setting it to nil when running its body.

Maybe.

> Low level functions (in C) that insert text into a buffer should
> unconditionally delete the tentative region first, if there is one, and
> set tentative-mark to nil.

No, I disagree.  Philosophically, this is a mixup of levels.  A low-level
function which is inserting text should NOT be messing around with
tentative regions.  This will surely cause pain, in some as yet unclear
way.  Surely higher level defuns should be built which call the C
primitives, allowing these primitives to remain primitive.

Also, can't we make Emacs a bit better?  A tentative region should be
_killed_, not deleted - i.e., there should be an easy way of recovering
it when it's accidentally de-regioned.

> Conceptually, this is a generalization of the notion of a "point".  A
> point is an index naming a theoretical "space between" two adjacent
> characters in a buffer, or the space at the beginning or end of buffer.
> A "tentative region" is like having a pseudo-point which indicates a
> conceptual "space between" in a hypothetical buffer that results from
> deleting the contents of the tentative region.

> That is the essential functionality that delete-selection-mode is
> aiming for but, by adding the concept of a tentative-mark, that
> essential functionality is simplified enough that it can reasonably be
> built-in as unconditional behavior of a few insertion commands.

That unconditionality would make the concept of a "tentative region" less
flexible and less useful, wouldn't it?  The user should be able to
customize when his tentative regions are killed by insertion commands;
for example, by major mode.

> There should be a a second and third variable:
> maybe-preserved-tentative-mark and preserved-tentative-mark.  These
> are, again, either nil or a mark.   These are used to control which
> commands preserve the tentative mark vs. which set it back to nil (the
> default behavior):

You've completely lost me, here.  I can't see how the first two sentences
connect with the last one.

I'm also getting lost in the sheer complexity of the proposal, and feel
that three "tentative-mark" variables is a bad idea - there will be too
much confusion between them.

> When a command returns to a command loop, the value of
> preserved-tentative-mark should be copied to tentative-mark,
> unconditionally.  Both maybe-preserved-... and preserved-... should be
> set to nil.    So, by default, commands implicitly "clear" the
> tentative mark.

Presumbaly, there would be customization commands to tailor this default.
For example, C-l is the sort of thing you'd want to do _without_ losing a
tentative region.

> Before a command loop invokes a command, it should first copy
> tenative-mark to maybe-preserved-...  That way, if a command wants to
> preserve the tentative mark if it is already present (the default
> interpretation of "shifted keysequences") then it can simply copy
> maybe-preserved-...  to preserved-tentative-mark.  When the command
> returns, that saved mark will be copied back to tentative-mark.

This sounds like the tail waggging the dog.  If a command wants to
preserve a tentative mark, it merely needs to do nothing.  Why should the
command loop be complicated for this purpose?

I really don't think we should be messing with the command loop for this
facility; that's a horrible kludge.  The mechanics of executing one
command after another should be kept separate from what these commands
do; conceptually, the "tentative region" mechanism has no connection with
the command loop, any more than scrolling, fontification or indentation
has.

[ .... ]

> So:

> three new variables
> one new display feature (clone of an existing feature)
> a couple unconditional variable copies in the command loop
> a few new functions
> unconditionally delete the transient region in some C code
> modify some core functions like yank and replace-string
> fix obscure commands that work similarly to yank or replace-string on-demand
> lots and lots of code that doesn't have to be modified at all
> a very simple "state machine" model of the behavior
> a behavior that highly agrees with "all those other GUIs"

and how about a name for this new editor?  ;-)

> For extra special featurefulness, you could build on that
> by adding a "transient region ring" -- a circular buffer that
> remembers the last N transient regions whenever some
> command nillifies the transient region at the top level.
> A "remembered" transient region is a pair of marks:
> the transient-mark and a marker at what was then the
> point.

Something like this is utterly required.

> N should probably be small but the idea is that recent
> transient regions are cached so that if the region is
> accidentally cleared by some command then a user
> can likely restore it, easily.

YES!!!

> So, in terms of "pronouns" again -- "addressing modes" for users -- the
> mark stack gives you a set of pronouns for recursing while the
> transient region ring gives you augmented short-term memory about "fat
> cursors".

> I'm really surprised, as I've been led to think about these features by
> the recent discussion, just exactly how complementary "GUI-style
> shift-select" and Emacs' user model and command interaction loop turn
> out to be.   They fit together like hand and glove, if only Emacs will
> actually implement it that way.

Hmm...  Do they really?  One good reason I've stayed with Emacs is that
it doesn't impose this (to me) ghastlily inefficient and nerve-wrackingly
fragile shift-select mechanism on me.  Please make sure that ALL the
features you're talking about are optional, even if they do become the
default.

> I'm one of those users who is both an Emacs power user *and* make
> pretty heavy use of GUI-style apps.   I constantly have the low-level
> frustration of how selection, cut, paste, etc. work differently between
> these environments:  often typing or mousing into some app as if it
> were Emacs or into Emacs as if it were some other app.   So, I feel
> pretty viscerally the pain that work on shift selection is trying to
> address.  

> I'm pretty convinced the little state machine model I've been
> developing here is a really good model for the desired functionality.
> So, I'm skeptical that all the hair of trying to use
> transient-mark-mode for this stuff is a good idea.

I rather think that these things are more flavour of the decade rather
than permanent; in ten or twenty years time, shift-select may well have
gone the way of autoexec.bat.  So lets not embed it too firmly inside
Emacs, below the level of individual commands.

> -t

-- 
Alan Mackenzie (Nuremberg, Germany).





^ permalink raw reply	[flat|nested] 167+ messages in thread

* Re: Shift selection using interactive spec
  2008-03-16 21:00                             ` Thomas Lord
  2008-03-16 20:45                               ` Thien-Thi Nguyen
  2008-03-16 23:04                               ` Lennart Borgman (gmail)
@ 2008-03-16 23:35                               ` Stephen J. Turnbull
  2008-03-17  0:55                                 ` Thomas Lord
  2008-03-17  2:21                               ` Stefan Monnier
  3 siblings, 1 reply; 167+ messages in thread
From: Stephen J. Turnbull @ 2008-03-16 23:35 UTC (permalink / raw)
  To: Thomas Lord
  Cc: Chong Yidong, Dan Nicolaescu, Stefan Monnier, Kim F. Storm,
	emacs-devel

Thomas Lord writes:

 > You keep misunderstanding me.  I understand (enough) about how
 > transient mark mode models "activation".  What I'm saying in
 > response to that design, not in ignorance of it, is that
 > "activation" is the wrong model and that the three-variable model
 > is the model users are thinking of.  And the three variable model
 > seems to come out cleanly in code.  And the three variable model
 > extends and complements the traditional Emacs mark stack.

I'm not going to discuss the ins and outs of this, but I'd like to
point out that zmacs-regions and shifted-motion-keys-select-region
have been t by default in Windows builds of XEmacs for about ten
years, and I've *never* heard a Windows user complain about the region
doing the wrong thing.  ("zmacs-regions" is the Lucid equivalent of
t-m-m, and s-m-k-s-r is what it says.)

XEmacs implements the "active flag for top of mark stack" model.

If you want to do something subtler, Tom, I think a sample
implementation really needs to be provided and exercised thoroughly,
because the t-m-m model just plain ain't broke in best current
practice.




^ permalink raw reply	[flat|nested] 167+ messages in thread

* Re: Shift selection using interactive spec
  2008-03-17  0:46                                 ` Thomas Lord
@ 2008-03-17  0:21                                   ` Lennart Borgman (gmail)
  2008-03-17  1:16                                     ` Thomas Lord
  0 siblings, 1 reply; 167+ messages in thread
From: Lennart Borgman (gmail) @ 2008-03-17  0:21 UTC (permalink / raw)
  To: Thomas Lord
  Cc: Chong Yidong, Dan Nicolaescu, emacs-devel, Stefan Monnier,
	Kim F. Storm

Thomas Lord wrote:
> Lennart Borgman (gmail) wrote:
>>
>> I translate it to something like this in elisp code:
>>
>> ;;;; pre-pre
>> ...
> 
> There's no need for a pre-pre hook or
> for a test of whether the last sequence
> was shifted.   You're using the "three variables"
> correctly, but there are simpler ways to use them
> to achieve the same effect.

Yes, I use pre-pre just as a name for a position in the command loop. It 
could be a hook, but need of course not be implemented that way.

Sorry for writing the code a bit un-lispish ;-)

>> ;;;; post-post
>> ;;
>> (if buffer-was-changed
>>     (setq preserved-tm nil)
>>   (unless preserved-tm
>>     (when user-wants-it
>>       (setq preserved-tm maybe-preserved-tm))))
>> (setq tm preserved-tm)
>>
>>
> 
> 
> No.   "buffer-was-changed" has nothing to do with
> anything here.  Sorry.

Thanks for the clarification.

> Nor is there any need
> for a "post-post" hook.   The command loop can
> simply, unconditionally, copy tentative-mark to
> maybe-preserved-... before running a command,
> and preserved-... to tentative-mark before returning
> control to the user -- two unconditional "setq"s in
> the loop.   None of this "buffer-was-changed" stuff.
> Those distinctions happen elsewhere in this scheme,
> and on a different basis.
> 
> -t
> 
> 
> 
> -t
> 
> 




^ permalink raw reply	[flat|nested] 167+ messages in thread

* Re: Shift selection using interactive spec
  2008-03-16 23:04                               ` Lennart Borgman (gmail)
  2008-03-16 23:17                                 ` Lennart Borgman (gmail)
@ 2008-03-17  0:46                                 ` Thomas Lord
  2008-03-17  0:21                                   ` Lennart Borgman (gmail)
  1 sibling, 1 reply; 167+ messages in thread
From: Thomas Lord @ 2008-03-17  0:46 UTC (permalink / raw)
  To: Lennart Borgman (gmail)
  Cc: Chong Yidong, Dan Nicolaescu, emacs-devel, Stefan Monnier,
	Kim F. Storm

Lennart Borgman (gmail) wrote:
>
> I translate it to something like this in elisp code:
>
> ;;;; pre-pre
> ...

There's no need for a pre-pre hook or
for a test of whether the last sequence
was shifted.   You're using the "three variables"
correctly, but there are simpler ways to use them
to achieve the same effect.



> ;;;; post-post
> ;;
> (if buffer-was-changed
>     (setq preserved-tm nil)
>   (unless preserved-tm
>     (when user-wants-it
>       (setq preserved-tm maybe-preserved-tm))))
> (setq tm preserved-tm)
>
>


No.   "buffer-was-changed" has nothing to do with
anything here.  Sorry.   Nor is there any need
for a "post-post" hook.   The command loop can
simply, unconditionally, copy tentative-mark to
maybe-preserved-... before running a command,
and preserved-... to tentative-mark before returning
control to the user -- two unconditional "setq"s in
the loop.   None of this "buffer-was-changed" stuff.
Those distinctions happen elsewhere in this scheme,
and on a different basis.

-t



-t





^ permalink raw reply	[flat|nested] 167+ messages in thread

* Re: Shift selection using interactive spec
  2008-03-16 14:40                     ` Shift selection using interactive spec Chong Yidong
  2008-03-16 15:04                       ` Lennart Borgman (gmail)
@ 2008-03-17  0:54                       ` Chong Yidong
  2008-03-17  2:40                         ` Stefan Monnier
  1 sibling, 1 reply; 167+ messages in thread
From: Chong Yidong @ 2008-03-17  0:54 UTC (permalink / raw)
  To: Kim F. Storm; +Cc: Dan Nicolaescu, Stefan Monnier, emacs-devel

> If transient mark mode is on, activating shift selection should
> resets and activates the mark, and the first unshifted command
> should then return transient mark mode to its original non-nil
> value.  Thus shift selection "stacks" on top of transient mark mode.
> I am not certain if there is a clean way to do this.  Maybe allow
> transient-mark-mode to take the form of a list?  Any suggestions?

Here is one stab at the problem: allow transient-mark-mode to be a
cons cell.  If the car of the cell is `only' or `identity', the effect
is the same as setting transient-mark-mode itself to `only' or
`identity'.  The only difference is that at the end of the command
transient-mark-mode is set to the cdr of the cons cell, instead of
nil.

This lets us record the `old' value of transient-mark-mode when
setting the transient mark temporarily.

Here is a proposed patch, including the shift-selection behavior,
handled using a new elisp function handle-shift-selection.

*** trunk/src/callint.c.~1.161.~	2008-03-16 20:41:57.000000000 -0400
--- trunk/src/callint.c	2008-03-16 20:40:38.000000000 -0400
***************
*** 51,56 ****
--- 51,58 ----
     even if mark_active is 0.  */
  Lisp_Object Vmark_even_if_inactive;
  
+ Lisp_Object Qhandle_shift_selection;
+ 
  Lisp_Object Vmouse_leave_buffer_hook, Qmouse_leave_buffer_hook;
  
  Lisp_Object Qlist, Qlet, Qletx, Qsave_excursion, Qprogn, Qif, Qwhen;
***************
*** 121,128 ****
  If the string begins with `@', then Emacs searches the key sequence
   which invoked the command for its first mouse click (or any other
   event which specifies a window), and selects that window before
!  reading any arguments.  You may use both `@' and `*'; they are
!  processed in the order that they appear.
  usage: (interactive ARGS)  */)
       (args)
       Lisp_Object args;
--- 123,134 ----
  If the string begins with `@', then Emacs searches the key sequence
   which invoked the command for its first mouse click (or any other
   event which specifies a window), and selects that window before
!  reading any arguments.
! If the string begins with `^' and `this-command-keys-shift-translated'
!  is non-nil, Emacs calls `handle-shift-selection' before reading
!  any arguments.
! You may use `@', `*', and `^' together; they are processed in the
!  order that they appear.
  usage: (interactive ARGS)  */)
       (args)
       Lisp_Object args;
***************
*** 447,452 ****
--- 453,463 ----
  	    }
  	  string++;
  	}
+       else if (*string == '^')
+ 	{
+ 	  call0 (Qhandle_shift_selection);
+ 	  string++;
+ 	}
        else break;
      }
  
***************
*** 936,941 ****
--- 947,955 ----
    Qmouse_leave_buffer_hook = intern ("mouse-leave-buffer-hook");
    staticpro (&Qmouse_leave_buffer_hook);
  
+   Qhandle_shift_selection = intern ("handle-shift-selection");
+   staticpro (&Qhandle_shift_selection);
+ 
    DEFVAR_KBOARD ("prefix-arg", Vprefix_arg,
  		 doc: /* The value of the prefix argument for the next editing command.
  It may be a number, or the symbol `-' for just a minus sign as arg,
*** trunk/src/keyboard.c.~1.948.~	2008-03-16 07:24:34.000000000 -0400
--- trunk/src/keyboard.c	2008-03-16 20:31:24.000000000 -0400
***************
*** 132,137 ****
--- 132,140 ----
  Lisp_Object raw_keybuf;
  int raw_keybuf_count;
  
+ /* Non-nil if the present key sequence was obtained by shift translation.  */
+ Lisp_Object Vthis_command_keys_shift_translated;
+ 
  #define GROW_RAW_KEYBUF							\
   if (raw_keybuf_count == XVECTOR (raw_keybuf)->size)			\
     raw_keybuf = larger_vector (raw_keybuf, raw_keybuf_count * 2, Qnil)  \
***************
*** 1648,1653 ****
--- 1651,1657 ----
        Vthis_command = Qnil;
        real_this_command = Qnil;
        Vthis_original_command = Qnil;
+       Vthis_command_keys_shift_translated = Qnil;
  
        /* Read next key sequence; i gets its length.  */
        i = read_key_sequence (keybuf, sizeof keybuf / sizeof keybuf[0],
***************
*** 1754,1760 ****
  	}
        else
  	{
! 	  if (NILP (current_kboard->Vprefix_arg))
  	    {
  	      /* In case we jump to directly_done.  */
  	      Vcurrent_prefix_arg = current_kboard->Vprefix_arg;
--- 1758,1765 ----
  	}
        else
  	{
! 	  if (NILP (current_kboard->Vprefix_arg)
! 	      && NILP (Vthis_command_keys_shift_translated))
  	    {
  	      /* In case we jump to directly_done.  */
  	      Vcurrent_prefix_arg = current_kboard->Vprefix_arg;
***************
*** 1801,1807 ****
  		    direct_output_forward_char (1);
  		  goto directly_done;
  		}
! 	      else if (EQ (Vthis_command, Qbackward_char) && PT > BEGV)
  		{
                    struct Lisp_Char_Table *dp
  		    = window_display_table (XWINDOW (selected_window));
--- 1806,1813 ----
  		    direct_output_forward_char (1);
  		  goto directly_done;
  		}
! 	      else if (EQ (Vthis_command, Qbackward_char) && PT > BEGV
! 		       && NILP (Vthis_command_keys_shift_translated))
  		{
                    struct Lisp_Char_Table *dp
  		    = window_display_table (XWINDOW (selected_window));
***************
*** 1964,1972 ****
  	  /* Setting transient-mark-mode to `only' is a way of
  	     turning it on for just one command.  */
  
! 	  if (EQ (Vtransient_mark_mode, Qidentity))
  	    Vtransient_mark_mode = Qnil;
! 	  if (EQ (Vtransient_mark_mode, Qonly))
  	    Vtransient_mark_mode = Qidentity;
  
  	  if (!NILP (Vdeactivate_mark) && !NILP (Vtransient_mark_mode))
--- 1970,1989 ----
  	  /* Setting transient-mark-mode to `only' is a way of
  	     turning it on for just one command.  */
  
! 	  if (CONSP (Vtransient_mark_mode))
! 	    {
! 	      if (EQ (XCAR (Vtransient_mark_mode), Qidentity))
! 		{
! 		  Vtransient_mark_mode = XCDR (Vtransient_mark_mode);
! 		  if (! NILP (Vtransient_mark_mode))
! 		    Vdeactivate_mark = Qt;
! 		}
! 	      else if (EQ (XCAR (Vtransient_mark_mode), Qonly))
! 		XSETCAR (Vtransient_mark_mode, Qidentity);
! 	    }
! 	  else if (EQ (Vtransient_mark_mode, Qidentity))
  	    Vtransient_mark_mode = Qnil;
! 	  else if (EQ (Vtransient_mark_mode, Qonly))
  	    Vtransient_mark_mode = Qidentity;
  
  	  if (!NILP (Vdeactivate_mark) && !NILP (Vtransient_mark_mode))
***************
*** 9194,9199 ****
--- 9211,9221 ----
    /* Likewise, for key_translation_map and input-decode-map.  */
    volatile keyremap keytran, indec;
  
+   /* This is non-zero if we are trying to map a key by changing an
+      upper-case letter to lower-case or a shifted function key to an
+      unshifted one.  */
+   volatile int shift_translated = 0;
+ 
    /* If we receive a `switch-frame' or `select-window' event in the middle of
       a key sequence, we put it off for later.
       While we're reading, we keep the event here.  */
***************
*** 10113,10118 ****
--- 10135,10141 ----
  	  keybuf[t - 1] = new_key;
  	  mock_input = max (t, mock_input);
  
+ 	  shift_translated = 1;
  	  goto replay_sequence;
  	}
        /* If KEY is not defined in any of the keymaps,
***************
*** 10154,10159 ****
--- 10177,10183 ----
  	      fkey.start = fkey.end = 0;
  	      keytran.start = keytran.end = 0;
  
+ 	      shift_translated = 1;
  	      goto replay_sequence;
  	    }
  	}
***************
*** 10171,10177 ****
    if ((dont_downcase_last || first_binding >= nmaps)
        && t > 0
        && t - 1 == original_uppercase_position)
!     keybuf[t - 1] = original_uppercase;
  
    /* Occasionally we fabricate events, perhaps by expanding something
       according to function-key-map, or by adding a prefix symbol to a
--- 10195,10207 ----
    if ((dont_downcase_last || first_binding >= nmaps)
        && t > 0
        && t - 1 == original_uppercase_position)
!     {
!       keybuf[t - 1] = original_uppercase;
!       shift_translated = 0;
!     }
! 
!   if (shift_translated)
!     Vthis_command_keys_shift_translated = Qt;
  
    /* Occasionally we fabricate events, perhaps by expanding something
       according to function-key-map, or by adding a prefix symbol to a
***************
*** 10190,10197 ****
        add_command_key (keybuf[t]);
      }
  
- 
- 
    UNGCPRO;
    return t;
  }
--- 10220,10225 ----
***************
*** 12083,12088 ****
--- 12111,12124 ----
  will be in `last-command' during the following command.  */);
    Vthis_command = Qnil;
  
+   DEFVAR_LISP ("this-command-keys-shift-translated",
+ 	       &Vthis_command_keys_shift_translated,
+ 	       doc: /* Non-nil if the key sequence invoking this command was shift-translated.
+ Shift translation occurs when there is no binding for the entered key
+ sequence, and a binding is found by changing an upper-case letter to
+ lower-case or a shifted function key to an unshifted one.  */);
+   Vthis_command_keys_shift_translated = Qnil;
+ 
    DEFVAR_LISP ("this-original-command", &Vthis_original_command,
  	       doc: /* The command bound to the current key sequence before remapping.
  It equals `this-command' if the original command was not remapped through
*** trunk/lisp/simple.el.~1.906.~	2008-03-16 20:41:07.000000000 -0400
--- trunk/lisp/simple.el	2008-03-16 20:40:38.000000000 -0400
***************
*** 3572,3577 ****
--- 3572,3590 ----
        (goto-char omark)
        nil)))
  
+ (defun handle-shift-selection ()
+   (when this-command-keys-shift-translated
+     (temporary-region-highlight)))
+ 
+ (defun temporary-region-highlight ()
+   (if (consp transient-mark-mode)
+       (progn (unless (eq (car transient-mark-mode) 'identity)
+ 	       (push-mark nil nil t))
+ 	     (setcar transient-mark-mode 'only))
+     (unless (eq transient-mark-mode 'identity)
+       (push-mark nil nil t))
+     (setq transient-mark-mode (cons 'only transient-mark-mode))))
+ 
  (define-minor-mode transient-mark-mode
    "Toggle Transient Mark mode.
  With arg, turn Transient Mark mode on if arg is positive, off otherwise.
***************
*** 3654,3660 ****
  If you are thinking of using this in a Lisp program, consider
  using `forward-line' instead.  It is usually easier to use
  and more reliable (no dependence on goal column, etc.)."
!   (interactive "p\np")
    (or arg (setq arg 1))
    (if (and next-line-add-newlines (= arg 1))
        (if (save-excursion (end-of-line) (eobp))
--- 3667,3673 ----
  If you are thinking of using this in a Lisp program, consider
  using `forward-line' instead.  It is usually easier to use
  and more reliable (no dependence on goal column, etc.)."
!   (interactive "^p\np")
    (or arg (setq arg 1))
    (if (and next-line-add-newlines (= arg 1))
        (if (save-excursion (end-of-line) (eobp))
***************
*** 3687,3693 ****
  If you are thinking of using this in a Lisp program, consider using
  `forward-line' with a negative argument instead.  It is usually easier
  to use and more reliable (no dependence on goal column, etc.)."
!   (interactive "p\np")
    (or arg (setq arg 1))
    (if (interactive-p)
        (condition-case nil
--- 3700,3706 ----
  If you are thinking of using this in a Lisp program, consider using
  `forward-line' with a negative argument instead.  It is usually easier
  to use and more reliable (no dependence on goal column, etc.)."
!   (interactive "^p\np")
    (or arg (setq arg 1))
    (if (interactive-p)
        (condition-case nil
***************
*** 4310,4316 ****
  (defun backward-word (&optional arg)
    "Move backward until encountering the beginning of a word.
  With argument, do this that many times."
!   (interactive "p")
    (forward-word (- (or arg 1))))
  
  (defun mark-word (&optional arg allow-extend)
--- 4323,4329 ----
  (defun backward-word (&optional arg)
    "Move backward until encountering the beginning of a word.
  With argument, do this that many times."
!   (interactive "^p")
    (forward-word (- (or arg 1))))
  
  (defun mark-word (&optional arg allow-extend)
*** trunk/src/cmds.c.~1.102.~	2008-02-01 11:00:53.000000000 -0500
--- trunk/src/cmds.c	2008-03-16 20:37:21.000000000 -0400
***************
*** 56,62 ****
    return make_number (PT + XINT (n));
  }
  
! DEFUN ("forward-char", Fforward_char, Sforward_char, 0, 1, "p",
         doc: /* Move point right N characters (left if N is negative).
  On reaching end of buffer, stop and signal error.  */)
       (n)
--- 56,62 ----
    return make_number (PT + XINT (n));
  }
  
! DEFUN ("forward-char", Fforward_char, Sforward_char, 0, 1, "^p",
         doc: /* Move point right N characters (left if N is negative).
  On reaching end of buffer, stop and signal error.  */)
       (n)
***************
*** 92,98 ****
    return Qnil;
  }
  
! DEFUN ("backward-char", Fbackward_char, Sbackward_char, 0, 1, "p",
         doc: /* Move point left N characters (right if N is negative).
  On attempt to pass beginning or end of buffer, stop and signal error.  */)
       (n)
--- 92,98 ----
    return Qnil;
  }
  
! DEFUN ("backward-char", Fbackward_char, Sbackward_char, 0, 1, "^p",
         doc: /* Move point left N characters (right if N is negative).
  On attempt to pass beginning or end of buffer, stop and signal error.  */)
       (n)
*** trunk/src/syntax.c.~1.210.~	2008-02-12 16:29:33.000000000 -0500
--- trunk/src/syntax.c	2008-03-16 20:37:33.000000000 -0400
***************
*** 1324,1330 ****
    return from;
  }
  
! DEFUN ("forward-word", Fforward_word, Sforward_word, 0, 1, "p",
         doc: /* Move point forward ARG words (backward if ARG is negative).
  Normally returns t.
  If an edge of the buffer or a field boundary is reached, point is left there
--- 1324,1330 ----
    return from;
  }
  
! DEFUN ("forward-word", Fforward_word, Sforward_word, 0, 1, "^p",
         doc: /* Move point forward ARG words (backward if ARG is negative).
  Normally returns t.
  If an edge of the buffer or a field boundary is reached, point is left there
*** trunk/lisp/textmodes/paragraphs.el.~1.91.~	2008-03-14 13:42:15.000000000 -0400
--- trunk/lisp/textmodes/paragraphs.el	2008-03-16 20:39:03.000000000 -0400
***************
*** 217,223 ****
  A paragraph end is the beginning of a line which is not part of the paragraph
  to which the end of the previous line belongs, or the end of the buffer.
  Returns the count of paragraphs left to move."
!   (interactive "p")
    (or arg (setq arg 1))
    (let* ((opoint (point))
  	 (fill-prefix-regexp
--- 217,223 ----
  A paragraph end is the beginning of a line which is not part of the paragraph
  to which the end of the previous line belongs, or the end of the buffer.
  Returns the count of paragraphs left to move."
!   (interactive "^p")
    (or arg (setq arg 1))
    (let* ((opoint (point))
  	 (fill-prefix-regexp
***************
*** 361,367 ****
  blank line.
  
  See `forward-paragraph' for more information."
!   (interactive "p")
    (or arg (setq arg 1))
    (forward-paragraph (- arg)))
  
--- 361,367 ----
  blank line.
  
  See `forward-paragraph' for more information."
!   (interactive "^p")
    (or arg (setq arg 1))
    (forward-paragraph (- arg)))
  
***************
*** 445,451 ****
  
  The variable `sentence-end' is a regular expression that matches ends of
  sentences.  Also, every paragraph boundary terminates sentences as well."
!   (interactive "p")
    (or arg (setq arg 1))
    (let ((opoint (point))
          (sentence-end (sentence-end)))
--- 445,451 ----
  
  The variable `sentence-end' is a regular expression that matches ends of
  sentences.  Also, every paragraph boundary terminates sentences as well."
!   (interactive "^p")
    (or arg (setq arg 1))
    (let ((opoint (point))
          (sentence-end (sentence-end)))
***************
*** 477,483 ****
  (defun backward-sentence (&optional arg)
    "Move backward to start of sentence.  With arg, do it arg times.
  See `forward-sentence' for more information."
!   (interactive "p")
    (or arg (setq arg 1))
    (forward-sentence (- arg)))
  
--- 477,483 ----
  (defun backward-sentence (&optional arg)
    "Move backward to start of sentence.  With arg, do it arg times.
  See `forward-sentence' for more information."
!   (interactive "^p")
    (or arg (setq arg 1))
    (forward-sentence (- arg)))
  




^ permalink raw reply	[flat|nested] 167+ messages in thread

* Re: Shift selection using interactive spec
  2008-03-16 23:35                               ` Stephen J. Turnbull
@ 2008-03-17  0:55                                 ` Thomas Lord
  2008-03-17  2:23                                   ` Stefan Monnier
  0 siblings, 1 reply; 167+ messages in thread
From: Thomas Lord @ 2008-03-17  0:55 UTC (permalink / raw)
  To: Stephen J. Turnbull
  Cc: Chong Yidong, Dan Nicolaescu, Stefan Monnier, Kim F. Storm,
	emacs-devel

Stephen J. Turnbull wrote:
> I've *never* heard a Windows user complain about the region
> doing the wrong thing. 
>   

> XEmacs implements the "active flag for top of mark stack" model.
>   


I think you are are prematurely self-congratulatory.  

If XEmacs were really successful in this area, especially
given the Lucid ancestry, then Eclipse would not exist
in its present form.  (Rather, it would be "eclipse.el".)





> If you want to do something subtler, Tom, I think a sample
> implementation really needs to be provided and exercised thoroughly,
> because the t-m-m model just plain ain't broke in best current
> practice.
>
>   

I have a stack of 2 big things on my "put up or shut up" debt list
at just this moment and I'm not adding this thing as a third.

But this thing... how shift-select should work... it's a much simpler
problem than the other two and I think I can fix it just by describing
the solution.   Yeah, I'm crazy optimistic that way, sometimes, in some
contexts.

-t






^ permalink raw reply	[flat|nested] 167+ messages in thread

* Re: Shift selection using interactive spec
  2008-03-17  0:21                                   ` Lennart Borgman (gmail)
@ 2008-03-17  1:16                                     ` Thomas Lord
  0 siblings, 0 replies; 167+ messages in thread
From: Thomas Lord @ 2008-03-17  1:16 UTC (permalink / raw)
  To: Lennart Borgman (gmail)
  Cc: Chong Yidong, Dan Nicolaescu, Stefan Monnier, Kim F. Storm,
	emacs-devel

Lennart Borgman (gmail) wrote:
>
> Thanks for the clarification.
>
>

The "three variables" idea is, at  root, very simple -- but
it's subtle and unfamiliar.    So I don't mind a few excuses
to make up "yet another" way to highlight details of how it
works.     Too many is too many and I'm probably floating near
that threshold but, up to that point, a little bit of "repetition by
re-expression" is an efficient way to communicate a subtle idea.
Well, I think so, anyway.  Or at least hope so.

-t







>
>





^ permalink raw reply	[flat|nested] 167+ messages in thread

* Re: Shift selection using interactive spec
  2008-03-16 21:00                             ` Thomas Lord
                                                 ` (2 preceding siblings ...)
  2008-03-16 23:35                               ` Stephen J. Turnbull
@ 2008-03-17  2:21                               ` Stefan Monnier
  2008-03-17  3:47                                 ` what's the point (re shift selection) Thomas Lord
  3 siblings, 1 reply; 167+ messages in thread
From: Stefan Monnier @ 2008-03-17  2:21 UTC (permalink / raw)
  To: Thomas Lord; +Cc: Chong Yidong, Dan Nicolaescu, emacs-devel, Kim F. Storm

> There are two aspects to the answer:  cleanliness and
> semantics.

> Cleanliness: the three variable proposal needs a *tiny bit*
> of new code in the C part of Emacs.   In exchange, it
> doesn't need transitive-mark or delete-mark... elisp code
> at all (because the default behaviors are better).

Most of the transient-mark-mode is C-level as well.  The "only" form of
transient-mark-mode does pretty much what you suggest.
And no: it's not clean.  The mere fact that you have a "value before
command", "value to set at the end of this command", etc... makes it
brittle in the face of non-local exits and, recursive edits and things
like that.

Besides, I want *less* C code, not more.  Especially for a feature which
I only find relevant for UI-compatibility with other applications.
Using C-SPC + movement is at least as convenient.  You may say it's
a bit more VI-ish since it's modal, but honestly, I think Emacs already
uses more than enough modifiers.

> Cleanliness again:  In the three variable system, most
> commands DTRT by default, even if they remain ignorant
> of the three variables.

We already have that with the pre/post-command-hook implementation in
cua-selection-mode.

> This proliferation of categories is the price for using a binary "active"
> flag rather than the three-variable system.    How are those categories

No, it's unrelated.  It's because I want a different behavior.

Don't take me wrong: the current way transient-mark-mode works, i.e. the way
things are spread between the mark itself, mark-active, deactivate-mark, and
transient-mark-mode, is pretty messy but it doesn't have any impact
about where code has to run, only about how to write the code (which
tends to have to look at more than a single variable).

> supposed to compose, anyway?   That is, if I call a "consuming" command
> as a function, does that make my command also "consuming"?

No, these are all meant to be specifically for `interactive' use.
But it simply depends on where the code is put.  The exact same problem
holds for your proposal.

> Better (more consistent, simpler) is:  "when a command is bound to
> a non-shifted key but is invoked via a shifted sequence, we want the
> shift-select region to remain active during that command".
> There's no need to talk about "motion".

But I don't *want* that generality, which is why I want/need the notion
of "movement command".


        Stefan




^ permalink raw reply	[flat|nested] 167+ messages in thread

* Re: Shift selection using interactive spec
  2008-03-17  0:55                                 ` Thomas Lord
@ 2008-03-17  2:23                                   ` Stefan Monnier
  2008-03-17  3:12                                     ` Thomas Lord
  0 siblings, 1 reply; 167+ messages in thread
From: Stefan Monnier @ 2008-03-17  2:23 UTC (permalink / raw)
  To: Thomas Lord
  Cc: Stephen J. Turnbull, Dan Nicolaescu, Chong Yidong, Kim F. Storm,
	emacs-devel

>> I've *never* heard a Windows user complain about the region
>> doing the wrong thing.   

>> XEmacs implements the "active flag for top of mark stack" model.
>> 


> I think you are are prematurely self-congratulatory.  

> If XEmacs were really successful in this area, especially
> given the Lucid ancestry, then Eclipse would not exist
> in its present form.  (Rather, it would be "eclipse.el".)

Please keep such off-topic remarks off this mailing-list.  Thank you,


        Stefan




^ permalink raw reply	[flat|nested] 167+ messages in thread

* Re: Shift selection using interactive spec
  2008-03-17  0:54                       ` Chong Yidong
@ 2008-03-17  2:40                         ` Stefan Monnier
  2008-03-17  3:24                           ` Chong Yidong
  0 siblings, 1 reply; 167+ messages in thread
From: Stefan Monnier @ 2008-03-17  2:40 UTC (permalink / raw)
  To: Chong Yidong; +Cc: Dan Nicolaescu, emacs-devel, Kim F. Storm

> --- 1758,1765 ----
>   	}
>         else
>   	{
> ! 	  if (NILP (current_kboard->Vprefix_arg)
> ! 	      && NILP (Vthis_command_keys_shift_translated))
>   	    {
>   	      /* In case we jump to directly_done.  */
>   	      Vcurrent_prefix_arg = current_kboard->Vprefix_arg;
> ***************
> *** 1801,1807 ****
>   		    direct_output_forward_char (1);
>   		  goto directly_done;
>   		}
> ! 	      else if (EQ (Vthis_command, Qbackward_char) && PT > BEGV)
>   		{
>                     struct Lisp_Char_Table *dp
>   		    = window_display_table (XWINDOW (selected_window));
> --- 1806,1813 ----
>   		    direct_output_forward_char (1);
>   		  goto directly_done;
>   		}
> ! 	      else if (EQ (Vthis_command, Qbackward_char) && PT > BEGV
> ! 		       && NILP (Vthis_command_keys_shift_translated))
>   		{
>                     struct Lisp_Char_Table *dp
>   		    = window_display_table (XWINDOW (selected_window));

Shouldn't we just get rid of those special cases "to speed up the cases
that are plenty fast anyway"?

> ***************
> *** 1964,1972 ****
>   	  /* Setting transient-mark-mode to `only' is a way of
>   	     turning it on for just one command.  */
  
> ! 	  if (EQ (Vtransient_mark_mode, Qidentity))
>   	    Vtransient_mark_mode = Qnil;
> ! 	  if (EQ (Vtransient_mark_mode, Qonly))
>   	    Vtransient_mark_mode = Qidentity;
  
>   	  if (!NILP (Vdeactivate_mark) && !NILP (Vtransient_mark_mode))
> --- 1970,1989 ----
>   	  /* Setting transient-mark-mode to `only' is a way of
>   	     turning it on for just one command.  */
  
> ! 	  if (CONSP (Vtransient_mark_mode))
> ! 	    {
> ! 	      if (EQ (XCAR (Vtransient_mark_mode), Qidentity))
> ! 		{
> ! 		  Vtransient_mark_mode = XCDR (Vtransient_mark_mode);
> ! 		  if (! NILP (Vtransient_mark_mode))
> ! 		    Vdeactivate_mark = Qt;
> ! 		}
> ! 	      else if (EQ (XCAR (Vtransient_mark_mode), Qonly))
> ! 		XSETCAR (Vtransient_mark_mode, Qidentity);
> ! 	    }
> ! 	  else if (EQ (Vtransient_mark_mode, Qidentity))
>   	    Vtransient_mark_mode = Qnil;
> ! 	  else if (EQ (Vtransient_mark_mode, Qonly))
>   	    Vtransient_mark_mode = Qidentity;

It is ugly right now and this makes it worse.  How 'bout just

   if (CONSP (Vtransient_mark_mode))
      Vtransient_mark_mode = XCDR (Vtransient_mark_mode);

and then replace `identity' with (t . nil) and `only' with (t . (t . nil)).
Or something like that?
  
> + (defun handle-shift-selection ()
> +   (when this-command-keys-shift-translated
> +     (temporary-region-highlight)))
> + 
> + (defun temporary-region-highlight ()
> +   (if (consp transient-mark-mode)
> +       (progn (unless (eq (car transient-mark-mode) 'identity)
> + 	       (push-mark nil nil t))
> + 	     (setcar transient-mark-mode 'only))
> +     (unless (eq transient-mark-mode 'identity)
> +       (push-mark nil nil t))
> +     (setq transient-mark-mode (cons 'only transient-mark-mode))))

Any reason to use `only' rather than to explicitly deactivate the mark
in handle-shift-selection when this-command-keys-shift-translated is
(and the region was selected with this-command-keys-shift-translated)?
Apparently that is the approach that is used in pc-selection-mode and in
cua-selection-mode, so it seems to work well enough.  The `only' form of
transient-mark-mode is a bit brittle for my taste (gets broken by
switch-frame events and things like that), so I'd rather only use it if
really necessary.


        Stefan




^ permalink raw reply	[flat|nested] 167+ messages in thread

* Re: Shift selection using interactive spec
  2008-03-17  2:23                                   ` Stefan Monnier
@ 2008-03-17  3:12                                     ` Thomas Lord
  0 siblings, 0 replies; 167+ messages in thread
From: Thomas Lord @ 2008-03-17  3:12 UTC (permalink / raw)
  To: Stefan Monnier
  Cc: Stephen J. Turnbull, Dan Nicolaescu, emacs-devel, Chong Yidong,
	Kim F. Storm

Stefan Monnier wrote:
> Please keep such off-topic remarks off this mailing-list.  Thank you,
>
>   

How are those remarks, about the state of the "product category" of Emacs,
off topic?

This is a quite sincere question and another way to ask it is:

Does Emacs' popularity legitimately figure into the calculations
of how Emacs is developed?   Is "being popular" a goal?  Or is
it antithetical to what Emacs is about?

I can see either answer being reasonable.    If being popular is
one of the goals then I think Stephen and my exchange isn't
too badly off topic.   If being popular isn't one of the goals
then... I guess we are off topic after all but.... well, it'd be nice
to know that that's *really* what you mean.

-t







^ permalink raw reply	[flat|nested] 167+ messages in thread

* Re: Shift selection using interactive spec
  2008-03-17  2:40                         ` Stefan Monnier
@ 2008-03-17  3:24                           ` Chong Yidong
  2008-03-17 13:26                             ` Stefan Monnier
  0 siblings, 1 reply; 167+ messages in thread
From: Chong Yidong @ 2008-03-17  3:24 UTC (permalink / raw)
  To: Stefan Monnier; +Cc: Dan Nicolaescu, emacs-devel, Kim F. Storm

Stefan Monnier <monnier@iro.umontreal.ca> writes:

> Shouldn't we just get rid of those special cases "to speed up the cases
> that are plenty fast anyway"?

Not sure what you mean.

> It is ugly right now and this makes it worse.  How 'bout just
>
>    if (CONSP (Vtransient_mark_mode))
>       Vtransient_mark_mode = XCDR (Vtransient_mark_mode);
>
> and then replace `identity' with (t . nil) and `only' with (t . (t . nil)).
> Or something like that?

I'm assuming we want to preserve backward compatibility re the meaning
of `only' and `identity' for transient-mark-mode.  I'm not sure if
there are external packages using these.  If we decide not to retain
compatibility, we can remain the part of the code that handles the
case where transient-mark-mode is `only' and `identity' rather than
`(only t)' and `(only nil)', etc.

(If we break compability, we also ought to choose more descriptive
symbol names than `identity' and `only'.)

> Any reason to use `only' rather than to explicitly deactivate the mark
> in handle-shift-selection when this-command-keys-shift-translated is
> (and the region was selected with this-command-keys-shift-translated)?
> Apparently that is the approach that is used in pc-selection-mode and in
> cua-selection-mode, so it seems to work well enough.  The `only' form of
> transient-mark-mode is a bit brittle for my taste (gets broken by
> switch-frame events and things like that), so I'd rather only use it if
> really necessary.

If the user runs any other command, it is supposed to deactivate the
mark/unhighlight the region.  Transient mark mode's `only' mechanism
handles this automatically.  Off the top of my head, if we implement a
separate system for shift selection, making it DTRT would require code
changes at exactly the same places where the `only' mechanism is
already in place.  So I don't see a big advantage in implementing a
parallel system.




^ permalink raw reply	[flat|nested] 167+ messages in thread

* what's the point (re shift selection)
  2008-03-17  2:21                               ` Stefan Monnier
@ 2008-03-17  3:47                                 ` Thomas Lord
  0 siblings, 0 replies; 167+ messages in thread
From: Thomas Lord @ 2008-03-17  3:47 UTC (permalink / raw)
  To: Stefan Monnier; +Cc: Chong Yidong, Dan Nicolaescu, emacs-devel, Kim F. Storm

What *is* "the point"?

In emacs, "the point" is the name of a potential
location for the gap.   Insert commands always
happen at the gap.  "the point" is the gap location
of interest.  It's "what we're talking about".   It's
a key element of the dynamic state.

That's all traditional.   That's done.  That's how
Emacs has always worked.

Ok, next new insight: what exactly do we mean by
"potential location for the gap"?

Trivially, the gap can be placed between any two
extant, adjacent characters.  That's again, traditional
Emacs behavior.

But there is a generalization..... specifically: drop
the the qualifier "adjacent" and say, instead:

The point represents the potential gap between
any two characters in the buffer.

So, sometimes the point is not "point-like" -- it
is a "fat cursor".   The point is a potential gap that
spans between two non-adjacent characters.

That is how shift selection behaves in other apps --
as if the point is clearly the name of an arbitrary
potential gap, not merely a potential gap between
two already adjacent characters.

The concept of a "tentative-mark" is to give a
direct expression to the idea of a "fat cursor" -- of
a point that actually spans many characters.

The phase sensitivity -- the "maybe-preserved-..."
and "preserved-..." variables -- that is, indeed, a kind
of "psychological" hack.   Those *are* ad hoc.  They
are hair, as hair goes.   But they are minimal hair. 
They default in all the right ways.  They are easy to
explain and deal with.    They are a feature that exists
at the intersection between "how people think with short
term memory" and "how the emacs command loop works".
They are TRT, imho.

Over and out.   I give up.   Back to work on my VM and,
now, thanks to (friendly, good) provocation by Stefan, also
back to work on Arch 2.0 if I can work up the courage to
squeeze it in.

Have fun.  Let's test this "meritocracy of ideas" concept
the hard way :-)

-t





^ permalink raw reply	[flat|nested] 167+ messages in thread

* Re: Shift selection using interactive spec
  2008-03-17  3:24                           ` Chong Yidong
@ 2008-03-17 13:26                             ` Stefan Monnier
  2008-03-17 16:33                               ` Chong Yidong
  2008-03-18 14:45                               ` Chong Yidong
  0 siblings, 2 replies; 167+ messages in thread
From: Stefan Monnier @ 2008-03-17 13:26 UTC (permalink / raw)
  To: Chong Yidong; +Cc: Dan Nicolaescu, emacs-devel, Kim F. Storm

>> Shouldn't we just get rid of those special cases "to speed up the cases
>> that are plenty fast anyway"?
> Not sure what you mean.

Something like the patch below.

>> It is ugly right now and this makes it worse.  How 'bout just
>> 
>> if (CONSP (Vtransient_mark_mode))
>> Vtransient_mark_mode = XCDR (Vtransient_mark_mode);
>> 
>> and then replace `identity' with (t . nil) and `only' with (t . (t . nil)).
>> Or something like that?

> I'm assuming we want to preserve backward compatibility re the meaning
> of `only' and `identity' for transient-mark-mode.  I'm not sure if
> there are external packages using these.

I don't think this backward compatibility is important: these are fairly
recently introduced values and they're only used in unusual corner cases.

> (If we break compability, we also ought to choose more descriptive
> symbol names than `identity' and `only'.)

Then again, we may want to move these special value to deactivate-mark
or something like that.  I think we should feel free to rework this bit
if the result is cleaner.

>> Any reason to use `only' rather than to explicitly deactivate the mark
>> in handle-shift-selection when this-command-keys-shift-translated is
>> (and the region was selected with this-command-keys-shift-translated)?
>> Apparently that is the approach that is used in pc-selection-mode and in
>> cua-selection-mode, so it seems to work well enough.  The `only' form of
>> transient-mark-mode is a bit brittle for my taste (gets broken by
>> switch-frame events and things like that), so I'd rather only use it if
>> really necessary.

> If the user runs any other command, it is supposed to deactivate the
> mark/unhighlight the region.

Maybe for most commands, but maybe not all.  If all(most) non-shifted
movement commands turn it off explicitly (as I suggested above), and
given that all buffer modifications already turn it off, there isn't
much left and those left may actually be better off *not* turning the
selection off.

I first want to try this, and only if it causes actual problems will
I want to try something else.  The "only" form is too fleeting and tends
to disappear for the tiniest reasons.  I prefer a region that
occasionally stays ON when we don't want it than one where you feel like
it might disappear from under you at any time.


        Stefan


=== modified file 'src/keyboard.c'
--- src/keyboard.c	2008-03-16 18:24:38 +0000
+++ src/keyboard.c	2008-03-17 13:17:46 +0000
@@ -1754,143 +1754,8 @@
 	}
       else
 	{
-	  if (NILP (current_kboard->Vprefix_arg))
-	    {
-	      /* In case we jump to directly_done.  */
-	      Vcurrent_prefix_arg = current_kboard->Vprefix_arg;
-
-	      /* Recognize some common commands in common situations and
-		 do them directly.  */
-	      if (EQ (Vthis_command, Qforward_char) && PT < ZV)
-		{
-                  struct Lisp_Char_Table *dp
-		    = window_display_table (XWINDOW (selected_window));
-		  lose = FETCH_CHAR (PT_BYTE);
-		  SET_PT (PT + 1);
-		  if (! NILP (Vpost_command_hook))
-		    /* Put this before calling adjust_point_for_property
-		       so it will only get called once in any case.  */
-		    goto directly_done;
-		  if (current_buffer == prev_buffer
-		      && last_point_position != PT
-		      && NILP (Vdisable_point_adjustment)
-		      && NILP (Vglobal_disable_point_adjustment))
-		    adjust_point_for_property (last_point_position, 0);
-		  already_adjusted = 1;
-		  if (PT == last_point_position + 1
-		      && (dp
-			  ? (VECTORP (DISP_CHAR_VECTOR (dp, lose))
-			     ? XVECTOR (DISP_CHAR_VECTOR (dp, lose))->size == 1
-			     : (NILP (DISP_CHAR_VECTOR (dp, lose))
-				&& (lose >= 0x20 && lose < 0x7f)))
-			  : (lose >= 0x20 && lose < 0x7f))
-		      /* To extract the case of continuation on
-                         wide-column characters.  */
-		      && ASCII_BYTE_P (lose)
-		      && (XFASTINT (XWINDOW (selected_window)->last_modified)
-			  >= MODIFF)
-		      && (XFASTINT (XWINDOW (selected_window)->last_overlay_modified)
-			  >= OVERLAY_MODIFF)
-		      && (XFASTINT (XWINDOW (selected_window)->last_point)
-			  == PT - 1)
-		      && !windows_or_buffers_changed
-		      && EQ (current_buffer->selective_display, Qnil)
-		      && !detect_input_pending ()
-		      && NILP (XWINDOW (selected_window)->column_number_displayed)
-		      && NILP (Vexecuting_kbd_macro))
-		    direct_output_forward_char (1);
-		  goto directly_done;
-		}
-	      else if (EQ (Vthis_command, Qbackward_char) && PT > BEGV)
-		{
-                  struct Lisp_Char_Table *dp
-		    = window_display_table (XWINDOW (selected_window));
-		  SET_PT (PT - 1);
-		  lose = FETCH_CHAR (PT_BYTE);
-		  if (! NILP (Vpost_command_hook))
-		    goto directly_done;
-		  if (current_buffer == prev_buffer
-		      && last_point_position != PT
-		      && NILP (Vdisable_point_adjustment)
-		      && NILP (Vglobal_disable_point_adjustment))
-		    adjust_point_for_property (last_point_position, 0);
-		  already_adjusted = 1;
-		  if (PT == last_point_position - 1
-		      && (dp
-			  ? (VECTORP (DISP_CHAR_VECTOR (dp, lose))
-			     ? XVECTOR (DISP_CHAR_VECTOR (dp, lose))->size == 1
-			     : (NILP (DISP_CHAR_VECTOR (dp, lose))
-				&& (lose >= 0x20 && lose < 0x7f)))
-			  : (lose >= 0x20 && lose < 0x7f))
-		      && (XFASTINT (XWINDOW (selected_window)->last_modified)
-			  >= MODIFF)
-		      && (XFASTINT (XWINDOW (selected_window)->last_overlay_modified)
-			  >= OVERLAY_MODIFF)
-		      && (XFASTINT (XWINDOW (selected_window)->last_point)
-			  == PT + 1)
-		      && !windows_or_buffers_changed
-		      && EQ (current_buffer->selective_display, Qnil)
-		      && !detect_input_pending ()
-		      && NILP (XWINDOW (selected_window)->column_number_displayed)
-		      && NILP (Vexecuting_kbd_macro))
-		    direct_output_forward_char (-1);
-		  goto directly_done;
-		}
-	      else if (EQ (Vthis_command, Qself_insert_command)
-		       /* Try this optimization only on char keystrokes.  */
-		       && NATNUMP (last_command_char)
-		       && CHAR_VALID_P (XFASTINT (last_command_char), 0))
-		{
-		  unsigned int c
-		    = translate_char (Vtranslation_table_for_input,
-				      XFASTINT (last_command_char));
-		  int value;
-		  if (NILP (Vexecuting_kbd_macro)
-		      && !EQ (minibuf_window, selected_window))
-		    {
-		      if (!nonundocount || nonundocount >= 20)
-			{
-			  Fundo_boundary ();
-			  nonundocount = 0;
-			}
-		      nonundocount++;
-		    }
-
-		  lose = ((XFASTINT (XWINDOW (selected_window)->last_modified)
-			   < MODIFF)
-			  || (XFASTINT (XWINDOW (selected_window)->last_overlay_modified)
-			      < OVERLAY_MODIFF)
-			  || (XFASTINT (XWINDOW (selected_window)->last_point)
-			      != PT)
-			  || MODIFF <= SAVE_MODIFF
-			  || windows_or_buffers_changed
-			  || !EQ (current_buffer->selective_display, Qnil)
-			  || detect_input_pending ()
-			  || !NILP (XWINDOW (selected_window)->column_number_displayed)
-			  || !NILP (Vexecuting_kbd_macro));
-
-		  value = internal_self_insert (c, 0);
-
-		  if (value == 2)
-		    nonundocount = 0;
-
-		  if (! NILP (Vpost_command_hook))
-		    /* Put this before calling adjust_point_for_property
-		       so it will only get called once in any case.  */
-		    goto directly_done;
-
-		  /* VALUE == 1 when AFTER-CHANGE functions are
-		     installed which is the case most of the time
-		     because FONT-LOCK installs one.  */
-		  if (!lose && !value)
-		    direct_output_for_insert (c);
-		  goto directly_done;
-		}
-	    }
-
 	  /* Here for a command that isn't executed directly */
 
-          {
 #ifdef HAVE_X_WINDOWS
             int scount = SPECPDL_INDEX ();
 
@@ -1917,8 +1782,6 @@
             unbind_to (scount, Qnil);
 #endif
           }
-	}
-    directly_done: ;
       current_kboard->Vlast_prefix_arg = Vcurrent_prefix_arg;
 
       /* Note that the value cell will never directly contain nil





^ permalink raw reply	[flat|nested] 167+ messages in thread

* Re: Shift selection using interactive spec
  2008-03-17 13:26                             ` Stefan Monnier
@ 2008-03-17 16:33                               ` Chong Yidong
  2008-03-17 17:21                                 ` Lennart Borgman (gmail)
                                                   ` (2 more replies)
  2008-03-18 14:45                               ` Chong Yidong
  1 sibling, 3 replies; 167+ messages in thread
From: Chong Yidong @ 2008-03-17 16:33 UTC (permalink / raw)
  To: Stefan Monnier; +Cc: Dan Nicolaescu, emacs-devel, Kim F. Storm

Stefan Monnier <monnier@iro.umontreal.ca> writes:

>>> Shouldn't we just get rid of those special cases "to speed up the cases
>>> that are plenty fast anyway"?
>> Not sure what you mean.
>
> Something like the patch below.

The comments in the redisplay code suggest that this optimization is
important.  If the code isn't harming anything, why remove it?  At the
very least, maybe you should ask Gerd what the impact might be.

>> I'm assuming we want to preserve backward compatibility re the meaning
>> of `only' and `identity' for transient-mark-mode.  I'm not sure if
>> there are external packages using these.
>
> I don't think this backward compatibility is important: these are fairly
> recently introduced values and they're only used in unusual corner cases.
>
>> (If we break compability, we also ought to choose more descriptive
>> symbol names than `identity' and `only'.)
>
> Then again, we may want to move these special value to deactivate-mark
> or something like that.  I think we should feel free to rework this bit
> if the result is cleaner.

Nevertheless, regardless of the exact details, shift-selection will
have to end up setting transient-mark-mode to a non-nil value.  This
is because there is simply too large a body of code, both inside the
Emacs distribution and elsewhere, that treats a non-nil value of
transient-mark-mode as "operate on the region instead".

>> If the user runs any other command, it is supposed to deactivate the
>> mark/unhighlight the region.
>
> Maybe for most commands, but maybe not all.  If all(most) non-shifted
> movement commands turn it off explicitly (as I suggested above), and
> given that all buffer modifications already turn it off, there isn't
> much left and those left may actually be better off *not* turning the
> selection off.
>
> I first want to try this, and only if it causes actual problems will
> I want to try something else.  The "only" form is too fleeting and tends
> to disappear for the tiniest reasons.  I prefer a region that
> occasionally stays ON when we don't want it than one where you feel like
> it might disappear from under you at any time.

The way I see it, C-SPC provides a robust region, and Emacs users will
continue using this even after we implement shift-selection; holding
down the shift key is too much of a nuisance.  So we're talking about
how Emacs behaves for new/casual users, who use shift-selection
because they're either unaware of or unused to C-SPC.  It seems to me
that such users would expect the shift-selected region to be fleeting,
since that is the behavior in other editors.  Furthermore,
shift-selection is *inherently* fleeting, since entering any unshifted
motion key deactivates the mark, and motion commands are
psychologically "tinier" (or rather less consequential) than most
commands.

I've been thinking about cases where you might want the shift-selected
region to persist after a command.  The only good example I can find
is M-x eval region, which doesn't deactivate the mark in tmm.  But
even in this case, the advantage either way seems to be marginal.  If
you care enough about keeping the mark active, why not use C-SPC in
the first place?

Now, there is one other example, and that's switching windows.  You
might argue that it's good to preserve a shift-selected region for
this, so that it is still there when you return to the window.  But it
seems to me that the effects of shift-selection and mouse selection
ought to be as close to equivalent as we can make it (*), and
preserving a shift-selected region when switching windows is
counter-intuitive in the mouse selection context.

(*) The rationale is that if we are going to have more than one set of
    rules about how the region behaves, it is better to have two sets
    than three different sets.




^ permalink raw reply	[flat|nested] 167+ messages in thread

* Re: Shift selection using interactive spec
  2008-03-17 16:33                               ` Chong Yidong
@ 2008-03-17 17:21                                 ` Lennart Borgman (gmail)
  2008-03-17 19:11                                 ` Stefan Monnier
  2008-03-17 22:24                                 ` martin rudalics
  2 siblings, 0 replies; 167+ messages in thread
From: Lennart Borgman (gmail) @ 2008-03-17 17:21 UTC (permalink / raw)
  To: Chong Yidong; +Cc: Dan Nicolaescu, Stefan Monnier, Kim F. Storm, emacs-devel

Chong Yidong wrote:
> The way I see it, C-SPC provides a robust region, and Emacs users will
> continue using this even after we implement shift-selection; holding
> down the shift key is too much of a nuisance.  So we're talking about
> how Emacs behaves for new/casual users, who use shift-selection
> because they're either unaware of or unused to C-SPC.  It seems to me
> that such users would expect the shift-selected region to be fleeting,
> since that is the behavior in other editors.  Furthermore,
> shift-selection is *inherently* fleeting, since entering any unshifted
> motion key deactivates the mark, and motion commands are
> psychologically "tinier" (or rather less consequential) than most
> commands.

I think that for those of us who are very used to shift-selection there 
must still be ways to avoid deactivating the mark with certain move 
commands. If for no other reason because keyboard looks quite different. 
  (For example, to type M-> I have to use the shift key. Though 
admittedly I have never used that one ...)

I would rather restrict dectivation to those keys that deactivates 
region in other applications. (Plus C-g etc of course.)

> I've been thinking about cases where you might want the shift-selected
> region to persist after a command.  The only good example I can find
> is M-x eval region, which doesn't deactivate the mark in tmm.  But
> even in this case, the advantage either way seems to be marginal.  If
> you care enough about keeping the mark active, why not use C-SPC in
> the first place?

Replacing things in various ways in a region seems like good candidates.

Maybe there should be a way to say "don't deactivate the mark after next 
command whatever it does"?

> Now, there is one other example, and that's switching windows.  You
> might argue that it's good to preserve a shift-selected region for
> this, so that it is still there when you return to the window.  But it
> seems to me that the effects of shift-selection and mouse selection
> ought to be as close to equivalent as we can make it (*), and
> preserving a shift-selected region when switching windows is
> counter-intuitive in the mouse selection context.

Wouldn't it be troublesome to keep the region when switching windows 
when the new window contains the same buffer with a different 
window-point? (Maybe at least a warning question in such cases?)




^ permalink raw reply	[flat|nested] 167+ messages in thread

* Re: Shift selection using interactive spec
  2008-03-17 16:33                               ` Chong Yidong
  2008-03-17 17:21                                 ` Lennart Borgman (gmail)
@ 2008-03-17 19:11                                 ` Stefan Monnier
  2008-03-17 21:10                                   ` Chong Yidong
  2008-03-20  5:03                                   ` Chong Yidong
  2008-03-17 22:24                                 ` martin rudalics
  2 siblings, 2 replies; 167+ messages in thread
From: Stefan Monnier @ 2008-03-17 19:11 UTC (permalink / raw)
  To: Chong Yidong; +Cc: Dan Nicolaescu, emacs-devel, Kim F. Storm

>>> (If we break compability, we also ought to choose more descriptive
>>> symbol names than `identity' and `only'.)
>> 
>> Then again, we may want to move these special value to deactivate-mark
>> or something like that.  I think we should feel free to rework this bit
>> if the result is cleaner.

> Nevertheless, regardless of the exact details, shift-selection will
> have to end up setting transient-mark-mode to a non-nil value.

Indeed.  I just saw that Miles and Kim were talking about moving the
handling of "only" to deactivate-mark, or something along those lines.

I plead guilty to turning transient-mark-mode into a non-boolean
variable, and would be happy to see it go back to being boolean.

> The way I see it, C-SPC provides a robust region, and Emacs users will
> continue using this even after we implement shift-selection; holding
> down the shift key is too much of a nuisance.  So we're talking about
> how Emacs behaves for new/casual users, who use shift-selection
> because they're either unaware of or unused to C-SPC.  It seems to me
> that such users would expect the shift-selected region to be fleeting,
> since that is the behavior in other editors.  Furthermore,
> shift-selection is *inherently* fleeting, since entering any unshifted
> motion key deactivates the mark, and motion commands are
> psychologically "tinier" (or rather less consequential) than most
> commands.

The way I see it "only-TTM" is a more brittle and less used&tested
implementation than "temporary-TTM", so everything else being equal
I prefer "temporary-TTM".  In this case I'm not convinced the difference
matters, so I prefer "temporary-TTM".

> Now, there is one other example, and that's switching windows.  You
> might argue that it's good to preserve a shift-selected region for
> this, so that it is still there when you return to the window.  But it
> seems to me that the effects of shift-selection and mouse selection
> ought to be as close to equivalent as we can make it (*), and
> preserving a shift-selected region when switching windows is
> counter-intuitive in the mouse selection context.

> (*) The rationale is that if we are going to have more than one set of
>     rules about how the region behaves, it is better to have two sets
>     than three different sets.

That's a valid argument.  So maybe mouse-selection should use
"temporary-TTM" as well (and be deactivated by unshifted movement)?
Then we could get rid of "only-TTM" altogether.


        Stefan




^ permalink raw reply	[flat|nested] 167+ messages in thread

* Re: Shift selection using interactive spec
  2008-03-17 19:11                                 ` Stefan Monnier
@ 2008-03-17 21:10                                   ` Chong Yidong
  2008-03-17 21:44                                     ` Drew Adams
  2008-03-18 11:40                                     ` Kim F. Storm
  2008-03-20  5:03                                   ` Chong Yidong
  1 sibling, 2 replies; 167+ messages in thread
From: Chong Yidong @ 2008-03-17 21:10 UTC (permalink / raw)
  To: Stefan Monnier; +Cc: Dan Nicolaescu, emacs-devel, Kim F. Storm

Stefan Monnier <monnier@iro.umontreal.ca> writes:

>> Nevertheless, regardless of the exact details, shift-selection will
>> have to end up setting transient-mark-mode to a non-nil value.
>
> Indeed.  I just saw that Miles and Kim were talking about moving the
> handling of "only" to deactivate-mark, or something along those lines.
>
> I plead guilty to turning transient-mark-mode into a non-boolean
> variable, and would be happy to see it go back to being boolean.

If we're willing to ignore backward compatibility, I think a good way
to clean this up as follows:

 - make transient-mark-mode a boolean again

 - give mark-active a couple new possible values:

    nil == same as now

    t == mark active but no highlighting

    `highlight' == mark active, highlight the region

    `highlight-until-deactivated' == temporary TMM (like `lambda')

 - change every relevant place in the code (including a couple of
   spots in xdisp.c).  For example,

     (and transient-mark-mode mark-active)

   would become

     (memq mark-active '(highlight highlight-until-deactivated))

WDYT?

> The way I see it "only-TTM" is a more brittle and less used&tested
> implementation than "temporary-TTM", so everything else being equal
> I prefer "temporary-TTM".  In this case I'm not convinced the difference
> matters, so I prefer "temporary-TTM".

I don't feel strongly about this, so OK.  AFAICT, it's simply a matter
of using `lambda' instead of `only', and some extra code in
handle-shift-selection.

> maybe mouse-selection should use "temporary-TTM" as well (and be
> deactivated by unshifted movement)?  Then we could get rid of
> "only-TTM" altogether.

Might be workable, might not.  I'll think about it.




^ permalink raw reply	[flat|nested] 167+ messages in thread

* RE: Shift selection using interactive spec
  2008-03-17 21:10                                   ` Chong Yidong
@ 2008-03-17 21:44                                     ` Drew Adams
  2008-03-18 11:40                                     ` Kim F. Storm
  1 sibling, 0 replies; 167+ messages in thread
From: Drew Adams @ 2008-03-17 21:44 UTC (permalink / raw)
  To: 'Chong Yidong', 'Stefan Monnier'
  Cc: 'Dan Nicolaescu', 'Kim F. Storm', emacs-devel

> If we're willing to ignore backward compatibility, I think
> a good way to clean this up as follows:
>  - make transient-mark-mode a boolean again
>  - give mark-active a couple new possible values:
>     nil == same as now
>     t == mark active but no highlighting
>     `highlight' == mark active, highlight the region
>     `highlight-until-deactivated' == temporary TMM (like `lambda')
>  - change every relevant place in the code (including a couple of
>    spots in xdisp.c).  For example,
>      (and transient-mark-mode mark-active)
>    would become
>      (memq mark-active '(highlight highlight-until-deactivated))

I have not been following all of the stuff in this thread - mea culpa.

What is the reason for breaking backward compatibility and breaking
3rd-party code (e.g. the need to change (and transient-mark-mode
mark-active) -> (memq mark-active '(highlight highlight-until-deactivated))?

Is all of this only about satisfying those who want to let newbies use Shift
to select text in a way that doesn't perturb their habit, or is something
else behind this? If the former, it doesn't seem to me worth requiring code
changes all over the place. It sounds like much ado about nothing (or
little).

If we gain nothing substantial by this, then count me among those who think
it ain't broke now (and if it ain't broke, don't fix it). We have CUA
selection mode, delete selection mode, PC selection mode, and transient mark
mode. I've got nothing against adding yet another selection mode or
combining some existing selection modes, but not at a cost of forcing
changes to existing 3rd-party code.

Please summarize the perceived need and, especially, the costs & benefits of
the proposed changes. Thx.







^ permalink raw reply	[flat|nested] 167+ messages in thread

* Re: Shift selection using interactive spec
  2008-03-17 16:33                               ` Chong Yidong
  2008-03-17 17:21                                 ` Lennart Borgman (gmail)
  2008-03-17 19:11                                 ` Stefan Monnier
@ 2008-03-17 22:24                                 ` martin rudalics
  2008-03-17 22:37                                   ` Lennart Borgman (gmail)
                                                     ` (2 more replies)
  2 siblings, 3 replies; 167+ messages in thread
From: martin rudalics @ 2008-03-17 22:24 UTC (permalink / raw)
  To: Chong Yidong; +Cc: Kim F. Storm, Stefan Monnier, emacs-devel

 > The way I see it, C-SPC provides a robust region, and Emacs users will
 > continue using this even after we implement shift-selection; holding
 > down the shift key is too much of a nuisance.  So we're talking about
 > how Emacs behaves for new/casual users, who use shift-selection
 > because they're either unaware of or unused to C-SPC.  It seems to me
 > that such users would expect the shift-selected region to be fleeting,
 > since that is the behavior in other editors.  Furthermore,
 > shift-selection is *inherently* fleeting, since entering any unshifted
 > motion key deactivates the mark, and motion commands are
 > psychologically "tinier" (or rather less consequential) than most
 > commands.

Currently I do not find a single way to handle the following scenario
reliably: (1) Select some "region" of text, (2) scroll the window the
text appears in such that `window-point' gets relocated, (3) perform an
action on the region selected in step (1).  Everything I tried so far
(transient-mark-mode, mouse-drag-region, delete-selection-mode,
pc-selection-mode, CUA-mode) failed.  Any plans to handle this?





^ permalink raw reply	[flat|nested] 167+ messages in thread

* Re: Shift selection using interactive spec
  2008-03-17 22:24                                 ` martin rudalics
@ 2008-03-17 22:37                                   ` Lennart Borgman (gmail)
  2008-03-18  0:50                                     ` Thomas Lord
  2008-03-18  7:48                                     ` martin rudalics
  2008-03-17 22:53                                   ` Chong Yidong
  2008-03-18  3:12                                   ` Stefan Monnier
  2 siblings, 2 replies; 167+ messages in thread
From: Lennart Borgman (gmail) @ 2008-03-17 22:37 UTC (permalink / raw)
  To: martin rudalics; +Cc: Chong Yidong, emacs-devel, Stefan Monnier, Kim F. Storm

martin rudalics wrote:
>  > The way I see it, C-SPC provides a robust region, and Emacs users will
>  > continue using this even after we implement shift-selection; holding
>  > down the shift key is too much of a nuisance.  So we're talking about
>  > how Emacs behaves for new/casual users, who use shift-selection
>  > because they're either unaware of or unused to C-SPC.  It seems to me
>  > that such users would expect the shift-selected region to be fleeting,
>  > since that is the behavior in other editors.  Furthermore,
>  > shift-selection is *inherently* fleeting, since entering any unshifted
>  > motion key deactivates the mark, and motion commands are
>  > psychologically "tinier" (or rather less consequential) than most
>  > commands.
> 
> Currently I do not find a single way to handle the following scenario
> reliably: (1) Select some "region" of text, (2) scroll the window the
> text appears in such that `window-point' gets relocated, (3) perform an
> action on the region selected in step (1).  Everything I tried so far
> (transient-mark-mode, mouse-drag-region, delete-selection-mode,
> pc-selection-mode, CUA-mode) failed.  Any plans to handle this?

What do you mean with "failed" here? Do you mean that the region is 
changed or that it disappears (or something else) when you have come to 3?

If you use C-space then the region does not disappear - as I guess you know.

BTW, here is a suggestion:
- If the region was not created with C-space (or something equivalent) 
then C-space should not cance the region, but make it behave just as 
C-space was used to create it.

This could mitigate the problem that some commands (like scroll) 
deactivates the mark.




^ permalink raw reply	[flat|nested] 167+ messages in thread

* Re: Shift selection using interactive spec
  2008-03-17 22:24                                 ` martin rudalics
  2008-03-17 22:37                                   ` Lennart Borgman (gmail)
@ 2008-03-17 22:53                                   ` Chong Yidong
  2008-03-18  3:12                                   ` Stefan Monnier
  2 siblings, 0 replies; 167+ messages in thread
From: Chong Yidong @ 2008-03-17 22:53 UTC (permalink / raw)
  To: martin rudalics; +Cc: Kim F. Storm, Stefan Monnier, emacs-devel

martin rudalics <rudalics@gmx.at> writes:

> Currently I do not find a single way to handle the following scenario
> reliably: (1) Select some "region" of text, (2) scroll the window the
> text appears in such that `window-point' gets relocated, (3) perform an
> action on the region selected in step (1).  Everything I tried so far
> (transient-mark-mode, mouse-drag-region, delete-selection-mode,
> pc-selection-mode, CUA-mode) failed.  Any plans to handle this?

There are no plans for this, and I don't see how it could be
accomplished.  (For certain such purposes, you might be able to use
registers to do what you want.)




^ permalink raw reply	[flat|nested] 167+ messages in thread

* Re: Shift selection using interactive spec
  2008-03-17 22:37                                   ` Lennart Borgman (gmail)
@ 2008-03-18  0:50                                     ` Thomas Lord
  2008-03-18  7:48                                       ` martin rudalics
  2008-03-18  7:48                                     ` martin rudalics
  1 sibling, 1 reply; 167+ messages in thread
From: Thomas Lord @ 2008-03-18  0:50 UTC (permalink / raw)
  To: Lennart Borgman (gmail)
  Cc: martin rudalics, Chong Yidong, Kim F. Storm, Stefan Monnier,
	emacs-devel

Lennart Borgman (gmail) wrote:
> What do you mean with "failed" here? 
I believe he asking, essentially, how he can scroll
a window such that the point becomes invisible (is
in some part of the buffer not shown).

E.g., in a browser, double click on a word, selecting
it.   Now scroll so that is out of view.   Type C-c to
copy the selection.   You copied the originally selected word.
In Emacs, when you scroll the point moves if it has
to to stay in the window.


-t





^ permalink raw reply	[flat|nested] 167+ messages in thread

* Re: Shift selection using interactive spec
  2008-03-17 22:24                                 ` martin rudalics
  2008-03-17 22:37                                   ` Lennart Borgman (gmail)
  2008-03-17 22:53                                   ` Chong Yidong
@ 2008-03-18  3:12                                   ` Stefan Monnier
  2008-03-18  7:49                                     ` martin rudalics
  2 siblings, 1 reply; 167+ messages in thread
From: Stefan Monnier @ 2008-03-18  3:12 UTC (permalink / raw)
  To: martin rudalics; +Cc: Chong Yidong, Kim F. Storm, emacs-devel

> Currently I do not find a single way to handle the following scenario
> reliably: (1) Select some "region" of text, (2) scroll the window the
> text appears in such that `window-point' gets relocated, (3) perform an
> action on the region selected in step (1).  Everything I tried so far
> (transient-mark-mode, mouse-drag-region, delete-selection-mode,
> pc-selection-mode, CUA-mode) failed.  Any plans to handle this?

It's due to 2 limitations:
1 - one of the region's ends is point.
2 - point is kept visible.

Lifting limitation 1 is probably undesirable.

Lifting limitation 2 basically means being able to scroll point out of
view without relocating window-point.  This might be doable: probably
any non-scroll command would force scrolling back to make point
visible again (which is what happens in other editors that provide this
facility, AFAICT).

It might even be hacked in Elisp at least for a proof of concept, by
detecting when point is moved because of scrolling, then setting
cursor-type to nil, recording the original point, deactivating the mark,
and then in some pre-command-hook reactivate the mark (if it was
activated before) and set point back to its original value (thus causing
the scroll-back).


        Stefan




^ permalink raw reply	[flat|nested] 167+ messages in thread

* Re: Shift selection using interactive spec
  2008-03-17 22:37                                   ` Lennart Borgman (gmail)
  2008-03-18  0:50                                     ` Thomas Lord
@ 2008-03-18  7:48                                     ` martin rudalics
  1 sibling, 0 replies; 167+ messages in thread
From: martin rudalics @ 2008-03-18  7:48 UTC (permalink / raw)
  To: Lennart Borgman (gmail)
  Cc: Chong Yidong, emacs-devel, Stefan Monnier, Kim F. Storm

 > What do you mean with "failed" here? Do you mean that the region is
 > changed or that it disappears (or something else) when you have come to 3?

The highlighted region either changes along with point relocation - this
happens with `transient-mark-mode' and C-SPC (or C-SPC C-SPC if you have
tmm disabled) - or an operation gets applied to a different region than
the highlighted one - this may happen with mouse-selection (and can be
awfully confusing).

 > If you use C-space then the region does not disappear - as I guess you
 > know.

But it changes in some arbitrary fashion when `point' gets relocated
during scrolling.

 > BTW, here is a suggestion:
 > - If the region was not created with C-space (or something equivalent)
 > then C-space should not cance the region, but make it behave just as
 > C-space was used to create it.
 >
 > This could mitigate the problem that some commands (like scroll)
 > deactivates the mark.

Why should scrolling deactivate the mark in the first place?





^ permalink raw reply	[flat|nested] 167+ messages in thread

* Re: Shift selection using interactive spec
  2008-03-18  0:50                                     ` Thomas Lord
@ 2008-03-18  7:48                                       ` martin rudalics
  2008-03-18 17:46                                         ` Thomas Lord
  0 siblings, 1 reply; 167+ messages in thread
From: martin rudalics @ 2008-03-18  7:48 UTC (permalink / raw)
  To: Thomas Lord
  Cc: Chong Yidong, Kim F. Storm, Lennart Borgman (gmail),
	Stefan Monnier, emacs-devel

 > E.g., in a browser, double click on a word, selecting
 > it.   Now scroll so that is out of view.   Type C-c to
 > copy the selection.   You copied the originally selected word.
 > In Emacs, when you scroll the point moves if it has
 > to to stay in the window.

Here no program (editor, browser, mua, file-manager, viewer, packer) but
Emacs deactivates or mutilates highlighting of a region while scrolling.
People used to that behavior will simply stop using Emacs as one person
on bug-gun-emacs probably did last year.





^ permalink raw reply	[flat|nested] 167+ messages in thread

* Re: Shift selection using interactive spec
  2008-03-18  3:12                                   ` Stefan Monnier
@ 2008-03-18  7:49                                     ` martin rudalics
  2008-03-18 16:36                                       ` Stefan Monnier
  0 siblings, 1 reply; 167+ messages in thread
From: martin rudalics @ 2008-03-18  7:49 UTC (permalink / raw)
  To: Stefan Monnier; +Cc: Chong Yidong, Kim F. Storm, emacs-devel

 > It might even be hacked in Elisp at least for a proof of concept, by
 > detecting when point is moved because of scrolling, then setting
 > cursor-type to nil, recording the original point, deactivating the mark,
 > and then in some pre-command-hook reactivate the mark (if it was
 > activated before) and set point back to its original value (thus causing
 > the scroll-back).

That's what I tried with

http://lists.gnu.org/archive/html/emacs-devel/2008-02/msg01892.html






^ permalink raw reply	[flat|nested] 167+ messages in thread

* Re: Shift selection using interactive spec
  2008-03-17 21:10                                   ` Chong Yidong
  2008-03-17 21:44                                     ` Drew Adams
@ 2008-03-18 11:40                                     ` Kim F. Storm
  2008-03-18 14:16                                       ` Chong Yidong
  2008-03-18 16:24                                       ` Stefan Monnier
  1 sibling, 2 replies; 167+ messages in thread
From: Kim F. Storm @ 2008-03-18 11:40 UTC (permalink / raw)
  To: Chong Yidong; +Cc: Dan Nicolaescu, Stefan Monnier, emacs-devel

Chong Yidong <cyd@stupidchicken.com> writes:

> Stefan Monnier <monnier@iro.umontreal.ca> writes:
>
>>> Nevertheless, regardless of the exact details, shift-selection will
>>> have to end up setting transient-mark-mode to a non-nil value.
>>
>> Indeed.  I just saw that Miles and Kim were talking about moving the
>> handling of "only" to deactivate-mark, or something along those lines.
>>
>> I plead guilty to turning transient-mark-mode into a non-boolean
>> variable, and would be happy to see it go back to being boolean.
>
> If we're willing to ignore backward compatibility, 


The t-m-m 'only stuff was added in Emacs 23.x, so it's ok to
undo that particular change and replace it by something else.

More radical changes that would break code which works with 22.x
is IMO not an option.

So IMO the proposal below is simply too radical a change re. backwards
compatibility.

>                                                    I think a good way
> to clean this up as follows:
>
>  - make transient-mark-mode a boolean again

It's wasn't a boolean in 22.x either (it may be 'lambda too).

>  - give mark-active a couple new possible values:

This is simply non-manageable, breaking way too much code.


I don't understand why there's such a big fuzz over this.

Based on my experience with CUA mode, and Miles' ideas, it seems
sufficient to use t-m-m "only" mode for the case where t-m-m is off
(the default), and simply leaving t-m-m on for the case where t-m-m is
on (set by user) should do what we want.

This makes it a question of finding the right condition for keeping or
deactivating the mark at the end of a given command...  which is the
question in all cases anyway.

-- 
Kim F. Storm <storm@cua.dk> http://www.cua.dk





^ permalink raw reply	[flat|nested] 167+ messages in thread

* Re: Shift selection using interactive spec
  2008-03-18 11:40                                     ` Kim F. Storm
@ 2008-03-18 14:16                                       ` Chong Yidong
  2008-03-18 15:07                                         ` Kim F. Storm
  2008-03-18 16:24                                       ` Stefan Monnier
  1 sibling, 1 reply; 167+ messages in thread
From: Chong Yidong @ 2008-03-18 14:16 UTC (permalink / raw)
  To: Kim F. Storm; +Cc: Dan Nicolaescu, Stefan Monnier, emacs-devel

storm@cua.dk (Kim F. Storm) writes:

> The t-m-m 'only stuff was added in Emacs 23.x, so it's ok to
> undo that particular change and replace it by something else.
>
> More radical changes that would break code which works with 22.x
> is IMO not an option.
>
> So IMO the proposal below is simply too radical a change re. backwards
> compatibility.

Actually, the `only' stuff is in Emacs 22 also; it's used by mouse
selection.




^ permalink raw reply	[flat|nested] 167+ messages in thread

* Re: Shift selection using interactive spec
  2008-03-17 13:26                             ` Stefan Monnier
  2008-03-17 16:33                               ` Chong Yidong
@ 2008-03-18 14:45                               ` Chong Yidong
  2008-03-18 16:39                                 ` Stefan Monnier
  2008-03-18 17:45                                 ` Thomas Lord
  1 sibling, 2 replies; 167+ messages in thread
From: Chong Yidong @ 2008-03-18 14:45 UTC (permalink / raw)
  To: Stefan Monnier; +Cc: Dan Nicolaescu, emacs-devel, Kim F. Storm

Stefan Monnier <monnier@iro.umontreal.ca> writes:

>> If the user runs any other command, it is supposed to deactivate the
>> mark/unhighlight the region.
>
> Maybe for most commands, but maybe not all.  If all(most) non-shifted
> movement commands turn it off explicitly (as I suggested above), and
> given that all buffer modifications already turn it off, there isn't
> much left and those left may actually be better off *not* turning the
> selection off.
>
> I first want to try this, and only if it causes actual problems will
> I want to try something else.  The "only" form is too fleeting and tends
> to disappear for the tiniest reasons.  I prefer a region that
> occasionally stays ON when we don't want it than one where you feel like
> it might disappear from under you at any time.

After playing around with an implementation of this, I feel that it is
very problematic.

The trouble with using handle-shift-selection to explicitly
unhighlight the region is that every single motion command needs to
call handle-shift-selection, by adding the ^ interactive spec.  For
every motion comman (or command that moves point in addition to
something else), there will be a bug: the shift-selected region won't
be highlighted.  This therefore breaks backward compatibility with all
external packages that define their own motion commands.

I think it's better to stick to the implementation in my last patch,
and change those commands for which we don't want to deactivate
transient mark `only' mode.  It's just a matter of making them set
`identity' back to `only'.




^ permalink raw reply	[flat|nested] 167+ messages in thread

* Re: Shift selection using interactive spec
  2008-03-18 14:16                                       ` Chong Yidong
@ 2008-03-18 15:07                                         ` Kim F. Storm
  0 siblings, 0 replies; 167+ messages in thread
From: Kim F. Storm @ 2008-03-18 15:07 UTC (permalink / raw)
  To: Chong Yidong; +Cc: Dan Nicolaescu, Stefan Monnier, emacs-devel

Chong Yidong <cyd@stupidchicken.com> writes:

> storm@cua.dk (Kim F. Storm) writes:
>
>> The t-m-m 'only stuff was added in Emacs 23.x, so it's ok to
>> undo that particular change and replace it by something else.
>>
>> More radical changes that would break code which works with 22.x
>> is IMO not an option.
>>
>> So IMO the proposal below is simply too radical a change re. backwards
>> compatibility.
>
> Actually, the `only' stuff is in Emacs 22 also; it's used by mouse
> selection.

You are right - I stand corrected.

Still it's so cryptic that I doubt anyone else has actually used that
interface, so I still think we can change that specific feature if we
really need to...

-- 
Kim F. Storm <storm@cua.dk> http://www.cua.dk





^ permalink raw reply	[flat|nested] 167+ messages in thread

* Re: Shift selection using interactive spec
  2008-03-18 11:40                                     ` Kim F. Storm
  2008-03-18 14:16                                       ` Chong Yidong
@ 2008-03-18 16:24                                       ` Stefan Monnier
  2008-03-18 17:54                                         ` Drew Adams
  1 sibling, 1 reply; 167+ messages in thread
From: Stefan Monnier @ 2008-03-18 16:24 UTC (permalink / raw)
  To: Kim F. Storm; +Cc: Chong Yidong, Dan Nicolaescu, emacs-devel

>>>> Nevertheless, regardless of the exact details, shift-selection will
>>>> have to end up setting transient-mark-mode to a non-nil value.
>>> 
>>> Indeed.  I just saw that Miles and Kim were talking about moving the
>>> handling of "only" to deactivate-mark, or something along those lines.
>>> 
>>> I plead guilty to turning transient-mark-mode into a non-boolean
>>> variable, and would be happy to see it go back to being boolean.
>> 
>> If we're willing to ignore backward compatibility, 

> The t-m-m 'only stuff was added in Emacs 23.x, so it's ok to
> undo that particular change and replace it by something else.

Indeed.

> More radical changes that would break code which works with 22.x
> is IMO not an option.

Agreed.

> So IMO the proposal below is simply too radical a change re. backwards
> compatibility.

Agreed.

>> I think a good way
>> to clean this up as follows:
>> - make transient-mark-mode a boolean again
> It's wasn't a boolean in 22.x either (it may be 'lambda too).

I don't think it's a problem: I doubt (m)any external packages have
treated it any different than boolean.

The problem is that code like (and mark-active transient-mark-mode)
should still work, because that is used at many places.


        Stefan




^ permalink raw reply	[flat|nested] 167+ messages in thread

* Re: Shift selection using interactive spec
  2008-03-18  7:49                                     ` martin rudalics
@ 2008-03-18 16:36                                       ` Stefan Monnier
  2008-03-18 16:44                                         ` Lennart Borgman (gmail)
  0 siblings, 1 reply; 167+ messages in thread
From: Stefan Monnier @ 2008-03-18 16:36 UTC (permalink / raw)
  To: martin rudalics; +Cc: Chong Yidong, Kim F. Storm, emacs-devel

>> It might even be hacked in Elisp at least for a proof of concept, by
>> detecting when point is moved because of scrolling, then setting
>> cursor-type to nil, recording the original point, deactivating the mark,
>> and then in some pre-command-hook reactivate the mark (if it was
>> activated before) and set point back to its original value (thus causing
>> the scroll-back).

> That's what I tried with

> http://lists.gnu.org/archive/html/emacs-devel/2008-02/msg01892.html

Oh, yes, now I remember it.  Thanks.  That's neat.

BTW, when some things don't properly run pre/post-command-hook, I think
it should generally be treated as a bug (even if the fix is not easy).
E.g. the mouse-drag problem.

If you have any ideas of changes we may want to make so as to make such
a package easier to write, please submit them.


        Stefan




^ permalink raw reply	[flat|nested] 167+ messages in thread

* Re: Shift selection using interactive spec
  2008-03-18 14:45                               ` Chong Yidong
@ 2008-03-18 16:39                                 ` Stefan Monnier
  2008-03-18 18:28                                   ` Chong Yidong
  2008-03-18 17:45                                 ` Thomas Lord
  1 sibling, 1 reply; 167+ messages in thread
From: Stefan Monnier @ 2008-03-18 16:39 UTC (permalink / raw)
  To: Chong Yidong; +Cc: Dan Nicolaescu, emacs-devel, Kim F. Storm

> After playing around with an implementation of this, I feel that it is
> very problematic.

> The trouble with using handle-shift-selection to explicitly
> unhighlight the region is that every single motion command needs to
> call handle-shift-selection, by adding the ^ interactive spec.  For
> every motion comman (or command that moves point in addition to
> something else), there will be a bug: the shift-selected region won't
> be highlighted.  This therefore breaks backward compatibility with all
> external packages that define their own motion commands.

I do not understand what you mean.  Could you give a sample case?


        Stefan




^ permalink raw reply	[flat|nested] 167+ messages in thread

* Re: Shift selection using interactive spec
  2008-03-18 16:36                                       ` Stefan Monnier
@ 2008-03-18 16:44                                         ` Lennart Borgman (gmail)
  0 siblings, 0 replies; 167+ messages in thread
From: Lennart Borgman (gmail) @ 2008-03-18 16:44 UTC (permalink / raw)
  To: Stefan Monnier; +Cc: martin rudalics, Chong Yidong, emacs-devel, Kim F. Storm

Stefan Monnier wrote:
>>> It might even be hacked in Elisp at least for a proof of concept, by
>>> detecting when point is moved because of scrolling, then setting
>>> cursor-type to nil, recording the original point, deactivating the mark,
>>> and then in some pre-command-hook reactivate the mark (if it was
>>> activated before) and set point back to its original value (thus causing
>>> the scroll-back).
> 
>> That's what I tried with
> 
>> http://lists.gnu.org/archive/html/emacs-devel/2008-02/msg01892.html
> 
> Oh, yes, now I remember it.  Thanks.  That's neat.
> 
> BTW, when some things don't properly run pre/post-command-hook, I think
> it should generally be treated as a bug (even if the fix is not easy).
> E.g. the mouse-drag problem.
> 
> If you have any ideas of changes we may want to make so as to make such
> a package easier to write, please submit them.


Is not the order of the functions in pre/post important?




^ permalink raw reply	[flat|nested] 167+ messages in thread

* Re: Shift selection using interactive spec
  2008-03-18 17:46                                         ` Thomas Lord
@ 2008-03-18 17:36                                           ` Lennart Borgman (gmail)
  2008-03-18 19:07                                             ` Thomas Lord
  0 siblings, 1 reply; 167+ messages in thread
From: Lennart Borgman (gmail) @ 2008-03-18 17:36 UTC (permalink / raw)
  To: Thomas Lord
  Cc: martin rudalics, Chong Yidong, Kim F. Storm, Stefan Monnier,
	emacs-devel

Thomas Lord wrote:
> martin rudalics wrote:
>> Here no program (editor, browser, mua, file-manager, viewer, packer) but
>> Emacs deactivates or mutilates highlighting of a region while scrolling.
>> People used to that behavior will simply stop using Emacs as one person
>> on bug-gun-emacs probably did last year.
> 
> A related one is what happens when you have two
> windows on a single buffer.   The selections in each
> of the two windows interfere with each other because
> Emacs is trying to use the mark stack for this rather
> than adding support for a fat cursor.


Is this similar to the analogy below?

   window-point / point
   window-mark  / mark




^ permalink raw reply	[flat|nested] 167+ messages in thread

* Re: Shift selection using interactive spec
  2008-03-18 14:45                               ` Chong Yidong
  2008-03-18 16:39                                 ` Stefan Monnier
@ 2008-03-18 17:45                                 ` Thomas Lord
  1 sibling, 0 replies; 167+ messages in thread
From: Thomas Lord @ 2008-03-18 17:45 UTC (permalink / raw)
  To: Chong Yidong; +Cc: Dan Nicolaescu, Stefan Monnier, Kim F. Storm, emacs-devel

Chong Yidong wrote:
> After playing around with an implementation of this, I feel that it is
> very problematic.
>   


Have you looked at the other recent messages about
scrolling the selection outside of the visible region?

There's a related problem, too.   Not many GUIs
give you Emacs' ability to display the same "buffer"
in two windows *but* it is the case that the selections
in two windows are always independent of one another.

Yet in Emacs, because the buffer-local mark stack is
used instead of a window-local tentative mark, all
windows on the same buffer share one end point
of the selection in common.   I can't see any user benefit
to that restriction at all.   I think it is a symptom of
a design mistake in the first place.    (The mark stack
is a fine and powerful thing.   It just isn't suitable as
a tentative mark.)

That suggests a simple model where a window-local
tentative-mark, if not nil, makes the cursor fat.   In
turn, that leaves the question of how to arrange that most
commands turn it off by default yet commands can
treat it specially.  I don't know of any simpler way to
do that than with the two variables that relate to command
phases:  maybe-preserved-tentative-mark so that commands
know what tentative mark the user last saw.   preserved-tentative-mark
so that commands can assert what tentative mark the user should
next see.

The concept is probably useful in low-level elisp, too. 
Less need to write code like:

    (let ((start (point)))
      (forward-word)
      (delete-region start (point))
      (insert "bar"))

if there's an available short-hand, something like:

    (with-tentative-mark (point)
      (forward-word)
      (insert "bar"))

Programs can usefully "shift select" on their own,
behind the user's back, just as a handy way to express
the common pattern of having to operate on some region
that is being measured out on-the-fly.


-t





^ permalink raw reply	[flat|nested] 167+ messages in thread

* Re: Shift selection using interactive spec
  2008-03-18  7:48                                       ` martin rudalics
@ 2008-03-18 17:46                                         ` Thomas Lord
  2008-03-18 17:36                                           ` Lennart Borgman (gmail)
  0 siblings, 1 reply; 167+ messages in thread
From: Thomas Lord @ 2008-03-18 17:46 UTC (permalink / raw)
  To: martin rudalics
  Cc: Chong Yidong, Kim F. Storm, Lennart Borgman (gmail),
	Stefan Monnier, emacs-devel

martin rudalics wrote:
> Here no program (editor, browser, mua, file-manager, viewer, packer) but
> Emacs deactivates or mutilates highlighting of a region while scrolling.
> People used to that behavior will simply stop using Emacs as one person
> on bug-gun-emacs probably did last year.

A related one is what happens when you have two
windows on a single buffer.   The selections in each
of the two windows interfere with each other because
Emacs is trying to use the mark stack for this rather
than adding support for a fat cursor.

-t





^ permalink raw reply	[flat|nested] 167+ messages in thread

* RE: Shift selection using interactive spec
  2008-03-18 16:24                                       ` Stefan Monnier
@ 2008-03-18 17:54                                         ` Drew Adams
  0 siblings, 0 replies; 167+ messages in thread
From: Drew Adams @ 2008-03-18 17:54 UTC (permalink / raw)
  To: 'Stefan Monnier', 'Kim F. Storm'
  Cc: 'Chong Yidong', 'Dan Nicolaescu', emacs-devel

> The problem is that code like (and mark-active transient-mark-mode)
> should still work, because that is used at many places.

Yes, including by external libraries and perhaps user init files. 

Anything that forces code changes having to do with activating or
deactivating the mark is a bother. Code such as (deactivate-mark), (setq
deactivate-mark nil), push-mark with non-nil 3rd arg, tests of mark-active,
or setting or binding mark-active.





^ permalink raw reply	[flat|nested] 167+ messages in thread

* Re: Shift selection using interactive spec
  2008-03-18 16:39                                 ` Stefan Monnier
@ 2008-03-18 18:28                                   ` Chong Yidong
  2008-03-18 21:42                                     ` Stefan Monnier
  0 siblings, 1 reply; 167+ messages in thread
From: Chong Yidong @ 2008-03-18 18:28 UTC (permalink / raw)
  To: Stefan Monnier; +Cc: Dan Nicolaescu, emacs-devel, Kim F. Storm

Stefan Monnier <monnier@IRO.UMontreal.CA> writes:

>> After playing around with an implementation of this, I feel that it is
>> very problematic.
>
>> The trouble with using handle-shift-selection to explicitly
>> unhighlight the region is that every single motion command needs to
>> call handle-shift-selection, by adding the ^ interactive spec.  For
>> every motion comman (or command that moves point in addition to
>> something else), there will be a bug: the shift-selected region won't
>> be highlighted.  This therefore breaks backward compatibility with all
>> external packages that define their own motion commands.
>
> I do not understand what you mean.  Could you give a sample case?

Suppose we have an external package that defines the motion commands
forward-section and backward-section, which move point forward and
backward by mode-specific amount.  (It might, for example, be rebound
to M-right or M-left.)

In shift selection mode, the first unshifted motion command must
deactivate the mark.  This is the expected behavior.

Now suppose we make the motion commands responsible for deactivating
the mark; for example, by adding an interactive spec code that calls a
function `handle-shift-selection' that checks if the calling key
sequence was shifted, and deactivates the mark if it was not.  If we
start to define a shift-selected region using a shifted forward-char
command, and follow this with an unshifted forward-section command,
the region won't get deactivated.  Instead, it will extend the region.

To fix this bug, we would have to change the external package.

In contrast, it seems to me that there is only a small number of
commands for which we *don't* want to deactivate a shift selection,
e.g. switching windows.  These commands are mostly built into Emacs,
and could be easily modified to DTRT.  That would fix the perceived
fragility of `only' TMM.




^ permalink raw reply	[flat|nested] 167+ messages in thread

* Re: Shift selection using interactive spec
  2008-03-18 17:36                                           ` Lennart Borgman (gmail)
@ 2008-03-18 19:07                                             ` Thomas Lord
  0 siblings, 0 replies; 167+ messages in thread
From: Thomas Lord @ 2008-03-18 19:07 UTC (permalink / raw)
  To: Lennart Borgman (gmail)
  Cc: martin rudalics, Chong Yidong, Kim F. Storm, Stefan Monnier,
	emacs-devel

Lennart Borgman (gmail) wrote:
> Is this similar to the analogy below?
>
>   window-point / point
>   window-mark  / mark
>


I'm not sure exactly what you're asking but.. yeah, sorta-like
that.

In "traditional emacs" the "point" is always 0-width -- it is
always between two characters (or an end point of a buffer).

In all the GUIs, the "point" is usually 0-width but can be
wider.   Instead between being between two characters,
the point covers a (possibly empty) range of characters.
Rather than a mark-ring and implied region, these programs
use a "fat cursor" as their model of "selection".

So, I'm suggesting a variable "tentative-mark" and,
when not nil and set to a marker, the point is considered
to have non-0 width -- between the location (point) and
that marker.

And then yes:  because we think of the traditional (point)
as window-local, and because tentative-mark is essentially
just an extension to that traditional concept of the point,
then yes, tentative-mark should also have a window-local
binding. 

-t





^ permalink raw reply	[flat|nested] 167+ messages in thread

* Re: Shift selection using interactive spec
  2008-03-18 18:28                                   ` Chong Yidong
@ 2008-03-18 21:42                                     ` Stefan Monnier
  2008-03-18 22:30                                       ` Kim F. Storm
  0 siblings, 1 reply; 167+ messages in thread
From: Stefan Monnier @ 2008-03-18 21:42 UTC (permalink / raw)
  To: Chong Yidong; +Cc: Dan Nicolaescu, emacs-devel, Kim F. Storm

> Suppose we have an external package that defines the motion commands
> forward-section and backward-section, which move point forward and
> backward by mode-specific amount.  (It might, for example, be rebound
> to M-right or M-left.)

> In shift selection mode, the first unshifted motion command must
> deactivate the mark.  This is the expected behavior.

> Now suppose we make the motion commands responsible for deactivating
> the mark; for example, by adding an interactive spec code that calls a
> function `handle-shift-selection' that checks if the calling key
> sequence was shifted, and deactivates the mark if it was not.  If we
> start to define a shift-selected region using a shifted forward-char
> command, and follow this with an unshifted forward-section command,
> the region won't get deactivated.  Instead, it will extend the region.

Oh, that.  It's a pretty minor bug in my opinion.
And those commands have another bug anyway: using shift with them
doesn't select the region.

> To fix this bug, we would have to change the external package.

Yup.  We have to fix it anyway in order for the shift to start the selection.


        Stefan




^ permalink raw reply	[flat|nested] 167+ messages in thread

* Re: Shift selection using interactive spec
  2008-03-18 21:42                                     ` Stefan Monnier
@ 2008-03-18 22:30                                       ` Kim F. Storm
  2008-03-18 22:39                                         ` Lennart Borgman (gmail)
  2008-03-19  4:40                                         ` M Jared Finder
  0 siblings, 2 replies; 167+ messages in thread
From: Kim F. Storm @ 2008-03-18 22:30 UTC (permalink / raw)
  To: Stefan Monnier; +Cc: Chong Yidong, Dan Nicolaescu, emacs-devel

Stefan Monnier <monnier@iro.umontreal.ca> writes:

>> To fix this bug, we would have to change the external package.
>
> Yup.  We have to fix it anyway in order for the shift to start the selection.

That's the beauty of CUA's command property approach - you can fix
it simply by setting a property on the problematic commands in
your own .emacs -- no need to mess inside the source code.

And it is the same for the delete-selection feature -- you can
make external packages delete-selection aware simply by setting
a suitable property.

I.e. if someone complaints that package xxx doesn't work, it is
much easier to tell them to "add these two lines to your .emacs"
rather than "you need to find file xxx.el and edit the interactive
spec of commands xxx-forward and xxx-backward, and then byte-compile
the file".

But I've given up already - it seems that most people making decisions
on this issue don't use shift-select or delete-selection themselves,
and they are not interested in listening to those who use it and have
proven experience in implementing it (and having spent a lot of time
making it work very well).

-- 
Kim F. Storm <storm@cua.dk> http://www.cua.dk





^ permalink raw reply	[flat|nested] 167+ messages in thread

* Re: Shift selection using interactive spec
  2008-03-18 22:30                                       ` Kim F. Storm
@ 2008-03-18 22:39                                         ` Lennart Borgman (gmail)
  2008-03-19  4:40                                         ` M Jared Finder
  1 sibling, 0 replies; 167+ messages in thread
From: Lennart Borgman (gmail) @ 2008-03-18 22:39 UTC (permalink / raw)
  To: Kim F. Storm; +Cc: Chong Yidong, Dan Nicolaescu, Stefan Monnier, emacs-devel

Kim F. Storm wrote:
> Stefan Monnier <monnier@iro.umontreal.ca> writes:
> 
>>> To fix this bug, we would have to change the external package.
>> Yup.  We have to fix it anyway in order for the shift to start the selection.
> 
> That's the beauty of CUA's command property approach - you can fix
> it simply by setting a property on the problematic commands in
> your own .emacs -- no need to mess inside the source code.
> 
> And it is the same for the delete-selection feature -- you can
> make external packages delete-selection aware simply by setting
> a suitable property.
> 
> I.e. if someone complaints that package xxx doesn't work, it is
> much easier to tell them to "add these two lines to your .emacs"
> rather than "you need to find file xxx.el and edit the interactive
> spec of commands xxx-forward and xxx-backward, and then byte-compile
> the file".
> 
> But I've given up already - it seems that most people making decisions
> on this issue don't use shift-select or delete-selection themselves,
> and they are not interested in listening to those who use it and have
> proven experience in implementing it (and having spent a lot of time
> making it work very well).


I have not given up yet, I am just waiting for others to realize that 
this is the way to go. I see some signs of that a change is coming close.

Let us hope that what users will see of this will be very similar to 
what there is in other applications, + some enhancement that are natural 
here, like C-space etc. But please do not let these enhancement stop 
making the other part of the user interface as close to what people are 
used to as possible.





^ permalink raw reply	[flat|nested] 167+ messages in thread

* Re: Shift selection using interactive spec
  2008-03-18 22:30                                       ` Kim F. Storm
  2008-03-18 22:39                                         ` Lennart Borgman (gmail)
@ 2008-03-19  4:40                                         ` M Jared Finder
  2008-03-26  8:09                                           ` David Kastrup
  1 sibling, 1 reply; 167+ messages in thread
From: M Jared Finder @ 2008-03-19  4:40 UTC (permalink / raw)
  To: emacs-devel

Kim F. Storm wrote:
> Stefan Monnier <monnier@iro.umontreal.ca> writes:
> 
>>> To fix this bug, we would have to change the external package.
>> Yup.  We have to fix it anyway in order for the shift to start the selection.
> 
> That's the beauty of CUA's command property approach - you can fix
> it simply by setting a property on the problematic commands in
> your own .emacs -- no need to mess inside the source code.
> 
> And it is the same for the delete-selection feature -- you can
> make external packages delete-selection aware simply by setting
> a suitable property.
> 
> I.e. if someone complaints that package xxx doesn't work, it is
> much easier to tell them to "add these two lines to your .emacs"
> rather than "you need to find file xxx.el and edit the interactive
> spec of commands xxx-forward and xxx-backward, and then byte-compile
> the file".
> 
> But I've given up already - it seems that most people making decisions
> on this issue don't use shift-select or delete-selection themselves,
> and they are not interested in listening to those who use it and have
> proven experience in implementing it (and having spent a lot of time
> making it work very well).
> 

As an honest-to-god USER of Emacs, I want to say I completely agree with 
  Kim, here.  Since I discovered cua-mode, I've had the following code 
in my .emacs:

> (let ((move-fns '(c-forward-conditional c-backward-conditional
>                   c-down-conditional c-up-conditional
>                   c-down-conditional-with-else
>                   c-up-conditional-with-else
>                   c-beginning-of-statement c-end-of-statement)))
>   (require 'cua-base)
>   (dolist (symbol move-fns)
>     (unless (eq 'move (get symbol 'CUA))
>       (display-warning 'emacs (format "Adding CUA property to `%s'." symbol))
>       (setf (get symbol 'CUA) 'move))))

All I have to do to make an existing command support shift-select is add 
its name to the list.  (The move-fns list used to be a lot longer when I 
was using Emacs 21.)

If adding shift-select support to existing functions is much harder than 
adding a function name to a list, and can not be done WITHOUT MODIFYING 
THE PACKAGE, I will consider that a huge loss of functionality.

I can not grok why you want to remove this very elegant way of 
supporting shift-select.  If you guys end up removing it, I'll justkeep 
using the old CUA mode, as it seems much more elegant to me, and more 
importantly, JUST WORKS.

   -- MJF





^ permalink raw reply	[flat|nested] 167+ messages in thread

* Re: Shift selection using interactive spec
  2008-03-17 19:11                                 ` Stefan Monnier
  2008-03-17 21:10                                   ` Chong Yidong
@ 2008-03-20  5:03                                   ` Chong Yidong
  2008-03-23  1:39                                     ` Stefan Monnier
  1 sibling, 1 reply; 167+ messages in thread
From: Chong Yidong @ 2008-03-20  5:03 UTC (permalink / raw)
  To: Stefan Monnier; +Cc: Dan Nicolaescu, emacs-devel, Kim F. Storm

Stefan Monnier <monnier@iro.umontreal.ca> writes:

> The way I see it "only-TTM" is a more brittle and less used&tested
> implementation than "temporary-TTM", so everything else being equal
> I prefer "temporary-TTM".  In this case I'm not convinced the difference
> matters, so I prefer "temporary-TTM".

Here's a patch that changes `only' mode so that it is not explicitly
turned off by the command loop.  It should play nicely with
transient-mark-mode, temporary mark (C-SPC C-SPC), and mouse
selection.  Play around with the shift selection and let me know what
you think.

*** /home/cyd/trunk/src/callint.c.~1.161.~	2008-03-20 00:53:18.000000000 -0400
--- /home/cyd/trunk/src/callint.c	2008-03-16 20:40:38.000000000 -0400
***************
*** 51,56 ****
--- 51,58 ----
     even if mark_active is 0.  */
  Lisp_Object Vmark_even_if_inactive;
  
+ Lisp_Object Qhandle_shift_selection;
+ 
  Lisp_Object Vmouse_leave_buffer_hook, Qmouse_leave_buffer_hook;
  
  Lisp_Object Qlist, Qlet, Qletx, Qsave_excursion, Qprogn, Qif, Qwhen;
***************
*** 121,128 ****
  If the string begins with `@', then Emacs searches the key sequence
   which invoked the command for its first mouse click (or any other
   event which specifies a window), and selects that window before
!  reading any arguments.  You may use both `@' and `*'; they are
!  processed in the order that they appear.
  usage: (interactive ARGS)  */)
       (args)
       Lisp_Object args;
--- 123,134 ----
  If the string begins with `@', then Emacs searches the key sequence
   which invoked the command for its first mouse click (or any other
   event which specifies a window), and selects that window before
!  reading any arguments.
! If the string begins with `^' and `this-command-keys-shift-translated'
!  is non-nil, Emacs calls `handle-shift-selection' before reading
!  any arguments.
! You may use `@', `*', and `^' together; they are processed in the
!  order that they appear.
  usage: (interactive ARGS)  */)
       (args)
       Lisp_Object args;
***************
*** 447,452 ****
--- 453,463 ----
  	    }
  	  string++;
  	}
+       else if (*string == '^')
+ 	{
+ 	  call0 (Qhandle_shift_selection);
+ 	  string++;
+ 	}
        else break;
      }
  
***************
*** 936,941 ****
--- 947,955 ----
    Qmouse_leave_buffer_hook = intern ("mouse-leave-buffer-hook");
    staticpro (&Qmouse_leave_buffer_hook);
  
+   Qhandle_shift_selection = intern ("handle-shift-selection");
+   staticpro (&Qhandle_shift_selection);
+ 
    DEFVAR_KBOARD ("prefix-arg", Vprefix_arg,
  		 doc: /* The value of the prefix argument for the next editing command.
  It may be a number, or the symbol `-' for just a minus sign as arg,
*** /home/cyd/trunk/src/keyboard.c.~1.948.~	2008-03-20 00:53:23.000000000 -0400
--- /home/cyd/trunk/src/keyboard.c	2008-03-20 00:52:22.000000000 -0400
***************
*** 132,137 ****
--- 132,140 ----
  Lisp_Object raw_keybuf;
  int raw_keybuf_count;
  
+ /* Non-nil if the present key sequence was obtained by shift translation.  */
+ Lisp_Object Vthis_command_keys_shift_translated;
+ 
  #define GROW_RAW_KEYBUF							\
   if (raw_keybuf_count == XVECTOR (raw_keybuf)->size)			\
     raw_keybuf = larger_vector (raw_keybuf, raw_keybuf_count * 2, Qnil)  \
***************
*** 659,665 ****
     to support it.  */
  static int cannot_suspend;
  
! extern Lisp_Object Qidentity, Qonly;
  \f
  /* Install the string STR as the beginning of the string of echoing,
     so that it serves as a prompt for the next character.
--- 662,668 ----
     to support it.  */
  static int cannot_suspend;
  
! /* extern Lisp_Object Qidentity, Qonly; */
  \f
  /* Install the string STR as the beginning of the string of echoing,
     so that it serves as a prompt for the next character.
***************
*** 1648,1653 ****
--- 1651,1657 ----
        Vthis_command = Qnil;
        real_this_command = Qnil;
        Vthis_original_command = Qnil;
+       Vthis_command_keys_shift_translated = Qnil;
  
        /* Read next key sequence; i gets its length.  */
        i = read_key_sequence (keybuf, sizeof keybuf / sizeof keybuf[0],
***************
*** 1754,1767 ****
  	}
        else
  	{
! 	  if (NILP (current_kboard->Vprefix_arg))
  	    {
  	      /* In case we jump to directly_done.  */
  	      Vcurrent_prefix_arg = current_kboard->Vprefix_arg;
  
  	      /* Recognize some common commands in common situations and
  		 do them directly.  */
! 	      if (EQ (Vthis_command, Qforward_char) && PT < ZV)
  		{
                    struct Lisp_Char_Table *dp
  		    = window_display_table (XWINDOW (selected_window));
--- 1758,1775 ----
  	}
        else
  	{
! 	  if (NILP (current_kboard->Vprefix_arg)
! 	      && NILP (Vthis_command_keys_shift_translated))
  	    {
  	      /* In case we jump to directly_done.  */
  	      Vcurrent_prefix_arg = current_kboard->Vprefix_arg;
  
  	      /* Recognize some common commands in common situations and
  		 do them directly.  */
! 	      if (EQ (Vthis_command, Qforward_char) && PT < ZV
! 		  && NILP (Vthis_command_keys_shift_translated)
! 		  && (NILP (Vtransient_mark_mode)
! 		      || EQ (Vtransient_mark_mode, Qt)))
  		{
                    struct Lisp_Char_Table *dp
  		    = window_display_table (XWINDOW (selected_window));
***************
*** 1801,1807 ****
  		    direct_output_forward_char (1);
  		  goto directly_done;
  		}
! 	      else if (EQ (Vthis_command, Qbackward_char) && PT > BEGV)
  		{
                    struct Lisp_Char_Table *dp
  		    = window_display_table (XWINDOW (selected_window));
--- 1809,1818 ----
  		    direct_output_forward_char (1);
  		  goto directly_done;
  		}
! 	      else if (EQ (Vthis_command, Qbackward_char) && PT > BEGV
! 		       && NILP (Vthis_command_keys_shift_translated)
! 		       && (NILP (Vtransient_mark_mode)
! 			   || EQ (Vtransient_mark_mode, Qt)))
  		{
                    struct Lisp_Char_Table *dp
  		    = window_display_table (XWINDOW (selected_window));
***************
*** 1961,1974 ****
  
        if (!NILP (current_buffer->mark_active) && !NILP (Vrun_hooks))
  	{
- 	  /* Setting transient-mark-mode to `only' is a way of
- 	     turning it on for just one command.  */
- 
- 	  if (EQ (Vtransient_mark_mode, Qidentity))
- 	    Vtransient_mark_mode = Qnil;
- 	  if (EQ (Vtransient_mark_mode, Qonly))
- 	    Vtransient_mark_mode = Qidentity;
- 
  	  if (!NILP (Vdeactivate_mark) && !NILP (Vtransient_mark_mode))
  	    {
  	      /* We could also call `deactivate'mark'.  */
--- 1972,1977 ----
***************
*** 9194,9199 ****
--- 9197,9207 ----
    /* Likewise, for key_translation_map and input-decode-map.  */
    volatile keyremap keytran, indec;
  
+   /* This is non-zero if we are trying to map a key by changing an
+      upper-case letter to lower-case or a shifted function key to an
+      unshifted one.  */
+   volatile int shift_translated = 0;
+ 
    /* If we receive a `switch-frame' or `select-window' event in the middle of
       a key sequence, we put it off for later.
       While we're reading, we keep the event here.  */
***************
*** 10113,10118 ****
--- 10121,10127 ----
  	  keybuf[t - 1] = new_key;
  	  mock_input = max (t, mock_input);
  
+ 	  shift_translated = 1;
  	  goto replay_sequence;
  	}
        /* If KEY is not defined in any of the keymaps,
***************
*** 10154,10159 ****
--- 10163,10169 ----
  	      fkey.start = fkey.end = 0;
  	      keytran.start = keytran.end = 0;
  
+ 	      shift_translated = 1;
  	      goto replay_sequence;
  	    }
  	}
***************
*** 10171,10177 ****
    if ((dont_downcase_last || first_binding >= nmaps)
        && t > 0
        && t - 1 == original_uppercase_position)
!     keybuf[t - 1] = original_uppercase;
  
    /* Occasionally we fabricate events, perhaps by expanding something
       according to function-key-map, or by adding a prefix symbol to a
--- 10181,10193 ----
    if ((dont_downcase_last || first_binding >= nmaps)
        && t > 0
        && t - 1 == original_uppercase_position)
!     {
!       keybuf[t - 1] = original_uppercase;
!       shift_translated = 0;
!     }
! 
!   if (shift_translated)
!     Vthis_command_keys_shift_translated = Qt;
  
    /* Occasionally we fabricate events, perhaps by expanding something
       according to function-key-map, or by adding a prefix symbol to a
***************
*** 10190,10197 ****
        add_command_key (keybuf[t]);
      }
  
- 
- 
    UNGCPRO;
    return t;
  }
--- 10206,10211 ----
***************
*** 12083,12088 ****
--- 12097,12110 ----
  will be in `last-command' during the following command.  */);
    Vthis_command = Qnil;
  
+   DEFVAR_LISP ("this-command-keys-shift-translated",
+ 	       &Vthis_command_keys_shift_translated,
+ 	       doc: /* Non-nil if the key sequence invoking this command was shift-translated.
+ Shift translation occurs when there is no binding for the entered key
+ sequence, and a binding is found by changing an upper-case letter to
+ lower-case or a shifted function key to an unshifted one.  */);
+   Vthis_command_keys_shift_translated = Qnil;
+ 
    DEFVAR_LISP ("this-original-command", &Vthis_original_command,
  	       doc: /* The command bound to the current key sequence before remapping.
  It equals `this-command' if the original command was not remapped through
*** /home/cyd/trunk/lisp/simple.el.~1.906.~	2008-03-20 00:56:04.000000000 -0400
--- /home/cyd/trunk/lisp/simple.el	2008-03-20 00:45:01.000000000 -0400
***************
*** 3322,3327 ****
--- 3322,3331 ----
    (cond
     ((eq transient-mark-mode 'lambda)
      (setq transient-mark-mode nil))
+    ((eq transient-mark-mode 'only)
+     (setq transient-mark-mode nil))
+    ((eq (car-safe transient-mark-mode) 'only)
+     (setq transient-mark-mode (cdr transient-mark-mode)))
     (transient-mark-mode
      (setq mark-active nil)
      (run-hooks 'deactivate-mark-hook))))
***************
*** 3487,3492 ****
--- 3491,3499 ----
      (if arg
  	(pop-to-mark-command)
        (push-mark-command t)))
+    ((eq (car-safe transient-mark-mode) 'only)
+     (deactivate-mark)
+     (push-mark-command nil))
     ((and set-mark-command-repeat-pop
  	 (eq last-command 'pop-to-mark-command))
      (setq this-command 'pop-to-mark-command)
***************
*** 3572,3577 ****
--- 3579,3602 ----
        (goto-char omark)
        nil)))
  
+ (defun handle-shift-selection ()
+   (if this-command-keys-shift-translated
+       (temporary-region-highlight)
+     (temporary-region-unhighlight)))
+ 
+ (defun temporary-region-highlight ()
+   (unless (eq (car-safe transient-mark-mode) 'only)
+     (setq transient-mark-mode
+ 	  (cons 'only
+ 		(unless (eq transient-mark-mode 'lambda)
+ 		  transient-mark-mode)))
+     (push-mark nil nil t)))
+ 
+ (defun temporary-region-unhighlight ()
+   (when (eq (car-safe transient-mark-mode) 'only)
+     (setq transient-mark-mode (cdr transient-mark-mode))
+     (deactivate-mark)))
+ 
  (define-minor-mode transient-mark-mode
    "Toggle Transient Mark mode.
  With arg, turn Transient Mark mode on if arg is positive, off otherwise.
***************
*** 3654,3660 ****
  If you are thinking of using this in a Lisp program, consider
  using `forward-line' instead.  It is usually easier to use
  and more reliable (no dependence on goal column, etc.)."
!   (interactive "p\np")
    (or arg (setq arg 1))
    (if (and next-line-add-newlines (= arg 1))
        (if (save-excursion (end-of-line) (eobp))
--- 3679,3685 ----
  If you are thinking of using this in a Lisp program, consider
  using `forward-line' instead.  It is usually easier to use
  and more reliable (no dependence on goal column, etc.)."
!   (interactive "^p\np")
    (or arg (setq arg 1))
    (if (and next-line-add-newlines (= arg 1))
        (if (save-excursion (end-of-line) (eobp))
***************
*** 3687,3693 ****
  If you are thinking of using this in a Lisp program, consider using
  `forward-line' with a negative argument instead.  It is usually easier
  to use and more reliable (no dependence on goal column, etc.)."
!   (interactive "p\np")
    (or arg (setq arg 1))
    (if (interactive-p)
        (condition-case nil
--- 3712,3718 ----
  If you are thinking of using this in a Lisp program, consider using
  `forward-line' with a negative argument instead.  It is usually easier
  to use and more reliable (no dependence on goal column, etc.)."
!   (interactive "^p\np")
    (or arg (setq arg 1))
    (if (interactive-p)
        (condition-case nil
***************
*** 4310,4316 ****
  (defun backward-word (&optional arg)
    "Move backward until encountering the beginning of a word.
  With argument, do this that many times."
!   (interactive "p")
    (forward-word (- (or arg 1))))
  
  (defun mark-word (&optional arg allow-extend)
--- 4335,4341 ----
  (defun backward-word (&optional arg)
    "Move backward until encountering the beginning of a word.
  With argument, do this that many times."
!   (interactive "^p")
    (forward-word (- (or arg 1))))
  
  (defun mark-word (&optional arg allow-extend)
*** /home/cyd/trunk/src/cmds.c.~1.102.~	2008-03-20 00:53:19.000000000 -0400
--- /home/cyd/trunk/src/cmds.c	2008-03-16 20:37:21.000000000 -0400
***************
*** 56,62 ****
    return make_number (PT + XINT (n));
  }
  
! DEFUN ("forward-char", Fforward_char, Sforward_char, 0, 1, "p",
         doc: /* Move point right N characters (left if N is negative).
  On reaching end of buffer, stop and signal error.  */)
       (n)
--- 56,62 ----
    return make_number (PT + XINT (n));
  }
  
! DEFUN ("forward-char", Fforward_char, Sforward_char, 0, 1, "^p",
         doc: /* Move point right N characters (left if N is negative).
  On reaching end of buffer, stop and signal error.  */)
       (n)
***************
*** 92,98 ****
    return Qnil;
  }
  
! DEFUN ("backward-char", Fbackward_char, Sbackward_char, 0, 1, "p",
         doc: /* Move point left N characters (right if N is negative).
  On attempt to pass beginning or end of buffer, stop and signal error.  */)
       (n)
--- 92,98 ----
    return Qnil;
  }
  
! DEFUN ("backward-char", Fbackward_char, Sbackward_char, 0, 1, "^p",
         doc: /* Move point left N characters (right if N is negative).
  On attempt to pass beginning or end of buffer, stop and signal error.  */)
       (n)
*** /home/cyd/trunk/src/syntax.c.~1.210.~	2008-03-20 00:53:24.000000000 -0400
--- /home/cyd/trunk/src/syntax.c	2008-03-16 20:37:33.000000000 -0400
***************
*** 1324,1330 ****
    return from;
  }
  
! DEFUN ("forward-word", Fforward_word, Sforward_word, 0, 1, "p",
         doc: /* Move point forward ARG words (backward if ARG is negative).
  Normally returns t.
  If an edge of the buffer or a field boundary is reached, point is left there
--- 1324,1330 ----
    return from;
  }
  
! DEFUN ("forward-word", Fforward_word, Sforward_word, 0, 1, "^p",
         doc: /* Move point forward ARG words (backward if ARG is negative).
  Normally returns t.
  If an edge of the buffer or a field boundary is reached, point is left there
*** /home/cyd/trunk/lisp/textmodes/paragraphs.el.~1.91.~	2008-03-20 00:56:30.000000000 -0400
--- /home/cyd/trunk/lisp/textmodes/paragraphs.el	2008-03-16 20:39:03.000000000 -0400
***************
*** 217,223 ****
  A paragraph end is the beginning of a line which is not part of the paragraph
  to which the end of the previous line belongs, or the end of the buffer.
  Returns the count of paragraphs left to move."
!   (interactive "p")
    (or arg (setq arg 1))
    (let* ((opoint (point))
  	 (fill-prefix-regexp
--- 217,223 ----
  A paragraph end is the beginning of a line which is not part of the paragraph
  to which the end of the previous line belongs, or the end of the buffer.
  Returns the count of paragraphs left to move."
!   (interactive "^p")
    (or arg (setq arg 1))
    (let* ((opoint (point))
  	 (fill-prefix-regexp
***************
*** 361,367 ****
  blank line.
  
  See `forward-paragraph' for more information."
!   (interactive "p")
    (or arg (setq arg 1))
    (forward-paragraph (- arg)))
  
--- 361,367 ----
  blank line.
  
  See `forward-paragraph' for more information."
!   (interactive "^p")
    (or arg (setq arg 1))
    (forward-paragraph (- arg)))
  
***************
*** 445,451 ****
  
  The variable `sentence-end' is a regular expression that matches ends of
  sentences.  Also, every paragraph boundary terminates sentences as well."
!   (interactive "p")
    (or arg (setq arg 1))
    (let ((opoint (point))
          (sentence-end (sentence-end)))
--- 445,451 ----
  
  The variable `sentence-end' is a regular expression that matches ends of
  sentences.  Also, every paragraph boundary terminates sentences as well."
!   (interactive "^p")
    (or arg (setq arg 1))
    (let ((opoint (point))
          (sentence-end (sentence-end)))
***************
*** 477,483 ****
  (defun backward-sentence (&optional arg)
    "Move backward to start of sentence.  With arg, do it arg times.
  See `forward-sentence' for more information."
!   (interactive "p")
    (or arg (setq arg 1))
    (forward-sentence (- arg)))
  
--- 477,483 ----
  (defun backward-sentence (&optional arg)
    "Move backward to start of sentence.  With arg, do it arg times.
  See `forward-sentence' for more information."
!   (interactive "^p")
    (or arg (setq arg 1))
    (forward-sentence (- arg)))
  




^ permalink raw reply	[flat|nested] 167+ messages in thread

* Re: Shift selection using interactive spec
  2008-03-20  5:03                                   ` Chong Yidong
@ 2008-03-23  1:39                                     ` Stefan Monnier
  0 siblings, 0 replies; 167+ messages in thread
From: Stefan Monnier @ 2008-03-23  1:39 UTC (permalink / raw)
  To: Chong Yidong; +Cc: Dan Nicolaescu, emacs-devel, Kim F. Storm

>> The way I see it "only-TTM" is a more brittle and less used&tested
>> implementation than "temporary-TTM", so everything else being equal
>> I prefer "temporary-TTM".  In this case I'm not convinced the difference
>> matters, so I prefer "temporary-TTM".

> Here's a patch that changes `only' mode so that it is not explicitly
> turned off by the command loop.  It should play nicely with
> transient-mark-mode, temporary mark (C-SPC C-SPC), and mouse
> selection.  Play around with the shift selection and let me know what
> you think.

> + Lisp_Object Qhandle_shift_selection;

I'm wondering if its name should hint at "movement-command" rather
than at "shift".

> ! If the string begins with `^' and `this-command-keys-shift-translated'
> !  is non-nil, Emacs calls `handle-shift-selection' before reading
> !  any arguments.
> ! You may use `@', `*', and `^' together; they are processed in the
> !  order that they appear.
>   usage: (interactive ARGS)  */)
>        (args)
>        Lisp_Object args;
> ***************
> *** 447,452 ****
> --- 453,463 ----
>   	    }
>   	  string++;
>   	}
> +       else if (*string == '^')
> + 	{
> + 	  call0 (Qhandle_shift_selection);
> + 	  string++;
> + 	}
>         else break;
>       }

The code is right, the docstring is not.
  
> --- 1758,1775 ----
>   	}
>         else
>   	{
> ! 	  if (NILP (current_kboard->Vprefix_arg)
> ! 	      && NILP (Vthis_command_keys_shift_translated))
>   	    {
>   	      /* In case we jump to directly_done.  */
>   	      Vcurrent_prefix_arg = current_kboard->Vprefix_arg;
  
>   	      /* Recognize some common commands in common situations and
>   		 do them directly.  */
> ! 	      if (EQ (Vthis_command, Qforward_char) && PT < ZV
> ! 		  && NILP (Vthis_command_keys_shift_translated)
> ! 		  && (NILP (Vtransient_mark_mode)
> ! 		      || EQ (Vtransient_mark_mode, Qt)))
>   		{
>                     struct Lisp_Char_Table *dp
>   		    = window_display_table (XWINDOW (selected_window));

[ Side remark, please ignore ]
Yuck!  We really should get rid of this "optimization".

> ***************
> *** 1961,1974 ****
  
>         if (!NILP (current_buffer->mark_active) && !NILP (Vrun_hooks))
>   	{
> - 	  /* Setting transient-mark-mode to `only' is a way of
> - 	     turning it on for just one command.  */
> - 
> - 	  if (EQ (Vtransient_mark_mode, Qidentity))
> - 	    Vtransient_mark_mode = Qnil;
> - 	  if (EQ (Vtransient_mark_mode, Qonly))
> - 	    Vtransient_mark_mode = Qidentity;
> - 
>   	  if (!NILP (Vdeactivate_mark) && !NILP (Vtransient_mark_mode))
>   	    {
>   	      /* We could also call `deactivate'mark'.  */

This is good ;-)

> +   /* This is non-zero if we are trying to map a key by changing an
> +      upper-case letter to lower-case or a shifted function key to an
> +      unshifted one.  */
> +   volatile int shift_translated = 0;

We should either directly set Vthis_command_keys_shift_translated or
explain why we have this two-step approach where we first set
shift-translated and then assign it to Vthis_command_keys_shift_translated.

> ***************
> *** 3322,3327 ****
> --- 3322,3331 ----
>     (cond
>      ((eq transient-mark-mode 'lambda)
>       (setq transient-mark-mode nil))
> +    ((eq transient-mark-mode 'only)
> +     (setq transient-mark-mode nil))
> +    ((eq (car-safe transient-mark-mode) 'only)
> +     (setq transient-mark-mode (cdr transient-mark-mode)))
>      (transient-mark-mode
>       (setq mark-active nil)
>       (run-hooks 'deactivate-mark-hook))))

Yuck.  But I guess that's what we get for removing the corresponding C code.

> ***************
> *** 3487,3492 ****
> --- 3491,3499 ----
>       (if arg
>   	(pop-to-mark-command)
>         (push-mark-command t)))
> +    ((eq (car-safe transient-mark-mode) 'only)
> +     (deactivate-mark)
> +     (push-mark-command nil))
>      ((and set-mark-command-repeat-pop
>   	 (eq last-command 'pop-to-mark-command))
>       (setq this-command 'pop-to-mark-command)

Even more yuck.

Here's an another solution: let's remove all the `only' thingy in
`transient-mark-mode', and instead we introduce a new variable for it,
which says whether the mark is highlighted for just this one command.

So we'd define

   (defun temporary-region-highlight ()
     (unless mark-active-just-once
       (setq mark-active-just-once t)
       (unless transient-mark-mode
         (setq transient-mark-mode 'lambda))
       (push-mark nil nil t)))
   
   (defun temporary-region-unhighlight ()
     (when mark-active-just-once
       (deactivate-mark)))

and of course deactivate-mark needs to set mark-active-just-once to nil.
I don't particularly like the name "mark-active-just-once" either.
   

        Stefan




^ permalink raw reply	[flat|nested] 167+ messages in thread

* Re: Shift selection using interactive spec
  2008-03-19  4:40                                         ` M Jared Finder
@ 2008-03-26  8:09                                           ` David Kastrup
  2008-03-26 10:48                                             ` Juri Linkov
  0 siblings, 1 reply; 167+ messages in thread
From: David Kastrup @ 2008-03-26  8:09 UTC (permalink / raw)
  To: M Jared Finder; +Cc: emacs-devel

M Jared Finder <jared@hpalace.com> writes:

> As an honest-to-god USER of Emacs, I want to say I completely agree
> with Kim, here.  Since I discovered cua-mode, I've had the following
> code in my .emacs:
>
>> (let ((move-fns '(c-forward-conditional c-backward-conditional
>>                   c-down-conditional c-up-conditional
>>                   c-down-conditional-with-else
>>                   c-up-conditional-with-else
>>                   c-beginning-of-statement c-end-of-statement)))
>>   (require 'cua-base)
>>   (dolist (symbol move-fns)
>>     (unless (eq 'move (get symbol 'CUA))
>>       (display-warning 'emacs (format "Adding CUA property to `%s'." symbol))
>>       (setf (get symbol 'CUA) 'move))))
>
> All I have to do to make an existing command support shift-select is
> add its name to the list.  (The move-fns list used to be a lot longer
> when I was using Emacs 21.)

Changing a command's behavior after the thought can be dealt with by
using advice.

Attaching properties is a can of worms that does not work for anonymous
functions.

-- 
David Kastrup, Kriemhildstr. 15, 44793 Bochum




^ permalink raw reply	[flat|nested] 167+ messages in thread

* Re: Shift selection using interactive spec
  2008-03-26  8:09                                           ` David Kastrup
@ 2008-03-26 10:48                                             ` Juri Linkov
  2008-03-26 11:32                                               ` David Kastrup
                                                                 ` (2 more replies)
  0 siblings, 3 replies; 167+ messages in thread
From: Juri Linkov @ 2008-03-26 10:48 UTC (permalink / raw)
  To: David Kastrup; +Cc: M Jared Finder, emacs-devel

>> As an honest-to-god USER of Emacs, I want to say I completely agree
>> with Kim, here.  Since I discovered cua-mode, I've had the following
>> code in my .emacs:
>>
>>> (let ((move-fns '(c-forward-conditional c-backward-conditional
>>>                   c-down-conditional c-up-conditional
>>>                   c-down-conditional-with-else
>>>                   c-up-conditional-with-else
>>>                   c-beginning-of-statement c-end-of-statement)))
>>>   (require 'cua-base)
>>>   (dolist (symbol move-fns)
>>>     (unless (eq 'move (get symbol 'CUA))
>>>       (display-warning 'emacs (format "Adding CUA property to `%s'." symbol))
>>>       (setf (get symbol 'CUA) 'move))))
>>
>> All I have to do to make an existing command support shift-select is
>> add its name to the list.  (The move-fns list used to be a lot longer
>> when I was using Emacs 21.)
>
> Changing a command's behavior after the thought can be dealt with by
> using advice.
>
> Attaching properties is a can of worms that does not work for anonymous
> functions.

But an interactive code does not work when a spec is a Lisp expression
that is not a string.  So just as an interactive Lisp expression should
call a special function `shift-translation-handler' explicitly,
anonymous functions can call the same function as well (though it is
not recommended to use anonymous functions for commands).  So both these
approaches are on a par in this regard.

But using properties seems to be more preferable since there is a need to
implement more related features like delete-selection-mode and inventing
more funny interactive codes doesn't seem like a wise thing to do.

The only problem I see is that properties currently are hard to discover.
I think that just as `C-h f' describe-function displays information
when the function is advised, we should change `C-h v' describe-variable
to display information about attached variable properties as well.

Also as Kim already noted supporting external packages using the
interactive specification code approach would be a nightmare.
So it seems it would be the best to go the way Kim suggested and
just reimplement in C cua-selection-mode with properties that was
proven by time and experience to be the right solution.

-- 
Juri Linkov
http://www.jurta.org/emacs/




^ permalink raw reply	[flat|nested] 167+ messages in thread

* Re: Shift selection using interactive spec
  2008-03-26 10:48                                             ` Juri Linkov
@ 2008-03-26 11:32                                               ` David Kastrup
  2008-03-26 11:39                                                 ` Juri Linkov
  2008-03-26 12:02                                                 ` Lennart Borgman (gmail)
  2008-03-26 11:47                                               ` Lennart Borgman (gmail)
  2008-03-26 22:26                                               ` Richard Stallman
  2 siblings, 2 replies; 167+ messages in thread
From: David Kastrup @ 2008-03-26 11:32 UTC (permalink / raw)
  To: Juri Linkov; +Cc: M Jared Finder, emacs-devel

Juri Linkov <juri@jurta.org> writes:

>> Changing a command's behavior after the thought can be dealt with by
>> using advice.
>>
>> Attaching properties is a can of worms that does not work for anonymous
>> functions.
>
> But an interactive code does not work when a spec is a Lisp expression
> that is not a string.  So just as an interactive Lisp expression should
> call a special function `shift-translation-handler' explicitly,
> anonymous functions can call the same function as well (though it is
> not recommended to use anonymous functions for commands).  So both these
> approaches are on a par in this regard.

Which two approaches are you discussing here?  I don't see that your
argument addresses anything regarding properties.

> But using properties seems to be more preferable since there is a need
> to implement more related features like delete-selection-mode and
> inventing more funny interactive codes doesn't seem like a wise thing
> to do.

Attaching information magically to symbols rather than the actual
function seems much more unwise to me.

> The only problem I see is that properties currently are hard to
> discover.

That is because properties are not part of a function, but part of a
symbol.  And a symbol has all of function cell, value cell, property
list and name.  Those are disparate things.  Storing information about
the function in the property list scatters the information and makes it
impossible to use the actual function rather than the referring symbol.

> I think that just as `C-h f' describe-function displays information
> when the function is advised, we should change `C-h v'
> describe-variable to display information about attached variable
> properties as well.

But we are talking right now about _functions_.  And it is a mistake to
consider the property list part of either variable or function: it has
different scopes and is independent from both variable or function.

> Also as Kim already noted supporting external packages using the
> interactive specification code approach would be a nightmare.  So it
> seems it would be the best to go the way Kim suggested and just
> reimplement in C cua-selection-mode with properties that was proven by
> time and experience to be the right solution.

Uh, "could be made to work" does not imply "right solution".

-- 
David Kastrup




^ permalink raw reply	[flat|nested] 167+ messages in thread

* Re: Shift selection using interactive spec
  2008-03-26 11:32                                               ` David Kastrup
@ 2008-03-26 11:39                                                 ` Juri Linkov
  2008-03-26 12:20                                                   ` David Kastrup
  2008-03-26 12:02                                                 ` Lennart Borgman (gmail)
  1 sibling, 1 reply; 167+ messages in thread
From: Juri Linkov @ 2008-03-26 11:39 UTC (permalink / raw)
  To: David Kastrup; +Cc: M Jared Finder, emacs-devel

>> But an interactive code does not work when a spec is a Lisp expression
>> that is not a string.  So just as an interactive Lisp expression should
>> call a special function `shift-translation-handler' explicitly,
>> anonymous functions can call the same function as well (though it is
>> not recommended to use anonymous functions for commands).  So both these
>> approaches are on a par in this regard.
>
> Which two approaches are you discussing here?

1. interactive codes
2. properties

>> I think that just as `C-h f' describe-function displays information
>> when the function is advised, we should change `C-h v'
>> describe-variable to display information about attached variable
>> properties as well.
>
> But we are talking right now about _functions_.  And it is a mistake to
> consider the property list part of either variable or function: it has
> different scopes and is independent from both variable or function.

Sorry, I meant a symbol's property list for a function, not for a variable.
Property lists are already widely used in Emacs, so there is no reason
to avoid them.  They are integral part of Emacs Lisp, and will cause no more
problems.

-- 
Juri Linkov
http://www.jurta.org/emacs/




^ permalink raw reply	[flat|nested] 167+ messages in thread

* Re: Shift selection using interactive spec
  2008-03-26 10:48                                             ` Juri Linkov
  2008-03-26 11:32                                               ` David Kastrup
@ 2008-03-26 11:47                                               ` Lennart Borgman (gmail)
  2008-03-26 22:26                                                 ` Richard Stallman
  2008-03-26 22:26                                               ` Richard Stallman
  2 siblings, 1 reply; 167+ messages in thread
From: Lennart Borgman (gmail) @ 2008-03-26 11:47 UTC (permalink / raw)
  To: Juri Linkov; +Cc: M Jared Finder, emacs-devel

Juri Linkov wrote:
> But using properties seems to be more preferable since there is a need to
> implement more related features like delete-selection-mode and inventing
> more funny interactive codes doesn't seem like a wise thing to do.
> 
> The only problem I see is that properties currently are hard to discover.
> I think that just as `C-h f' describe-function displays information
> when the function is advised, we should change `C-h v' describe-variable
> to display information about attached variable properties as well.
> 
> Also as Kim already noted supporting external packages using the
> interactive specification code approach would be a nightmare.
> So it seems it would be the best to go the way Kim suggested and
> just reimplement in C cua-selection-mode with properties that was
> proven by time and experience to be the right solution.

Agreed. If description of properties are added it will also be easy to 
add specific description for properties with known use.




^ permalink raw reply	[flat|nested] 167+ messages in thread

* Re: Shift selection using interactive spec
  2008-03-26 11:32                                               ` David Kastrup
  2008-03-26 11:39                                                 ` Juri Linkov
@ 2008-03-26 12:02                                                 ` Lennart Borgman (gmail)
  1 sibling, 0 replies; 167+ messages in thread
From: Lennart Borgman (gmail) @ 2008-03-26 12:02 UTC (permalink / raw)
  To: David Kastrup; +Cc: Juri Linkov, M Jared Finder, emacs-devel

David Kastrup wrote:
> That is because properties are not part of a function, but part of a
> symbol.  And a symbol has all of function cell, value cell, property
> list and name.  Those are disparate things.  Storing information about
> the function in the property list scatters the information and makes it
> impossible to use the actual function rather than the referring symbol.

Could you please tell when this is practically a problem?

> But we are talking right now about _functions_.  And it is a mistake to
> consider the property list part of either variable or function: it has
> different scopes and is independent from both variable or function.

It has independent scope but is normally used for the variable or the 
function.




^ permalink raw reply	[flat|nested] 167+ messages in thread

* Re: Shift selection using interactive spec
  2008-03-26 11:39                                                 ` Juri Linkov
@ 2008-03-26 12:20                                                   ` David Kastrup
  2008-03-26 13:14                                                     ` Johan Bockgård
                                                                       ` (2 more replies)
  0 siblings, 3 replies; 167+ messages in thread
From: David Kastrup @ 2008-03-26 12:20 UTC (permalink / raw)
  To: Juri Linkov; +Cc: M Jared Finder, emacs-devel

Juri Linkov <juri@jurta.org> writes:

>>> But an interactive code does not work when a spec is a Lisp expression
>>> that is not a string.  So just as an interactive Lisp expression should
>>> call a special function `shift-translation-handler' explicitly,
>>> anonymous functions can call the same function as well (though it is
>>> not recommended to use anonymous functions for commands).  So both these
>>> approaches are on a par in this regard.
>>
>> Which two approaches are you discussing here?
>
> 1. interactive codes
> 2. properties
>
>>> I think that just as `C-h f' describe-function displays information
>>> when the function is advised, we should change `C-h v'
>>> describe-variable to display information about attached variable
>>> properties as well.
>>
>> But we are talking right now about _functions_.  And it is a mistake to
>> consider the property list part of either variable or function: it has
>> different scopes and is independent from both variable or function.
>
> Sorry, I meant a symbol's property list for a function, not for a
> variable.

They are inherently not attached to either.  So it makes no sense to use
them on C-h f.  In particular since C-h k can deliver something like

<mouse-2> (translated from <down-mouse-2> <mouse-2>) at that spot runs the command (lambda (event) (interactive "e") (preview-toggle #<overlay from 1367 to 1387 in circ.tex> (quote toggle) event))
  which is an interactive Lisp function.
(anonymous EVENT)

Not documented.

There is no associated property list here.

> Property lists are already widely used in Emacs, so there is no reason
> to avoid them.  They are integral part of Emacs Lisp, and will cause
> no more problems.

Red herring.  Property lists are an inherent part of Lisp, but as an
element of _symbols_, not functions.

The interactive specifications are made part of _functions_ for a
reason, even though it makes it somewhat harder to extract them
explicitly (using interactive-form).  It is inconsistent to attach stuff
like that to a property-list that is more or less incidentally part of a
symbol that might or might not be the accessor to a function cell.

(call-interactively 'woozle)

currently is equivalent to

(call-interactively (symbol-function 'woozle))

And

(call-interactively last-command)

currently repeats the last action.

If we don't want the interactive call information to be in the
interactive form but in property lists attached to symbols, we need to
formally replace interactive forms completely, not mess the system up on
a case-by-case basis.

-- 
David Kastrup




^ permalink raw reply	[flat|nested] 167+ messages in thread

* Re: Shift selection using interactive spec
  2008-03-26 12:20                                                   ` David Kastrup
@ 2008-03-26 13:14                                                     ` Johan Bockgård
  2008-03-26 13:26                                                       ` David Kastrup
  2008-03-26 14:52                                                     ` Stefan Monnier
  2008-03-27  0:46                                                     ` Juri Linkov
  2 siblings, 1 reply; 167+ messages in thread
From: Johan Bockgård @ 2008-03-26 13:14 UTC (permalink / raw)
  To: emacs-devel

David Kastrup <dak@gnu.org> writes:

> The interactive specifications are made part of _functions_ for a
> reason, even though it makes it somewhat harder to extract them
> explicitly (using interactive-form). It is inconsistent to attach
> stuff like that to a property-list that is more or less incidentally
> part of a symbol that might or might not be the accessor to a function
> cell.

Too late ;)

> (call-interactively 'woozle)
>
> currently is equivalent to
>
> (call-interactively (symbol-function 'woozle))

(defun foo (&optional x) (interactive) x)

(fset 'bar 'foo)
(put 'bar 'interactive-form '(interactive (list 1)))

(call-interactively 'bar)
  => 1

(call-interactively (symbol-function 'bar))
  => nil

-- 
Johan Bockgård





^ permalink raw reply	[flat|nested] 167+ messages in thread

* Re: Shift selection using interactive spec
  2008-03-26 13:14                                                     ` Johan Bockgård
@ 2008-03-26 13:26                                                       ` David Kastrup
  0 siblings, 0 replies; 167+ messages in thread
From: David Kastrup @ 2008-03-26 13:26 UTC (permalink / raw)
  To: emacs-devel

bojohan+news@dd.chalmers.se (Johan Bockgård) writes:

> David Kastrup <dak@gnu.org> writes:
>
>> The interactive specifications are made part of _functions_ for a
>> reason, even though it makes it somewhat harder to extract them
>> explicitly (using interactive-form). It is inconsistent to attach
>> stuff like that to a property-list that is more or less incidentally
>> part of a symbol that might or might not be the accessor to a function
>> cell.
>
> Too late ;)
>
>> (call-interactively 'woozle)
>>
>> currently is equivalent to
>>
>> (call-interactively (symbol-function 'woozle))
>
> (defun foo (&optional x) (interactive) x)
>
> (fset 'bar 'foo)
> (put 'bar 'interactive-form '(interactive (list 1)))
>
> (call-interactively 'bar)
>   => 1
>
> (call-interactively (symbol-function 'bar))
>   => nil

If your point is that a single inconsistency should be sufficient excuse
to open the floodgates, that actually is a strong argument _against_
introducing _any_ inconsistency.  And it means that we should probably
get rid of that earlier inconsistency.

-- 
David Kastrup




^ permalink raw reply	[flat|nested] 167+ messages in thread

* Re: Shift selection using interactive spec
  2008-03-26 12:20                                                   ` David Kastrup
  2008-03-26 13:14                                                     ` Johan Bockgård
@ 2008-03-26 14:52                                                     ` Stefan Monnier
  2008-03-27  0:46                                                     ` Juri Linkov
  2 siblings, 0 replies; 167+ messages in thread
From: Stefan Monnier @ 2008-03-26 14:52 UTC (permalink / raw)
  To: David Kastrup; +Cc: Juri Linkov, M Jared Finder, emacs-devel

> (call-interactively 'woozle)

> currently is equivalent to

> (call-interactively (symbol-function 'woozle))

Actually, even if you ignore things that depend on symbol properties
(e.g. the interactive-form property), this still fails in some
corner cases.  My favorite one is when `woozle' is autoloaded.


        Stefan




^ permalink raw reply	[flat|nested] 167+ messages in thread

* Re: Shift selection using interactive spec
  2008-03-26 10:48                                             ` Juri Linkov
  2008-03-26 11:32                                               ` David Kastrup
  2008-03-26 11:47                                               ` Lennart Borgman (gmail)
@ 2008-03-26 22:26                                               ` Richard Stallman
  2 siblings, 0 replies; 167+ messages in thread
From: Richard Stallman @ 2008-03-26 22:26 UTC (permalink / raw)
  To: Juri Linkov; +Cc: jared, emacs-devel

    >> As an honest-to-god USER of Emacs, I want to say I completely agree
    >> with Kim, here.

In the Church of Emacs, we have no gods, so shouldn't he have said
"honest-to-Emacs"?




^ permalink raw reply	[flat|nested] 167+ messages in thread

* Re: Shift selection using interactive spec
  2008-03-26 11:47                                               ` Lennart Borgman (gmail)
@ 2008-03-26 22:26                                                 ` Richard Stallman
  2008-03-26 23:31                                                   ` Lennart Borgman (gmail)
  2008-03-27  0:49                                                   ` Juri Linkov
  0 siblings, 2 replies; 167+ messages in thread
From: Richard Stallman @ 2008-03-26 22:26 UTC (permalink / raw)
  To: Lennart Borgman (gmail); +Cc: juri, jared, emacs-devel

I think that `interactive' codes are much better than symbol properties
for defining the meaning of a command.

When the `interactive' spec is a Lisp expression, that expression
can call a suitably provided function to do the job.




^ permalink raw reply	[flat|nested] 167+ messages in thread

* Re: Shift selection using interactive spec
  2008-03-26 22:26                                                 ` Richard Stallman
@ 2008-03-26 23:31                                                   ` Lennart Borgman (gmail)
  2008-03-27  7:02                                                     ` David Kastrup
  2008-03-27 19:41                                                     ` Richard Stallman
  2008-03-27  0:49                                                   ` Juri Linkov
  1 sibling, 2 replies; 167+ messages in thread
From: Lennart Borgman (gmail) @ 2008-03-26 23:31 UTC (permalink / raw)
  To: rms; +Cc: juri, jared, emacs-devel

Richard Stallman wrote:
> I think that `interactive' codes are much better than symbol properties
> for defining the meaning of a command.

Yes, but the problem here is rather that you may need to redefine which 
commands should deactivate the mark. Doing that with a symbol property 
makes it much more flexible.




^ permalink raw reply	[flat|nested] 167+ messages in thread

* Re: Shift selection using interactive spec
  2008-03-26 12:20                                                   ` David Kastrup
  2008-03-26 13:14                                                     ` Johan Bockgård
  2008-03-26 14:52                                                     ` Stefan Monnier
@ 2008-03-27  0:46                                                     ` Juri Linkov
  2 siblings, 0 replies; 167+ messages in thread
From: Juri Linkov @ 2008-03-27  0:46 UTC (permalink / raw)
  To: David Kastrup; +Cc: M Jared Finder, emacs-devel

> They are inherently not attached to either.  So it makes no sense to use
> them on C-h f.  In particular since C-h k can deliver something like
>
> <mouse-2> (translated from <down-mouse-2> <mouse-2>) at that spot runs the command
> (lambda (event) (interactive "e") (preview-toggle #<overlay from 1367 to 1387 in circ.tex> (quote toggle) event))
>   which is an interactive Lisp function.
> (anonymous EVENT)
>
> Not documented.
>
> There is no associated property list here.

To make this command shift-aware, you can add `shift-translation-handler'
call like (lambda (event) (interactive "e") (shift-translation-handler) (preview-toggle

But such anonymous commands are very rare, so there is no serious problem
with them.

>> Property lists are already widely used in Emacs, so there is no reason
>> to avoid them.  They are integral part of Emacs Lisp, and will cause
>> no more problems.
>
> Red herring.  Property lists are an inherent part of Lisp, but as an
> element of _symbols_, not functions.
>
> The interactive specifications are made part of _functions_ for a
> reason, even though it makes it somewhat harder to extract them
> explicitly (using interactive-form).  It is inconsistent to attach stuff
> like that to a property-list that is more or less incidentally part of a
> symbol that might or might not be the accessor to a function cell.

There are already dozens of different properties in Emacs attached
formally to commands, not to function's symbols.  No one opposed
to such practice in the past.

-- 
Juri Linkov
http://www.jurta.org/emacs/




^ permalink raw reply	[flat|nested] 167+ messages in thread

* Re: Shift selection using interactive spec
  2008-03-26 22:26                                                 ` Richard Stallman
  2008-03-26 23:31                                                   ` Lennart Borgman (gmail)
@ 2008-03-27  0:49                                                   ` Juri Linkov
  2008-03-27  2:59                                                     ` Chong Yidong
  2008-03-27 19:41                                                     ` Richard Stallman
  1 sibling, 2 replies; 167+ messages in thread
From: Juri Linkov @ 2008-03-27  0:49 UTC (permalink / raw)
  To: rms; +Cc: jared, Lennart Borgman (gmail), emacs-devel

> I think that `interactive' codes are much better than symbol properties
> for defining the meaning of a command.
>
> When the `interactive' spec is a Lisp expression, that expression
> can call a suitably provided function to do the job.

According to the documentation, the `interactive' spec tells
`call-interactively' how to read arguments to pass to the function.

There is one exception that is not used to read arguments: if the
string begins with `*' then an error is signaled if the buffer is
read-only.  Since when the buffer is read-only, the command is unable
to operate on the buffer any way, it makes no sense for the user to want
to modify this behavior.

OTOH, shift-selection doesn't tell how to read arguments, It even doesn't
define the meaning of a command.  It specifies the behavior of a separate
optional feature invoked before the command call (in this case to set the
mark before the command call).

Moreover, the user might want to disable this feature for some commands or
enable it for some commands.  Modifying the `interactive' spec of a set of
commands in .emacs would be a big burden for the user.  But changing their
properties in .emacs is very easy as users already do for cua-selection-mode.

-- 
Juri Linkov
http://www.jurta.org/emacs/




^ permalink raw reply	[flat|nested] 167+ messages in thread

* Re: Shift selection using interactive spec
  2008-03-27  0:49                                                   ` Juri Linkov
@ 2008-03-27  2:59                                                     ` Chong Yidong
  2008-03-27 19:41                                                     ` Richard Stallman
  1 sibling, 0 replies; 167+ messages in thread
From: Chong Yidong @ 2008-03-27  2:59 UTC (permalink / raw)
  To: Juri Linkov; +Cc: Lennart Borgman (gmail), jared, rms, emacs-devel

Juri Linkov <juri@jurta.org> writes:

> Moreover, the user might want to disable this feature for some commands or
> enable it for some commands.  Modifying the `interactive' spec of a set of
> commands in .emacs would be a big burden for the user.  But changing their
> properties in .emacs is very easy as users already do for cua-selection-mode.

That's a good point.




^ permalink raw reply	[flat|nested] 167+ messages in thread

* Re: Shift selection using interactive spec
  2008-03-26 23:31                                                   ` Lennart Borgman (gmail)
@ 2008-03-27  7:02                                                     ` David Kastrup
  2008-03-27  8:19                                                       ` Lennart Borgman (gmail)
  2008-03-27 19:41                                                     ` Richard Stallman
  1 sibling, 1 reply; 167+ messages in thread
From: David Kastrup @ 2008-03-27  7:02 UTC (permalink / raw)
  To: Lennart Borgman (gmail); +Cc: juri, jared, rms, emacs-devel

"Lennart Borgman (gmail)" <lennart.borgman@gmail.com> writes:

> Richard Stallman wrote:
>> I think that `interactive' codes are much better than symbol properties
>> for defining the meaning of a command.
>
> Yes, but the problem here is rather that you may need to redefine
> which commands should deactivate the mark. Doing that with a symbol
> property makes it much more flexible.

Read "flexible" as "conveniently hot-patchable around things not
designed for it".  We have a policy not to use advice (another hotpatch
facility) for components distributed as part of Emacs because we want
all information pertaining to a particular function accessible and
readable from a single location in a clear manner.

I don't see this any different.  If there is a need for a user to
hot-patch around functions not designed for it, advice is still
available.

-- 
David Kastrup, Kriemhildstr. 15, 44793 Bochum




^ permalink raw reply	[flat|nested] 167+ messages in thread

* Re: Shift selection using interactive spec
  2008-03-27  7:02                                                     ` David Kastrup
@ 2008-03-27  8:19                                                       ` Lennart Borgman (gmail)
  2008-03-27  8:41                                                         ` David Kastrup
  0 siblings, 1 reply; 167+ messages in thread
From: Lennart Borgman (gmail) @ 2008-03-27  8:19 UTC (permalink / raw)
  To: David Kastrup; +Cc: juri, jared, rms, emacs-devel

David Kastrup wrote:
> "Lennart Borgman (gmail)" <lennart.borgman@gmail.com> writes:
> 
>> Richard Stallman wrote:
>>> I think that `interactive' codes are much better than symbol properties
>>> for defining the meaning of a command.
>> Yes, but the problem here is rather that you may need to redefine
>> which commands should deactivate the mark. Doing that with a symbol
>> property makes it much more flexible.
> 
> Read "flexible" as "conveniently hot-patchable around things not
> designed for it".  We have a policy not to use advice (another hotpatch
> facility) for components distributed as part of Emacs because we want
> all information pertaining to a particular function accessible and
> readable from a single location in a clear manner.
> 
> I don't see this any different.  If there is a need for a user to
> hot-patch around functions not designed for it, advice is still
> available.

But I believe this will only affect things on the command level. Is not 
that a big difference?




^ permalink raw reply	[flat|nested] 167+ messages in thread

* Re: Shift selection using interactive spec
  2008-03-27  8:19                                                       ` Lennart Borgman (gmail)
@ 2008-03-27  8:41                                                         ` David Kastrup
  2008-03-27 13:57                                                           ` Lennart Borgman (gmail)
  0 siblings, 1 reply; 167+ messages in thread
From: David Kastrup @ 2008-03-27  8:41 UTC (permalink / raw)
  To: Lennart Borgman (gmail); +Cc: juri, jared, rms, emacs-devel

"Lennart Borgman (gmail)" <lennart.borgman@gmail.com> writes:

> David Kastrup wrote:
>> "Lennart Borgman (gmail)" <lennart.borgman@gmail.com> writes:
>>
>>> Richard Stallman wrote:
>>>> I think that `interactive' codes are much better than symbol properties
>>>> for defining the meaning of a command.
>>> Yes, but the problem here is rather that you may need to redefine
>>> which commands should deactivate the mark. Doing that with a symbol
>>> property makes it much more flexible.
>>
>> Read "flexible" as "conveniently hot-patchable around things not
>> designed for it".  We have a policy not to use advice (another hotpatch
>> facility) for components distributed as part of Emacs because we want
>> all information pertaining to a particular function accessible and
>> readable from a single location in a clear manner.
>>
>> I don't see this any different.  If there is a need for a user to
>> hot-patch around functions not designed for it, advice is still
>> available.
>
> But I believe this will only affect things on the command level. Is
> not that a big difference?

The "command level" is distinguished by interactive forms.  So there is
a difference in that we _already_ have a standard location where the
command level behavior is determined, namely the interactive form.

If people really want to hot-patch command behavior manually by poking
around with properties rather than advice, the 'interactive-form
property already provides enough leeway for that.

I don't see that we want to open the floodgates for all sort of bypasses
for command-specific properties attached to something other than the
interactive form.

-- 
David Kastrup




^ permalink raw reply	[flat|nested] 167+ messages in thread

* Re: Shift selection using interactive spec
  2008-03-27  8:41                                                         ` David Kastrup
@ 2008-03-27 13:57                                                           ` Lennart Borgman (gmail)
  2008-03-27 14:39                                                             ` David Kastrup
  0 siblings, 1 reply; 167+ messages in thread
From: Lennart Borgman (gmail) @ 2008-03-27 13:57 UTC (permalink / raw)
  To: David Kastrup; +Cc: juri, jared, rms, emacs-devel

David Kastrup wrote:
> "Lennart Borgman (gmail)" <lennart.borgman@gmail.com> writes:
> 
>> David Kastrup wrote:
>>> "Lennart Borgman (gmail)" <lennart.borgman@gmail.com> writes:
>>>
>>>> Richard Stallman wrote:
>>>>> I think that `interactive' codes are much better than symbol properties
>>>>> for defining the meaning of a command.
>>>> Yes, but the problem here is rather that you may need to redefine
>>>> which commands should deactivate the mark. Doing that with a symbol
>>>> property makes it much more flexible.
>>> Read "flexible" as "conveniently hot-patchable around things not
>>> designed for it".  We have a policy not to use advice (another hotpatch
>>> facility) for components distributed as part of Emacs because we want
>>> all information pertaining to a particular function accessible and
>>> readable from a single location in a clear manner.
>>>
>>> I don't see this any different.  If there is a need for a user to
>>> hot-patch around functions not designed for it, advice is still
>>> available.
>> But I believe this will only affect things on the command level. Is
>> not that a big difference?
> 
> The "command level" is distinguished by interactive forms.  So there is
> a difference in that we _already_ have a standard location where the
> command level behavior is determined, namely the interactive form.
> 
> If people really want to hot-patch command behavior manually by poking
> around with properties rather than advice, the 'interactive-form
> property already provides enough leeway for that.
> 
> I don't see that we want to open the floodgates for all sort of bypasses
> for command-specific properties attached to something other than the
> interactive form.

Can you provide an example of how to change the interactive form for an 
existing function (without using advice of course)?




^ permalink raw reply	[flat|nested] 167+ messages in thread

* Re: Shift selection using interactive spec
  2008-03-27 13:57                                                           ` Lennart Borgman (gmail)
@ 2008-03-27 14:39                                                             ` David Kastrup
  2008-03-27 15:01                                                               ` Juanma Barranquero
  2008-03-27 15:13                                                               ` Johan Bockgård
  0 siblings, 2 replies; 167+ messages in thread
From: David Kastrup @ 2008-03-27 14:39 UTC (permalink / raw)
  To: Lennart Borgman (gmail); +Cc: juri, jared, rms, emacs-devel

"Lennart Borgman (gmail)" <lennart.borgman@gmail.com> writes:

> David Kastrup wrote:
>> "Lennart Borgman (gmail)" <lennart.borgman@gmail.com> writes:
>>
>>> David Kastrup wrote:
>>>> "Lennart Borgman (gmail)" <lennart.borgman@gmail.com> writes:
>>>>
>>>>> Richard Stallman wrote:
>>>>>> I think that `interactive' codes are much better than symbol properties
>>>>>> for defining the meaning of a command.
>>>>> Yes, but the problem here is rather that you may need to redefine
>>>>> which commands should deactivate the mark. Doing that with a symbol
>>>>> property makes it much more flexible.
>>>> Read "flexible" as "conveniently hot-patchable around things not
>>>> designed for it".  We have a policy not to use advice (another hotpatch
>>>> facility) for components distributed as part of Emacs because we want
>>>> all information pertaining to a particular function accessible and
>>>> readable from a single location in a clear manner.
>>>>
>>>> I don't see this any different.  If there is a need for a user to
>>>> hot-patch around functions not designed for it, advice is still
>>>> available.
>>> But I believe this will only affect things on the command level. Is
>>> not that a big difference?
>>
>> The "command level" is distinguished by interactive forms.  So there is
>> a difference in that we _already_ have a standard location where the
>> command level behavior is determined, namely the interactive form.
>>
>> If people really want to hot-patch command behavior manually by poking
>> around with properties rather than advice, the 'interactive-form
>> property already provides enough leeway for that.
>>
>> I don't see that we want to open the floodgates for all sort of bypasses
>> for command-specific properties attached to something other than the
>> interactive form.
>
> Can you provide an example of how to change the interactive form for
> an existing function (without using advice of course)?

(put 'forward-char 'interactive-form '(interactive "*p"))

Seemingly has no effect (except on explicit interactive-form calls), but
that would seem more like a bug than a principal problem.

-- 
David Kastrup




^ permalink raw reply	[flat|nested] 167+ messages in thread

* Re: Shift selection using interactive spec
  2008-03-27 14:39                                                             ` David Kastrup
@ 2008-03-27 15:01                                                               ` Juanma Barranquero
  2008-03-27 15:34                                                                 ` David Kastrup
  2008-03-27 15:13                                                               ` Johan Bockgård
  1 sibling, 1 reply; 167+ messages in thread
From: Juanma Barranquero @ 2008-03-27 15:01 UTC (permalink / raw)
  To: David Kastrup; +Cc: juri, jared, Lennart Borgman (gmail), rms, emacs-devel

On Thu, Mar 27, 2008 at 3:39 PM, David Kastrup <dak@gnu.org> wrote:

> "Lennart Borgman (gmail)" <lennart.borgman@gmail.com> writes:

>  > Can you provide an example of how to change the interactive form for
>  > an existing function (without using advice of course)?

>  (put 'forward-char 'interactive-form '(interactive "*p"))

???

But you previously said:

> Attaching information magically to symbols rather than the actual
> function seems much more unwise to me.

In which way is 'interactive-form not that "attaching information
magically to symbols"?

   Juanma




^ permalink raw reply	[flat|nested] 167+ messages in thread

* Re: Shift selection using interactive spec
  2008-03-27 14:39                                                             ` David Kastrup
  2008-03-27 15:01                                                               ` Juanma Barranquero
@ 2008-03-27 15:13                                                               ` Johan Bockgård
  1 sibling, 0 replies; 167+ messages in thread
From: Johan Bockgård @ 2008-03-27 15:13 UTC (permalink / raw)
  To: emacs-devel

David Kastrup <dak@gnu.org> writes:

> (put 'forward-char 'interactive-form '(interactive "*p"))
>
> Seemingly has no effect (except on explicit interactive-form calls), but
> that would seem more like a bug than a principal problem.

forward-char is a special case.  defadvice wouldn't work either.

-- 
Johan Bockgård





^ permalink raw reply	[flat|nested] 167+ messages in thread

* Re: Shift selection using interactive spec
  2008-03-27 15:01                                                               ` Juanma Barranquero
@ 2008-03-27 15:34                                                                 ` David Kastrup
  2008-03-27 15:41                                                                   ` Juanma Barranquero
  0 siblings, 1 reply; 167+ messages in thread
From: David Kastrup @ 2008-03-27 15:34 UTC (permalink / raw)
  To: Juanma Barranquero; +Cc: juri, jared, Lennart Borgman (gmail), rms, emacs-devel

"Juanma Barranquero" <lekktu@gmail.com> writes:

> On Thu, Mar 27, 2008 at 3:39 PM, David Kastrup <dak@gnu.org> wrote:
>
>> "Lennart Borgman (gmail)" <lennart.borgman@gmail.com> writes:
>
>>  > Can you provide an example of how to change the interactive form for
>>  > an existing function (without using advice of course)?
>
>>  (put 'forward-char 'interactive-form '(interactive "*p"))
>
> ???
>
> But you previously said:
>
>> Attaching information magically to symbols rather than the actual
>> function seems much more unwise to me.
>
> In which way is 'interactive-form not that "attaching information
> magically to symbols"?

Sigh.  I never claimed that it wasn't.  Could you please reread the
thread?  What I said is that the interactive-form property already
provides an inconsistency in that it attaches to the symbol rather than
the function.  People have argued that this is the perfect excuse to
introduce further such inconsistencies not even related to interactive
forms at all.

All I said that the presence of the interactive-form property should not
be used to open the floodgates in that manner, in particular since one
can employ it for this particular purpose if one really, really thinks
this a good idea.

Personally, I don't like the inconsistency introduced by this property.
But it would be even more foolish not to make use of it except as an
excuse for introducing further redundant inconsistencies.

At least this inconsistency is openly connected with interactive forms
(and interactive forms are the proper place to deal with interactive
calls).

The proposed other properties would not even have that connection.

-- 
David Kastrup




^ permalink raw reply	[flat|nested] 167+ messages in thread

* Re: Shift selection using interactive spec
  2008-03-27 15:34                                                                 ` David Kastrup
@ 2008-03-27 15:41                                                                   ` Juanma Barranquero
  0 siblings, 0 replies; 167+ messages in thread
From: Juanma Barranquero @ 2008-03-27 15:41 UTC (permalink / raw)
  To: David Kastrup; +Cc: juri, jared, Lennart Borgman (gmail), rms, emacs-devel

On Thu, Mar 27, 2008 at 4:34 PM, David Kastrup <dak@gnu.org> wrote:

>  Sigh.  I never claimed that it wasn't.  Could you please reread the
>  thread?

I've read it, I just didn't memorize it. Sorry.

>  Personally, I don't like the inconsistency introduced by this property.
>  But it would be even more foolish not to make use of it except as an
>  excuse for introducing further redundant inconsistencies.

Well, FWIW I agree with you that, long term, it would perhaps make
sense to remove even this one property, if there's a suitable
mechanism that can be attached to the function and not the symbol.

 Juanma




^ permalink raw reply	[flat|nested] 167+ messages in thread

* Re: Shift selection using interactive spec
  2008-03-27  0:49                                                   ` Juri Linkov
  2008-03-27  2:59                                                     ` Chong Yidong
@ 2008-03-27 19:41                                                     ` Richard Stallman
  2008-03-27 23:48                                                       ` Juri Linkov
  1 sibling, 1 reply; 167+ messages in thread
From: Richard Stallman @ 2008-03-27 19:41 UTC (permalink / raw)
  To: Juri Linkov; +Cc: jared, lennart.borgman, emacs-devel

    OTOH, shift-selection doesn't tell how to read arguments, It even doesn't
    define the meaning of a command.  It specifies the behavior of a separate
    optional feature invoked before the command call (in this case to set the
    mark before the command call).

The general purpose of `interactive' is to specify how to call the
command interactively.  This fits perfectly into that perfect.

I've long thought about giving `interactive' a second argument that
would specify how to display the command's return value.  This would
make it convenient to write commands that would return certain
information as a value when called from Lisp, and display the
same information when called interactively.




^ permalink raw reply	[flat|nested] 167+ messages in thread

* Re: Shift selection using interactive spec
  2008-03-26 23:31                                                   ` Lennart Borgman (gmail)
  2008-03-27  7:02                                                     ` David Kastrup
@ 2008-03-27 19:41                                                     ` Richard Stallman
  2008-03-27 23:52                                                       ` Juri Linkov
  2008-03-28  4:05                                                       ` M Jared Finder
  1 sibling, 2 replies; 167+ messages in thread
From: Richard Stallman @ 2008-03-27 19:41 UTC (permalink / raw)
  To: Lennart Borgman (gmail); +Cc: juri, jared, emacs-devel

    Yes, but the problem here is rather that you may need to redefine which 
    commands should deactivate the mark. Doing that with a symbol property 
    makes it much more flexible.

Why is it important to be able change whether a command deactivates
the mark without changing the command itself?




^ permalink raw reply	[flat|nested] 167+ messages in thread

* Re: Shift selection using interactive spec
  2008-03-27 19:41                                                     ` Richard Stallman
@ 2008-03-27 23:48                                                       ` Juri Linkov
  2008-03-28 20:41                                                         ` Richard Stallman
  0 siblings, 1 reply; 167+ messages in thread
From: Juri Linkov @ 2008-03-27 23:48 UTC (permalink / raw)
  To: rms; +Cc: jared, lennart.borgman, emacs-devel

> I've long thought about giving `interactive' a second argument that
> would specify how to display the command's return value.  This would
> make it convenient to write commands that would return certain
> information as a value when called from Lisp, and display the
> same information when called interactively.

This is an interesting feature.  Just as a first argument of
`interactive' specifies command's input, a second argument would
specify its output.  I think this pair of input/output arguments
of `interactive' makes sense.

-- 
Juri Linkov
http://www.jurta.org/emacs/




^ permalink raw reply	[flat|nested] 167+ messages in thread

* Re: Shift selection using interactive spec
  2008-03-27 19:41                                                     ` Richard Stallman
@ 2008-03-27 23:52                                                       ` Juri Linkov
  2008-03-28  7:33                                                         ` David Kastrup
  2008-03-28  4:05                                                       ` M Jared Finder
  1 sibling, 1 reply; 167+ messages in thread
From: Juri Linkov @ 2008-03-27 23:52 UTC (permalink / raw)
  To: rms; +Cc: jared, lennart.borgman, emacs-devel

>     Yes, but the problem here is rather that you may need to redefine which
>     commands should deactivate the mark. Doing that with a symbol property
>     makes it much more flexible.
>
> Why is it important to be able change whether a command deactivates
> the mark without changing the command itself?

As the users of cua-selection-mode already testified on this thread,
it is important for them to be able to tune this feature for some
commands.  And the easiest way to do this is to change properties.

Since there were complaints that property lists are "hidden" from users,
I propose the following patch to display them in the output of
`describe-function' and `describe-variable'.  The first part of this
patch also fixes a bug in navigating to the definition of an advised
function by using the correct variable `function' instead of
`real-function':

Index: lisp/help-fns.el
===================================================================
RCS file: /sources/emacs/emacs/lisp/help-fns.el,v
retrieving revision 1.118
diff -c -r1.118 help-fns.el
*** lisp/help-fns.el	26 Mar 2008 14:49:15 -0000	1.118
--- lisp/help-fns.el	27 Mar 2008 23:51:33 -0000
***************
*** 347,353 ****
        (with-current-buffer standard-output
          (save-excursion
  	  (re-search-backward "`\\([^`']+\\)'" nil t)
! 	  (help-xref-button 1 'help-function-def real-function file-name))))
      (princ ".")
      (with-current-buffer (help-buffer)
        (fill-region-as-paragraph (save-excursion (goto-char pt1) (forward-line 0) (point))
--- 347,353 ----
        (with-current-buffer standard-output
          (save-excursion
  	  (re-search-backward "`\\([^`']+\\)'" nil t)
! 	  (help-xref-button 1 'help-function-def function file-name))))
      (princ ".")
      (with-current-buffer (help-buffer)
        (fill-region-as-paragraph (save-excursion (goto-char pt1) (forward-line 0) (point))
***************
*** 435,441 ****
  			  (t "."))
  		    "\n"))
            (insert "\n"
!                   (or doc "Not documented.")))))))
  
  \f
  ;; Variables
--- 435,446 ----
  			  (t "."))
  		    "\n"))
            (insert "\n"
!                   (or doc "Not documented.")))
! 	(let ((pl (symbol-plist function)))
! 	  (when pl
! 	    (princ "\n\nSymbol plist is:\n")
! 	    (while pl
! 	      (princ (format "  %s %S\n" (pop pl) (pop pl))))))))))
  
  \f
  ;; Variables
***************
*** 679,684 ****
--- 684,695 ----
  	      (with-current-buffer standard-output
  		(insert (or doc "Not documented as a variable."))))
  
+ 	    (let ((pl (symbol-plist variable)))
+ 	      (when pl
+ 		(princ "\n\nSymbol plist is:\n")
+ 		(while pl
+ 		  (princ (format "  %s %S\n" (pop pl) (pop pl))))))
+ 
              (let ((customize-label "customize")
                    (initialization-file "initialization file"))
                ;; All variables can be set; some can be customized

-- 
Juri Linkov
http://www.jurta.org/emacs/




^ permalink raw reply	[flat|nested] 167+ messages in thread

* Re: Shift selection using interactive spec
  2008-03-27 19:41                                                     ` Richard Stallman
  2008-03-27 23:52                                                       ` Juri Linkov
@ 2008-03-28  4:05                                                       ` M Jared Finder
  2008-03-28 11:10                                                         ` David Kastrup
  2008-03-28 20:42                                                         ` Richard Stallman
  1 sibling, 2 replies; 167+ messages in thread
From: M Jared Finder @ 2008-03-28  4:05 UTC (permalink / raw)
  To: rms; +Cc: juri, Lennart Borgman (gmail), emacs-devel

Richard Stallman wrote:
>     Yes, but the problem here is rather that you may need to redefine which 
>     commands should deactivate the mark. Doing that with a symbol property 
>     makes it much more flexible.
>
> Why is it important to be able change whether a command deactivates
> the mark without changing the command itself?
>   
It'd be a disaster to have to restate the whole command or even just the 
interactive spec to make commands CUA-mode aware.  Right now, if I am 
using an external package that is not fully CUA-mode aware (like 
CC-mode), all I need to do is:
> (let ((move-fns '(c-forward-conditional c-backward-conditional
>                   c-down-conditional c-up-conditional
>                   c-down-conditional-with-else
>                   c-up-conditional-with-else
>                   c-beginning-of-statement c-end-of-statement)))
>   (require 'cua-base)
>   (dolist (symbol move-fns)
>     (unless (eq 'move (get symbol 'CUA))
>       (display-warning 'emacs (format "Adding CUA property to `%s'." 
> symbol))
>       (setf (get symbol 'CUA) 'move))))
If I had to restate the interactive spec, this would not be nearly as 
easy.  Please, listen to the users of CUA-mode and do *not* make this 
any harder.

  -- MJF




^ permalink raw reply	[flat|nested] 167+ messages in thread

* Re: Shift selection using interactive spec
  2008-03-27 23:52                                                       ` Juri Linkov
@ 2008-03-28  7:33                                                         ` David Kastrup
  2008-03-29  0:47                                                           ` Juri Linkov
  0 siblings, 1 reply; 167+ messages in thread
From: David Kastrup @ 2008-03-28  7:33 UTC (permalink / raw)
  To: Juri Linkov; +Cc: lennart.borgman, jared, rms, emacs-devel

Juri Linkov <juri@jurta.org> writes:

>>     Yes, but the problem here is rather that you may need to redefine which
>>     commands should deactivate the mark. Doing that with a symbol property
>>     makes it much more flexible.
>>
>> Why is it important to be able change whether a command deactivates
>> the mark without changing the command itself?
>
> As the users of cua-selection-mode already testified on this thread,
> it is important for them to be able to tune this feature for some
> commands.

Because the commands are not prepared for "this feature".  The solution
is to make them support the feature straightforwardly, not with covert
properties tacked on as an afterthought.

> And the easiest way to do this is to change properties.

I am not concerned about the easiest, but an appropriate way.

> Since there were complaints that property lists are "hidden" from
> users, I propose the following patch to display them in the output of
> `describe-function' and `describe-variable'.

Properties are not part of either variable or function.  They are part
of the symbol.

Lisp is Lisp, and Scheme is Scheme.

-- 
David Kastrup, Kriemhildstr. 15, 44793 Bochum




^ permalink raw reply	[flat|nested] 167+ messages in thread

* Re: Shift selection using interactive spec
  2008-03-28  4:05                                                       ` M Jared Finder
@ 2008-03-28 11:10                                                         ` David Kastrup
  2008-03-28 17:14                                                           ` Lennart Borgman (gmail)
  2008-03-28 20:42                                                         ` Richard Stallman
  1 sibling, 1 reply; 167+ messages in thread
From: David Kastrup @ 2008-03-28 11:10 UTC (permalink / raw)
  To: M Jared Finder; +Cc: juri, Lennart Borgman (gmail), rms, emacs-devel

M Jared Finder <jared@hpalace.com> writes:

> Richard Stallman wrote:
>>     Yes, but the problem here is rather that you may need to
>> redefine which     commands should deactivate the mark. Doing that
>> with a symbol property     makes it much more flexible.
>>
>> Why is it important to be able change whether a command deactivates
>> the mark without changing the command itself?
>>   
> It'd be a disaster to have to restate the whole command or even just
> the interactive spec to make commands CUA-mode aware.

Why?  We are not talking about "CUA-mode aware" but about mark
deactivation.

> Right now, if I am using an external package that is not fully
> CUA-mode aware (like CC-mode),

cc-mode is not an external package.  It is distributed as part of Emacs.

> all I need to do is:
>> (let ((move-fns '(c-forward-conditional c-backward-conditional
>>                   c-down-conditional c-up-conditional
>>                   c-down-conditional-with-else
>>                   c-up-conditional-with-else
>>                   c-beginning-of-statement c-end-of-statement)))
>>   (require 'cua-base)
>>   (dolist (symbol move-fns)
>>     (unless (eq 'move (get symbol 'CUA))
>>       (display-warning 'emacs (format "Adding CUA property to `%s'."
>> symbol))
>>       (setf (get symbol 'CUA) 'move))))
> If I had to restate the interactive spec, this would not be nearly as
> easy.  Please, listen to the users of CUA-mode and do *not* make this
> any harder.

If CUA-mode chooses to provide an additional futzing interface for
meddling with external packages, this does not preclude us from using a
proper interface within Emacs itself.

This is quite similar to the usage of advice: it is convenient for
_messing_ with things that are not prepared for it.  But that does not
make it a good idea for _regular_ interaction.

-- 
David Kastrup




^ permalink raw reply	[flat|nested] 167+ messages in thread

* Re: Shift selection using interactive spec
  2008-03-28 11:10                                                         ` David Kastrup
@ 2008-03-28 17:14                                                           ` Lennart Borgman (gmail)
  2008-03-28 20:05                                                             ` David Kastrup
  0 siblings, 1 reply; 167+ messages in thread
From: Lennart Borgman (gmail) @ 2008-03-28 17:14 UTC (permalink / raw)
  To: David Kastrup; +Cc: juri, M Jared Finder, rms, emacs-devel

David Kastrup wrote:
> If CUA-mode chooses to provide an additional futzing interface for
> meddling with external packages, this does not preclude us from using a
> proper interface within Emacs itself.

David, thanks for the example you provided earlier of how to change the 
interactive form. However to me it looks like this can not be used 
directly. It is too complicated.

To handle this you would perhaps write simple functions or even a 
defcustom that modifies the interactive forms for those functions that 
you want.

Maybe a first step would be to agree on a set of functions to modify and 
read the "move" information? Whether this modifies the interactive form 
property or some separate property does not IMO make significant 
difference. The main thing is that it must be easy for the user to 
handle this.

BTW, I think you are mixing two subjects: how to store the "move" 
information and where to attach this information. I agree that it might 
sometimes be good to have properties attached to the variable and to the 
function instead of the symbol.




^ permalink raw reply	[flat|nested] 167+ messages in thread

* Re: Shift selection using interactive spec
  2008-03-28 17:14                                                           ` Lennart Borgman (gmail)
@ 2008-03-28 20:05                                                             ` David Kastrup
  2008-03-28 23:49                                                               ` Lennart Borgman (gmail)
  0 siblings, 1 reply; 167+ messages in thread
From: David Kastrup @ 2008-03-28 20:05 UTC (permalink / raw)
  To: Lennart Borgman (gmail); +Cc: juri, M Jared Finder, rms, emacs-devel

"Lennart Borgman (gmail)" <lennart.borgman@gmail.com> writes:

> David Kastrup wrote:
>> If CUA-mode chooses to provide an additional futzing interface for
>> meddling with external packages, this does not preclude us from using a
>> proper interface within Emacs itself.
>
> David, thanks for the example you provided earlier of how to change
> the interactive form. However to me it looks like this can not be used
> directly. It is too complicated.

Sigh.  I am sick of all those strawmen.  It is not complicated to put an
additional character into an interactive string when appropriate.  If I
state that we already have ways to do ugly things and don't need another
one for that reason alone, that does not mean that I consider those ways
the proper thing to do.

What you are complaining about that there is no simple ad-hoc way to
patch up functions with _separated_ code when they are not actually
prepared to do the right thing.

Such ad-hoc patchery can be done in a manner of ways, starting with
advice over going through the interactive form.

It is easy enough to write and put a _function_ in cua-mode.el, _iff_
such patchery is desired, to perform this patchery and adjust all the
documentation strings appropriately in that process.  Whether or not
this is a complicated operation or not is utterly _irrelevant_: if it is
deemed important, a function doing the job can be provided with an
interface that is _easy_ to the user, regardless of what it does behind
the scenes.

Tacking a property to a symbol is doing a _half-baked_ job, and it is
plainly insane that people suggest C-h f trying to list all properties
on a symbol, on the notion that there might be some crazy undocumented
ad-hoc mechanism somehow interpreting some property on a symbol which
has its function cell set to some function.

This is utterly crazy.  Emacs is supposed to be self-documenting.  We
don't _want_ undocumented side-effects as a way to manipulate something
in the vicinity of a function, in a manner that will easily break
function aliases and other completely natural things.

If people want an easy way to mess with functions _after_ they have been
defined for this purpose, cua-mode can implement a proper function doing
this job.  There is no necessity that this function needs to be simple,
or be called "put".

-- 
David Kastrup, Kriemhildstr. 15, 44793 Bochum




^ permalink raw reply	[flat|nested] 167+ messages in thread

* Re: Shift selection using interactive spec
  2008-03-27 23:48                                                       ` Juri Linkov
@ 2008-03-28 20:41                                                         ` Richard Stallman
  2008-03-29  0:54                                                           ` Juri Linkov
  0 siblings, 1 reply; 167+ messages in thread
From: Richard Stallman @ 2008-03-28 20:41 UTC (permalink / raw)
  To: Juri Linkov; +Cc: jared, lennart.borgman, emacs-devel

    This is an interesting feature.  Just as a first argument of
    `interactive' specifies command's input, a second argument would
    specify its output.  I think this pair of input/output arguments
    of `interactive' makes sense.

The hard part is to figure out a good design for it.

It is important to support both returning a single value and returning
a list of values.  There could be a character at the beginning of the
interactive output string which specifies that it's a list of values.
Otherwise it is one value.

But what do we use after that?

It could be a format string to format the values.
Is that general enough?

And what about using Lisp code for how to format the value?
How would that Lisp code refer to the value itself?
Perhaps that Lisp code should take the form of a lambda expression.

But how do we specify whether it wants a list of values or a single
value?  I don't see any clean and natural way to specify that.




^ permalink raw reply	[flat|nested] 167+ messages in thread

* Re: Shift selection using interactive spec
  2008-03-28  4:05                                                       ` M Jared Finder
  2008-03-28 11:10                                                         ` David Kastrup
@ 2008-03-28 20:42                                                         ` Richard Stallman
  2008-03-28 21:47                                                           ` Chong Yidong
  1 sibling, 1 reply; 167+ messages in thread
From: Richard Stallman @ 2008-03-28 20:42 UTC (permalink / raw)
  To: M Jared Finder; +Cc: juri, lennart.borgman, emacs-devel

    It'd be a disaster to have to restate the whole command or even just the 
    interactive spec to make commands CUA-mode aware.  Right now, if I am 
    using an external package that is not fully CUA-mode aware (like 
    CC-mode), all I need to do is:

That is a valid point -- it is useful to be able to patch an external
library command by adding a property.

However, for writing commands in Emacs, I think the cleanest way
is to use the interactive spec.

So I think we should support both ways, but prefer the interactive
spec.




^ permalink raw reply	[flat|nested] 167+ messages in thread

* Re: Shift selection using interactive spec
  2008-03-28 20:42                                                         ` Richard Stallman
@ 2008-03-28 21:47                                                           ` Chong Yidong
  2008-03-28 22:01                                                             ` David Kastrup
  0 siblings, 1 reply; 167+ messages in thread
From: Chong Yidong @ 2008-03-28 21:47 UTC (permalink / raw)
  To: rms; +Cc: juri, lennart.borgman, M Jared Finder, emacs-devel

Richard Stallman <rms@gnu.org> writes:

>     It'd be a disaster to have to restate the whole command or even just the 
>     interactive spec to make commands CUA-mode aware.  Right now, if I am 
>     using an external package that is not fully CUA-mode aware (like 
>     CC-mode), all I need to do is:
>
> That is a valid point -- it is useful to be able to patch an external
> library command by adding a property.
>
> However, for writing commands in Emacs, I think the cleanest way
> is to use the interactive spec.
>
> So I think we should support both ways, but prefer the interactive
> spec.

Yeah.

So I suppose precedence would be given to the interactive spec; if the ^
code is not present, we'd check the `handle-shift-selection' property.
Also, to support an easy way of turning off shift selection in commands,
a value of (say) `off' in the `handle-shift-selection' property would
mean to avoid doing shift selection (otherwise, we wouldn't be able to
tell whether `handle-shift-selection' nil means the property hasn't been
defined, or whether the user wants to turn shift-selection off).

We would probably need a global variable to turn off shift-selection for
all commands too.

WDYT?




^ permalink raw reply	[flat|nested] 167+ messages in thread

* Re: Shift selection using interactive spec
  2008-03-28 21:47                                                           ` Chong Yidong
@ 2008-03-28 22:01                                                             ` David Kastrup
  2008-03-30  0:48                                                               ` Juri Linkov
  0 siblings, 1 reply; 167+ messages in thread
From: David Kastrup @ 2008-03-28 22:01 UTC (permalink / raw)
  To: Chong Yidong; +Cc: juri, M Jared Finder, lennart.borgman, rms, emacs-devel

Chong Yidong <cyd@stupidchicken.com> writes:

> Richard Stallman <rms@gnu.org> writes:
>
>>     It'd be a disaster to have to restate the whole command or even just the 
>>     interactive spec to make commands CUA-mode aware.  Right now, if I am 
>>     using an external package that is not fully CUA-mode aware (like 
>>     CC-mode), all I need to do is:
>>
>> That is a valid point -- it is useful to be able to patch an external
>> library command by adding a property.
>>
>> However, for writing commands in Emacs, I think the cleanest way
>> is to use the interactive spec.
>>
>> So I think we should support both ways, but prefer the interactive
>> spec.
>
> Yeah.
>
> So I suppose precedence would be given to the interactive spec; if the ^
> code is not present, we'd check the `handle-shift-selection' property.
> Also, to support an easy way of turning off shift selection in commands,
> a value of (say) `off' in the `handle-shift-selection' property would
> mean to avoid doing shift selection (otherwise, we wouldn't be able to
> tell whether `handle-shift-selection' nil means the property hasn't been
> defined, or whether the user wants to turn shift-selection off).
>
> We would probably need a global variable to turn off shift-selection for
> all commands too.
>
> WDYT?

I think it nonsensical to have a particular special way to alter a lot
of commands individually in just one aspect.

If the functionality is as annoying when being switched on as to warrant
per-function fine-tuning, we should tone down the obnoxious parts.

Do you have an example for a function which should by default obey
shift-selection, but where a user would rather have it turned off?

-- 
David Kastrup, Kriemhildstr. 15, 44793 Bochum




^ permalink raw reply	[flat|nested] 167+ messages in thread

* Re: Shift selection using interactive spec
  2008-03-28 20:05                                                             ` David Kastrup
@ 2008-03-28 23:49                                                               ` Lennart Borgman (gmail)
  0 siblings, 0 replies; 167+ messages in thread
From: Lennart Borgman (gmail) @ 2008-03-28 23:49 UTC (permalink / raw)
  To: David Kastrup; +Cc: juri, M Jared Finder, rms, emacs-devel

David Kastrup wrote:
> "Lennart Borgman (gmail)" <lennart.borgman@gmail.com> writes:
> 
>> David Kastrup wrote:
>>> If CUA-mode chooses to provide an additional futzing interface for
>>> meddling with external packages, this does not preclude us from using a
>>> proper interface within Emacs itself.
>> David, thanks for the example you provided earlier of how to change
>> the interactive form. However to me it looks like this can not be used
>> directly. It is too complicated.
> 
> What you are complaining about that there is no simple ad-hoc way to
> patch up functions with _separated_ code when they are not actually
> prepared to do the right thing.
> 
> Such ad-hoc patchery can be done in a manner of ways, starting with
> advice over going through the interactive form.


I am sorry but it seems like you are misunderstanding the subject.


> It is easy enough to write and put a _function_ in cua-mode.el, _iff_
> such patchery is desired, to perform this patchery and adjust all the
> documentation strings appropriately in that process.  Whether or not

The functionality is desired, but it should of course not go into 
cua-mode.el. It is important not to introduce unneeded complexity. This 
should be a common functionality, not something specific to cua-mode.




^ permalink raw reply	[flat|nested] 167+ messages in thread

* Re: Shift selection using interactive spec
  2008-03-28  7:33                                                         ` David Kastrup
@ 2008-03-29  0:47                                                           ` Juri Linkov
  2008-03-29  7:03                                                             ` David Kastrup
  0 siblings, 1 reply; 167+ messages in thread
From: Juri Linkov @ 2008-03-29  0:47 UTC (permalink / raw)
  To: David Kastrup; +Cc: lennart.borgman, jared, rms, emacs-devel

>> And the easiest way to do this is to change properties.
>
> I am not concerned about the easiest, but an appropriate way.

Emacs should be easy to use and customize, not appropriate for some
abstract goal.

>> Since there were complaints that property lists are "hidden" from
>> users, I propose the following patch to display them in the output of
>> `describe-function' and `describe-variable'.
>
> Properties are not part of either variable or function.  They are part
> of the symbol.

So what?  There are already about 200 distinct properties in Emacs
attached indirectly to functions and variables via symbols, and they
modify the default behavior, so the documentation should reveal them
to users.

> Lisp is Lisp, and Scheme is Scheme.

And Emacs is Emacs (_extensible_, _customizable_, _self-documenting_
real-time display editor).

-- 
Juri Linkov
http://www.jurta.org/emacs/




^ permalink raw reply	[flat|nested] 167+ messages in thread

* Re: Shift selection using interactive spec
  2008-03-28 20:41                                                         ` Richard Stallman
@ 2008-03-29  0:54                                                           ` Juri Linkov
  2008-03-29  1:15                                                             ` Lennart Borgman (gmail)
  2008-03-29 16:37                                                             ` Richard Stallman
  0 siblings, 2 replies; 167+ messages in thread
From: Juri Linkov @ 2008-03-29  0:54 UTC (permalink / raw)
  To: rms; +Cc: jared, lennart.borgman, emacs-devel

> The hard part is to figure out a good design for it.
>
> It is important to support both returning a single value and returning
> a list of values.  There could be a character at the beginning of the
> interactive output string which specifies that it's a list of values.
> Otherwise it is one value.
>
> But what do we use after that?
>
> It could be a format string to format the values.
> Is that general enough?
>
> And what about using Lisp code for how to format the value?
> How would that Lisp code refer to the value itself?
> Perhaps that Lisp code should take the form of a lambda expression.
>
> But how do we specify whether it wants a list of values or a single
> value?  I don't see any clean and natural way to specify that.

As I understand the purpose of this feature is practically to move
the last expression of the command's body that usually is written as

    (if (interactive-p)
        (message "Result of this command is %.0f" return-value)
      (format "%.0f" return-value))

to the second argument of `interactive'?

If so, then I see no way to generalize this expression as it can be
anything allowed in Lisp.

-- 
Juri Linkov
http://www.jurta.org/emacs/




^ permalink raw reply	[flat|nested] 167+ messages in thread

* Re: Shift selection using interactive spec
  2008-03-29  0:54                                                           ` Juri Linkov
@ 2008-03-29  1:15                                                             ` Lennart Borgman (gmail)
  2008-03-29 16:37                                                             ` Richard Stallman
  1 sibling, 0 replies; 167+ messages in thread
From: Lennart Borgman (gmail) @ 2008-03-29  1:15 UTC (permalink / raw)
  To: Juri Linkov; +Cc: jared, rms, emacs-devel

Juri Linkov wrote:
>> The hard part is to figure out a good design for it.
>>
>> It is important to support both returning a single value and returning
>> a list of values.  There could be a character at the beginning of the
>> interactive output string which specifies that it's a list of values.
>> Otherwise it is one value.
>>
>> But what do we use after that?
>>
>> It could be a format string to format the values.
>> Is that general enough?
>>
>> And what about using Lisp code for how to format the value?
>> How would that Lisp code refer to the value itself?
>> Perhaps that Lisp code should take the form of a lambda expression.
>>
>> But how do we specify whether it wants a list of values or a single
>> value?  I don't see any clean and natural way to specify that.
> 
> As I understand the purpose of this feature is practically to move
> the last expression of the command's body that usually is written as
> 
>     (if (interactive-p)
>         (message "Result of this command is %.0f" return-value)
>       (format "%.0f" return-value))
> 
> to the second argument of `interactive'?
> 
> If so, then I see no way to generalize this expression as it can be
> anything allowed in Lisp.

I can't understand the usefulness of this feature for an interactive 
function. Why not just do something like the above?

But there is another rather similar feature that I think would be 
useful: handling of errors differently when a function is called 
interactively. I think the current implementation with 
debug-ignored-errors is a bug since it does not distinguish when a 
function is called interactively or not. This can be cured in other ways 
too, of course.




^ permalink raw reply	[flat|nested] 167+ messages in thread

* Re: Shift selection using interactive spec
  2008-03-29  0:47                                                           ` Juri Linkov
@ 2008-03-29  7:03                                                             ` David Kastrup
  2008-03-29 11:53                                                               ` Lennart Borgman (gmail)
  2008-03-29 12:30                                                               ` Juri Linkov
  0 siblings, 2 replies; 167+ messages in thread
From: David Kastrup @ 2008-03-29  7:03 UTC (permalink / raw)
  To: Juri Linkov; +Cc: lennart.borgman, jared, rms, emacs-devel

Juri Linkov <juri@jurta.org> writes:

>>> And the easiest way to do this is to change properties.
>>
>> I am not concerned about the easiest, but an appropriate way.
>
> Emacs should be easy to use and customize, not appropriate for some
> abstract goal.

Giving a function a well-defined default behavior is not customization.
It is function definition.

>>> Since there were complaints that property lists are "hidden" from
>>> users, I propose the following patch to display them in the output
>>> of `describe-function' and `describe-variable'.
>>
>> Properties are not part of either variable or function.  They are
>> part of the symbol.
>
> So what?  There are already about 200 distinct properties in Emacs
> attached indirectly to functions and variables via symbols, and they
> modify the default behavior, so the documentation should reveal them
> to users.

But there is no _meaning_ conveyed by some property.  It is
undocumented.

>> Lisp is Lisp, and Scheme is Scheme.
>
> And Emacs is Emacs (_extensible_, _customizable_, _self-documenting_
> real-time display editor).

So what about "self-documenting" applies to arbitrary properties?  We
don't document functions by disassembling them, but by documentation
strings.  The presence of a property is not self-explanatory, and it is
not apparent whether it may affect the variable, the function, or
something else.

-- 
David Kastrup, Kriemhildstr. 15, 44793 Bochum




^ permalink raw reply	[flat|nested] 167+ messages in thread

* Re: Shift selection using interactive spec
  2008-03-29  7:03                                                             ` David Kastrup
@ 2008-03-29 11:53                                                               ` Lennart Borgman (gmail)
  2008-03-29 12:30                                                               ` Juri Linkov
  1 sibling, 0 replies; 167+ messages in thread
From: Lennart Borgman (gmail) @ 2008-03-29 11:53 UTC (permalink / raw)
  To: David Kastrup; +Cc: Juri Linkov, jared, rms, emacs-devel

David Kastrup wrote:
> So what about "self-documenting" applies to arbitrary properties?  We
> don't document functions by disassembling them, but by documentation
> strings.  The presence of a property is not self-explanatory, and it is
> not apparent whether it may affect the variable, the function, or
> something else.

The self-documenting system takes care of some of the properties. Of 
course it should take care of the property we are talking about here.




^ permalink raw reply	[flat|nested] 167+ messages in thread

* Re: Shift selection using interactive spec
  2008-03-29  7:03                                                             ` David Kastrup
  2008-03-29 11:53                                                               ` Lennart Borgman (gmail)
@ 2008-03-29 12:30                                                               ` Juri Linkov
  2008-03-29 14:07                                                                 ` David Kastrup
  2008-03-30  5:49                                                                 ` Richard Stallman
  1 sibling, 2 replies; 167+ messages in thread
From: Juri Linkov @ 2008-03-29 12:30 UTC (permalink / raw)
  To: David Kastrup; +Cc: lennart.borgman, jared, rms, emacs-devel

>>>> And the easiest way to do this is to change properties.
>>>
>>> I am not concerned about the easiest, but an appropriate way.
>>
>> Emacs should be easy to use and customize, not appropriate for some
>> abstract goal.
>
> Giving a function a well-defined default behavior is not customization.
> It is function definition.

Shift-selection is not an inherent part of function definition since
a function can normally work with or without this feature either way.

And it would be very confusing to set a default behavior using
interactive codes, but allow to modify it using properties.
The source of this confusion is non-obvious interaction between two ways
of doing the same thing.

>>> Properties are not part of either variable or function.  They are
>>> part of the symbol.
>>
>> So what?  There are already about 200 distinct properties in Emacs
>> attached indirectly to functions and variables via symbols, and they
>> modify the default behavior, so the documentation should reveal them
>> to users.
>
> But there is no _meaning_ conveyed by some property.  It is
> undocumented.

Of course, a property has a meaning, but it is different from the
meaning of a command.  For instance, `forward-char' has the meaning of
moving point right n characters.  OTOH, the `shift-selection' property
has the meaning of activating the mark before executing the command.
Those are different meanings of different features.

>>> Lisp is Lisp, and Scheme is Scheme.
>>
>> And Emacs is Emacs (_extensible_, _customizable_, _self-documenting_
>> real-time display editor).
>
> So what about "self-documenting" applies to arbitrary properties?  We
> don't document functions by disassembling them, but by documentation
> strings.  The presence of a property is not self-explanatory, and it is
> not apparent whether it may affect the variable, the function, or
> something else.

Actually you presented the argument against using interactive codes for
the shift-selection feature.  Using an interactive code will require
adding a text like "This command activates the mark before its execution
when Shift key is pressed" to the documentation string of the command.

But when the user will turn off this feature (external to the function
definition) the documentation string will lie to the user.

So it is clear that the shift-selection feature should not be part
of function definition (not to have an interactive code nor
corresponding text in its documentation string).

The only alternative to assigning properties to function symbols
I see is creating a new user option with a list of command names
that should activate the mark before their execution.

-- 
Juri Linkov
http://www.jurta.org/emacs/




^ permalink raw reply	[flat|nested] 167+ messages in thread

* Re: Shift selection using interactive spec
  2008-03-29 12:30                                                               ` Juri Linkov
@ 2008-03-29 14:07                                                                 ` David Kastrup
  2008-03-29 14:45                                                                   ` Lennart Borgman (gmail)
  2008-03-30  0:52                                                                   ` Juri Linkov
  2008-03-30  5:49                                                                 ` Richard Stallman
  1 sibling, 2 replies; 167+ messages in thread
From: David Kastrup @ 2008-03-29 14:07 UTC (permalink / raw)
  To: Juri Linkov; +Cc: lennart.borgman, jared, rms, emacs-devel

Juri Linkov <juri@jurta.org> writes:

>>>>> And the easiest way to do this is to change properties.
>>>>
>>>> I am not concerned about the easiest, but an appropriate way.
>>>
>>> Emacs should be easy to use and customize, not appropriate for some
>>> abstract goal.
>>
>> Giving a function a well-defined default behavior is not customization.
>> It is function definition.
>
> Shift-selection is not an inherent part of function definition since a
> function can normally work with or without this feature either way.

How is this different from any interactive call specification?  In
particular, from, say, the "*" flag in an interactive call string?

> And it would be very confusing to set a default behavior using
> interactive codes, but allow to modify it using properties.

So the solution is not to let properties meddle with this.  Fine with
me.

>>>> Properties are not part of either variable or function.  They are
>>>> part of the symbol.
>>>
>>> So what?  There are already about 200 distinct properties in Emacs
>>> attached indirectly to functions and variables via symbols, and they
>>> modify the default behavior, so the documentation should reveal them
>>> to users.
>>
>> But there is no _meaning_ conveyed by some property.  It is
>> undocumented.
>
> Of course, a property has a meaning, but it is different from the
> meaning of a command.

It has no _inherent_ meaning.  And there is no way of documenting any
meaning of it, anyway.

> For instance, `forward-char' has the meaning of moving point right n
> characters.  OTOH, the `shift-selection' property has the meaning of
> activating the mark before executing the command.

Before executing a command that happens to be bound to a particular
symbol, when this command is called in a particular way in the command
loop by doing symbol lookup.

That's very arbitrary.

> Those are different meanings of different features.

This is not even comparing apples and oranges.  It is comparing apples
and geography.

>>>> Lisp is Lisp, and Scheme is Scheme.
>>>
>>> And Emacs is Emacs (_extensible_, _customizable_, _self-documenting_
>>> real-time display editor).
>>
>> So what about "self-documenting" applies to arbitrary properties?  We
>> don't document functions by disassembling them, but by documentation
>> strings.  The presence of a property is not self-explanatory, and it is
>> not apparent whether it may affect the variable, the function, or
>> something else.
>
> Actually you presented the argument against using interactive codes
> for the shift-selection feature.  Using an interactive code will
> require adding a text like "This command activates the mark before its
> execution when Shift key is pressed" to the documentation string of
> the command.

Your point being?  Of course one adapts the function documentation
string as well when one changes the interactive code.  That's the same
with all other interactive calls.

But there is no way to change the DOC string when one tacks a property
onto the function.  And that means that the DOC string change and the
property tack-on are not inherently _synchronized_.  And that is a bad
idea.

> But when the user will turn off this feature (external to the function
> definition) the documentation string will lie to the user.

Make up a better documentation string, then, referring to the variable
which presumably turns on/off the feature.

> So it is clear that the shift-selection feature should not be part of
> function definition (not to have an interactive code nor corresponding
> text in its documentation string).

We can stop this right here.  There is _no_ _way_ whatsoever that you
will convince me that a part of the interactive behavior of the function
should _not_ be put into its interactive form and _not_ into its
documentation.

I consider this completely inappropriate.  You will not change my mind
on that.

> The only alternative to assigning properties to function symbols I see
> is creating a new user option with a list of command names that should
> activate the mark before their execution.

Again, this hides away part of the interactive behavior of a command to
a different place.  And again, it makes the mechanism depend on the
_name_ (aka symbol) of the called function rather than its function
definition.

-- 
David Kastrup, Kriemhildstr. 15, 44793 Bochum




^ permalink raw reply	[flat|nested] 167+ messages in thread

* Re: Shift selection using interactive spec
  2008-03-29 14:07                                                                 ` David Kastrup
@ 2008-03-29 14:45                                                                   ` Lennart Borgman (gmail)
  2008-03-29 15:09                                                                     ` David Kastrup
  2008-03-30  0:52                                                                   ` Juri Linkov
  1 sibling, 1 reply; 167+ messages in thread
From: Lennart Borgman (gmail) @ 2008-03-29 14:45 UTC (permalink / raw)
  To: David Kastrup; +Cc: Juri Linkov, jared, rms, emacs-devel

David Kastrup wrote:
> But there is no way to change the DOC string when one tacks a property
> onto the function.  And that means that the DOC string change and the
> property tack-on are not inherently _synchronized_.  And that is a bad
> idea.

I think you are attaching the wrong point. What is important is not only 
the doc string, but what the help system does. Of course the help system 
can take care of this. In this respect there is no problem with using a 
property here.

> Again, this hides away part of the interactive behavior of a command to
> a different place.  And again, it makes the mechanism depend on the
> _name_ (aka symbol) of the called function rather than its function
> definition.

David, may I remind you that I asked you earlier about a way to change 
the interactive spec in the function cell. You answered with a way to 
instead attach a property to the symbol name.




^ permalink raw reply	[flat|nested] 167+ messages in thread

* Re: Shift selection using interactive spec
  2008-03-29 14:45                                                                   ` Lennart Borgman (gmail)
@ 2008-03-29 15:09                                                                     ` David Kastrup
  2008-03-29 15:30                                                                       ` Lennart Borgman (gmail)
  0 siblings, 1 reply; 167+ messages in thread
From: David Kastrup @ 2008-03-29 15:09 UTC (permalink / raw)
  To: Lennart Borgman (gmail); +Cc: Juri Linkov, jared, rms, emacs-devel

"Lennart Borgman (gmail)" <lennart.borgman@gmail.com> writes:

> David Kastrup wrote:
>> But there is no way to change the DOC string when one tacks a property
>> onto the function.  And that means that the DOC string change and the
>> property tack-on are not inherently _synchronized_.  And that is a bad
>> idea.
>
> I think you are attaching the wrong point. What is important is not
> only the doc string, but what the help system does. Of course the help
> system can take care of this. In this respect there is no problem with
> using a property here.
>
>> Again, this hides away part of the interactive behavior of a command to
>> a different place.  And again, it makes the mechanism depend on the
>> _name_ (aka symbol) of the called function rather than its function
>> definition.
>
> David, may I remind you that I asked you earlier about a way to change
> the interactive spec in the function cell. You answered with a way to
> instead attach a property to the symbol name.

Lennart, may I remind you that this was in answer to your asking for an
example after I pointed out that we _already_ have this interactive-form
property which, misguided as it may be, obliterates the necessity for
further things of its likeness which are not even remotely looking like
they have anything to do with the interactive call.

I am utterly fed up with this sort of game playing.  I did _not_, I
repeat _not_ at any point of time suggest that using _any_ property
_including_ the interactive-form property for stealthily modifying a
function's behavior inside of Emacs was a good idea.  I merely pointed
out that _if_ one wants to follow such an imprudent course, there is no
necessity to _further_ mess around with properties.

I regret giving you the example you requested since you apparently were
only interested in fabricating a strawman from it.

-- 
David Kastrup, Kriemhildstr. 15, 44793 Bochum




^ permalink raw reply	[flat|nested] 167+ messages in thread

* Re: Shift selection using interactive spec
  2008-03-29 15:09                                                                     ` David Kastrup
@ 2008-03-29 15:30                                                                       ` Lennart Borgman (gmail)
  0 siblings, 0 replies; 167+ messages in thread
From: Lennart Borgman (gmail) @ 2008-03-29 15:30 UTC (permalink / raw)
  To: David Kastrup; +Cc: Juri Linkov, jared, rms, emacs-devel

David Kastrup wrote:
> "Lennart Borgman (gmail)" <lennart.borgman@gmail.com> writes:
> 
>> David Kastrup wrote:
>>> Again, this hides away part of the interactive behavior of a command to
>>> a different place.  And again, it makes the mechanism depend on the
>>> _name_ (aka symbol) of the called function rather than its function
>>> definition.
>> David, may I remind you that I asked you earlier about a way to change
>> the interactive spec in the function cell. You answered with a way to
>> instead attach a property to the symbol name.
> 
> Lennart, may I remind you that this was in answer to your asking for an
> example after I pointed out that we _already_ have this interactive-form
> property which, misguided as it may be, obliterates the necessity for
> further things of its likeness which are not even remotely looking like
> they have anything to do with the interactive call.

I see. My misunderstanding. I thought you suggested that we should use 
the interactive spec for the function and change that on the fly.

> I am utterly fed up with this sort of game playing.  I did _not_, I
> repeat _not_ at any point of time suggest that using _any_ property
> _including_ the interactive-form property for stealthily modifying a
> function's behavior inside of Emacs was a good idea.  I merely pointed
> out that _if_ one wants to follow such an imprudent course, there is no
> necessity to _further_ mess around with properties.
> 
> I regret giving you the example you requested since you apparently were
> only interested in fabricating a strawman from it.

No need to regret, just a misunderstanding.

However I of course still disagree with you, but now for a bit better 
reason ;-)

More seriously: This does not change my view of the short term solution 
of the current problem, but I can see your point more clearly.

PS: I think it is much easier to read your arguments if you do not use 
words loaded with bad connotations.






^ permalink raw reply	[flat|nested] 167+ messages in thread

* Re: Shift selection using interactive spec
  2008-03-29  0:54                                                           ` Juri Linkov
  2008-03-29  1:15                                                             ` Lennart Borgman (gmail)
@ 2008-03-29 16:37                                                             ` Richard Stallman
  2008-03-30  1:05                                                               ` Juri Linkov
  1 sibling, 1 reply; 167+ messages in thread
From: Richard Stallman @ 2008-03-29 16:37 UTC (permalink / raw)
  To: Juri Linkov; +Cc: jared, lennart.borgman, emacs-devel

    As I understand the purpose of this feature is practically to move
    the last expression of the command's body that usually is written as

	(if (interactive-p)
	    (message "Result of this command is %.0f" return-value)
	  (format "%.0f" return-value))

You have the right idea in mind for what the code would be trying to
do.  But code like that would be a strange way to write it, and in
practice does seem to occur much if at all.  The way I would envision
this is more like

	(if interactive-call
	    (message "Result of this command is %.0f" return-value))
   	return-value)

where `interactive-call' is an argument initialized to non-nil
for an interactive call.

The job of the second arg to `interctive', that I've proposed, would
be to control how to generate the message in the interactive case.




^ permalink raw reply	[flat|nested] 167+ messages in thread

* Re: Shift selection using interactive spec
  2008-03-28 22:01                                                             ` David Kastrup
@ 2008-03-30  0:48                                                               ` Juri Linkov
  2008-03-30 17:55                                                                 ` David Kastrup
  0 siblings, 1 reply; 167+ messages in thread
From: Juri Linkov @ 2008-03-30  0:48 UTC (permalink / raw)
  To: David Kastrup
  Cc: M Jared Finder, Chong Yidong, lennart.borgman, rms, emacs-devel

> If the functionality is as annoying when being switched on as to warrant
> per-function fine-tuning, we should tone down the obnoxious parts.
>
> Do you have an example for a function which should by default obey
> shift-selection, but where a user would rather have it turned off?

We have an infinite set of examples where a user would have it turned ON.

-- 
Juri Linkov
http://www.jurta.org/emacs/




^ permalink raw reply	[flat|nested] 167+ messages in thread

* Re: Shift selection using interactive spec
  2008-03-29 14:07                                                                 ` David Kastrup
  2008-03-29 14:45                                                                   ` Lennart Borgman (gmail)
@ 2008-03-30  0:52                                                                   ` Juri Linkov
  2008-03-30 17:56                                                                     ` David Kastrup
  1 sibling, 1 reply; 167+ messages in thread
From: Juri Linkov @ 2008-03-30  0:52 UTC (permalink / raw)
  To: David Kastrup; +Cc: lennart.borgman, jared, rms, emacs-devel

>> Shift-selection is not an inherent part of function definition since a
>> function can normally work with or without this feature either way.
>
> How is this different from any interactive call specification?  In
> particular, from, say, the "*" flag in an interactive call string?

If is known beforehand that a command can't work on read-only buffers.
But shift-selection can be freely turned on/off.

> But there is no way to change the DOC string when one tacks a property
> onto the function.  And that means that the DOC string change and the
> property tack-on are not inherently _synchronized_.  And that is a bad
> idea.

A patch I sent solves this by displaying properties in the *Help* buffer
after the docstring.

>> The only alternative to assigning properties to function symbols I see
>> is creating a new user option with a list of command names that should
>> activate the mark before their execution.
>
> Again, this hides away part of the interactive behavior of a command to
> a different place.  And again, it makes the mechanism depend on the
> _name_ (aka symbol) of the called function rather than its function
> definition.

Do you propose to remove all existing properties together with user
options and move all features that modify the default behavior to only
function definitions and docstrings?

-- 
Juri Linkov
http://www.jurta.org/emacs/




^ permalink raw reply	[flat|nested] 167+ messages in thread

* Re: Shift selection using interactive spec
  2008-03-29 16:37                                                             ` Richard Stallman
@ 2008-03-30  1:05                                                               ` Juri Linkov
  2008-03-30  4:12                                                                 ` Stefan Monnier
  2008-03-30 19:56                                                                 ` Richard Stallman
  0 siblings, 2 replies; 167+ messages in thread
From: Juri Linkov @ 2008-03-30  1:05 UTC (permalink / raw)
  To: rms; +Cc: jared, lennart.borgman, emacs-devel

>     As I understand the purpose of this feature is practically to move
>     the last expression of the command's body that usually is written as
>
> 	(if (interactive-p)
> 	    (message "Result of this command is %.0f" return-value)
> 	  (format "%.0f" return-value))
>
> You have the right idea in mind for what the code would be trying to
> do.  But code like that would be a strange way to write it, and in
> practice does seem to occur much if at all.  The way I would envision
> this is more like
>
> 	(if interactive-call
> 	    (message "Result of this command is %.0f" return-value))
>    	return-value)
>
> where `interactive-call' is an argument initialized to non-nil
> for an interactive call.
>
> The job of the second arg to `interactive', that I've proposed, would
> be to control how to generate the message in the interactive case.

Then the second arg to `interactive' could be just a lambda
with one argument with the value this function returns, e.g.

(defun command ()
  (interactive
    nil
    (lambda (ret-val)
      (message "Result of this command is %.0f" ret-val)))
  ...
  (let ((return-value ...))
    ...
    return-value))

-- 
Juri Linkov
http://www.jurta.org/emacs/




^ permalink raw reply	[flat|nested] 167+ messages in thread

* Re: Shift selection using interactive spec
  2008-03-30  1:05                                                               ` Juri Linkov
@ 2008-03-30  4:12                                                                 ` Stefan Monnier
  2008-03-30 18:33                                                                   ` Juri Linkov
  2008-03-30 19:56                                                                 ` Richard Stallman
  1 sibling, 1 reply; 167+ messages in thread
From: Stefan Monnier @ 2008-03-30  4:12 UTC (permalink / raw)
  To: Juri Linkov; +Cc: lennart.borgman, jared, rms, emacs-devel

>> As I understand the purpose of this feature is practically to move
>> the last expression of the command's body that usually is written as
>> 
>> (if (interactive-p)
>> (message "Result of this command is %.0f" return-value)
>> (format "%.0f" return-value))
>> 
>> You have the right idea in mind for what the code would be trying to
>> do.  But code like that would be a strange way to write it, and in
>> practice does seem to occur much if at all.  The way I would envision
>> this is more like
>> 
>> (if interactive-call
>> (message "Result of this command is %.0f" return-value))
>> return-value)
>> 
>> where `interactive-call' is an argument initialized to non-nil
>> for an interactive call.
>> 
>> The job of the second arg to `interactive', that I've proposed, would
>> be to control how to generate the message in the interactive case.

> Then the second arg to `interactive' could be just a lambda
> with one argument with the value this function returns, e.g.

Yes, and if the use of `lambda' turns out to be a bit heavy, we can
provide a handy alternative: if the return-spec is a list but not
a function, then take the list as a function call with a missing argument:

   (defun command ()
     (interactive
       nil
       (lambda (ret-val)
         (message "Result of this command is %.0f" ret-val)))
     ...
     (let ((return-value ...))
       ...
       return-value))

=>

   (defun command ()
     (interactive
       nil
       (message "Result of this command is %.0f"))
     ...
     (let ((return-value ...))
       ...
       return-value))


-- Stefan




^ permalink raw reply	[flat|nested] 167+ messages in thread

* Re: Shift selection using interactive spec
  2008-03-29 12:30                                                               ` Juri Linkov
  2008-03-29 14:07                                                                 ` David Kastrup
@ 2008-03-30  5:49                                                                 ` Richard Stallman
  1 sibling, 0 replies; 167+ messages in thread
From: Richard Stallman @ 2008-03-30  5:49 UTC (permalink / raw)
  To: Juri Linkov; +Cc: lennart.borgman, jared, emacs-devel

    And it would be very confusing to set a default behavior using
    interactive codes, but allow to modify it using properties.
    The source of this confusion is non-obvious interaction between two ways
    of doing the same thing.

The preferred way to specify this should be with `interactive',
but we could also have properties for the sake of "patching"
libraries that were released separately and not written
with this in mind.





^ permalink raw reply	[flat|nested] 167+ messages in thread

* Re: Shift selection using interactive spec
  2008-03-30  0:48                                                               ` Juri Linkov
@ 2008-03-30 17:55                                                                 ` David Kastrup
  2008-03-30 18:55                                                                   ` Juri Linkov
  0 siblings, 1 reply; 167+ messages in thread
From: David Kastrup @ 2008-03-30 17:55 UTC (permalink / raw)
  To: Juri Linkov
  Cc: M Jared Finder, Chong Yidong, lennart.borgman, rms, emacs-devel

Juri Linkov <juri@jurta.org> writes:

>> If the functionality is as annoying when being switched on as to warrant
>> per-function fine-tuning, we should tone down the obnoxious parts.
>>
>> Do you have an example for a function which should by default obey
>> shift-selection, but where a user would rather have it turned off?
>
> We have an infinite set of examples where a user would have it turned
> ON.

I recommend you look up the definition of "infinite" in a dictionary of
your choice.

Anyway, that does not count, since we are going to turn on this
functionality for all functions inside of Emacs where it makes sense.

So the question is whether there exists a reason for a user to turn it
off for any of the functions getting the interactive call/spec from us.
If there isn't, there is no need to provide an "easy" way beside the
proper one to fudge something on/off.

-- 
David Kastrup, Kriemhildstr. 15, 44793 Bochum




^ permalink raw reply	[flat|nested] 167+ messages in thread

* Re: Shift selection using interactive spec
  2008-03-30  0:52                                                                   ` Juri Linkov
@ 2008-03-30 17:56                                                                     ` David Kastrup
  0 siblings, 0 replies; 167+ messages in thread
From: David Kastrup @ 2008-03-30 17:56 UTC (permalink / raw)
  To: Juri Linkov; +Cc: lennart.borgman, jared, rms, emacs-devel

Juri Linkov <juri@jurta.org> writes:

>>> Shift-selection is not an inherent part of function definition since a
>>> function can normally work with or without this feature either way.
>>
>> How is this different from any interactive call specification?  In
>> particular, from, say, the "*" flag in an interactive call string?
>
> If is known beforehand that a command can't work on read-only buffers.
> But shift-selection can be freely turned on/off.

Again: can you provide an example where it makes sense for a user to
turn it off selectively?

We don't need to bother about hypothetical functionality for which there
is no real use case.

-- 
David Kastrup, Kriemhildstr. 15, 44793 Bochum




^ permalink raw reply	[flat|nested] 167+ messages in thread

* Re: Shift selection using interactive spec
  2008-03-30  4:12                                                                 ` Stefan Monnier
@ 2008-03-30 18:33                                                                   ` Juri Linkov
  2008-03-31 16:24                                                                     ` Richard Stallman
  0 siblings, 1 reply; 167+ messages in thread
From: Juri Linkov @ 2008-03-30 18:33 UTC (permalink / raw)
  To: Stefan Monnier; +Cc: lennart.borgman, jared, rms, emacs-devel

>> Then the second arg to `interactive' could be just a lambda
>> with one argument with the value this function returns, e.g.
>
> Yes, and if the use of `lambda' turns out to be a bit heavy, we can
> provide a handy alternative: if the return-spec is a list but not
> a function, then take the list as a function call with a missing argument:
>
>    (defun command ()
>      (interactive
>        nil
>        (lambda (ret-val)
>          (message "Result of this command is %.0f" ret-val)))
>      ...
>      (let ((return-value ...))
>        ...
>        return-value))
>
> =>
>
>    (defun command ()
>      (interactive
>        nil
>        (message "Result of this command is %.0f"))
>      ...
>      (let ((return-value ...))
>        ...
>        return-value))

And then another simplest alternative we could provide is t when the
return value should be displayed with just `(message "%s" ret-val)':

   (defun command ()
     (interactive
       nil
       t)
     ...
     (let ((return-value ...))
       ...
       return-value))

-- 
Juri Linkov
http://www.jurta.org/emacs/




^ permalink raw reply	[flat|nested] 167+ messages in thread

* Re: Shift selection using interactive spec
  2008-03-30 17:55                                                                 ` David Kastrup
@ 2008-03-30 18:55                                                                   ` Juri Linkov
  0 siblings, 0 replies; 167+ messages in thread
From: Juri Linkov @ 2008-03-30 18:55 UTC (permalink / raw)
  To: David Kastrup
  Cc: M Jared Finder, Chong Yidong, lennart.borgman, rms, emacs-devel

>>> If the functionality is as annoying when being switched on as to warrant
>>> per-function fine-tuning, we should tone down the obnoxious parts.
>>>
>>> Do you have an example for a function which should by default obey
>>> shift-selection, but where a user would rather have it turned off?
>>
>> We have an infinite set of examples where a user would have it turned
>> ON.
>
> I recommend you look up the definition of "infinite" in a dictionary of
> your choice.

  infinite
   adj.
     [common] Consisting of a large number of objects; extreme. Used very
     loosely as in: "This program produces infinite garbage." "He is an
     infinite loser." The word most likely to follow infinite, though, is
     hair. (It has been pointed out that fractals are an excellent
     example of infinite hair.) These uses are abuses of the word's
     mathematical meaning. The term semi-infinite, denoting an immoderately
     large amount of some resource, is also heard. "This compiler is taking
     a semi-infinite amount of time to optimize my program." See also
     semi.

  From Jargon File (4.4.4, 14 Aug 2003)

-- 
Juri Linkov
http://www.jurta.org/emacs/




^ permalink raw reply	[flat|nested] 167+ messages in thread

* Re: Shift selection using interactive spec
  2008-03-30  1:05                                                               ` Juri Linkov
  2008-03-30  4:12                                                                 ` Stefan Monnier
@ 2008-03-30 19:56                                                                 ` Richard Stallman
  2008-03-30 22:46                                                                   ` Juri Linkov
  1 sibling, 1 reply; 167+ messages in thread
From: Richard Stallman @ 2008-03-30 19:56 UTC (permalink / raw)
  To: Juri Linkov; +Cc: jared, lennart.borgman, emacs-devel

    Then the second arg to `interactive' could be just a lambda
    with one argument with the value this function returns, e.g.

I guess that is the best design option, for when you want to use
a Lisp expression.  But the simple case should be a string -- perhaps
a format string.

Stefan wrote:

    Yes, and if the use of `lambda' turns out to be a bit heavy, we can
    provide a handy alternative: if the return-spec is a list but not
    a function, then take the list as a function call with a missing argument:

I don't like that idea, because an incomplete form like this
seems like too fundamental a change in the Lisp way of doing things.




^ permalink raw reply	[flat|nested] 167+ messages in thread

* Re: Shift selection using interactive spec
  2008-03-30 19:56                                                                 ` Richard Stallman
@ 2008-03-30 22:46                                                                   ` Juri Linkov
  0 siblings, 0 replies; 167+ messages in thread
From: Juri Linkov @ 2008-03-30 22:46 UTC (permalink / raw)
  To: rms; +Cc: jared, lennart.borgman, emacs-devel

>     Then the second arg to `interactive' could be just a lambda
>     with one argument with the value this function returns, e.g.
>
> I guess that is the best design option, for when you want to use
> a Lisp expression.  But the simple case should be a string -- perhaps
> a format string.

Then in case of using a format string my suggestion for using t is
not necessary, because it would be easy to specify this with just "%s":

   (defun command ()
     (interactive
       nil
       "%s")
     ...
     (let ((return-value ...))
       ...
       return-value))

-- 
Juri Linkov
http://www.jurta.org/emacs/




^ permalink raw reply	[flat|nested] 167+ messages in thread

* Re: Shift selection using interactive spec
  2008-03-30 18:33                                                                   ` Juri Linkov
@ 2008-03-31 16:24                                                                     ` Richard Stallman
  0 siblings, 0 replies; 167+ messages in thread
From: Richard Stallman @ 2008-03-31 16:24 UTC (permalink / raw)
  To: Juri Linkov; +Cc: lennart.borgman, jared, monnier, emacs-devel

    And then another simplest alternative we could provide is t when the
    return value should be displayed with just `(message "%s" ret-val)':

There's no harm in that, but usually the command should add some text
around the return value.  So I think use of t would be rather rare.
Using a format string would be the more common case.

What I am not sure of is whether the existing format string feature
is powerful enough for most of the real cases.




^ permalink raw reply	[flat|nested] 167+ messages in thread

end of thread, other threads:[~2008-03-31 16:24 UTC | newest]

Thread overview: 167+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2008-03-13 23:29 Shift selection using interactive spec Chong Yidong
2008-03-14  0:44 ` Thomas Lord
2008-03-14  0:10   ` David Kastrup
2008-03-14  1:22     ` Thomas Lord
2008-03-14  9:46       ` David Kastrup
2008-03-14 10:01         ` Johan Bockgård
2008-03-14 10:30           ` David Kastrup
2008-03-14 11:18           ` Thomas Lord
2008-03-14 11:11         ` Thomas Lord
2008-03-14 10:42           ` David Kastrup
2008-03-14 11:36             ` Thomas Lord
2008-03-14 11:50             ` Thomas Lord
2008-03-14 11:39               ` David Kastrup
2008-03-14 18:41                 ` Thomas Lord
2008-03-14  4:06 ` Dan Nicolaescu
2008-03-14 14:26   ` Kim F. Storm
2008-03-14 14:32     ` Chong Yidong
2008-03-14 14:53       ` Kim F. Storm
2008-03-14 16:19         ` David Kastrup
2008-03-14 15:54       ` Stefan Monnier
2008-03-14 16:09         ` Drew Adams
2008-03-14 20:52         ` Chong Yidong
2008-03-14 20:59           ` David Kastrup
2008-03-14 21:08             ` Chong Yidong
2008-03-15  0:56           ` Stefan Monnier
2008-03-15  2:02             ` Chong Yidong
2008-03-15  3:31               ` Stefan Monnier
2008-03-15 14:07                 ` Chong Yidong
2008-03-15 15:07                   ` Stefan Monnier
2008-03-15 17:11                     ` Chong Yidong
2008-03-15 20:52                       ` Stefan Monnier
2008-03-15 21:45                         ` Thomas Lord
2008-03-16 14:15                           ` Chong Yidong
2008-03-16 14:37                             ` Lennart Borgman (gmail)
2008-03-15 22:01                         ` shift-select harmony Thomas Lord
2008-03-15 23:38                           ` Thomas Lord
2008-03-15 17:16                   ` Shift selection using interactive spec Kim F. Storm
2008-03-15 20:59                     ` Thomas Lord
2008-03-16 23:31                       ` Alan Mackenzie
2008-03-15 21:08                     ` Thomas Lord
2008-03-16  0:27                       ` Chong Yidong
2008-03-16  1:37                         ` Thomas Lord
2008-03-16  9:09                           ` Mathias Dahl
2008-03-16 14:21                             ` Chong Yidong
2008-03-16 16:56                               ` Thomas Lord
2008-03-16 16:34                             ` Dear lazyweb (Re: Shift selection using interactive spec) Thomas Lord
2008-03-16 18:40                           ` Shift selection using interactive spec Stefan Monnier
2008-03-16 21:00                             ` Thomas Lord
2008-03-16 20:45                               ` Thien-Thi Nguyen
2008-03-16 21:46                                 ` Thomas Lord
2008-03-16 21:24                                   ` Thien-Thi Nguyen
2008-03-16 22:27                                     ` Thomas Lord
2008-03-16 23:04                               ` Lennart Borgman (gmail)
2008-03-16 23:17                                 ` Lennart Borgman (gmail)
2008-03-17  0:46                                 ` Thomas Lord
2008-03-17  0:21                                   ` Lennart Borgman (gmail)
2008-03-17  1:16                                     ` Thomas Lord
2008-03-16 23:35                               ` Stephen J. Turnbull
2008-03-17  0:55                                 ` Thomas Lord
2008-03-17  2:23                                   ` Stefan Monnier
2008-03-17  3:12                                     ` Thomas Lord
2008-03-17  2:21                               ` Stefan Monnier
2008-03-17  3:47                                 ` what's the point (re shift selection) Thomas Lord
2008-03-16 14:40                     ` Shift selection using interactive spec Chong Yidong
2008-03-16 15:04                       ` Lennart Borgman (gmail)
2008-03-16 17:13                         ` Thomas Lord
2008-03-17  0:54                       ` Chong Yidong
2008-03-17  2:40                         ` Stefan Monnier
2008-03-17  3:24                           ` Chong Yidong
2008-03-17 13:26                             ` Stefan Monnier
2008-03-17 16:33                               ` Chong Yidong
2008-03-17 17:21                                 ` Lennart Borgman (gmail)
2008-03-17 19:11                                 ` Stefan Monnier
2008-03-17 21:10                                   ` Chong Yidong
2008-03-17 21:44                                     ` Drew Adams
2008-03-18 11:40                                     ` Kim F. Storm
2008-03-18 14:16                                       ` Chong Yidong
2008-03-18 15:07                                         ` Kim F. Storm
2008-03-18 16:24                                       ` Stefan Monnier
2008-03-18 17:54                                         ` Drew Adams
2008-03-20  5:03                                   ` Chong Yidong
2008-03-23  1:39                                     ` Stefan Monnier
2008-03-17 22:24                                 ` martin rudalics
2008-03-17 22:37                                   ` Lennart Borgman (gmail)
2008-03-18  0:50                                     ` Thomas Lord
2008-03-18  7:48                                       ` martin rudalics
2008-03-18 17:46                                         ` Thomas Lord
2008-03-18 17:36                                           ` Lennart Borgman (gmail)
2008-03-18 19:07                                             ` Thomas Lord
2008-03-18  7:48                                     ` martin rudalics
2008-03-17 22:53                                   ` Chong Yidong
2008-03-18  3:12                                   ` Stefan Monnier
2008-03-18  7:49                                     ` martin rudalics
2008-03-18 16:36                                       ` Stefan Monnier
2008-03-18 16:44                                         ` Lennart Borgman (gmail)
2008-03-18 14:45                               ` Chong Yidong
2008-03-18 16:39                                 ` Stefan Monnier
2008-03-18 18:28                                   ` Chong Yidong
2008-03-18 21:42                                     ` Stefan Monnier
2008-03-18 22:30                                       ` Kim F. Storm
2008-03-18 22:39                                         ` Lennart Borgman (gmail)
2008-03-19  4:40                                         ` M Jared Finder
2008-03-26  8:09                                           ` David Kastrup
2008-03-26 10:48                                             ` Juri Linkov
2008-03-26 11:32                                               ` David Kastrup
2008-03-26 11:39                                                 ` Juri Linkov
2008-03-26 12:20                                                   ` David Kastrup
2008-03-26 13:14                                                     ` Johan Bockgård
2008-03-26 13:26                                                       ` David Kastrup
2008-03-26 14:52                                                     ` Stefan Monnier
2008-03-27  0:46                                                     ` Juri Linkov
2008-03-26 12:02                                                 ` Lennart Borgman (gmail)
2008-03-26 11:47                                               ` Lennart Borgman (gmail)
2008-03-26 22:26                                                 ` Richard Stallman
2008-03-26 23:31                                                   ` Lennart Borgman (gmail)
2008-03-27  7:02                                                     ` David Kastrup
2008-03-27  8:19                                                       ` Lennart Borgman (gmail)
2008-03-27  8:41                                                         ` David Kastrup
2008-03-27 13:57                                                           ` Lennart Borgman (gmail)
2008-03-27 14:39                                                             ` David Kastrup
2008-03-27 15:01                                                               ` Juanma Barranquero
2008-03-27 15:34                                                                 ` David Kastrup
2008-03-27 15:41                                                                   ` Juanma Barranquero
2008-03-27 15:13                                                               ` Johan Bockgård
2008-03-27 19:41                                                     ` Richard Stallman
2008-03-27 23:52                                                       ` Juri Linkov
2008-03-28  7:33                                                         ` David Kastrup
2008-03-29  0:47                                                           ` Juri Linkov
2008-03-29  7:03                                                             ` David Kastrup
2008-03-29 11:53                                                               ` Lennart Borgman (gmail)
2008-03-29 12:30                                                               ` Juri Linkov
2008-03-29 14:07                                                                 ` David Kastrup
2008-03-29 14:45                                                                   ` Lennart Borgman (gmail)
2008-03-29 15:09                                                                     ` David Kastrup
2008-03-29 15:30                                                                       ` Lennart Borgman (gmail)
2008-03-30  0:52                                                                   ` Juri Linkov
2008-03-30 17:56                                                                     ` David Kastrup
2008-03-30  5:49                                                                 ` Richard Stallman
2008-03-28  4:05                                                       ` M Jared Finder
2008-03-28 11:10                                                         ` David Kastrup
2008-03-28 17:14                                                           ` Lennart Borgman (gmail)
2008-03-28 20:05                                                             ` David Kastrup
2008-03-28 23:49                                                               ` Lennart Borgman (gmail)
2008-03-28 20:42                                                         ` Richard Stallman
2008-03-28 21:47                                                           ` Chong Yidong
2008-03-28 22:01                                                             ` David Kastrup
2008-03-30  0:48                                                               ` Juri Linkov
2008-03-30 17:55                                                                 ` David Kastrup
2008-03-30 18:55                                                                   ` Juri Linkov
2008-03-27  0:49                                                   ` Juri Linkov
2008-03-27  2:59                                                     ` Chong Yidong
2008-03-27 19:41                                                     ` Richard Stallman
2008-03-27 23:48                                                       ` Juri Linkov
2008-03-28 20:41                                                         ` Richard Stallman
2008-03-29  0:54                                                           ` Juri Linkov
2008-03-29  1:15                                                             ` Lennart Borgman (gmail)
2008-03-29 16:37                                                             ` Richard Stallman
2008-03-30  1:05                                                               ` Juri Linkov
2008-03-30  4:12                                                                 ` Stefan Monnier
2008-03-30 18:33                                                                   ` Juri Linkov
2008-03-31 16:24                                                                     ` Richard Stallman
2008-03-30 19:56                                                                 ` Richard Stallman
2008-03-30 22:46                                                                   ` Juri Linkov
2008-03-26 22:26                                               ` Richard Stallman
2008-03-18 17:45                                 ` Thomas Lord
2008-03-16  2:33                 ` Richard Stallman
  -- strict thread matches above, loose matches on Subject: below --
2008-03-16 12:58 Robert J. Chassell

Code repositories for project(s) associated with this public inbox

	https://git.savannah.gnu.org/cgit/emacs.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).