diff --git a/lua/flutter-tools.lua b/lua/flutter-tools.lua index a24530f..8756e7f 100644 --- a/lua/flutter-tools.lua +++ b/lua/flutter-tools.lua @@ -130,6 +130,7 @@ local function setup_autocommands() pattern = { "*" }, callback = function() dev_tools.stop() + if package.loaded["flutter-tools.commands"] then commands.on_exit() end if package.loaded["flutter-tools.widget_preview"] then widget_preview.on_exit() end end, }) diff --git a/lua/flutter-tools/commands.lua b/lua/flutter-tools/commands.lua index 2fa060f..9e9a909 100644 --- a/lua/flutter-tools/commands.lua +++ b/lua/flutter-tools/commands.lua @@ -28,6 +28,7 @@ local current_device = nil ---@field cleanup fun(funner: flutter.Runner) ---@field send fun(runner: flutter.Runner, cmd:string, quiet: boolean?, on_response: fun(response: any)|nil) ---@field attach fun(runner: flutter.Runner, paths:table, args:table, cwd:string, on_run_data:fun(is_err:boolean, data:string), on_run_exit:fun(data:string[], args: table, project_conf: flutter.ProjectConfig?,launch_config: dap.Configuration?)) +---@field stop? fun(runner: flutter.Runner) ---@type flutter.Runner? local runner = nil @@ -65,6 +66,10 @@ function M.current_device() return current_device end function M.is_running() return runner ~= nil and runner:is_running() end +function M.on_exit() + if runner and runner.stop then runner:stop() end +end + local function match_error_string(line) if not line then return false end -- match the error string if no devices are setup diff --git a/lua/flutter-tools/runners/job_runner.lua b/lua/flutter-tools/runners/job_runner.lua index 73c796d..d070c6a 100644 --- a/lua/flutter-tools/runners/job_runner.lua +++ b/lua/flutter-tools/runners/job_runner.lua @@ -74,6 +74,14 @@ end function JobRunner:cleanup() run_job = nil end +-- SIGTERM lets the flutter tool stop the app (or only detach, when attached) +-- before exiting; closing stdin alone leaves it running. +function JobRunner:stop() + if not run_job or not run_job.pid then return end + vim.uv.kill(run_job.pid, vim.uv.constants.SIGTERM) + vim.wait(3000, function() return run_job == nil or run_job.is_shutdown end) +end + function JobRunner:attach(paths, args, cwd, on_run_data, on_run_exit) local command = paths.flutter_bin local command_args = args