I am trying to format a list that uses tabs for indentation so it will render as a bulleted list on Confluence. That means that each instance of a tab needs to be replaced with an asterisk (*), plus one leading asterisk, and then a space at the end of the string of asterisks.


Level 1
\tLevel 2
\tLevel 2
\t\tLevel 3
\tLevel 2
Level 1

Would become:

* Level 1
** Level 2
** Level 2
*** Level 3
** Level 2
* Level 1

I have tried doing a global replace (s/\t/\*/g) and then adding an asterisk at the beginning of each line, but that leaves me without the trailing space. I also tried the \ze atom as detailed here (s/\*\ze/\* /), but that replaces the first asterisk, not the last. I feel like I'm really close but there's something I'm missing that will make this clear.

2 Answers 2


Here's a solution I came up with:

:%s/^\(\t*\)/\="*" . substitute(submatch(1), '\t', '\*', 'g') . " "/
  • %s///: Do a substitute on every line in the file
  • ^\(\t*\): Match as many tabs as you can find at the beginning of the line
  • \=: Allows us to use an expression in the replacement
  • substitute(submatch(1), '\t', '\*', 'g'): Replace all the tabs with asterisks. (The submatch(1) selects the the first group of "memory parentheses" \(\))
  • "*" . ... . " ": Prepend an asterisk and append a space character

See :h submatch and :h sub-replace-\= for more info.

  • Shorter variation, just for fun: :%s/^\t*/\='*'.tr(submatch(0), "\t", '*').' '/ Commented Jul 29, 2016 at 12:50

I imagine the easiest way is to run 2 simple substitutions.

:%s/\w/* &/

The first to replaces tab characters with stars and the second to puts an additional star and space before the first character.

If you can't use the % range then you can combine this with the global command, :g, to execute a command on each line that matches a pattern.

:g/^\t*/s/\t/*/g|s/\w/* &

We use the | to run 2 separate commands so we can run multiple commands in one line.

For more help see:

:h :s
:h s/\\&
:h /\w
:h :g
:h :|

Your Answer

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

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