David-Kunz / gen.nvim

Neovim plugin to generate text using LLMs with customizable prompts
The Unlicense
992 stars 64 forks source link

Output window remains blank #32

Closed siblanco closed 8 months ago

siblanco commented 8 months ago

hi there,

thanks for the plugin!

I am trying it out but - unfortunately - cannot get ollamas output to display inside of nvim. Running the commands the plugin runs in my terminal directly, everything works fine.

Here's a mp4: https://storage.siblanco.dev/gen-nvim.mp4

Neovim version:

NVIM v0.9.4
Build type: Release
LuaJIT 2.1.1692716794

Any idea how I could debug this further? Please, let me know what else I could provide.

dmitriypereverza commented 8 months ago

i have the same error

stefano-regosa-deel commented 8 months ago

Same here !

kapral18 commented 8 months ago

Same

macukadam commented 8 months ago

I also had the same issue on my system:

Ubuntu 22.04.3 LTS Alacritty 0.13.0-dev NVIM v0.10.0-dev

After debugging for a while. I've fixed it by setting pyt=true. Below is the full code.

    job_id = vim.fn.jobstart(cmd, {
        on_stdout = function(_, data, _)
            -- window was closed, so cancel the job
            if not vim.api.nvim_win_is_valid(float_win) then
                vim.fn.jobstop(job_id)
                return
            end
            -- Remove carriage returns from each line
            for i, line in ipairs(data) do
                data[i] = line:gsub('\r', '')
            end
            result_string = result_string .. table.concat(data, '\n')
            lines = vim.split(result_string, '\n', true)
            vim.api.nvim_buf_set_lines(result_buffer, 0, -1, false, lines)
            vim.api.nvim_win_call(float_win, function()
                vim.fn.feedkeys('$')
            end)
        end,
        on_stderr = function(_, data, _)
            if opts.debugCommand then
                -- window was closed, so cancel the job
                if not vim.api.nvim_win_is_valid(float_win) then
                    vim.fn.jobstop(job_id)
                    return
                end
                result_string = result_string .. table.concat(data, '\n')
                lines = vim.split(result_string, '\n', true)
                vim.api.nvim_buf_set_lines(result_buffer, 0, -1, false, lines)
                vim.api.nvim_win_call(float_win, function()
                    vim.fn.feedkeys('$')
                end)
            end
        end,
        stderr_buffered = opts.debugCommand,
        pty = true,
        on_exit = function(a, b)
            if b == 0 and opts.replace then
                if extractor then
                    local extracted = result_string:match(extractor)
                    if not extracted then
                        vim.cmd('bd ' .. result_buffer)
                        return
                    end
                    lines = vim.split(extracted, '\n', true)
                end
                lines = trim_table(lines)
                vim.api.nvim_buf_set_text(curr_buffer, start_pos[2] - 1,
                    start_pos[3] - 1, end_pos[2] - 1,
                    end_pos[3] - 1, lines)
                vim.cmd('bd ' .. result_buffer)
            end
        end
    })
    vim.keymap.set('n', '<esc>', function() vim.fn.jobstop(job_id) end,
        { buffer = result_buffer })

    vim.api.nvim_buf_attach(result_buffer, false,
        { on_detach = function() result_buffer = nil end })
end

Nvim help for jobstart() states: pty: (boolean) Connect the job to a new pseudo terminal, and its streams to the master file descriptor. on_stdout receives all output, on_stderr is ignored.

Hope it helps.

kjjuno commented 8 months ago

Does this code work for you? https://github.com/kjjuno/gen.nvim

This is the code for https://github.com/David-Kunz/gen.nvim/pull/31

and I believe it will fix this issue

stefano-regosa-deel commented 8 months ago

I managed to make it work with this config and Docker running !

return {
  "David-Kunz/gen.nvim",
  config = function()
    vim.keymap.set("v", "<leader>gn", ":Gen<CR>")
    vim.keymap.set("n", "<leader>gn", ":Gen<CR>")
    require("gen").model = "mistral:instruct"
    require("gen").container = "ollama"
  end,
}
corsettiDev commented 8 months ago

Does this code work for you? https://github.com/kjjuno/gen.nvim

This is the code for #31

and I believe it will fix this issue

I'm having the same issue and this fork did not solve the issue for me.

kjjuno commented 8 months ago

After I posted that I realized I hadn’t addressed your issue. Are you on Linux?

Ghasak commented 8 months ago

I am using Mac and still having an empty buffer! Any new update on this issue! The plug-in was working flawlessly last week!

corsettiDev commented 8 months ago

I'm using Mac as well, Sonoma 14.0

dmitriypereverza commented 8 months ago

Maybe it's related to output buffering

siblanco commented 8 months ago

Does this code work for you? https://github.com/kjjuno/gen.nvim

This is the code for #31

