* [PATCH] Make `C-x {' and `C-x }' repeatable @ 2013-05-20 19:59 Gauthier Östervall 2013-05-21 9:58 ` Vitalie Spinu ` (2 more replies) 0 siblings, 3 replies; 51+ messages in thread From: Gauthier Östervall @ 2013-05-20 19:59 UTC (permalink / raw) To: emacs-devel Ever since I started using emacs and tried to say good bye to my mouse, I have felt that the resizing of windows with `C-x }' and `C-x {' is too cumbersome to use. - Typing `C-x }' several times in a row is not practical. - I always undershoot when using things of the form `M-10 C-x }' - I alway overshoot when using `C-x } C-x zzzzz' This branch makes `C-x {' and `C-x }' behave similarly to `C-x C-+' (text-scale-adjust). After the original `C-x }' (or `C-x {'), additional `{' and `}' continue to resize the window, until the user enters another character. The change is in lisp/window.el, which has dynamic scoping. I understand that this new function would be better with lexical binding, allowing for a clean closure. However I do not feel confident enough (yet) with dynamic scoping to change the file's binding mode by myself. Please tell me if I should have done that differently, and I'll try to implement it. I'd be happy to see window.el get lexical binding, and use a closure instead of a macro. If the patch is acceptable as is, it would be very nice to see it integrated. Note that this is my first patch to GNU Emacs and with bzr. I might for example have missed indentation conventions (no tabs in the new function, only spaces), but I could not find info about tabbing conventions on the wiki or gnu.org (a link would be welcome, if available). Please guide me if I missed other standard things. https://code.launchpad.net/~gauthier-i/emacs/resize-window-repeat lp:~gauthier-i/emacs/resize-window-repeat Launchpad says that the branch is "Updating" and "empty", and has been saying so for days. Weeks, really. The code seems to be there though. Tell me if it's not reachable for you, and if you have suggestions for how to fix it, it'd be nice. Otherwise, here's the bundle: # Bazaar merge directive format 2 (Bazaar 0.90) # revision_id: gauthier@ostervall.se-20130520193632-fm01gjdl38ux3egc # target_branch: file:///media/sf_prog/emacs/trunk/ # testament_sha1: 6d88925597179e2c8c55153d5f9c62703d6ecd68 # timestamp: 2013-05-20 21:51:05 +0200 # base_revision_id: rgm@gnu.org-20130430101735-ccy06l3ndx4vrj18 # # Begin patch === modified file 'lisp/ChangeLog' (properties changed: -x to +x) --- lisp/ChangeLog 2013-04-29 20:09:18 +0000 +++ lisp/ChangeLog 2013-05-20 19:36:32 +0000 @@ -1,3 +1,7 @@ +2013-05-20 Gauthier Ostervall <gauthier@ostervall.se> + + * window.el (window-size-adjust): New function. + 2013-04-29 Leo Liu <sdl.web@gmail.com> * progmodes/octave.el (octave-font-lock-keywords): Handle 'end' in === modified file 'lisp/window.el' (properties changed: -x to +x) --- lisp/window.el 2013-04-13 14:37:20 +0000 +++ lisp/window.el 2013-05-07 12:13:36 +0000 @@ -6025,6 +6025,48 @@ (interactive "p") (shrink-window delta t)) +;;;###autoload (define-key ctl-x-map [(?{)] 'window-size-adjust) +;;;###autoload (define-key ctl-x-map [(?})] 'window-size-adjust) +;;;###autoload +(defun window-size-adjust (inc) + "Adjust the width or height of the current window by INC. + +INC may be passed as a numeric prefix argument. + +The actual adjustment made depends on the final component of the +key-binding used to invoke the command, with all modifiers removed: + + { Decrease the window width by one step + } Increase the window width by one step + +When adjusting with `{' or `}', continue to read input events and +further adjust the windows width as long as the input event read +\(with all modifiers removed) is `{' or `}'. + +This command is a special-purpose wrapper around the +`enlarge-window-horizontally' command which makes repetition convenient +even when it is bound in a non-top-level keymap. For binding in +a top-level keymap, `enlarge-window-horzontally' or +`shrink-window-horizontally' may be more appropriate." + (interactive "p") + (let ((ev last-command-event) + (echo-keystrokes nil)) + (let* ((base (event-basic-type ev)) + (step + (pcase base + (?{ (- inc)) + (?} inc) + (t inc)))) + (enlarge-window-horizontally step) + (message "Use {,} for further adjustment") + (set-temporary-overlay-map + (let ((map (make-sparse-keymap))) + (dolist (mods '(())) + (dolist (key '(?{ ?})) + (define-key map (vector (append mods (list key))) + `(lambda () (interactive) (window-size-adjust (abs ,inc)))))) + map))))) + (defun count-screen-lines (&optional beg end count-final-newline window) "Return the number of screen lines in the region. The number of screen lines may be different from the number of actual lines, @@ -6734,8 +6776,8 @@ (define-key ctl-x-map "3" 'split-window-right) (define-key ctl-x-map "o" 'other-window) (define-key ctl-x-map "^" 'enlarge-window) -(define-key ctl-x-map "}" 'enlarge-window-horizontally) -(define-key ctl-x-map "{" 'shrink-window-horizontally) +(define-key ctl-x-map "}" 'window-size-adjust) +(define-key ctl-x-map "{" 'window-size-adjust) (define-key ctl-x-map "-" 'shrink-window-if-larger-than-buffer) (define-key ctl-x-map "+" 'balance-windows) (define-key ctl-x-4-map "0" 'kill-buffer-and-window) # Begin bundle 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 ^ permalink raw reply [flat|nested] 51+ messages in thread
* Re: [PATCH] Make `C-x {' and `C-x }' repeatable 2013-05-20 19:59 [PATCH] Make `C-x {' and `C-x }' repeatable Gauthier Östervall @ 2013-05-21 9:58 ` Vitalie Spinu 2013-05-21 13:53 ` Gauthier Östervall 2013-05-21 18:34 ` Juri Linkov 2013-05-22 19:05 ` Stefan Monnier 2 siblings, 1 reply; 51+ messages in thread From: Vitalie Spinu @ 2013-05-21 9:58 UTC (permalink / raw) To: Gauthier Östervall; +Cc: emacs-devel I think this is a very nice idea. Similar change would make sense for C-x ^. Vitalie >> Gauthier Östervall <gauthier@ostervall.se> >> on Mon, 20 May 2013 21:59:06 +0200 wrote: > Ever since I started using emacs and tried to say good bye to my > mouse, I have felt that the resizing of windows with `C-x }' and > `C-x {' is too cumbersome to use. > - Typing `C-x }' several times in a row is not practical. > - I always undershoot when using things of the form `M-10 C-x }' > - I alway overshoot when using `C-x } C-x zzzzz' > This branch makes `C-x {' and `C-x }' behave similarly to `C-x > C-+' (text-scale-adjust). After the original `C-x }' (or `C-x > {'), additional `{' and `}' continue to resize the window, until > the user enters another character. > The change is in lisp/window.el, which has dynamic scoping. I > understand that this new function would be better with lexical > binding, allowing for a clean closure. However I do not feel > confident enough (yet) with dynamic scoping to change the file's > binding mode by myself. > Please tell me if I should have done that differently, and I'll > try to implement it. I'd be happy to see window.el get lexical > binding, and use a closure instead of a macro. If the patch is > acceptable as is, it would be very nice to see it integrated. > Note that this is my first patch to GNU Emacs and with bzr. I > might for example have missed indentation conventions (no tabs in > the new function, only spaces), but I could not find info about > tabbing conventions on the wiki or gnu.org (a link would be > welcome, if available). Please guide me if I missed other > standard things. > https://code.launchpad.net/~gauthier-i/emacs/resize-window-repeatlp:~gauthier-i/emacs/resize-window-repeat > Launchpad says that the branch is "Updating" and "empty", and has > been saying so for days. Weeks, really. The code seems to be > there though. Tell me if it's not reachable for you, and if you > have suggestions for how to fix it, it'd be nice. > Otherwise, here's the bundle: > # Bazaar merge directive format 2 (Bazaar 0.90) > # revision_id: gauthier@ostervall.se-20130520193632-fm01gjdl38ux3egc > # target_branch: file:///media/sf_prog/emacs/trunk/ > # testament_sha1: 6d88925597179e2c8c55153d5f9c62703d6ecd68 > # timestamp: 2013-05-20 21:51:05 +0200 > # base_revision_id: rgm@gnu.org-20130430101735-ccy06l3ndx4vrj18 > # > # Begin patch > === modified file 'lisp/ChangeLog' (properties changed: -x to +x) > --- lisp/ChangeLog 2013-04-29 20:09:18 +0000 > +++ lisp/ChangeLog 2013-05-20 19:36:32 +0000 > @@ -1,3 +1,7 @@ > +2013-05-20 Gauthier Ostervall <gauthier@ostervall.se> > + > + * window.el (window-size-adjust): New function. > + > 2013-04-29 Leo Liu <sdl.web@gmail.com> > * progmodes/octave.el (octave-font-lock-keywords): Handle 'end' in > === modified file 'lisp/window.el' (properties changed: -x to +x) > --- lisp/window.el 2013-04-13 14:37:20 +0000 > +++ lisp/window.el 2013-05-07 12:13:36 +0000 > @@ -6025,6 +6025,48 @@ > (interactive "p") > (shrink-window delta t)) > +;;;###autoload (define-key ctl-x-map [(?{)] 'window-size-adjust) > +;;;###autoload (define-key ctl-x-map [(?})] 'window-size-adjust) > +;;;###autoload > +(defun window-size-adjust (inc) > + "Adjust the width or height of the current window by INC. > + > +INC may be passed as a numeric prefix argument. > + > +The actual adjustment made depends on the final component of the > +key-binding used to invoke the command, with all modifiers removed: > + > + { Decrease the window width by one step > + } Increase the window width by one step > + > +When adjusting with `{' or `}', continue to read input events and > +further adjust the windows width as long as the input event read > +\(with all modifiers removed) is `{' or `}'. > + > +This command is a special-purpose wrapper around the > +`enlarge-window-horizontally' command which makes repetition convenient > +even when it is bound in a non-top-level keymap. For binding in > +a top-level keymap, `enlarge-window-horzontally' or > +`shrink-window-horizontally' may be more appropriate." > + (interactive "p") > + (let ((ev last-command-event) > + (echo-keystrokes nil)) > + (let* ((base (event-basic-type ev)) > + (step > + (pcase base > + (?{ (- inc)) > + (?} inc) > + (t inc)))) > + (enlarge-window-horizontally step) > + (message "Use {,} for further adjustment") > + (set-temporary-overlay-map > + (let ((map (make-sparse-keymap))) > + (dolist (mods '(())) > + (dolist (key '(?{ ?})) > + (define-key map (vector (append mods (list key))) > + `(lambda () (interactive) (window-size-adjust (abs ,inc)))))) > + map))))) > + > (defun count-screen-lines (&optional beg end count-final-newline window) > "Return the number of screen lines in the region. > The number of screen lines may be different from the number of actual lines, > @@ -6734,8 +6776,8 @@ > (define-key ctl-x-map "3" 'split-window-right) > (define-key ctl-x-map "o" 'other-window) > (define-key ctl-x-map "^" 'enlarge-window) > -(define-key ctl-x-map "}" 'enlarge-window-horizontally) > -(define-key ctl-x-map "{" 'shrink-window-horizontally) > +(define-key ctl-x-map "}" 'window-size-adjust) > +(define-key ctl-x-map "{" 'window-size-adjust) > (define-key ctl-x-map "-" 'shrink-window-if-larger-than-buffer) > (define-key ctl-x-map "+" 'balance-windows) > (define-key ctl-x-4-map "0" 'kill-buffer-and-window) > # Begin bundle > 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 ^ permalink raw reply [flat|nested] 51+ messages in thread
* Re: [PATCH] Make `C-x {' and `C-x }' repeatable 2013-05-21 9:58 ` Vitalie Spinu @ 2013-05-21 13:53 ` Gauthier Östervall 0 siblings, 0 replies; 51+ messages in thread From: Gauthier Östervall @ 2013-05-21 13:53 UTC (permalink / raw) To: Vitalie Spinu, emacs-devel On Tue, May 21, 2013 at 11:58 AM, Vitalie Spinu <spinuvit@gmail.com> wrote: > > I think this is a very nice idea. Similar change would make sense for > C-x ^. > It would. It could even work after entering with C-x {, and { could work after entering with C-x ^. For example: C-x { { { { } } ^ ^ } C-x ^ ^ } } could be valid sequences. One problem is that there is currently no standard key binding for (shrink-window). That would need to be decided upon first. Having (enlarge-window) and not its opposite would not work well. Even more, + (balance-windows) could be included (and possibly exit this resize mode). Same thing with - (shrink-window-if-larger-than-buffer). I'm willing to implement (balance-windows) as a second step if this patch is accepted. I nearly never `C-x -' or `C-x ^', but I could put it in once there is an opposite to `C-x ^', for completeness. How are standard key bindings decided upon, may I just come up with something? ^ permalink raw reply [flat|nested] 51+ messages in thread
* Re: [PATCH] Make `C-x {' and `C-x }' repeatable 2013-05-20 19:59 [PATCH] Make `C-x {' and `C-x }' repeatable Gauthier Östervall 2013-05-21 9:58 ` Vitalie Spinu @ 2013-05-21 18:34 ` Juri Linkov 2013-05-22 17:44 ` Drew Adams 2013-05-22 19:05 ` Stefan Monnier 2 siblings, 1 reply; 51+ messages in thread From: Juri Linkov @ 2013-05-21 18:34 UTC (permalink / raw) To: Gauthier Östervall; +Cc: emacs-devel > Ever since I started using emacs and tried to say good bye to my > mouse, I have felt that the resizing of windows with `C-x }' and > `C-x {' is too cumbersome to use. Thanks for this useful feature. I am experiencing the same difficulties with `C-x }' and `C-x {', so your feature would be of a great help. > Please tell me if I should have done that differently, and I'll > try to implement it. Please make the keymap user-customizable, e.g. if you'll create a separate keymap with a name like `window-size-adjust-keymap' then users would be able to add more keybindings in ~/.emacs like: (define-key window-size-adjust-keymap [right] 'enlarge-window-horizontally) (define-key window-size-adjust-keymap [left] 'shrink-window-horizontally) (define-key window-size-adjust-keymap [down] 'enlarge-window) (define-key window-size-adjust-keymap [up] 'shrink-window) to use arrow keys for window resizing. Then having such map you could just add one line: (set-temporary-overlay-map window-size-adjust-keymap) to the end of all these four functions to implement this feature. I mean changing existing commands: (defun shrink-window-horizontally (delta) (interactive "p") (shrink-window delta t)) to (defun shrink-window-horizontally (delta) (interactive "p") (shrink-window delta t) (set-temporary-overlay-map window-size-adjust-keymap)) and the feature will just work without creating a "dispatcher" kind of function `window-size-adjust'. This will preserve the current global keybindings (i.e. `shrink-window-horizontally' still bound to `C-x {' etc.) and provide more customizability. Then remaining possible improvements would be adding an option to disable this feature (I think it should be enabled by default), adding an informative echo-area message about available keybindings, adding a keybinding (like `RET' in `isearch-mode') to exit a keysequence of resizing keys, etc. > One problem is that there is currently no standard key binding for > (shrink-window). It's very difficult to find a free global keybinding for such less frequently used commands. But there is no need because users could use the existing global keybindings to initiate a window-resizing keysequence and use other keys from the map for more fine-grained resizing. ^ permalink raw reply [flat|nested] 51+ messages in thread
* RE: [PATCH] Make `C-x {' and `C-x }' repeatable 2013-05-21 18:34 ` Juri Linkov @ 2013-05-22 17:44 ` Drew Adams 2013-05-22 18:55 ` Juri Linkov 0 siblings, 1 reply; 51+ messages in thread From: Drew Adams @ 2013-05-22 17:44 UTC (permalink / raw) To: Juri Linkov, Gauthier Östervall; +Cc: emacs-devel Juri's suggestion is a good one. There is another way to do this (which I have mentioned before): ;; Needs library `repeat.el'. Either autoload it or add (require 'repeat) ;; to a command that needs it. ;;;### (autoload 'repeat-command "repeat" t nil) (defun repeat-command (command) ; To be added to `repeat.el'. "Repeat COMMAND." (let ((repeat-message-function 'ignore)) (setq last-repeatable-command command) (repeat nil))) You can then make a repeatable command from any ordinary command. E.g., window-sizing: (defun window-widen (arg) "...." (interactive "P") (repeat-command 'enlarge-window-horizontally)) (defun window-narrow (arg) "...." (interactive "P") (repeat-command 'shrink-window-horizontally)) (defun window-heighten (arg) "...." (interactive "P") (repeat-command 'enlarge-window)) (defun window-shorten (arg) "...." (interactive "P") (repeat-command 'shrink-window)) Bind to any keys you like. E.g., replace non-repeatable cmds: (define-key ctl-x-map [(?})] 'window-widen) (define-key ctl-x-map [(?{)] 'window-narrow) (define-key ctl-x-map [(?^)] 'window-heighten) (define-key ctl-x-map [(?-)] 'window-shorten) And you can put them all on a `window-size-map' keymap, as Juri suggested: (defvar window-size-map (make-sparse-keymap) "...") (define-key window-size-map [right] 'window-widen) (define-key window-size-map [left] 'window-narrow) (define-key window-size-map [up] 'window-heighten) (define-key window-size-map [down] 'window-shorten) (global-set-key [f2] window-size-map) Juri's suggestion too, of course, does not prevent you from having separate repeatable and non-repeatable commands. E.g., (defun window-widen (arg) ; Repeatable `enlarge-window-horizontally' "...." (interactive "p") (enlarge-window-horizontally arg) (set-temporary-overlay-map window-size-map)) An advantage of Juri's suggestion over the `repeat-command' approach is that it is not just for repeating a particular command. You can easily switch from `right' to `left' or `down'. E.g., `f2 right right down down left'. With the `repeat-command' approach you cannot: it recognizes only one command; it is really about repetition. An advantage of the `repeat-command' approach over Juri's suggestion is that the prefix arg that you give at the outset is used for each repeated step. With Juri's suggestion, a prefix arg is available for only the first step. Typically you want to repeatedly increase/decrease by the same amount. You cannot even provide a separate prefix arg for each step (which would be annoying in general but might have a use in some contexts). With Juri's suggestion you can make the first use of a command use a step size of 6, but repeating it puts you back to a step size of 1. Perhaps there is a simple fix to make Juri's suggestion behave better in this respect. --- I take advantage of this thread to point out bug #14095, which I think is relevant here and which has so far gotten no response. It is a regression introduced at the same time as that of bug #122232 (which was fixed). The change that introduced both problems is the use of `set-temporary-overlay-map' (also pertinent to Juri's suggestion here). I want to have a repeatable command bound to a key on `isearch-mode-map'. E.g., I bind repeatable command `isearchp-yank-line' to `C-y C-e', so I can successively yank multiple lines into the search string. E.g., during Isearch: C-y C-e C-e C-e ... That works with the older `repeat.el' code. It is broken now because of a change to `repeat-repeat-char' so that it uses `set-temporary-overlay-map '. This is because the temporary (overlay) map is overruled by `overriding(-terminal)-local-map', which Isearch uses. I would really like to see this bug fixed. Users should be able to use repeatable keys on `isearch-mode-map'. ^ permalink raw reply [flat|nested] 51+ messages in thread
* Re: [PATCH] Make `C-x {' and `C-x }' repeatable 2013-05-22 17:44 ` Drew Adams @ 2013-05-22 18:55 ` Juri Linkov 2013-05-22 21:39 ` Drew Adams 2013-05-22 21:47 ` Stefan Monnier 0 siblings, 2 replies; 51+ messages in thread From: Juri Linkov @ 2013-05-22 18:55 UTC (permalink / raw) To: Drew Adams; +Cc: Gauthier Östervall, emacs-devel > With Juri's suggestion you can make the first use of a command use > a step size of 6, but repeating it puts you back to a step size of 1. > Perhaps there is a simple fix to make Juri's suggestion behave better > in this respect. I don't know why a prefix arg exits temporary-overlay-map. Trying to (define-key window-size-adjust-keymap [?\C-u] 'universal-argument) doesn't help to fix this. `C-u' still terminates the key sequence `C-x } } } } C-u }'. > I want to have a repeatable command bound to a key on `isearch-mode-map'. In bug#10654 I proposed a patch that implements repeatable keys for Isearch e.g. `M-s C-f C-f M-f C-f ...' Maybe a better implementation would be with the help of `set-temporary-overlay-map'. I'll try to do this for Isearch. But it seems repeat.el can't be used if there are different commands in the key sequence. ^ permalink raw reply [flat|nested] 51+ messages in thread
* RE: [PATCH] Make `C-x {' and `C-x }' repeatable 2013-05-22 18:55 ` Juri Linkov @ 2013-05-22 21:39 ` Drew Adams 2013-05-22 22:08 ` Stefan Monnier 2013-05-22 21:47 ` Stefan Monnier 1 sibling, 1 reply; 51+ messages in thread From: Drew Adams @ 2013-05-22 21:39 UTC (permalink / raw) To: Juri Linkov; +Cc: Gauthier Östervall, emacs-devel > I don't know why a prefix arg exits temporary-overlay-map. Trying to > (define-key window-size-adjust-keymap [?\C-u] 'universal-argument) > doesn't help to fix this. `C-u' still terminates the key sequence > `C-x } } } } C-u }'. Dunno. But anyway, as I said, the typical use case for repetition (at least for me) would reuse the same prefix-arg value given to the prefix key. IOW, I would typically not want to use a different prefix value for one occurrence of repetition from another. Or at least I would not want to be *obliged* to repeat the prefix arg each time I repeated the final key. And I think that is what your approach amounts to (assuming you can fix it so a prefix arg does not exit the map). It would be OK for a user to be *able* to employ a new prefix arg along the way, for a one-off final-key occurrence. But you wouldn't want to be forced to keep providing a prefix arg for each final-key repetition. > > I want to have a repeatable command bound to a key on `isearch-mode-map'. > > In bug#10654 I proposed a patch that implements repeatable keys for Isearch > e.g. `M-s C-f C-f M-f C-f ...' Yes, I saw that. Good. I would still prefer a simpler approach. You are essentially requiring each repeatable command to set variables `isearch-repeat-command' and `isearch-repeat-key'. (That might be similar to the older approach used in repeat.el - dunno.) I would prefer something simpler, using either an approach like `set-temporary-overlay-map' (which you proposed for this thread) or an approach like `repeat-command' (which I mentioned). Both of those allow for short, simple & clear command definitions. The former has the advantage that you can define the map to include a set of keys, any of which can be the repeatable final key (mix & match within the set). Of course it means creating a different map for each such set of keys. E.g., if you want several such sets on the same key prefix, but you want them to be separate - so that, e.g., you could repeat with `C-x a b c a b b' or with `C-x m m o n o o', but not with `C-x a b m a n'. And you would need to use a singleton map if you wanted a singleton final-key set. E.g, if you want to get the effect that repeat.el provides of allowing `C-x a a a a' and `C-x b b b', but not C-x a b b a, then you would need two singleton keymaps. IOW, it is good to be able to define sets of final keys that work together, repeating any of them without needing to repeat the prefix key. Code that lets you do that simply, even for the singleton set case, and preferably without needing to define multiple global vars, would be preferable. FWIW, I have all of these "yank" keys on prefix `C-y' in Isearch: `C-y C-(' `isearchp-yank-sexp-symbol-or-char' `C-y C-2' `isearch-yank-secondary' `C-y C-c' `isearchp-yank-char' `C-y C-e' `isearchp-yank-line' `C-y C-w' `isearchp-yank-word-or-char' `C-y C-y' `isearch-yank-kill' `C-y M-y' `isearch-yank-pop' 5 of those commands are repeatable. But because I use `repeat-command' to implement this, you cannot mix and match these within the same `C-y' occurrence: each is separately repeatable (e.g., `C-y C-e C-e... C-y C-w C-w' is OK, but not `C-y C-e C-e C-w C-w'). (And anyway, the repeatable Isearch commands have stopped working because of bug #14095.) > Maybe a better implementation would be with the help of > `set-temporary-overlay-map'. Only, I think, if bug #14095 gets fixed. I think it's the same problem. The problem that bug #14095 points out is that `set-temporary-overlay-map' does not work with Isearch because its map does not override the map used by Isearch. `overriding(-terminal)-local-map' (used by Isearch) overrules the temporary map used by `set-temporary-overlay-map'. > I'll try to do this for Isearch. See previous. AFAICT, it won't work to use `set-temporary-overlay-map' there, unless bug #14095 is fixed. > But it seems repeat.el can't be used if there are different commands > in the key sequence. No (i.e., correct), at least not the way I did it. I thought for a moment that perhaps one could somehow leverage a sequence value of `repeat-on-final-keystroke', to allow such behavior, but I guess not. Too bad. I guess that's only for allowing multiple "alias" keys for the *same* repeatable command (not for multiple commands intended to be used together). (And I'm not even sure how you would use that option for keys such as <right>. Any idea? I tried fiddling with option values but couldn't make it work. And why the doc speaks of "characters" instead of keys, I don't know.) ^ permalink raw reply [flat|nested] 51+ messages in thread
* Re: [PATCH] Make `C-x {' and `C-x }' repeatable 2013-05-22 21:39 ` Drew Adams @ 2013-05-22 22:08 ` Stefan Monnier 2013-05-22 23:53 ` Drew Adams 0 siblings, 1 reply; 51+ messages in thread From: Stefan Monnier @ 2013-05-22 22:08 UTC (permalink / raw) To: Drew Adams; +Cc: Juri Linkov, Gauthier Östervall, emacs-devel >> But it seems repeat.el can't be used if there are different commands >> in the key sequence. > No (i.e., correct), at least not the way I did it. Indeed. But I don't think it's a big deal: set-temporary-overlay-map makes it easy enough that you shouldn't need to use repeat.el programatically (i.e. repeat.el is only useful as an implementation of the C-x z command). Stefan ^ permalink raw reply [flat|nested] 51+ messages in thread
* RE: [PATCH] Make `C-x {' and `C-x }' repeatable 2013-05-22 22:08 ` Stefan Monnier @ 2013-05-22 23:53 ` Drew Adams 2013-05-23 0:18 ` chad 0 siblings, 1 reply; 51+ messages in thread From: Drew Adams @ 2013-05-22 23:53 UTC (permalink / raw) To: Stefan Monnier; +Cc: Juri Linkov, Gauthier Östervall, emacs-devel > >> But it seems repeat.el can't be used if there are different commands > >> in the key sequence. > > No (i.e., correct), at least not the way I did it. > > Indeed. But I don't think it's a big deal: set-temporary-overlay-map > makes it easy enough that you shouldn't need to use repeat.el > programatically (i.e. repeat.el is only useful as an implementation of > the C-x z command). Fine with me, if the things discussed (e.g., prefix arg passed to all final-key "repetitions" after the prefix key) can be worked out. I agree that, since it lets you define a group of related "repeatable" final keys for the same prefix key, the `set-temporary-overlay-map' approach is more general than what I do with `repeat-command'. But it is a little less convenient for the use case of a singleton group. One good thing might be to have an abbreviation to handle that use case. IOW, a simple way to do what one can do with `repeat-command', avoiding explicitly creating a singleton keymap. Not a big deal; it would be just a little more convenient. There is also the question (assuming a fix that would apply the prefix arg from the prefix key to each repeated final key) of whether using a prefix arg before an individual final key should affect only that key occurrence or all subsequent key hits as well. IOW, should using a prefix arg be modal for the repeated keys that follow it (until/unless you use another prefix arg), or should it apply only to the next final-key occurrence? E.g., C-2 C-x a a a C-6 a a a C-3 a a A prefix arg value of 2 should apply to each of the first 3 `a's (what `repeat-command' does that Juri's approach currently does not do). But should the prefix arg of 6 apply to just the first `a' that follows it, with the next 2 `a's getting a prefix arg value of 2? And likewise, the prefix arg of 3 apply only to the `a' that immediately follows it? Or should the prefix arg of 6 apply to the 3 `a's that follow it, and the prefix arg of 3 apply to the last two `a's? IOW, modal among final-key repetitions. ^ permalink raw reply [flat|nested] 51+ messages in thread
* Re: [PATCH] Make `C-x {' and `C-x }' repeatable 2013-05-22 23:53 ` Drew Adams @ 2013-05-23 0:18 ` chad 2013-05-23 16:19 ` Drew Adams 0 siblings, 1 reply; 51+ messages in thread From: chad @ 2013-05-23 0:18 UTC (permalink / raw) To: Drew Adams, emacs-devel@gnu.org Development On 22 May 2013, at 16:53, Drew Adams <drew.adams@oracle.com> wrote: > There is also the question (assuming a fix that would apply the prefix > arg from the prefix key to each repeated final key) of whether using a > prefix arg before an individual final key should affect only that key > occurrence or all subsequent key hits as well. I haven't tried this yet, but I imagine that I would want subsequent commands to *ignore* the prefix. For example, I would grow a window by 4 or 16, then use single keystrokes to fit more accurately from there. I do something similar to this now with a simple macro (long-since built into my fingers) that grows a window by 12. Have you perhaps tried this behavior with window-sizing commands? Did it feel more natural to always adjust the window by a large increment, or did you find that you typically adjusted it by a small increment and repeated the growth multiple times? Thanks in advance. ~Chad ^ permalink raw reply [flat|nested] 51+ messages in thread
* RE: [PATCH] Make `C-x {' and `C-x }' repeatable 2013-05-23 0:18 ` chad @ 2013-05-23 16:19 ` Drew Adams 2013-05-23 16:48 ` Stefan Monnier 0 siblings, 1 reply; 51+ messages in thread From: Drew Adams @ 2013-05-23 16:19 UTC (permalink / raw) To: chad, emacs-devel@gnu.org Development > > There is also the question (assuming a fix that would apply the prefix > > arg from the prefix key to each repeated final key) of whether using a > > prefix arg before an individual final key should affect only that key > > occurrence or all subsequent key hits as well. > > I haven't tried this yet, but I imagine that I would want subsequent > commands to *ignore* the prefix. For example, I would grow a window > by 4 or 16, then use single keystrokes to fit more accurately from > there. I do something similar to this now with a simple macro > (long-since built into my fingers) that grows a window by 12. Good point. That is indeed another use case. > Have you perhaps tried this behavior with window-sizing commands? > Did it feel more natural to always adjust the window by a large > increment, or did you find that you typically adjusted it by a small > increment and repeated the growth multiple times? I would probably prefer that the prefix arg be applied modally here. IOW, the last prefix arg be used for subsequent repetitions until I change it. That way, when and whether to change to a more or less fine-grained increment is up to me, not to some hard-coded rule. E.g., what you suggest is to always immediately revert to no prefix arg, which means an increment of one, after the first use of the sizing key. I would prefer to keep the increment as I requested it, until I change it: C-5 C-x a a a a C-2 a a a ^^^ Change to more fine-grained control here, not before. Moving a frame around is probably a better example, since window resizing by increments of a line or char at a time rarely needs repetitions with large increments. Or think of window resizing by pixel increments instead of line/column increments. You might well want to start with a large increment and switch to a smaller one when you got closer to what you wanted. But the point is that where/when you switch is based on what you see currently, not just automatically after the first key hit. There is nothing to guarantee that your first try gets you close enough to the point where you want to switch. IOW, I would give users the control interactively, not leave it up to some hard rule. And I would let the increment be modal, so users need to do less specifying of the increment to use. They should, IOW, need to specify only *changes* in the increment. ^ permalink raw reply [flat|nested] 51+ messages in thread
* Re: [PATCH] Make `C-x {' and `C-x }' repeatable 2013-05-23 16:19 ` Drew Adams @ 2013-05-23 16:48 ` Stefan Monnier 2013-05-23 19:52 ` Drew Adams 0 siblings, 1 reply; 51+ messages in thread From: Stefan Monnier @ 2013-05-23 16:48 UTC (permalink / raw) To: Drew Adams; +Cc: chad, emacs-devel@gnu.org Development > Or think of window resizing by pixel increments instead of line/column > increments. You might well want to start with a large increment and > switch to a smaller one when you got closer to what you wanted. Such situations might also just benefit from a more automatic handling, where the increment depends on how many times you repeated the same command in a short time interval. Stefan ^ permalink raw reply [flat|nested] 51+ messages in thread
* RE: [PATCH] Make `C-x {' and `C-x }' repeatable 2013-05-23 16:48 ` Stefan Monnier @ 2013-05-23 19:52 ` Drew Adams 2013-05-24 4:53 ` Stephen J. Turnbull 0 siblings, 1 reply; 51+ messages in thread From: Drew Adams @ 2013-05-23 19:52 UTC (permalink / raw) To: Stefan Monnier; +Cc: chad, emacs-devel@gnu.org Development > > Or think of window resizing by pixel increments instead of line/column > > increments. You might well want to start with a large increment and > > switch to a smaller one when you got closer to what you wanted. > > Such situations might also just benefit from a more automatic handling, > where the increment depends on how many times you repeated the same > command in a short time interval. Ugly & inconvenient, IMHO. And YAGNI. User control is better. ^ permalink raw reply [flat|nested] 51+ messages in thread
* RE: [PATCH] Make `C-x {' and `C-x }' repeatable 2013-05-23 19:52 ` Drew Adams @ 2013-05-24 4:53 ` Stephen J. Turnbull 2013-05-24 15:55 ` Drew Adams 0 siblings, 1 reply; 51+ messages in thread From: Stephen J. Turnbull @ 2013-05-24 4:53 UTC (permalink / raw) To: Drew Adams; +Cc: chad, Stefan Monnier, emacs-devel@gnu.org Development Drew Adams writes: > Ugly & inconvenient, IMHO. And YAGNI. > User control is better. Drew, there's no "Y" in "I ain't gonna need it". Now, why would some values of "Y" want it? (1) Discoverability. Auto-acceleration would likely happen to me frequently, so I'd learn it. (Maybe not learn to use it, but learn to avoid it, at least.)[1] "C-u C-u C-x } } C-3 }" is not something I would likely try on my own, nor would I find it easy to remember if I read about it in passing. Because of: (2) Consistency. I can't think of any other case where an infix key controls the behavior of a command. You wouldn't need to learn anything special to take advantage of auto-acceleration, so it's weakly consistent with the existing Emacs UI. (3) Usability. Some people, like you, can estimate pretty well whether you need C-2 or C-3. Others can't, and would need to calculate, possibly costing more time than they save. Auto- acceleration has no such cost of computation. (4) Economy. The advantage of user control is smaller than you suggest, I believe. Anything bigger than C-1 will cause you to miss the target half the time or more. Sometimes people will need to correct for overshooting, which means either starting over with the inverse command or using a negative count. And even if they undershoot they need to switch to C-1. I don't want it badly enough to write the code, but I suspect more users will find it useful than the UI you propose. Both are valid proposals and worth experimenting with. Footnotes: [1] The excluded middle of "it happens but I learn nothing" is of course the Unrealizable Ideal, because that means it's a perfect optimization of my current behavior. ^ permalink raw reply [flat|nested] 51+ messages in thread
* RE: [PATCH] Make `C-x {' and `C-x }' repeatable 2013-05-24 4:53 ` Stephen J. Turnbull @ 2013-05-24 15:55 ` Drew Adams 2013-05-24 17:00 ` Stephen J. Turnbull 0 siblings, 1 reply; 51+ messages in thread From: Drew Adams @ 2013-05-24 15:55 UTC (permalink / raw) To: Stephen J. Turnbull; +Cc: chad, Stefan Monnier, emacs-devel@gnu.org Development > (1) Discoverability. Auto-acceleration It's undefined, so far. Hard to defend or criticize something still pie-in-the-sky. But my crystal ball and experience whisper to me that "automatic" too often misses the mark and does not really DWIM. On the other hand, _direct manipulation_ is all about user control, with immediate feedback. > would likely happen to me frequently, so I'd learn it. > (Maybe not learn to use it, but learn to avoid it, at least.) Avoiding an "automatic" do-it-all solution is one way to try to deal with it. But it does not solve the problem. > "C-u C-u C-x } } C-3 }" is not something I would likely try > on my own, nor would I find it easy to remember if I read > about it in passing. No need to remember anything. The default behavior (no prefix arg) provides a fine-tuning value (e.g. an increment) of 1. And trying C-u at the outset, which is pretty simple and discoverable, quickly shows you what it does: provides a larger increment for subsequent stepping. Just stop and start again with the prefix key, if you like, to use a different increment for subsequent steps. Also obvious. And if you _happen_ to use a prefix arg also before one of the final-key occurrences... WYSIWYG - immediately. This is just a shortcut so you don't have to start again with the prefix key. Readers of the doc string or curious experimenters will quickly discover the shortcut. And others are not handicapped without the shortcut: they can just hit the prefix key again, giving it a different prefix arg to change the increment size. IOW, if you don't happen to stumble upon all the available behaviors, it's likely you'll continue using the default increment, which means fine-tuning all the time. Or you'll figure out only the initial prefix arg, so will quit after N uses and start again without a prefix arg to fine-tune. > (2) Consistency. I can't think of any other case where an infix key > controls the behavior of a command. There is no "infix" key anywhere here. There are just keys, bound to various commands. And each key accepts a prefix arg and does something with it. The only thing different from usual here is that the default value of the prefix arg is the last used prefix arg, instead of 1. And that is already what we do for C-x C-(+|-), except that we don't let you change the prefix arg along the way. The arg you use initially continues to be used for each subsequent step. We do NOT revert you to the default increment size for steps after the first. You continue to increment/decrement using the same increment size for all steps. That's the approach I recommend. With the added feature that you can, if you like, change the increment on the fly, without having to start over with the prefix key. > (3) Usability. Some people, like you, can estimate pretty well > whether you need C-2 or C-3. Others can't, and would need to > calculate, possibly costing more time than they save. Auto- > acceleration has no such cost of computation. No, you miss the point. This is direct manipulation. Typically each such resizing, moving, etc. command/key has its opposite: `right' cancels `left' etc. Overshoot? Just come back. Come back less or more, as needed. There is nothing to "estimate". Just do it and see immediately the effect, adjusting on the fly as needed. This is typical of any command that is repeatable and provides incremental adjustment. A different but similar approach is used in DoReMi, which lets you incrementally change all kinds of things. There, instead of a prefix arg, there is a default increment size, and using the `Meta' key with the usual incrementing keys (e.g. `up', `down', `left', `right') boosts the default increment by a factor. So if you want to move your frame quickly across the screen then you hold down `M-' while you hold down `right'. If you want to slow down you release `M-'. If you go too far then you use `left' to come back. Simple, even obvious. The point is that it is trivial to "discover" how to incrementally adjust something, including taking advantage, when you want to, of any scaling/boosting/accelerating. This is no more difficult to "learn" or discover than sliding a scroll-bar thumb with your mouse pointer. > (4) Economy. The advantage of user control is smaller than you > suggest, I believe. Anything bigger than C-1 will cause you to > miss the target half the time or more. Simply not true. Where do you get that "half the time or more"? And what does "miss the target" even mean here, precisely? We're talking about incremental adjustment. If I want to move an Emacs frame downward so that its bottom edge precisely aligns with the top of another frame (just as an example), that edge coincidence is presumably your "target". It is obvious and simple to do this incrementally. If you want to move the whole distance using a tiny increment (e.g. 1 pixel at a time), you can do that. But if you want to move most of the distance using a larger increment then you can do that too. And if you overshoot (and you likely will, when in a final "docking" maneuver) then you just move back (and forth, if necessary, until you get it right). This is so simple as to make any description of it overkill. But hopefully it is clear now? > Sometimes people will need > to correct for overshooting, which means either starting over with > the inverse command or using a negative count. And even if they > undershoot they need to switch to C-1. You make over/undershooting sound like some kind of error. It is in fact the _normal_ way we interact with our environments (and even with ourselves). You cannot sit down or stand up or take a step without making over/undershoot adjustments. And no, I do not understand your statement about starting over. > I don't want it badly enough to write the code, but I suspect more > users will find it useful than the UI you propose. Both are valid > proposals and worth experimenting with. Yes to the idea that experimenting is helpful. If you want to experiment with incremental adjustment (if not the same prefix-arg design), here are a few places to start: * frame-cmds.el: commands such as `move-frame-(down|up|right|left)', `(enlarge|shrink)-frame(-horizontally)' http://www.emacswiki.org/emacs-en/download/frame-cmds.el * doremi-frm.el, doremi-cmd.el: any of the commands (increment face/frame colors, frame/font sizes, etc.) http://www.emacswiki.org/emacs-en/download/doremi-frm.el http://www.emacswiki.org/emacs-en/download/doremi-cmd.el http://www.emacswiki.org/cgi-bin/wiki/DoReMi Even in vanilla Emacs, just consider adjusting text size using C-x C-(-|+), with and without a prefix arg. A prefix arg here is "modal" in the sense that the initial prefix arg you give is passed on to each subsequent +/-, instead of reverting to an increment of 1. You cannot, however, change the increment along the way (which is the additional feature I proposed in the current context). Or even just using `M-f' and `C-f' to move across text to your "target", coming back with `(M|C)-b' if you overshoot, etc. Here, like the DoReMi booster-key case, there are separate keys for different size increments. A prefix arg here controls not the increment size but the number of jumps. Really not a big deal at all. All of these different ways of incrementally adjusting something provide easy ways to fine-tune, including adjusting for over/undershoot. ^ permalink raw reply [flat|nested] 51+ messages in thread
* RE: [PATCH] Make `C-x {' and `C-x }' repeatable 2013-05-24 15:55 ` Drew Adams @ 2013-05-24 17:00 ` Stephen J. Turnbull 0 siblings, 0 replies; 51+ messages in thread From: Stephen J. Turnbull @ 2013-05-24 17:00 UTC (permalink / raw) To: Drew Adams; +Cc: chad, Stefan Monnier, emacs-devel@gnu.org Development Drew Adams writes: [Many many many words elided.] > Really not a big deal at all. The quantity of words you use to describe how easy it all is belies your main point. The proof of the pudding is, as usual, in the eating, and I hope both flavors will be available at the county fair, although I expect the mango cream to be tastier. sayonara to this thread, ^ permalink raw reply [flat|nested] 51+ messages in thread
* Re: [PATCH] Make `C-x {' and `C-x }' repeatable 2013-05-22 18:55 ` Juri Linkov 2013-05-22 21:39 ` Drew Adams @ 2013-05-22 21:47 ` Stefan Monnier 2013-05-22 22:24 ` Stefan Monnier ` (2 more replies) 1 sibling, 3 replies; 51+ messages in thread From: Stefan Monnier @ 2013-05-22 21:47 UTC (permalink / raw) To: Juri Linkov; +Cc: Gauthier Östervall, Drew Adams, emacs-devel > I don't know why a prefix arg exits temporary-overlay-map. Trying to > (define-key window-size-adjust-keymap [?\C-u] 'universal-argument) > doesn't help to fix this. `C-u' still terminates the key sequence > `C-x } } } } C-u }'. I haven't looked into it, but at least I wouldn't know offhand why that would be a problem (`universal-argument' is a special command with some nasty ad-hoc handling in the command_loop C code for it, but I can't think of an obvious reason why it would explain what you're seeing). >> I want to have a repeatable command bound to a key on `isearch-mode-map'. Of course. Bug#14095 is a clear bug linked to the following comment in set-temporary-overlay-map: ;; FIXME: That's the keymaps with highest precedence, except for ;; the `keymap' text-property ;-( the bug is actually wrong, because additionally to the `keymap' property, overriding-local-map and overriding-terminal-local-map are two more keymaps of higher precedence. So the right fix for it is to introduce a new keymap (call it "overriding-temporary-local-map" or something) which is like overriding-terminal-local-map except that it doesn't disable other keymaps (it just has higher precedence). > Maybe a better implementation would be with the help of > `set-temporary-overlay-map'. I'll try to do this for Isearch. Isearch might benefit from being changed to use such a new overriding-temporary-local-map as well. It might let us drop the isearch-other-char command (which has the drawback of putting things back onto unread-command-event, which is inherently unreliable in the presence of some function-key-map bindings, among other problems). Of course, such a change might also bump into new problems. Stefan ^ permalink raw reply [flat|nested] 51+ messages in thread
* Re: [PATCH] Make `C-x {' and `C-x }' repeatable 2013-05-22 21:47 ` Stefan Monnier @ 2013-05-22 22:24 ` Stefan Monnier 2013-05-22 23:53 ` Drew Adams 2013-05-23 22:30 ` Juri Linkov 2 siblings, 0 replies; 51+ messages in thread From: Stefan Monnier @ 2013-05-22 22:24 UTC (permalink / raw) To: Juri Linkov; +Cc: Gauthier Östervall, Drew Adams, emacs-devel > I haven't looked into it, but at least I wouldn't know offhand why that > would be a problem (`universal-argument' is a special command with some Duh: universal-argument uses overriding-terminal-local-map, so yes, of course it bumps into similar problems as isearch when combines with set-temporary-overlay-map. Stefan ^ permalink raw reply [flat|nested] 51+ messages in thread
* RE: [PATCH] Make `C-x {' and `C-x }' repeatable 2013-05-22 21:47 ` Stefan Monnier 2013-05-22 22:24 ` Stefan Monnier @ 2013-05-22 23:53 ` Drew Adams 2013-05-23 22:30 ` Juri Linkov 2 siblings, 0 replies; 51+ messages in thread From: Drew Adams @ 2013-05-22 23:53 UTC (permalink / raw) To: Stefan Monnier, Juri Linkov; +Cc: Gauthier Östervall, emacs-devel > >> I want to have a repeatable command bound to a key on `isearch-mode-map'. > > Of course. Bug#14095 is a clear bug That's reassuring; thanks. As no one had yet had a chance to respond to the bug report, I wasn't sure that you would see it that way. > linked to the following comment in set-temporary-overlay-map: > > ;; FIXME: That's the keymaps with highest precedence, except for > ;; the `keymap' text-property ;-( > > the bug is actually wrong, Do you mean that comment or the bug #14095 report? > because additionally to the `keymap' > property, overriding-local-map and overriding-terminal-local-map are two > more keymaps of higher precedence. So the right fix for it is to > introduce a new keymap (call it "overriding-temporary-local-map" or > something) which is like overriding-terminal-local-map except that it > doesn't disable other keymaps (it just has higher precedence). Sounds good to me (with limited understanding). > > Maybe a better implementation would be with the help of > > `set-temporary-overlay-map'. I'll try to do this for Isearch. > > Isearch might benefit from being changed to use such a new > overriding-temporary-local-map as well. It might let us drop the > isearch-other-char command (which has the drawback of putting things > back onto unread-command-event, which is inherently unreliable in the > presence of some function-key-map bindings, among other problems). > Of course, such a change might also bump into new problems. A priori, that too sounds good to me (again, with limited understanding). ^ permalink raw reply [flat|nested] 51+ messages in thread
* Re: [PATCH] Make `C-x {' and `C-x }' repeatable 2013-05-22 21:47 ` Stefan Monnier 2013-05-22 22:24 ` Stefan Monnier 2013-05-22 23:53 ` Drew Adams @ 2013-05-23 22:30 ` Juri Linkov 2013-05-24 3:58 ` Stefan Monnier 2 siblings, 1 reply; 51+ messages in thread From: Juri Linkov @ 2013-05-23 22:30 UTC (permalink / raw) To: Stefan Monnier; +Cc: Gauthier Östervall, Drew Adams, emacs-devel > So the right fix for it is to introduce a new keymap (call it > "overriding-temporary-local-map" or something) which is like > overriding-terminal-local-map except that it doesn't disable other > keymaps (it just has higher precedence). Adding it to the pseudo-code in (info "(elisp) Searching Keymaps") is this what you meant? (or (FIND-IN overriding-temporary-local-map) (cond (overriding-terminal-local-map (FIND-IN overriding-terminal-local-map)) (overriding-local-map (FIND-IN overriding-local-map)) ((or (FIND-IN (get-char-property (point) 'keymap)) (FIND-IN TEMP-MAP) (FIND-IN-ANY emulation-mode-map-alists) (FIND-IN-ANY minor-mode-overriding-map-alist) (FIND-IN-ANY minor-mode-map-alist) (if (get-text-property (point) 'local-map) (FIND-IN (get-char-property (point) 'local-map)) (FIND-IN (current-local-map)))))) (FIND-IN (current-global-map))) > Isearch might benefit from being changed to use such a new > overriding-temporary-local-map as well. It might let us drop the > isearch-other-char command (which has the drawback of putting things > back onto unread-command-event, which is inherently unreliable in the > presence of some function-key-map bindings, among other problems). > Of course, such a change might also bump into new problems. I tried to do this for isearch to implement key sequences like `M-s C-f C-f M-f C-M-f C-e M-}' that moves point and at the same time adds the passed text to the search string: (defvar isearch-yank-jump-keymap (let ((map (make-sparse-keymap))) (define-key map "\C-f" 'isearch-yank-jump) ;; next char (define-key map "\M-f" 'isearch-yank-jump) ;; next word (define-key map "\C-\M-f" 'isearch-yank-jump) ;; next sexp (define-key map "\C-n" 'isearch-yank-jump) ;; next line (define-key map "\C-e" 'isearch-yank-jump) ;; end-of-line (define-key map "\M-}" 'isearch-yank-jump) ;; next paragraph map) "Keymap to yank text from jumped positions.") ;; Use prefix key `M-s' to activate yanking key sequences. (define-key isearch-mode-map "\M-s\C-f" 'isearch-yank-jump) (define-key isearch-mode-map "\M-s\M-f" 'isearch-yank-jump) (define-key isearch-mode-map "\M-s\C-\M-f" 'isearch-yank-jump) (define-key isearch-mode-map "\M-s\C-n" 'isearch-yank-jump) (define-key isearch-mode-map "\M-s\C-e" 'isearch-yank-jump) (define-key isearch-mode-map "\M-s\M-}" 'isearch-yank-jump) (defun isearch-yank-jump (&optional arg) (interactive "p") (let* ((keys last-command-event) (overriding-terminal-local-map nil) (binding (key-binding (vector keys)))) (when binding (setq prefix-arg arg) (isearch-yank-internal (lambda () (command-execute binding) (point)))) (set-temporary-overlay-map isearch-yank-jump-keymap))) But `set-temporary-overlay-map' has no effect. Could the new `overriding-temporary-local-map' help in this case? ^ permalink raw reply [flat|nested] 51+ messages in thread
* Re: [PATCH] Make `C-x {' and `C-x }' repeatable 2013-05-23 22:30 ` Juri Linkov @ 2013-05-24 3:58 ` Stefan Monnier 0 siblings, 0 replies; 51+ messages in thread From: Stefan Monnier @ 2013-05-24 3:58 UTC (permalink / raw) To: Juri Linkov; +Cc: Gauthier Östervall, Drew Adams, emacs-devel > Adding it to the pseudo-code in (info "(elisp) Searching Keymaps") > is this what you meant? > (or (FIND-IN overriding-temporary-local-map) > (cond > (overriding-terminal-local-map > (FIND-IN overriding-terminal-local-map)) > (overriding-local-map > (FIND-IN overriding-local-map)) > ((or (FIND-IN (get-char-property (point) 'keymap)) > (FIND-IN TEMP-MAP) > (FIND-IN-ANY emulation-mode-map-alists) > (FIND-IN-ANY minor-mode-overriding-map-alist) > (FIND-IN-ANY minor-mode-map-alist) > (if (get-text-property (point) 'local-map) > (FIND-IN (get-char-property (point) 'local-map)) > (FIND-IN (current-local-map)))))) > (FIND-IN (current-global-map))) Right. > But `set-temporary-overlay-map' has no effect. Could the new > `overriding-temporary-local-map' help in this case? Presumably, yes. But maybe getting Isearch, universal-argument, and your isearch-yank-jump to correctly use set-temporary-overlay-map at the same time will prove tricky. I hope it will be workable, with the use of "composed keymaps". Stefan ^ permalink raw reply [flat|nested] 51+ messages in thread
* Re: [PATCH] Make `C-x {' and `C-x }' repeatable 2013-05-20 19:59 [PATCH] Make `C-x {' and `C-x }' repeatable Gauthier Östervall 2013-05-21 9:58 ` Vitalie Spinu 2013-05-21 18:34 ` Juri Linkov @ 2013-05-22 19:05 ` Stefan Monnier 2013-05-23 12:21 ` Gauthier Östervall 2 siblings, 1 reply; 51+ messages in thread From: Stefan Monnier @ 2013-05-22 19:05 UTC (permalink / raw) To: Gauthier Östervall; +Cc: emacs-devel > Ever since I started using emacs and tried to say good bye to my > mouse, I have felt that the resizing of windows with `C-x }' and > `C-x {' is too cumbersome to use. Have you tried M-x windresize ? It's too modal for my taste (I'd like to be able to exit more easily than via `q'), but other than that I hope such a command will eventually make C-x {, C-x }, and C-x ^ redundant. Stefan ^ permalink raw reply [flat|nested] 51+ messages in thread
* Re: [PATCH] Make `C-x {' and `C-x }' repeatable 2013-05-22 19:05 ` Stefan Monnier @ 2013-05-23 12:21 ` Gauthier Östervall 2013-05-23 13:41 ` Stefan Monnier 0 siblings, 1 reply; 51+ messages in thread From: Gauthier Östervall @ 2013-05-23 12:21 UTC (permalink / raw) To: Stefan Monnier; +Cc: emacs-devel On Wed, May 22, 2013 at 9:05 PM, Stefan Monnier > Have you tried M-x windresize ? It's too modal for my taste (I'd like > to be able to exit more easily than via `q'), but other than that > I hope such a command will eventually make C-x {, C-x }, and C-x ^ redundant. windresize.el is not part of my distribution, so I haven't. I will give it a try, but I feel that functionality should be built-in. Thanks for the hint anyway. ^ permalink raw reply [flat|nested] 51+ messages in thread
* Re: [PATCH] Make `C-x {' and `C-x }' repeatable 2013-05-23 12:21 ` Gauthier Östervall @ 2013-05-23 13:41 ` Stefan Monnier 2013-05-23 22:04 ` Juri Linkov 0 siblings, 1 reply; 51+ messages in thread From: Stefan Monnier @ 2013-05-23 13:41 UTC (permalink / raw) To: Gauthier Östervall; +Cc: emacs-devel >> Have you tried M-x windresize ? It's too modal for my taste (I'd >> like to be able to exit more easily than via `q'), but other than >> that I hope such a command will eventually make C-x {, C-x }, and C-x >> ^ redundant. > windresize.el is not part of my distribution, so I haven't. It's in GNU ELPA. > I will give it a try, but I feel that functionality should be > built-in. Yes clearly, that is needed before we can consider it to make C-x [{}^] redundant. Stefan ^ permalink raw reply [flat|nested] 51+ messages in thread
* Re: [PATCH] Make `C-x {' and `C-x }' repeatable 2013-05-23 13:41 ` Stefan Monnier @ 2013-05-23 22:04 ` Juri Linkov 2013-05-24 9:38 ` Alan Mackenzie 2013-06-09 12:07 ` [PATCH] set-temporary-overlay-map improvement and make windresize exit on other commands Vitalie Spinu 0 siblings, 2 replies; 51+ messages in thread From: Juri Linkov @ 2013-05-23 22:04 UTC (permalink / raw) To: Stefan Monnier; +Cc: Gauthier Östervall, emacs-devel >> I will give it a try, but I feel that functionality should be >> built-in. > > Yes clearly, that is needed before we can consider it to make C-x > [{}^] redundant. If the goal is to replace `C-x [{}^]' with one global keybinding, the currently free and intuitive key prefix for window related commands would be `C-x w', so that a command to activate window-resizing key sequence could be bound to `C-x w r'. Until this is implemented, something like below could help for experimenting with possible implementations: (defvar window-resize-keymap (let ((map (make-sparse-keymap))) ;; Standard keys: (define-key map "0" 'delete-window) (define-key map "1" 'delete-other-windows) (define-key map "2" 'split-window-below) (define-key map "3" 'split-window-right) (define-key map "o" 'other-window) (define-key map "^" 'enlarge-window) (define-key map "}" 'enlarge-window-horizontally) (define-key map "{" 'shrink-window-horizontally) (define-key map "-" 'shrink-window-if-larger-than-buffer) (define-key map "+" 'balance-windows) ;; Additional keys: (define-key map "v" 'shrink-window) (define-key map [down] 'shrink-window) (define-key map [up] 'enlarge-window) (define-key map [left] 'shrink-window-horizontally) (define-key map [right] 'enlarge-window-horizontally) map) "Keymap to resize windows.") (advice-add 'enlarge-window-horizontally :after (lambda (delta) (set-temporary-overlay-map window-resize-keymap))) (advice-add 'shrink-window-horizontally :after (lambda (delta) (set-temporary-overlay-map window-resize-keymap))) (advice-add 'enlarge-window :after (lambda (delta &optional horizontal) (set-temporary-overlay-map window-resize-keymap))) (advice-add 'shrink-window :after (lambda (delta &optional horizontal) (set-temporary-overlay-map window-resize-keymap))) (defun window-resize-init () (interactive) (message "Use window-resizing keys...") (set-temporary-overlay-map window-resize-keymap)) (define-key ctl-x-map "wr" 'window-resize-init) ^ permalink raw reply [flat|nested] 51+ messages in thread
* Re: [PATCH] Make `C-x {' and `C-x }' repeatable 2013-05-23 22:04 ` Juri Linkov @ 2013-05-24 9:38 ` Alan Mackenzie 2013-05-24 20:31 ` Juri Linkov 2013-06-09 12:07 ` [PATCH] set-temporary-overlay-map improvement and make windresize exit on other commands Vitalie Spinu 1 sibling, 1 reply; 51+ messages in thread From: Alan Mackenzie @ 2013-05-24 9:38 UTC (permalink / raw) To: Juri Linkov; +Cc: Stefan Monnier, Gauthier Östervall, emacs-devel Hello, Juri. On Fri, May 24, 2013 at 01:04:40AM +0300, Juri Linkov wrote: > >> I will give it a try, but I feel that functionality should be > >> built-in. > > Yes clearly, that is needed before we can consider it to make C-x > > [{}^] redundant. > If the goal is to replace `C-x [{}^]' with one global keybinding, the > currently free and intuitive key prefix for window related commands > would be `C-x w', so that a command to activate window-resizing key > sequence could be bound to `C-x w r'. `C-x w' is not free. It is used by `highlight-regexp' and friends (still). These key bindings are set inside hi-lock.el itself. -- Alan Mackenzie (Nuremberg, Germany). ^ permalink raw reply [flat|nested] 51+ messages in thread
* Re: [PATCH] Make `C-x {' and `C-x }' repeatable 2013-05-24 9:38 ` Alan Mackenzie @ 2013-05-24 20:31 ` Juri Linkov 2013-05-25 20:01 ` Alan Mackenzie 0 siblings, 1 reply; 51+ messages in thread From: Juri Linkov @ 2013-05-24 20:31 UTC (permalink / raw) To: Alan Mackenzie; +Cc: Stefan Monnier, Gauthier Östervall, emacs-devel >> If the goal is to replace `C-x [{}^]' with one global keybinding, the >> currently free and intuitive key prefix for window related commands >> would be `C-x w', so that a command to activate window-resizing key >> sequence could be bound to `C-x w r'. > > `C-x w' is not free. It is used by `highlight-regexp' and friends > (still). These key bindings are set inside hi-lock.el itself. `C-x w' is defined only when 'hi-lock-mode' is active but `M-s h' is always available, so `C-x w' is redundant. BTW, do you think that adding `overriding-temporary-local-map' could help you to implement `isearch-allow-prefix' that you proposed in http://lists.gnu.org/archive/html/emacs-devel/2011-09/msg00216.html There is an unaddressed request for this feature in bug#9706. ^ permalink raw reply [flat|nested] 51+ messages in thread
* Re: [PATCH] Make `C-x {' and `C-x }' repeatable 2013-05-24 20:31 ` Juri Linkov @ 2013-05-25 20:01 ` Alan Mackenzie 2013-05-25 20:40 ` Juri Linkov 0 siblings, 1 reply; 51+ messages in thread From: Alan Mackenzie @ 2013-05-25 20:01 UTC (permalink / raw) To: Juri Linkov; +Cc: Stefan Monnier, Gauthier Östervall, emacs-devel Hi, Juri. On Fri, May 24, 2013 at 11:31:48PM +0300, Juri Linkov wrote: > >> If the goal is to replace `C-x [{}^]' with one global keybinding, the > >> currently free and intuitive key prefix for window related commands > >> would be `C-x w', so that a command to activate window-resizing key > >> sequence could be bound to `C-x w r'. > > `C-x w' is not free. It is used by `highlight-regexp' and friends > > (still). These key bindings are set inside hi-lock.el itself. > `C-x w' is defined only when 'hi-lock-mode' is active but > `M-s h' is always available, so `C-x w' is redundant. Yes. But my point was to remind people that the clash would need to be dealt with somehow and not just forgotten. > BTW, do you think that adding `overriding-temporary-local-map' > could help you to implement `isearch-allow-prefix' that you proposed in > http://lists.gnu.org/archive/html/emacs-devel/2011-09/msg00216.html I'd forgotten about this one. But it was Drew rather than me that proposed it - I just wrote the patch. I don't know about `overriding-temporary-local-map', I haven't been following this thread in detail. I'll really need to read through the thread and understand it. My gut feeling is that if we're going to be introducing yet another keymap, there'd better be a very good reason for it. > There is an unaddressed request for this feature in bug#9706. If I remember correctly, the patch to the code was finished and working (and who knows, might still work), but the patch to the manual hadn't yet been written. -- Alan Mackenzie (Nuremberg, Germany). ^ permalink raw reply [flat|nested] 51+ messages in thread
* Re: [PATCH] Make `C-x {' and `C-x }' repeatable 2013-05-25 20:01 ` Alan Mackenzie @ 2013-05-25 20:40 ` Juri Linkov 2013-06-02 21:05 ` isearch-allow-prefix [Was: [PATCH] Make `C-x {' and `C-x }' repeatable] Alan Mackenzie 0 siblings, 1 reply; 51+ messages in thread From: Juri Linkov @ 2013-05-25 20:40 UTC (permalink / raw) To: Alan Mackenzie; +Cc: Stefan Monnier, Gauthier Östervall, emacs-devel >> There is an unaddressed request for this feature in bug#9706. > > If I remember correctly, the patch to the code was finished and working > (and who knows, might still work), but the patch to the manual hadn't yet > been written. I highly recommend enabling `isearch-allow-prefix' by default in your patch, provided that it can correctly apply a specified argument either to a isearch command (that doesn't exit isearch) or to a normal command (that exits isearch). IOW, if `C-u C-M-y' typed in isearch-mode will apply `C-u' to `isearch-yank-char' without exiting isearch, but `C-u C-f' will exit isearch and apply `C-u' to `forward-char', then the default value of `isearch-allow-prefix' should be `t'. ^ permalink raw reply [flat|nested] 51+ messages in thread
* isearch-allow-prefix [Was: [PATCH] Make `C-x {' and `C-x }' repeatable] 2013-05-25 20:40 ` Juri Linkov @ 2013-06-02 21:05 ` Alan Mackenzie 2013-06-04 18:03 ` Juri Linkov 0 siblings, 1 reply; 51+ messages in thread From: Alan Mackenzie @ 2013-06-02 21:05 UTC (permalink / raw) To: Juri Linkov, Stefan Monnier; +Cc: Drew Adams, emacs-devel Hi, Juri and Stefan. On Sat, May 25, 2013 at 11:40:55PM +0300, Juri Linkov wrote: > >> There is an unaddressed request for this feature in bug#9706. > > If I remember correctly, the patch to the code was finished and working > > (and who knows, might still work), but the patch to the manual hadn't yet > > been written. > I highly recommend enabling `isearch-allow-prefix' by default > in your patch, provided that it can correctly apply a specified > argument either to a isearch command (that doesn't exit isearch) > or to a normal command (that exits isearch). > IOW, if `C-u C-M-y' typed in isearch-mode will apply `C-u' > to `isearch-yank-char' without exiting isearch, but `C-u C-f' > will exit isearch and apply `C-u' to `forward-char', then > the default value of `isearch-allow-prefix' should be `t'. OK. Here is a patch for isearch.el, search.texi and NEWS. I'm not terribly impressed by the documentation patch, but it was the best I could manage. Do you have any comments on the patch, or should I just commit it? === modified file 'doc/emacs/emacs.texi' *** doc/emacs/emacs.texi 2013-03-30 16:47:07 +0000 --- doc/emacs/emacs.texi 2013-06-02 18:25:29 +0000 *************** *** 396,409 **** Incremental Search ! * Basic Isearch:: Basic incremental search commands. ! * Repeat Isearch:: Searching for the same string again. ! * Error in Isearch:: When your string is not found. ! * Special Isearch:: Special input in incremental search. ! * Isearch Yank:: Commands that grab text into the search string ! or else edit the search string. ! * Isearch Scroll:: Scrolling during an incremental search. ! * Isearch Minibuffer:: Incremental search of the minibuffer history. Replacement Commands --- 396,410 ---- Incremental Search ! * Basic Isearch:: Basic incremental search commands. ! * Repeat Isearch:: Searching for the same string again. ! * Error in Isearch:: When your string is not found. ! * Prefix Argument in Isearch:: What prefix arguments do. ! * Special Isearch:: Special input in incremental search. ! * Isearch Yank:: Commands that grab text into the search string ! or else edit the search string. ! * Isearch Scroll:: Scrolling during an incremental search. ! * Isearch Minibuffer:: Incremental search of the minibuffer history. Replacement Commands === modified file 'doc/emacs/search.texi' *** doc/emacs/search.texi 2013-05-15 23:14:18 +0000 --- doc/emacs/search.texi 2013-06-02 20:52:05 +0000 *************** *** 52,65 **** @end table @menu ! * Basic Isearch:: Basic incremental search commands. ! * Repeat Isearch:: Searching for the same string again. ! * Error in Isearch:: When your string is not found. ! * Special Isearch:: Special input in incremental search. ! * Isearch Yank:: Commands that grab text into the search string ! or else edit the search string. ! * Isearch Scroll:: Scrolling during an incremental search. ! * Isearch Minibuffer:: Incremental search of the minibuffer history. @end menu @node Basic Isearch --- 52,66 ---- @end table @menu ! * Basic Isearch:: Basic incremental search commands. ! * Repeat Isearch:: Searching for the same string again. ! * Error in Isearch:: When your string is not found. ! * Prefix Argument in Isearch:: What prefix arguments do. ! * Special Isearch:: Special input in incremental search. ! * Isearch Yank:: Commands that grab text into the search string ! or else edit the search string. ! * Isearch Scroll:: Scrolling during an incremental search. ! * Isearch Minibuffer:: Incremental search of the minibuffer history. @end menu @node Basic Isearch *************** *** 212,217 **** --- 213,234 ---- waiting for more input, so a second @kbd{C-g} will cancel the entire search. + @node Prefix Argument in Isearch + @subsection The Prefix Argument in Incremental Search + + @vindex isearch-allow-prefix + In incremental search, when you enter a prefix argument + (@pxref{Arguments}), by default it will apply either to the next + action in the search or to the command that exits the search. + + In previous versions of Emacs, entering a prefix argument always + terminated the search. You can revert to this behavior by setting the + variable @code{isearch-allow-prefix} to @code{nil}. + + When @code{isearch-allow-scroll} is non-@code{nil} (@pxref{Isearch + Scroll}), prefix arguments always have the default behavior described + above. + @node Special Isearch @subsection Special Input for Incremental Search === modified file 'etc/NEWS' *** etc/NEWS 2013-05-27 23:02:37 +0000 --- etc/NEWS 2013-06-02 19:56:21 +0000 *************** *** 244,249 **** --- 244,253 ---- *** `query-replace' skips invisible text when `search-invisible' is nil, and opens overlays with hidden text when `search-invisible' is `open'. + +++ + *** By default, prefix arguments can now be entered without + terminating Isearch mode. Set `isearch-allow-prefix' to nil to disable. + ** MH-E has been updated to MH-E version 8.5. See MH-E-NEWS for details. === modified file 'lisp/isearch.el' *** lisp/isearch.el 2013-05-27 22:42:11 +0000 --- lisp/isearch.el 2013-06-02 20:54:25 +0000 *************** *** 2102,2107 **** --- 2102,2115 ---- :type 'boolean :group 'isearch) + (defcustom isearch-allow-prefix t + "Whether prefix arguments are allowed during incremental search. + If non-nil, entering a prefix argument will not terminate the + search. This option is ignored \(presumed t) when + `isearch-allow-scroll' is set." + :type 'boolean + :group 'isearch) + (defun isearch-string-out-of-window (isearch-point) "Test whether the search string is currently outside of the window. Return nil if it's completely visible, or if point is visible, *************** *** 2254,2265 **** (setq prefix-arg arg) (apply 'isearch-unread keylist) (isearch-edit-string)) ! ;; Handle a scrolling function. ! ((and isearch-allow-scroll ! (progn (setq key (isearch-reread-key-sequence-naturally keylist)) ! (setq keylist (listify-key-sequence key)) ! (setq main-event (aref key 0)) ! (setq scroll-command (isearch-lookup-scroll-key key)))) ;; From this point onwards, KEY, KEYLIST and MAIN-EVENT hold a ;; complete key sequence, possibly as modified by function-key-map, ;; not merely the one or two event fragment which invoked --- 2262,2280 ---- (setq prefix-arg arg) (apply 'isearch-unread keylist) (isearch-edit-string)) ! ;; Handle a scrolling function or prefix argument. ! ((progn ! (setq key (isearch-reread-key-sequence-naturally keylist) ! keylist (listify-key-sequence key) ! main-event (aref key 0)) ! (or (and isearch-allow-scroll ! (setq scroll-command (isearch-lookup-scroll-key key))) ! (and isearch-allow-prefix ! (let (overriding-terminal-local-map) ! (setq scroll-command (key-binding key)) ! (memq scroll-command ! '(universal-argument ! negative-argument digit-argument)))))) ;; From this point onwards, KEY, KEYLIST and MAIN-EVENT hold a ;; complete key sequence, possibly as modified by function-key-map, ;; not merely the one or two event fragment which invoked -- Alan Mackenzie (Nuremberg, Germany). ^ permalink raw reply [flat|nested] 51+ messages in thread
* Re: isearch-allow-prefix [Was: [PATCH] Make `C-x {' and `C-x }' repeatable] 2013-06-02 21:05 ` isearch-allow-prefix [Was: [PATCH] Make `C-x {' and `C-x }' repeatable] Alan Mackenzie @ 2013-06-04 18:03 ` Juri Linkov 2013-06-04 21:24 ` Alan Mackenzie 0 siblings, 1 reply; 51+ messages in thread From: Juri Linkov @ 2013-06-04 18:03 UTC (permalink / raw) To: Alan Mackenzie; +Cc: Stefan Monnier, Drew Adams, emacs-devel > OK. Here is a patch for isearch.el, search.texi and NEWS. Thanks, I tested your patch and it correctly passes a prefix argument to the next command. > I'm not terribly impressed by the documentation patch, > but it was the best I could manage. Could you try adding new text to the existing node (info "(emacs) Isearch Scroll") and renaming it to something more general that would fit both variables? I know that it's not trivial to find such a name, but it would be better to have related variables in the same node. What about the node name "Exiting Isearch" to document in one node all options that affect commands exiting Isearch? > Do you have any comments on the patch, or should I just commit it? I have no more comments on your patch, and just want to note that after committing we will be able to finally implement http://debbugs.gnu.org/10614 to support a prefix argument in `isearch-repeat-forward' and `isearch-repeat-backward' and other commands. ^ permalink raw reply [flat|nested] 51+ messages in thread
* Re: isearch-allow-prefix [Was: [PATCH] Make `C-x {' and `C-x }' repeatable] 2013-06-04 18:03 ` Juri Linkov @ 2013-06-04 21:24 ` Alan Mackenzie 2013-06-05 8:23 ` Juri Linkov 0 siblings, 1 reply; 51+ messages in thread From: Alan Mackenzie @ 2013-06-04 21:24 UTC (permalink / raw) To: Juri Linkov; +Cc: Stefan Monnier, Drew Adams, emacs-devel Hi, Juri. On Tue, Jun 04, 2013 at 09:03:07PM +0300, Juri Linkov wrote: > > I'm not terribly impressed by the documentation patch, but it was the > > best I could manage. > Could you try adding new text to the existing node (info "(emacs) > Isearch Scroll") and renaming it to something more general that would > fit both variables? I know that it's not trivial to find such a name, > but it would be better to have related variables in the same node. > What about the node name "Exiting Isearch" to document in one node all > options that affect commands exiting Isearch? I've used something similar: "Not Exiting Isearch". :-) I've also made the two somewhat dissimilar parts of this @subsection into a @table. I think it jars a bit less, and is a bit less confusing, than simply having the bit about prefixes running into the bit about scrolling. Could I ask you to take one more look, please? Thanks! === modified file 'doc/emacs/emacs.texi' *** doc/emacs/emacs.texi 2013-03-30 16:47:07 +0000 --- doc/emacs/emacs.texi 2013-06-04 20:45:12 +0000 *************** *** 396,409 **** Incremental Search ! * Basic Isearch:: Basic incremental search commands. ! * Repeat Isearch:: Searching for the same string again. ! * Error in Isearch:: When your string is not found. ! * Special Isearch:: Special input in incremental search. ! * Isearch Yank:: Commands that grab text into the search string ! or else edit the search string. ! * Isearch Scroll:: Scrolling during an incremental search. ! * Isearch Minibuffer:: Incremental search of the minibuffer history. Replacement Commands --- 396,409 ---- Incremental Search ! * Basic Isearch:: Basic incremental search commands. ! * Repeat Isearch:: Searching for the same string again. ! * Error in Isearch:: When your string is not found. ! * Special Isearch:: Special input in incremental search. ! * Isearch Yank:: Commands that grab text into the search string ! or else edit the search string. ! * Not Exiting Isearch:: Prefix argument and scrolling commands. ! * Isearch Minibuffer:: Incremental search of the minibuffer history. Replacement Commands === modified file 'doc/emacs/search.texi' *** doc/emacs/search.texi 2013-05-15 23:14:18 +0000 --- doc/emacs/search.texi 2013-06-04 20:48:10 +0000 *************** *** 52,65 **** @end table @menu ! * Basic Isearch:: Basic incremental search commands. ! * Repeat Isearch:: Searching for the same string again. ! * Error in Isearch:: When your string is not found. ! * Special Isearch:: Special input in incremental search. ! * Isearch Yank:: Commands that grab text into the search string ! or else edit the search string. ! * Isearch Scroll:: Scrolling during an incremental search. ! * Isearch Minibuffer:: Incremental search of the minibuffer history. @end menu @node Basic Isearch --- 52,65 ---- @end table @menu ! * Basic Isearch:: Basic incremental search commands. ! * Repeat Isearch:: Searching for the same string again. ! * Error in Isearch:: When your string is not found. ! * Special Isearch:: Special input in incremental search. ! * Isearch Yank:: Commands that grab text into the search string ! or else edit the search string. ! * Not Exiting Isearch:: Prefix argument and scrolling commands. ! * Isearch Minibuffer:: Incremental search of the minibuffer history. @end menu @node Basic Isearch *************** *** 332,340 **** minibuffer with @kbd{M-e} (@pxref{Repeat Isearch}) and type @kbd{C-f} at the end of the search string in the minibuffer. ! @node Isearch Scroll ! @subsection Scrolling During Incremental Search @vindex isearch-allow-scroll Normally, scrolling commands exit incremental search. If you change the variable @code{isearch-allow-scroll} to a non-@code{nil} value, --- 332,359 ---- minibuffer with @kbd{M-e} (@pxref{Repeat Isearch}) and type @kbd{C-f} at the end of the search string in the minibuffer. ! @node Not Exiting Isearch ! @subsection Not Exiting Incremental Search + This subsection describes two categories of commands which you can + type without exiting the current incremental search, even though they + are not themselves part of incremental search. + + @table @asis + @item Prefix Arguments + @vindex isearch-allow-prefix + In incremental search, when you enter a prefix argument + (@pxref{Arguments}), by default it will apply either to the next + action in the search or to the command that exits the search. + + In previous versions of Emacs, entering a prefix argument always + terminated the search. You can revert to this behavior by setting the + variable @code{isearch-allow-prefix} to @code{nil}. + + When @code{isearch-allow-scroll} is non-@code{nil} (see below), + prefix arguments always have the default behavior described above. + + @item Scrolling Commands @vindex isearch-allow-scroll Normally, scrolling commands exit incremental search. If you change the variable @code{isearch-allow-scroll} to a non-@code{nil} value, *************** *** 366,371 **** --- 385,391 ---- change point, the buffer contents, the match data, the current buffer, or the selected window and frame. The command must not itself attempt an incremental search. + @end table @node Isearch Minibuffer @subsection Searching the Minibuffer -- Alan Mackenzie (Nuremberg, Germany). ^ permalink raw reply [flat|nested] 51+ messages in thread
* Re: isearch-allow-prefix [Was: [PATCH] Make `C-x {' and `C-x }' repeatable] 2013-06-04 21:24 ` Alan Mackenzie @ 2013-06-05 8:23 ` Juri Linkov 2013-06-05 21:02 ` Alan Mackenzie 0 siblings, 1 reply; 51+ messages in thread From: Juri Linkov @ 2013-06-05 8:23 UTC (permalink / raw) To: Alan Mackenzie; +Cc: Stefan Monnier, Drew Adams, emacs-devel >> What about the node name "Exiting Isearch" to document in one node all >> options that affect commands exiting Isearch? > > I've used something similar: "Not Exiting Isearch". :-) This is much better, thanks! ^ permalink raw reply [flat|nested] 51+ messages in thread
* Re: isearch-allow-prefix [Was: [PATCH] Make `C-x {' and `C-x }' repeatable] 2013-06-05 8:23 ` Juri Linkov @ 2013-06-05 21:02 ` Alan Mackenzie 2013-06-06 6:07 ` isearch-allow-move [Was: isearch-allow-prefix] Juri Linkov 0 siblings, 1 reply; 51+ messages in thread From: Alan Mackenzie @ 2013-06-05 21:02 UTC (permalink / raw) To: Juri Linkov; +Cc: Stefan Monnier, Drew Adams, emacs-devel Hi, Juri. On Wed, Jun 05, 2013 at 11:23:20AM +0300, Juri Linkov wrote: > >> What about the node name "Exiting Isearch" to document in one node all > >> options that affect commands exiting Isearch? > > I've used something similar: "Not Exiting Isearch". :-) > This is much better, thanks! OK, I've committed it. -- Alan Mackenzie (Nuremberg, Germany). ^ permalink raw reply [flat|nested] 51+ messages in thread
* isearch-allow-move [Was: isearch-allow-prefix] 2013-06-05 21:02 ` Alan Mackenzie @ 2013-06-06 6:07 ` Juri Linkov 2013-06-06 12:45 ` Stefan Monnier 2013-06-06 20:07 ` Alan Mackenzie 0 siblings, 2 replies; 51+ messages in thread From: Juri Linkov @ 2013-06-06 6:07 UTC (permalink / raw) To: Alan Mackenzie; +Cc: Stefan Monnier, Drew Adams, emacs-devel > OK, I've committed it. Thank you, Alan. Let me reuse your excellent design and create a similar option `isearch-allow-move' that is like `isearch-allow-scroll' but instead of scrolling commands it affects point motion commands to yank text as you go. So typing `C-f' will pull the next char from the buffer and add it to the search string, `M-f' - next word, `C-M-f' - next expression, `M-}' - next paragraph, `C-e' - next line, and so on. Definitely `isearch-allow-move' should be nil by default, and I doubt that many users might want to enable it since it's more useful when motion commands exit Isearch. But to make this feature available regardless of the value of `isearch-allow-move' it could be activated temporarily by the keymap `M-s' to allow key sequences like `M-s C-f M-f C-M-f C-e' that is implemented by this patch: === modified file 'lisp/isearch.el' --- lisp/isearch.el 2013-06-05 20:57:09 +0000 +++ lisp/isearch.el 2013-06-06 06:04:35 +0000 @@ -513,6 +550,10 @@ (defvar isearch-mode-map (define-key map "\M-r" 'isearch-toggle-regexp) (define-key map "\M-e" 'isearch-edit-string) + (let ((s-map (make-sparse-keymap))) + (define-key map "\M-s" s-map) + (define-key s-map [t] 'isearch-other-move-char)) + (define-key map "\M-sc" 'isearch-toggle-case-fold) (define-key map "\M-si" 'isearch-toggle-invisible) (define-key map "\M-sr" 'isearch-toggle-regexp) @@ -668,6 +732,7 @@ (define-key esc-map "\C-r" 'isearch-back (define-key search-map "w" 'isearch-forward-word) (define-key search-map "_" 'isearch-forward-symbol) (define-key search-map "." 'isearch-forward-symbol-at-point) +(define-key search-map [t] 'isearch-forward-other-move-char) ;; Entry points to isearch-mode. @@ -987,6 +1057,7 @@ (defun isearch-update () ;; We must prevent the point moving to the end of composition when a ;; part of the composition has just been searched. (setq disable-point-adjustment t) + (setq isearch-allow-move-temporarily nil) (run-hooks 'isearch-update-post-hook)) (defun isearch-done (&optional nopush edit) @@ -2160,6 +2287,42 @@ (defcustom isearch-allow-prefix t :type 'boolean :group 'isearch) +(defcustom isearch-allow-move nil + "Whether cursor movement is allowed during incremental search. +If non-nil, point motion commands can be used in Isearch mode. +They add the passed text to the search string. +If nil, motion commands will first cancel Isearch mode." + :type 'boolean + :version "24.4" + :group 'isearch) + +(defvar isearch-allow-move-temporarily nil + "Enable yanking text by point motion commands temporarily. +It is enabled on `M-s' and a subsequent point motion command and allows +any subsequent point motion command to add the passed text to the +search string as they go allowing key sequences like `M-s C-f M-f C-M-f' +to add next character, next word, and next expression to the search string. +Any subsequent isearch command that is not a point motion command, +the value of this variable is set to nil.") + +(put 'right-char 'isearch-move t) +(put 'forward-char 'isearch-move t) +(put 'forward-word 'isearch-move t) +(put 'forward-sexp 'isearch-move t) +(put 'forward-paragraph 'isearch-move t) +(put 'move-end-of-line 'isearch-move t) + +;; Handle universal argument for motion commands when both +;; `isearch-allow-scroll' and `isearch-allow-prefix' are nil. +(put 'universal-argument 'isearch-move t) +(put 'negative-argument 'isearch-move t) +(put 'digit-argument 'isearch-move t) + (defun isearch-string-out-of-window (isearch-point) "Test whether the search string is currently outside of the window. Return nil if it's completely visible, or if point is visible, @@ -2224,6 +2388,26 @@ (defun isearch-lookup-scroll-key (key-se (eq (get binding 'scroll-command) t)) binding))) +(defun isearch-lookup-move-key (key-seq) + "If KEY-SEQ is bound to a motion command, return it as a symbol. +Otherwise return nil." + (let* ((overriding-terminal-local-map nil) + (binding (key-binding key-seq))) + (and binding (symbolp binding) (commandp binding) + (eq (get binding 'isearch-move) t) + binding))) + +(defun isearch-other-move-char (&optional arg) + (interactive "P") + (setq isearch-allow-move-temporarily t) + (isearch-other-meta-char arg)) + +(defun isearch-forward-other-move-char (&optional arg) + "Do incremental search starting with a motion command that yanks text." + (interactive "P") + (isearch-forward nil 1) + (isearch-other-move-char arg)) + (defalias 'isearch-other-control-char 'isearch-other-meta-char) (defun isearch-other-meta-char (&optional arg) @@ -2336,7 +2525,22 @@ (defun isearch-other-meta-char (&optiona (if ab-bel (isearch-back-into-window (eq ab-bel 'above) isearch-point) (goto-char isearch-point))) - (isearch-update)) + (isearch-update) + ;; Allow prefix arg for the next motion command. + (setq isearch-allow-move-temporarily t)) + ;; Handle a motion function. + ((and (or isearch-allow-move isearch-allow-move-temporarily) + (progn (setq key (isearch-reread-key-sequence-naturally keylist)) + (setq keylist (listify-key-sequence key)) + (setq main-event (aref key 0)) + (setq move-command (isearch-lookup-move-key + ;; Use the last key in the sequence. + (vector (aref key (1- (length key)))))))) + (setq prefix-arg arg) + (isearch-yank-internal + (lambda () (command-execute move-command) (point))) + (isearch-update) + (setq isearch-allow-move-temporarily t)) ;; A mouse click on the isearch message starts editing the search string ((and (eq (car-safe main-event) 'down-mouse-1) (window-minibuffer-p (posn-window (event-start main-event)))) ^ permalink raw reply [flat|nested] 51+ messages in thread
* Re: isearch-allow-move [Was: isearch-allow-prefix] 2013-06-06 6:07 ` isearch-allow-move [Was: isearch-allow-prefix] Juri Linkov @ 2013-06-06 12:45 ` Stefan Monnier 2013-06-06 15:07 ` Juri Linkov 2013-06-06 20:07 ` Alan Mackenzie 1 sibling, 1 reply; 51+ messages in thread From: Stefan Monnier @ 2013-06-06 12:45 UTC (permalink / raw) To: Juri Linkov; +Cc: Alan Mackenzie, Drew Adams, emacs-devel > So typing `C-f' will pull the next char from the buffer and add it > to the search string, `M-f' - next word, `C-M-f' - next expression, > `M-}' - next paragraph, `C-e' - next line, and so on. > Definitely `isearch-allow-move' should be nil by default, I think it's fine if some people want such a feature, but I don't think it belongs in isearch.el. OTOH it's perfectly OK to add hooks or do some changes in order to make it possible to implement such a feature cleanly outside of isearch.el. Stefan ^ permalink raw reply [flat|nested] 51+ messages in thread
* Re: isearch-allow-move [Was: isearch-allow-prefix] 2013-06-06 12:45 ` Stefan Monnier @ 2013-06-06 15:07 ` Juri Linkov 2013-06-06 15:43 ` Drew Adams 2013-06-06 16:39 ` Stefan Monnier 0 siblings, 2 replies; 51+ messages in thread From: Juri Linkov @ 2013-06-06 15:07 UTC (permalink / raw) To: Stefan Monnier; +Cc: Alan Mackenzie, Drew Adams, emacs-devel > I think it's fine if some people want such a feature, but I don't think > it belongs in isearch.el. OTOH it's perfectly OK to add hooks or do > some changes in order to make it possible to implement such a feature > cleanly outside of isearch.el. It is intended to replace several mostly unusable and ugly (mis)features in isearch.el, replacing all them with a unified and intuitive user interface: 1. Replace the hard to type key sequence `M-s C-e M-s C-e M-s C-e ...' that pulls consecutive lines with more usable and easy to type shorter key sequence `M-s C-e C-e C-e ...' that will fix bug#10654. 2. Remove such surprising and inconvenient feature as typing `C-f' at the end of the isearch-edit-string minibuffer to pull characters to the end of the minibuffer. It will help to finally get rid of the command `isearch-yank-char-in-minibuffer' and to remove its binding `C-f' from `minibuffer-local-isearch-map', because now the same functionality will be available without such non-standard behavior, i.e. by replacing the sequence `C-s M-e C-f C-f C-f' with less surprising `M-s C-f C-f C-f M-e'. 3. Make the value `edit' of the option `search-exit-option' obsolete, i.e. currently when `search-exit-option' is `edit', then typing `C-s C-f C-f C-f' activates the minibuffer and pulls characters to the end of the minibuffer. The proposed patch will replace this with `M-s C-f C-f C-f M-e'. 4. Replace unintuitive keybindings `C-M-w' (isearch-del-char) and `C-M-y' (isearch-yank-char) with more convenient and intuitive `M-s C-f C-b', thus allowing the keys `C-M-w' and `C-M-y' exit Isearch and execute global commands (`C-M-y' is currently unbound globally, but there were proposals for its global bindings). 5. Instead of adding more explicit yanking commands like `isearch-yank-sexp' proposed in bug#6232, it will be possible to just put the `isearch-allow-move' property on `forward-sexp' or many other motion commands. ^ permalink raw reply [flat|nested] 51+ messages in thread
* RE: isearch-allow-move [Was: isearch-allow-prefix] 2013-06-06 15:07 ` Juri Linkov @ 2013-06-06 15:43 ` Drew Adams 2013-06-06 16:39 ` Stefan Monnier 1 sibling, 0 replies; 51+ messages in thread From: Drew Adams @ 2013-06-06 15:43 UTC (permalink / raw) To: Juri Linkov, Stefan Monnier; +Cc: Alan Mackenzie, emacs-devel FWIW - I generally agree with what Juri proposes, though I haven't checked the details. And I think it does belong in isearch.el, as much as anything else that is already there. This kind of thing (performing actions on the fly while searching, including yanking different things into the search string) greatly improves Isearch, IMO. It should be optional and configurable, of course. The search string is editable, (even apart from using `M-e'), i.e., you can type/delete/yank text there. And interacting with the search string is in some ways like interacting with an edit buffer. But that interaction has long been fairly primitive - there is only so much you can do. Letting users take advantage of more of Emacs for interacting with the search string is a good thing, in general. This is a move in that direction. Again, it should be a user choice, of course. > 3. Make the value `edit' of the option `search-exit-option' obsolete, > i.e. currently when `search-exit-option' is `edit', then typing > `C-s C-f C-f C-f' activates the minibuffer and pulls characters > to the end of the minibuffer. That part (description of the current behavior) I do not understand. The doc string and defcustom indicate that all non-nil values should behave the same, etc. What makes a value of `edit' behave differently from a value of `t' or 42? Oh, I see that `isearch-other-meta-char' mentions the value `edit', and treats it specially. Another bug, apparently: The defcustom and the doc string do not reflect that possibility at all. Apparently whoever updated the function to add this special case did not pay attention to the definition of the option. ^ permalink raw reply [flat|nested] 51+ messages in thread
* Re: isearch-allow-move [Was: isearch-allow-prefix] 2013-06-06 15:07 ` Juri Linkov 2013-06-06 15:43 ` Drew Adams @ 2013-06-06 16:39 ` Stefan Monnier 2013-06-07 7:07 ` Juri Linkov 1 sibling, 1 reply; 51+ messages in thread From: Stefan Monnier @ 2013-06-06 16:39 UTC (permalink / raw) To: Juri Linkov; +Cc: Alan Mackenzie, Drew Adams, emacs-devel > such non-standard behavior, i.e. by replacing the sequence > `C-s M-e C-f C-f C-f' with less surprising `M-s C-f C-f C-f M-e'. C-f exits isearch. I don't think we want to change this by default. Maybe we could provide a "grab from buffer" key after which C-f grabs the next char from the buffer rather than exiting, but otherwise, I think this is a non-starter as far as default behavior goes. Stefan ^ permalink raw reply [flat|nested] 51+ messages in thread
* Re: isearch-allow-move [Was: isearch-allow-prefix] 2013-06-06 16:39 ` Stefan Monnier @ 2013-06-07 7:07 ` Juri Linkov 0 siblings, 0 replies; 51+ messages in thread From: Juri Linkov @ 2013-06-07 7:07 UTC (permalink / raw) To: Stefan Monnier; +Cc: Alan Mackenzie, Drew Adams, emacs-devel >> such non-standard behavior, i.e. by replacing the sequence >> `C-s M-e C-f C-f C-f' with less surprising `M-s C-f C-f C-f M-e'. > > C-f exits isearch. I don't think we want to change this by default. I agree that C-f alone should exit isearch. > Maybe we could provide a "grab from buffer" key after which C-f grabs > the next char from the buffer rather than exiting, but otherwise, > I think this is a non-starter as far as default behavior goes. I'm carefully trying to preserve the current default behavior. That's why grabbing from the buffer should be started only with `M-s C-f'. However, for subsequent keys after `M-s C-f' maybe should be an option to choose between `M-s C-f M-s C-f M-s C-f' or a shorter sequence `M-s C-f C-f C-f'. ^ permalink raw reply [flat|nested] 51+ messages in thread
* Re: isearch-allow-move [Was: isearch-allow-prefix] 2013-06-06 6:07 ` isearch-allow-move [Was: isearch-allow-prefix] Juri Linkov 2013-06-06 12:45 ` Stefan Monnier @ 2013-06-06 20:07 ` Alan Mackenzie 2013-06-07 6:59 ` Juri Linkov 2013-06-07 20:04 ` Juri Linkov 1 sibling, 2 replies; 51+ messages in thread From: Alan Mackenzie @ 2013-06-06 20:07 UTC (permalink / raw) To: Juri Linkov; +Cc: Stefan Monnier, Drew Adams, emacs-devel Hi, Juri. On Thu, Jun 06, 2013 at 09:07:34AM +0300, Juri Linkov wrote: > > OK, I've committed it. > Thank you, Alan. > Let me reuse your excellent design and create a similar option > `isearch-allow-move' that is like `isearch-allow-scroll' but > instead of scrolling commands it affects point motion commands > to yank text as you go. > So typing `C-f' will pull the next char from the buffer and add it > to the search string, `M-f' - next word, `C-M-f' - next expression, > `M-}' - next paragraph, `C-e' - next line, and so on. I can't help feeling there will be excessively complicated interactions here, somewhere. I'm assuming that backward commands like C-b won't be included. But what does it mean to C-f with a prefix arg of -1? Does it mean "remove the last char from the search string"? If not, why not? Or maybe a negative prefix argument would cause the command to be ignored. Or maybe C-b would be allowed here to remove the last char from the search string. You could then use it to erase the entire search string and then convert a forward search into backward search by another C-b. Maybe. Maybe I'm just being a bit conservative, but I can foresee there being more complications here than would make the implementation worthwhile. > Definitely `isearch-allow-move' should be nil by default, > and I doubt that many users might want to enable it since > it's more useful when motion commands exit Isearch. > But to make this feature available regardless of the value of > `isearch-allow-move' it could be activated temporarily by the > keymap `M-s' to allow key sequences like `M-s C-f M-f C-M-f C-e' > that is implemented by this patch: (Apologies for not having read the patch in full detail.) -- Alan Mackenzie (Nuremberg, Germany). ^ permalink raw reply [flat|nested] 51+ messages in thread
* Re: isearch-allow-move [Was: isearch-allow-prefix] 2013-06-06 20:07 ` Alan Mackenzie @ 2013-06-07 6:59 ` Juri Linkov 2013-06-07 10:30 ` Alan Mackenzie 2013-06-07 20:04 ` Juri Linkov 1 sibling, 1 reply; 51+ messages in thread From: Juri Linkov @ 2013-06-07 6:59 UTC (permalink / raw) To: Alan Mackenzie; +Cc: Stefan Monnier, Drew Adams, emacs-devel > But what does it mean to C-f with a prefix arg of -1? Does it mean > "remove the last char from the search string"? If not, why not? > Or maybe a negative prefix argument would cause the command to be ignored. > > Or maybe C-b would be allowed here to remove the last char from the > search string. Good idea. This is implemented now by this patch (cumulative to the previously sent one) where `C-b' or `C-u -1 C-f' removes the last char from the search string (`M-b' removes the last word, `C-M-b' removes the last expression, etc. allowing key sequences like `M-s C-b M-b C-M-b'), and eventually stops removing characters at the beginning of the current match when the search string becomes empty. Is this approach simple enough and intuitive? === modified file 'lisp/isearch.el' --- lisp/isearch.el 2013-06-07 04:57:40 +0000 +++ lisp/isearch.el 2013-06-07 06:51:29 +0000 @@ -2367,11 +2370,17 @@ (defvar isearch-allow-move-temporarily n the value of this variable is set to nil.") (put 'right-char 'isearch-move t) +(put 'left-char 'isearch-move t) (put 'forward-char 'isearch-move t) +(put 'backward-char 'isearch-move t) (put 'forward-word 'isearch-move t) +(put 'backward-word 'isearch-move t) (put 'forward-sexp 'isearch-move t) +(put 'backward-sexp 'isearch-move t) (put 'forward-paragraph 'isearch-move t) +(put 'backward-paragraph 'isearch-move t) (put 'move-end-of-line 'isearch-move t) +(put 'move-beginning-of-line 'isearch-move t) ;; Handle universal argument for motion commands when both ;; `isearch-allow-scroll' and `isearch-allow-prefix' are nil. @@ -2546,9 +2549,25 @@ (defun isearch-other-meta-char (&optiona ;; Use the last key in the sequence. (vector (aref key (1- (length key)))))))) (setq prefix-arg arg) - (isearch-yank-internal - (lambda () (command-execute move-command) (point))) - (isearch-update) + (let* ((old-point (or (and (not isearch-forward) isearch-other-end) + (point))) + (new-point (save-excursion + (goto-char old-point) + (command-execute move-command) + (point)))) + (if (< old-point new-point) + ;; Add text to the search string. + (isearch-yank-string + (buffer-substring-no-properties old-point new-point)) + ;; Remove text from the search string. + (setq isearch-string (substring isearch-string 0 + (max (- (length isearch-string) + (- old-point new-point)) 0)) + isearch-message (mapconcat 'isearch-text-char-description + isearch-string "")) + ;; Don't move cursor in reverse search. + (setq isearch-yank-flag t) + (isearch-search-and-update))) (setq isearch-allow-move-temporarily t)) ;; A mouse click on the isearch message starts editing the search string ((and (eq (car-safe main-event) 'down-mouse-1) ^ permalink raw reply [flat|nested] 51+ messages in thread
* Re: isearch-allow-move [Was: isearch-allow-prefix] 2013-06-07 6:59 ` Juri Linkov @ 2013-06-07 10:30 ` Alan Mackenzie 2013-06-07 19:30 ` Juri Linkov 0 siblings, 1 reply; 51+ messages in thread From: Alan Mackenzie @ 2013-06-07 10:30 UTC (permalink / raw) To: Juri Linkov; +Cc: Stefan Monnier, Drew Adams, emacs-devel Hi, Juri! On Fri, Jun 07, 2013 at 09:59:49AM +0300, Juri Linkov wrote: > > But what does it mean to C-f with a prefix arg of -1? Does it mean > > "remove the last char from the search string"? If not, why not? > > Or maybe a negative prefix argument would cause the command to be ignored. > > Or maybe C-b would be allowed here to remove the last char from the > > search string. > Good idea. This is implemented now by this patch (cumulative to > the previously sent one) where `C-b' or `C-u -1 C-f' removes the > last char from the search string (`M-b' removes the last word, > `C-M-b' removes the last expression, etc. allowing key sequences like > `M-s C-b M-b C-M-b'), and eventually stops removing characters at the > beginning of the current match when the search string becomes empty. > Is this approach simple enough and intuitive? I don't think so. What happens in a regexp search? Particularly when the last typed characters are "\)" or "]", or "?", or there's still an unbalanced "\(" in the string. What does M-b do then? My gut feeling is that this proposal will add complexity rather than reducing it, and the new facility won't be worth that cost. -- Alan Mackenzie (Nuremberg, Germany). ^ permalink raw reply [flat|nested] 51+ messages in thread
* Re: isearch-allow-move [Was: isearch-allow-prefix] 2013-06-07 10:30 ` Alan Mackenzie @ 2013-06-07 19:30 ` Juri Linkov 2013-06-09 20:09 ` Juri Linkov 0 siblings, 1 reply; 51+ messages in thread From: Juri Linkov @ 2013-06-07 19:30 UTC (permalink / raw) To: Alan Mackenzie; +Cc: Stefan Monnier, Drew Adams, emacs-devel > What happens in a regexp search? Particularly when the last typed > characters are "\)" or "]", or "?", or there's still an unbalanced > "\(" in the string. It does exactly the same as `C-M-w' already does in a regexp search. IOW, the new feature just replaces `C-M-r ... C-M-w C-M-w ...' with a more intuitive key sequence `C-M-r ... M-s C-b C-b ...' If the existing `C-M-w' (isearch-del-char) has some problems, then `M-s C-b' shares the same problems with it, although I'm not aware of any problems with `isearch-del-char'. However, the new feature `M-s C-f' helped to discover a problem in a word search where the same problem exists in `C-M-y' (isearch-yank-char). Test case: type `M-s w C-M-y C-M-y ...' and see how it fails to grab the next character at the word boundary at the end of the word. This bug should be fixed with the following patch: === modified file 'lisp/isearch.el' --- lisp/isearch.el 2013-06-05 20:57:09 +0000 +++ lisp/isearch.el 2013-06-07 19:28:35 +0000 @@ -1549,7 +1635,7 @@ (defun word-search-regexp (string &optio "" (concat "\\b" - (mapconcat 'identity (split-string string "\\W+" t) "\\W+") + (mapconcat 'identity (split-string string "\\W+") "\\W+") (if (or (not lax) (string-match-p "\\W$" string)) "\\b")))) ^ permalink raw reply [flat|nested] 51+ messages in thread
* Re: isearch-allow-move [Was: isearch-allow-prefix] 2013-06-07 19:30 ` Juri Linkov @ 2013-06-09 20:09 ` Juri Linkov 2013-06-11 19:35 ` Juri Linkov 0 siblings, 1 reply; 51+ messages in thread From: Juri Linkov @ 2013-06-09 20:09 UTC (permalink / raw) To: Alan Mackenzie; +Cc: Stefan Monnier, Drew Adams, emacs-devel > However, the new feature `M-s C-f' helped to discover a problem > in a word search where the same problem exists in `C-M-y' > (isearch-yank-char). Actually removing OMIT-NULLS from `split-string' produces a wrong regexp "\\bw\\W+\\b" for the input string "w ". Better is to handle leading/trailing whitespace explicitly to produce more correct regexp "\\bw\\b\\W+" as the patch below does. This feature also helped to discover more problems (in addition to the above mentioned problem where `isearch-yank-char' failed to yank trailing whitespace). Another problem is that `word-search-regexp' fails to handle multi-line matches. This problem can be fixed by using "\\`" instead of "\\^" in `word-search-regexp'. The third problem is the need to apply the LAX arg to the beginning of the regexp in a reverse search that can be fixed by adding a new argument BACKWARD to `word-search-regexp'. `isearch-symbol-regexp' requires the same changes that will make it a copy of `word-search-regexp' that uses "\\_<" and "\\_>" instead of "\\b". === modified file 'lisp/isearch.el' --- lisp/isearch.el 2013-06-06 06:23:19 +0000 +++ lisp/isearch.el 2013-06-09 20:08:29 +0000 @@ -1536,7 +1638,7 @@ (defun isearch-toggle-invisible () \f ;; Word search -(defun word-search-regexp (string &optional lax) +(defun word-search-regexp (string &optional lax backward) "Return a regexp which matches words, ignoring punctuation. Given STRING, a string of words separated by word delimiters, compute a regexp that matches those exact words separated by @@ -1545,12 +1647,14 @@ (defun word-search-regexp (string &optio Used in `word-search-forward', `word-search-backward', `word-search-forward-lax', `word-search-backward-lax'." - (if (string-match-p "^\\W*$" string) - "" + (if (string-match-p "\\`\\W*\\'" string) + "\\W*" (concat - "\\b" - (mapconcat 'identity (split-string string "\\W+" t) "\\W+") - (if (or (not lax) (string-match-p "\\W$" string)) "\\b")))) + (if (string-match-p "\\`\\W" string) "\\W+") + (if (or (not lax) (not backward)) "\\b") + (mapconcat 'regexp-quote (split-string string "\\W+" t) "\\W+") + (if (or (not lax) backward) "\\b") + (if (string-match-p "\\W\\'" string) "\\W+")))) (defun word-search-backward (string &optional bound noerror count) "Search backward from point for STRING, ignoring differences in punctuation. @@ -1565,7 +1669,7 @@ (defun word-search-backward (string &opt of words in STRING to a regexp used to search words without regard to punctuation." (interactive "sWord search backward: ") - (re-search-backward (word-search-regexp string nil) bound noerror count)) + (re-search-backward (word-search-regexp string nil t) bound noerror count)) (defun word-search-forward (string &optional bound noerror count) "Search forward from point for STRING, ignoring differences in punctuation. @@ -1580,7 +1684,7 @@ (defun word-search-forward (string &opti of words in STRING to a regexp used to search words without regard to punctuation." (interactive "sWord search: ") - (re-search-forward (word-search-regexp string nil) bound noerror count)) + (re-search-forward (word-search-regexp string nil nil) bound noerror count)) (defun word-search-backward-lax (string &optional bound noerror count) "Search backward from point for STRING, ignoring differences in punctuation. @@ -1599,7 +1703,7 @@ (defun word-search-backward-lax (string of words in STRING to a regexp used to search words without regard to punctuation." (interactive "sWord search backward: ") - (re-search-backward (word-search-regexp string t) bound noerror count)) + (re-search-backward (word-search-regexp string t t) bound noerror count)) (defun word-search-forward-lax (string &optional bound noerror count) "Search forward from point for STRING, ignoring differences in punctuation. @@ -1618,15 +1722,22 @@ (defun word-search-forward-lax (string & of words in STRING to a regexp used to search words without regard to punctuation." (interactive "sWord search: ") - (re-search-forward (word-search-regexp string t) bound noerror count)) + (re-search-forward (word-search-regexp string t nil) bound noerror count)) ;; Symbol search -(defun isearch-symbol-regexp (string &optional lax) +(defun isearch-symbol-regexp (string &optional lax backward) "Return a regexp which matches STRING as a symbol. Creates a regexp where STRING is surrounded by symbol delimiters \\_< and \\_>. If LAX is non-nil, the end of the string need not match a symbol boundary." - (concat "\\_<" (regexp-quote string) (unless lax "\\_>"))) + (if (string-match-p "\\`\\W*\\'" string) + "\\W*" + (concat + (if (string-match-p "\\`\\W" string) "\\W+") + (if (or (not lax) (not backward)) "\\_<") + (mapconcat 'regexp-quote (split-string string "\\W+" t) "\\W+") + (if (or (not lax) backward) "\\_>") + (if (string-match-p "\\W\\'" string) "\\W+")))) PS: a table that summarizes the returned values after the change: (word-search-regexp "" ) "\\W*" (word-search-regexp " " ) "\\W*" (word-search-regexp "w" ) "\\bw\\b" (word-search-regexp " w" ) "\\W+\\bw\\b" (word-search-regexp "w " ) "\\bw\\b\\W+" (word-search-regexp " w " ) "\\W+\\bw\\b\\W+" (word-search-regexp "w w" ) "\\bw\\W+w\\b" (word-search-regexp " w w" ) "\\W+\\bw\\W+w\\b" (word-search-regexp "w w " ) "\\bw\\W+w\\b\\W+" (word-search-regexp " w w ") "\\W+\\bw\\W+w\\b\\W+" (word-search-regexp "" nil t) "\\W*" (word-search-regexp " " nil t) "\\W*" (word-search-regexp "w" nil t) "\\bw\\b" (word-search-regexp " w" nil t) "\\W+\\bw\\b" (word-search-regexp "w " nil t) "\\bw\\b\\W+" (word-search-regexp " w " nil t) "\\W+\\bw\\b\\W+" (word-search-regexp "w w" nil t) "\\bw\\W+w\\b" (word-search-regexp " w w" nil t) "\\W+\\bw\\W+w\\b" (word-search-regexp "w w " nil t) "\\bw\\W+w\\b\\W+" (word-search-regexp " w w " nil t) "\\W+\\bw\\W+w\\b\\W+" (word-search-regexp "" t) "\\W*" (word-search-regexp " " t) "\\W*" (word-search-regexp "w" t) "\\bw" (word-search-regexp " w" t) "\\W+\\bw" (word-search-regexp "w " t) "\\bw\\W+" (word-search-regexp " w " t) "\\W+\\bw\\W+" (word-search-regexp "w w" t) "\\bw\\W+w" (word-search-regexp " w w" t) "\\W+\\bw\\W+w" (word-search-regexp "w w " t) "\\bw\\W+w\\W+" (word-search-regexp " w w " t) "\\W+\\bw\\W+w\\W+" (word-search-regexp "" t t) "\\W*" (word-search-regexp " " t t) "\\W*" (word-search-regexp "w" t t) "w\\b" (word-search-regexp " w" t t) "\\W+w\\b" (word-search-regexp "w " t t) "w\\b\\W+" (word-search-regexp " w " t t) "\\W+w\\b\\W+" (word-search-regexp "w w" t t) "w\\W+w\\b" (word-search-regexp " w w" t t) "\\W+w\\W+w\\b" (word-search-regexp "w w " t t) "w\\W+w\\b\\W+" (word-search-regexp " w w " t t) "\\W+w\\W+w\\b\\W+" (isearch-symbol-regexp "" ) "\\W*" (isearch-symbol-regexp " " ) "\\W*" (isearch-symbol-regexp "w" ) "\\_<w\\_>" (isearch-symbol-regexp " w" ) "\\W+\\_<w\\_>" (isearch-symbol-regexp "w " ) "\\_<w\\_>\\W+" (isearch-symbol-regexp " w " ) "\\W+\\_<w\\_>\\W+" (isearch-symbol-regexp "w w" ) "\\_<w\\W+w\\_>" (isearch-symbol-regexp " w w" ) "\\W+\\_<w\\W+w\\_>" (isearch-symbol-regexp "w w " ) "\\_<w\\W+w\\_>\\W+" (isearch-symbol-regexp " w w ") "\\W+\\_<w\\W+w\\_>\\W+" (isearch-symbol-regexp "" nil t) "\\W*" (isearch-symbol-regexp " " nil t) "\\W*" (isearch-symbol-regexp "w" nil t) "\\_<w\\_>" (isearch-symbol-regexp " w" nil t) "\\W+\\_<w\\_>" (isearch-symbol-regexp "w " nil t) "\\_<w\\_>\\W+" (isearch-symbol-regexp " w " nil t) "\\W+\\_<w\\_>\\W+" (isearch-symbol-regexp "w w" nil t) "\\_<w\\W+w\\_>" (isearch-symbol-regexp " w w" nil t) "\\W+\\_<w\\W+w\\_>" (isearch-symbol-regexp "w w " nil t) "\\_<w\\W+w\\_>\\W+" (isearch-symbol-regexp " w w " nil t) "\\W+\\_<w\\W+w\\_>\\W+" (isearch-symbol-regexp "" t) "\\W*" (isearch-symbol-regexp " " t) "\\W*" (isearch-symbol-regexp "w" t) "\\_<w" (isearch-symbol-regexp " w" t) "\\W+\\_<w" (isearch-symbol-regexp "w " t) "\\_<w\\W+" (isearch-symbol-regexp " w " t) "\\W+\\_<w\\W+" (isearch-symbol-regexp "w w" t) "\\_<w\\W+w" (isearch-symbol-regexp " w w" t) "\\W+\\_<w\\W+w" (isearch-symbol-regexp "w w " t) "\\_<w\\W+w\\W+" (isearch-symbol-regexp " w w " t) "\\W+\\_<w\\W+w\\W+" (isearch-symbol-regexp "" t t) "\\W*" (isearch-symbol-regexp " " t t) "\\W*" (isearch-symbol-regexp "w" t t) "w\\_>" (isearch-symbol-regexp " w" t t) "\\W+w\\_>" (isearch-symbol-regexp "w " t t) "w\\_>\\W+" (isearch-symbol-regexp " w " t t) "\\W+w\\_>\\W+" (isearch-symbol-regexp "w w" t t) "w\\W+w\\_>" (isearch-symbol-regexp " w w" t t) "\\W+w\\W+w\\_>" (isearch-symbol-regexp "w w " t t) "w\\W+w\\_>\\W+" (isearch-symbol-regexp " w w " t t) "\\W+w\\W+w\\_>\\W+" ^ permalink raw reply [flat|nested] 51+ messages in thread
* Re: isearch-allow-move [Was: isearch-allow-prefix] 2013-06-09 20:09 ` Juri Linkov @ 2013-06-11 19:35 ` Juri Linkov 0 siblings, 0 replies; 51+ messages in thread From: Juri Linkov @ 2013-06-11 19:35 UTC (permalink / raw) To: emacs-devel; +Cc: Alan Mackenzie, Stefan Monnier, Drew Adams > `isearch-symbol-regexp' requires the same changes > that will make it a copy of `word-search-regexp' > that uses "\\_<" and "\\_>" instead of "\\b". But it also requires changing "\\W+" (used in `word-search-regexp') to a regexp that doesn't match symbols. IOW, in a word search `word-search-regexp' uses the "\\W+" regexp to skip non-word characters, so `isearch-symbol-regexp' needs to do the same to also skip non-symbol characters. Unfortunately I have no idea how to do this. What is needed is a negation of the regexp "\\(\\sw\\|\\s_\\)+" to match any character except the ones that have word syntax or symbol syntax. Naively I tried "[^\\sw\\s_]+" but it fails to work the same way as it works for e.g. "[^[:word:]]". Whereas (skip-syntax-forward "^w_") moves point across characters whose syntax is not word or symbol, I see no way to do the same with a regexp. Could someone please help me write a regexp that matches a non-word non-symbol character? ^ permalink raw reply [flat|nested] 51+ messages in thread
* Re: isearch-allow-move [Was: isearch-allow-prefix] 2013-06-06 20:07 ` Alan Mackenzie 2013-06-07 6:59 ` Juri Linkov @ 2013-06-07 20:04 ` Juri Linkov 1 sibling, 0 replies; 51+ messages in thread From: Juri Linkov @ 2013-06-07 20:04 UTC (permalink / raw) To: Alan Mackenzie; +Cc: Stefan Monnier, Drew Adams, emacs-devel > You could then use it to erase the entire search string and then > convert a forward search into backward search by another C-b. Converting a forward search into backward search turned out to be a very good idea. After trying it I see that this is the most natural thing to do. The updated part of the patch is below (most code should be refactored to more general functions, so the remaining code should leave about 30 lines here): === modified file 'lisp/isearch.el' --- lisp/isearch.el 2013-06-05 20:57:09 +0000 +++ lisp/isearch.el 2013-06-07 19:55:08 +0000 @@ -2336,6 +2540,72 @@ (defun isearch-other-meta-char (&optiona (isearch-back-into-window (eq ab-bel 'above) isearch-point) (goto-char isearch-point))) (isearch-update)) + ;; Handle a motion function. + ((and (or isearch-allow-move isearch-allow-move-temporarily) + (progn (setq key (isearch-reread-key-sequence-naturally keylist)) + (setq keylist (listify-key-sequence key)) + (setq main-event (aref key 0)) + (setq move-command (or + (isearch-lookup-move-key key) + (isearch-lookup-move-key + ;; Use the last key in the sequence. + (vector (aref key (1- (length key))))))) + isearch-success)) + (setq prefix-arg arg) + (let* ((old-point (point)) + (new-point (save-excursion + (condition-case () + (command-execute move-command) + (error nil)) + (point)))) + ;; Change search direction between forward and backward. + (when (and isearch-other-end + (not isearch-error) ; for regexp incomplete input + (if isearch-forward + (< new-point isearch-other-end) + (> new-point isearch-other-end))) + (setq isearch-forward (not isearch-forward)) + (setq isearch-string "" isearch-message "") + (setq old-point isearch-other-end)) + (if (< old-point new-point) + ;; Add text to the search string. + (if isearch-forward + (isearch-yank-string + (buffer-substring-no-properties old-point new-point)) + ;; In backward search delete text from beginning of search string. + (setq isearch-string (substring isearch-string + (min (- new-point old-point) + (length isearch-string)) + (length isearch-string)) + isearch-message (mapconcat 'isearch-text-char-description + isearch-string "")) + (setq isearch-yank-flag t) + (goto-char new-point) + (isearch-search-and-update)) + (if isearch-forward + (progn + ;; Delete text from the search string. + (setq isearch-string (substring isearch-string 0 + (max (- (length isearch-string) + (- old-point new-point)) 0)) + isearch-message (mapconcat 'isearch-text-char-description + isearch-string "")) + (setq isearch-yank-flag t) + (isearch-search-and-update)) + ;; In backward search add text to beginning of search string. + (setq isearch-string + (concat + (if isearch-regexp + (regexp-quote + (buffer-substring-no-properties old-point new-point)) + (buffer-substring-no-properties old-point new-point)) + isearch-string) + isearch-message (mapconcat 'isearch-text-char-description + isearch-string "")) + (setq isearch-yank-flag t) + (goto-char new-point) + (isearch-search-and-update)))) + (setq isearch-allow-move-temporarily t)) ;; A mouse click on the isearch message starts editing the search string ((and (eq (car-safe main-event) 'down-mouse-1) (window-minibuffer-p (posn-window (event-start main-event)))) ^ permalink raw reply [flat|nested] 51+ messages in thread
* [PATCH] set-temporary-overlay-map improvement and make windresize exit on other commands 2013-05-23 22:04 ` Juri Linkov 2013-05-24 9:38 ` Alan Mackenzie @ 2013-06-09 12:07 ` Vitalie Spinu 2013-06-09 16:03 ` Stefan Monnier 1 sibling, 1 reply; 51+ messages in thread From: Vitalie Spinu @ 2013-06-09 12:07 UTC (permalink / raw) To: Juri Linkov; +Cc: Stefan Monnier, Gauthier Östervall, emacs-devel [-- Attachment #1: Type: text/plain, Size: 756 bytes --] Here are two simple patches that make windresize work with set-temporary-overlay-map. First patch is to emacs trunk and adds ON-EXIT argument to set-temporary-overlay-map. Irrespective of windresize I think this is a useful addition anyhow. It opens the way for set-temporary-overlay-map to be directly used by electric commands that need to clean up temporary buffers, messages, window configuration etc. Second patch is to windresize. Depending on the value of windresize-exit-on-other-command, windresize will exit on any other command than those defined in windresize-map. I set it to t by default. It seems like a nicer default given the discussion on current thread. My .emacs now has (define-key ctl-x-map "w" 'windresize) Vitalie [-- Warning: decoded text below may be mangled, UTF-8 assumed --] [-- Attachment #2: 0001-add-ON-EXIT-argument-to-set-temporary-overlay-map.patch --] [-- Type: text/x-diff, Size: 2200 bytes --] From 103046272cb842451c57c6bf097755b2ef40f474 Mon Sep 17 00:00:00 2001 From: Vitalie Spinu <spinuvit@gmail.com> Date: Sun, 9 Jun 2013 13:38:23 +0200 Subject: [PATCH] add ON-EXIT argument to set-temporary-overlay-map * lisp/subr.el (set-temporary-overlay-map): Optional ON-EXIT argument is a function that is called after the deactivation of MAP. --- lisp/subr.el | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/lisp/subr.el b/lisp/subr.el index 65943ae..bb35a9a 100644 --- a/lisp/subr.el +++ b/lisp/subr.el @@ -4260,7 +4260,7 @@ If NUM is non-nil, return non-nil iff F can be called with NUM args." (and (>= num (car res)) (or (eq 'many (cdr res)) (<= num (cdr res))))))) -(defun set-temporary-overlay-map (map &optional keep-pred) +(defun set-temporary-overlay-map (map &optional keep-pred on-exit) "Set MAP as a temporary keymap taking precedence over most other keymaps. Note that this does NOT take precedence over the \"overriding\" maps `overriding-terminal-local-map' and `overriding-local-map' (or the @@ -4270,7 +4270,10 @@ found in MAP, the normal key lookup sequence then continues. Normally, MAP is used only once. If the optional argument KEEP-PRED is t, MAP stays active if a key from MAP is used. KEEP-PRED can also be a function of no arguments: if it returns -non-nil then MAP stays active." +non-nil then MAP stays active. + +Optional ON-EXIT argument is a function that is called after the +deactivation of MAP." (let* ((clearfunsym (make-symbol "clear-temporary-overlay-map")) (overlaysym (make-symbol "t")) (alist (list (cons overlaysym map))) @@ -4286,7 +4289,9 @@ non-nil then MAP stays active." (set ',overlaysym nil) ;Just in case. (remove-hook 'pre-command-hook ',clearfunsym) (setq emulation-mode-map-alists - (delq ',alist emulation-mode-map-alists)))))) + (delq ',alist emulation-mode-map-alists)) + ,(when on-exit + `(funcall ',on-exit)))))) (set overlaysym overlaysym) (fset clearfunsym clearfun) (add-hook 'pre-command-hook clearfunsym) -- 1.8.1.2 [-- Warning: decoded text below may be mangled, UTF-8 assumed --] [-- Attachment #3: patch-windresize-exit-on-other-command.patch --] [-- Type: text/x-diff, Size: 2056 bytes --] *** /home/vitoshka/Dropbox/ELPA/windresize-0.1/windresize.el.~1~ 2013-06-09 12:01:27.257902916 +0200 --- /home/vitoshka/Dropbox/ELPA/windresize-0.1/windresize.el 2013-06-09 13:46:50.737784424 +0200 *************** *** 109,114 **** --- 109,120 ---- :group 'convenience :type 'integer) + (defcustom windresize-exit-on-other-command t + "If non-nil, windresize will exit on any command not defined in + `windresize-map'" + :group 'convenience + :type 'boolean) + (defcustom windresize-modifiers '((meta shift) meta (control meta) control) "A list of modifiers for arrow keys commands. *************** *** 157,164 **** (defvar windresize-map (let ((map (make-sparse-keymap))) (define-key map [remap self-insert-command] 'windresize-other-char) - (define-key map (kbd "M-x") 'windresize-other-char) - (define-key map (kbd "C-h") 'windresize-other-char) ;; move borders outwards or shrink/enlarge (define-key map [left] 'windresize-left) (define-key map [right] 'windresize-right) --- 163,168 ---- *************** *** 364,371 **** (current-window-configuration)) (setq windresize-buffer (current-buffer)) ;; set overriding map and pre/post-command hooks ! (setq overriding-terminal-local-map windresize-map) ! (setq overriding-local-map-menu-flag t) (windresize-add-command-hooks) ;; set the initial message (setq windresize-msg --- 368,379 ---- (current-window-configuration)) (setq windresize-buffer (current-buffer)) ;; set overriding map and pre/post-command hooks ! (if windresize-exit-on-other-command ! (set-temporary-overlay-map windresize-map t 'windresize-exit) ! (define-key windresize-map (kbd "M-x") 'windresize-other-char) ! (define-key windresize-map (kbd "C-h") 'windresize-other-char) ! (setq overriding-terminal-local-map windresize-map) ! (setq overriding-local-map-menu-flag t)) (windresize-add-command-hooks) ;; set the initial message (setq windresize-msg [-- Attachment #4: Type: text/plain, Size: 2396 bytes --] >> Juri Linkov <juri@jurta.org> >> on Fri, 24 May 2013 01:04:40 +0300 wrote: >>> I will give it a try, but I feel that functionality should be >>> built-in. >> >> Yes clearly, that is needed before we can consider it to make C-x >> [{}^] redundant. JL> If the goal is to replace `C-x [{}^]' with one global keybinding, JL> the currently free and intuitive key prefix for window related commands JL> would be `C-x w', so that a command to activate window-resizing JL> key sequence could be bound to `C-x w r'. JL> Until this is implemented, something like below could help JL> for experimenting with possible implementations: JL> (defvar window-resize-keymap JL> (let ((map (make-sparse-keymap))) JL> ;; Standard keys: JL> (define-key map "0" 'delete-window) JL> (define-key map "1" 'delete-other-windows) JL> (define-key map "2" 'split-window-below) JL> (define-key map "3" 'split-window-right) JL> (define-key map "o" 'other-window) JL> (define-key map "^" 'enlarge-window) JL> (define-key map "}" 'enlarge-window-horizontally) JL> (define-key map "{" 'shrink-window-horizontally) JL> (define-key map "-" 'shrink-window-if-larger-than-buffer) JL> (define-key map "+" 'balance-windows) JL> ;; Additional keys: JL> (define-key map "v" 'shrink-window) JL> (define-key map [down] 'shrink-window) JL> (define-key map [up] 'enlarge-window) JL> (define-key map [left] 'shrink-window-horizontally) JL> (define-key map [right] 'enlarge-window-horizontally) JL> map) JL> "Keymap to resize windows.") JL> (advice-add 'enlarge-window-horizontally :after (lambda (delta) JL> (set-temporary-overlay-map window-resize-keymap))) JL> (advice-add 'shrink-window-horizontally :after (lambda (delta) JL> (set-temporary-overlay-map window-resize-keymap))) JL> (advice-add 'enlarge-window :after (lambda (delta &optional horizontal) JL> (set-temporary-overlay-map window-resize-keymap))) JL> (advice-add 'shrink-window :after (lambda (delta &optional horizontal) JL> (set-temporary-overlay-map window-resize-keymap))) JL> (defun window-resize-init () JL> (interactive) JL> (message "Use window-resizing keys...") JL> (set-temporary-overlay-map window-resize-keymap)) JL> (define-key ctl-x-map "wr" 'window-resize-init) ^ permalink raw reply related [flat|nested] 51+ messages in thread
* Re: [PATCH] set-temporary-overlay-map improvement and make windresize exit on other commands 2013-06-09 12:07 ` [PATCH] set-temporary-overlay-map improvement and make windresize exit on other commands Vitalie Spinu @ 2013-06-09 16:03 ` Stefan Monnier 2013-06-09 17:12 ` Vitalie Spinu 0 siblings, 1 reply; 51+ messages in thread From: Stefan Monnier @ 2013-06-09 16:03 UTC (permalink / raw) To: Vitalie Spinu; +Cc: Juri Linkov, Gauthier Östervall, emacs-devel > First patch is to emacs trunk and adds ON-EXIT argument to > set-temporary-overlay-map. Irrespective of windresize I think this is a > useful addition anyhow. It opens the way for set-temporary-overlay-map > to be directly used by electric commands that need to clean up temporary > buffers, messages, window configuration etc. That looks fine, thanks. > Second patch is to windresize. Depending on the value of > windresize-exit-on-other-command, windresize will exit on any other > command than those defined in windresize-map. I set it to t by > default. It seems like a nicer default given the discussion on current > thread. I don't think it's worth the trouble to keep the "windresize-exit-on-other-command==nil" option. Stefan ^ permalink raw reply [flat|nested] 51+ messages in thread
* Re: [PATCH] set-temporary-overlay-map improvement and make windresize exit on other commands 2013-06-09 16:03 ` Stefan Monnier @ 2013-06-09 17:12 ` Vitalie Spinu 2013-06-13 20:44 ` Stefan Monnier 0 siblings, 1 reply; 51+ messages in thread From: Vitalie Spinu @ 2013-06-09 17:12 UTC (permalink / raw) To: Stefan Monnier; +Cc: Juri Linkov, bzg, Gauthier Östervall, emacs-devel [-- Attachment #1: Type: text/plain, Size: 925 bytes --] >> Stefan Monnier <monnier@iro.umontreal.ca> >> on Sun, 09 Jun 2013 12:03:55 -0400 wrote: [...] >> Second patch is to windresize. Depending on the value of >> windresize-exit-on-other-command, windresize will exit on any other >> command than those defined in windresize-map. I set it to t by >> default. It seems like a nicer default given the discussion on current >> thread. > I don't think it's worth the trouble to keep the > "windresize-exit-on-other-command==nil" option. I agree. It also leads to a simpler code, so here it is. The patch is against elpa branch. It does rely on 'on-exit argument for set-temporary-overlay-map in my other patch. So it makes sense only if windresize becomes part of emacs proper (thing that I infer conceivable from your previous posts). Otherwise an explicit check for versions should be introduced and also windresize-exit-on-other-command probably kept. Vitalie [-- Warning: decoded text below may be mangled, UTF-8 assumed --] [-- Attachment #2: 0001-windresize-exit-on-other-commands.patch --] [-- Type: text/x-diff, Size: 2230 bytes --] From e2784f98c2c7e2a34d03e6b81553c902573854f8 Mon Sep 17 00:00:00 2001 From: Vitalie Spinu <spinuvit@gmail.com> Date: Sun, 9 Jun 2013 18:55:19 +0200 Subject: [PATCH] windresize: exit on other commands * packages/windresize/windresize.el: remove `windresize-other-char' (windresize): use `set-temporary-overlay-map' instead of `overriding-local-map' (windresize-map): Don't bind M-x and C-h in `windresize-map' --- packages/windresize/windresize.el | 19 +------------------ 1 file changed, 1 insertion(+), 18 deletions(-) diff --git a/packages/windresize/windresize.el b/packages/windresize/windresize.el index e13dd3f..7378b46 100755 --- a/packages/windresize/windresize.el +++ b/packages/windresize/windresize.el @@ -156,9 +156,6 @@ conflicts between keybindings." (defvar windresize-map (let ((map (make-sparse-keymap))) - (define-key map [remap self-insert-command] 'windresize-other-char) - (define-key map (kbd "M-x") 'windresize-other-char) - (define-key map (kbd "C-h") 'windresize-other-char) ;; move borders outwards or shrink/enlarge (define-key map [left] 'windresize-left) (define-key map [right] 'windresize-right) @@ -240,19 +237,6 @@ conflicts between keybindings." map) "Keymap for `windresize'.") -(defun windresize-other-char () - "Show a message instead of processing `self-insert-command'." - (interactive) - (let* ((key (if current-prefix-arg - (substring (this-command-keys) - universal-argument-num-events) - (this-command-keys)))) - (cond ((vectorp key) (ding)) - ((stringp key) - ;; send warning for only no warning for complex keys and - ;; mouse events - (setq windresize-msg - (cons (format "[`%s' not bound]" key) 1)))))) ;;; Aliases: @@ -364,8 +348,7 @@ will set the new window configuration and exit. (current-window-configuration)) (setq windresize-buffer (current-buffer)) ;; set overriding map and pre/post-command hooks - (setq overriding-terminal-local-map windresize-map) - (setq overriding-local-map-menu-flag t) + (set-temporary-overlay-map windresize-map t 'windresize-exit) (windresize-add-command-hooks) ;; set the initial message (setq windresize-msg -- 1.8.1.2 ^ permalink raw reply related [flat|nested] 51+ messages in thread
* Re: [PATCH] set-temporary-overlay-map improvement and make windresize exit on other commands 2013-06-09 17:12 ` Vitalie Spinu @ 2013-06-13 20:44 ` Stefan Monnier 0 siblings, 0 replies; 51+ messages in thread From: Stefan Monnier @ 2013-06-13 20:44 UTC (permalink / raw) To: Vitalie Spinu; +Cc: Juri Linkov, bzg, Gauthier Östervall, emacs-devel >> I don't think it's worth the trouble to keep the >> "windresize-exit-on-other-command==nil" option. > I agree. It also leads to a simpler code, so here it is. Right, the simplification is the main motivation. > The patch is against elpa branch. It does rely on 'on-exit argument for > set-temporary-overlay-map in my other patch. I just installed that on-exit on the trunk, thanks. > So it makes sense only if windresize becomes part of emacs proper > (thing that I infer conceivable from your previous posts). Oh, good point. Stefan ^ permalink raw reply [flat|nested] 51+ messages in thread
end of thread, other threads:[~2013-06-13 20:44 UTC | newest] Thread overview: 51+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2013-05-20 19:59 [PATCH] Make `C-x {' and `C-x }' repeatable Gauthier Östervall 2013-05-21 9:58 ` Vitalie Spinu 2013-05-21 13:53 ` Gauthier Östervall 2013-05-21 18:34 ` Juri Linkov 2013-05-22 17:44 ` Drew Adams 2013-05-22 18:55 ` Juri Linkov 2013-05-22 21:39 ` Drew Adams 2013-05-22 22:08 ` Stefan Monnier 2013-05-22 23:53 ` Drew Adams 2013-05-23 0:18 ` chad 2013-05-23 16:19 ` Drew Adams 2013-05-23 16:48 ` Stefan Monnier 2013-05-23 19:52 ` Drew Adams 2013-05-24 4:53 ` Stephen J. Turnbull 2013-05-24 15:55 ` Drew Adams 2013-05-24 17:00 ` Stephen J. Turnbull 2013-05-22 21:47 ` Stefan Monnier 2013-05-22 22:24 ` Stefan Monnier 2013-05-22 23:53 ` Drew Adams 2013-05-23 22:30 ` Juri Linkov 2013-05-24 3:58 ` Stefan Monnier 2013-05-22 19:05 ` Stefan Monnier 2013-05-23 12:21 ` Gauthier Östervall 2013-05-23 13:41 ` Stefan Monnier 2013-05-23 22:04 ` Juri Linkov 2013-05-24 9:38 ` Alan Mackenzie 2013-05-24 20:31 ` Juri Linkov 2013-05-25 20:01 ` Alan Mackenzie 2013-05-25 20:40 ` Juri Linkov 2013-06-02 21:05 ` isearch-allow-prefix [Was: [PATCH] Make `C-x {' and `C-x }' repeatable] Alan Mackenzie 2013-06-04 18:03 ` Juri Linkov 2013-06-04 21:24 ` Alan Mackenzie 2013-06-05 8:23 ` Juri Linkov 2013-06-05 21:02 ` Alan Mackenzie 2013-06-06 6:07 ` isearch-allow-move [Was: isearch-allow-prefix] Juri Linkov 2013-06-06 12:45 ` Stefan Monnier 2013-06-06 15:07 ` Juri Linkov 2013-06-06 15:43 ` Drew Adams 2013-06-06 16:39 ` Stefan Monnier 2013-06-07 7:07 ` Juri Linkov 2013-06-06 20:07 ` Alan Mackenzie 2013-06-07 6:59 ` Juri Linkov 2013-06-07 10:30 ` Alan Mackenzie 2013-06-07 19:30 ` Juri Linkov 2013-06-09 20:09 ` Juri Linkov 2013-06-11 19:35 ` Juri Linkov 2013-06-07 20:04 ` Juri Linkov 2013-06-09 12:07 ` [PATCH] set-temporary-overlay-map improvement and make windresize exit on other commands Vitalie Spinu 2013-06-09 16:03 ` Stefan Monnier 2013-06-09 17:12 ` Vitalie Spinu 2013-06-13 20:44 ` Stefan Monnier
Code repositories for project(s) associated with this external index https://git.savannah.gnu.org/cgit/emacs.git https://git.savannah.gnu.org/cgit/emacs/org-mode.git This is an external index of several public inboxes, see mirroring instructions on how to clone and mirror all data and code used by this external index.