merge main

This commit is contained in:
Myzel394 2024-05-26 13:05:29 +02:00
commit 96e8f2b8a3
No known key found for this signature in database
GPG Key ID: DEC4AAB876F73185
4 changed files with 56 additions and 49 deletions

View File

@ -1,9 +1,9 @@
# jsonfly.nvim # jsonfly.nvim
Fly through your JSON files with ease. Fly through your JSON, XML and YAML files with ease.
Search ✨ blazingly fast ✨ for keys via [Telescope](https://github.com/nvim-telescope/telescope.nvim), navigate through your JSON structure with ease, and insert deeply nested keys without fear. Search ✨ blazingly fast ✨ for keys via [Telescope](https://github.com/nvim-telescope/telescope.nvim), navigate through your JSON structure with ease, and insert deeply nested keys without fear.
json(fly) is a Telescope extension that will show you all keys (including nested ones) in your JSON files and allow you to search and jump to them quickly. json(fly) is a Telescope extension that will show you all keys (including nested ones) in your JSON (or XML or YAML) files and allow you to search and jump to them quickly.
It's completely customizable and even supports highlighting of the values. It's completely customizable and even supports highlighting of the values.
<img src="docs/horizontal_layout.png"> <img src="docs/horizontal_layout.png">
@ -48,7 +48,7 @@ Here's how I load it with lazy.nvim with lazy-loading and `<leader>j` as the key
"<leader>j", "<leader>j",
"<cmd>Telescope jsonfly<cr>", "<cmd>Telescope jsonfly<cr>",
desc = "Open json(fly)", desc = "Open json(fly)",
ft = { "json" }, ft = { "json", "xml", "yaml" },
mode = "n" mode = "n"
} }
} }

View File

