7.23 Query Replace Term

Sweep includes a powerful search and replace mechanism called Term Replace, that allows you to quickly and consistently transform some terms across a Prolog buffer. Term Replace searches for terms with the same flexibility and precision of Term Search (see Term Search), while letting you interactively transform and replace matching terms in place. You can use Term Replace to refactor your code in many ways, such as extending a predicate with another argument, or replacing all calls to a predicate with another one while transposing some of the arguments. If you’re familiar with Emacs’s Query Replace commands, you can think of Term Replace as a Prolog-specific superpowered version of query-replace-regexp (see (emacs)Query Replace). To initiate Term Replace, use the following command:

C-c C-S

Replace some terms after point matching a given template with a given replacement (sweeprolog-query-replace-term).

The command sweeprolog-query-replace-term (bound to C-c C-S) prompts for two Prolog terms, the template term and the replacement term, and then asks for each term in the buffer that matches the template if you want to replace it. You can use variables in the template term to capture sub-terms of the matching term, and use them in the replacement term. For example, if you want to transpose the two arguments in a bunch of calls to =/2, you can specify R=L as the template term and L=R as the replacement.

This command uses the same underlying term search as C-c C-s (sweeprolog-term-search) does for finding matches, expect that sweeprolog-query-replace-term only searches from point to the end of buffer. If you invoke sweeprolog-query-replace-term with an active region, it limits the operation to matching terms in the region. sweeprolog-query-replace-term highlights the current match with the sweeprolog-query-replace-term-current face, and all other matches with the sweeprolog-query-replace-term-match face. By default, these faces inherit from sweeprolog-term-search-current and sweeprolog-term-search-match, respectively. Furthermore, similarly to C-c C-s, you can invoke sweeprolog-query-replace-term with a prefix argument to refine the search with an arbitrary Prolog goal that matching terms must satisfy, or with two prefix arguments to target only terms in certain contexts. See Term Search for full details about prefix arguments and search refinement.

sweeprolog-query-replace-term goes over the matching terms in turn and asks you what to do with each. The available answers are:

y

Replace the current match and move to the next one.

n

Skip the current match without replacing it.

t

Replace the current match, show the result, and suggest reverting back before moving to the next match.

q

Quit without replacing the current match.

.

Replace the current match, and exit right away asking about further matches.

!

Replace the current match and all remaining matches without asking.

e

Edit the replacement term for the current match in the minibuffer, and then perform the replacement.

C-r

Enter recursive edit. This allows you to pause the current Term Replace session, perform some edits, or otherwise use Emacs however you please, an then resume Term Replace from the same point by typing C-M-c. See (emacs)Recursive Edit.

If you include a new variable in the replacement term that does not appear in the template term, sweeprolog-query-replace-term uses that variable as-is in each replacement, expect if the matching term happens to contain a variable with that name already, in which case this command adds the suffix ‘Fresh’ to the name of the new variable from the replacement. Including a new variable in the replacement term is useful, for example, for introducing a new argument to a predicate.