initial commit

This commit is contained in:
Scott E. Graves 2022-07-29 10:12:52 -05:00
parent dec0f79640
commit 8da655bcae
4 changed files with 323 additions and 0 deletions

0
doc/.keep Normal file
View File

294
lua/init.lua Normal file
View File

@ -0,0 +1,294 @@
local Job = require("plenary.job")
local action_state = require "telescope.actions.state"
local actions = require "telescope.actions"
local conf = require("telescope.config").values
local finders = require("telescope.finders")
local pickers = require("telescope.pickers")
local global_state = require("telescope.state")
local utils = require("nvim-flutter-companion.utils")
local M = {}
local callbacks = {nil, nil}
local flutter_busy = false
local spinner_frames = {"", "", "", "", "", "", "", ""}
local EMULATOR = 1
local DEVICE = 2
local get_config_path = function()
return utils.create_path(vim.fn.getcwd(), ".flutter-companion")
end
local load_table = function(path)
local file, err = io.open(path, "r")
if err or file == nil then
return {}
end
local lines = file:read("a")
file:close()
local ok, json =
pcall(
function()
return vim.json.decode(lines)
end
)
return utils.iff(ok, json, {})
end
local parse = function(line, device_type)
local parts = vim.split(line, "")
local is_emulator = device_type == EMULATOR
local name_index = not is_emulator and 1 or 2
local id_index = not is_emulator and 2 or 1
if #parts == 4 then
return {
name = vim.trim(parts[name_index]),
id = vim.trim(parts[id_index]),
platform = vim.trim(parts[3]),
system = vim.trim(parts[4]),
type = device_type
}
end
end
local save_table = function(data, filename)
local file, err = io.open(filename, "wb")
if err or file == nil then
return err
end
file:write(vim.json.encode(data))
file:close()
end
_G.Flutter_Coc_Clear_Selected_Device = function()
local config_path = get_config_path()
local config_data = load_table(config_path)
if config_data.device ~= nil then
config_data.device = nil
save_table(config_data, config_path)
end
end
_G.Flutter_Coc_Run_Selected_Device = function()
local config_path = get_config_path()
local config_data = load_table(config_path)
if config_data.device == nil then
if callbacks[1] == nil then
callbacks[1] = _G.Flutter_Coc_Run_Selected_Device
vim.api.nvim_command("Telescope coc flutter_devices")
end
else
vim.api.nvim_command("CocCommand flutter.run -d " .. config_data.device.id)
end
end
_G.Flutter_Coc_Clear_Selected_Emulator = function()
local config_path = get_config_path()
local config_data = load_table(config_path)
if config_data.emulator ~= nil then
config_data.emulator = nil
save_table(config_data, config_path)
end
end
_G.Flutter_Coc_Run_Selected_Emulator = function()
local config_path = get_config_path()
local config_data = load_table(config_path)
if config_data.emulator == nil then
if callbacks[2] == nil then
callbacks[2] = _G.Flutter_Coc_Run_Selected_Emulator
vim.api.nvim_command("Telescope coc flutter_emulators")
end
else
local cmd = "flutter"
if vim.fn.has("win32") == 1 or vim.fn.has("win64") == 1 then
cmd = cmd .. ".bat"
end
local job = Job:new({command = cmd, args = {"emulators", "--launch", config_data.emulator.id}})
job:start()
end
end
local get_devices = function(result, type)
local devices = {}
for _, line in pairs(result) do
local device = parse(line, type)
if device then
table.insert(devices, device)
end
end
return devices
end
local extract_device_props = function(result, device_type)
device_type = device_type or DEVICE
local devices = {}
local device_list = get_devices(result, device_type)
if #device_list > 0 then
for _, device in pairs(device_list) do
table.insert(devices, device)
end
end
return devices
end
local parse_devices_output = function(job, callback)
local result = job:result()
local devices = extract_device_props(result, DEVICE)
callback(devices)
end
local list_devices = function(callback)
local cmd = "flutter"
if vim.fn.has("win32") == 1 or vim.fn.has("win64") == 1 then
cmd = cmd .. ".bat"
end
local job = Job:new({command = cmd, args = {"devices"}})
job:after_success(
vim.schedule_wrap(
function()
parse_devices_output(job, callback)
end
)
)
job:start()
end
local function list_emulators(callback)
local cmd = "flutter"
if vim.fn.has("win32") == 1 or vim.fn.has("win64") == 1 then
cmd = cmd .. ".bat"
end
local job = Job:new({command = cmd, args = {"emulators"}})
job:after_success(
vim.schedule_wrap(
function()
local emulators = extract_device_props(job:result(), EMULATOR)
callback(emulators)
end
)
)
job:start()
end
local start_spinner = function(name, get_active)
local spinner = 0
local record
local function update_spinner()
if get_active() then
local next_record =
require("notify").notify(
"Detecting " .. name .. "...",
"info",
{
title = "Flutter Action",
hide_from_history = true,
icon = spinner_frames[(spinner % #spinner_frames) + 1],
replace = record
}
)
record = next_record
spinner = spinner + 1
vim.defer_fn(update_spinner, 100)
end
end
update_spinner()
end
local stop_spinner = function(set_inactive)
set_inactive()
require("notify").dismiss()
end
function M.flutter_list(is_emulators, opts)
if flutter_busy == true then
return
end
flutter_busy = true
local config_path = get_config_path()
local config_data = load_table(config_path)
local callback_index = utils.iff(is_emulators, 2, 1)
local list_function = utils.iff(is_emulators, list_emulators, list_devices)
local name = utils.iff(is_emulators, "Emulators", "Devices")
local completed_callback
if callbacks[callback_index] ~= nil then
completed_callback = callbacks[callback_index]
callbacks[callback_index] = nil
end
local active = true
start_spinner(
name,
function()
return active
end
)
list_function(
function(items)
stop_spinner(
function()
active = false
end
)
if #items == 0 then
vim.notify("No " .. name .. " were found", "error", {title = "Flutter Action"})
else
global_state.set_global_key("selected_entry", nil)
pickers.new(
opts,
{
prompt_title = "Flutter " .. name,
sorter = conf.generic_sorter(opts),
finder = finders.new_table(
{
results = items,
entry_maker = function(item)
return {
value = item,
ordinal = item.name,
display = item.name
}
end
}
),
attach_mappings = function(prompt_bufnr --[[, map ]])
actions.select_default:replace(
function()
actions.close(prompt_bufnr)
local selection = action_state.get_selected_entry()
if is_emulators then
config_data.emulator = selection.value
else
config_data.device = selection.value
end
save_table(config_data, config_path)
if completed_callback ~= nil then
completed_callback()
end
end
)
return true
end
}
):find()
end
flutter_busy = false
end
)
end
return M

View File

@ -0,0 +1,25 @@
local M = {}
M.iff = function(b, l, r)
if b then
return l
end
return r
end
M.is_windows = vim.fn.has("win32") == 1 or vim.fn.has("win64") == 1
M.directory_sep = M.iff(M.is_windows, "\\\\", "/")
M.not_directory_sep = M.iff(M.is_windows, "/", "\\\\")
M.create_path = function(...)
local Path = require "plenary.path"
local ret =
Path:new({...}):absolute():gsub(M.not_directory_sep, M.directory_sep):gsub(
M.directory_sep .. M.directory_sep,
M.directory_sep
)
return ret
end
return M

View File

@ -0,0 +1,4 @@
if vim.g.loaded_nvim_flutter_companion == 1 then
return
end
vim.g.loaded_nvim_flutter_companion = 1