# Quoting blocks but ignoring whitespace

Let's say I have

Foo BAR Baz   Quxxx     Foo
Baar Asd      Duxxxxx   Bar Foo
Baazzz        Kuxx      Baz


I would ideally like to be to highlight the first, second, or third column. Then I would like to able to quote them such that they're like this,

'Foo BAR Baz'   'Quxxx'     'Foo'
'Baar Asd'      'Duxxxxx'   'Bar Foo'
'Baazzz'        'Kuxx'      'Baz'


What is the easiest way to do that. I've asked this question before but none of those solutions covered these kinds of use cases,

• You can't skip over by using W, because the first column may have more than one WORD.
• I would like the WORD to be delimited by the last non-whitespace character highlighted on the line in block mode.

Ideally this would work in visual mode.

The single substitution command

:%s/\S\+$$\S\+$$*/'&'/g


works under the assumptions

different columns are separated by more than one white space

and

only a single space separates words within cells.

It changes

Foo BAR Baz   Quxxx     Foo
Baar Asd      Duxxxxx   Bar Foo
Baazzz        Kuxx      Baz
Baazzz        K         Baz


to

'Foo BAR Baz'   'Quxxx'     'Foo'
'Baar Asd'      'Duxxxxx'   'Bar Foo'
'Baazzz'        'Kuxx'      'Baz'
'Baazzz'        'K'         'Baz'

• You know this isn't the ideal answer, but it's so damn simple and easy for me to coerce data into this form, I'm half temped to accept it as the best workaround. We'll see what else is provided. Good suggestion anyway. Thanks a ton! – Evan Carroll Oct 9 '18 at 18:41

Your question is pretty hard to answer in a meaningful way because it is a very specific use case.

If you can be sure that the different columns are separated by more than one white space (like in your example) you could use the following substitution commands:

First use :%s/\s\{2,}/'&'/g to surround every string of two or more white spaces with quotes:

Foo BAR Baz'   'Quxxx'     'Foo
Baar Asd'      'Duxxxxx'   'Bar Foo
Baazzz'        'Kuxx'      'Baz


Then with :%s/^\|\$/'/g add a quote at the beginning and at the end of the lines:

'Foo BAR Baz'   'Quxxx'     'Foo'
'Baar Asd'      'Duxxxxx'   'Bar Foo'
'Baazzz'        'Kuxx'      'Baz'


This answer is based on the vis plugin. That plugin provides the ability to run ex commands on just the visually-selected text. In this case, it can be used to execute a substitute command on just the selected column of text.

First visually select the column to be quoted. That is, move the cursor to the upper-left corner of the column, type Ctrl-V, then move the cursor to the lower-right corner of the column (don't worry about whitespace preceding or trailing the text). Then type the following.

:'<,'>B s/$$\s*$$$$\S.*\S\|\S$$$$\s*$$/\1'\2'\3/


The B command executes the ex command that follows it on the visually-selected block. The substitute command finds three patterns: leading whitespace, one or more words, and trailing whitespace. It replaces the matching text with the leading whitespace, a single quote, the matched words, another single quote, and the trailing whitespace.

There's a bug in this answer, but I'm going to leave it anyway. Maybe someone else can fix it or maybe the solution will come to me later. The replacement tokens \1 and \3 insert an additional space. The cleanup required is minor, but it's still annoying. I was using gvim 8.1.351 on Windows and vis v20.

• This also doesn't work if the string is one character. – Evan Carroll Oct 9 '18 at 4:32
• Good point. Thanks. I updated the regular expression by adding \|\S to the second term. Also tried using \= and submatch(n) instead of \n but that didn't help with the extra spaces. – garyjohn Oct 9 '18 at 18:32