Создайте временный буфер только для чтения для тестового вывода

Я хочу создать плагин Neovim, который автоматически запускает набор тестов всякий раз, когда файл сохраняется. Вот обзор:

  1. Если я сохраню файл Rust, запустите cargo test
  2. Если буфер для тестового вывода не открыт, автоматически создайте буфер
  3. Пометить этот буфер только для чтения
  4. Если я сохраню другой файл, повторно использовать существующий буфер
  5. Если буфер закрыт (например, :q), создайте новый буфер при следующем запуске теста.

Однако в настоящее время я сталкиваюсь с тремя проблемами:

  1. Я не могу определить, когда я выхожу из буфера
  2. Когда тестовый вывод длиннее высоты буфера, буфер не будет прокручиваться вниз
  3. Когда я хочу выйти из Neovim, он просит меня сохранить все эти временные буферы (чего я делать не хочу)

Как я могу решить эти проблемы? Для справки, вот мой код:

local buffer_number = -1

local function log(_, data)
    if data then
        vim.api.nvim_buf_set_lines(buffer_number, -1, -1, true, data)
    end
end

local function open_buffer()
    if buffer_number == -1 then
        vim.api.nvim_command('botright vnew')
        buffer_number = vim.api.nvim_get_current_buf()
    end
end

local function autotest(pattern, command)
    vim.api.nvim_create_autocmd("BufWritePost", {
        group = vim.api.nvim_create_augroup("autotest", { clear = true }),
        pattern = pattern,
        callback = function()
            open_buffer()
            vim.api.nvim_buf_set_lines(buffer_number, 0, -1, true, {})
            vim.fn.jobstart(command, {
                stdout_buffered = true,
                on_stdout = log,
                on_stderr = log,
            })
        end
    })
end

autotest("*.rs", { "cargo", "test" })

P.S. Я знаю, что есть несколько существующих плагинов для тестирования. Я создаю свой собственный, потому что хочу научиться писать плагины для neovim.

«Если буфер закрыт (например, :q)», то «Когда я хочу выйти из Neovim, он просит меня сохранить все эти временные буферы (чего я не хочу делать)» => используйте :q! вместо :q для каждый буфер и :qa! для всех буферов. Однако, поскольку он просит вас сохранить, это означает, что буферы были изменены (должно быть что-то, что вы делаете неправильно?)

gildux 26.01.2023 02:42
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
3
1
111
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Я приложил все усилия. Я считаю, что это отвечает на ваши вопросы и делает то, что вы стремитесь сделать.

local buffer_number = -1

local function log(_, data)
    if data then
        -- Make it temporarily writable so we don't have warnings.
        vim.api.nvim_buf_set_option(buffer_number, "readonly", false)
        
        -- Append the data.
        vim.api.nvim_buf_set_lines(buffer_number, -1, -1, true, data)

        -- Make readonly again.
        vim.api.nvim_buf_set_option(buffer_number, "readonly", true)

        -- Mark as not modified, otherwise you'll get an error when
        -- attempting to exit vim.
        vim.api.nvim_buf_set_option(buffer_number, "modified", false)

        -- Get the window the buffer is in and set the cursor position to the bottom.
        local buffer_window = vim.api.nvim_call_function("bufwinid", { buffer_number })
        local buffer_line_count = vim.api.nvim_buf_line_count(buffer_number)
        vim.api.nvim_win_set_cursor(buffer_window, { buffer_line_count, 0 })
    end
end

local function open_buffer()
    -- Get a boolean that tells us if the buffer number is visible anymore.
    --
    -- :help bufwinnr
    local buffer_visible = vim.api.nvim_call_function("bufwinnr", { buffer_number }) ~= -1

    if buffer_number == -1 or not buffer_visible then
        -- Create a new buffer with the name "AUTOTEST_OUTPUT".
        -- Same name will reuse the current buffer.
        vim.api.nvim_command("botright vsplit AUTOTEST_OUTPUT")
        
        -- Collect the buffer's number.
        buffer_number = vim.api.nvim_get_current_buf()
        
        -- Mark the buffer as readonly.
        vim.opt_local.readonly = true
    end
end

function autotest(pattern, command)
    vim.api.nvim_create_autocmd("BufWritePost", {
        pattern = pattern,
        callback = function()
            -- Open our buffer, if we need to.
            open_buffer()
        
            -- Clear the buffer's contents incase it has been used.
            vim.api.nvim_buf_set_lines(buffer_number, 0, -1, true, {})

            -- Run the command.
            vim.fn.jobstart(command, {
                stdout_buffered = true,
                on_stdout = log,
                on_stderr = log,
            })
        end
    })
end

autotest("*.rs", { "cargo", "test" })

Я добавил несколько комментариев, чтобы помочь объяснить каждый шаг, но конкретно для каждой из ваших проблем:

  1. Я не могу определить, когда я выхожу из буфера

Поскольку у вас уже есть номер буфера, вы можете запросить, виден ли он. Просто используя одно и то же имя при создании нового буфера, мы повторно используем любые существующие.

  1. Когда тестовый вывод длиннее высоты буфера, буфер не будет прокручиваться вниз

Это было сложно, и я не уверен, что это лучший способ, но я смог запросить, сколько строк было в буфере, и установить курсор окна буфера внизу.

  1. Когда я хочу выйти из Neovim, он просит меня сохранить все эти временные буферы (чего я делать не хочу)

Это связано с тем, что буферы изменены. Neovim по умолчанию не хочет упрощать случайную потерю вашей работы, если у вас есть активные модификации. Чтобы обойти это, мы можем легко отметить, что он не изменен!

Надеюсь, это поможет.

Другие вопросы по теме