emacs-devel
[Top][All Lists]
Advanced

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

query-replace-read-args - be able to use word-at-point? init-value?


From: Drew Adams
Subject: query-replace-read-args - be able to use word-at-point? init-value?
Date: Mon, 11 Oct 2004 00:33:30 -0700

I think that this, or something similar, was already beat to death back in
July, but I'm not sure that this side of it was raised. I'll desist at the
first sign that no one wants to hear this, but let me argue this _once_. I
think I'll make my point clearly enough that I won't have to follow up to
reinforce the argument. If others want to discuss it, fine, but I won't push
this discussion.

I think I understand how query-replace args are read, from reading the code
and experimenting, but correct me if I'm wrong here.
`query-replace-read-args' currently does this:

 - If `query-replace-interactive', then the last search string (regexp or
not, as appropriate) is used as the `from' prompt value.

 - Otherwise, it prompts with (default lastfrom -> lastto), where lastfrom
and lasto are the last-used replacement args (old & new, respectively). If
you enter just RET, then these last-used args are reused.

 - Regardless of the prompt used, if you enter explicit args for the `from'
and `to' values, these are used for q-r, and they are added to the
respective from and to history lists, for future use.

 - When prompted, besides being able to confirm the (old -> new) prompt, or
confirm the last search string as the default `from' or `to' value, you can
also use M-p to retrieve previous values from the two q-r history lists
(from and to).

 - You _cannot_, however, use M-n to retrieve a default value. There is none
available.

So, you have these pre-existing values available, to choose from:

 - The last search string (regexp or straight)
 - The last q-r (repeat the lastfrom -> lastto)
 - Any previously used values (from q-r history lists)

Only in the last case can you _edit_ one of these available values. The
first two are take-it-or-leave-it. More precisely, the last search string
value can be edited as `to' value (after retrieving it via M-p), but not as
`from' value.

In particular, you do _not_ have, as a default value, the word at or near
point. You can, however, do this to obtain it as a default value (assuming
you are at its beginning): C-s C-w M-%. (In that case, you cannot edit it as
`from' value, however, as just mentioned.) That works OK, but it's not that
handy IMO.

I also understand that a decision was made some time ago that the INIT-VALUE
arg for `read-from-minibuffer' and `completing-read' is now deprecated, or
nearly so; it's use is frowned upon, in any case (except in the special
consp case). The argument for this is that putting an initial value in the
minibuffer "intrudes" on the user.

Assuming I understand everything correctly so far (probably not 100%, given
the complexity of the q-r interactive interface), here's my point, for
discussion. The separate aspects of it can be shot down separately, if you
like. Fire away:

1. Not being able to _easily_ retrieve and edit the word at or near point is
not good. We have put the emphasis on being able to easily reuse previous
q-r args, and that's fine, but we've sacrificed using the words in the
buffer as editable default values. Most of the time, I find, I want to
replace something that already exists nearby.

2. I'm not convinced by the "don't intrude" argument, at least not
completely. And I think that q-r provides a good case for using an
init-value. It shows that the init-value can be used for one thing, and
empty input can mean a completely different thing. To be specific, the
init-value can be the word-at-point (editable), and the empty-input behavior
can be as defined currently: repeat the lastfrom -> lastto q-r.

The code below shows what I would do, assuming that we want to keep all the
functionality already defined (lastfrom -> lastto etc.). This is the
function that reads the default `from' value; the `to' reader is similar.
The only difference here from the CVS version is that the `word-at-point' is
inserted into the minibuffer as the init-value. You can still use the
history lists, and you can still enter nothing to repeat the previous query
replacement operation (the prompt tells you this). Of course, to enter
nothing, or to not use the init-value for editing, you need to first
_remove_ it.

Ay, there's the rub, and the nub of the argument against init-value, I
think. If, most of the time, you don't want the `word-at-point' as either
`from' or `to' value, then you have to delete it from the minibuffer before
typing what you do want. Most of the time, _I_ do want it, but I also use an
easy key binding to empty the minibuffer.

So, I guess I'm asking:

1. Can't we do something better for q-r, so you can easily retrieve and edit
the word-at-point? To me, that's a better default value than anything
available currently.

2. Is the debate over init-value closed? Are you sure it's a no-no that has
to go?

Obviously, other ways could be devised to let you use word-at-point, besides
resorting to allowing init-value. But I'd like to bring up both points
(once).

 - Drew

P.S. In my own code, I even use `symbol-name-nearest-point' instead of
`word-at-point', so I _always_ have an init-value -- talk about intrusion!
(The former does what it says.)

Actually, instead of hard-coding `symbol-name-nearest-point' I use a
variable, `search/replace-default-fn', that I can bind to different
`*-nearest-point' functions in different contexts. It's true that with `C-s
C-w C-w...' you can pick up more than a single word, but it can also be
useful to retrieve a nearby symbol-name, file-name, Lisp sexp, etc.,
depending on the context (mode etc.).

------------8<--------------------

(defun query-replace-read-from (string regexp-flag) "..."
  (if query-replace-interactive
      (car (if regexp-flag regexp-search-ring search-ring))
    (let* ((default (word-at-point))
           (lastto (car (symbol-value query-replace-to-history-variable)))
           (lastfrom (car (symbol-value
query-replace-from-history-variable)))
           (from-prompt
            (progn
              (when (equal lastfrom lastto)
                (setq lastfrom (cadr (symbol-value
query-replace-from-history-variable))))
              (if (and lastto lastfrom)
                  (format "%s. OLD (empty means %s -> %s): " string
(query-replace-descr lastfrom)
                          (query-replace-descr lastto))
                (concat string ". OLD: "))))
           (from (save-excursion
                   (if query-replace-interactive
                       (car (if regexp-flag regexp-search-ring search-ring))
                     (read-from-minibuffer from-prompt default nil nil

query-replace-from-history-variable nil t)))))
      (if (and (zerop (length from)) lastto lastfrom)
          (cons lastfrom lastto)
        (and regexp-flag
             (string-match "\\(\\`\\|[^\\]\\)\\(\\\\\\\\\\)*\\(\\\\[nt]\\)"
from)
             (let ((match (match-string 3 from)))
               (cond
                ((string= match "\\n")
                 (message "Note: `\\n' here doesn't match a newline; to do
that, type C-q C-j instead"))
                ((string= match "\\t")
                 (message "Note: `\\t' here doesn't match a tab; to do that,
just type TAB")))
               (sit-for 2)))
        from))))





reply via email to

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