jbyuki / one-small-step-for-vimkind

Debug adapter for Neovim plugins
MIT License
409 stars 11 forks source link

Can't start lua debugger on init.lua #52

Open lervag opened 3 months ago

lervag commented 3 months ago

This is closely related to #47. I've added the following snippet to the top of my init.lua file:

vim.opt.runtimepath:prepend "~/.local/plugged/one-small-step-for-vimkind/"
if vim.env.DO_DEBUG then
  require "osv".launch { port=8086, blocking=true }
end

local x = 1
-- additional content below ...

Running DO_DEBUG=1 nvim in one terminal now blocks and waits for a connection. Cool.

However, I now open my init.lua in another terminal. I add a breakpoint to the local x = 1 line. Then I connect to the debuggee. It does attach, as expected, but the breakpoint does not work. In fact, any breakpoint in my init.lua or from scripts sourced/required will not work directly.

Breakpoints related to things happening after sourcing the init.lua scripts do work. E.g., given this snippet from my init scripts:

vim.api.nvim_create_autocmd({ "VimEnter", "FileType" }, {
  desc = "Go to last known position on buffer open",
  group = group,
  callback = function()
    local mark = vim.api.nvim_buf_get_mark(0, '"')
    local buf_lines = vim.api.nvim_buf_line_count(0)

    if mark[1] > 0 and mark[1] <= buf_lines then
      pcall(vim.api.nvim_win_set_cursor, 0, mark)
    end

    if vim.o.foldlevel == 0 then
      vim.cmd [[normal! zM]]
    end

    vim.cmd [[normal! zvzz]]
  end,
})

Adding a breakpoint to the first line does not work. But if I add a breakpoint to the callback, it works as expected.

I am curious if this is the expected behaviour?

As far as I can see, I've configured things as suggested in the docs. My full config is here: https://github.com/lervag/dotnvim/.

jbyuki commented 3 months ago

Thanks for raising this issue. This is not expected, but it's also a brand new feature with few feedback so it may break easily.

What do you get when running with logging enabled ? I'm curious to see if it attaches well.

Quickly skimming through the dotfiles I saw:

