A Neovim plugin that lets you search using JavaScript/PCRE regex syntax — patterns are translated to Vim regex and executed as a native / search, so n, N, hlsearch, and all built-in search features work out of the box.
- Write regex in JavaScript/PCRE syntax instead of Vim's
- Patterns are translated to Vim regex and fed to the native
/search n/Nnavigation works automatically (no custom keymaps)hlsearchhighlighting works automatically- No external dependencies (no
rg,grep, or any other tool) - Interactive prompt via
vim.ui.input
Instead of calling external tools like rg or grep, this plugin translates your JavaScript-style regex into Vim's regex syntax using \v (very magic) mode and then sets the search register (@/). This means Neovim handles the actual searching, highlighting, and navigation natively.
| JavaScript/PCRE | Vim (very magic) |
|---|---|
(group) |
(group) (same in \v) |
a+, a?, a{2,3} |
Same in \v |
*?, +?, ?? (lazy) |
{-}, {-1,}, {-0,1} |
{n,m}? (lazy) |
{-n,m} |
a|b |
a|b (same in \v) |
(?:non-capture) |
%(non-capture) |
(?=lookahead) |
(lookahead)@= |
(?!neg lookahead) |
(neg lookahead)@! |
(?<=lookbehind) |
(lookbehind)@<= |
(?<!neg lookbehind) |
(neg lookbehind)@<! |
(?<name>named) |
(named) (name stripped) |
\b (word boundary) |
(\<|\>) |
\d, \w, \s |
Same |
[a-z] |
Same |
Using lazy.nvim
{
"jsregex.nvim",
dir = "~/projects/jsregex.nvim",
config = function()
require("jsregex").setup()
end,
}Using packer.nvim
use {
"~/projects/jsregex.nvim",
config = function()
require("jsregex").setup()
end
}Using vim-plug
Plug '~/projects/jsregex.nvim'Then in your init.lua:
require("jsregex").setup():JSRegexSearch- Prompts for a JS/PCRE regex pattern and searches the buffer:JSRegexClear- Clears the search highlight and search register
local jsregex = require("jsregex")
-- Search with a specific pattern
jsregex.find_matches("\\w+")
-- Prompt user for pattern interactively
jsregex.search()
-- Clear search
jsregex.clear()
-- Translate a pattern without searching (useful for debugging)
local vim_regex = jsregex.js_to_vim_regex("(?<=@)\\w+")
-- Returns: \v(\@<=)\w+ (or similar)vim.keymap.set("n", "<leader>rs", "<cmd>JSRegexSearch<cr>", { desc = "JS regex search" })
vim.keymap.set("n", "<leader>rc", "<cmd>JSRegexClear<cr>", { desc = "Clear regex search" })Once you run :JSRegexSearch and enter a pattern:
- All matches are highlighted (via
hlsearch) - Press
nto jump to the next match - Press
Nto jump to the previous match - Use
:JSRegexClearor:nohlsearchto clear
These are all standard Neovim behaviors — no custom keymaps are involved.
Use JavaScript/PCRE regex syntax directly:
\w+- Match one or more word charactersfunction- Match the literal word "function"\d{3}- Match exactly 3 digits^\s*$- Match empty lineshttps?://- Match http or https URLs(['"])(.*?)\1- Match quoted strings with backreferences(?:non)?capturing- Non-capturing groups(?<=@)\w+- Positive lookbehind (match word after @)(?=\s)- Positive lookahead (match position before whitespace)
The following PCRE features do not have Vim equivalents and are not supported:
- Possessive quantifiers (
a++,a?+) - Atomic groups (
(?>...)) - Conditional patterns (
(?(condition)yes|no)) \p{...}Unicode property classes- Recursive patterns
\K(keep out)
Most everyday JavaScript regex patterns work correctly.
- Edit files in
~/projects/jsregex.nvim/ - Reload Neovim or run
:source % - Test with
:JSRegexSearch
You can also test translations directly:
:lua print(require("jsregex").js_to_vim_regex("(?<=@)\\w+"))Tests use busted, a Lua unit testing framework.
-
Install busted via LuaRocks:
luarocks install busted
-
Run the tests from the project root:
busted tests/
MIT