Skip to content

Commit

Permalink
fix: skip out of unrecognized filetypes
Browse files Browse the repository at this point in the history
Closes #43

Co-Authored-By: Argjun Sahlot <[email protected]>
  • Loading branch information
bennypowers and ArjunSahlot committed May 26, 2024
1 parent 78fff71 commit 40da8f8
Show file tree
Hide file tree
Showing 2 changed files with 46 additions and 33 deletions.
51 changes: 29 additions & 22 deletions lua/regexplainer.lua
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,23 @@ local tree = require 'regexplainer.utils.treesitter'
local utils = require 'regexplainer.utils'
local buffers = require 'regexplainer.buffers'
local defer = require 'regexplainer.utils.defer'
local get_node_text = vim.treesitter.get_node_text or vim.treesitter.query.get_node_text

---@class RegexplainerOptions
---@field mode? 'narrative' # TODO: 'ascii', 'graphical'
---@field auto? boolean # Automatically display when cursor enters a regexp
---@field filetypes? string[] # Filetypes (extensions) to automatically show regexplainer.
---@field debug? boolean # Notify debug logs
---@field display? 'split'|'popup'
---@field mappings? RegexplainerMappings # keymappings to automatically bind. Supports `which-key`
---@field narrative? RegexplainerNarrativeRendererOptions # Options for the narrative renderer
---@field popup? NuiPopupBufferOptions # options for the popup buffer
---@field split? NuiSplitBufferOptions # options for the split buffer

---@class RegexplainerRenderOptions : RegexplainerOptions
---@field register "*"|"+"|'"'|":"|"."|"%"|"/"|"#"|"0"|"1"|"2"|"3"|"4"|"5"|"6"|"7"|"8"|"9"

---@class RegexplainerYankOptions : RegexplainerOptions
---@field register "*"|"+"|'"'|":"|"."|"%"|"/"|"#"|"0"|"1"|"2"|"3"|"4"|"5"|"6"|"7"|"8"|"9"

---@class RegexplainerMappings
---@field show? string # shows regexplainer
Expand All @@ -13,6 +29,8 @@ local get_node_text = vim.treesitter.get_node_text or vim.treesitter.query.get_n
---@field show_split? string # shows regexplainer in a split window
---@field show_popup? string # shows regexplainer in a popup window

local get_node_text = vim.treesitter.get_node_text or vim.treesitter.query.get_node_text