and I believe it will fix this issue

This works, it opens the output in a new split window and actually outputs stuff...I like it, thank you. Btw. I am on arch linux using kitty 0.31.0

edit: Ok after trying the default change code prompt, it outputs to the new split and then just closes it, without actually changing anything.

kapral18 commented 8 months ago

I tried all suggestions above and none fully work. Most don't. Some fix this specific problem but break everything else or mess up the output. I also tried to use earlier commit versions, still unsuccessfully. @David-Kunz do you by chance experience this problem as well?

hampgoodwin commented 8 months ago

I'm actively trying to debug this, but I am fairly new to nvim, like most of us here 😂 . I've enabled dev for this and am doing iterations testing this out.

So far I suspect something with the buffer, as suggested by @dmitriypereverza . I have attempted both my local dev plugin and the official David-Kunz/gen.nvim plugin and getting nothing in the buffer after running the Ask prompt.

I am testing by:

  1. Calling vim user command :Gen ( i do this both via keymap and typing :Gen, since I saw in another issue some folks were having trouble which these)
  2. Providing a simple prompt like "what is 2+2?"
  3. Waiting some time (maybe ~30 seconds)
  4. running the vim command :%p
  5. Seeing E749: Empty buffer whithin the context of the new floating window that was created.

Going to continue to iterate; I suspect either gen.nvim buffer setup is an issue (less likely because it seems to work for some people), or that I have some kind of conflicting buffer in my setup.


For ref, my nvim configuration is based on kickstart.nvim; I have a few additions but they're fairly light and only one place where I an creating a buffer.

ch-tactica commented 8 months ago

@macukadam's fix worked for me, however the ollama startup spinner seems to be adding a bunch of braille glyphs into my buffer, I can possibly live with this... 🤣

hampgoodwin commented 8 months ago

Ooh, thankyou @macukadam and @ch-tactica ,. This a at least some progress. Like ch-tactica has mentioned, I now get all the braille indicating that the response is processing.

For those who are less experienced like me, I accomplished this by setting the plugin to dev mode against a local clone of this repo, then modified the code in the init.lua file in the repo, as mentioned by @macukadam .

Going to work with this a bit more.

ch-tactica commented 8 months ago

Makes me think, maybe something changed with the way ollama returns output that is causing things to break, I've had to update a billion things within the past 48 hours and I wouldn't be surprised if some ollama updates snuck in there. They did have a release a few days ago, looks like they did make some changes to ollama run in particular:

https://github.com/jmorganca/ollama/releases/tag/v0.1.10

hampgoodwin commented 8 months ago

Ooh, great thinking. I will attempt to downgrade my ollama version to maybe a month ago, and rerun it without the pty modification to see if that helps.

hampgoodwin commented 8 months ago

I just downgraded to ollama@0.1.5 (from about a month ago) and it works exactly as expected; so I think you're correct that this is a difference in how ollama writes to stdout.


SO, I would say for now if anyone is having trouble it's safe to attempt downgrading your ollama version by downloading an older version from ollama github? I'll try to poke around tonight/tomorrow to see if I can figure out the stdout/output for the latest version ollama@v0.1.10 before someone else more knowledgeable beats me to it.

yesidrs commented 8 months ago

You have all the reason the problem is the version of Ollama, then now if we want to use the latest releases then we must await an update in the gen.nvim that solve the recent incompatibility with the output. but now the problems is, how prevent that ollama updates automatically XD

hampgoodwin commented 8 months ago

Yeah. I'll see what I can do. As @ch-tactica has mentioned, v0.1.10 has added wordwrap updates; so I am going to attempt to add a run opt of --nowordwrap to the cmd with v0.1.10 ollama and see if that helps. This will probably be the last thing I can do for today.

kjjuno commented 8 months ago

I have a PR up that adds conversation support. In order to add that I had to switch to the REST api. I think that might be the better direction anyway.

stefanadelbert commented 8 months ago

Using the ollama REST API seems like a good way to do this kind of integration. Good call.

stefanadelbert commented 8 months ago

Although... I've been looking at how to make a POST request from a lua neovim plugin and it's really not obvious! One recommendation is to use rest-nvim/rest.nvim, which seems like an overkill. Generally speaking, you could use socket.http, but that's not available from a lua neovim plugin and I think that's because it's not part of the lua standard library. Any ideas?

David-Kunz commented 8 months ago

Hi,

With the latest update of ollama, I can reproduce this issue. I'll have a look.

hampgoodwin commented 8 months ago

@David-Kunz I suspect something with how we're detecting on_stdout is part of the problem. Just as a test to see if we were getting anything on std out, I was attemting to nvim_buf_set_lines with just a hardcoded table of string, and nothing was ever written to the screen.

I suspect the way that ollama detects where the cmd is being ran from and how it subsequently creates output may have something to do with it.

