1

I need to execute a regular expression with case conversion in a entire project. If I run query-replace-regexp in a single file informing '\([A-Z]+\)' and '\,(downcase \1)', it works as expected. But when I try that with projectile-replace-regexp I get the following error:

Invalid use of ‘\’ in replacement text

I investigated it a bit and it seems that the elisp expression doesn't work when query-replace-regexp is not called interactively, because if I run M-: (replace-regexp "'\\([A-Z_]+'\\)" "'\\,(downcase \\1)") I also have the error above.

Am I doing something wrong or is this some limitation? If so, is there another way to achieve this?

  • The doc string of query-replace-regexp says "In interactive calls, the replacement text can contain ‘\,’ followed by a Lisp expression. Each replacement evaluates that expression to compute the replacement string. Inside of that expression, ‘\&’ is a string denoting the whole match as a string, ‘\N’ for a partial match, ‘\#&’ and ‘\#N’ for the whole or a partial match converted to a number with ‘string-to-number’, and ‘\#’ itself for the number of replacements done so far (starting with zero)." – Drew Apr 4 at 17:19
  • And the doc string of replace-regexp says "This function is for interactive use only; in Lisp code use re-search-forward and replace-match instead." – Drew Apr 4 at 17:19
  • If the projectile command does not allow the query-replace-regexp behavior then maybe consider filing an enhancement request with its maintainer. – Drew Apr 4 at 17:21
  • @Drew Just filed a bug report. I consider it as a bug if a function that has replace-regexp in its name and does not behave like it. – Tobias Apr 4 at 22:23
1

The question is related to another question about non-interactive calls of query-replace-regexp. If they cannot use query-replace-read-args in projectile-replace-regexp they should at least apply query-replace-compile-replacement to the TO argument of tags-query-replace.

The following advice of projectile-replace-regexp does that for you.

(defun my-tags-query-replace-compile-replacement (fun &rest args)
  "Apply `q-r-compile-replacement' to `tags-query-replace' in FUN with ARGS."
  (cl-letf* ((old-tags-query-replace (symbol-function 'tags-query-replace))
         ((symbol-function 'tags-query-replace)
          (lambda (from to &rest other-args)
        (apply old-tags-query-replace
               from
               (query-replace-compile-replacement to t)
               other-args))))
    (apply fun args)))

(advice-add 'projectile-replace-regexp :around #'my-tags-query-replace-compile-replacement)

DISCLAIMER: Note that I do not have projectile installed. So I cannot test the code above. Please test it and report back the test results.

NOTE: I already filed a bug-report for the problem that projectile-replace-regexp does not have the interactive features of replace-regexp.

  • It worked! Very nice solution. Thanks a lot! – Jesse Apr 5 at 12:30
  • @Jesse Do you have the possibility to comment on the bug report? It would be good to have an acknowledgement of the bug by a real projectile-user. This should be easy if you already have a github account. Ignore that comment if you do not have such an account. – Tobias Apr 5 at 12:35
  • Sure, no problem – Jesse Apr 5 at 12:58

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.