@ -19,6 +19,12 @@ local PRIMITIVE_TYPES = {
number = true, number = true,
boolean = true, boolean = true,
} }
local CONTAINS_CHILDREN_TYPES = {
[2] = true, -- Module / Javascript Object
[8] = true, -- Field
[18] = true, -- Array
[19] = true, -- Object
}
local M = {} local M = {}
@ -91,7 +97,7 @@ end
---@return string|number|table|boolean|nil ---@return string|number|table|boolean|nil
function M:parse_lsp_value(result) function M:parse_lsp_value(result)
-- Object -- Object
if result.kind == 2 then if CONTAINS_CHILDREN_TYPES[result.kind] then
local value = {} local value = {}
for _, child in ipairs(result.children) do for _, child in ipairs(result.children) do
@ -165,7 +171,7 @@ function M:get_entries_from_lsp_symbols(symbols)
} }
keys[#keys + 1] = entry keys[#keys + 1] = entry
if symbol.kind == 2 or symbol.kind == 18 then if CONTAINS_CHILDREN_TYPES[symbol.kind] then
local sub_keys = M:get_entries_from_lsp_symbols(symbol.children) local sub_keys = M:get_entries_from_lsp_symbols(symbol.children)
for jindex=1, #sub_keys do for jindex=1, #sub_keys do

View File

@ -63,14 +63,18 @@ end
---@param value any ---@param value any
---@param conceal boolean ---@param conceal boolean
function M:create_display_preview(value, conceal) ---@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 t == "table" then
if render_objects == false then
return "", "other"
end
local preview_table = {} local preview_table = {}
for k, v in pairs(value) do for k, v in pairs(value) do
preview_table[#preview_table + 1] = k .. ": " .. M:create_display_preview(v, conceal) preview_table[#preview_table + 1] = k .. ": " .. M:create_display_preview(v, conceal, render_objects)
end end
return "{ " .. table.concat(preview_table, ", ") .. " }", "other" return "{ " .. table.concat(preview_table, ", ") .. " }", "other"

View File

@ -10,6 +10,7 @@
---@field highlights Highlights - Highlight groups for different types ---@field highlights Highlights - Highlight groups for different types
---@field jump_behavior "key_start"|"value_start" - Behavior for jumping to the location, "key_start" == Jump to the start of the key, "value_start" == Jump to the start of the value, Default: "key_start" ---@field jump_behavior "key_start"|"value_start" - Behavior for jumping to the location, "key_start" == Jump to the start of the key, "value_start" == Jump to the start of the value, Default: "key_start"
---@field subkeys_display "normal"|"waterfall" - Display subkeys in a normal or waterfall style, Default: "normal" ---@field subkeys_display "normal"|"waterfall" - Display subkeys in a normal or waterfall style, Default: "normal"
---@field show_nested_child_preview boolean - Whether to show a preview of nested children, Default: true
---@field backend "lua"|"lsp" - Backend to use for parsing JSON, "lua" = Use our own Lua parser to parse the JSON, "lsp" = Use your LSP to parse the JSON (currently only https://github.com/Microsoft/vscode-json-languageservice is supported). If the "lsp" backend is selected but the LSP fails, it will fallback to the "lua" backend, Default: "lsp" ---@field backend "lua"|"lsp" - Backend to use for parsing JSON, "lua" = Use our own Lua parser to parse the JSON, "lsp" = Use your LSP to parse the JSON (currently only https://github.com/Microsoft/vscode-json-languageservice is supported). If the "lsp" backend is selected but the LSP fails, it will fallback to the "lua" backend, Default: "lsp"
---@field use_cache number - Whether to use cache the parsed JSON. The cache will be activated if the number of lines is greater or equal to this value, By default, the cache is activate when the file if 1000 lines or more; `0` to disable the cache, Default: 500 ---@field use_cache number - Whether to use cache the parsed JSON. The cache will be activated if the number of lines is greater or equal to this value, By default, the cache is activate when the file if 1000 lines or more; `0` to disable the cache, Default: 500
---@field commands Commands - Shortcuts for commands ---@field commands Commands - Shortcuts for commands
@ -33,14 +34,14 @@ local languages = require"jsonfly.languages"
local json = require"jsonfly.json" local json = require"jsonfly.json"
local finders = require "telescope.finders" local finders = require "telescope.finders"
local pickers = require "telescope.pickers" local pickers = require "telescope.pickers"
local conf = require"telescope.config".values local conf = require("telescope.config").values
local make_entry = require "telescope.make_entry" local make_entry = require "telescope.make_entry"
local entry_display = require "telescope.pickers.entry_display" local entry_display = require "telescope.pickers.entry_display"
local action_state = require "telescope.actions.state" local action_state = require "telescope.actions.state"
---@type Options ---@type Options
local opts = { local DEFAULT_CONFIG = {
key_max_length = 50, key_max_length = 50,
key_exact_length = false, key_exact_length = false,
max_length = 9999, max_length = 9999,
@ -56,6 +57,7 @@ local opts = {
}, },
jump_behavior = "key_start", jump_behavior = "key_start",
subkeys_display = "normal", subkeys_display = "normal",
show_nested_child_preview = true,
backend = "lsp", backend = "lsp",
use_cache = 500, use_cache = 500,
commands = { commands = {
@ -63,34 +65,37 @@ local opts = {
} }
} }
local global_config = {}
---@param entries Entry[] ---@param entries Entry[]
---@param buffer number ---@param buffer number
local function show_picker(entries, buffer) 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 filename = vim.api.nvim_buf_get_name(buffer)
local displayer = entry_display.create { local displayer = entry_display.create {
separator = " ", separator = " ",
items = { items = {
{ width = 1 }, { width = 1 },
opts.key_exact_length and { width = opts.key_max_length } or { remaining = true }, global_config.key_exact_length and { width = global_config.key_max_length } or { remaining = true },
{ remaining = true }, { remaining = true },
}, },
} }
---@type boolean ---@type boolean
local conceal local conceal
if opts.conceal == "auto" then if global_config.conceal == "auto" then
conceal = vim.o.conceallevel > 0 conceal = vim.o.conceallevel > 0
else else
conceal = opts.conceal == true conceal = global_config.conceal == true
end end
pickers.new(opts, { pickers.new(config, {
prompt_title = opts.prompt_title, prompt_title = global_config.prompt_title,
attach_mappings = function(_, map) attach_mappings = function(_, map)
map( map(
opts.commands.add_key[1], global_config.commands.add_key[1],
opts.commands.add_key[2], global_config.commands.add_key[2],
function(prompt_bufnr) function(prompt_bufnr)
local current_picker = action_state.get_current_picker(prompt_bufnr) local current_picker = action_state.get_current_picker(prompt_bufnr)
local input = current_picker:_get_prompt() local input = current_picker:_get_prompt()
@ -114,27 +119,27 @@ local function show_picker(entries, buffer)
value = buffer, value = buffer,
ordinal = entry.key, ordinal = entry.key,
display = function(_) display = function(_)
local preview, hl_group_key = utils:create_display_preview(entry.value, conceal) local preview, hl_group_key = utils:create_display_preview(entry.value, conceal, global_config.show_nested_child_preview)
local key = opts.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"}, { depth, "TelescopeResultsNumber"},
{ {
utils:truncate_overflow( utils:truncate_overflow(
key, key,
opts.key_max_length, global_config.key_max_length,
opts.overflow_marker global_config.overflow_marker
), ),
"@property.json", "@property.json",
}, },
{ {
utils:truncate_overflow( utils:truncate_overflow(
preview, preview,
opts.max_length, global_config.max_length,
opts.overflow_marker global_config.overflow_marker
), ),
opts.highlights[hl_group_key] or "TelescopeResultsString", global_config.highlights[hl_group_key] or "TelescopeResultsString",
}, },
} }
end, end,
@ -142,22 +147,22 @@ local function show_picker(entries, buffer)
bufnr = buffer, bufnr = buffer,
filename = filename, filename = filename,
lnum = entry.position.line_number, lnum = entry.position.line_number,
col = opts.jump_behavior == "key_start" col = global_config.jump_behavior == "key_start"
and entry.position.key_start and entry.position.key_start
-- Use length ("#" operator) as vim jumps to the bytes, not characters -- Use length ("#" operator) as vim jumps to the bytes, not characters
or entry.position.value_start or entry.position.value_start
}, opts) }, config)
end, end,
}, },
previewer = conf.grep_previewer(opts), previewer = conf.grep_previewer(config),
sorter = conf.generic_sorter(opts), sorter = conf.generic_sorter(config),
sorting_strategy = "ascending", sorting_strategy = "ascending",
}):find() }):find()
end end
return require"telescope".register_extension { return require("telescope").register_extension {
setup = function(extension_config) setup = function(extension_config)
opts = vim.tbl_deep_extend("force", opts, extension_config or {}) global_config = vim.tbl_deep_extend("force", DEFAULT_CONFIG, extension_config or {})
end, end,
exports = { exports = {
jsonfly = function(xopts) jsonfly = function(xopts)
@ -166,13 +171,13 @@ return require"telescope".register_extension {
local cached_entries = cache:get_cache(current_buf) local cached_entries = cache:get_cache(current_buf)
if cached_entries ~= nil then if cached_entries ~= nil then
show_picker(cached_entries, current_buf) show_picker(cached_entries, current_buf, xopts)
return return
end end
local content_lines = vim.api.nvim_buf_get_lines(current_buf, 0, -1, false) local content_lines = vim.api.nvim_buf_get_lines(current_buf, 0, -1, false)
local content = table.concat(content_lines, "\n") local content = table.concat(content_lines, "\n")
local allow_cache = opts.use_cache > 0 and #content_lines >= opts.use_cache local allow_cache = global_config.use_cache > 0 and #content_lines >= global_config.use_cache
if allow_cache then if allow_cache then
cache:register_listeners(current_buf) cache:register_listeners(current_buf)
@ -186,39 +191,31 @@ return require"telescope".register_extension {
cache:cache_buffer(current_buf, entries) cache:cache_buffer(current_buf, entries)
end end
show_picker(entries, current_buf) show_picker(entries, current_buf, xopts)
end end
if opts.backend == "lsp" then if global_config.backend == "lsp" then
local params = vim.lsp.util.make_position_params(xopts.winnr) local params = vim.lsp.util.make_position_params(xopts.winnr)
vim.lsp.buf_request( vim.lsp.buf_request_all(
current_buf, current_buf,
"textDocument/documentSymbol", "textDocument/documentSymbol",
params, params,
function(error, lsp_response) function(response)
print(vim.inspect(lsp_response)) if response == nil or #response == 0 then
languages:filter_lsp_symbol_by_position(
lsp_response[1],
params.position
)
print(vim.inspect(lsp_response))
if error then
run_lua_parser() run_lua_parser()
return return
end end
local entries = parsers:get_entries_from_lsp_symbols(lsp_response) local result = response[1].result
local entries = parsers:get_entries_from_lsp_symbols(result)
if allow_cache then if allow_cache then
cache:cache_buffer(current_buf, entries) cache:cache_buffer(current_buf, entries)
end end
show_picker(entries, current_buf) show_picker(entries, current_buf, xopts)
end end
) )
else else