Files
outline.nvim/lua/outline/view.lua
27Onion Nebell 5779c6f6a7 fix: migrating to 0.11
fix: migrating to 0.11

fix: migrating to 0.11

fix: migrating to 0.11
2025-04-12 00:34:23 +08:00

145 lines
5.2 KiB
Lua

local cfg = require('outline.config')
local highlight = require('outline.highlight')
---@class outline.View
local View = {}
---@class outline.View
---@field buf integer
---@field win integer
function View:new()
return setmetatable({ buf = nil, win = nil }, { __index = View })
end
---Creates the outline window and sets it up
---@param split_command string A valid split command that is to be executed in order to create the view.
function View:setup_view(split_command)
-- create a scratch unlisted buffer
self.buf = vim.api.nvim_create_buf(false, true)
-- set filetype
vim.api.nvim_set_option_value('filetype', 'Outline', { buf = self.buf })
-- delete buffer when window is closed / buffer is hidden
vim.api.nvim_set_option_value('bufhidden', 'delete', { buf = self.buf })
-- create a split
vim.cmd(split_command)
-- get current (outline) window and attach our buffer to it
self.win = vim.api.nvim_get_current_win()
vim.api.nvim_win_set_buf(self.win, self.buf)
-- resize if split_command not specify width like "25vsplit"
if split_command:match('%d+') == nil then
-- resize to a % of the current window size
vim.cmd('vertical resize ' .. cfg.o.outline_window.width)
end
-- window stuff
vim.api.nvim_set_option_value('spell', false, { win = self.win })
vim.api.nvim_set_option_value('signcolumn', 'no', { win = self.win })
vim.api.nvim_set_option_value('foldcolumn', '0', { win = self.win })
vim.api.nvim_set_option_value('number', false, { win = self.win })
vim.api.nvim_set_option_value('relativenumber', false, { win = self.win })
vim.api.nvim_set_option_value('winfixwidth', true, { win = self.win })
vim.api.nvim_set_option_value('list', false, { win = self.win })
vim.api.nvim_set_option_value('wrap', cfg.o.outline_window.wrap, { win = self.win })
vim.api.nvim_set_option_value('winhl', cfg.o.outline_window.winhl, { win = self.win })
vim.api.nvim_set_option_value('linebreak', true, { win = self.win }) -- only has effect when wrap=true
vim.api.nvim_set_option_value('breakindent', true, { win = self.win }) -- only has effect when wrap=true
-- Would be nice to use guides.markers.vertical as part of showbreak to keep
-- continuity of the tree UI, but there's currently no way to style the
-- color, apart from globally overriding hl-NonText, which will potentially
-- mess with other theme/user settings. So just use empty spaces for now.
vim.api.nvim_set_option_value('showbreak', ' ', { win = self.win }) -- only has effect when wrap=true.
-- buffer stuff
local tab = vim.api.nvim_get_current_tabpage()
vim.api.nvim_buf_set_name(self.buf, 'OUTLINE_' .. tostring(tab))
vim.api.nvim_set_option_value('modifiable', false, { buf = self.buf })
if cfg.o.outline_window.show_numbers or cfg.o.outline_window.show_relative_numbers then
vim.api.nvim_set_option_value('nu', true, { win = self.win })
end
if cfg.o.outline_window.show_relative_numbers then
vim.api.nvim_set_option_value('rnu', true, { win = self.win })
end
local cl = cfg.o.outline_window.show_cursorline
if cl == true or cl == 'focus_in_outline' then
vim.api.nvim_set_option_value('cursorline', true, { win = self.win })
end
end
---Close view window and remove winnr/bufnr fields
function View:close()
if self.win then
local windows = vim.api.nvim_list_wins()
local win_count = #windows
if win_count == 1 then
vim.api.nvim_command('q')
else
vim.api.nvim_win_close(self.win, true)
self.win = nil
self.buf = nil
end
end
end
---Return whether view has valid buf and win numbers
function View:is_open()
return self.win
and self.buf
and vim.api.nvim_buf_is_valid(self.buf)
and vim.api.nvim_win_is_valid(self.win)
end
---Replace all lines in buffer with given new `lines`
---@param lines string[]
function View:rewrite_lines(lines)
if self.buf and vim.api.nvim_buf_is_valid(self.buf) then
vim.api.nvim_set_option_value('modifiable', true, { buf = self.buf })
vim.api.nvim_buf_set_lines(self.buf, 0, -1, false, lines)
vim.api.nvim_set_option_value('modifiable', false, { buf = self.buf })
end
end
function View:clear_all_ns()
if self.buf then
highlight.clear_all_ns(self.buf)
end
end
---Ensure all existing highlights are already cleared before calling!
---@param hl outline.HL[]
---@param nodes outline.FlatSymbol[]
---@param details string[]
---@param linenos string[]
function View:add_hl_and_ns(hl, nodes, details, linenos)
highlight.items(self.buf, hl)
if cfg.o.outline_items.highlight_hovered_item then
highlight.hovers(self.buf, nodes)
end
if cfg.o.outline_items.show_symbol_details then
highlight.details(self.buf, details)
end
-- Note on hl_mode:
-- When hide_cursor + cursorline enabled, we want the lineno to also take on
-- the cursorline background so wherever the cursor is, it appears blended.
-- We want 'replace' even for `hide_cursor=false cursorline=true` because
-- vim's native line numbers do not get highlighted by cursorline.
if cfg.o.outline_items.show_symbol_lineno then
-- stylua: ignore start
highlight.linenos(
self.buf, linenos,
(cfg.o.outline_window.hide_cursor and 'combine') or 'replace'
)
-- stylua: ignore end
end
end
return View