Skip to content

matiyas/vue-sfc-format.nvim

vue-sfc-format.nvim

CI LuaRocks License: MIT

A Neovim plugin that formats Vue Single File Components (SFC) by applying configurable formatters to each section separately.

Core Purpose

When working with Vue SFC files, you often want different formatting for different sections:

  • Template: HTML formatting with specific indentation rules
  • Script: JavaScript/TypeScript formatting with your preferred style
  • Style: CSS/SCSS formatting

This plugin extracts each section, formats it with the appropriate tool, and reassembles the file.

Key Features

  • Configurable formatters for each section via JSON config
  • Automatic SCSS detection from lang="scss" attribute
  • Provides :VueSfcFormat command
  • Integrates with formatter.nvim

Requirements

  • Neovim >= 0.9.0
  • Formatters configured in .vue-sfc-format.json must be available in PATH

Installation

lazy.nvim

{
  "matiyas/vue-sfc-format.nvim",
  ft = { "vue" },
  opts = {},
  keys = {
    {
      "<leader>fv",
      function()
        require("vue-sfc-format").format()
      end,
      desc = "Format Vue SFC",
      ft = "vue",
    },
  },
}

packer.nvim

use({
  "matiyas/vue-sfc-format.nvim",
  ft = { "vue" },
  config = function()
    require("vue-sfc-format").setup()
  end,
})

Configuration

Plugin Options

require("vue-sfc-format").setup({
  config_file = ".vue-sfc-format.json",  -- JSON config file name
  indent = 2,                             -- Indentation for template content
  temp_dir = "/tmp",                      -- Temp file directory
  remove_space_before_self_close = true,  -- Remove space before /> in self-closing tags
})

JSON Configuration File

Create a .vue-sfc-format.json file in your project root:

{
  "indent": 2,
  "remove_space_before_self_close": true,
  "formatters": {
    "template": {
      "cmd": "npx",
      "args": [
        "js-beautify",
        "--type", "html",
        "--indent-size", "2",
        "--wrap-attributes", "force-aligned",
        "--wrap-line-length", "120",
        "--indent-inner-html",
        "--preserve-newlines",
        "--max-preserve-newlines", "2"
      ]
    },
    "script": {
      "cmd": "npx",
      "args": [
        "prettier",
        "--parser", "babel",
        "--semi", "false",
        "--single-quote",
        "--trailing-comma", "none",
        "--tab-width", "2",
        "--print-width", "120"
      ]
    },
    "style": {
      "cmd": "npx",
      "args": [
        "prettier",
        "--parser", "css",
        "--tab-width", "2",
        "--print-width", "120"
      ]
    },
    "style_scss": {
      "cmd": "npx",
      "args": [
        "prettier",
        "--parser", "scss",
        "--tab-width", "2",
        "--print-width", "120"
      ]
    }
  }
}

The plugin automatically uses style_scss when <style lang="scss"> is detected.

Usage

Command

:VueSfcFormat

Lua API

-- Format current buffer
require("vue-sfc-format").format()

-- Format specific buffer
require("vue-sfc-format").format(bufnr)

formatter.nvim Integration

require("formatter").setup({
  filetype = {
    vue = {
      function()
        return require("vue-sfc-format").formatter_nvim_config()
      end,
    },
  },
})

Example

Given this Vue file:

<template>
<div class="container"><span>Hello</span></div>
</template>

<script>
export default {name: 'MyComponent',data() {return {message: 'Hello'}}}
</script>

<style lang="scss" scoped>
.container {color: red;span {font-weight: bold;}}
</style>

After formatting:

<template>
  <div class="container">
    <span>Hello</span>
  </div>
</template>

<script>
export default {
  name: 'MyComponent',
  data() {
    return { message: 'Hello' }
  }
}
</script>

<style lang="scss" scoped>
.container {
  color: red;
  span {
    font-weight: bold;
  }
}
</style>

License

MIT

Community

About

Format Vue SFC files with configurable formatters for each section

Topics

Resources

License

Code of conduct

Contributing

Security policy

Stars

Watchers

Forks

Packages

 
 
 

Contributors