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; 166+ 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] 166+ messages in thread

end of thread, other threads:[~2008-03-31 16:24 UTC | newest]

Thread overview: 166+ 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

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).