bennypowers/nvim-regexplainer

github github
editing-support
stars 591
issues 6
subscribers 4
forks 7
CREATED

2022-02-16

UPDATED

6 months ago


Am Yisrael Chai - עם ישראל חי

nvim-regexplainer

Lua GitHub Workflow Status Number of users on dotfyle

Describe the regular expression under the cursor.

https://user-images.githubusercontent.com/1466420/156946492-a05600dc-0a5b-49e6-9ad2-417a403909a8.mov

Heavily inspired by the venerable atom-regexp-railroad.

👉 NOTE: Requires Neovim 0.7 👈

🚚 Installation

use { 'bennypowers/nvim-regexplainer',
      config = function() require'regexplainer'.setup() end,
      requires = {
        'nvim-treesitter/nvim-treesitter',
        'MunifTanjim/nui.nvim',
      } }

You need to install regex with nvim-treesitter, as well as the grammar for whichever host language you're using. So for example if you wish to use Regexplainer with TypeScript sources, you need to do this:

:TSInstall regex typescript

🤔 Config

-- defaults
require'regexplainer'.setup {
  -- 'narrative'
  mode = 'narrative', -- TODO: 'ascii', 'graphical'

  -- automatically show the explainer when the cursor enters a regexp
  auto = false,

  -- filetypes (i.e. extensions) in which to run the autocommand
  filetypes = {
    'html',
    'js',
    'cjs',
    'mjs',
    'ts',
    'jsx',
    'tsx',
    'cjsx',
    'mjsx',
  },

  -- Whether to log debug messages
  debug = false, 

  -- 'split', 'popup'
  display = 'popup',

  mappings = {
    toggle = 'gR',
    -- examples, not defaults:
    -- show = 'gS',
    -- hide = 'gH',
    -- show_split = 'gP',
    -- show_popup = 'gU',
  },

  narrative = {
    separator = '\n',
  },
}

display

Regexplainer offers a small variety of display modes to suit your preferences.

Split Window

Set to split to display the explainer in a window below the editor. The window will be reused, and has the filetype Regexplainer

Popup Below Cursor

Set to popup (the default) to display the explainer in a popup below the cursor. When the cursor moves, the popup closes. if auto is set, the popup will automatically display whenever the cursor moves inside a regular expression You can call show with your own display type to override your config

require'regexplainer'.show { display = 'split' }

Or use the commands RegexplainerShowSplit or RegexplainerShowPopup. RegexplainerHide and RegexplainerToggle are also available.

You can customize the popup window by specifying options.popup.border, which is a table of popup options from nui. Any options specified for options.popup will also override the defaults.

require'regexplainer'.show {
  display = 'popup',
  popup = {
    border = {
      padding = { 1, 2 },
      style = 'solid',
    },
  },
}

You could use this to, for example, set a different border based on the state of your editor.

Render Options

narrative.separator can also be a function taking the current component and returning a string clause separator. For example, to separate clauses by a new line, followed by > for each level of capture-group depth, define the following function:

narrative = {
  separator = function(component)
    local sep = '\n';
    if component.depth > 0 then
      for _ = 1, component.depth do
        sep = sep .. '> '
      end
    end
    return sep
  end
},

Input:

/zero(one(two(?<inner>three)))/;

Output:

`zero`  
capture group 1:  
> `one`  
> capture group 2:  
> > `two`  
> > named capture group 3 `inner`:  
> > > `three`

Yank

You can yank the regexplanation into any register with the yank function. The default register is ". This can be useful if you'd like to share the explanation of a regexp with your teammates, or if you'd like to report a mistake in regexplainer. The argument to yank is either a string (the register to yank to) or a table with register: string and options to show (e.g. mode = 'narrative', narrative = {}, etc.).

For example, to copy the regexplanation to your system clipboard, use either of these:

require'regexplainer'.yank'+'
require'regexplainer'.yank { register = '+' }

You can also use the command RegexplainerYank

:RegexplainerYank +

🗃️ TODO list