Teo Gelles
Teo Gelles

Reputation: 82

Automatically indent file after command in Vim

I am trying to write a custom vim command called Remove which takes a single argument and deletes all lines of the file that are exactly that argument. For example, if the file was

int main() {
    int x = 3;
    int y = 4;
    cout << x << endl;
}

and I use the command

:Remove int y = 4;

The output would be

int main() {
    int x = 3;
    cout << x << endl;
}

I can get pretty close by defining

:command -nargs=1 Remove :%s/<args>\n//g

But with this command the file is not indented properly after the substitution, which requires me to run gg=G afterwards.

Is there a way to make gg=G run automatically as part of the command?

Upvotes: 1

Views: 75

Answers (2)

yolenoyer
yolenoyer

Reputation: 9465

The indenting is wrong because your Remove command doesn't remove the leading spaces/tabs in the found lines.

Instead of reindenting all the file, you can modify your command to remove the spaces as well:

:command -nargs=1 Remove %s/^\s*\V<args>\n//g
  • ^ matches the beginning of the line;
  • \s* matches optional spaces or tabs; you could even put \s* again just before \n, to consider lines with hidden spaces at the end;
  • I added \V, which avoids special regex chars in your command argument to be interpreted. If you don't put it, the following command:

    :Remove char *my_str = 0;
    

    would be misinterpreted because of the *.

Upvotes: 1

Ingo Karkat
Ingo Karkat

Reputation: 172778

Sure. You can concatenate multiple commands with |. If this gets too long, you can factor out the code into a :function. Because = is a normal mode command, not an Ex command like :substitute, you need to invoke it via :normal; the ! avoids that mappings interfere.

:command -nargs=1 Remove %s/<args>\n//g | normal! gg=G

Upvotes: 2

Related Questions