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