Skip to content

[IDEA] Use interactive prefix arg for number of pairs - #2

Closed
josephmturner wants to merge 1 commit into
hokomo:masterfrom
josephmturner:wip/prefix-arg
Closed

[IDEA] Use interactive prefix arg for number of pairs#2
josephmturner wants to merge 1 commit into
hokomo:masterfrom
josephmturner:wip/prefix-arg

Conversation

@josephmturner

Copy link
Copy Markdown
Contributor

Inspired by the suggestion from your talk Q&A to use the prefix arg to determine how many times to prompt for replacements pairs.

This patch doesn't work because current-prefix-arg is already used in query-replace:

In interactive use, the prefix arg (non-nil DELIMITED in
non-interactive use), means replace only matches surrounded by
word boundaries.  A negative prefix arg means replace backward.

Seems like a niche use-case...

I still like the idea of having query-replace-parallel be a drop-in replacement for query-replace. One potential option is to add a transient menu that would allow users to specify the number of queries as well as a value for DELIMITED and other parameters.

That's definitely outside the scope of this project though :)

Thanks!!!

@hokomo

hokomo commented Dec 9, 2023

Copy link
Copy Markdown
Owner

Indeed, we've thought a little bit about the idea after it was suggested during the Q&A, but then remembered that sadly the prefix argument is already in use by query-replace and there's no more room for additional options.

We've also thought of having a transient menu like you suggested, but concluded that we didn't want to pull in a whole another dependency for a use case of unknown frequency. For now we prefer to keep the interface consistent with query-replace to reduce surprises for anyone who's got years of muscle memory. :-)

However, here's a piece of advice that you can drop into your config that adds the functionality you want. The approach is the same except that (1) I make sure to ignore the returned delim and backward flags, and (2) I also added a counter that shows you how many pairs are still to be input (shown only when n > 1).

(define-advice query-replace-parallel--prompt
    (:override (regexp-flag n) hok/count-arg)
  (concat "Query replace parallel"
          (and regexp-flag " regexp")
          (and (use-region-p) " in region")
          (and n (format " (%d)" n))))

(define-advice query-replace-parallel--read-args
    (:override (regexp-flag) hok/count-arg)
  (let ((n (prefix-numeric-value current-prefix-arg)))
    (cl-loop for i from n downto 1
             for (from to _delim _backward)
               = (query-replace-read-args
                  (query-replace-parallel--prompt regexp-flag (and (> n 1) i))
                  regexp-flag)
             for pair = (cons from to)
             collect pair into pairs
             finally (cl-return (list pairs nil nil)))))

@josephmturner

josephmturner commented Dec 10, 2023 via email

Copy link
Copy Markdown
Contributor Author

@hokomo

hokomo commented Dec 11, 2023

Copy link
Copy Markdown
Owner

Oh, good catch! I forgot that query-replace-read-args also inspects the prefix argument. Perhaps instead of ignoring the flags, maybe it's easier to then just bind current-prefix-argument to nil around the call to the function. Like this:

(define-advice query-replace-parallel--read-args
    (:override (regexp-flag) hok/count-arg)
  (let ((n (prefix-numeric-value current-prefix-arg)))
    (cl-loop for i from n downto 1
             for (from to delim backward)
               = (let ((current-prefix-arg nil))
                   (query-replace-read-args
                    (query-replace-parallel--prompt regexp-flag (and (> n 1) i))
                    regexp-flag))
             for pair = (cons from to)
             collect pair into pairs
             finally (cl-return (list pairs delim backward)))))

This also keeps the effect local, so query-replace's usual lazy highlighting should continue to work. :-)

@josephmturner

Copy link
Copy Markdown
Contributor Author

That's a much better solution. Thank you! Might I suggest adding the two advices to the README for folks who come from the talk and are interested in using this package as a stand-in for query-replace?

@josephmturner

josephmturner commented Dec 12, 2023

Copy link
Copy Markdown
Contributor Author

You could also link to this comment, but then folks would have to use GitHub to discover your useful advices.

(when (package-installed-p 'query-replace-parallel)
  (global-set-key [remap query-replace] #'query-replace-parallel)
  (global-set-key [remap query-replace-regexp] #'query-replace-parallel-regexp)

  (define-advice query-replace-parallel--prompt
      (:override (regexp-flag n) hok/count-arg)
    (concat "Query replace parallel"
            (and regexp-flag " regexp")
            (and (use-region-p) " in region")
            (and n (format " (%d)" n))))

  (define-advice query-replace-parallel--read-args
      (:override (regexp-flag) hok/count-arg)
    (let ((n (prefix-numeric-value current-prefix-arg)))
      (cl-loop for i from n downto 1
               for (from to delim backward)
               = (let ((current-prefix-arg nil))
                   (query-replace-read-args
                    (query-replace-parallel--prompt regexp-flag (and (> n 1) i))
                    regexp-flag))
               for pair = (cons from to)
               collect pair into pairs
               finally (cl-return (list pairs delim backward))))))

@hokomo

hokomo commented Dec 13, 2023

Copy link
Copy Markdown
Owner

I've added a small FAQ section to the README with instructions. Thanks! :-)

@josephmturner

Copy link
Copy Markdown
Contributor Author

Perfect! Thanks :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants