Some checks failed
		
		
	
	Detach Plugins / check (FlyGrep.vim) (push) Has been cancelled
				
			Detach Plugins / check (GitHub.vim) (push) Has been cancelled
				
			Detach Plugins / check (JavaUnit.vim) (push) Has been cancelled
				
			Detach Plugins / check (SourceCounter.vim) (push) Has been cancelled
				
			Detach Plugins / check (cpicker.nvim) (push) Has been cancelled
				
			Detach Plugins / check (dein-ui.vim) (push) Has been cancelled
				
			Detach Plugins / check (git.vim) (push) Has been cancelled
				
			Detach Plugins / check (iedit.vim) (push) Has been cancelled
				
			Detach Plugins / check (scrollbar.vim) (push) Has been cancelled
				
			Detach Plugins / check (vim-chat) (push) Has been cancelled
				
			Detach Plugins / check (vim-cheat) (push) Has been cancelled
				
			Detach Plugins / check (vim-todo) (push) Has been cancelled
				
			Detach Plugins / check (xmake.vim) (push) Has been cancelled
				
			test / Linux (nvim, nightly) (push) Has been cancelled
				
			test / Linux (nvim, v0.3.8) (push) Has been cancelled
				
			test / Linux (nvim, v0.4.0) (push) Has been cancelled
				
			test / Linux (nvim, v0.4.2) (push) Has been cancelled
				
			test / Linux (nvim, v0.4.3) (push) Has been cancelled
				
			test / Linux (nvim, v0.4.4) (push) Has been cancelled
				
			test / Linux (nvim, v0.5.0) (push) Has been cancelled
				
			test / Linux (nvim, v0.5.1) (push) Has been cancelled
				
			test / Linux (nvim, v0.6.0) (push) Has been cancelled
				
			test / Linux (nvim, v0.6.1) (push) Has been cancelled
				
			test / Linux (nvim, v0.7.0) (push) Has been cancelled
				
			test / Linux (nvim, v0.7.2) (push) Has been cancelled
				
			test / Linux (nvim, v0.8.0) (push) Has been cancelled
				
			test / Linux (nvim, v0.8.1) (push) Has been cancelled
				
			test / Linux (nvim, v0.8.2) (push) Has been cancelled
				
			test / Linux (nvim, v0.8.3) (push) Has been cancelled
				
			test / Linux (nvim, v0.9.0) (push) Has been cancelled
				
			test / Linux (nvim, v0.9.1) (push) Has been cancelled
				
			test / Linux (true, vim, v7.4.052) (push) Has been cancelled
				
			test / Linux (true, vim, v7.4.1689) (push) Has been cancelled
				
			test / Linux (true, vim, v7.4.629) (push) Has been cancelled
				
			test / Linux (true, vim, v8.0.0027) (push) Has been cancelled
				
			test / Linux (true, vim, v8.0.0183) (push) Has been cancelled
				
			test / Linux (vim, nightly) (push) Has been cancelled
				
			test / Linux (vim, v8.0.0184) (push) Has been cancelled
				
			test / Linux (vim, v8.0.1453) (push) Has been cancelled
				
			test / Linux (vim, v8.1.2269) (push) Has been cancelled
				
			test / Linux (vim, v8.2.2434) (push) Has been cancelled
				
			test / Linux (vim, v8.2.3995) (push) Has been cancelled
				
			test / Windows (nvim, nightly) (push) Has been cancelled
				
			test / Windows (nvim, v0.3.8) (push) Has been cancelled
				
			test / Windows (nvim, v0.4.2) (push) Has been cancelled
				
			test / Windows (nvim, v0.4.3) (push) Has been cancelled
				
			test / Windows (nvim, v0.4.4) (push) Has been cancelled
				
			test / Windows (nvim, v0.5.0) (push) Has been cancelled
				
			test / Windows (nvim, v0.5.1) (push) Has been cancelled
				
			test / Windows (nvim, v0.6.0) (push) Has been cancelled
				
			test / Windows (nvim, v0.6.1) (push) Has been cancelled
				
			test / Windows (nvim, v0.7.0) (push) Has been cancelled
				
			test / Windows (nvim, v0.7.2) (push) Has been cancelled
				
			test / Windows (nvim, v0.8.0) (push) Has been cancelled
				
			test / Windows (nvim, v0.8.1) (push) Has been cancelled
				
			test / Windows (nvim, v0.8.2) (push) Has been cancelled
				
			test / Windows (nvim, v0.8.3) (push) Has been cancelled
				
			test / Windows (nvim, v0.9.0) (push) Has been cancelled
				
			test / Windows (nvim, v0.9.1) (push) Has been cancelled
				
			test / Windows (vim, nightly) (push) Has been cancelled
				
			test / Windows (vim, v7.4.1185) (push) Has been cancelled
				
			test / Windows (vim, v7.4.1689) (push) Has been cancelled
				
			test / Windows (vim, v8.0.0027) (push) Has been cancelled
				
			test / Windows (vim, v8.0.1453) (push) Has been cancelled
				
			test / Windows (vim, v8.1.2269) (push) Has been cancelled
				
			test / Windows (vim, v8.2.2434) (push) Has been cancelled
				
			test / Windows (vim, v8.2.3995) (push) Has been cancelled
				
			docker / docker (push) Has been cancelled
				
			mirror / check (coding) (push) Has been cancelled
				
			mirror / check (gitee) (push) Has been cancelled
				
			mirror / check (gitlab) (push) Has been cancelled
				
			
		
			
				
	
	
		
			420 lines
		
	
	
		
			12 KiB
		
	
	
	
		
			Lua
		
	
	
	
	
	
			
		
		
	
	
			420 lines
		
	
	
		
			12 KiB
		
	
	
	
		
			Lua
		
	
	
	
	
	
