diff options
| author | Dmitrii Morozov <snoopdesigns@gmail.com> | 2025-10-29 23:26:37 +0100 |
|---|---|---|
| committer | Dmitrii Morozov <snoopdesigns@gmail.com> | 2025-10-29 23:26:37 +0100 |
| commit | 6c2c5dc975059a98ba1403556c3b55673fd9a0bd (patch) | |
| tree | d9a0a9b0e87c9498c91ff053bebc7315d0baf8d6 | |
| parent | 1c3d6072b0a75666d3de5ae01ed3710f25877b20 (diff) | |
| -rw-r--r-- | lua/intellij_to_vscode/converter.lua | 140 | ||||
| -rw-r--r-- | lua/intellij_to_vscode/intellij_to_vscode.lua | 11 |
2 files changed, 22 insertions, 129 deletions
diff --git a/lua/intellij_to_vscode/converter.lua b/lua/intellij_to_vscode/converter.lua index 5d87cd8..1b5572f 100644 --- a/lua/intellij_to_vscode/converter.lua +++ b/lua/intellij_to_vscode/converter.lua @@ -1,6 +1,4 @@ local M = {} -local uv = vim.loop -local api = vim.api local function read_file(path) local fd = io.open(path, "r") @@ -25,17 +23,14 @@ local function write_file(path, content) fd:close() end --- Minimal XML attribute extractor for a tag like: <option name="MAIN_CLASS_NAME" value="com.example.Main" /> local function extract_attributes(tag) local attrs = {} - for k, v in tag:gmatch('(%w+)%s*=\\s*"([^"]*)"') do + for k, v in tag:gmatch('(%w+)%s*=%s*"([^"]*)"') do attrs[k] = v end return attrs end --- Given the whole xml content, return table: --- { type = "Application", name = "MyApp", options = { [name] = value, ... }, env = {k=v}, method = {...} } local function parse_run_configuration(xml) -- find <configuration ...> ... </configuration> local cfg_tag, body = xml:match("<configuration%s+([^>]*)>(.-)</configuration>") @@ -49,7 +44,7 @@ local function parse_run_configuration(xml) end local cfg_attrs = extract_attributes(cfg_tag) - local result = { _attrs = cfg_attrs, options = {}, env = {}, method = {} } + local result = { _attrs = cfg_attrs, options = {} } -- options: <option name="..." value="..."/> for option in body:gmatch("<option%s+([^>/]-)/>") do @@ -58,135 +53,45 @@ local function parse_run_configuration(xml) result.options[a.name] = a.value end end + return result +end - -- envs: <envs><env name="K" value="V"/></envs> - local envs_block = body:match("<envs>(.-)</envs>") - if envs_block then - for envtag in envs_block:gmatch("<env%s+([^>/]-)/>") do - local a = extract_attributes(envtag) - if a.name and a.value then - result.env[a.name] = a.value - end - end - end +local function print_table(t, indent) + indent = indent or 0 + local prefix = string.rep(" ", indent) - -- method (for JUnit): <method v="2"> <option name="..." value="..."/> </method> - local method_block = body:match("<method%s+([^>]*)>(.-)</method>") - if method_block then - local method_tag, method_body = body:match("<method%s+([^>]*)>(.-)</method>") - if method_tag then - result.method._attrs = extract_attributes(method_tag) - result.method.options = {} - for opt in method_body:gmatch("<option%s+([^>/]-)/>") do - local a = extract_attributes(opt) - if a.name and a.value then - result.method.options[a.name] = a.value - end - end + for key, value in pairs(t) do + if type(value) == "table" then + print(prefix .. tostring(key) .. ":") + print_table(value, indent + 1) + else + print(prefix .. tostring(key) .. " = " .. tostring(value)) end end - - return result end -- Map a single parsed config to a VSCode launch configuration (as Lua table) -local function map_to_vscode(name, parsed) - local t = parsed._attrs.type or parsed._attrs.factoryName or "" +local function map_to_vscode(parsed) + local type = parsed._attrs.type or parsed._attrs.factoryName or "" local vscode = { - name = name or parsed._attrs.name or "Converted", + name = parsed._attrs.name or "<undefined>", request = "launch", } -- Common Application type - if t:match("[Aa]pplication") or parsed.options.MAIN_CLASS_NAME then + if type:match("[Aa]pplication") then vscode.type = "java" - vscode.mainClass = parsed.options.MAIN_CLASS_NAME or parsed.options.MAIN_CLASS - if parsed.options.PROGRAM_PARAMETERS and parsed.options.PROGRAM_PARAMETERS ~= "" then - -- split by space respecting simple quotes (basic) - local args = {} - for a in parsed.options.PROGRAM_PARAMETERS:gmatch("%S+") do - table.insert(args, a) - end - vscode.args = args - end - if parsed.options.VM_PARAMETERS and parsed.options.VM_PARAMETERS ~= "" then - vscode.vmArgs = parsed.options.VM_PARAMETERS - end - if parsed.options.WORKING_DIRECTORY and parsed.options.WORKING_DIRECTORY ~= "" then - vscode.cwd = parsed.options.WORKING_DIRECTORY:gsub("%$PROJECT_DIR%$", "${workspaceFolder}") - else - vscode.cwd = "${workspaceFolder}" - end - if next(parsed.env) then - vscode.env = parsed.env - end - -- If module present, attach projectName (useful for java extension) - if parsed.options.MODULE_NAME then - vscode.projectName = parsed.options.MODULE_NAME - end - + vscode.mainClass = parsed.options.MAIN_CLASS_NAME return vscode end - -- JUnit test configuration - if - t:match("[Jj]Unit") - or parsed.method.options and (parsed.method.options.CLASS_NAME or parsed.method.options.METHOD_NAME) - then - vscode.type = "java" - -- Use test runner config via mainClass (JUnit runner) or use builtin test adapters - if parsed.method.options.CLASS_NAME then - vscode.name = (parsed._attrs.name or "JUnit:") .. " " .. parsed.method.options.CLASS_NAME - -- map to a launch that runs the single test class - vscode.mainClass = parsed.method.options.CLASS_NAME - vscode.args = {} - end - if next(parsed.env) then - vscode.env = parsed.env - end - vscode.cwd = parsed.options.WORKING_DIRECTORY - and parsed.options.WORKING_DIRECTORY:gsub("%$PROJECT_DIR%$", "${workspaceFolder}") - or "${workspaceFolder}" - return vscode - end - - -- Gradle run config - if t:match("[Gg]radle") or parsed._attrs.type == "Gradle" or parsed.options.TASK_NAME then - -- Represent as a 'command' launch using terminal.integrated (fallback) - vscode.type = "pwa-node" -- generic terminal-ish; user may change - vscode.name = parsed._attrs.name or "Gradle Task" - local task = parsed.options.TASK_NAME or parsed.options.GRADLE_TASK - vscode.request = "launch" - vscode.runtimeExecutable = "gradle" - vscode.args = {} - if task and task ~= "" then - for tkn in (task .. ""):gmatch("%S+") do - table.insert(vscode.args, tkn) - end - end - vscode.cwd = parsed.options.WORKING_DIRECTORY - and parsed.options.WORKING_DIRECTORY:gsub("%$PROJECT_DIR%$", "${workspaceFolder}") - or "${workspaceFolder}" - if next(parsed.env) then - vscode.env = parsed.env - end - return vscode - end - - -- Fallback: produce a shell launch that echos an unsupported type - return { - type = "pwa-node", - name = parsed._attrs.name or "Converted (unsupported)", - request = "launch", - program = "${file}", - cwd = "${workspaceFolder}", - } + error("Unknown configuration type: " .. type) end -- Main: scan .idea/runConfigurations and convert function M.convert_all(opts) opts = opts or {} - local pattern = ".run/*.xml" + local pattern = ".idea/runConfigurations/*.xml" local files = vim.tbl_filter(function(p) return p ~= "" end, vim.fn.glob(pattern, false, true)) @@ -200,10 +105,9 @@ function M.convert_all(opts) if not content then vim.notify("Cannot read " .. f, vim.log.levels.WARN) end - local name = f:match("([^/]+)%.xml$") or f local parsed = parse_run_configuration(content) if parsed then - local vs = map_to_vscode(name, parsed) + local vs = map_to_vscode(parsed) table.insert(configs, vs) else vim.notify("Skipping (unrecognized) " .. f, vim.log.levels.DEBUG) @@ -211,7 +115,7 @@ function M.convert_all(opts) end local launch = { version = "0.2.0", configurations = configs } - local ok, j = pcall(vim.fn.json_encode, launch) + local ok, j = pcall(vim.json.encode, launch) if not ok then error("Failed to encode launch.json") end diff --git a/lua/intellij_to_vscode/intellij_to_vscode.lua b/lua/intellij_to_vscode/intellij_to_vscode.lua deleted file mode 100644 index a2bfa78..0000000 --- a/lua/intellij_to_vscode/intellij_to_vscode.lua +++ /dev/null @@ -1,11 +0,0 @@ --- This file makes the plugin load on startup and provide command if not already created -if vim.fn.exists(":ITVConvert") == 0 then - vim.api.nvim_create_user_command("ITVConvert", function() - local ok, err = pcall(function() - require("intellij_to_vscode").convert_all() - end) - if not ok then - vim.notify("ITVConvert failed: " .. tostring(err), vim.log.levels.ERROR) - end - end, {}) -end |
