diff --git a/lua/platformio/pickers/init.lua b/lua/platformio/pickers/init.lua index b9e6163..ef13ca9 100644 --- a/lua/platformio/pickers/init.lua +++ b/lua/platformio/pickers/init.lua @@ -3,61 +3,70 @@ local M = {} local config = require('platformio').config local function load_backend(name) - local ok, backend = pcall(require, 'platformio.pickers.' .. name) - if ok then - return backend - end - return nil + local ok, backend = pcall(require, 'platformio.pickers.' .. name) + if ok then + return backend + end + return nil end local function get_backend() - local backend_name = config.picker_backend or 'auto' + local backend_name = config.picker_backend or 'auto' - if backend_name == 'telescope' then - return load_backend('telescope') or load_backend('ui_select') - end + if backend_name == 'telescope' then + return load_backend('telescope') or load_backend('ui_select') + end - if backend_name == 'ui_select' then - return load_backend('ui_select') - end + if backend_name == 'ui_select' then + return load_backend('ui_select') + end - return load_backend('telescope') or load_backend('ui_select') + return load_backend('telescope') or load_backend('ui_select') end function M.pick_board(boards, on_select) - local backend = get_backend() - if not backend then - vim.notify('No picker backend available for PlatformIO.', vim.log.levels.ERROR) - return - end - backend.pick_board(boards, on_select) + local backend = get_backend() + if not backend then + vim.notify('No picker backend available for PlatformIO.', vim.log.levels.ERROR) + return + end + backend.pick_board(boards, on_select) end function M.pick_framework(frameworks, on_select) - local backend = get_backend() - if not backend then - vim.notify('No picker backend available for PlatformIO.', vim.log.levels.ERROR) - return - end - backend.pick_framework(frameworks, on_select) + local backend = get_backend() + if not backend then + vim.notify('No picker backend available for PlatformIO.', vim.log.levels.ERROR) + return + end + backend.pick_framework(frameworks, on_select) end function M.pick_library(libraries, on_select) - local backend = get_backend() - if not backend then - vim.notify('No picker backend available for PlatformIO.', vim.log.levels.ERROR) - return - end - backend.pick_library(libraries, on_select) + local backend = get_backend() + if not backend then + vim.notify('No picker backend available for PlatformIO.', vim.log.levels.ERROR) + return + end + backend.pick_library(libraries, on_select) end function M.pick_terminal(terminals, on_select) - local backend = get_backend() - if not backend then - vim.notify('No picker backend available for PlatformIO.', vim.log.levels.ERROR) - return - end - backend.pick_terminal(terminals, on_select) + local backend = get_backend() + if not backend then + vim.notify('No picker backend available for PlatformIO.', vim.log.levels.ERROR) + return + end + backend.pick_terminal(terminals, on_select) +end + +function M.pick_env(envs, on_select) + local backend = get_backend() + if not backend then + vim.notify('No picker backend available for PlatformIO.', vim.log.levels.ERROR) + return + end + backend.pick_env(envs, on_select) end return M diff --git a/lua/platformio/pickers/telescope.lua b/lua/platformio/pickers/telescope.lua index d180099..8ab29e6 100644 --- a/lua/platformio/pickers/telescope.lua +++ b/lua/platformio/pickers/telescope.lua @@ -11,201 +11,224 @@ local previewers = require('telescope.previewers') local utils = require('platformio.utils') local function boardentry_maker(opts) - local displayer = entry_display.create({ - separator = '▏', - items = { - { width = 35 }, - { width = 20 }, - { width = 15 }, - }, - }) - - local make_display = function(entry) - return displayer({ - entry.value.name, - entry.value.vendor, - entry.value.platform, + local displayer = entry_display.create({ + separator = '▏', + items = { + { width = 35 }, + { width = 20 }, + { width = 15 }, + }, }) - end - return function(entry) - return make_entry.set_default_entry_mt({ - value = { - id = entry.id, - name = entry.name, - vendor = entry.vendor, - platform = entry.platform, - data = entry, - }, - ordinal = entry.name .. ' ' .. entry.vendor .. ' ' .. entry.platform, - display = make_display, - }, opts) - end + local make_display = function(entry) + return displayer({ + entry.value.name, + entry.value.vendor, + entry.value.platform, + }) + end + + return function(entry) + return make_entry.set_default_entry_mt({ + value = { + id = entry.id, + name = entry.name, + vendor = entry.vendor, + platform = entry.platform, + data = entry, + }, + ordinal = entry.name .. ' ' .. entry.vendor .. ' ' .. entry.platform, + display = make_display, + }, opts) + end end local function libentry_maker(opts) - local displayer = entry_display.create({ - separator = '▏', - items = { - { width = 20 }, - { width = 20 }, - { remaining = true }, - }, - }) - - local make_display = function(entry) - return displayer({ - entry.value.name, - entry.value.owner, - entry.value.description, + local displayer = entry_display.create({ + separator = '▏', + items = { + { width = 20 }, + { width = 20 }, + { remaining = true }, + }, }) - end - return function(entry) - return make_entry.set_default_entry_mt({ - value = { - name = entry.name, - owner = entry.owner and entry.owner.username or '', - description = entry.description, - data = entry, - }, - ordinal = (entry.name or '') .. ' ' .. (entry.owner and entry.owner.username or '') .. ' ' .. (entry.description or ''), - display = make_display, - }, opts) - end + local make_display = function(entry) + return displayer({ + entry.value.name, + entry.value.owner, + entry.value.description, + }) + end + + return function(entry) + return make_entry.set_default_entry_mt({ + value = { + name = entry.name, + owner = entry.owner and entry.owner.username or '', + description = entry.description, + data = entry, + }, + ordinal = (entry.name or '') .. ' ' .. (entry.owner and entry.owner.username or '') .. ' ' .. (entry.description or ''), + display = make_display, + }, opts) + end end function M.pick_framework(frameworks, on_select) - local opts = {} - pickers - .new(opts, { - prompt_title = 'frameworks', - finder = finders.new_table({ - results = frameworks, - }), - attach_mappings = function(prompt_bufnr, _) - actions.select_default:replace(function() - actions.close(prompt_bufnr) - local selection = action_state.get_selected_entry() - if selection then - on_select(selection[1] or selection.value) - end - end) - return true - end, - sorter = telescope_conf.generic_sorter(opts), - }) - :find() + local opts = {} + pickers + .new(opts, { + prompt_title = 'frameworks', + finder = finders.new_table({ + results = frameworks, + }), + attach_mappings = function(prompt_bufnr, _) + actions.select_default:replace(function() + actions.close(prompt_bufnr) + local selection = action_state.get_selected_entry() + if selection then + on_select(selection[1] or selection.value) + end + end) + return true + end, + sorter = telescope_conf.generic_sorter(opts), + }) + :find() end function M.pick_board(boards, on_select) - local opts = {} - pickers - .new(opts, { - prompt_title = 'Boards', - finder = finders.new_table({ - results = boards, - entry_maker = opts.entry_maker or boardentry_maker(opts), - }), - attach_mappings = function(prompt_bufnr, _) - actions.select_default:replace(function() - actions.close(prompt_bufnr) - local selection = action_state.get_selected_entry() - if selection and selection.value then - on_select(selection.value.data) - end - end) - return true - end, - previewer = previewers.new_buffer_previewer({ - title = 'Board Info', - define_preview = function(self, entry, _) - local json = utils.strsplit(vim.inspect(entry.value.data), '\n') - local bufnr = self.state.bufnr - vim.api.nvim_buf_set_lines(bufnr, 0, -1, false, json) - vim.api.nvim_set_option_value('filetype', 'lua', { buf = bufnr }) - vim.defer_fn(function() - local win = self.state.winid - vim.api.nvim_set_option_value('wrap', true, { scope = 'local', win = win }) - vim.api.nvim_set_option_value('linebreak', true, { scope = 'local', win = win }) - vim.api.nvim_set_option_value('wrapmargin', 2, { buf = bufnr }) - end, 0) - end, - }), - sorter = telescope_conf.generic_sorter(opts), - }) - :find() + local opts = {} + pickers + .new(opts, { + prompt_title = 'Boards', + finder = finders.new_table({ + results = boards, + entry_maker = opts.entry_maker or boardentry_maker(opts), + }), + attach_mappings = function(prompt_bufnr, _) + actions.select_default:replace(function() + actions.close(prompt_bufnr) + local selection = action_state.get_selected_entry() + if selection and selection.value then + on_select(selection.value.data) + end + end) + return true + end, + previewer = previewers.new_buffer_previewer({ + title = 'Board Info', + define_preview = function(self, entry, _) + local json = utils.strsplit(vim.inspect(entry.value.data), '\n') + local bufnr = self.state.bufnr + vim.api.nvim_buf_set_lines(bufnr, 0, -1, false, json) + vim.api.nvim_set_option_value('filetype', 'lua', { buf = bufnr }) + vim.defer_fn(function() + local win = self.state.winid + vim.api.nvim_set_option_value('wrap', true, { scope = 'local', win = win }) + vim.api.nvim_set_option_value('linebreak', true, { scope = 'local', win = win }) + vim.api.nvim_set_option_value('wrapmargin', 2, { buf = bufnr }) + end, 0) + end, + }), + sorter = telescope_conf.generic_sorter(opts), + }) + :find() end function M.pick_library(libraries, on_select) - local opts = {} - pickers - .new(opts, { - prompt_title = 'Libraries', - finder = finders.new_table({ - results = libraries, - entry_maker = opts.entry_maker or libentry_maker(opts), - }), - attach_mappings = function(prompt_bufnr, _) - actions.select_default:replace(function() - actions.close(prompt_bufnr) - local selection = action_state.get_selected_entry() - if selection and selection.value then - on_select(selection.value.data) - end - end) - return true - end, - previewer = previewers.new_buffer_previewer({ - title = 'Package Info', - define_preview = function(self, entry, _) - local json = utils.strsplit(vim.inspect(entry.value.data), '\n') - local bufnr = self.state.bufnr - vim.api.nvim_buf_set_lines(bufnr, 0, -1, false, json) - vim.api.nvim_set_option_value('filetype', 'lua', { buf = bufnr }) - vim.defer_fn(function() - local win = self.state.winid - vim.api.nvim_set_option_value('wrap', true, { scope = 'local', win = win }) - vim.api.nvim_set_option_value('linebreak', true, { scope = 'local', win = win }) - vim.api.nvim_set_option_value('wrapmargin', 2, { buf = bufnr }) - end, 0) - end, - }), - sorter = telescope_conf.generic_sorter(opts), - }) - :find() + local opts = {} + pickers + .new(opts, { + prompt_title = 'Libraries', + finder = finders.new_table({ + results = libraries, + entry_maker = opts.entry_maker or libentry_maker(opts), + }), + attach_mappings = function(prompt_bufnr, _) + actions.select_default:replace(function() + actions.close(prompt_bufnr) + local selection = action_state.get_selected_entry() + if selection and selection.value then + on_select(selection.value.data) + end + end) + return true + end, + previewer = previewers.new_buffer_previewer({ + title = 'Package Info', + define_preview = function(self, entry, _) + local json = utils.strsplit(vim.inspect(entry.value.data), '\n') + local bufnr = self.state.bufnr + vim.api.nvim_buf_set_lines(bufnr, 0, -1, false, json) + vim.api.nvim_set_option_value('filetype', 'lua', { buf = bufnr }) + vim.defer_fn(function() + local win = self.state.winid + vim.api.nvim_set_option_value('wrap', true, { scope = 'local', win = win }) + vim.api.nvim_set_option_value('linebreak', true, { scope = 'local', win = win }) + vim.api.nvim_set_option_value('wrapmargin', 2, { buf = bufnr }) + end, 0) + end, + }), + sorter = telescope_conf.generic_sorter(opts), + }) + :find() end function M.pick_terminal(terminals, on_select) - local opts = {} - pickers - .new(opts, { - prompt_title = 'PIO terminals', - finder = finders.new_table({ - results = terminals, - entry_maker = function(entry) - local is_hidden = vim.api.nvim_buf_is_loaded(entry.term.bufnr) and (vim.fn.bufwinid(entry.term.bufnr) == -1) - local label = string.format('%d:%s (hidden: %s)', entry.term.id, entry.termtype, tostring(is_hidden)) - return { - value = entry, - display = label, - ordinal = label, - } - end, - }), - attach_mappings = function(prompt_bufnr, _) - actions.select_default:replace(function() - actions.close(prompt_bufnr) - local selection = action_state.get_selected_entry() - if selection and selection.value then - on_select(selection.value) - end - end) - return true - end, - sorter = telescope_conf.generic_sorter(opts), - }) - :find() + local opts = {} + pickers + .new(opts, { + prompt_title = 'PIO terminals', + finder = finders.new_table({ + results = terminals, + entry_maker = function(entry) + local is_hidden = vim.api.nvim_buf_is_loaded(entry.term.bufnr) and (vim.fn.bufwinid(entry.term.bufnr) == -1) + local label = string.format('%d:%s (hidden: %s)', entry.term.id, entry.termtype, tostring(is_hidden)) + return { + value = entry, + display = label, + ordinal = label, + } + end, + }), + attach_mappings = function(prompt_bufnr, _) + actions.select_default:replace(function() + actions.close(prompt_bufnr) + local selection = action_state.get_selected_entry() + if selection and selection.value then + on_select(selection.value) + end + end) + return true + end, + sorter = telescope_conf.generic_sorter(opts), + }) + :find() +end + +function M.pick_env(envs, on_select) + local opts = {} + pickers + .new(opts, { + prompt_title = 'Environments', + finder = finders.new_table({ + results = envs, + }), + attach_mappings = function(prompt_bufnr, _) + actions.select_default:replace(function() + actions.close(prompt_bufnr) + local selection = action_state.get_selected_entry() + if selection and selection.value then + on_select(selection.value) + end + end) + return true + end, + sorter = telescope_conf.generic_sorter(opts), + }) + :find() end return M diff --git a/lua/platformio/pickers/ui_select.lua b/lua/platformio/pickers/ui_select.lua index aa2ead8..0337a6f 100644 --- a/lua/platformio/pickers/ui_select.lua +++ b/lua/platformio/pickers/ui_select.lua @@ -1,62 +1,72 @@ local M = {} local function board_label(board) - return string.format('%s | %s | %s', board.name or '', board.vendor or '', board.platform or '') + return string.format('%s | %s | %s', board.name or '', board.vendor or '', board.platform or '') end function M.pick_framework(frameworks, on_select) - vim.ui.select(frameworks, { - prompt = 'Select framework:', - format_item = function(item) - return item - end, - }, function(chosen) - if chosen then - on_select(chosen) - end - end) + vim.ui.select(frameworks, { + prompt = 'Select framework:', + format_item = function(item) + return item + end, + }, function(chosen) + if chosen then + on_select(chosen) + end + end) end function M.pick_board(boards, on_select) - vim.ui.select(boards, { - prompt = 'Select board:', - format_item = board_label, - }, function(chosen) - if chosen then - on_select(chosen) - end - end) + vim.ui.select(boards, { + prompt = 'Select board:', + format_item = board_label, + }, function(chosen) + if chosen then + on_select(chosen) + end + end) end function M.pick_library(libraries, on_select) - vim.ui.select(libraries, { - prompt = 'Select library:', - format_item = function(item) - local owner = (item.owner and item.owner.username) or '' - return string.format('%s | %s | %s', item.name or '', owner, item.description or '') - end, - }, function(chosen) - if chosen then - on_select(chosen) - end - end) + vim.ui.select(libraries, { + prompt = 'Select library:', + format_item = function(item) + local owner = (item.owner and item.owner.username) or '' + return string.format('%s | %s | %s', item.name or '', owner, item.description or '') + end, + }, function(chosen) + if chosen then + on_select(chosen) + end + end) end function M.pick_terminal(terminals, on_select) - vim.ui.select(terminals, { - prompt = 'Select a PIO terminal window:', - kind = 'PioTerminals', - format_item = function(item) - local is_hidden = vim.api.nvim_buf_is_loaded(item.term.bufnr) and (vim.fn.bufwinid(item.term.bufnr) == -1) - return string.format('%d:%s (hidden: %s)', item.term.id, item.termtype, tostring(is_hidden)) - end, - }, function(chosen) - if chosen then - on_select(chosen) - else - on_select(nil) - end - end) + vim.ui.select(terminals, { + prompt = 'Select a PIO terminal window:', + kind = 'PioTerminals', + format_item = function(item) + local is_hidden = vim.api.nvim_buf_is_loaded(item.term.bufnr) and (vim.fn.bufwinid(item.term.bufnr) == -1) + return string.format('%d:%s (hidden: %s)', item.term.id, item.termtype, tostring(is_hidden)) + end, + }, function(chosen) + if chosen then + on_select(chosen) + else + on_select(nil) + end + end) +end + +function M.pick_env(envs, on_select) + vim.ui.select(envs, { + prompt = 'Select an environment to use as default:', + }, function(chosen) + if chosen then + on_select(chosen) + end + end) end return M diff --git a/lua/platformio/piocmd.lua b/lua/platformio/piocmd.lua index 0f5fde5..5450d8a 100644 --- a/lua/platformio/piocmd.lua +++ b/lua/platformio/piocmd.lua @@ -1,4 +1,5 @@ local utils = require('platformio.utils') +local env = require('platformio.pioenv') local M = {} function M.piocmd(cmd_table, direction) @@ -15,6 +16,9 @@ function M.piocmd(cmd_table, direction) for _, v in pairs(cmd_table) do cmd = cmd .. ' ' .. v end + if env.command_accepts_flag(cmd_table[1]) then + cmd = cmd .. env.get_flag() + end utils.ToggleTerminal(cmd, direction) end end diff --git a/lua/platformio/piodebug.lua b/lua/platformio/piodebug.lua index d3786e5..67bb563 100644 --- a/lua/platformio/piodebug.lua +++ b/lua/platformio/piodebug.lua @@ -1,4 +1,5 @@ local utils = require('platformio.utils') +local env = require('platformio.pioenv') local M = {} function M.piodebug(args_table) @@ -8,7 +9,7 @@ function M.piodebug(args_table) utils.cd_pioini() - local command = 'pio debug --interface=gdb -- -x .pioinit' + local command = 'pio debug --interface=gdb ' .. env.get_flag() .. ' -- -x .pioinit' -- utils.extra -- local command = string.format('pio debug --interface=gdb -- -x .pioinit %s', utils.extra) utils.ToggleTerminal(command, 'float') end diff --git a/lua/platformio/pioenv.lua b/lua/platformio/pioenv.lua new file mode 100644 index 0000000..7968193 --- /dev/null +++ b/lua/platformio/pioenv.lua @@ -0,0 +1,146 @@ +local utils = require('platformio.utils') +local picker = require('platformio.pickers') +local M = { + default_env = 'none', +} +local config = require('platformio').config + +--- changes symlink if feasible. +function M.change_compiledb_symlink(env) + local pathsep = '/' + if utils.is_windows then + pathsep = '\\' + end + if M.default_env == 'none' then + vim.notify('compiledb does not exist for env ' .. M.default_env, vim.log.levels.ERROR, opts) + return + end + utils.cd_pioini() + local compile_commands_filename = 'compile_commands.json' + local compile_commands_path = '.pio' .. pathsep .. 'build' .. pathsep .. M.default_env .. pathsep .. compile_commands_filename + if not utils.file_exists(compile_commands_path) then + vim.notify(compile_commands_path .. ' does not exist to link it', vim.log.levels.ERROR, opts) + return + end + if utils.file_exists(compile_commands_filename) then + if not os.remove(compile_commands_filename) then + vim.notify(compile_commands_filename .. ' did not get removed', vim.log.levels.ERROR) + return + end + end + if config.clangd_source == 'compiledb' and utils.file_exists(compile_commands_path) then + if utils.is_windows then + os.execute('mklink ' .. compile_commands_filename .. ' ' .. compile_commands_path) + else + os.execute('ln -s ' .. compile_commands_path) + end + end +end + +function M.pioenv() + --- @type vim.log.levels + local loglevel = vim.log.levels.INFO + utils.cd_pioini() + + local cmd + -- TODO: execute target list command + if utils.is_windows then + cmd = 'pio run --list-targets' + else + cmd = 'grep -F "[env:" < platformio.ini | sed "s/\\[env://" | sed "s/\\]//"' + end + --- @type file*? + local stdio_stream + stdio_stream, _ = io.popen(cmd, 'r') + -- TODO: error checking + if not stdio_stream then + vim.notify('opening stdio or executing the cmd ' .. cmd .. 'failed', vim.log.levels.ERROR) + return + end + + io.input(stdio_stream) + -- vim.notify(io.read('*a'), vim.log.levels.INFO) + + -- table layout: + -- table header + -- ---------------------- + -- env_name_without_spaces some garbage + -- + -- env_name_without_spaces some garbage + -- ... + + -- discard the first few lines, since they are just table headers and decorators + -- _ = stdio_stream.read(stdio_stream, '*l') + -- _ = stdio_stream.read(stdio_stream, '*l') + + --- @type string[] + local envs = {} + --- @type integer | nil + local env_name_end + if utils.is_windows then + _ = stdio_stream.read(stdio_stream, '*line') + _ = stdio_stream.read(stdio_stream, '*line') + end + for line in stdio_stream.lines(stdio_stream, '*l') do -- readmode is for the output of lines as var `line` + if utils.is_windows then + env_name_end, _ = string.find(line, ' ', 2) -- if cmd succeeds, the env name has to be at least 1 char long and contains no spaces. skip the first one and search for space + env_name_end = env_name_end - 1 + if env_name_end then -- would start at 1, regardless of start index, so we don't need to differentiate between 0 and nil + table.insert(envs, string.sub(line, 1, env_name_end)) + else + vim.notify('formatting pio output failed on finding the first space char', vim.log.levels.ERROR) + io.close(stdio_stream) + return + end + _ = stdio_stream.read(stdio_stream, '*line') + else + table.insert(envs, line) + end + end + + table.insert(envs, 'none') + io.close(stdio_stream) + -- TODO: execute picker + picker.pick_env(envs, function(selected_env) + M.default_env = selected_env + M.change_compiledb_symlink() + end) +end + +--- function to use for other modules to get the env flag +---@return string env_flag either an empty string, or a string with the flag +function M.get_flag() + if M.default_env ~= 'none' then + return ' -e ' .. M.default_env + end + return '' +end + +--- function to determine if a pio-command accepts the env flag +---@param cmd string name of command that will be run +---@return boolean accepts_flag is true if cmd accepts the env flag +function M.command_accepts_flag(cmd) + local true_table = { + access = false, + account = false, + boards = false, + check = true, + ci = true, + debug = true, + device = false, + home = false, + org = false, + pkg = false, + project = false, + remote = false, + run = true, + setting = false, + system = false, + team = false, + test = true, + upgrade = false, + } + return true_table[cmd] +end + +return M diff --git a/lua/platformio/pioinit.lua b/lua/platformio/pioinit.lua index 6cee0d3..2cbb0f9 100644 --- a/lua/platformio/pioinit.lua +++ b/lua/platformio/pioinit.lua @@ -36,21 +36,21 @@ function M.pioinit() -- Read stdout local command = 'pio boards --json-output' - local handel = io.popen(command .. utils.devNul) - if not handel then + local handle = io.popen(command .. utils.devNul) + if not handle then return end - local json_str = handel:read('*a') - handel:close() + local json_str = handle:read('*a') + handle:close() if #json_str == 0 then -- read stderr - handel = io.popen(command .. ' 2>&1') - if not handel then + handle = io.popen(command .. ' 2>&1') + if not handle then return end - local command_output = handel:read('*a') - handel:close() + local command_output = handle:read('*a') + handle:close() vim.notify('Some error occured while executing `' .. command .. "`', command output: \n", vim.log.levels.WARN) print(command_output) return diff --git a/lua/platformio/piolsp.lua b/lua/platformio/piolsp.lua index fac211e..f22ceb7 100644 --- a/lua/platformio/piolsp.lua +++ b/lua/platformio/piolsp.lua @@ -117,6 +117,7 @@ function M.piolsp() if config.lsp == 'clangd' then M.gen_clangd_config() gitignore_lsp_configs('compile_commands.json') + -- TODO: check for file first os.remove(vim.fs.joinpath(vim.g.platformioRootDir, '.ccls')) else gitignore_lsp_configs('.ccls') diff --git a/lua/platformio/piorun.lua b/lua/platformio/piorun.lua index 89020f2..5a39555 100644 --- a/lua/platformio/piorun.lua +++ b/lua/platformio/piorun.lua @@ -1,28 +1,29 @@ local M = {} local utils = require('platformio.utils') +local env = require('platformio.pioenv') function M.piobuild() utils.cd_pioini() - local command = 'pio run' -- .. utils.extra + local command = 'pio run' .. env.get_flag() -- .. utils.extra utils.ToggleTerminal(command, 'float') end function M.pioupload() utils.cd_pioini() - local command = 'pio run --target upload' -- .. utils.extra + local command = 'pio run --target upload' .. env.get_flag() -- .. utils.extra utils.ToggleTerminal(command, 'float') end function M.piouploadfs() utils.cd_pioini() - local command = 'pio run --target uploadfs' -- .. utils.extra + local command = 'pio run --target uploadfs' .. env.get_flag() -- .. utils.extra utils.ToggleTerminal(command, 'float') end function M.pioclean() utils.cd_pioini() - local command = 'pio run --target clean' -- .. utils.extra + local command = 'pio run --target clean' .. env.get_flag() -- .. utils.extra utils.ToggleTerminal(command, 'float') end diff --git a/lua/platformio/utils.lua b/lua/platformio/utils.lua index 83f8608..df15736 100644 --- a/lua/platformio/utils.lua +++ b/lua/platformio/utils.lua @@ -1,5 +1,10 @@ local M = {} +--- @alias userdir +--- | '"data"' +--- | '"state"' +--- | '"cache"' + local config = require('platformio').config -- M.extra = 'printf \'\\\\n\\\\033[0;33mPlease Press ENTER to continue \\\\033[0m\'; read' @@ -24,14 +29,14 @@ local function pathmul(n) end ------------------------------------------------------ -local is_windows = jit.os == 'Windows' +M.is_windows = jit.os == 'Windows' -M.devNul = is_windows and ' 2>./nul' or ' 2>/dev/null' +M.devNul = M.is_windows and ' 2>./nul' or ' 2>/dev/null' -- INFO: get current OS enter function M.enter() local shell = vim.o.shell - if is_windows then + if M.is_windows then return vim.fn.executable('pwsh') and '\r' or '\r\n' elseif shell:find('nu') then return '\r' @@ -351,9 +356,9 @@ function M.cd_pioini() end function M.pio_install_check() - local handel = (jit.os == 'Windows') and assert(io.popen('where.exe pio 2>./nul')) or assert(io.popen('which pio 2>/dev/null')) - local pio_path = assert(handel:read('*a')) - handel:close() + local handle = (jit.os == 'Windows') and assert(io.popen('where.exe pio 2>./nul')) or assert(io.popen('which pio 2>/dev/null')) + local pio_path = assert(handle:read('*a')) + handle:close() if #pio_path == 0 then vim.notify('Platformio not found in the path', vim.log.levels.ERROR) @@ -397,4 +402,31 @@ function M.shell_cmd_blocking(command) return result end +--- gets the os user data dir for windows or linux +---@return string data_dir_path +function M.get_os_user_data_dir() + --- @type string + local os_dirname, path_separator + if M.is_windows then + path_separator = '\\' + os_dirname = 'LOCALAPPDATA' + else + path_separator = '/' + os_dirname = 'XDG_STATE_HOME' + end + return os.getenv(os_dirname) .. path_separator .. 'nvim' .. path_separator .. 'nvim-platformio' +end + +--- creates the user data dir conditionally, based on its existence. +---@return string data_dir_path for performance +function M.make_os_user_data_dir() + local data_dir_path = M.get_os_user_data_dir() + local cmd = 'mkdir ' .. data_dir_path + if not M.is_windows then + cmd = cmd .. ' -p' + end + os.execute(cmd) + return data_dir_path +end + return M diff --git a/plugin/platformio.lua b/plugin/platformio.lua index 2373403..9c526bb 100644 --- a/plugin/platformio.lua +++ b/plugin/platformio.lua @@ -95,3 +95,7 @@ end, {}) vim.api.nvim_create_user_command('PioTermList', function() require('platformio.piotermlist').piotermlist() end, {}) + +vim.api.nvim_create_user_command('Pioenv', function() + require('platformio.pioenv').pioenv() +end, {})