local vim = vim
 | 
						|
local utils = require("neo-tree.utils")
 | 
						|
local highlights = require("neo-tree.ui.highlights")
 | 
						|
local events = require("neo-tree.events")
 | 
						|
local manager = require("neo-tree.sources.manager")
 | 
						|
local log = require("neo-tree.log")
 | 
						|
local renderer = require("neo-tree.ui.renderer")
 | 
						|
 | 
						|
local neo_tree_preview_namespace = vim.api.nvim_create_namespace("neo_tree_preview")
 | 
						|
 | 
						|
local function create_floating_preview_window(state)
 | 
						|
  local default_position = utils.resolve_config_option(state, "window.position", "left")
 | 
						|
  state.current_position = state.current_position or default_position
 | 
						|
 | 
						|
  local winwidth = vim.api.nvim_win_get_width(state.winid)
 | 
						|
  local winheight = vim.api.nvim_win_get_height(state.winid)
 | 
						|
  local height = vim.o.lines - 4
 | 
						|
  local width = 120
 | 
						|
  local row, col = 0, 0
 | 
						|
 | 
						|
  if state.current_position == "left" then
 | 
						|
    col = winwidth + 1
 | 
						|
    width = math.min(vim.o.columns - col, 120)
 | 
						|
  elseif state.current_position == "top" or state.current_position == "bottom" then
 | 
						|
    height = height - winheight
 | 
						|
    width = winwidth - 2
 | 
						|
    if state.current_position == "top" then
 | 
						|
      row = vim.api.nvim_win_get_height(state.winid) + 1
 | 
						|
    end
 | 
						|
  elseif state.current_position == "right" then
 | 
						|
    width = math.min(vim.o.columns - winwidth - 4, 120)
 | 
						|
    col = vim.o.columns - winwidth - width - 3
 | 
						|
  elseif state.current_position == "float" then
 | 
						|
    local pos = vim.api.nvim_win_get_position(state.winid)
 | 
						|
    -- preview will be same height and top as tree
 | 
						|
    row = pos[1] - 1
 | 
						|
    height = winheight
 | 
						|
 | 
						|
    -- tree and preview window will be side by side and centered in the editor
 | 
						|
    width = math.min(vim.o.columns - winwidth - 4, 120)
 | 
						|
    local total_width = winwidth + width + 4
 | 
						|
    local margin = math.floor((vim.o.columns - total_width) / 2)
 | 
						|
    col = margin + winwidth + 2
 | 
						|
 | 
						|
    -- move the tree window to make the combined layout centered
 | 
						|
    local popup = renderer.get_nui_popup(state.winid)
 | 
						|
    popup:update_layout({
 | 
						|
      relative = "editor",
 | 
						|
      position = {
 | 
						|
        row = row,
 | 
						|
        col = margin,
 | 
						|
      },
 | 
						|
    })
 | 
						|
  else
 | 
						|
    local cur_pos = state.current_position or "unknown"
 | 
						|
    log.error('Preview cannot be used when position = "' .. cur_pos .. '"')
 | 
						|
    return
 | 
						|
  end
 | 
						|
 | 
						|
  local popups = require("neo-tree.ui.popups")
 | 
						|
  local options = popups.popup_options("Neo-tree Preview", width, {
 | 
						|
    ns_id = highlights.ns_id,
 | 
						|
    size = { height = height, width = width },
 | 
						|
    relative = "editor",
 | 
						|
    position = {
 | 
						|
      row = row,
 | 
						|
      col = col,
 | 
						|
    },
 | 
						|
    win_options = {
 | 
						|
      number = true,
 | 
						|
      winhighlight = "Normal:"
 | 
						|
        .. highlights.FLOAT_NORMAL
 | 
						|
        .. ",FloatBorder:"
 | 
						|
        .. highlights.FLOAT_BORDER,
 | 
						|
    },
 | 
						|
  })
 | 
						|
  options.zindex = 40
 | 
						|
  options.buf_options.filetype = "neo-tree-preview"
 | 
						|
 | 
						|
  local NuiPopup = require("nui.popup")
 | 
						|
  local win = NuiPopup(options)
 | 
						|
  win:mount()
 | 
						|
  return win
 | 
						|
end
 | 
						|
 | 
						|
local Preview = {}
 | 
						|
local instance = nil
 | 
						|
 | 
						|
---Creates a new preview.
 | 
						|
---@param state table The state of the source.
 | 
						|
---@return table preview A new preview. A preview is a table consisting of the following keys:
 | 
						|
--  active = boolean           Whether the preview is active.
 | 
						|
--  winid = number             The id of the window being used to preview.
 | 
						|
--  is_neo_tree_window boolean Whether the preview window belongs to neo-tree.
 | 
						|
--  bufnr = number             The buffer that is currently in the preview window.
 | 
						|
--  start_pos = array or nil   An array-like table specifying the (0-indexed) starting position of the previewed text.
 | 
						|
--  end_pos = array or nil     An array-like table specifying the (0-indexed) ending position of the preview text.
 | 
						|
--  truth = table              A table containing information to be restored when the preview ends.
 | 
						|
--  events = array             A list of events the preview is subscribed to.
 | 
						|
--These keys should not be altered directly. Note that the keys `start_pos`, `end_pos` and `truth`
 | 
						|
--may be inaccurate if `active` is false.
 | 
						|
function Preview:new(state)
 | 
						|
  local preview = {}
 | 
						|
  preview.active = false
 | 
						|
  preview.config = vim.deepcopy(state.config)
 | 
						|
  setmetatable(preview, { __index = self })
 | 
						|
  preview:findWindow(state)
 | 
						|
  return preview
 | 
						|
end
 | 
						|
 | 
						|
---Preview a buffer in the preview window and optionally reveal and highlight the previewed text.
 | 
						|
---@param bufnr number? The number of the buffer to be previewed.
 | 
						|
---@param start_pos table? The (0-indexed) starting position of the previewed text. May be absent.
 | 
						|
---@param end_pos table? The (0-indexed) ending position of the previewed text. May be absent
 | 
						|
function Preview:preview(bufnr, start_pos, end_pos)
 | 
						|
  if self.is_neo_tree_window then
 | 
						|
    log.warn("Could not find appropriate window for preview")
 | 
						|
    return
 | 
						|
  end
 | 
						|
 | 
						|
  bufnr = bufnr or self.bufnr
 | 
						|
  if not self.active then
 | 
						|
    self:activate()
 | 
						|
  end
 | 
						|
 | 
						|
  if not self.active then
 | 
						|
    return
 | 
						|
  end
 | 
						|
 | 
						|
  if bufnr ~= self.bufnr then
 | 
						|
    self:setBuffer(bufnr)
 | 
						|
  end
 | 
						|
 | 
						|
  self:clearHighlight()
 | 
						|
 | 
						|
  self.bufnr = bufnr
 | 
						|
  self.start_pos = start_pos
 | 
						|
  self.end_pos = end_pos
 | 
						|
 | 
						|
  self:reveal()
 | 
						|
  self:highlight()
 | 
						|
