nvim-dap icon indicating copy to clipboard operation
nvim-dap copied to clipboard

Attach over unix domain socket instead of hostname/port?

Open will opened this issue 3 years ago • 9 comments

Problem Statement

It would be maybe nice to use vim.fn.tempname() to generate a tempfile socket and use that to communicate with a dap server, instead of having to make sure to grab an unused port on localhost.

Ideas or possible solutions

I'm pretty sure libuv can do this with new_pipe and pipe_bind but I'm not that sure.

will avatar Jul 15 '22 15:07 will

Which debug adapters support domain sockets?

Would it help if adapters could be configured with something like this:

local myadapter = {
  type = "server"
  port = "${port}",
  executable = {
    cmd = "my-debugadapter",
    args = {"--port", "${port}"}
  }
}

Where nvim-dap resolves ${port} to a free port number?

mfussenegger avatar Jul 16 '22 09:07 mfussenegger

Which debug adapters support domain sockets?

This is for https://github.com/ruby/debug . With no args it'll start on some random temp socket, but you can pass in an argument to choose the path. You can also do tcp ports, which is what I've been doing so far.

Would it help if adapters could be configured with something like this:

I think that'd be neat, but so far I've come to a solution of having the port be some high number and adding math.random(0,200) to it, and that's been good enough really. So feel free to close this issue out at anytime.

Other somewhat unrelated observations:

This isn't really worth opening issues for, but I was having a bunch of annoyance with the ruby debug project because if you do connect over a port instead of a UDS, it assumes you might be doing it across machines and won't use the local filesystem to map paths of the source code. And if it doesn't do that, it doesn't accept breakpoints. From digging through the source of both that and this project, I figured out if you pass localfs=true as part of the attach request, it will work. It wasn't really clear to me from the nvim-dap documentation that you can just add random key/value pairs to the debugee configuration. I see now the line

In addition, a Configuration accepts an arbitrary number of further options which are debug-adapter-specific.

but it didn't jump out at me as the answer without hindsight. I don’t really have a suggestion though of how to improve it though.

Also it'd be nice if there was a ${lineNumber} of where your cursor is. That way it'd be easier to run just a single test through the debugger. I imagine it would't be so hard to come up with a lua function that uses run() or launch() directly though.

will avatar Jul 16 '22 16:07 will

I think that'd be neat, but so far I've come to a solution of having the port be some high number [...]

I added support for it https://github.com/mfussenegger/nvim-dap/pull/606

I'm not opposed to domain sockets, but would feel a bit better about it if there were at least one other debug adapter that uses them.

I figured out if you pass localfs=true as part of the attach request, it will work

Want to mention that in https://github.com/mfussenegger/nvim-dap/wiki/Debug-Adapter-installation#Ruby ?

I also saw that it got added in https://github.com/suketa/nvim-dap-ruby/commit/287e60587d6643ceb368716ba49112152b8cd0ba

Also it'd be nice if there was a ${lineNumber} of where your cursor is. That way it'd be easier to run just a single test through the debugger.

Can you elaborate on that? Having the line number alone is usually not sufficient to run tests, and given that the configuration values can be functions where you can use nvim_win_get_cursor it should be easy enough to retrieve it if needed.

mfussenegger avatar Jul 21 '22 08:07 mfussenegger

I added support for it https://github.com/mfussenegger/nvim-dap/pull/606

Nice. I'm using type=server though, and it looks like this is only for type=executable ? I based my setup off of https://github.com/suketa/nvim-dap-ruby/blob/main/lua/dap-ruby.lua

There might be a way to use executable, but I haven't tried that path at all yet.

Want to mention that in https://github.com/mfussenegger/nvim-dap/wiki/Debug-Adapter-installation#Ruby

Can you elaborate on that? Having the line number alone is usually not sufficient to run tests, and given that the configuration values can be functions where you can use nvim_win_get_cursor it should be easy enough to retrieve it if needed.

