ej-shafran / compile-mode.nvim

A plugin for Neovim inspired by Emacs' Compilation Mode
The Unlicense
50 stars 12 forks source link

Compilation buffer not opening right #16

Closed uuuulopta closed 4 months ago

uuuulopta commented 4 months ago

The problem

When the buffer_name is set to the default "*compilation*", the compilation buffer opens in the current buffer I'm editing, overwriting it meaning I can't edit the file until I restart neovim.

Expected behaviour

By reading the code and README the expected behaviour should be that if the compilation window is not open it should open in a split window

Debug

I have added some debug outputs in the M.split_unless_open inside lua/compile-mode/utils.lua file, and here are the outputs I get when the buffer_name is set to *compilation* versus compilation :

config = {
  buffer_name = "*compilation*",
...} // I trimmed the rest, irrelevant info
== compile() ==
== runcommand() ==
== opening compilation buffer ==
buffer_name*compilation*
==split_unless_open==
All buffers: 
  1 %a   "lua\compile-mode\utils.lua"   line 28
Initial bufnum: 1
winunum1
bufnr = 1
== running command: `make` ==
== runjob() ==
== starting job ==
job_id = 4

As you can see, even though the only buffer open is utils.lua it incorrectly thinks that it's the buffer named compilation

Now here is the output when I change the buffer_name to compilation

config = {
  buffer_name = "compilation",
... } // I trimmed the rest, irrelevant info
== compile() ==
== runcommand() ==
== opening compilation buffer ==
buffer_namecompilation
==split_unless_open==
All buffers: 
  1 %a + "lua\compile-mode\utils.lua"   line 28
Initial bufnum: -1
winunum-1
bufnr = 26
== running command: `make` ==
== runjob() ==
== starting job ==

It is working as expected.

If we look at this line in M.split_unless_open:

local bufnum = M.bufnr(vim.fn.expand(fname))

We see that it is calling vim.fn.expand . Here are the outputs of vim.fn.expand when i put " *compilation* " and " compilation " as its input

vim.fn.expand("*compilation*") // returns ""
vim.fn.expand("compilation") // returns compilation

Now, when "" or nothing is passed into bufnr function it always returns the buffer that is currently selected.

Even when vim.fn.expand functions are removed, so that fname is purely passed into bufnr you cannot do command :split *compilation* as it leads to an error of E480: no match: *compilation* .

The potential solution I found to allow the asterisk in the names is to ditch the expand function, use :h bufadd which adds the buffer with the exact name and returns the id of the buffer. After which you can use :h sbuffer to split to a buffer number. This way bufnr would return the correct buffer.

Windows 11 NVIM v0.9.4 Nightly branch

uuuulopta commented 4 months ago

Also, I suppose that you don't have this issue. Would be interesting to see how these debugs print out for you, I wonder what is breaking it on my machine in comparison to yours.

ej-shafran commented 4 months ago

How strange! I presume it has something to do with the fact that you're on windows while I'm on Linux. Am at work right now, will give this a deeper look later tonight. Thanks for your patience!

ej-shafran commented 4 months ago

Hi, sorry for the delay in my response

I've tried using bufadd as you suggested - mind checking the nightly branch and seeing if it works for you right now?

uuuulopta commented 4 months ago

You forgot to split using :sb.

function M.split_unless_open(fname, smods, count)
    local bufnum = vim.fn.bufadd(fname)

    if smods.hide then
        return bufnum
    end

    local winnum = vim.fn.bufwinnr(bufnum)

    if winnum == -1 then
        local cmd = tostring(bufnum)
        if smods.vertical then
            cmd = "vert sb" .. cmd
        else
            cmd = "sb" .. cmd
        end

        if smods.split and smods.split ~= "" then
            cmd = smods.split .. " " .. cmd
        end

        vim.cmd(cmd)

        if count ~= 0 and count ~= nil then
            vim.cmd("resize" .. count)
        end
    end

    return bufnum
end

At the end I added the command to resize the window if a count has been set, because unlike :split, :sb doesn't use the count for resizing. Functionally this should be completely same.

ej-shafran commented 4 months ago

I've applied the changes you mentioned. You can check it out on the nightly or latest branch - both should work