Compare commits

..

No commits in common. "2346a75cae02dc770801ac5a4625bd4bc7ddd548" and "5b11ed040450b471e4f77261438f93c216aa61cc" have entirely different histories.

9 changed files with 1168 additions and 1286 deletions

61
flake.lock generated
View File

@ -1,61 +0,0 @@
{
"nodes": {
"nixpkgs": {
"locked": {
"lastModified": 1748929857,
"narHash": "sha256-lcZQ8RhsmhsK8u7LIFsJhsLh/pzR9yZ8yqpTzyGdj+Q=",
"owner": "nixos",
"repo": "nixpkgs",
"rev": "c2a03962b8e24e669fb37b7df10e7c79531ff1a4",
"type": "github"
},
"original": {
"owner": "nixos",
"ref": "nixos-unstable",
"repo": "nixpkgs",
"type": "github"
}
},
"root": {
"inputs": {
"nixpkgs": "nixpkgs",
"utils": "utils"
}
},
"systems": {
"locked": {
"lastModified": 1681028828,
"narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
"owner": "nix-systems",
"repo": "default",
"rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
"type": "github"
},
"original": {
"owner": "nix-systems",
"repo": "default",
"type": "github"
}
},
"utils": {
"inputs": {
"systems": "systems"
},
"locked": {
"lastModified": 1731533236,
"narHash": "sha256-l0KFg5HjrsfsO/JpG+r7fRrqm12kzFHyUHqHCVpMMbI=",
"owner": "numtide",
"repo": "flake-utils",
"rev": "11707dc2f618dd54ca8739b309ec4fc024de578b",
"type": "github"
},
"original": {
"owner": "numtide",
"repo": "flake-utils",
"type": "github"
}
}
},
"root": "root",
"version": 7
}

View File

@ -1,43 +0,0 @@
{
description = "jsonfly";
inputs = {
nixpkgs.url = "github:nixos/nixpkgs?ref=nixos-unstable";
utils.url = "github:numtide/flake-utils";
};
outputs = { nixpkgs, utils, ... } @ inputs:
utils.lib.eachDefaultSystem(system:
let
pkgs = nixpkgs.legacyPackages.${system};
logo = pkgs.writeText "logo.txt" ''
'';
in
{
devShells.default = pkgs.mkShell {
packages = with pkgs; [
stylua
# If this ever fails, just remove it. It's just for the logo.
lolcat
];
shellHook = ''
cat ${logo} | lolcat
echo "";
echo "Welcome to the jsonfly.nvim development environment!";
echo "";
'';
};
}
);
}

View File

@ -1,10 +0,0 @@
#!/usr/bin/env just --justfile
set dotenv-load := true
_default:
just --list -u
lint:
stylua lua

View File

@ -1,42 +1,47 @@
local M = {}
local M = {};
local _cache = {}
local _cache = {};
---@param buffer integer
function M:cache_buffer(buffer, value)
_cache[buffer] = value
_cache[buffer] = value;
end
---@param buffer integer
function M:invalidate_buffer(buffer)
_cache[buffer] = nil
_cache[buffer] = nil;
end
---@param buffer integer
---@return string[]|nil
function M:get_cache(buffer)
return _cache[buffer]
return _cache[buffer];
end
local _listening_buffers = {}
local _listening_buffers = {};
---@param buffer integer
function M:register_listeners(buffer)
if _listening_buffers[buffer] then
return
return;
end
_listening_buffers[buffer] = true
_listening_buffers[buffer] = true;
vim.api.nvim_buf_attach(buffer, false, {
vim.api.nvim_buf_attach(
buffer,
false,
{
on_lines = function()
self:invalidate_buffer(buffer)
end,
on_detach = function()
self:invalidate_buffer(buffer)
_listening_buffers[buffer] = nil
_listening_buffers[buffer] = nil;
end,
})
}
);
end
return M
return M;

View File