With a file and line number, rspec will run just the nearest test or group of tests rspec path/to/file_spec.rb:123, you don’t need to parse out the names of tests or anything. There is ${file} now, so I was just thinking it'd be a nice pair. Thanks for the pointer though of how to do it myself.

will avatar Jul 21 '22 18:07 will

I'm using type=server though, and it looks like this is only for type=executable

It's for type = server

mfussenegger avatar Jul 21 '22 20:07 mfussenegger

Hm, so this is what I have now

local function setup_ruby_adapter(dap)
  dap.adapters.ruby = function(callback, config)
    local stdout = vim.loop.new_pipe(false)
    local waiting = config.waiting or 500
    local pid_or_err, handle, args
    config.port = config.port + math.random(200)

    args = { "exec", "rdbg", "-n", "--open", "--port", config.port, "-c", "--", "bundle", "exec", config.command, config.script, }

    local opts = {
      stdio = { nil, stdout },
      args = args,
      detached = false,
    }

    handle, pid_or_err = vim.loop.spawn("bundle", opts, function(code)
      handle:close()
      if code ~= 0 then
        assert(handle, "rdbg exited with code: " .. tostring(code))
        print("rdbg exited with code", code)
      end
    end)

    assert(handle, "Error running rgdb: " .. tostring(pid_or_err))

    stdout:read_start(function(err, chunk)
      assert(not err, err)
      if chunk then vim.schedule(function() require("dap.repl").append(chunk) end) end
    end)

    -- Wait for rdbg to start
    vim.defer_fn(function() callback { type = "server", host = config.server, port = config.port } end, waiting)
  end
end

local function setup_ruby_configuration(dap)
  dap.configurations.ruby = {
    {
      type = "ruby",
      name = "debug current file",
      bundle = "",
      request = "attach",
      localfs = true,
      command = "ruby",
      script = "${file}",
      port = 38698,
      server = "127.0.0.1",
      waiting = 1000,
    },
    {
      type = "ruby",
      name = "run current spec file",
      bundle = "bundle",
      request = "attach",
      localfs = true,
      command = "rspec",
      script = "${file}",
      port = 38698,
      server = "127.0.0.1",
      waiting = 1000,
    },
  }
end

local dap = require "dap"
setup_ruby_adapter(dap)
setup_ruby_configuration(dap)

and if I change that to be port = '${port}',

It doesn't work

Error executing luv callback:
...nvim/site/pack/packer/start/nvim-dap/lua/dap/session.lua:1009: bad argument #2 to 'connect' (number expected, got nil)
stack traceback:
        [C]: in function 'connect'
        ...nvim/site/pack/packer/start/nvim-dap/lua/dap/session.lua:1009: in function <...nvim/site/pack/packer/start/nvim-dap/lua/dap/session.lua:1002>

And throwing a vim.notify up in the dap.adatpers.ruby = function(callback, config) function, it looks like config.port is coming in just as the string.

I'm on 69efa4d40ecab580783a2fc848767d7c2b6288e2 from today, so it should have that patch from #606.

will avatar Jul 21 '22 22:07 will

Oh, nevermind now that I type that all out, I see that the variable template has to be on the adapter side not the config side. Whoops, sorry.

will avatar Jul 21 '22 22:07 will

You could change that to something like this:

dap.adapters.ruby = function(callback, config)
  callback({
    type = "server",
    host = "127.0.01",
    port = "${port}",
    executable = {
      command = "bundle"
      args = {"exec", "rdbg", "-n", "--open", "--port", "${port}", "-c", "--", "bundle", "exec", config.command, config.script, }
    }
  })
end

mfussenegger avatar Jul 22 '22 07:07 mfussenegger

That's much nicer, thank you. I put my setup using that in the wiki at https://github.com/mfussenegger/nvim-dap/wiki/Debug-Adapter-installation#with-ruby-debug

will avatar Jul 23 '22 01:07 will