2

I want to format a multiline string according to a textwidth of 32.

group:
  - normal: scalar
  - multiline: "Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua."
  - normal: "text"

to this:

group:
  - normal: scalar
  - multiline: "Lorem ipsum
      dolor sit amet, consetetur
      sadipscing elitr, sed diam
      nonumy eirmod tempor
      invidunt ut labore et
      dolore magna aliquyam
      erat, sed diam voluptua."
  - normal: "text"

My vim settings for this file are

set sw=2 tw=32 et
set formatoptions=tjcroq

For re-flowing paragraphs I frequently use gwap and formatoptions for on-the-fly formatting. In this case, autoformat is only turned on when in such a section with: fo+=a but this only works for paragraphs with an empty line before and after the string and does not respect full indentation. My workaround is to add empty lines before and after and delete them afterwards.

This must be a frequent task for most coders here but I don't know how to do it. My guess was to use the marks from the start and end of the current syntax highlighting tag, which is <yamlFlowString> here, for constraining the auto-formatting to it. Is there any solution to this?

Also see http://vimhelp.appspot.com/change.txt.html#formatting

2
  • So your having an issue with formatting bleeding to adjacent lines? What if you us gq$ from the multi-line?
    – B Layer
    Commented Sep 29, 2018 at 5:58
  • @BLayer It is a common task for me to edit such a multiline string again. Your command will not work in such a case. Although, exchanging p by sth else for not applying the reformat to the whole "paragraph" is the right path.
    – user8162
    Commented Oct 1, 2018 at 15:52

2 Answers 2

1

Not sure if this what you want, but try reading: https://vimways.org/2018/formatting-lists-with-vim/

What I have in my settings regarding list formatting:

setlocal formatoptions=tcqln
setlocal formatlistpat=^\\s*
setlocal formatlistpat+=[
setlocal formatlistpat+=\\[({]\\?
setlocal formatlistpat+=\\(
setlocal formatlistpat+=[0-9]\\+
setlocal formatlistpat+=\\\|
setlocal formatlistpat+=[a-zA-Z]
setlocal formatlistpat+=\\)
setlocal formatlistpat+=[\\]:.)}
setlocal formatlistpat+=]
setlocal formatlistpat+=\\s\\+
setlocal formatlistpat+=\\\|
setlocal formatlistpat+=^\\s*-\\s\\+
setlocal formatlistpat+=\\\|
setlocal formatlistpat+=^\\s*[*]\\+\\s\\+

enter image description here

0

Via External Tool Pretty-Yaml (pyaml)

  1. Install pyaml with pip

    $ pip install pyaml 
    

    or to your home directory

    $ pip install --user pyaml
    
  2. Filter all lines through pyaml and give width option -w/--width:

    :%!python -m pyaml -w 32
    

Note there is a limitation to the width option according to their help message:

❯ python -m pyaml -h
usage: __main__.py [-h] [-w chars] [path]

Process and dump prettified YAML to stdout.

positional arguments:
  path                  Path to YAML to read (default: use stdin).

optional arguments:
  -h, --help            show this help message and exit
  -w chars, --width chars
                        Max line width hint to pass to pyyaml for the dump.
                        Only used to format scalars and collections (e.g.
                        lists).

Update

Add following to ~/.vim/after/ftplugin/yaml.vim

setlocal textwidth=32
let &l:formatprg = 'python -m pyaml -w' . &l:textwidth

If you change textwidth during runtime and formatprg should pick up the new value, see set formatprg dynamically based on textwidth?. Note there are also plugins to help you here, e.g. vim-autoformat, neoformat, or vim-codefmt.

2

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.