@ -1,11 +1,11 @@
local utils = require("jsonfly.utils")
local utils = require"jsonfly.utils"
-- This string will be used to position the cursor properly.
-- Once everything is set, the cursor searches for this string and jumps to it.
-- After that, it will be removed immediately.
local CURSOR_SEARCH_HELPER = "_jsonFfFfFfLyY0904857CursorHelperRrRrRrR"
local M = {}
local M = {};
-- https://stackoverflow.com/a/24823383/9878135
function table.slice(tbl, first, last, step)
@ -84,7 +84,7 @@ local function write_keys(keys, index, lines)
local key = keys[index]
if index == #keys then
lines[#lines + 1] = '"' .. key.key .. '": "' .. CURSOR_SEARCH_HELPER .. '"'
lines[#lines + 1] = "\"" .. key.key .. "\": \"" .. CURSOR_SEARCH_HELPER .. "\""
return
end
@ -100,7 +100,7 @@ local function write_keys(keys, index, lines)
lines[#lines + 1] = "}"
elseif key.type == "key" then
lines[#lines + 1] = '"' .. key.key .. '":'
lines[#lines + 1] = "\"" .. key.key .. "\":"
write_keys(keys, index + 1, lines)
elseif key.type == "array_wrapper" then
@ -132,7 +132,12 @@ local function add_comma(buffer, insertion_line)
-- Find next non-empty character in reverse
for ii=insertion_line, 0, -BUFFER_SIZE do
local previous_lines = vim.api.nvim_buf_get_lines(buffer, math.max(0, ii - BUFFER_SIZE), ii, false)
local previous_lines = vim.api.nvim_buf_get_lines(
buffer,
math.max(0, ii - BUFFER_SIZE),
ii,
false
)
if #previous_lines == 0 then
return
@ -151,7 +156,14 @@ local function add_comma(buffer, insertion_line)
-- Insert comma at position
local line_number = math.max(0, ii - BUFFER_SIZE) + jj - 1
vim.api.nvim_buf_set_text(buffer, line_number, char_index, line_number, char_index, { "," })
vim.api.nvim_buf_set_text(
buffer,
line_number,
char_index,
line_number,
char_index,
{","}
)
return
end
end
@ -167,10 +179,16 @@ local function expand_empty_object(buffer, line_number)
local position_closing_bracket = string.find(line, "[%}%]]")
local remaining_line = string.sub(line, position_closing_bracket + 1)
vim.api.nvim_buf_set_lines(buffer, line_number, line_number + 1, false, {
vim.api.nvim_buf_set_lines(
buffer,
line_number,
line_number + 1,
false,
{
"{",
"}" .. remaining_line,
})
"}" .. remaining_line
}
)
return line_number + 1
end
@ -280,7 +298,7 @@ function M:jump_to_cursor_helper(buffer)
)
-- -- Go into insert mode
vim.cmd([[execute "normal a"]])
vim.cmd [[execute "normal a"]]
end
-- TODO: Handle top level empty arrays
@ -289,7 +307,7 @@ end
---@param buffer number
function M:insert_new_key(entries, keys, buffer)
-- Close current buffer
vim.cmd([[quit!]])
vim.cmd [[quit!]]
local input_key = flatten_key_description(keys)
---@type boolean
@ -308,8 +326,8 @@ function M:insert_new_key(entries, keys, buffer)
position = {
key_start = 1,
line_number = 1,
value_start = 1,
},
value_start = 1
}
}
should_add_comma = false
else
@ -335,8 +353,8 @@ function M:insert_new_key(entries, keys, buffer)
position = {
key_start = 1,
line_number = 1,
value_start = 1,
},
value_start = 1
}
}
else
local existing_input_keys_depth = #utils:split_by_char(entry.key, ".") + 1
@ -365,7 +383,7 @@ function M:insert_new_key(entries, keys, buffer)
-- Hacky way to jump to end of object
vim.api.nvim_win_set_cursor(0, {entry.position.line_number, entry.position.value_start})
vim.cmd([[execute "normal %"]])
vim.cmd [[execute "normal %"]]
local changes = #writes
local start_line = vim.api.nvim_win_get_cursor(0)[1] - 1
@ -391,4 +409,4 @@ function M:insert_new_key(entries, keys, buffer)
M:jump_to_cursor_helper(buffer)
end
return M
return M;