end
 | 
						|
 | 
						|
---Reverts the preview and inactivates it, restoring the preview window to its previous state.
 | 
						|
function Preview:revert()
 | 
						|
  self.active = false
 | 
						|
  self:unsubscribe()
 | 
						|
  self:clearHighlight()
 | 
						|
 | 
						|
  if not renderer.is_window_valid(self.winid) then
 | 
						|
    self.winid = nil
 | 
						|
    return
 | 
						|
  end
 | 
						|
 | 
						|
  if self.config.use_float then
 | 
						|
    vim.api.nvim_win_close(self.winid, true)
 | 
						|
    self.winid = nil
 | 
						|
    return
 | 
						|
  else
 | 
						|
    local foldenable = utils.get_value(self.truth, "options.foldenable", nil, false)
 | 
						|
    if foldenable ~= nil then
 | 
						|
      vim.api.nvim_win_set_option(self.winid, "foldenable", self.truth.options.foldenable)
 | 
						|
    end
 | 
						|
    vim.api.nvim_win_set_var(self.winid, "neo_tree_preview", 0)
 | 
						|
  end
 | 
						|
 | 
						|
  local bufnr = self.truth.bufnr
 | 
						|
  if type(bufnr) ~= "number" then
 | 
						|
    return
 | 
						|
  end
 | 
						|
  if not vim.api.nvim_buf_is_valid(bufnr) then
 | 
						|
    return
 | 
						|
  end
 | 
						|
  self:setBuffer(bufnr)
 | 
						|
  self.bufnr = bufnr
 | 
						|
  if vim.api.nvim_win_is_valid(self.winid) then
 | 
						|
    vim.api.nvim_win_call(self.winid, function()
 | 
						|
      vim.fn.winrestview(self.truth.view)
 | 
						|
    end)
 | 
						|
  end
 | 
						|
  vim.api.nvim_buf_set_option(self.bufnr, "bufhidden", self.truth.options.bufhidden)
 | 
						|
end
 | 
						|
 | 
						|
---Subscribe to event and add it to the preview event list.
 | 
						|
--@param source string? Name of the source to add the event to. Will use `events.subscribe` if nil.
 | 
						|
--@param event table Event to subscribe to.
 | 
						|
function Preview:subscribe(source, event)
 | 
						|
  if source == nil then
 | 
						|
    events.subscribe(event)
 | 
						|
  else
 | 
						|
    manager.subscribe(source, event)
 | 
						|
  end
 | 
						|
  self.events = self.events or {}
 | 
						|
  table.insert(self.events, { source = source, event = event })
 | 
						|
end
 | 
						|
 | 
						|
---Unsubscribe to all events in the preview event list.
 | 
						|
function Preview:unsubscribe()
 | 
						|
  if self.events == nil then
 | 
						|
    return
 | 
						|
  end
 | 
						|
  for _, event in ipairs(self.events) do
 | 
						|
    if event.source == nil then
 | 
						|
      events.unsubscribe(event.event)
 | 
						|
    else
 | 
						|
      manager.unsubscribe(event.source, event.event)
 | 
						|
    end
 | 
						|
  end
 | 
						|
  self.events = {}
 | 
						|
end
 | 
						|
 | 
						|
---Finds the appropriate window and updates the preview accordingly.
 | 
						|
---@param state table The state of the source.
 | 
						|
function Preview:findWindow(state)
 | 
						|
  local winid, is_neo_tree_window
 | 
						|
  if self.config.use_float then
 | 
						|
    if
 | 
						|
      type(self.winid) == "number"
 | 
						|
      and vim.api.nvim_win_is_valid(self.winid)
 | 
						|
      and utils.is_floating(self.winid)
 | 
						|
    then
 | 
						|
      return
 | 
						|
    end
 | 
						|
    local win = create_floating_preview_window(state)
 | 
						|
    if not win then
 | 
						|
      self.active = false
 | 
						|
      return
 | 
						|
    end
 | 
						|
    winid = win.winid
 | 
						|
    is_neo_tree_window = false
 | 
						|
  else
 | 
						|
    winid, is_neo_tree_window = utils.get_appropriate_window(state)
 | 
						|
    self.bufnr = vim.api.nvim_win_get_buf(winid)
 | 
						|
  end
 | 
						|
 | 
						|
  if winid == self.winid then
 | 
						|
    return
 | 
						|
  end
 | 
						|
  self.winid, self.is_neo_tree_window = winid, is_neo_tree_window
 | 
						|
 | 
						|
  if self.active then
 | 
						|
    self:revert()
 | 
						|
    self:preview()
 | 
						|
  end
 | 
						|