I am not in the code right now but I vaguely remember parsing on carriage return and then writing to the screen in gen.nvvim? Perhaps we're no longer getting that carriage return character, and only and EOF symbol once it's completed?

OK, I have to go to work for the day :)

David-Kunz commented 8 months ago

Thank you, @hampgoodwin , yes, that's also what I saw. None of the channel callbacks are called. I tried the ollama --nowordwrap flag (since someone above mentioned that it might have something to do with that change), without success.

I will check the carriage return proposal, thank you!

hampgoodwin commented 8 months ago

Thank you, @hampgoodwin , yes, that's also what I saw. None of the channel callbacks are called. I tried the ollama --nowordwrap flag (since someone above mentioned that it might have something to do with that change), without success.

I will check the carriage return proposal, thank you!

I did notice that the nowordwrap flag is not taken into account if ollama believes the data is coming from a piped command, which is possible since I believe jobstart is not ran 'as a terminal', hence why adding pty=true, may have gotten the values actually writing.

These are all wild assumptions on my end, I'm very new to Lua. Thank you for this rad plugin and I'll continue to try to help where I can.

hampgoodwin commented 8 months ago

OH, I bet that is it.. I bet we need to set pty=true, on_stdout filter the progress symbols, and then write any other symbols... Let me know if you think that is a good path; if someone else is unable to get a start on this before I'm off work I will get started and see how that pans out.

David-Kunz commented 8 months ago

That did the trick, @hampgoodwin .

    job_id = vim.fn.jobstart(cmd, {
+        pty = true,

Now, I get the result, but also ANSI escape codes.

David-Kunz commented 8 months ago

I'm thinking of making all of this simpler and just spawn a

:te ollama run ...

That also works.

hampgoodwin commented 8 months ago

Awesome! Let me know if you make a PR and want second eyes on it or want me to test the changes.


edit:

I'm not sure that with :te if we need to filter out escape codes and the progress bar symbols? The progress symbols are here and the termination symbols are here.

David-Kunz commented 8 months ago

Thank you, @hampgoodwin !

The following works:

    vim.api.nvim_buf_call(result_buffer, function()
      vim.fn.termopen(cmd, {
        on_exit = function(a, b)
          if b == 0 and opts.replace then
              local lines = trim_table(vim.api.nvim_buf_get_lines(result_buffer, 0, -1, false))
              local text = table.concat(lines, '\n')
              if extractor then
                  local extracted = text:match(extractor)
                  if not extracted then
                      vim.cmd('bd ' .. result_buffer)
                      return
                  end
                  lines = vim.split(extracted, '\n', true)
              end
              vim.api.nvim_buf_set_text(curr_buffer, start_pos[2] - 1,
                                        start_pos[3] - 1, end_pos[2] - 1,
                                        end_pos[3] - 1, lines)
              vim.cmd('bd ' .. result_buffer)
          end
        end
      })
    end)

but now the result is not displayed in markdown highlighting :(

David-Kunz commented 8 months ago

I merged it into main: https://github.com/David-Kunz/gen.nvim/commit/501fe1f7ef801efa26e9c446ba58ab51e8cfedf7

It would be great, if you could test it, @hampgoodwin ! Now, I need to figure out how to solve the markdown highlighting with termopen.

David-Kunz commented 8 months ago

So set syntax=on give me at lest some syntax highlighting, not based on Tree-Sitter though. Before, it was enough to do set filetype=markdown.

hampgoodwin commented 8 months ago

I will check it out; I have treesitter and markdown installed for it. Would this be when you attempt to replace some buffer text with a prompt suggestion? (I have not used that feature yet, only Ask)

David-Kunz commented 8 months ago

Thank you, @hampgoodwin !

Whenever the window opens to show the generated text, it should be properly highlighted with Tree-Sitter, but that's currently not the case. The best I could do for now is set syntax=on, but that doesn't use Tree-Sitter. I'll need to do more investigations.

Screenshot 2023-11-20 at 19 20 10

hampgoodwin commented 8 months ago

I see; I had not noticed syntax highlighting before, but I haven't been using the plugin. I experience the same.

Should we close this issue since we're able to get output on the screen and start another issue for this?

Also, if you have time sometime this week I'd enjoy discussing where you see the project going and where I could contribute to your vision of it.

image

edit: I experience the same with set filetype=markdown and set syntax=on (then with off, ofc no highlighting at all).

hampgoodwin commented 8 months ago

I bet we're losing the treesitter highlighting because we're launching it as a pseudoterminal, instead of as a codeeditor window? That could cause nvim to not load some things? I guess, because technically it is 'not' neovim, but a terminal? I'm out of my depth here :D

David-Kunz commented 8 months ago

Thanks a lot, @hampgoodwin ! It would be fantastic to talk with you and share ideas!