View File

@ -1,4 +1,4 @@
local VERSION = "20161109.21" -- version history at end of file
local VERSION = '20161109.21' -- version history at end of file
local AUTHOR_NOTE = "-[ JSON.lua package by Jeffrey Friedl (http://regex.info/blog/lua/json) version 20161109.21 ]-"
local OBJDEF = {
@ -6,21 +6,13 @@ local OBJDEF = {
AUTHOR_NOTE = AUTHOR_NOTE,
}
local default_pretty_indent = " "
local default_pretty_options = { pretty = true, align_keys = false, indent = default_pretty_indent }
local isArray = {
__tostring = function()
return "JSON array"
end,
}
isArray.__index = isArray
local isObject = {
__tostring = function()
return "JSON object"
end,
}
isObject.__index = isObject
local isArray = { __tostring = function() return "JSON array" end } isArray.__index = isArray
local isObject = { __tostring = function() return "JSON object" end } isObject.__index = isObject
function OBJDEF:newArray(tbl)
return setmetatable(tbl or {}, isArray)
@ -30,56 +22,36 @@ function OBJDEF:newObject(tbl)
return setmetatable(tbl or {}, isObject)
end
local function getnum(op)
return type(op) == "number" and op or op.N
return type(op) == 'number' and op or op.N
end
local isNumber = {
__tostring = function(T)
return T.S
end,
__unm = function(op)
return getnum(op)
end,
__tostring = function(T) return T.S end,
__unm = function(op) return getnum(op) end,
__concat = function(op1, op2)
return tostring(op1) .. tostring(op2)
end,
__add = function(op1, op2)
return getnum(op1) + getnum(op2)
end,
__sub = function(op1, op2)
return getnum(op1) - getnum(op2)
end,
__mul = function(op1, op2)
return getnum(op1) * getnum(op2)
end,
__div = function(op1, op2)
return getnum(op1) / getnum(op2)
end,
__mod = function(op1, op2)
return getnum(op1) % getnum(op2)
end,
__pow = function(op1, op2)
return getnum(op1) ^ getnum(op2)
end,
__lt = function(op1, op2)
return getnum(op1) < getnum(op2)
end,
__eq = function(op1, op2)
return getnum(op1) == getnum(op2)
end,
__le = function(op1, op2)
return getnum(op1) <= getnum(op2)
end,
__concat = function(op1, op2) return tostring(op1) .. tostring(op2) end,
__add = function(op1, op2) return getnum(op1) + getnum(op2) end,
__sub = function(op1, op2) return getnum(op1) - getnum(op2) end,
__mul = function(op1, op2) return getnum(op1) * getnum(op2) end,
__div = function(op1, op2) return getnum(op1) / getnum(op2) end,
__mod = function(op1, op2) return getnum(op1) % getnum(op2) end,
__pow = function(op1, op2) return getnum(op1) ^ getnum(op2) end,
__lt = function(op1, op2) return getnum(op1) < getnum(op2) end,
__eq = function(op1, op2) return getnum(op1) == getnum(op2) end,
__le = function(op1, op2) return getnum(op1) <= getnum(op2) end,
}
isNumber.__index = isNumber
function OBJDEF:asNumber(item)
if getmetatable(item) == isNumber then
-- it's already a JSON number object.
return item
elseif type(item) == "table" and type(item.S) == "string" and type(item.N) == "number" then
elseif type(item) == 'table' and type(item.S) == 'string' and type(item.N) == 'number' then
-- it's a number-object table that lost its metatable, so give it one
return setmetatable(item, isNumber)
else
@ -93,7 +65,7 @@ function OBJDEF:asNumber(item)
end
function OBJDEF:forceString(item)
if type(item) == "table" and type(item.S) == "string" then
if type(item) == 'table' and type(item.S) == 'string' then
return item.S
else
return tostring(item)
@ -101,26 +73,30 @@ function OBJDEF:forceString(item)
end
function OBJDEF:forceNumber(item)
if type(item) == "table" and type(item.N) == "number" then
if type(item) == 'table' and type(item.N) == 'number' then
return item.N
else
return tonumber(item)
end
end
local function unicode_codepoint_as_utf8(codepoint)
--
-- codepoint is a number
--
if codepoint <= 127 then
return string.char(codepoint)
elseif codepoint <= 2047 then
--
-- 110yyyxx 10xxxxxx <-- useful notation from http://en.wikipedia.org/wiki/Utf8
--
local highpart = math.floor(codepoint / 0x40)
local lowpart = codepoint - (0x40 * highpart)
return string.char(0xC0 + highpart, 0x80 + lowpart)
return string.char(0xC0 + highpart,
0x80 + lowpart)
elseif codepoint <= 65535 then
--
-- 1110yyyy 10yyyyxx 10xxxxxx
@ -138,16 +114,18 @@ local function unicode_codepoint_as_utf8(codepoint)
-- Check for an invalid character (thanks Andy R. at Adobe).
-- See table 3.7, page 93, in http://www.unicode.org/versions/Unicode5.2.0/ch03.pdf#G28070
--
if
(highpart == 0xE0 and midpart < 0xA0)
or (highpart == 0xED and midpart > 0x9F)
or (highpart == 0xF0 and midpart < 0x90)
or (highpart == 0xF4 and midpart > 0x8F)
if ( highpart == 0xE0 and midpart < 0xA0 ) or
( highpart == 0xED and midpart > 0x9F ) or
( highpart == 0xF0 and midpart < 0x90 ) or
( highpart == 0xF4 and midpart > 0x8F )
then
return "?"
else
return string.char(highpart, midpart, lowpart)
return string.char(highpart,
midpart,
lowpart)
end
else
--
-- 11110zzz 10zzyyyy 10yyyyxx 10xxxxxx
@ -159,7 +137,10 @@ local function unicode_codepoint_as_utf8(codepoint)
local midB = math.floor(remainder / 0x40)
local lowpart = remainder - 0x40 * midB
return string.char(0xF0 + highpart, 0x80 + midA, 0x80 + midB, 0x80 + lowpart)
return string.char(0xF0 + highpart,
0x80 + midA,
0x80 + midB,
0x80 + lowpart)
end
end
@ -206,7 +187,8 @@ local function grok_number(self, text, start, options)
--
-- Grab the integer part
--
local integer_part = text:match("^-?[1-9]%d*", start) or text:match("^-?0", start)
local integer_part = text:match('^-?[1-9]%d*', start)
or text:match("^-?0", start)
if not integer_part then
self:onDecodeError("expected number", text, start, options.etc)
@ -218,14 +200,14 @@ local function grok_number(self, text, start, options)
--
-- Grab an optional decimal part
--
local decimal_part = text:match("^%.%d+", i) or ""
local decimal_part = text:match('^%.%d+', i) or ""
i = i + decimal_part:len()
--
-- Grab an optional exponential part
--
local exponent_part = text:match("^[eE][-+]?%d+", i) or ""
local exponent_part = text:match('^[eE][-+]?%d+', i) or ""
i = i + exponent_part:len()
@ -241,19 +223,21 @@ local function grok_number(self, text, start, options)
-- I suppose we should really look to see whether the exponent is actually big enough one
-- way or the other to trip stringification, but I'll be lazy about it until someone asks.
--
if
(
options.decodeIntegerStringificationLength
and (integer_part:len() >= options.decodeIntegerStringificationLength or exponent_part:len() > 0)
)
or (
options.decodeDecimalStringificationLength
and (decimal_part:len() >= options.decodeDecimalStringificationLength or exponent_part:len() > 0)
)
if (options.decodeIntegerStringificationLength
and
(integer_part:len() >= options.decodeIntegerStringificationLength or exponent_part:len() > 0))
or
(options.decodeDecimalStringificationLength
and
(decimal_part:len() >= options.decodeDecimalStringificationLength or exponent_part:len() > 0))
then
return full_number_text, i -- this returns the exact string representation seen in the original JSON
end
local as_number = tonumber(full_number_text)
if not as_number then
@ -264,7 +248,9 @@ local function grok_number(self, text, start, options)
return as_number, i
end
local function grok_string(self, text, start, options)
if text:sub(start,start) ~= '"' then
self:onDecodeError("expected string's opening quote", text, start, options.etc)
return nil, start -- in case the error method doesn't abort, return something sensible
@ -278,29 +264,26 @@ local function grok_string(self, text, start, options)
if c == '"' then
return VALUE, i + 1
end
if c ~= "\\" then
if c ~= '\\' then
VALUE = VALUE .. c
i = i + 1
elseif text:match("^\\b", i) then
elseif text:match('^\\b', i) then
VALUE = VALUE .. "\b"
i = i + 2
elseif text:match("^\\f", i) then
elseif text:match('^\\f', i) then
VALUE = VALUE .. "\f"
i = i + 2
elseif text:match("^\\n", i) then
elseif text:match('^\\n', i) then
VALUE = VALUE .. "\n"
i = i + 2
elseif text:match("^\\r", i) then
elseif text:match('^\\r', i) then
VALUE = VALUE .. "\r"
i = i + 2
elseif text:match("^\\t", i) then
elseif text:match('^\\t', i) then
VALUE = VALUE .. "\t"
i = i + 2
else
local hex = text:match(
"^\\u([0123456789aAbBcCdDeEfF][0123456789aAbBcCdDeEfF][0123456789aAbBcCdDeEfF][0123456789aAbBcCdDeEfF])",
i
)
local hex = text:match('^\\u([0123456789aAbBcCdDeEfF][0123456789aAbBcCdDeEfF][0123456789aAbBcCdDeEfF][0123456789aAbBcCdDeEfF])', i)
if hex then
i = i + 6 -- bypass what we just read
@ -309,8 +292,7 @@ local function grok_string(self, text, start, options)
local codepoint = tonumber(hex, 16)
if codepoint >= 0xD800 and codepoint <= 0xDBFF then
-- it's a hi surrogate... see whether we have a following low
local lo_surrogate =
text:match("^\\u([dD][cdefCDEF][0123456789aAbBcCdDeEfF][0123456789aAbBcCdDeEfF])", i)
local lo_surrogate = text:match('^\\u([dD][cdefCDEF][0123456789aAbBcCdDeEfF][0123456789aAbBcCdDeEfF])', i)
if lo_surrogate then
i = i + 6 -- bypass the low surrogate we just read
codepoint = 0x2400 + (codepoint - 0xD800) * 0x400 + tonumber(lo_surrogate, 16)
@ -319,9 +301,11 @@ local function grok_string(self, text, start, options)
end
end
VALUE = VALUE .. unicode_codepoint_as_utf8(codepoint)
else
-- just pass through what's escaped
VALUE = VALUE .. text:match("^\\(.)", i)
VALUE = VALUE .. text:match('^\\(.)', i)
i = i + 2
end
end
@ -342,7 +326,7 @@ end
-- Count newlines in `text` up to `start`
local function count_newlines(text, start)
local _, count = text:sub(1, start):gsub("\n", "\n")
local _, count = text:sub(1, start):gsub('\n', '\n')
return count
end
@ -355,7 +339,7 @@ local function get_relative_i(text, i)
local count = 0
for j = i, 1, -1 do
if text:sub(j, j) == "\n" then
if text:sub(j, j) == '\n' then
break
end
count = count + 1
@ -367,16 +351,17 @@ end
local grok_one -- assigned later
local function grok_object(self, text, start, options)
if text:sub(start, start) ~= "{" then
if text:sub(start,start) ~= '{' then
self:onDecodeError("expected '{'", text, start, options.etc)
return nil, start -- in case the error method doesn't abort, return something sensible
end
local i = skip_whitespace(text, start + 1) -- +1 to skip the '{'
local VALUE = self.strictTypes and self:newObject({}) or {}
local VALUE = self.strictTypes and self:newObject { } or { }
if text:sub(i, i) == "}" then
if text:sub(i,i) == '}' then
return VALUE, i + 1
end
local text_len = text:len()
@ -390,7 +375,7 @@ local function grok_object(self, text, start, options)
i = skip_whitespace(text, new_i)
if text:sub(i, i) ~= ":" then
if text:sub(i, i) ~= ':' then
self:onDecodeError("expected colon", text, i, options.etc)
return nil, i -- in case the error method doesn't abort, return something sensible
end
@ -414,11 +399,11 @@ local function grok_object(self, text, start, options)
local c = text:sub(i,i)
if c == "}" then
if c == '}' then
return VALUE, i + 1
end
if text:sub(i, i) ~= "," then
if text:sub(i, i) ~= ',' then
self:onDecodeError("expected comma or '}'", text, i, options.etc)
return nil, i -- in case the error method doesn't abort, return something sensible
end
@ -431,14 +416,14 @@ local function grok_object(self, text, start, options)
end
local function grok_array(self, text, start, options)
if text:sub(start, start) ~= "[" then
if text:sub(start,start) ~= '[' then
self:onDecodeError("expected '['", text, start, options.etc)
return nil, start -- in case the error method doesn't abort, return something sensible
end
local i = skip_whitespace(text, start + 1) -- +1 to skip the '['
local VALUE = self.strictTypes and self:newArray({}) or {}
if text:sub(i, i) == "]" then
local VALUE = self.strictTypes and self:newArray { } or { }
if text:sub(i,i) == ']' then
return VALUE, i + 1
end
@ -465,10 +450,10 @@ local function grok_array(self, text, start, options)
-- Expect now either ']' to end things, or a ',' to allow us to continue.
--
local c = text:sub(i,i)
if c == "]" then
if c == ']' then
return VALUE, i + 1
end
if text:sub(i, i) ~= "," then
if text:sub(i, i) ~= ',' then
self:onDecodeError("expected comma or ']'", text, i, options.etc)
return nil, i -- in case the error method doesn't abort, return something sensible
end
@ -478,6 +463,7 @@ local function grok_array(self, text, start, options)
return nil, i -- in case the error method doesn't abort, return something sensible
end
grok_one = function(self, text, start, options)
-- Skip any whitespace
start = skip_whitespace(text, start)
@ -489,18 +475,25 @@ grok_one = function(self, text, start, options)
if text:find('^"', start) then
return grok_string(self, text, start, options.etc)
elseif text:find("^[-0123456789 ]", start) then
elseif text:find('^[-0123456789 ]', start) then
return grok_number(self, text, start, options)
elseif text:find("^%{", start) then
elseif text:find('^%{', start) then
return grok_object(self, text, start, options)
elseif text:find("^%[", start) then
elseif text:find('^%[', start) then
return grok_array(self, text, start, options)
elseif text:find("^true", start) then
elseif text:find('^true', start) then
return true, start + 4
elseif text:find("^false", start) then
elseif text:find('^false', start) then
return false, start + 5
elseif text:find("^null", start) then
elseif text:find('^null', start) then
return nil, start + 4
else
self:onDecodeError("can't parse JSON", text, start, options.etc)
return nil, 1 -- in case the error method doesn't abort, return something sensible
@ -511,7 +504,7 @@ function OBJDEF:decode(text, etc, options)
--
-- If the user didn't pass in a table of decode options, make an empty one.
--
if type(options) ~= "table" then
if type(options) ~= 'table' then
options = {}
end
@ -523,12 +516,12 @@ function OBJDEF:decode(text, etc, options)
options.etc = etc
end
if text:match("^%s*$") then
if text:match('^%s*$') then
-- an empty string is nothing, but not an error
return nil
end
if text:match("^%s*<") then
if text:match('^%s*<') then
-- Can't be JSON... we'll assume it's HTML
local error_message = "HTML passed to JSON:decode()"
self:onDecodeOfHTMLError(error_message, text, nil, options.etc)
@ -565,6 +558,7 @@ function OBJDEF:decode(text, etc, options)
local success, value, next_i = pcall(grok_one, self, text, 1, options)
if success then
local error_message = nil
if next_i ~= #text + 1 then
-- something's left over after we parsed the first thing.... whitespace is allowed.
@ -576,7 +570,9 @@ function OBJDEF:decode(text, etc, options)
end
end
return value, error_message
else
-- If JSON:onDecodeError() didn't abort out of the pcall, we'll have received
-- the error message here as "value", so pass it along as an assert.
local error_message = value
@ -588,6 +584,7 @@ function OBJDEF:decode(text, etc, options)
-- ...and if we're still here (because the assert didn't throw an error),
-- return a nil and throw the error message on as a second arg
return nil, error_message
end
end
@ -610,3 +607,5 @@ function OBJDEF:new(args)
end
return OBJDEF:new()

