summaryrefslogtreecommitdiff
path: root/lua/intellij_to_vscode/converter.lua
diff options
context:
space:
mode:
Diffstat (limited to 'lua/intellij_to_vscode/converter.lua')
-rw-r--r--lua/intellij_to_vscode/converter.lua140
1 files changed, 22 insertions, 118 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