diff --git a/lua/flutter-tools/commands.lua b/lua/flutter-tools/commands.lua index 9b7165e..957828f 100644 --- a/lua/flutter-tools/commands.lua +++ b/lua/flutter-tools/commands.lua @@ -9,6 +9,7 @@ local dev_tools = lazy.require("flutter-tools.dev_tools") ---@module "flutter- local lsp = lazy.require("flutter-tools.lsp") ---@module "flutter-tools.lsp" local job_runner = lazy.require("flutter-tools.runners.job_runner") ---@module "flutter-tools.runners.job_runner" local debugger_runner = lazy.require("flutter-tools.runners.debugger_runner") ---@module "flutter-tools.runners.debugger_runner" +local path = lazy.require("flutter-tools.utils.path") ---@module "flutter-tools.utils.path" local dev_log = lazy.require("flutter-tools.log") ---@module "flutter-tools.log" local M = {} @@ -20,7 +21,7 @@ local current_device = nil ---@class flutter.Runner ---@field is_running fun(runner: flutter.Runner):boolean ----@field run 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)) +---@field run 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), is_flutter_project: boolean, project_conf: flutter.ProjectConfig?) ---@field cleanup fun(funner: flutter.Runner) ---@field send fun(runner: flutter.Runner, cmd:string, quiet: boolean?) @@ -195,6 +196,17 @@ local function get_cwd(project_conf) return lsp.get_lsp_root_dir() end +---@param cwd string +local function has_flutter_dependency_in_pubspec(cwd) + local pubspec = vim.fn.glob(path.join(cwd, "pubspec.yaml")) + if pubspec == "" then return false end + local pubspec_content = vim.fn.readfile(pubspec) + local joined_content = table.concat(pubspec_content, "\n") + + local flutter_dependency = string.match(joined_content, "flutter:\n[%s\t]*sdk:[%s\t]*flutter") + return flutter_dependency ~= nil +end + ---@param opts RunOpts ---@param project_conf flutter.ProjectConfig? local function run(opts, project_conf) @@ -203,7 +215,6 @@ local function run(opts, project_conf) local args = opts.cli_args or get_run_args(opts, project_conf) current_device = opts.device or get_device_from_args(args) - ui.notify("Starting flutter project...") if project_conf then if project_conf.pre_run_callback then local callback_args = { @@ -215,8 +226,17 @@ local function run(opts, project_conf) project_conf.pre_run_callback(callback_args) end end + local cwd = get_cwd(project_conf) + -- To determinate if the project is a flutter project we need to check if the pubspec.yaml + -- file has a flutter dependency in it. We need to get cwd first to pick correct pubspec.yaml file. + local is_flutter_project = has_flutter_dependency_in_pubspec(cwd) + if is_flutter_project then + ui.notify("Starting flutter project...") + else + ui.notify("Starting dart project...") + end runner = use_debugger_runner() and debugger_runner or job_runner - runner:run(paths, args, get_cwd(project_conf), on_run_data, on_run_exit) + runner:run(paths, args, cwd, on_run_data, on_run_exit, is_flutter_project, project_conf) end) end diff --git a/lua/flutter-tools/config.lua b/lua/flutter-tools/config.lua index 6e3a4d1..911c740 100644 --- a/lua/flutter-tools/config.lua +++ b/lua/flutter-tools/config.lua @@ -84,26 +84,7 @@ local config = { enabled = false, exception_breakpoints = nil, evaluate_to_string_in_debug_views = true, - register_configurations = function(paths) - require("dap").configurations.dart = { - { - type = "dart", - request = "launch", - name = "Launch flutter", - dartSdkPath = paths.dart_sdk, - flutterSdkPath = paths.flutter_sdk, - program = "${workspaceFolder}/lib/main.dart", - }, - { - type = "dart", - request = "attach", - name = "Connect flutter", - dartSdkPath = paths.dart_sdk, - flutterSdkPath = paths.flutter_sdk, - program = "${workspaceFolder}/lib/main.dart", - }, - } - end, + register_configurations = nil, }, closing_tags = { highlight = "Comment", diff --git a/lua/flutter-tools/dap.lua b/lua/flutter-tools/dap.lua index 1ec533d..c128f05 100644 --- a/lua/flutter-tools/dap.lua +++ b/lua/flutter-tools/dap.lua @@ -1,5 +1,4 @@ local lazy = require("flutter-tools.lazy") -local path = lazy.require("flutter-tools.utils.path") ---@module "flutter-tools.utils.path" local ui = lazy.require("flutter-tools.ui") ---@module "flutter-tools.ui" local success, dap = pcall(require, "dap") @@ -10,57 +9,9 @@ end local M = {} -local function has_flutter_dependency_in_pubspec() - local pubspec = vim.fn.glob("pubspec.yaml") - if pubspec == "" then return false end - local pubspec_content = vim.fn.readfile(pubspec) - local joined_content = table.concat(pubspec_content, "\n") - - local flutter_dependency = string.match(joined_content, "flutter:\n[%s\t]*sdk:[%s\t]*flutter") - return flutter_dependency ~= nil -end - function M.setup(config) local opts = config.debugger - require("flutter-tools.executable").get(function(paths) - local is_flutter_project = has_flutter_dependency_in_pubspec() - - if is_flutter_project then - dap.adapters.dart = { - type = "executable", - command = paths.flutter_bin, - args = { "debug-adapter" }, - } - if path.is_windows then - -- https://github.com/mfussenegger/nvim-dap/wiki/Debug-Adapter-installation#dart - -- add this if on windows, otherwise server won't open successfully - dap.adapters.dart.options = { - detached = false, - } - end - local repl = require("dap.repl") - repl.commands = vim.tbl_extend("force", repl.commands, { - custom_commands = { - [".hot-reload"] = function() dap.session():request("hotReload") end, - [".hot-restart"] = function() dap.session():request("hotRestart") end, - }, - }) - else - dap.adapters.dart = { - type = "executable", - command = paths.dart_bin, - args = { "debug_adapter" }, - } - dap.configurations.dart = { - { - type = "dart", - request = "launch", - name = "Launch Dart", - dartSdkPath = paths.dart_sdk, - program = "${workspaceFolder}/bin/main.dart", - }, - } - end + require("flutter-tools.executable").get(function(_) if opts.exception_breakpoints and type(opts.exception_breakpoints) == "table" then dap.defaults.dart.exception_breakpoints = opts.exception_breakpoints end diff --git a/lua/flutter-tools/runners/debugger_runner.lua b/lua/flutter-tools/runners/debugger_runner.lua index 048a7d1..7b76b26 100644 --- a/lua/flutter-tools/runners/debugger_runner.lua +++ b/lua/flutter-tools/runners/debugger_runner.lua @@ -3,6 +3,7 @@ local ui = lazy.require("flutter-tools.ui") ---@module "flutter-tools.ui" local dev_tools = lazy.require("flutter-tools.dev_tools") ---@module "flutter-tools.dev_tools" local config = lazy.require("flutter-tools.config") ---@module "flutter-tools.config" local utils = lazy.require("flutter-tools.utils") ---@module "flutter-tools.utils" +local path = lazy.require("flutter-tools.utils.path") ---@module "flutter-tools.utils.path" local vm_service_extensions = lazy.require("flutter-tools.runners.vm_service_extensions") ---@module "flutter-tools.runners.vm_service_extensions" local _, dap = pcall(require, "dap") @@ -23,7 +24,95 @@ local command_requests = { function DebuggerRunner:is_running() return dap.session() ~= nil end -function DebuggerRunner:run(paths, args, cwd, on_run_data, on_run_exit) +---@param paths table +---@param is_flutter_project boolean +local function register_debug_adapter(paths, is_flutter_project) + if is_flutter_project then + dap.adapters.dart = { + type = "executable", + command = paths.flutter_bin, + args = { "debug-adapter" }, + } + if path.is_windows then + -- https://github.com/mfussenegger/nvim-dap/wiki/Debug-Adapter-installation#dart + -- add this if on windows, otherwise server won't open successfully + dap.adapters.dart.options = { + detached = false, + } + end + local repl = require("dap.repl") + repl.commands = vim.tbl_extend("force", repl.commands, { + custom_commands = { + [".hot-reload"] = function() dap.session():request("hotReload") end, + [".hot-restart"] = function() dap.session():request("hotRestart") end, + }, + }) + else + dap.adapters.dart = { + type = "executable", + command = paths.dart_bin, + args = { "debug_adapter" }, + } + end +end + +---@param paths table +---@param is_flutter_project boolean +---@param project_config flutter.ProjectConfig? +local function register_default_configurations(paths, is_flutter_project, project_config) + local program + if is_flutter_project then + if project_config and project_config.target then + program = project_config.target + else + program = "lib/main.dart" + end + require("dap").configurations.dart = { + { + type = "dart", + request = "launch", + name = "Launch flutter", + dartSdkPath = paths.dart_sdk, + flutterSdkPath = paths.flutter_sdk, + program = program, + }, + { + type = "dart", + request = "attach", + name = "Connect flutter", + dartSdkPath = paths.dart_sdk, + flutterSdkPath = paths.flutter_sdk, + program = program, + }, + } + else + if project_config and project_config.target then + program = project_config.target + else + local root_dir_name = vim.fn.fnamemodify(vim.fn.getcwd(), ":t") + program = path.join("bin", root_dir_name .. ".dart") + end + require("dap").configurations.dart = { + { + type = "dart", + request = "launch", + name = "Launch dart", + dartSdkPath = paths.dart_sdk, + program = program, + }, + } + end +end + +function DebuggerRunner:run( + paths, + args, + cwd, + on_run_data, + on_run_exit, + is_flutter_project, + project_config +) local started = false local before_start_logs = {} vm_service_extensions.reset() @@ -68,9 +157,11 @@ function DebuggerRunner:run(paths, args, cwd, on_run_data, on_run_exit) end end + register_debug_adapter(paths, is_flutter_project) local launch_configurations = {} local launch_configuration_count = 0 - config.debugger.register_configurations(paths) + register_default_configurations(paths, is_flutter_project, project_config) + if config.debugger.register_configurations then config.debugger.register_configurations(paths) end local all_configurations = require("dap").configurations.dart if not all_configurations then ui.notify("No launch configuration for DAP found", ui.ERROR) diff --git a/lua/flutter-tools/runners/job_runner.lua b/lua/flutter-tools/runners/job_runner.lua index 4fc1e42..4a98b78 100644 --- a/lua/flutter-tools/runners/job_runner.lua +++ b/lua/flutter-tools/runners/job_runner.lua @@ -23,10 +23,29 @@ local command_keys = { function JobRunner:is_running() return run_job ~= nil end -function JobRunner:run(paths, args, cwd, on_run_data, on_run_exit) +function JobRunner:run( + paths, + args, + cwd, + on_run_data, + on_run_exit, + is_flutter_project, + project_config +) + local command, command_args + if is_flutter_project then + command = paths.flutter_bin + command_args = args + else + command = paths.dart_bin + command_args = { "run" } ---@type string[] + if project_config and project_config.target then + table.insert(command_args, project_config.target) + end + end run_job = Job:new({ - command = paths.flutter_bin, - args = args, + command = command, + args = command_args, cwd = cwd, on_start = function() utils.emit_event(utils.events.APP_STARTED) end, on_stdout = vim.schedule_wrap(function(_, data, _)