---Maps config.mappings keys to vim command names and descriptions
--
local config_command_map = {
Expand All @@ -27,17 +45,7 @@ local config_command_map = {
---Augroup for auto = true
local augroup_name = 'Regexplainer'

---@class RegexplainerOptions
---@field mode? 'narrative' # TODO: 'ascii', 'graphical'
---@field auto? boolean # Automatically display when cursor enters a regexp
---@field filetypes? string[] # Filetypes (extensions) to automatically show regexplainer.
---@field debug? boolean # Notify debug logs
---@field display? 'split'|'popup'
---@field mappings? RegexplainerMappings # keymappings to automatically bind. Supports `which-key`
---@field narrative? RegexplainerNarrativeRendererOptions # Options for the narrative renderer
---@field popup? NuiPopupBufferOptions # options for the popup buffer
---@field split? NuiSplitBufferOptions # options for the split buffer
--
---@type RegexplainerOptions
local default_config = {
mode = 'narrative',
auto = false,
Expand All @@ -62,9 +70,6 @@ local default_config = {
},
}

---@class RegexplainerRenderOptions : RegexplainerOptions
---@field register "*"|"+"|'"'|":"|"."|"%"|"/"|"#"|"0"|"1"|"2"|"3"|"4"|"5"|"6"|"7"|"8"|"9"

--- A deep copy of the default config.
--- During setup(), any user-provided config will be folded in
---@type RegexplainerOptions
Expand All @@ -77,7 +82,7 @@ local local_config = vim.tbl_deep_extend('keep', default_config, {})
--
local function show(options)
options = vim.tbl_deep_extend('force', local_config, options or {})
local node, error = tree.get_regexp_pattern_at_cursor()
local node, error = tree.get_regexp_pattern_at_cursor(options)

if error and options.debug then
utils.notify('Rexexplainer: ' .. error, 'debug')
Expand All @@ -89,7 +94,7 @@ local function show(options)

---@type RegexplainerRenderer
local renderer
---@type boolean, RexeplainerRenderer
---@type boolean, RegexplainerRenderer
local can_render, _renderer = pcall(require, 'regexplainer.renderers.' .. options.mode)

if can_render then
Expand All @@ -105,7 +110,8 @@ local function show(options)
local buffer = buffers.get_buffer(options)

if not buffer and options.debug then
return require 'regexplainer.renderers.debug'.render(options, components)
local Debug = require 'regexplainer.renderers.debug'
return Debug.render(options, components)
end

buffers.render(buffer, renderer, components, options, {
Expand All @@ -132,17 +138,18 @@ function M.show(options)
disable_auto = false
end

---@class RegexplainerYankOptions
---@field register "*"|"+"|'"'|":"|"."|"%"|"/"|"#"|"0"|"1"|"2"|"3"|"4"|"5"|"6"|"7"|"8"|"9"

--- Yank the explainer for the regexp under the cursor into a given register
---@param options? string|RegexplainerYankOptions
function M.yank(options)
disable_auto = true
if type(options) == 'string' then
options = { register = options }
end
show(vim.tbl_deep_extend('force', options, { display = 'register' }))
show(vim.tbl_deep_extend(
'force',
options,
{ display = 'register' }
))
disable_auto = false
end

Expand Down
28 changes: 17 additions & 11 deletions lua/regexplainer/utils/treesitter.lua
Original file line number Diff line number Diff line change
Expand Up @@ -39,13 +39,13 @@ for _, type in ipairs(node_types) do
end

-- Get previous node with same parent
---@param node TSNode
---@param node? TSNode
---@param allow_switch_parents? boolean allow switching parents if first node
---@param allow_previous_parent? boolean allow previous parent if first node and previous parent without children
---@return TSNode?
local function get_previous_node(node, allow_switch_parents, allow_previous_parent)
local destination_node ---@type TSNode?
local parent = node:parent()
local parent = node and node:parent()
if not parent then
return
end
Expand All @@ -60,7 +60,7 @@ local function get_previous_node(node, allow_switch_parents, allow_previous_pare
if 0 < found_pos then
destination_node = parent:named_child(found_pos - 1)
elseif allow_switch_parents then
local previous_node = get_previous_node(node:parent())
local previous_node = get_previous_node(parent)
if previous_node and previous_node:named_child_count() > 0 then
destination_node = previous_node:named_child(previous_node:named_child_count() - 1)
elseif previous_node and allow_previous_parent then
Expand All @@ -70,7 +70,7 @@ local function get_previous_node(node, allow_switch_parents, allow_previous_pare
return destination_node
end

---@param node TSNode
---@param node? TSNode
---@return TSNode?
local function get_root_for_node(node)
---@type TSNode?
Expand All @@ -87,7 +87,7 @@ end

---@param row number
---@param col number
---@param root_lang_tree LanguageTree
---@param root_lang_tree vim.treesitter.LanguageTree
---@return TSNode?
local function get_root_for_position(row, col, root_lang_tree)
local lang_tree = root_lang_tree:language_for_range { row, col, row, col }
Expand All @@ -103,7 +103,7 @@ local function get_root_for_position(row, col, root_lang_tree)
return nil
end

---@param root_lang_tree LanguageTree
---@param root_lang_tree vim.treesitter.LanguageTree
---@return TSNode?
local function get_node_at_cursor(root_lang_tree)
local cursor = vim.api.nvim_win_get_cursor(0)
Expand All @@ -121,7 +121,7 @@ end

---Enter a parent-language's regexp node which contains the embedded
---regexp grammar
---@param root_lang_tree LanguageTree
---@param root_lang_tree vim.treesitter.LanguageTree
---@param node TSNode
---@return TSNode?
local function enter_js_re_node(root_lang_tree, node)
Expand Down Expand Up @@ -183,7 +183,7 @@ function M.is_punctuation(type)
end

-- Is this the document root (or close enough for our purposes)?
---@param node TSNode
---@param node? TSNode
---@return boolean
function M.is_document(node)
if node == nil then return true else
Expand Down Expand Up @@ -231,19 +231,25 @@ end

--- Using treesitter, find the current node at cursor, and traverse up to the
--- document root to determine if we're on a regexp
---@param options RegexplainerOptions
---@return any, string|nil
--
function M.get_regexp_pattern_at_cursor()
local root_lang_tree = vim.treesitter.get_parser(0, vim.treesitter.language.get_lang(vim.bo[0].ft))
function M.get_regexp_pattern_at_cursor(options)
local filetype = vim.bo[0].ft
if not vim.tbl_contains(options.filetypes, filetype) then
return nil, 'unrecognized filetype'
end
local root_lang_tree = vim.treesitter.get_parser(0, vim.treesitter.language.get_lang(filetype))
local cursor_node = get_node_at_cursor(root_lang_tree)
local cursor_node_type = cursor_node and cursor_node:type()
if not cursor_node or cursor_node_type == 'program' then
return
end

---@type TSNode?
local node = cursor_node

if node:type() == 'regex' then
if node and node:type() == 'regex' then
local iterator = node:iter_children()

-- break if we enter an infinite loop (probably)
Expand Down

0 comments on commit 40da8f8

Please sign in to comment.