neovim

Personal neovim configuration files
git clone git://gtms.dev/neovim
Log | Files | Refs

jsonpath.lua (1884B)


      1 local M = {}
      2 
      3 local parsers = require 'nvim-treesitter.parsers'
      4 local ts_utils = require 'nvim-treesitter.ts_utils'
      5 
      6 local get_node_text = function(node)
      7   return vim.treesitter.get_node_text(node, 0)
      8 end
      9 
     10 local get_string_content = function(node)
     11   for _, child in ipairs(ts_utils.get_named_children(node)) do
     12     if child:type() == 'string_content' then
     13       return get_node_text(child)
     14     end
     15   end
     16 
     17   return ''
     18 end
     19 
     20 local starts_with_number = function(str)
     21   return str:match('^%d')
     22 end
     23 
     24 local contains_special_characters = function(str)
     25   return str:match('[^a-zA-Z0-9_]')
     26 end
     27 
     28 M.get = function()
     29   if not parsers.has_parser() then
     30     return ''
     31   end
     32 
     33   local current_node = ts_utils.get_node_at_cursor()
     34   if not current_node then
     35     return ''
     36   end
     37 
     38   local accessors = {}
     39   local node = current_node
     40 
     41   while node do
     42     local accessor = ''
     43 
     44     if node:type() == 'pair' then
     45       local key_node = unpack(node:field('key'))
     46       local key = get_string_content(key_node)
     47 
     48       if starts_with_number(key) or contains_special_characters(key) then
     49         accessor = string.format('["%s"]', key)
     50       else
     51         accessor = string.format('%s', key)
     52       end
     53     end
     54 
     55     if node:type() == 'array' then
     56       accessor = '[]'
     57 
     58       for i, child in ipairs(ts_utils.get_named_children(node)) do
     59         if ts_utils.is_parent(child, current_node) then
     60           accessor = string.format('[%d]', i - 1)
     61         end
     62       end
     63     end
     64 
     65     if accessor ~= '' then
     66       table.insert(accessors, 1, accessor)
     67     end
     68 
     69     node = node:parent()
     70   end
     71 
     72   if #accessors == 0 then
     73     return '.'
     74   end
     75 
     76   local path = ''
     77 
     78   for i, accessor in ipairs(accessors) do
     79     if i == 1 then
     80       path = path .. '.' .. accessor
     81     elseif vim.startswith(accessor, '[') then
     82       path = path .. accessor
     83     else
     84       path = path .. '.' .. accessor
     85     end
     86   end
     87 
     88   return path
     89 end
     90 
     91 return M