View File

@ -66,7 +66,7 @@ function M:get_entries_from_lua_json(t)
line_number = raw_value.line_number,
key_start = raw_value.key_start,
value_start = raw_value.value_start,
},
}
}
table.insert(keys, entry)
@ -129,6 +129,7 @@ function M:parse_lsp_value(result)
end
end
---@class Symbol
---@field name string
---@field kind number 2 = Object, 16 = Number, 15 = String, 18 = Array, 13 = Null, 17 = Boolean
@ -166,7 +167,7 @@ function M:get_entries_from_lsp_symbols(symbols)
-- `"my_key": "my_value"`
-- Since we get the end of the key, we can just add 4 to get the start of the value
value_start = symbol.selectionRange["end"].character + 3,
},
}
}
keys[#keys + 1] = entry

View File

@ -86,7 +86,7 @@ function M:create_display_preview(value, conceal, render_objects)
if conceal then
return value, "string"
else
return '"' .. value .. '"', "string"
return "\"" .. value .. "\"", "string"
end
elseif t == "boolean" then
return value and "true" or "false", "boolean"
@ -198,7 +198,7 @@ function M:extract_key_description(text)
{
key = text,
type = "key",
},
}
}
end
@ -208,9 +208,7 @@ end
---@param name string
---@return boolean
function M:is_module_available(name)
return pcall(function()
require(name)
end) == true
return pcall(function() require(name) end) == true
end
return M

