jbyuki / one-small-step-for-vimkind

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

No response or event received #31

Closed yyy33 closed 1 year ago

yyy33 commented 1 year ago

Hi, When executing Disconnect Request or Terminate Request in dap-client, the response or event cannot be received. I execute the dap.terminate() method after successfully connecting to the debug adapter, but none of the listeners I set up are running properly.

This is my config, Modified form @ibhagwan

local ok, dap = pcall(require, 'dap')
local ok, util = pcall(require, 'util')

local function dap_server_lua(opts)
    local terminal = vim.fn.split(os.getenv("TERM"), '-', 1)[1]
    local pipe = vim.fn.tempname()
    local cmd = string.format('%s -e nvim --listen %s', terminal, pipe)
    local debugee_id = vim.fn.jobstart(cmd)
    assert(debugee_id ~= 0 or debugee_id ~= -1, 'fail')

    local ok, adapter_id
    ok = vim.wait(5000, function ()
        ok, adapter_id = pcall(vim.fn.sockconnect,'pipe', pipe, {rpc = true})
        return ok and adapter_id > 0
    end)
    assert(ok, 'timeout')

    vim.fn.rpcrequest(
        adapter_id,
        'nvim_create_autocmd',
        'vimleavepre',
        { command = [[lua require('osv').stop()]] }
    )

    local server = vim.fn.rpcrequest(
        adapter_id,
        "nvim_exec_lua",
        [[return require"osv".launch(...)]],
        { opts }
    ) or {}
    server.adapter_id = adapter_id
    server.debugee_id = debugee_id
    return server
end

dap.configurations.lua = {
    {
        type = "nlua",
        request = "attach",
        name = "current file",
        server = function() return dap_server_lua(nil) end,
    },
}

local nlua_server_by_session_id = {}
dap.adapters.nlua = function(callback, config)
    assert(config.server.host and config.server.port,  'fail')
    callback({ type = 'server', host = config.server.host, port = config.server.port })
    local session = dap.session() or {}
    assert(session.id and session.filetype == 'lua', 'fail')
    nlua_server_by_session_id[session.id] = config.server

    if not dap.listeners.after['Terminate']['osv'] then
        print('00')
        dap.listeners.after['Terminate']['osv'] = function(session, err, respond, request_payload, mes_id)
            if session.filetype ~= 'lua' then
                print('11')
               return
            end
            local server = nlua_server_by_session_id[session.id]
            if not server then
                print('22')
               return 
            end

            vim.fn.rpcrequest(
                server.adapter_id,
                "nvim_exec_lua",
                [[require"osv".stop()]]
            )
            vim.fn.jobstop(server.debugee_id)
        end
    end
    if not dap.listeners.after['Disconnect']['osv'] then
        print('00')
        dap.listeners.after['Disconnect']['osv'] = function(session, err, respond, request_payload, mes_id)
            if session.filetype ~= 'lua' then
                print('11')
               return
            end
            local server = nlua_server_by_session_id[session.id]
            if not server then
                print('22')
               return 
            end

            vim.fn.rpcrequest(
                server.adapter_id,
                "nvim_exec_lua",
                [[require"osv".stop()]]
            )
            vim.fn.jobstop(server.debugee_id)
        end
    end
end

local map_bak_list = {}
vim.keymap.set('n', 'dp', function() dap.toggle_breakpoint() end)
vim.keymap.set('n', 'd<cr>', function()
    dap.continue({ new = true })
    if #dap.sessions() > 1 then
        return
    end

    map_bak_list = {}
    for _, map in ipairs({
        { 'n', '<a-p>', function() dap.toggle_breakpoint() end },
        { 'n', '<a-c>', function() dap.toggle_breakpoint(vim.fn.input('c :')) end },
        { 'n', '<a-e>', function() dap.set_exception_breakpoints() end },
        { 'n', 'qp', function() dap.list_breakpoints() end },
        { 'n', 'cp', function() dap.clear_breakpoints() end },
        { 'n', '<a-j>', function() dap.step_into({ askForTargets = true }) end },
        { 'n', '<a-k>', function() dap.step_back({ askForTargets = true }) end },
        { 'n', '<a-l>', function() dap.step_over({ askForTargets = true }) end },
        { 'n', '<a-o>', function() dap.step_out({ askForTargets = true }) end },
        { 'n', '<a-g>', function() dap.run_to_cursor() end },
        { 'n', '<a-G>', function() dap.goto_() end },
        { 'n', '<cr>', function() dap.continue() end },
        { 'n', '<bs>', function() dap.reverse_continue() end },
        { 'n', '<a-r>', function() dap.restart() end },
        { 'n', '<space>', function() dap.pause() end },
        { 'n', '<c-n>', function() dap.down() end },
        { 'n', '<c-p>', function() dap.up() end },
        { 'n', '<c-m>', function() dap.focus_frame() end },
        { 'n', '<c-r>', function() dap.restart_frame() end },
        { 'n', 'rp', function() dap.repl.toggle() end },
        { 'n', '@>m-.<@', function()
            dap.terminate()
            if #dap.sessions() > 0 then
               return
            end

            for _, map in ipairs(map_bak_list) do
                util.restore_map(map)
            end
        end },
    }) do
        table.insert(map_bak_list, util.save_map(map[1], map[2]))
        vim.keymap.set(map[1], map[2], map[3])
    end
end)
jbyuki commented 1 year ago

I suggest reading the doc of nvim-dap carefully. It explains it well, much better than I can do. If you want to set up listeners, I suggest first trying to log the events using require"dap".set_log_level('DEBUG') and see what exactly is being communicated.

yyy33 commented 1 year ago

I suggest reading the doc of nvim-dap carefully. It explains it well, much better than I can do. If you want to set up listeners, I suggest first trying to log the events using require"dap".set_log_level('DEBUG') and see what exactly is being communicated.

I have read the nvim-dap documentation and the osv documentation carefully, and I know that nvim-dap can view log records, but I didn't think to use it to troubleshoot my configuration file errors, thanks for reminding me, I found the problem, the reason is that when listening for events or commands, I should use the name that starts with lowercase instead of uppercase (Ignoring case is a good idea, I think). By the way, do you have any plans to add the ability to supportsTerminateRequest to osv?

jbyuki commented 1 year ago

Great, I don't really think ignoring case is a good idea. It would add complexity which is unecessary in most cases, and I'm more of the opinion the programmer should be himself "case-sensitive". This is a too ubiquitous mistake in the programming world and I really dislike case-insensitive systems personally, it feels too loose.

Thanks for for reminding me as well to add more supported capabilities. We can add a few among which supportsTerminateRequest .