{
"mfussenegger/nvim-dap",
event = "BufReadPost",
dependencies = {
  {
    "theHamsta/nvim-dap-virtual-text",
    dependencies = { "nvim-treesitter/nvim-treesitter" },
    config = true,
  },
  {
    "LiadOz/nvim-dap-repl-highlights",
    config = true,
  },
  "jbyuki/one-small-step-for-vimkind",
},

I'm not too familiar with lazy.nvim but could it be that it's because of the BufReadPost event or is that completely unrelated?

It would be interesting to see if it's because of that so I can add it as a warning for future users.

lervag commented 3 months ago

I've tested it some more. With my own configuration, I find it sometimes work as expected, and sometimes not. If I avoid the lazy loading, it seems to work more often (but not always). So, it feels like this may have something to do with the connection.

I'll look into the log files now and I'll post it here if it seems relevant.

jbyuki commented 3 months ago

Yes, that sounds like a race condition. Some better understanding on how lazy.nvim loads its plugin could be useful. I will test if I can reproduce it with lazy.nvim installed.

On Wed, 14 Aug 2024, 12:22 am Karl Yngve Lervåg, @.***> wrote:

I've tested it some more. With my own configuration, I find it sometimes work as expected, and sometimes not. If I avoid the lazy loading, it seems to work more often (but not always). So, it feels like this may have something to do with the connection.

I'll look into the log files now and I'll post it here if it seems relevant.

— Reply to this email directly, view it on GitHub https://github.com/jbyuki/one-small-step-for-vimkind/issues/52#issuecomment-2287241472, or unsubscribe https://github.com/notifications/unsubscribe-auth/ALJBOFMKWKENPE2PHB3RL4LZRKBL3AVCNFSM6AAAAABMOFCV2GVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZDEOBXGI2DCNBXGI . You are receiving this because you commented.Message ID: @.***>

lervag commented 3 months ago

Here's a minimal init.lua that uses lazy.nvim to load things:

if vim.env.DEBUG then
  vim.opt.runtimepath:prepend ".lazy/plugins/one-small-step-for-vimkind"
  require "osv".launch { port = 8086, blocking = true }
end

vim.g.mapleader = " "

local root = vim.fn.fnamemodify("./.lazy", ":p")
for _, name in ipairs({ "config", "data", "state", "cache" }) do
  vim.env[("XDG_%s_HOME"):format(name:upper())] = root .. "/" .. name
end
local lazypath = root .. "/plugins/lazy.nvim"
if not vim.loop.fs_stat(lazypath) then
  vim.fn.system({ "git", "clone", "--filter=blob:none", "https://github.com/folke/lazy.nvim.git", lazypath, })
end
vim.opt.runtimepath:prepend(lazypath)
require("lazy").setup({
  {
    "mfussenegger/nvim-dap",
    config = function()
      local dap = require "dap"

      dap.set_log_level "INFO"

      dap.listeners.before.attach.dapui_config = function()
        require("dapui").open()
      end
      dap.listeners.before.launch.dapui_config = function()
        require("dapui").open()
      end
      dap.listeners.before.event_exited.dapui_config = function(_, status)
        require("dapui").close()
        vim.notify("Process finished (exit code = " .. status.exitCode .. ")")
      end
      dap.listeners.before.disconnect.dapui_config = function()
        require("dapui").close()
        dap.repl.close()
      end

      dap.adapters.nlua = function(callback, config)
        callback {
          type = "server",
          host = "127.0.0.1",
          port = config.port,
        }
      end

      dap.configurations.lua = {
        {
          type = "nlua",
          request = "attach",
          name = "Attach to running Neovim instance",
          port = 8086
        },
      }

      local mappings = {
        ["<leader>dd"] = dap.continue,
        ["<leader>dD"] = dap.run_last,
        ["<leader>dc"] = dap.run_to_cursor,
        ["<leader>dx"] = dap.terminate,
        ["<leader>dX"] = function()
          require("dapui").close()
        end,
        ["<leader>dn"] = dap.step_over,
        ["<leader>db"] = dap.toggle_breakpoint,
        ["<leader>d<c-b>"] = dap.clear_breakpoints,
      }

      for lhs, rhs in pairs(mappings) do
        vim.keymap.set("n", lhs, rhs)
      end
    end,
  },
  {
    "jbyuki/one-small-step-for-vimkind",
  },
  {
    "rcarriga/nvim-dap-ui",
    dependencies = {
      "nvim-neotest/nvim-nio",
    },
    -- lazy = true,
    opts = {
      controls = { enabled = false },
      icons = {
        current_frame = "🡆",
      },
      layouts = {
        {
          elements = {
            { id = "stacks", size = 0.25 },
            { id = "scopes", size = 0.25 },
            { id = "breakpoints", size = 0.25 },
            { id = "watches", size = 0.25 },
          },
          size = 45,
          position = "left",
        },
        {
          elements = {
            { id = "repl", size = 1.0 },
          },
          size = 20,
          position = "bottom",
        },
      },
    },
  },
}, {
  root = root .. "/plugins",
})

If you save this as mwe.lua in some test directory, then run nvim --clean -u mwe.lua, it will download and install the plugins with lazy. Now, use two terminals:

  1. In terminal 1, run nvim --clean -u mwe.lua mwe.lua. Add some breakpoints.

  2. In terminal 2, run DEBUG=1 nvim --clean -u mwe.lua.

  3. In terminal 1, connect with <space>dd and observe.

I find the behaviour is very dependent on whether the lazy specs are lazy or not. If you use lazy = true for nvim-dap-ui, then it seems liks osv will not properly understand the breakpoints. It is somewhat of a sporadic behaviour and the log output does not help me understand what is happening here.

jbyuki commented 3 months ago

I cannot reproduce unfortunately, however I have seen that some breakpoints are skipped sometimes probably due to jit optimization so they are simply not executed, afterall it's not running in debug mode. I will put this onto that account for now but i'll leave it open in case something comes up.

lervag commented 3 months ago

I cannot reproduce unfortunately,

That's strange. Perhaps it's also a neovim version specific thing? I'm on the nightly builds:

:vers
NVIM v0.11.0-dev-632+g33464189bc
Build type: Release
LuaJIT 2.1.1720049189

On my end, with the example I provided, I observe the following behaviour:

however I have seen that some breakpoints are skipped sometimes probably due to jit optimization so they are simply not executed, afterall it's not running in debug mode. I will put this onto that account for now but i'll leave it open in case something comes up.

Ok; considering that I can actually achieve the debugging I want I'm quite happy. But it's annoying with the nondeterministic behaviour, in particular that I don't understand why it is happening.

jbyuki commented 3 months ago

Yes, for now it seems necessary to understand how "lazy" loading works and how it interacts with nvim-dap and osv.

Out of the 20 times or so I tried, it worked every time and I'm running the latest nightly on native windows. The tests were done by setting nvim-dap-ui to lazy = true and putting a breakpoint on the first line after the dap server launch line, where it's setting the mapleader.

I will try to test it on other setups if i get the chance.

On Thu, 22 Aug 2024, 8:11 pm Karl Yngve Lervåg, @.***> wrote:

I cannot reproduce unfortunately,

That's strange. Perhaps it's also a neovim version specific thing? I'm on the nightly builds:

:vers NVIM v0.11.0-dev-632+g33464189bc Build type: Release LuaJIT 2.1.1720049189

On my end, with the example I provided, I observe the following behaviour:

  • If I add breakpoints and start debugging as the example was provided, it works about 50% of the times (i.e., it will stop on breakpoints). That's still good enough to be useful already - thus, my issue is half resolved.
  • If I use lazy = true for nvim-dap-ui, the breakpoints will never hit. It would be nice to understand why, but it is not a big problem and I can just avoid to lazy load it!

however I have seen that some breakpoints are skipped sometimes probably due to jit optimization so they are simply not executed, afterall it's not running in debug mode. I will put this onto that account for now but i'll leave it open in case something comes up.

Ok; considering that I can actually achieve the debugging I want I'm quite happy. But it's annoying with the nondeterministic behaviour, in particular that I don't understand why it is happening.

— Reply to this email directly, view it on GitHub https://github.com/jbyuki/one-small-step-for-vimkind/issues/52#issuecomment-2305355549, or unsubscribe https://github.com/notifications/unsubscribe-auth/ALJBOFMPD5J3C3KKY2VEW73ZSYSTNAVCNFSM6AAAAABMOFCV2GVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZDGMBVGM2TKNJUHE . You are receiving this because you commented.Message ID: @.***>