View File

@ -26,19 +26,19 @@
---@field null string - Highlight group for null values, Default: "@constant.builtin.json"
---@field other string - Highlight group for other types, Default: "@label.json"
local parsers = require("jsonfly.parsers")
local utils = require("jsonfly.utils")
local cache = require("jsonfly.cache")
local insert = require("jsonfly.insert")
local parsers = require"jsonfly.parsers"
local utils = require"jsonfly.utils"
local cache = require"jsonfly.cache"
local insert = require"jsonfly.insert"
local json = require("jsonfly.json")
local finders = require("telescope.finders")
local pickers = require("telescope.pickers")
local json = require"jsonfly.json"
local finders = require "telescope.finders"
local pickers = require "telescope.pickers"
local conf = require("telescope.config").values
local make_entry = require("telescope.make_entry")
local entry_display = require("telescope.pickers.entry_display")
local make_entry = require "telescope.make_entry"
local entry_display = require "telescope.pickers.entry_display"
local action_state = require("telescope.actions.state")
local action_state = require "telescope.actions.state"
---@type Options
local DEFAULT_CONFIG = {
@ -69,9 +69,9 @@ local DEFAULT_CONFIG = {
---@param prompt_bufnr number
function(path, prompt_bufnr)
vim.fn.setreg("+", path)
end,
},
},
end
}
}
}
local global_config = {}
@ -82,14 +82,14 @@ local function show_picker(entries, buffer, xopts)
local config = vim.tbl_deep_extend("force", global_config, xopts or {})
local filename = vim.api.nvim_buf_get_name(buffer)
local displayer = entry_display.create({
local displayer = entry_display.create {
separator = " ",
items = {
{ width = 1 },
global_config.key_exact_length and { width = global_config.key_max_length } or { remaining = true },
{ remaining = true },
},
})
}
---@type boolean
local conceal
@ -99,18 +99,21 @@ local function show_picker(entries, buffer, xopts)
conceal = global_config.conceal == true
end
pickers
.new(config, {
pickers.new(config, {
prompt_title = global_config.prompt_title,
attach_mappings = function(_, map)
map(global_config.commands.add_key[1], global_config.commands.add_key[2], function(prompt_bufnr)
map(
global_config.commands.add_key[1],
global_config.commands.add_key[2],
function(prompt_bufnr)
local current_picker = action_state.get_current_picker(prompt_bufnr)
local input = current_picker:_get_prompt()
local key_descriptor = utils:extract_key_description(input)
insert:insert_new_key(entries, key_descriptor, buffer)
end)
end
)
if global_config.commands.copy_jsonpath and utils:is_module_available("jsonpath") then
map(
@ -122,16 +125,13 @@ local function show_picker(entries, buffer, xopts)
local current_picker = action_state.get_current_picker(prompt_bufnr)
local selection = current_picker:get_selection()
local path = jsonpath.get(
vim.treesitter.get_node({
local path = jsonpath.get(vim.treesitter.get_node({
bufnr = buffer,
pos = {
selection.lnum - 1,
selection.index,
},
}),
buffer
)
}
}), buffer)
if path then
global_config.commands.copy_jsonpath[3](path, prompt_bufnr)
@ -142,7 +142,7 @@ local function show_picker(entries, buffer, xopts)
return true
end,
finder = finders.new_table({
finder = finders.new_table {
results = entries,
---@param entry Entry
entry_maker = function(entry)
@ -153,16 +153,11 @@ local function show_picker(entries, buffer, xopts)
value = buffer,
ordinal = entry.key,
display = function(_)
local preview, hl_group_key = utils:create_display_preview(
entry.value,
conceal,
global_config.show_nested_child_preview
)
local preview, hl_group_key = utils:create_display_preview(entry.value, conceal, global_config.show_nested_child_preview)
local key = global_config.subkeys_display == "normal" and entry.key
or utils:replace_previous_keys(entry.key, " ")
local key = global_config.subkeys_display == "normal" and entry.key or utils:replace_previous_keys(entry.key, " ")
return displayer({
return displayer {
{ depth, "TelescopeResultsNumber"},
{
utils:truncate_overflow(
@ -180,26 +175,26 @@ local function show_picker(entries, buffer, xopts)
),
global_config.highlights[hl_group_key] or "TelescopeResultsString",
},
})
}
end,
bufnr = buffer,
filename = filename,
lnum = entry.position.line_number,
col = global_config.jump_behavior == "key_start" and entry.position.key_start
col = global_config.jump_behavior == "key_start"
and entry.position.key_start
-- Use length ("#" operator) as vim jumps to the bytes, not characters
or entry.position.value_start,
or entry.position.value_start
}, config)
end,
}),
},
previewer = conf.grep_previewer(config),
sorter = conf.generic_sorter(config),
sorting_strategy = "ascending",
})
:find()
}):find()
end
return require("telescope").register_extension({
return require("telescope").register_extension {
setup = function(extension_config)
global_config = vim.tbl_deep_extend("force", DEFAULT_CONFIG, extension_config or {})
end,
@ -236,50 +231,30 @@ return require("telescope").register_extension({
if global_config.backend == "lsp" then
local params = vim.lsp.util.make_position_params(xopts.winnr)
-- Check i
local clients = vim.lsp.get_clients()
local any_support = false
for _, client in ipairs(clients) do
if client.supports_method("textDocument/documentSymbol") then
any_support = true
break
end
end
if any_support then
vim.lsp.buf_request_all(current_buf, "textDocument/documentSymbol", params, function(results)
if results == nil or vim.tbl_isempty(results) then
vim.lsp.buf_request_all(
current_buf,
"textDocument/documentSymbol",
params,
function(response)
if response == nil or #response == 0 then
run_lua_parser()
return
end
local combined_result = {}
local result = response[1].result
for _, res in pairs(results) do
if res.result then
vim.list_extend(combined_result, res.result)
end
end
if vim.tbl_isempty(combined_result) then
run_lua_parser()
return
end
local entries = parsers:get_entries_from_lsp_symbols(combined_result)
local entries = parsers:get_entries_from_lsp_symbols(result)
if allow_cache then
cache:cache_buffer(current_buf, entries)
end
show_picker(entries, current_buf, xopts)
end)
end
end
)
else
run_lua_parser()
end,
},
})
end
end
}
}