86 lines
4.2 KiB
Lua
86 lines
4.2 KiB
Lua
-- lua/user/android.lua
|
|
-- Android development support for Neovim:
|
|
-- * exports the Android SDK env (so LSP, Gradle and :terminal jobs see it)
|
|
-- * :Android* commands + <leader>a* keymaps for build / run / test / logcat / emulator
|
|
--
|
|
-- Java (nvim-jdtls) and Kotlin (JetBrains kotlin-lsp) are configured elsewhere; this
|
|
-- module is purely the build/run/device tooling around them.
|
|
|
|
local sdk = vim.fn.expand("~/Android/Sdk")
|
|
|
|
-- 1. Make the Android SDK visible to LSP, Gradle and terminal jobs launched from nvim.
|
|
vim.env.ANDROID_HOME = vim.env.ANDROID_HOME or sdk
|
|
vim.env.ANDROID_SDK_ROOT = vim.env.ANDROID_SDK_ROOT or sdk
|
|
do
|
|
local path = vim.env.PATH or ""
|
|
local extra = {
|
|
sdk .. "/platform-tools", -- adb
|
|
sdk .. "/emulator", -- emulator
|
|
sdk .. "/cmdline-tools/latest/bin",-- sdkmanager/avdmanager
|
|
vim.fn.expand("~/.local/bin"), -- the `android` CLI
|
|
}
|
|
for _, p in ipairs(extra) do
|
|
if vim.fn.isdirectory(p) == 1 and not string.find(path, p, 1, true) then
|
|
path = p .. ":" .. path
|
|
end
|
|
end
|
|
vim.env.PATH = path
|
|
end
|
|
|
|
-- 2. Locate the Gradle project root (nearest ancestor with a gradlew wrapper).
|
|
local function gradle_root()
|
|
local start = vim.fn.expand("%:p:h")
|
|
if start == "" then start = vim.fn.getcwd() end
|
|
local found = vim.fs.find("gradlew", { upward = true, path = start })
|
|
if found and found[1] then
|
|
return vim.fn.fnamemodify(found[1], ":h")
|
|
end
|
|
return vim.fn.getcwd()
|
|
end
|
|
|
|
-- 3. Run a shell command in a bottom terminal split (live, scrollable output).
|
|
local function run_in_term(shell_cmd)
|
|
vim.cmd("botright 15split")
|
|
vim.cmd("terminal " .. shell_cmd)
|
|
vim.cmd("startinsert")
|
|
end
|
|
|
|
local function run_gradle(args)
|
|
run_in_term(string.format("cd %s && ./gradlew %s", vim.fn.shellescape(gradle_root()), args))
|
|
end
|
|
|
|
local function run_cmd(c)
|
|
run_in_term(string.format("cd %s && %s", vim.fn.shellescape(gradle_root()), c))
|
|
end
|
|
|
|
-- 4. User commands.
|
|
local cmd = vim.api.nvim_create_user_command
|
|
cmd("AndroidBuild", function() run_gradle("assembleDebug") end, { desc = "Gradle assembleDebug" })
|
|
cmd("AndroidClean", function() run_gradle("clean") end, { desc = "Gradle clean" })
|
|
cmd("AndroidInstall", function() run_gradle("installDebug") end, { desc = "Gradle installDebug" })
|
|
cmd("AndroidTest", function() run_gradle("testDebugUnitTest") end,{ desc = "Gradle unit tests" })
|
|
cmd("AndroidRun", function() run_cmd("android run") end, { desc = "Deploy app (android run)" })
|
|
cmd("AndroidDevices", function() run_cmd("adb devices -l") end, { desc = "List adb devices" })
|
|
cmd("AndroidLogcat", function() run_cmd("adb logcat -c; adb logcat") end, { desc = "adb logcat (cleared)" })
|
|
cmd("AndroidEmulators", function() run_cmd("android emulator list") end, { desc = "List AVDs" })
|
|
cmd("AndroidEmulator", function(o)
|
|
if o.args ~= "" then
|
|
run_cmd("android emulator start " .. vim.fn.shellescape(o.args))
|
|
else
|
|
-- Default: start the first available AVD.
|
|
run_cmd([[android emulator start "$("]] .. sdk .. [[/emulator/emulator" -list-avds | head -1)"]])
|
|
end
|
|
end, { nargs = "?", desc = "Start an emulator (optional AVD name)" })
|
|
cmd("AndroidStopEmulator", function() run_cmd("android emulator stop") end, { desc = "Stop emulator" })
|
|
|
|
-- 5. Keymaps (<leader>A* = Android).
|
|
-- NOTE: uppercase A so it does NOT clash with <leader>a (LSP code action).
|
|
local map = vim.keymap.set
|
|
map("n", "<leader>Ab", "<cmd>AndroidBuild<CR>", { silent = true, desc = "Android: build (assembleDebug)" })
|
|
map("n", "<leader>Ar", "<cmd>AndroidRun<CR>", { silent = true, desc = "Android: run/deploy" })
|
|
map("n", "<leader>Ai", "<cmd>AndroidInstall<CR>", { silent = true, desc = "Android: install" })
|
|
map("n", "<leader>At", "<cmd>AndroidTest<CR>", { silent = true, desc = "Android: unit tests" })
|
|
map("n", "<leader>Al", "<cmd>AndroidLogcat<CR>", { silent = true, desc = "Android: logcat" })
|
|
map("n", "<leader>Ad", "<cmd>AndroidDevices<CR>", { silent = true, desc = "Android: devices" })
|
|
map("n", "<leader>Ae", "<cmd>AndroidEmulator<CR>", { silent = true, desc = "Android: start emulator" })
|
|
map("n", "<leader>Ac", "<cmd>AndroidClean<CR>", { silent = true, desc = "Android: clean" })
|