1

I have the following structure:

myproject
    ----src
       file1.cpp, ..., file10.cpp
    ----include
       incl1.h, ..., incl10.h
    ----data
       data1.txt, ..., data10.txt

I would like to restrict my searches and search-and-replaces to only the /src/ and /include/ subfolders.

To accomplish this, my current thought process is to populate the arglist directly via .vimrc by means of the following line in .vimrc:

:arg ./src/** ./include/** <CR>

As of now, this opens up vim with 20 files in the buffer itself. That is, as soon as the project opens within vim, if I issue :ls command, then file1.cpp through incl10.h are shown in the buffer list.

  1. Does this mean that at this point in time, argo and bufdo would accomplish the same thing? i.e., are these two commands the same?
:bufdo %s/search/replace/g
:argdo %s/search/replace/g

I would imageine that in situations where the output of :arg and the output of :ls are not the same, argdo and bufdo would give different results to the above search and replaces.

  1. When vim opens with the above .vimrc, before entering vim, I obtain the following :

    "./src/file1.cpp" [dos] 587L, 20677C Press Enter or type command to continue

Is there a way to suppress this message?

  1. In trying to run :argdo %s/search/replace/g, is there a way to make it interactive? That is, can I map this to say <C-s>r via .vimrc and then I get prompted for the word that should go into <search> placeholder, and the word that should go into <replace> placeholder?

  2. Is the above workflow even good practice? i.e., populating an argument list via .vimrc for subsequent usage in searches and search-and-replaces?

1
  • 1
    1)yes, 2)probably yes, 3) yes, 4) no. Sorry for not providing proper answers, I think you would have more detailed ones if you have asked them separately.
    – Maxim Kim
    Aug 28, 2021 at 18:18

1 Answer 1

4

Meta

This question is long (4 questions), and we normally prefer to keep questions to 1 question per question. The 4th is also opinion-based enough to be off-topic.

However, the questions are related enough and I have enough to say that I'm going to (try to) write an answer.


Your questions first:

  1. Does this mean that at this point in time, argo and bufdo would accomplish the same thing? i.e., are these two commands the same?
:bufdo %s/search/replace/g
:argdo %s/search/replace/g

Well, if :args and :ls give the same result, then yes, probably. (You may want the e flag, :help :s_e.)

I would imageine [sic] that in situations where the output of :arg and the output of :ls are not the same, argdo and bufdo would give different results to the above search and replaces.

Correct. Note that :bufdo should skip unlisted-buffers, per my reading of it.

  1. When vim opens with the above .vimrc, before entering vim, I obtain the following :
"./src/file1.cpp" [dos] 587L, 20677C
Press Enter or type command to continue

Is there a way to suppress this message?

You could try :silent, but see below.

  1. In trying to run :argdo %s/search/replace/g, is there a way to make it interactive? That is, can I map this to say <C-s>r via .vimrc and then I get prompted for the word that should go into <search> placeholder, and the word that should go into <replace> placeholder?

Of course: something like (in this version you have to press enter after the prompts, so you have a chance to make corrections/etc.).

nnoremap <expr> <C-s>r ':argdo %s/'.escape(input('search '), '/').'/'.escape(input('replace '), '/').'/g'
  1. Is the above workflow even good practice? i.e., populating an argument list via .vimrc for subsequent usage in searches and search-and-replaces?

Well, I think not. I'll talk all about search & replace (S&R) below, but setting the arglist in your vimrc

  • prevents vim <file>… from working the normal way;
  • makes your vimrc specific to one and only one project; and
  • limits your understanding of S&R.

If you want a special arglist, use s. Even vanilla :mksession and vim -S are quite good, though I recommend obsession for the avid session user.


So, let's talk S&R.

I would like to restrict my searches and search-and-replaces to only the /src/ and /include/ subfolders.

Great. How do you search? How do you replace?

On searching

There are a myriad of options:

  • / (always only the current file)
  • :grep (can easily be restricted)
  • :vimgrep (idem.)

and probably more. The last two populate the quickfix list (there are location list variants that start with l). We'll come back to this.

The last two also take file names, which can be generated from the arglist if you like (##), or any other way of getting filenames (:help {file}).

On replacing

The ubiquitous :substitute command is one way, though there are others (macros, complex :normal- or :-commands, :global, basically anything you would do interactively, &c.) that can be done from the ex command line.

As for targeting those replacements, you know the % range and :argdo/:bufdo. But there are also :windo, :tabdo, and more. Some favorites include :cdo and :cfdo, which iterate the quickfix list (see above). (Location list variants exist.) Combine with :Cfilter (:help cfilter-plugin) for a very powerful workflow:

  1. Search your desired files with one of the :grep variants.
  2. Refine the quickfix list with :Cfilter if necessary.
  3. Use :cdo (with no range) or :cfdo (with a % range) to run your replacement command.

This has the benefit of no longer needing the e flag for :substitute.

With smart grepprgs, you can limit to different files very easily. For example, git grep has lots of options and takes pathspecs as arguments (see git help glossary and search for pathspec; you usually have to quote them for the shell). Tools like ripgrep (ag/ack/etc.) can usually filter by file-type.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

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