This commit is contained in:
2026-10-31 12:18:07 +03:00
parent 16e88117d5
commit e8e2d25600
9 changed files with 568 additions and 9 deletions
+78 -1
View File
@@ -53,6 +53,13 @@ print("[lua] init.lua выполнен")
-- app:set_maximized(true/false)
-- app:minimize()
-- app:is_maximized()
-- app:open_input(options) -- плавающее поле ввода чуть выше центра;
-- -- options = { title = "...",
-- -- placeholder = "...",
-- -- callback = function(text) ... end };
-- -- Enter подтверждает и вызывает callback,
-- -- Esc или клик вне окна закрывают без него;
-- -- пока окно открыто, привязки клавиш молчат
--
-- Редактор app.editor (номера вкладок — с нуля):
-- app.editor:tabs() -- {{ index = 0, title = "main.rs",
@@ -292,6 +299,16 @@ end)
app:map_key("", "<C-q>", function() app:close() end)
-- Плавающее поле ввода. Пока оно открыто, сочетания клавиш приложения
-- заблокированы; Enter вызывает callback, Esc и клик вне окна — отменяют.
app:map_key("", "<C-g>", function()
app:open_input({
-- title = "Открыть файл",
placeholder = "src/main.rs",
callback = function(text) app.editor:open(text, {}) end,
})
end)
app:map_key("", "<C-e>", "toggle_left_panel")
app:map_key("", "<C-t>", "toggle_bottom_panel")
@@ -323,9 +340,48 @@ local function diagnostic_rank(diagnostic)
or 1
end
-- Строки активной вкладки, занятые иконками диагностики. Gutter действует
-- только на активную вкладку, поэтому запоминаем поставленные строки, чтобы
-- при следующем обновлении снять устаревшие иконки и не трогать остальные.
local diagnostic_gutter = {}
local function active_tab_title()
local active = app.editor:active_tab()
for _, tab in ipairs(app.editor:tabs()) do
if tab.index == active then
return tab.title
end
end
return nil
end
-- Заголовок вкладки — путь, которым открыли файл (обычно относительный), а LSP
-- присылает абсолютный путь. Сверяем полный путь с хвостом заголовка.
local function path_matches_title(path, title)
if not path or not title then
return false
end
path = path:gsub("\\", "/")
title = title:gsub("\\", "/")
if path == title then
return true
end
local suffix = "/" .. title
return #path > #suffix and path:sub(-#suffix) == suffix
end
app.editor:on_lsp_diagnostics(100, function(servers)
diagnostics_tree:clear()
-- Иконки прошлого обновления активной вкладки могли устареть.
local title = active_tab_title()
if title and diagnostic_gutter[title] then
for line in pairs(diagnostic_gutter[title]) do
app.editor:clear_gutter_icon(line)
end
diagnostic_gutter[title] = nil
end
-- Сначала собираем диагностику по файлам: одинаковые проблемы от разных
-- серверов попадают в одну запись.
local files = {}
@@ -383,9 +439,19 @@ app.editor:on_lsp_diagnostics(100, function(servers)
end
end
-- Подсветка и gutter в редакторе относятся к активной вкладке, поэтому
-- иконки ставим только для её файла.
local active = title ~= nil and path_matches_title(path, title)
local gutter_lines = active and {} or nil
local errors = {}
for index, key in ipairs(group_order) do
local group = groups[key]
local icon = severity_icons[group.severity] or "circle-alert"
if active then
app.editor:set_gutter_icon(group.line, icon)
gutter_lines[group.line] = true
end
errors[#errors + 1] = {
-- Префикс отделяет позицию от id файла, даже если в пути есть ':'.
id = string.format(
@@ -401,10 +467,21 @@ app.editor:on_lsp_diagnostics(100, function(servers)
group.character + 1,
table.concat(group.messages, "; ")
),
icon = severity_icons[group.severity] or "circle-alert",
icon = icon,
}
end
if active and next(gutter_lines) then
local stored = diagnostic_gutter[title]
if not stored then
stored = {}
diagnostic_gutter[title] = stored
end
for line in pairs(gutter_lines) do
stored[line] = true
end
end
diagnostics_tree:append({
{
id = path,