| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152 | local M = {  floating_buf = nil,  floating_win = nil,  prev_result = nil,}local function create_floating_file(location, opts)  vim.validate {    location = { location, "t" },    opts = { opts, "t", true },  }  -- Set some defaults  opts = opts or {}  local close_events = opts.close_events or { "CursorMoved", "CursorMovedI", "BufHidden", "InsertCharPre" }  -- location may be LocationLink or Location  local uri = location.targetUri or location.uri  if uri == nil then    return  end  local bufnr = vim.uri_to_bufnr(uri)  if not vim.api.nvim_buf_is_loaded(bufnr) then    vim.fn.bufload(bufnr)  end  local range = location.targetRange or location.range  local contents = vim.api.nvim_buf_get_lines(    bufnr,    range.start.line,    math.min(range["end"].line + 1 + (opts.context or 10), range.start.line + (opts.max_height or 15)), -- Don't let the window be more that 15 lines long(height)    false  )  local width, height = vim.lsp.util._make_floating_popup_size(contents, opts)  opts = vim.lsp.util.make_floating_popup_options(width, height, opts)  -- Don't make it minimal as it is meant to be fully featured  opts["style"] = nil  vim.api.nvim_buf_set_option(bufnr, "bufhidden", "wipe")  local winnr = vim.api.nvim_open_win(bufnr, false, opts)  vim.api.nvim_win_set_option(winnr, "winblend", 0)  vim.api.nvim_win_set_cursor(winnr, { range.start.line + 1, range.start.character })  vim.api.nvim_buf_set_var(bufnr, "lsp_floating_window", winnr)  -- Set some autocmds to close the window  vim.api.nvim_command(    "autocmd QuitPre <buffer> ++nested ++once lua pcall(vim.api.nvim_win_close, " .. winnr .. ", true)"  )  vim.lsp.util.close_preview_autocmd(close_events, winnr)  return bufnr, winnrendlocal function preview_location_callback(result)  if result == nil or vim.tbl_isempty(result) then    return nil  end  local opts = {    border = "rounded",    context = 10,  }  if vim.tbl_islist(result) then    M.prev_result = result[1]    M.floating_buf, M.floating_win = create_floating_file(result[1], opts)  else    M.prev_result = result    M.floating_buf, M.floating_win = create_floating_file(result, opts)  endendlocal function preview_location_callback_old_signature(_, _, result)  return preview_location_callback(result)endlocal function preview_location_callback_new_signature(_, result)  return preview_location_callback(result)endfunction M.open_file()  -- Get the file currently open in the floating window  local filepath = vim.fn.expand "%:."  if not filepath then    print "peek: Unable to open the file!"    return  end  -- Close the floating window  pcall(vim.api.nvim_win_close, M.floating_win, true)  -- Edit the file  vim.cmd("edit " .. filepath)  local winnr = vim.api.nvim_get_current_win()  -- Set the cursor at the right position  M.set_cursor_to_prev_pos(winnr)endfunction M.set_cursor_to_prev_pos(winnr)  -- Get position of the thing to peek at  local location = M.prev_result  local range = location.targetRange or location.range  local cursor_pos = { range.start.line + 1, range.start.character }  -- Set the winnr to the floating window if none was passed in  winnr = winnr or M.floating_win  -- Set the cursor at the correct position in the floating window  vim.api.nvim_win_set_cursor(winnr, cursor_pos)endfunction M.Peek(what)  -- If a window already exists, focus it at the right position!  if vim.tbl_contains(vim.api.nvim_list_wins(), M.floating_win) then    local success_1, _ = pcall(vim.api.nvim_set_current_win, M.floating_win)    if not success_1 then      print "peek: You cannot edit the current file in a preview!"      return    end    -- Set the cursor at the correct position in the floating window    M.set_cursor_to_prev_pos()    vim.api.nvim_buf_set_keymap(      M.floating_buf,      "n",      "<CR>",      ":lua require('lvim.lsp.peek').open_file()<CR>",      { noremap = true, silent = true }    )  else    -- Make a new request and then create the new window in the callback    local params = vim.lsp.util.make_position_params()    local preview_callback = preview_location_callback_old_signature    if vim.fn.has "nvim-0.5.1" > 0 then      preview_callback = preview_location_callback_new_signature    end    local success, _ = pcall(vim.lsp.buf_request, 0, "textDocument/" .. what, params, preview_callback)    if not success then      print(        'peek: Error calling LSP method "textDocument/' .. what .. '". The current language lsp might not support it.'      )    end  endendreturn M
 |