mfussenegger / nvim-dap

Debug Adapter Protocol client implementation for Neovim
GNU General Public License v3.0
5.65k stars 205 forks source link

Run in external terminal does not propagate environment variables correctly #1317

Closed sewbacca closed 3 months ago

sewbacca commented 3 months ago

Debug adapter definition and debug configuration

I am writing a debug adapter and noticed that while the integrated terminal correctly propagates environment variables, the external terminal does not.

Debug adapter version

2b428ff

Steps to Reproduce

  1. Use any debugger supporting passing environment variables and running in external terminal
  2. Write a program which prints a sample variable
  3. Set the sample variable to a text

Expected Result

The sample variable gets printed

Actual Result

No sample variable is set

apognu commented 1 month ago

Sorry for digging this up after it was closed, but I am still wondering about the behavior here. session.lua:123 here seems like it tries to merge the two environments, but only the env passed to the function is not nil.

Is that expected? I would assumed that even if no environment is passed to the function, it would try to inherit the environment neovim was started with. I wanted to use this to launch a new tab in the current terminal (and therefore needs to environment in the external terminal).

If I modify session.lua:123 to this, it works as I expect it, but I do not know if there is a good reason this is not happening:

-   for k, v in pairs(env and vim.tbl_extend('keep', env, vim.fn.environ()) or {}) do
+   for k, v in pairs(vim.tbl_extend('keep', env or {}, vim.fn.environ())) do
sewbacca commented 1 month ago

I didn't think it would make any difference in the PR. I assumed the environment is just copied from neovim, as I thought this would be the default behaviour for any new process. Did you found an example where this is not the case? i.e. set a environment var during startup and launch your program, which won't reflect that variable: FOOBAR=bla nvim and somehting along the lines of print(os.getenv 'FOOBAR') in the program you are debugging.

apognu commented 1 month ago

Thanks for answering on a closed issue. :pray:

Yes, I encounter this when developing a TUI program. It requires a TTY to run, so I need the external terminal so it can run. The exact thing I was trying to do is automatically run the program in a new tab in kitty, which requires inheriting an environment variable.

So, in my configuration, the launched external terminal does not directly run the program that is to be debugged, but runs a script that spawns it, if that makes any sense at all. :D

Here is my adapter configuration:

local dap = require("dap")

dap.defaults.fallback.external_terminal = {
  command = "/home/apognu/.local/bin/kitty-new-tab",
}

dap.adapters.lldb = {
  type = "server",
  port = "${port}",
  host = "127.0.0.1",
  executable = {
    command = "/usr/bin/codelldb",
    args = { "--port", "${port}" },
  },
}

dap.configurations.rust = {
  {
    name = "Run tuigreet",
    type = "lldb",
    request = "launch",
    program = function()
      return vim.fn.getcwd() .. "/target/debug/tuigreet"
    end,
    env = {
      GREETD_SOCK = "/tmp/greetd.sock",
    },
    terminal = "external",
  }
}

And here is the kitty-new-tab script that is configured as an external terminal:

#!/bin/sh

echo 'kitty-new-tab called' > /tmp/kitty-new-tab.log
env >> /tmp/kitty-new-tab.log

kitten @ --to $KITTY_LISTEN_ON launch --type=tab --keep-focus $@

I added the debug statements so I could show off the environment this is run with:

$ cat /tmp/kitty-new-tab.log
PWD=/home/apognu/code/personal/tuigreet
SHLVL=1
_=/usr/bin/env

If I patch session.lua with my change above, this issue is fixed, my whole environment is inherited by the external terminal, which can make use of it to spawn the shell properly.

Do you need any more information? I am happy to try things out if necessary (or to learn that I am not doing things the right way).

sewbacca commented 1 month ago

It would make sense for you to open a PR, if it fixes the issue (I am not the maintainer), but what doesn't make sense to me is that you did define an environment in your configuration, yet env is nil. And when you cat the log file, you also don't see GREETD_SOCK getting passed. Am I misreading your configuration?

apognu commented 1 month ago

I will open a PR, the maintainer might know if it's a good change or not.

The defined environment variable is passed to the debugged program properly, but not to the external terminal. It might be my configuration that is a bit unusual, though.

Thanks for your input!