mirror of
https://github.com/Myzel394/jsonfly.nvim.git
synced 2025-06-18 04:05:26 +02:00
fix: Fix fallback behavior; apply stylua
This commit is contained in:
parent
cbff2a5659
commit
8fe79c2783
@ -1,47 +1,42 @@
|
||||
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;
|
||||
end
|
||||
if _listening_buffers[buffer] then
|
||||
return
|
||||
end
|
||||
|
||||
_listening_buffers[buffer] = true;
|
||||
_listening_buffers[buffer] = true
|
||||
|
||||
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;
|
||||
end,
|
||||
}
|
||||
);
|
||||
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
|
||||
end,
|
||||
})
|
||||
end
|
||||
|
||||
return M;
|
||||
|
||||
return M
|
||||
|
@ -1,42 +1,42 @@
|
||||
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)
|
||||
local sliced = {}
|
||||
local sliced = {}
|
||||
|
||||
for i = first or 1, last or #tbl, step or 1 do
|
||||
sliced[#sliced+1] = tbl[i]
|
||||
end
|
||||
for i = first or 1, last or #tbl, step or 1 do
|
||||
sliced[#sliced + 1] = tbl[i]
|
||||
end
|
||||
|
||||
return sliced
|
||||
return sliced
|
||||
end
|
||||
|
||||
---@param line string
|
||||
---@param also_match_end_bracket boolean - Whether to also match only a closing bracket
|
||||
---@return boolean - Whether the line contains an empty JSON object
|
||||
local function line_contains_empty_json(line, also_match_end_bracket)
|
||||
-- Starting and ending on same line
|
||||
return string.match(line, ".*[%{%[]%s*[%}%]]%s*,?*%s*")
|
||||
-- Opening bracket on line
|
||||
or string.match(line, ".*[%{%[]%s*")
|
||||
-- Closing bracket on line
|
||||
or (also_match_end_bracket and string.match(line, ".*.*[%}%]]%s*,?%s*"))
|
||||
-- Starting and ending on same line
|
||||
return string.match(line, ".*[%{%[]%s*[%}%]]%s*,?*%s*")
|
||||
-- Opening bracket on line
|
||||
or string.match(line, ".*[%{%[]%s*")
|
||||
-- Closing bracket on line
|
||||
or (also_match_end_bracket and string.match(line, ".*.*[%}%]]%s*,?%s*"))
|
||||
end
|
||||
|
||||
---@param entry Entry
|
||||
---@param key string
|
||||
---@param index number
|
||||
local function check_key_equal(entry, key, index)
|
||||
local splitted = utils:split_by_char(entry.key, ".")
|
||||
local splitted = utils:split_by_char(entry.key, ".")
|
||||
|
||||
return splitted[index] == key
|
||||
return splitted[index] == key
|
||||
end
|
||||
|
||||
---Find the entry in `entries` with the most matching keys at the beginning based on the `keys`.
|
||||
@ -45,214 +45,196 @@ end
|
||||
---@param keys string[]
|
||||
---@return number|nil
|
||||
local function find_best_fitting_entry(entries, keys)
|
||||
local entry_index
|
||||
local current_indexes = {1, #entries}
|
||||
local entry_index
|
||||
local current_indexes = { 1, #entries }
|
||||
|
||||
for kk=1, #keys do
|
||||
local key = keys[kk]
|
||||
for kk = 1, #keys do
|
||||
local key = keys[kk]
|
||||
|
||||
local start_index = current_indexes[1]
|
||||
local end_index = current_indexes[2]
|
||||
local start_index = current_indexes[1]
|
||||
local end_index = current_indexes[2]
|
||||
|
||||
current_indexes = {nil, nil}
|
||||
current_indexes = { nil, nil }
|
||||
|
||||
for ii=start_index, end_index do
|
||||
if check_key_equal(entries[ii], key, kk) then
|
||||
if current_indexes[1] == nil then
|
||||
current_indexes[1] = ii
|
||||
end
|
||||
for ii = start_index, end_index do
|
||||
if check_key_equal(entries[ii], key, kk) then
|
||||
if current_indexes[1] == nil then
|
||||
current_indexes[1] = ii
|
||||
end
|
||||
|
||||
current_indexes[2] = ii
|
||||
end
|
||||
end
|
||||
current_indexes[2] = ii
|
||||
end
|
||||
end
|
||||
|
||||
if current_indexes[1] == nil then
|
||||
-- No entries found
|
||||
break
|
||||
else
|
||||
entry_index = current_indexes[1]
|
||||
end
|
||||
end
|
||||
if current_indexes[1] == nil then
|
||||
-- No entries found
|
||||
break
|
||||
else
|
||||
entry_index = current_indexes[1]
|
||||
end
|
||||
end
|
||||
|
||||
return entry_index
|
||||
return entry_index
|
||||
end
|
||||
|
||||
---@param keys KeyDescription
|
||||
---@param index number - Index of the key
|
||||
---@param lines string[] - Table to write the lines to
|
||||
local function write_keys(keys, index, lines)
|
||||
local key = keys[index]
|
||||
local key = keys[index]
|
||||
|
||||
if index == #keys then
|
||||
lines[#lines + 1] = "\"" .. key.key .. "\": \"" .. CURSOR_SEARCH_HELPER .. "\""
|
||||
return
|
||||
end
|
||||
if index == #keys then
|
||||
lines[#lines + 1] = '"' .. key.key .. '": "' .. CURSOR_SEARCH_HELPER .. '"'
|
||||
return
|
||||
end
|
||||
|
||||
if key.type == "object_wrapper" then
|
||||
local previous_line = lines[#lines] or ""
|
||||
if line_contains_empty_json(previous_line, true) or #lines == 0 then
|
||||
lines[#lines + 1] = "{"
|
||||
else
|
||||
lines[#lines] = previous_line .. " {"
|
||||
end
|
||||
if key.type == "object_wrapper" then
|
||||
local previous_line = lines[#lines] or ""
|
||||
if line_contains_empty_json(previous_line, true) or #lines == 0 then
|
||||
lines[#lines + 1] = "{"
|
||||
else
|
||||
lines[#lines] = previous_line .. " {"
|
||||
end
|
||||
|
||||
write_keys(keys, index + 1, lines)
|
||||
write_keys(keys, index + 1, lines)
|
||||
|
||||
lines[#lines + 1] = "}"
|
||||
elseif key.type == "key" then
|
||||
lines[#lines + 1] = "\"" .. key.key .. "\":"
|
||||
lines[#lines + 1] = "}"
|
||||
elseif key.type == "key" then
|
||||
lines[#lines + 1] = '"' .. key.key .. '":'
|
||||
|
||||
write_keys(keys, index + 1, lines)
|
||||
elseif key.type == "array_wrapper" then
|
||||
local previous_line = lines[#lines] or ""
|
||||
-- Starting and ending on same line
|
||||
if line_contains_empty_json(previous_line, true) or #lines == 0 then
|
||||
lines[#lines + 1] = "["
|
||||
else
|
||||
lines[#lines] = previous_line .. " ["
|
||||
end
|
||||
write_keys(keys, index + 1, lines)
|
||||
write_keys(keys, index + 1, lines)
|
||||
elseif key.type == "array_wrapper" then
|
||||
local previous_line = lines[#lines] or ""
|
||||
-- Starting and ending on same line
|
||||
if line_contains_empty_json(previous_line, true) or #lines == 0 then
|
||||
lines[#lines + 1] = "["
|
||||
else
|
||||
lines[#lines] = previous_line .. " ["
|
||||
end
|
||||
write_keys(keys, index + 1, lines)
|
||||
|
||||
lines[#lines + 1] = "]"
|
||||
elseif key.type == "array_index" then
|
||||
local amount = tonumber(key.key)
|
||||
-- Write previous empty array objects
|
||||
for _=1, amount do
|
||||
lines[#lines + 1] = "{},"
|
||||
end
|
||||
lines[#lines + 1] = "]"
|
||||
elseif key.type == "array_index" then
|
||||
local amount = tonumber(key.key)
|
||||
-- Write previous empty array objects
|
||||
for _ = 1, amount do
|
||||
lines[#lines + 1] = "{},"
|
||||
end
|
||||
|
||||
write_keys(keys, index + 1, lines)
|
||||
end
|
||||
write_keys(keys, index + 1, lines)
|
||||
end
|
||||
end
|
||||
|
||||
---@param buffer number
|
||||
---@param insertion_line number
|
||||
local function add_comma(buffer, insertion_line)
|
||||
local BUFFER_SIZE = 5
|
||||
local BUFFER_SIZE = 5
|
||||
|
||||
-- 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
|
||||
)
|
||||
-- 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)
|
||||
|
||||
if #previous_lines == 0 then
|
||||
return
|
||||
end
|
||||
if #previous_lines == 0 then
|
||||
return
|
||||
end
|
||||
|
||||
for jj=#previous_lines, 1, -1 do
|
||||
local line = previous_lines[jj]
|
||||
for jj = #previous_lines, 1, -1 do
|
||||
local line = previous_lines[jj]
|
||||
|
||||
for char_index=#line, 1, -1 do
|
||||
local char = line:sub(char_index, char_index)
|
||||
for char_index = #line, 1, -1 do
|
||||
local char = line:sub(char_index, char_index)
|
||||
|
||||
if char ~= " " and char ~= "\t" and char ~= "\n" and char ~= "\r" then
|
||||
if char == "," or char == "{" or char == "[" then
|
||||
return
|
||||
end
|
||||
if char ~= " " and char ~= "\t" and char ~= "\n" and char ~= "\r" then
|
||||
if char == "," or char == "{" or char == "[" then
|
||||
return
|
||||
end
|
||||
|
||||
-- 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,
|
||||
{","}
|
||||
)
|
||||
return
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
-- 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, { "," })
|
||||
return
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
---@return number - The new line number to be used, as the buffer has been modified
|
||||
local function expand_empty_object(buffer, line_number)
|
||||
local line = vim.api.nvim_buf_get_lines(buffer, line_number, line_number + 1, false)[1] or ""
|
||||
local line = vim.api.nvim_buf_get_lines(buffer, line_number, line_number + 1, false)[1] or ""
|
||||
|
||||
if line_contains_empty_json(line, false) then
|
||||
local position_closing_bracket = string.find(line, "[%}%]]")
|
||||
local remaining_line = string.sub(line, position_closing_bracket + 1)
|
||||
if line_contains_empty_json(line, false) then
|
||||
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,
|
||||
{
|
||||
"{",
|
||||
"}" .. remaining_line
|
||||
}
|
||||
)
|
||||
vim.api.nvim_buf_set_lines(buffer, line_number, line_number + 1, false, {
|
||||
"{",
|
||||
"}" .. remaining_line,
|
||||
})
|
||||
|
||||
return line_number + 1
|
||||
end
|
||||
return line_number + 1
|
||||
end
|
||||
|
||||
return line_number
|
||||
return line_number
|
||||
end
|
||||
|
||||
---@param keys KeyDescription[]
|
||||
---@param input_key_depth number
|
||||
local function get_key_descriptor_index(keys, input_key_depth)
|
||||
local depth = 0
|
||||
local index = 0
|
||||
local depth = 0
|
||||
local index = 0
|
||||
|
||||
for ii=1, #keys do
|
||||
if keys[ii].type == "key" or keys[ii].type == "array_index" then
|
||||
depth = depth + 1
|
||||
end
|
||||
for ii = 1, #keys do
|
||||
if keys[ii].type == "key" or keys[ii].type == "array_index" then
|
||||
depth = depth + 1
|
||||
end
|
||||
|
||||
if depth >= input_key_depth then
|
||||
index = ii
|
||||
break
|
||||
end
|
||||
end
|
||||
if depth >= input_key_depth then
|
||||
index = ii
|
||||
break
|
||||
end
|
||||
end
|
||||
|
||||
return index
|
||||
return index
|
||||
end
|
||||
|
||||
---@param entries Entry[]
|
||||
---@param keys string[]
|
||||
---@return integer|nil - The index of the entry
|
||||
local function get_entry_by_keys(entries, keys)
|
||||
for ii=1, #entries do
|
||||
local entry = entries[ii]
|
||||
local splitted = utils:split_by_char(entry.key, ".")
|
||||
for ii = 1, #entries do
|
||||
local entry = entries[ii]
|
||||
local splitted = utils:split_by_char(entry.key, ".")
|
||||
|
||||
local found = true
|
||||
local found = true
|
||||
|
||||
for jj=1, #keys do
|
||||
if keys[jj] ~= splitted[jj] then
|
||||
found = false
|
||||
break
|
||||
end
|
||||
end
|
||||
for jj = 1, #keys do
|
||||
if keys[jj] ~= splitted[jj] then
|
||||
found = false
|
||||
break
|
||||
end
|
||||
end
|
||||
|
||||
if found then
|
||||
return ii
|
||||
end
|
||||
end
|
||||
if found then
|
||||
return ii
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
---@param keys KeyDescription[]
|
||||
---@return string[]
|
||||
local function flatten_key_description(keys)
|
||||
local flat_keys = {}
|
||||
local flat_keys = {}
|
||||
|
||||
for ii=1, #keys do
|
||||
if keys[ii].type == "key" then
|
||||
flat_keys[#flat_keys + 1] = keys[ii].key
|
||||
elseif keys[ii].type == "array_index" then
|
||||
flat_keys[#flat_keys + 1] = tostring(keys[ii].key)
|
||||
end
|
||||
end
|
||||
for ii = 1, #keys do
|
||||
if keys[ii].type == "key" then
|
||||
flat_keys[#flat_keys + 1] = keys[ii].key
|
||||
elseif keys[ii].type == "array_index" then
|
||||
flat_keys[#flat_keys + 1] = tostring(keys[ii].key)
|
||||
end
|
||||
end
|
||||
|
||||
return flat_keys
|
||||
return flat_keys
|
||||
end
|
||||
|
||||
---Subtracts indexes if there are other indexes before already
|
||||
@ -262,43 +244,43 @@ end
|
||||
---@param starting_keys KeyDescription[]
|
||||
---@param key KeyDescription - Th key to be inserted; must be of type `array_index`; will be modified in-place
|
||||
local function normalize_array_indexes(entries, starting_keys, key)
|
||||
local starting_keys_flat = flatten_key_description(starting_keys)
|
||||
local starting_key_index = get_entry_by_keys(entries, starting_keys_flat)
|
||||
local entry = entries[starting_key_index]
|
||||
local starting_keys_flat = flatten_key_description(starting_keys)
|
||||
local starting_key_index = get_entry_by_keys(entries, starting_keys_flat)
|
||||
local entry = entries[starting_key_index]
|
||||
|
||||
key.key = key.key - #entry.value
|
||||
key.key = key.key - #entry.value
|
||||
end
|
||||
|
||||
---@param entries Entry[] - Entries, they must be children of a top level array
|
||||
---Counts how many top level children an array has
|
||||
local function count_array_children(entries)
|
||||
for ii=1, #entries do
|
||||
if string.match(entries[ii].key, "^%d+$") then
|
||||
return ii
|
||||
end
|
||||
end
|
||||
for ii = 1, #entries do
|
||||
if string.match(entries[ii].key, "^%d+$") then
|
||||
return ii
|
||||
end
|
||||
end
|
||||
|
||||
return #entries
|
||||
return #entries
|
||||
end
|
||||
|
||||
---Jump to the cursor helper and remove it
|
||||
---@param buffer number
|
||||
function M:jump_to_cursor_helper(buffer)
|
||||
vim.fn.search(CURSOR_SEARCH_HELPER)
|
||||
vim.fn.search(CURSOR_SEARCH_HELPER)
|
||||
|
||||
-- Remove cursor helper
|
||||
local position = vim.api.nvim_win_get_cursor(0)
|
||||
vim.api.nvim_buf_set_text(
|
||||
buffer,
|
||||
position[1] - 1,
|
||||
position[2],
|
||||
position[1] - 1,
|
||||
position[2] + #CURSOR_SEARCH_HELPER,
|
||||
{""}
|
||||
)
|
||||
-- Remove cursor helper
|
||||
local position = vim.api.nvim_win_get_cursor(0)
|
||||
vim.api.nvim_buf_set_text(
|
||||
buffer,
|
||||
position[1] - 1,
|
||||
position[2],
|
||||
position[1] - 1,
|
||||
position[2] + #CURSOR_SEARCH_HELPER,
|
||||
{ "" }
|
||||
)
|
||||
|
||||
-- -- Go into insert mode
|
||||
vim.cmd [[execute "normal a"]]
|
||||
-- -- Go into insert mode
|
||||
vim.cmd([[execute "normal a"]])
|
||||
end
|
||||
|
||||
-- TODO: Handle top level empty arrays
|
||||
@ -306,107 +288,107 @@ end
|
||||
---@param keys KeyDescription[]
|
||||
---@param buffer number
|
||||
function M:insert_new_key(entries, keys, buffer)
|
||||
-- Close current buffer
|
||||
vim.cmd [[quit!]]
|
||||
-- Close current buffer
|
||||
vim.cmd([[quit!]])
|
||||
|
||||
local input_key = flatten_key_description(keys)
|
||||
---@type boolean
|
||||
local should_add_comma = true
|
||||
local input_key = flatten_key_description(keys)
|
||||
---@type boolean
|
||||
local should_add_comma = true
|
||||
|
||||
---@type KeyDescription[]
|
||||
local remaining_keys
|
||||
---@type Entry
|
||||
local entry
|
||||
---@type KeyDescription[]
|
||||
local remaining_keys
|
||||
---@type Entry
|
||||
local entry
|
||||
|
||||
if #entries == 0 then
|
||||
remaining_keys = table.slice(keys, 2, #keys)
|
||||
if #entries == 0 then
|
||||
remaining_keys = table.slice(keys, 2, #keys)
|
||||
|
||||
entry = {
|
||||
key = "",
|
||||
position = {
|
||||
key_start = 1,
|
||||
line_number = 1,
|
||||
value_start = 1
|
||||
}
|
||||
}
|
||||
should_add_comma = false
|
||||
else
|
||||
local entry_index = find_best_fitting_entry(entries, input_key) or 0
|
||||
entry = entries[entry_index]
|
||||
entry = {
|
||||
key = "",
|
||||
position = {
|
||||
key_start = 1,
|
||||
line_number = 1,
|
||||
value_start = 1,
|
||||
},
|
||||
}
|
||||
should_add_comma = false
|
||||
else
|
||||
local entry_index = find_best_fitting_entry(entries, input_key) or 0
|
||||
entry = entries[entry_index]
|
||||
|
||||
---@type integer
|
||||
local existing_keys_index
|
||||
---@type integer
|
||||
local existing_keys_index
|
||||
|
||||
if entry == nil then
|
||||
-- Insert as root
|
||||
existing_keys_index = 0
|
||||
remaining_keys = table.slice(keys, 2, #keys)
|
||||
if entry == nil then
|
||||
-- Insert as root
|
||||
existing_keys_index = 0
|
||||
remaining_keys = table.slice(keys, 2, #keys)
|
||||
|
||||
-- Top level array
|
||||
if entries[1].key == "0" then
|
||||
-- Normalize array indexes
|
||||
remaining_keys[1].key = remaining_keys[1].key - count_array_children(entries)
|
||||
end
|
||||
-- Top level array
|
||||
if entries[1].key == "0" then
|
||||
-- Normalize array indexes
|
||||
remaining_keys[1].key = remaining_keys[1].key - count_array_children(entries)
|
||||
end
|
||||
|
||||
entry = {
|
||||
key = "",
|
||||
position = {
|
||||
key_start = 1,
|
||||
line_number = 1,
|
||||
value_start = 1
|
||||
}
|
||||
}
|
||||
else
|
||||
local existing_input_keys_depth = #utils:split_by_char(entry.key, ".") + 1
|
||||
existing_keys_index = get_key_descriptor_index(keys, existing_input_keys_depth)
|
||||
remaining_keys = table.slice(keys, existing_keys_index, #keys)
|
||||
entry = {
|
||||
key = "",
|
||||
position = {
|
||||
key_start = 1,
|
||||
line_number = 1,
|
||||
value_start = 1,
|
||||
},
|
||||
}
|
||||
else
|
||||
local existing_input_keys_depth = #utils:split_by_char(entry.key, ".") + 1
|
||||
existing_keys_index = get_key_descriptor_index(keys, existing_input_keys_depth)
|
||||
remaining_keys = table.slice(keys, existing_keys_index, #keys)
|
||||
|
||||
if remaining_keys[1].type == "array_index" then
|
||||
local starting_keys = table.slice(keys, 1, existing_keys_index - 1)
|
||||
normalize_array_indexes(entries, starting_keys, remaining_keys[1])
|
||||
end
|
||||
end
|
||||
end
|
||||
if remaining_keys[1].type == "array_index" then
|
||||
local starting_keys = table.slice(keys, 1, existing_keys_index - 1)
|
||||
normalize_array_indexes(entries, starting_keys, remaining_keys[1])
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local _writes = {}
|
||||
write_keys(remaining_keys, 1, _writes)
|
||||
local writes = {}
|
||||
local _writes = {}
|
||||
write_keys(remaining_keys, 1, _writes)
|
||||
local writes = {}
|
||||
|
||||
for ii=1, #_writes do
|
||||
if _writes[ii] == true then
|
||||
-- Unwrap table
|
||||
writes[#writes] = writes[#writes][1]
|
||||
else
|
||||
writes[#writes + 1] = _writes[ii]
|
||||
end
|
||||
end
|
||||
for ii = 1, #_writes do
|
||||
if _writes[ii] == true then
|
||||
-- Unwrap table
|
||||
writes[#writes] = writes[#writes][1]
|
||||
else
|
||||
writes[#writes + 1] = _writes[ii]
|
||||
end
|
||||
end
|
||||
|
||||
-- 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 %"]]
|
||||
-- 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 %"]])
|
||||
|
||||
local changes = #writes
|
||||
local start_line = vim.api.nvim_win_get_cursor(0)[1] - 1
|
||||
local changes = #writes
|
||||
local start_line = vim.api.nvim_win_get_cursor(0)[1] - 1
|
||||
|
||||
-- Add comma to previous JSON entry
|
||||
if should_add_comma then
|
||||
add_comma(buffer, start_line)
|
||||
end
|
||||
local new_start_line = expand_empty_object(buffer, start_line)
|
||||
-- Add comma to previous JSON entry
|
||||
if should_add_comma then
|
||||
add_comma(buffer, start_line)
|
||||
end
|
||||
local new_start_line = expand_empty_object(buffer, start_line)
|
||||
|
||||
if new_start_line ~= start_line then
|
||||
changes = changes + math.abs(new_start_line - start_line)
|
||||
start_line = new_start_line
|
||||
end
|
||||
if new_start_line ~= start_line then
|
||||
changes = changes + math.abs(new_start_line - start_line)
|
||||
start_line = new_start_line
|
||||
end
|
||||
|
||||
-- Insert new lines
|
||||
vim.api.nvim_buf_set_lines(buffer, start_line, start_line, false, writes)
|
||||
-- Insert new lines
|
||||
vim.api.nvim_buf_set_lines(buffer, start_line, start_line, false, writes)
|
||||
|
||||
-- Format lines
|
||||
vim.api.nvim_win_set_cursor(0, {start_line, 1})
|
||||
vim.cmd('execute "normal =' .. changes .. 'j"')
|
||||
-- Format lines
|
||||
vim.api.nvim_win_set_cursor(0, { start_line, 1 })
|
||||
vim.cmd('execute "normal =' .. changes .. 'j"')
|
||||
|
||||
M:jump_to_cursor_helper(buffer)
|
||||
M:jump_to_cursor_helper(buffer)
|
||||
end
|
||||
|
||||
return M;
|
||||
return M
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -15,121 +15,120 @@
|
||||
---@field key_start number
|
||||
|
||||
local PRIMITIVE_TYPES = {
|
||||
string = true,
|
||||
number = true,
|
||||
boolean = true,
|
||||
string = true,
|
||||
number = true,
|
||||
boolean = true,
|
||||
}
|
||||
local CONTAINS_CHILDREN_TYPES = {
|
||||
[2] = true, -- Module / Javascript Object
|
||||
[8] = true, -- Field
|
||||
[18] = true, -- Array
|
||||
[19] = true, -- Object
|
||||
[2] = true, -- Module / Javascript Object
|
||||
[8] = true, -- Field
|
||||
[18] = true, -- Array
|
||||
[19] = true, -- Object
|
||||
}
|
||||
|
||||
local M = {}
|
||||
|
||||
---@param entry JSONEntry
|
||||
local function get_contents_from_json_value(entry)
|
||||
local value = entry.value
|
||||
local value = entry.value
|
||||
|
||||
if type(value) == "table" then
|
||||
-- Recursively get the contents of the table
|
||||
local contents = {}
|
||||
if type(value) == "table" then
|
||||
-- Recursively get the contents of the table
|
||||
local contents = {}
|
||||
|
||||
for k, v in pairs(value) do
|
||||
contents[k] = get_contents_from_json_value(v)
|
||||
end
|
||||
for k, v in pairs(value) do
|
||||
contents[k] = get_contents_from_json_value(v)
|
||||
end
|
||||
|
||||
return contents
|
||||
else
|
||||
return entry.value
|
||||
end
|
||||
return contents
|
||||
else
|
||||
return entry.value
|
||||
end
|
||||
end
|
||||
|
||||
---@param t table|nil|string|number|boolean
|
||||
---@return Entry[]
|
||||
function M:get_entries_from_lua_json(t)
|
||||
if PRIMITIVE_TYPES[type(t)] or t == nil then
|
||||
return {}
|
||||
end
|
||||
if PRIMITIVE_TYPES[type(t)] or t == nil then
|
||||
return {}
|
||||
end
|
||||
|
||||
local keys = {}
|
||||
local keys = {}
|
||||
|
||||
for k, _raw_value in pairs(t) do
|
||||
---@type JSONEntry
|
||||
local raw_value = _raw_value
|
||||
---@type Entry
|
||||
local entry = {
|
||||
key = tostring(k),
|
||||
value = get_contents_from_json_value(raw_value),
|
||||
position = {
|
||||
line_number = raw_value.line_number,
|
||||
key_start = raw_value.key_start,
|
||||
value_start = raw_value.value_start,
|
||||
}
|
||||
}
|
||||
table.insert(keys, entry)
|
||||
for k, _raw_value in pairs(t) do
|
||||
---@type JSONEntry
|
||||
local raw_value = _raw_value
|
||||
---@type Entry
|
||||
local entry = {
|
||||
key = tostring(k),
|
||||
value = get_contents_from_json_value(raw_value),
|
||||
position = {
|
||||
line_number = raw_value.line_number,
|
||||
key_start = raw_value.key_start,
|
||||
value_start = raw_value.value_start,
|
||||
},
|
||||
}
|
||||
table.insert(keys, entry)
|
||||
|
||||
local v = raw_value.value
|
||||
local v = raw_value.value
|
||||
|
||||
if type(v) == "table" then
|
||||
local sub_keys = M:get_entries_from_lua_json(v)
|
||||
if type(v) == "table" then
|
||||
local sub_keys = M:get_entries_from_lua_json(v)
|
||||
|
||||
for index=1, #sub_keys do
|
||||
local sub_key = sub_keys[index]
|
||||
for index = 1, #sub_keys do
|
||||
local sub_key = sub_keys[index]
|
||||
|
||||
---@type Entry
|
||||
local entry = {
|
||||
key = k .. "." .. sub_key.key,
|
||||
value = sub_key.value,
|
||||
position = sub_key.position,
|
||||
}
|
||||
---@type Entry
|
||||
local entry = {
|
||||
key = k .. "." .. sub_key.key,
|
||||
value = sub_key.value,
|
||||
position = sub_key.position,
|
||||
}
|
||||
|
||||
keys[#keys + 1] = entry
|
||||
end
|
||||
end
|
||||
end
|
||||
keys[#keys + 1] = entry
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
return keys
|
||||
return keys
|
||||
end
|
||||
|
||||
---@param result Symbol
|
||||
---@return string|number|table|boolean|nil
|
||||
function M:parse_lsp_value(result)
|
||||
-- Object
|
||||
if CONTAINS_CHILDREN_TYPES[result.kind] then
|
||||
local value = {}
|
||||
-- Object
|
||||
if CONTAINS_CHILDREN_TYPES[result.kind] then
|
||||
local value = {}
|
||||
|
||||
for _, child in ipairs(result.children) do
|
||||
value[child.name] = M:parse_lsp_value(child)
|
||||
end
|
||||
for _, child in ipairs(result.children) do
|
||||
value[child.name] = M:parse_lsp_value(child)
|
||||
end
|
||||
|
||||
return value
|
||||
-- Integer
|
||||
elseif result.kind == 16 then
|
||||
return tonumber(result.detail)
|
||||
-- String
|
||||
elseif result.kind == 15 then
|
||||
return result.detail
|
||||
-- Array
|
||||
elseif result.kind == 18 then
|
||||
local value = {}
|
||||
return value
|
||||
-- Integer
|
||||
elseif result.kind == 16 then
|
||||
return tonumber(result.detail)
|
||||
-- String
|
||||
elseif result.kind == 15 then
|
||||
return result.detail
|
||||
-- Array
|
||||
elseif result.kind == 18 then
|
||||
local value = {}
|
||||
|
||||
for i, child in ipairs(result.children) do
|
||||
value[i] = M:parse_lsp_value(child)
|
||||
end
|
||||
for i, child in ipairs(result.children) do
|
||||
value[i] = M:parse_lsp_value(child)
|
||||
end
|
||||
|
||||
return value
|
||||
-- null
|
||||
elseif result.kind == 13 then
|
||||
return nil
|
||||
-- boolean
|
||||
elseif result.kind == 17 then
|
||||
return result.detail == "true"
|
||||
end
|
||||
return value
|
||||
-- null
|
||||
elseif result.kind == 13 then
|
||||
return nil
|
||||
-- boolean
|
||||
elseif result.kind == 17 then
|
||||
return result.detail == "true"
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
---@class Symbol
|
||||
---@field name string
|
||||
---@field kind number 2 = Object, 16 = Number, 15 = String, 18 = Array, 13 = Null, 17 = Boolean
|
||||
@ -149,45 +148,45 @@ end
|
||||
---@param symbols Symbol[]
|
||||
---@return Entry[]
|
||||
function M:get_entries_from_lsp_symbols(symbols)
|
||||
local keys = {}
|
||||
local keys = {}
|
||||
|
||||
for index=1, #symbols do
|
||||
local symbol = symbols[index]
|
||||
local key = symbol.name
|
||||
for index = 1, #symbols do
|
||||
local symbol = symbols[index]
|
||||
local key = symbol.name
|
||||
|
||||
---@type Entry
|
||||
local entry = {
|
||||
key = tostring(key),
|
||||
value = M:parse_lsp_value(symbol),
|
||||
position = {
|
||||
line_number = symbol.range.start.line + 1,
|
||||
key_start = symbol.range.start.character + 2,
|
||||
-- The LSP doesn't return the start of the value, so we'll just assume it's 3 characters after the key
|
||||
-- We assume a default JSON file like:
|
||||
-- `"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
|
||||
---@type Entry
|
||||
local entry = {
|
||||
key = tostring(key),
|
||||
value = M:parse_lsp_value(symbol),
|
||||
position = {
|
||||
line_number = symbol.range.start.line + 1,
|
||||
key_start = symbol.range.start.character + 2,
|
||||
-- The LSP doesn't return the start of the value, so we'll just assume it's 3 characters after the key
|
||||
-- We assume a default JSON file like:
|
||||
-- `"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
|
||||
|
||||
if CONTAINS_CHILDREN_TYPES[symbol.kind] then
|
||||
local sub_keys = M:get_entries_from_lsp_symbols(symbol.children)
|
||||
if CONTAINS_CHILDREN_TYPES[symbol.kind] then
|
||||
local sub_keys = M:get_entries_from_lsp_symbols(symbol.children)
|
||||
|
||||
for jindex=1, #sub_keys do
|
||||
---@type Entry
|
||||
local entry = {
|
||||
key = key .. "." .. sub_keys[jindex].key,
|
||||
value = sub_keys[jindex].value,
|
||||
position = sub_keys[jindex].position,
|
||||
}
|
||||
for jindex = 1, #sub_keys do
|
||||
---@type Entry
|
||||
local entry = {
|
||||
key = key .. "." .. sub_keys[jindex].key,
|
||||
value = sub_keys[jindex].value,
|
||||
position = sub_keys[jindex].position,
|
||||
}
|
||||
|
||||
keys[#keys + 1] = entry
|
||||
end
|
||||
end
|
||||
end
|
||||
keys[#keys + 1] = entry
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
return keys
|
||||
return keys
|
||||
end
|
||||
|
||||
return M
|
||||
|
@ -54,43 +54,43 @@
|
||||
local M = {}
|
||||
|
||||
function M:truncate_overflow(value, max_length, overflow_marker)
|
||||
if vim.fn.strdisplaywidth(value) > max_length then
|
||||
return value:sub(1, max_length - vim.fn.strdisplaywidth(overflow_marker)) .. overflow_marker
|
||||
end
|
||||
if vim.fn.strdisplaywidth(value) > max_length then
|
||||
return value:sub(1, max_length - vim.fn.strdisplaywidth(overflow_marker)) .. overflow_marker
|
||||
end
|
||||
|
||||
return value
|
||||
return value
|
||||
end
|
||||
|
||||
---@param value any
|
||||
---@param conceal boolean
|
||||
---@param render_objects boolean
|
||||
function M:create_display_preview(value, conceal, render_objects)
|
||||
local t = type(value)
|
||||
local t = type(value)
|
||||
|
||||
if t == "table" then
|
||||
if render_objects == false then
|
||||
return "", "other"
|
||||
end
|
||||
local preview_table = {}
|
||||
if t == "table" then
|
||||
if render_objects == false then
|
||||
return "", "other"
|
||||
end
|
||||
local preview_table = {}
|
||||
|
||||
for k, v in pairs(value) do
|
||||
preview_table[#preview_table + 1] = k .. ": " .. M:create_display_preview(v, conceal, render_objects)
|
||||
end
|
||||
for k, v in pairs(value) do
|
||||
preview_table[#preview_table + 1] = k .. ": " .. M:create_display_preview(v, conceal, render_objects)
|
||||
end
|
||||
|
||||
return "{ " .. table.concat(preview_table, ", ") .. " }", "other"
|
||||
elseif t == "nil" then
|
||||
return "null", "null"
|
||||
elseif t == "number" then
|
||||
return tostring(value), "number"
|
||||
elseif t == "string" then
|
||||
if conceal then
|
||||
return value, "string"
|
||||
else
|
||||
return "\"" .. value .. "\"", "string"
|
||||
end
|
||||
elseif t == "boolean" then
|
||||
return value and "true" or "false", "boolean"
|
||||
end
|
||||
return "{ " .. table.concat(preview_table, ", ") .. " }", "other"
|
||||
elseif t == "nil" then
|
||||
return "null", "null"
|
||||
elseif t == "number" then
|
||||
return tostring(value), "number"
|
||||
elseif t == "string" then
|
||||
if conceal then
|
||||
return value, "string"
|
||||
else
|
||||
return '"' .. value .. '"', "string"
|
||||
end
|
||||
elseif t == "boolean" then
|
||||
return value and "true" or "false", "boolean"
|
||||
end
|
||||
end
|
||||
|
||||
---@param key string
|
||||
@ -99,110 +99,110 @@ end
|
||||
---Replaces all previous keys with the replacement
|
||||
---Example: replace_previous_keys("a.b.c", "x") => "xxx.c"
|
||||
function M:replace_previous_keys(key, replacement)
|
||||
for i = #key, 1, -1 do
|
||||
if key:sub(i, i) == "." then
|
||||
local len = i - 1
|
||||
local before = replacement:rep(len)
|
||||
for i = #key, 1, -1 do
|
||||
if key:sub(i, i) == "." then
|
||||
local len = i - 1
|
||||
local before = replacement:rep(len)
|
||||
|
||||
return before .. "." .. key:sub(i + 1)
|
||||
end
|
||||
end
|
||||
return before .. "." .. key:sub(i + 1)
|
||||
end
|
||||
end
|
||||
|
||||
return key
|
||||
return key
|
||||
end
|
||||
|
||||
---@param text string
|
||||
---@param char string
|
||||
---@return string[]
|
||||
function M:split_by_char(text, char)
|
||||
local parts = {}
|
||||
local current = ""
|
||||
local parts = {}
|
||||
local current = ""
|
||||
|
||||
for i = 1, #text do
|
||||
local c = text:sub(i, i)
|
||||
for i = 1, #text do
|
||||
local c = text:sub(i, i)
|
||||
|
||||
if c == char then
|
||||
parts[#parts + 1] = current
|
||||
current = ""
|
||||
else
|
||||
current = current .. c
|
||||
end
|
||||
end
|
||||
if c == char then
|
||||
parts[#parts + 1] = current
|
||||
current = ""
|
||||
else
|
||||
current = current .. c
|
||||
end
|
||||
end
|
||||
|
||||
parts[#parts + 1] = current
|
||||
parts[#parts + 1] = current
|
||||
|
||||
return parts
|
||||
return parts
|
||||
end
|
||||
|
||||
---@param text string
|
||||
---@return KeyDescription[]
|
||||
function M:extract_key_description(text)
|
||||
local keys = {}
|
||||
local keys = {}
|
||||
|
||||
local splitted = M:split_by_char(text, ".")
|
||||
local splitted = M:split_by_char(text, ".")
|
||||
|
||||
local index = 1
|
||||
local index = 1
|
||||
|
||||
while index <= #splitted do
|
||||
local token = splitted[index]
|
||||
while index <= #splitted do
|
||||
local token = splitted[index]
|
||||
|
||||
-- Escape
|
||||
if string.sub(token, 1, 1) == "\\" then
|
||||
token = token:sub(2)
|
||||
-- Escape
|
||||
if string.sub(token, 1, 1) == "\\" then
|
||||
token = token:sub(2)
|
||||
|
||||
keys[#keys + 1] = {
|
||||
type = "object_wrapper",
|
||||
}
|
||||
keys[#keys + 1] = {
|
||||
key = token,
|
||||
type = "key",
|
||||
}
|
||||
-- Array
|
||||
elseif string.match(token, "%[%d+%]") then
|
||||
local array_index = tonumber(string.sub(token, 2, -2))
|
||||
keys[#keys + 1] = {
|
||||
type = "object_wrapper",
|
||||
}
|
||||
keys[#keys + 1] = {
|
||||
key = token,
|
||||
type = "key",
|
||||
}
|
||||
-- Array
|
||||
elseif string.match(token, "%[%d+%]") then
|
||||
local array_index = tonumber(string.sub(token, 2, -2))
|
||||
|
||||
keys[#keys + 1] = {
|
||||
type = "array_wrapper",
|
||||
}
|
||||
keys[#keys + 1] = {
|
||||
key = array_index,
|
||||
type = "array_index",
|
||||
}
|
||||
-- Array
|
||||
elseif string.match(token, "%d+") then
|
||||
local array_index = tonumber(token)
|
||||
keys[#keys + 1] = {
|
||||
type = "array_wrapper",
|
||||
}
|
||||
keys[#keys + 1] = {
|
||||
key = array_index,
|
||||
type = "array_index",
|
||||
}
|
||||
-- Array
|
||||
elseif string.match(token, "%d+") then
|
||||
local array_index = tonumber(token)
|
||||
|
||||
keys[#keys + 1] = {
|
||||
type = "array_wrapper",
|
||||
}
|
||||
keys[#keys + 1] = {
|
||||
key = array_index,
|
||||
type = "array_index",
|
||||
}
|
||||
-- Object
|
||||
else
|
||||
keys[#keys + 1] = {
|
||||
type = "object_wrapper",
|
||||
}
|
||||
keys[#keys + 1] = {
|
||||
key = token,
|
||||
type = "key",
|
||||
}
|
||||
end
|
||||
keys[#keys + 1] = {
|
||||
type = "array_wrapper",
|
||||
}
|
||||
keys[#keys + 1] = {
|
||||
key = array_index,
|
||||
type = "array_index",
|
||||
}
|
||||
-- Object
|
||||
else
|
||||
keys[#keys + 1] = {
|
||||
type = "object_wrapper",
|
||||
}
|
||||
keys[#keys + 1] = {
|
||||
key = token,
|
||||
type = "key",
|
||||
}
|
||||
end
|
||||
|
||||
index = index + 1
|
||||
end
|
||||
index = index + 1
|
||||
end
|
||||
|
||||
if #keys == 0 then
|
||||
return {
|
||||
{
|
||||
key = text,
|
||||
type = "key",
|
||||
}
|
||||
}
|
||||
end
|
||||
if #keys == 0 then
|
||||
return {
|
||||
{
|
||||
key = text,
|
||||
type = "key",
|
||||
},
|
||||
}
|
||||
end
|
||||
|
||||
return keys
|
||||
return keys
|
||||
end
|
||||
|
||||
return M
|
||||
|
@ -25,43 +25,43 @@
|
||||
---@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 = {
|
||||
key_max_length = 50,
|
||||
key_exact_length = false,
|
||||
max_length = 9999,
|
||||
overflow_marker = "…",
|
||||
conceal = "auto",
|
||||
prompt_title = "JSON(fly)",
|
||||
highlights = {
|
||||
string = "@string.json",
|
||||
number = "@number.json",
|
||||
boolean = "@boolean.json",
|
||||
null = "@constant.builtin.json",
|
||||
other = "@label.json",
|
||||
},
|
||||
jump_behavior = "key_start",
|
||||
subkeys_display = "normal",
|
||||
show_nested_child_preview = true,
|
||||
backend = "lsp",
|
||||
use_cache = 500,
|
||||
commands = {
|
||||
add_key = {"i", "<C-a>"}
|
||||
}
|
||||
key_max_length = 50,
|
||||
key_exact_length = false,
|
||||
max_length = 9999,
|
||||
overflow_marker = "…",
|
||||
conceal = "auto",
|
||||
prompt_title = "JSON(fly)",
|
||||
highlights = {
|
||||
string = "@string.json",
|
||||
number = "@number.json",
|
||||
boolean = "@boolean.json",
|
||||
null = "@constant.builtin.json",
|
||||
other = "@label.json",
|
||||
},
|
||||
jump_behavior = "key_start",
|
||||
subkeys_display = "normal",
|
||||
show_nested_child_preview = true,
|
||||
backend = "lsp",
|
||||
use_cache = 500,
|
||||
commands = {
|
||||
add_key = { "i", "<C-a>" },
|
||||
},
|
||||
}
|
||||
|
||||
local global_config = {}
|
||||
@ -69,168 +69,179 @@ local global_config = {}
|
||||
---@param entries Entry[]
|
||||
---@param buffer number
|
||||
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 config = vim.tbl_deep_extend("force", global_config, xopts or {})
|
||||
local filename = vim.api.nvim_buf_get_name(buffer)
|
||||
|
||||
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
|
||||
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
|
||||
|
||||
if global_config.conceal == "auto" then
|
||||
conceal = vim.o.conceallevel > 0
|
||||
else
|
||||
conceal = global_config.conceal == true
|
||||
end
|
||||
if global_config.conceal == "auto" then
|
||||
conceal = vim.o.conceallevel > 0
|
||||
else
|
||||
conceal = global_config.conceal == true
|
||||
end
|
||||
|
||||
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)
|
||||
local current_picker = action_state.get_current_picker(prompt_bufnr)
|
||||
local input = current_picker:_get_prompt()
|
||||
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)
|
||||
local current_picker = action_state.get_current_picker(prompt_bufnr)
|
||||
local input = current_picker:_get_prompt()
|
||||
|
||||
local key_descriptor = utils:extract_key_description(input)
|
||||
local key_descriptor = utils:extract_key_description(input)
|
||||
|
||||
insert:insert_new_key(entries, key_descriptor, buffer)
|
||||
end
|
||||
)
|
||||
insert:insert_new_key(entries, key_descriptor, buffer)
|
||||
end)
|
||||
|
||||
return true
|
||||
end,
|
||||
finder = finders.new_table {
|
||||
results = entries,
|
||||
---@param entry Entry
|
||||
entry_maker = function(entry)
|
||||
local _, raw_depth = entry.key:gsub("%.", ".")
|
||||
local depth = (raw_depth or 0) + 1
|
||||
return true
|
||||
end,
|
||||
finder = finders.new_table({
|
||||
results = entries,
|
||||
---@param entry Entry
|
||||
entry_maker = function(entry)
|
||||
local _, raw_depth = entry.key:gsub("%.", ".")
|
||||
local depth = (raw_depth or 0) + 1
|
||||
|
||||
return make_entry.set_default_entry_mt({
|
||||
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)
|
||||
return make_entry.set_default_entry_mt({
|
||||
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 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 {
|
||||
{ depth, "TelescopeResultsNumber"},
|
||||
{
|
||||
utils:truncate_overflow(
|
||||
key,
|
||||
global_config.key_max_length,
|
||||
global_config.overflow_marker
|
||||
),
|
||||
"@property.json",
|
||||
},
|
||||
{
|
||||
utils:truncate_overflow(
|
||||
preview,
|
||||
global_config.max_length,
|
||||
global_config.overflow_marker
|
||||
),
|
||||
global_config.highlights[hl_group_key] or "TelescopeResultsString",
|
||||
},
|
||||
}
|
||||
end,
|
||||
return displayer({
|
||||
{ depth, "TelescopeResultsNumber" },
|
||||
{
|
||||
utils:truncate_overflow(
|
||||
key,
|
||||
global_config.key_max_length,
|
||||
global_config.overflow_marker
|
||||
),
|
||||
"@property.json",
|
||||
},
|
||||
{
|
||||
utils:truncate_overflow(
|
||||
preview,
|
||||
global_config.max_length,
|
||||
global_config.overflow_marker
|
||||
),
|
||||
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
|
||||
-- Use length ("#" operator) as vim jumps to the bytes, not characters
|
||||
or entry.position.value_start
|
||||
}, config)
|
||||
end,
|
||||
},
|
||||
previewer = conf.grep_previewer(config),
|
||||
sorter = conf.generic_sorter(config),
|
||||
sorting_strategy = "ascending",
|
||||
}):find()
|
||||
bufnr = buffer,
|
||||
filename = filename,
|
||||
lnum = entry.position.line_number,
|
||||
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,
|
||||
}, config)
|
||||
end,
|
||||
}),
|
||||
previewer = conf.grep_previewer(config),
|
||||
sorter = conf.generic_sorter(config),
|
||||
sorting_strategy = "ascending",
|
||||
})
|
||||
:find()
|
||||
end
|
||||
|
||||
return require("telescope").register_extension {
|
||||
setup = function(extension_config)
|
||||
global_config = vim.tbl_deep_extend("force", DEFAULT_CONFIG, extension_config or {})
|
||||
end,
|
||||
exports = {
|
||||
jsonfly = function(xopts)
|
||||
local current_buf = vim.api.nvim_get_current_buf()
|
||||
return require("telescope").register_extension({
|
||||
setup = function(extension_config)
|
||||
global_config = vim.tbl_deep_extend("force", DEFAULT_CONFIG, extension_config or {})
|
||||
end,
|
||||
exports = {
|
||||
jsonfly = function(xopts)
|
||||
local current_buf = vim.api.nvim_get_current_buf()
|
||||
|
||||
local cached_entries = cache:get_cache(current_buf)
|
||||
local cached_entries = cache:get_cache(current_buf)
|
||||
|
||||
if cached_entries ~= nil then
|
||||
show_picker(cached_entries, current_buf, xopts)
|
||||
return
|
||||
end
|
||||
if cached_entries ~= nil then
|
||||
show_picker(cached_entries, current_buf, xopts)
|
||||
return
|
||||
end
|
||||
|
||||
local content_lines = vim.api.nvim_buf_get_lines(current_buf, 0, -1, false)
|
||||
local content = table.concat(content_lines, "\n")
|
||||
local allow_cache = global_config.use_cache > 0 and #content_lines >= global_config.use_cache
|
||||
local content_lines = vim.api.nvim_buf_get_lines(current_buf, 0, -1, false)
|
||||
local content = table.concat(content_lines, "\n")
|
||||
local allow_cache = global_config.use_cache > 0 and #content_lines >= global_config.use_cache
|
||||
|
||||
if allow_cache then
|
||||
cache:register_listeners(current_buf)
|
||||
end
|
||||
if allow_cache then
|
||||
cache:register_listeners(current_buf)
|
||||
end
|
||||
|
||||
local function run_lua_parser()
|
||||
local parsed = json:decode(content)
|
||||
local entries = parsers:get_entries_from_lua_json(parsed)
|
||||
local function run_lua_parser()
|
||||
local parsed = json:decode(content)
|
||||
local entries = parsers:get_entries_from_lua_json(parsed)
|
||||
|
||||
if allow_cache then
|
||||
cache:cache_buffer(current_buf, entries)
|
||||
end
|
||||
if allow_cache then
|
||||
cache:cache_buffer(current_buf, entries)
|
||||
end
|
||||
|
||||
show_picker(entries, current_buf, xopts)
|
||||
end
|
||||
show_picker(entries, current_buf, xopts)
|
||||
end
|
||||
|
||||
if global_config.backend == "lsp" then
|
||||
local params = vim.lsp.util.make_position_params(xopts.winnr)
|
||||
if global_config.backend == "lsp" then
|
||||
local params = vim.lsp.util.make_position_params(xopts.winnr)
|
||||
|
||||
vim.lsp.buf_request_all(
|
||||
current_buf,
|
||||
"textDocument/documentSymbol",
|
||||
params,
|
||||
function(results)
|
||||
if results == nil or vim.tbl_isempty(results) then
|
||||
run_lua_parser()
|
||||
return
|
||||
end
|
||||
-- Check i
|
||||
local clients = vim.lsp.get_clients()
|
||||
|
||||
local combined_result = {}
|
||||
local any_support = false
|
||||
|
||||
for _, res in pairs(results) do
|
||||
if res.result then
|
||||
vim.list_extend(combined_result, res.result)
|
||||
end
|
||||
end
|
||||
for _, client in ipairs(clients) do
|
||||
if client.supports_method("textDocument/documentSymbol") then
|
||||
any_support = true
|
||||
break
|
||||
end
|
||||
end
|
||||
|
||||
if vim.tbl_isempty(combined_result) then
|
||||
run_lua_parser()
|
||||
return
|
||||
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
|
||||
run_lua_parser()
|
||||
return
|
||||
end
|
||||
|
||||
local entries = parsers:get_entries_from_lsp_symbols(combined_result)
|
||||
local combined_result = {}
|
||||
|
||||
if allow_cache then
|
||||
cache:cache_buffer(current_buf, entries)
|
||||
end
|
||||
for _, res in pairs(results) do
|
||||
if res.result then
|
||||
vim.list_extend(combined_result, res.result)
|
||||
end
|
||||
end
|
||||
|
||||
show_picker(entries, current_buf, xopts)
|
||||
end
|
||||
)
|
||||
else
|
||||
run_lua_parser()
|
||||
end
|
||||
end
|
||||
}
|
||||
}
|
||||
if vim.tbl_isempty(combined_result) then
|
||||
run_lua_parser()
|
||||
return
|
||||
end
|
||||
|
||||
local entries = parsers:get_entries_from_lsp_symbols(combined_result)
|
||||
|
||||
if allow_cache then
|
||||
cache:cache_buffer(current_buf, entries)
|
||||
end
|
||||
|
||||
show_picker(entries, current_buf, xopts)
|
||||
end)
|
||||
end
|
||||
end
|
||||
|
||||
run_lua_parser()
|
||||
end,
|
||||
},
|
||||
})
|
||||
|
Loading…
x
Reference in New Issue
Block a user