end
 | 
						|
 | 
						|
---Activates the preview, but does not populate the preview window,
 | 
						|
function Preview:activate()
 | 
						|
  if self.active then
 | 
						|
    return
 | 
						|
  end
 | 
						|
  if not renderer.is_window_valid(self.winid) then
 | 
						|
    return
 | 
						|
  end
 | 
						|
  if self.config.use_float then
 | 
						|
    self.truth = {}
 | 
						|
  else
 | 
						|
    self.truth = {
 | 
						|
      bufnr = self.bufnr,
 | 
						|
      view = vim.api.nvim_win_call(self.winid, vim.fn.winsaveview),
 | 
						|
      options = {
 | 
						|
        bufhidden = vim.api.nvim_buf_get_option(self.bufnr, "bufhidden"),
 | 
						|
        foldenable = vim.api.nvim_win_get_option(self.winid, "foldenable"),
 | 
						|
      },
 | 
						|
    }
 | 
						|
    vim.api.nvim_buf_set_option(self.bufnr, "bufhidden", "hide")
 | 
						|
    vim.api.nvim_win_set_option(self.winid, "foldenable", false)
 | 
						|
  end
 | 
						|
  self.active = true
 | 
						|
  vim.api.nvim_win_set_var(self.winid, "neo_tree_preview", 1)
 | 
						|
end
 | 
						|
 | 
						|
---Set the buffer in the preview window without executing BufEnter or BufWinEnter autocommands.
 | 
						|
--@param bufnr number The buffer number of the buffer to set.
 | 
						|
function Preview:setBuffer(bufnr)
 | 
						|
  local eventignore = vim.opt.eventignore
 | 
						|
  vim.opt.eventignore:append("BufEnter,BufWinEnter")
 | 
						|
  vim.api.nvim_win_set_buf(self.winid, bufnr)
 | 
						|
  if self.config.use_float then
 | 
						|
    -- I'm not sufe why float windows won;t show numbers without this
 | 
						|
    vim.api.nvim_win_set_option(self.winid, "number", true)
 | 
						|
  end
 | 
						|
  vim.opt.eventignore = eventignore
 | 
						|
end
 | 
						|
 | 
						|
---Move the cursor to the previewed position and center the screen.
 | 
						|
function Preview:reveal()
 | 
						|
  local pos = self.start_pos or self.end_pos
 | 
						|
  if not self.active or not self.winid or not pos then
 | 
						|
    return
 | 
						|
  end
 | 
						|
  vim.api.nvim_win_set_cursor(self.winid, { (pos[1] or 0) + 1, pos[2] or 0 })
 | 
						|
  vim.api.nvim_win_call(self.winid, function()
 | 
						|
    vim.cmd("normal! zz")
 | 
						|
  end)
 | 
						|
end
 | 
						|
 | 
						|
---Highlight the previewed range
 | 
						|
function Preview:highlight()
 | 
						|
  if not self.active or not self.bufnr then
 | 
						|
    return
 | 
						|
  end
 | 
						|
  local start_pos, end_pos = self.start_pos, self.end_pos
 | 
						|
  if not start_pos and not end_pos then
 | 
						|
    return
 | 
						|
  elseif not start_pos then
 | 
						|
    start_pos = end_pos
 | 
						|
  elseif not end_pos then
 | 
						|
    end_pos = start_pos
 | 
						|
  end
 | 
						|
 | 
						|
  local highlight = function(line, col_start, col_end)
 | 
						|
    vim.api.nvim_buf_add_highlight(
 | 
						|
      self.bufnr,
 | 
						|
      neo_tree_preview_namespace,
 | 
						|
      highlights.PREVIEW,
 | 
						|
      line,
 | 
						|
      col_start,
 | 
						|
      col_end
 | 
						|
    )
 | 
						|
  end
 | 
						|
 | 
						|
  local start_line, end_line = start_pos[1], end_pos[1]
 | 
						|
  local start_col, end_col = start_pos[2], end_pos[2]
 | 
						|
  if start_line == end_line then
 | 
						|
    highlight(start_line, start_col, end_col)
 | 
						|
  else
 | 
						|
    highlight(start_line, start_col, -1)
 | 
						|
    for line = start_line + 1, end_line - 1 do
 | 
						|
      highlight(line, 0, -1)
 | 
						|
    end
 | 
						|
    highlight(end_line, 0, end_col)
 | 
						|
  end
 | 
						|
