json_qf.lua (1748B)
1 local function has_value(tab, val) 2 for _, value in ipairs(tab) do 3 if value == val then 4 return true 5 end 6 end 7 return false 8 end 9 10 local function get_key_location(key) 11 return { 12 row = vim.api.nvim_exec2([[g/^\s*"]] .. key .. [["/echo line('.')]], { output = true }), 13 col = vim.api.nvim_exec2([[g/^\s*"]] .. key .. [["/execute "normal! ^" | echo col('.')-1]], { output = true }), 14 } 15 end 16 17 local function populate_qf(type, sort, use_quickfix) 18 local cmd_lines = {} 19 local cur_file = vim.fn.getreg('%') 20 21 local json_types = { 'string', 'number', 'boolean', 'array', 'object', 'null' } 22 if has_value(json_types, type) then 23 for s in vim.fn.system('jq -c \'to_entries[] | if (.value|type == "' .. type .. '") then .key else empty end\' ' .. 24 cur_file):gmatch('[^\r\n]+') do 25 local key = s:gsub('%"', ''):gsub('^%s*(.-)%s*$', '%1'):gsub(',', '') 26 table.insert(cmd_lines, key) 27 end 28 else 29 local get_keys = sort and 'jq \'keys[]\' ' .. cur_file or 'jq \'keys_unsorted[]\' ' .. cur_file 30 for s in vim.fn.system(get_keys):gmatch('[^\r\n]+') do 31 local key = s:gsub('%"', ''):gsub('^%s*(.-)%s*$', '%1'):gsub(',', '') 32 table.insert(cmd_lines, key) 33 end 34 end 35 36 local qf_list = {} 37 for _, v in pairs(cmd_lines) do 38 table.insert(qf_list, 39 { filename = cur_file, lnum = get_key_location(v).row, col = get_key_location(v).col, text = v }) 40 end 41 42 if use_quickfix then 43 vim.fn.setqflist(qf_list, ' ') 44 vim.cmd.copen() 45 else 46 vim.fn.setloclist(0, qf_list, ' ') 47 vim.cmd.lopen() 48 end 49 end 50 51 vim.api.nvim_create_user_command('Json', function() 52 local ft = vim.api.nvim_get_option_value('ft', { buf = 0 }) 53 if ft == 'json' then 54 populate_qf(nil, true, false) 55 end 56 end, {})