0

I'm working on applying doctrine/coding-standard on doctrine/orm, and I would like to work smarter.

I would like to search occurences of

    /**
     * @Id
     * @Column(type="integer")
     * @GeneratedValue(strategy="AUTO")
     */

and replace them with

    /**
     * @var int
     * @Id
     * @Column(type="integer")
     * @GeneratedValue(strategy="AUTO")
     */

My current grepprg is rg\ --vimgrep\ --smart-case, so I tried :gr '/\*\*\n \* @Id\n \* @Column.*"integer"\)\n \* @GeneratedValue.*\n \*/' --multiline tests/ (I'm planning to use :cdo … after that, which should be easy enough.

It finds the occurences alright, but it formats them in such a way that each line of the matched block is considered a separate occurence, like this:

tests/Doctrine/Tests/ORM/Functional/Ticket/DDC881Test.php:109:5:    /**
tests/Doctrine/Tests/ORM/Functional/Ticket/DDC881Test.php:110:5:     * @Id
tests/Doctrine/Tests/ORM/Functional/Ticket/DDC881Test.php:111:5:     * @Column(type="integer")
tests/Doctrine/Tests/ORM/Functional/Ticket/DDC881Test.php:112:5:     * @GeneratedValue(strategy="AUTO")
tests/Doctrine/Tests/ORM/Functional/Ticket/DDC881Test.php:113:5:     */
tests/Doctrine/Tests/ORM/Functional/Ticket/DDC881Test.php:189:5:    /**
tests/Doctrine/Tests/ORM/Functional/Ticket/DDC881Test.php:190:5:     * @Id
tests/Doctrine/Tests/ORM/Functional/Ticket/DDC881Test.php:191:5:     * @Column(type="integer")
tests/Doctrine/Tests/ORM/Functional/Ticket/DDC881Test.php:192:5:     * @GeneratedValue(strategy="AUTO")
tests/Doctrine/Tests/ORM/Functional/Ticket/DDC881Test.php:193:5:     */

That will not work well with :cdo I'm afraid. Maybe it would work if rg '/\*\*\n \* @Id\n \* @Column.*"integer"\)\n \* @GeneratedValue.*\n \*/' --multiline tests/ --vimgrep printed the following instead:

tests/Doctrine/Tests/ORM/Functional/Ticket/DDC881Test.php:109:5:    /**
                                                                     * @Id
                                                                     * @Column(type="integer")
                                                                     * @GeneratedValue(strategy="AUTO")
                                                                     */
tests/Doctrine/Tests/ORM/Functional/Ticket/DDC881Test.php:189:5:    /**
                                                                     * @Id
                                                                     * @Column(type="integer")
                                                                     * @GeneratedValue(strategy="AUTO")
                                                                     */

How would you do such a complicated search and replace?

4
  • Probably I would grep something smaller and cdo a function call that checks for the whole pattern. – D. Ben Knoble Feb 13 at 14:27
  • Ah so for some reason it would work with grep? Interesting, let me try! – greg0ire Feb 13 at 17:23
  • 🤔 It does not seem that grep is able to do that: stackoverflow.com/questions/2686147/… – greg0ire Feb 13 at 17:39
  • 1
    No, I would :grep a single-line patter, and then do :cdo call F() where F examines the next few lines for a match and then applies the transformation. The -r trick is nice though. – D. Ben Knoble Feb 13 at 19:33
0

Answering my own question: It's a bit hackish, but you can hijack ripgrep's --replace flag, you can essentially replace each match with a single line one, producing the desired effect. In the end, what I did is the following:

:gr '/\*\*\n     \* @Id\n     \* @Column.*"integer"\)\n     \* @GeneratedValue.*\n     \*/' --multiline tests/ -r 'whatever, it does not matter'
:cdo call append('.', '     * @var int') | update

In more generic terms, _if ripgrep is your grepprg:

:gr 'some multiline pattern' --multiline tests/ -r 'whatever, it does not matter'
:cdo the colon command you want to execute for each occurence | update

The same does not seem to be doable with grep.

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.