Skip to content

Consider a more imperative formatter API #14

Open
@dbarnett

Description

@dbarnett

Formatters right now take a range and modify the buffer as a side-effect, e.g.

function someformatter.FormatRange(startline, endline) abort
  let l:lines = getline(1, line('$'))
  let l:result = maktaba#syscall#Create(…).WithStdin(join(l:lines, "\n")).Call()
  call maktaba#buffer#Overwrite(1, line('$'), split(l:result.stdout, "\n"))
endfunction

codefmt itself has very little insight into what the formatter is doing, and the amount of boilerplate is also a little annoying. Things can get weird if e.g. FormatRange is called multiple times to process multiple ranges, especially with formatters that try to populate errors into the quickfix list.

A different approach would be to pass a codefmt handle and implement formatter operations in terms of that handle, like

  • formattable.GetLines([start], [end])
  • formattable.SetLines({lines})
  • formattable.SetLines({start}, {end}, {lines})
  • formattable.SetCursor({row}, {col})
  • formattable.AddError({error}, [row], [col])

A simple formatter would look like

function someformatter.FormatRange(startline, endline, formattable) abort
  let l:input = join(a:formattable.GetLines(), "\n")
  let l:result = maktaba#syscall#Create(…).WithStdin(l:input).Call()
  call a:formattable.SetLines(l:result.stdout)
endfunction

Some advantages are that it can make some formatting operations more convenient and anti-patterns like overwriting files on disk less natural. If we run into wonkiness as we enable fancy features like format-changed-lines-on-save (multiple ranges), it could help solve issues like that, too.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions