Skip to content

Hdoc1509/hygen.nvim

Repository files navigation

hygen.nvim

Plugin that adds support for Hygen templates in Neovim.

Hygen template with Markdown parser injected

Features

Requirements

Install

Installation examples for lazy.nvim and packer.nvim:

nvim-treesitter at main branch

Important

This snippet is for neovim >= 0.11.0

{
  "nvim-treesitter/nvim-treesitter",
  lazy = false, -- if using `lazy.nvim`
  branch = 'main',
  -- `run` instead of `build` if using `packer.nvim`
  build = ':TSUpdate',
  -- `requires` instead of `dependencies` if using `packer.nvim`
  dependencies = { "Hdoc1509/hygen.nvim" },
  config = function()
    -- NOTE: register parser before installation
    require("hygen.tree-sitter").setup()

    require("nvim-treesitter").install({
      "bash", -- optional
      "embedded_template", -- optional
      "hygen_template", -- required
      "javascript", -- optional
      "regex", -- optional
      -- any other parser for dynamic injection
    })
  end,
}

Important

This snippet is for neovim >= 0.11.0. See Minit README for some details about possible compatibility for neovim 0.10.

Installation example

Use install module instead:

{
  "nvim-treesitter/nvim-treesitter",
  lazy = false, -- if using `lazy.nvim`
  branch = 'main',
  -- `run` instead of `build` if using `packer.nvim`
  build = ':TSUpdate',
  -- prior or equal to:
  commit = "73adbe597e8350cdf2773e524eb2199841ea2ab6",
  -- posterior or equal to:
  -- commit = "0bb981c87604200df6c8fb81e5a411101bdf93af",
  -- `requires` instead of `dependencies` if using `packer.nvim`
  dependencies = { 'Hdoc1509/hygen.nvim' },
  config = function()
    -- NOTE: register parser before installation
    require("hygen.tree-sitter").setup()

    require("nvim-treesitter.install").install({
      "bash", -- optional
      "embedded_template", -- optional
      "hygen_template", -- required
      "javascript", -- optional
      "regex", -- optional
      -- any other parser for dynamic injection
    })
  end,
}

configs module of master branch

Important

This snippet is for neovim >= 0.9.0.

Installation example
{
  "nvim-treesitter/nvim-treesitter",
  lazy = false, -- if using `lazy.nvim`
  branch = 'master',
  -- `run` instead of `build` if using `packer.nvim`
  build = ':TSUpdate',
  -- `requires` instead of `dependencies` if using `packer.nvim`
  dependencies = { 'Hdoc1509/hygen.nvim' },
  config = function()
    -- NOTE: register parser before installation
    require("hygen.tree-sitter").setup()

    require("nvim-treesitter.configs").setup({
      ensure_installed = {
        "bash", -- optional
        "embedded_template", -- optional
        "hygen_template", -- required
        "javascript", -- optional
        "regex", -- optional
      -- any other parser for dynamic injection
      },
    })
  end,
}

nvim-web-devicons

{
  "nvim-tree/nvim-web-devicons",
  -- `requires` instead of `dependencies` if using `packer.nvim`
  dependencies = { "Hdoc1509/hygen.nvim" },
  config = function()
    require("nvim-web-devicons").setup({})
    require("hygen.web-devicons").setup()
  end,
}

Default configuration

hygen.tree-sitter setup

Default configuration
---@type Hygen.TS.Opts
{
  -- Whether to `generate` files from the grammar before building it.
  from_grammar = nil,
  -- Path to local `tree-sitter-hygen-template`.
  path = nil,
  -- Remote URL to `tree-sitter-hygen-template`.
  url = "https://github.com/Hdoc1509/tree-sitter-hygen-template",
  -- Branch, tag or commit of `tree-sitter-hygen-template`.
  revision = "v0.5.0",
}

New directive

inject-hygen-ejs! directive

Important

This directive requires embedded_template parser.

This directive allows to inject ejs in dynamic-injection, i.e., having after/queries/bash/injections.scm in user's config directory:

; extends
; don't forget to include `extends` modeline!

(command
  (string
    (string_content) @injection.content
    (#lua-match? @injection.content "<%%=")
    (#inject-hygen-ejs! "")))

The example query will inject ejs to bash strings that contain <%= and are also string arguments of a command. This injection will only take effect in hygen files that has bash parser injected.

Hygen-colored icons

Note

This utillity requires nvim-web-devicons plugin.

The hygen.web-devicons module exports the get_icon(filename) utility. It fallbacks to nvim-web-devicons if filename does not match naming convention.

local hygen_devicons = require("hygen.web-devicons")

-- `icon` for `README.md` file, hygen `color` and `hl` group of hygen `color`
local icon, color, hl = hygen_devicons.get_icon("README.md.hygen")

-- now returns `icon` for `md` files
local icon, color, hl = hygen_devicons.get_icon("custom.md.hygen")

See screenshots of Dynamic injection section for visual examples.

Integrations

Important

Be sure to set hygen.nvim as a dependency and to load render-markdown.nvim for hygen filetype.

Configuration example

The following snippet will allow to attach to hygen files that has md or mdx as subextension.

local hygen_utils = require('hygen.utils')
local allowed_hygen_subext = { 'md', 'mdx' }

require("render-markdown").setup({
  ignore = function(bufnr)
    if vim.bo[bufnr].filetype == "hygen" then
      return not vim.tbl_contains(
        allowed_hygen_subext,
        hygen_utils.get_hygen_subext(bufnr)
      )
    else
      return false
    end
  end,
})

Important

Be sure to set hygen.nvim and nvim-web-devicons as a dependencies

Configuration example
local hygen_devicons = require('hygen.web-devicons')

require("tabby").setup({
  line = function(line)
    return {
      line.tabs().foreach(function(tab)
        local filename = tab.current_win().buf_name()
        local icon, icon_color = hygen_devicons.get_icon(filename)

        -- NOTE: use `icon` and `icon_color` to fit your needs
        return { --[[ ... ]] }
      end),
    }
  end,
})

Important

Be sure to set hygen.nvim and nvim-web-devicons as a dependencies

Configuration example
local hygen_devicons = require('hygen.web-devicons')

require("incline").setup({
  render = function(props)
    local filename = vim.fs.basename(vim.api.nvim_buf_get_name(props.buf))
    local icon, icon_color = hygen_devicons.get_icon(filename)

    -- NOTE: use `icon` and `icon_color` to fit your needs
    return { --[[ ... ]] }
  end,
})

Important

Be sure to set hygen.nvim and nvim-web-devicons as a dependencies

Configuration example
local hygen_devicons = require('hygen.web-devicons')

require("mini.files").setup({
  content = {
    prefix = function(fs_entry)
      if fs_entry.fs_type == 'directory' then
        return '', 'MiniFilesDirectory'
      end

      local icon, _, hl = hygen_devicons.get_icon(fs_entry.name)
      return icon .. ' ', hl
    end,
  },
})

LSP configuration

The hygen.ts-query-ls module exports an LSP configuration for ts_query_ls server to register the custom directives used by this plugin.

Important

This is only needed if you will use the directives defined by this plugin in your queries and if you have set the valid_directives setting for ts_query_ls.


Note

You can check my config for ts_query_ls for reference.

nvim-lspconfig + neovim < 0.11

Important

Be sure to set hygen.nvim as a dependency

local lspconfig = require('lspconfig')
local hygen = require('hygen.ts-query-ls')

lspconfig.ts_query_ls.setup(vim.tbl_deep_extend('force', {
  -- your settings
}, hygen))

vim.lsp.config + neovim >= 0.11

Important

Be sure to load hygen.nvim before

local hygen = require('hygen.ts-query-ls')

vim.lsp.config('ts_query_ls', vim.tbl_deep_extend('force', {
  -- your settings
}, hygen))
vim.lsp.enable('ts_query_ls')

after/lsp/ts_query_ls.lua + neovim >= 0.11

local hygen = require('hygen.ts-query-ls')

return vim.tbl_deep_extend('force', {
  -- your settings
}, hygen)

Important

Be sure to load vim-map-side.nvim before calling vim.lsp.enable()

See LSP config merge

Then, in your init.lua:

vim.lsp.enable('ts_query_ls')

Dynamic injection

Dynamic injection is applied following the file naming convention of tree-sitter-hygen-template

vite.config.ts.hygen

vite.config.ts.hygen

Normal icon


vite.config.ts.hygen with hygen-colored icon

Hygen-colored icon

Layout.astro.hygen

Layout.astro.hygen

Normal icon


Layout.astro.hygen with hygen-colored icon

Hygen-colored icon

package.json.hygen

package.json.hygen

Normal icon


package.json.hygen with hygen-colored icon

Hygen-colored icon

mini.files

mini.files

Normal icon

mini.files with hygen-colored icon

Hygen-colored icon

metadata-from-key.md.hygen

Hygen template with ignored body

Ignored template's body highlighted as comment because of presence of from metadata key

Troubleshooting

Important

Be sure to run :checkhealth vim.treesitter nvim-treesitter before checking the following errors.

Incompatible ABI version

If you found the following error:

- ERROR Parser "hygen_template" failed to load
  (path: .../hygen_template.so): ...: ABI version mismatch for
  .../hygen_template.so: supported between X and Y, found Z

Note

X and Y are the interval of ABI versions supported by neovim. Z is the ABI version that was used to develop the parser.

  1. Install the following tools:

  2. Run :TSInstallFromGrammar hygen_template to re-install the parser with the correct ABI version.

It's also recommended to add the from_grammar option to the setup function of the tree-sitter module in order to avoid the need to run :TSInstallFromGrammar every time nvim-treesitter is updated:

require("hygen.tree-sitter").setup({
  from_grammar = true
})

Duplicated hygen_template parser in output of vim.treesitter checkhealth

This error happens when nvim-treesitter has been updated from master branch to main branch because default value of install_dir for parsers has changed:

Before:

<path-of-nvim-treesitter>/parser/

After:

vim.fs.joinpath(vim.fn.stdpath('data'), 'site', 'parser')

This can cause to load the old version of hygen_template parser from main branch.

To fix this error, remove all .so files from <path-of-nvim-treesitter>/parser.

Now run :checkhealth vim.treesitter again and it should be fixed. Only one hygen_template parser should appear in the output.

Updates

This plugin will follow changes of tree-sitter-hygen-template:

Thanks

Thanks to @ngynkvn for this idea