end
 | 
						|
 | 
						|
---Clear the preview highlight in the buffer currently in the preview window.
 | 
						|
function Preview:clearHighlight()
 | 
						|
  if type(self.bufnr) == "number" and vim.api.nvim_buf_is_valid(self.bufnr) then
 | 
						|
    vim.api.nvim_buf_clear_namespace(self.bufnr, neo_tree_preview_namespace, 0, -1)
 | 
						|
  end
 | 
						|
end
 | 
						|
 | 
						|
local toggle_state = false
 | 
						|
 | 
						|
Preview.hide = function()
 | 
						|
  toggle_state = false
 | 
						|
  if instance then
 | 
						|
    instance:revert()
 | 
						|
  end
 | 
						|
  instance = nil
 | 
						|
end
 | 
						|
 | 
						|
Preview.is_active = function()
 | 
						|
  return instance and instance.active
 | 
						|
end
 | 
						|
 | 
						|
Preview.show = function(state)
 | 
						|
  local node = state.tree:get_node()
 | 
						|
  if node.type == "directory" then
 | 
						|
    return
 | 
						|
  end
 | 
						|
 | 
						|
  if instance then
 | 
						|
    instance:findWindow(state)
 | 
						|
  else
 | 
						|
    instance = Preview:new(state)
 | 
						|
  end
 | 
						|
 | 
						|
  local extra = node.extra or {}
 | 
						|
  local position = extra.position
 | 
						|
  local end_position = extra.end_position
 | 
						|
  local path = node.path or node:get_id()
 | 
						|
  local bufnr = extra.bufnr or vim.fn.bufadd(path)
 | 
						|
 | 
						|
  if bufnr and bufnr > 0 and instance then
 | 
						|
    instance:preview(bufnr, position, end_position)
 | 
						|
  end
 | 
						|
end
 | 
						|
 | 
						|
Preview.toggle = function(state)
 | 
						|
  if toggle_state then
 | 
						|
    Preview.hide()
 | 
						|
  else
 | 
						|
    Preview.show(state)
 | 
						|
    if instance and instance.active then
 | 
						|
      toggle_state = true
 | 
						|
    else
 | 
						|
      Preview.hide()
 | 
						|
      return
 | 
						|
    end
 | 
						|
    local winid = state.winid
 | 
						|
    local source_name = state.name
 | 
						|
    local preview_event = {
 | 
						|
      event = events.VIM_CURSOR_MOVED,
 | 
						|
      handler = function()
 | 
						|
        if not toggle_state or vim.api.nvim_get_current_win() == instance.winid then
 | 
						|
          return
 | 
						|
        end
 | 
						|
        if vim.api.nvim_get_current_win() == winid then
 | 
						|
          log.debug("Cursor moved in tree window, updating preview")
 | 
						|
          Preview.show(state)
 | 
						|
        else
 | 
						|
          log.debug("Neo-tree window lost focus, disposing preview")
 | 
						|
          Preview.hide()
 | 
						|
        end
 | 
						|
      end,
 | 
						|
      id = "preview-event",
 | 
						|
    }
 | 
						|
    instance:subscribe(source_name, preview_event)
 | 
						|
  end
 | 
						|
end
 | 
						|
 | 
						|
Preview.focus = function()
 | 
						|
  if Preview.is_active() then
 | 
						|
    vim.fn.win_gotoid(instance.winid)
 | 
						|
  end
 | 
						|
end
 | 
						|
 | 
						|
return Preview
 |