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