emacs-devel
[Top][All Lists]
Advanced

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

option to let selected commands act on search string instead of exiting


From: Drew Adams
Subject: option to let selected commands act on search string instead of exiting Isearch
Date: Fri, 27 May 2011 18:56:46 -0700

Interaction with the Isearch search string is similar to
interaction with the minibuffer in some ways.  But not in others.

In particular, in order to make changes to places other than the
very end of the search string, you need to enter an editing mode,
using `M-e'.

Whereas in the minibuffer you would just back up using `C-b',
`M-b', or similar to get to a position where you wanted to
change, delete, or insert chars, with Isearch you first need to
hit `M-e'.  A minor difference, but the flow doesn't feel the
same.  We are all of course used to this and think nothing of it.

If you hit `C-b' without `M-e' first then you break out of
Isearch altogether - the `backward-char' command is applied to
the buffer text, not to the search string.

For some commands/keys this exiting of Isearch is essential.  For
others it is probably what you want, at least most of the time.
But for some others it might not be.

By default, keys that delete chars at the end of the search
string do not break out of Isearch; they act directly on the
search string, not the buffer text.  `DEL' does not exit Isearch
and delete the char before point!  Again, this all seems
completely natural to us by now.  We take it for granted.

The behavior of any given key is decided by the Isearch code, but
you can of course customize the bindings in `isearch-mode-map'.
Not a big deal, in any case.

And yes, most of what we do is in fact to modify the end of the
search string.  This is incremental search, after all, and the
end is where the incrementing takes place.

But it is often (and increasingly?) the case that we reuse a
search string, either a previous search or text we yank as a copy
of the region.  And as is often the case with reuse, sometimes we
need to modify the string being reused.  For that, except for
deletions at the end, we need to use `M-e'.

Recently I proposed that when search fails `M-e' should position
the cursor at the mismatch position for editing.  That makes it
easy to insert a missing char or delete unwanted chars, etc.  The
mismatch start position is a primary location for editing, not
only for fixing fast-finger typos but also when reusing complex
strings.

Like highlighting the mismatch portion, this was an idea I
borrowed from Icicles completion.  Isearch interaction and
minibuffer interaction are inherently similar in several ways.

And just as you can easily edit minibuffer input without entering
some "edit" mode, so we could make it just a bit easier to edit
Isearch input: let some editing commands act on the search string
directly.

We could give users the option of letting certain leftward
commands (au choix) automatically initiate editing.  For
instance, let `C-b' and `M-b' move the cursor left one char/word
in the search string, as an edit.  IOW, let them act as
search-string commands rather than buffer-text commands.

Different users would want to use different commands this way, or
might not want to play this game at all.  We can create a user
option that lists the commands that should initiate editing this
way.

(defun isearch-update-edit-init-commands ()
  "Make `isearch-initiate-edit-commands' edit the search string."
  (dolist (cmd  isearchp-initiate-edit-commands)
    (substitute-key-definition
     cmd
     (lambda (&rest ignored)
       (interactive)
       (isearch-unread-key-sequence
        (listify-key-sequence (this-command-keys)))
       (isearch-edit-string))
     isearch-mode-map
     (current-global-map))))

(defcustom isearch-initiate-edit-commands
  '(backward-char ; `C-b'
    left-char     ; `left' (Emacs 24+)
    backward-word ; `M-b', `M-left'
    backward-sexp ; `C-M-b', `C-M-left'
    ;; ...
    )
  "Commands whose key bindings initiate Isearch edit.
When invoked by a key sequence, Isearch edits the search string,
applying the command to it immediately.

Commands you might want to include here are typically commands that
move point to the left, possibly deleting text along the way.

Set this to `nil' if you always want all such commands to exit Isearch
and act on the buffer text."
  :set #'(lambda (sym defs)
           (custom-set-default sym defs)
           (isearch-update-edit-init-commands))
  :type '(repeat (restricted-sexp :tag "Command"
                  ;; Use `symbolp', not `functionp' or `fboundp', in
                  ;; case the library defining the fn is not loaded.
                  :match-alternatives (symbolp) :value ignore))
  :group 'isearch)

Some other commands that some users might want to include as
editing initiators:

;; backward-delete-char          ; `DEL'
;; backward-delete-char-untabify ; `DEL'
;; backward-kill-paragraph       ; `C-backspace'
;; backward-kill-sentence        ; `C-x DEL'
;; backward-kill-sexp            ; `C-M-backspace'
;; backward-kill-word            ; `M-DEL'
;; backward-list                 ; `C-M-p'
;; backward-page                 ; `C-x ['
;; backward-paragraph            ; `C-up', `M-{'
;; backward-sentence             ; `M-a'
;; backward-to-indentation
;; backward-up-list              ; `C-M-u', `C-M-up'
;; beginning-of-buffer           ; `M-<', `C-home'
;; beginning-of-defun            ; `C-M-a', `C-M-home', 
;; beginning-of-line             ; `C-a', `home'
;; beginning-of-line+            ; `C-a', `home'
;; beginning-of-line-text
;; beginning-of-visual-line      ; `C-a', `home'
;; delete-backward-char
;; kill-backward-up-list

I've been using this feature for a while (esp. with the default
list of commands in the defcustom above, though I've also
experimented with some of those commented out above).  I think it
can be handy.  Yes, it's different, and we all have other habits
by now.

See what you think.  If we did this for Emacs then the default
option value would no doubt be nil (no change in the default
behavior).




reply via email to

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