Background

Various IDEs/tools I have used over the years have provided a code action Extract Interface, which would take the function signatures of a class and produce an interface from them.

I found myself needing to do this in Neovim and went looking for a solution.

A vim way?

Essentially Extract Interface boils down to “Copy all function signatures to a new code block”.

To get us most of the way there then we can further simplify this to Copy all lines matching a pattern.

It turns out this is very simple in vim/neovim:

Copy

" clear register a
qaq
" yank all lines matching patten into register a
:g/pattern/y A

Paste:

"ap

An example using go

func (h *HueAPIService) GetRooms() ([]models.HughGroup, error) {
    ...
}

func (h *HueAPIService) GetZones() ([]models.HughGroup, error) {
    ...
}

func (h *HueAPIService) GetAllGroups() ([]models.HughGroup, error) {
    ...
}

First we clear the register we are using

qaq

Then we copy the function signature lines

:g/func (h \*Hue/y A

Then we can paste these lines into an empty interface declaration

type SomeInterface interface {
  // cursor here
}

Paste from register a

"ap

We then have something like this.

type SomeInterface interface {
    func (h *HueAPIService) GetRooms() ([]models.HughGroup, error) {
    func (h *HueAPIService) GetZones() ([]models.HughGroup, error) {
    func (h *HueAPIService) GetAllGroups() ([]models.HughGroup, error) {
}

All that’s left to do is remove some extra things from the lines, but simple find/replace can easily take care of that.

yes, just blindly creating an interface from something is usually not the way to work in go, this is purely an example