import sublime import sublime_plugin import os, re import json from .setting import SfBasicConfig from .uiutil import SublConsole from . import util SFDX_SETTINGS = "sfdx.sublime-settings" class OpenSfdxSettingCommand(sublime_plugin.WindowCommand): def run(self): SETTING_PATH = os.path.join(sublime.packages_path(), "User", SFDX_SETTINGS) if not os.path.exists(SETTING_PATH): s = sublime.load_settings(SFDX_SETTINGS) tasks = s.get("tasks") custom_env = s.get("custom_env") s.set("tasks", tasks) s.set("custom_env", custom_env) sublime.save_settings(SFDX_SETTINGS) self.window.run_command("open_file", { "file": SETTING_PATH }) class SfdxCommand(sublime_plugin.WindowCommand): def run(self): self.sf_basic_config = SfBasicConfig() self.settings = self.sf_basic_config.get_setting() self.sublconsole = SublConsole(self.sf_basic_config) self.window = sublime.active_window() self.osutil = util.OsUtil(self.sf_basic_config) s = sublime.load_settings(SFDX_SETTINGS) tasks = s.get("tasks") self.env = s.get("custom_env") self.env.update(DxEnv().get_env()) self.env.update(CommandEnv(self.window, self.sf_basic_config.get_project_dir()).get_env()) self.sel_keys = [task["label"] for task in tasks] self.sel_vals = [task for task in tasks] self.window.show_quick_panel(self.sel_keys, self.panel_done, sublime.MONOSPACE_FONT) def panel_done(self, picked): if 0 > picked < len(self.sel_keys): return self.task = self.sel_vals[picked] is_os_termial = "os_termial" in self.task and self.task["os_termial"] if "SFDX_ALIAS" in self.task["command"]: if not self.env["SFDX_ALIAS"] or len(self.env["SFDX_ALIAS"]) == 0: self.sublconsole.showlog("sfdx alias empty! please check it!") Cmder().run(self.window, self.env, self.task["command"], console=self.sublconsole.showlog, is_os_termial=is_os_termial, encoding='UTF-8') class DxEnv(): def get_env(self): return { "SFDX_ALIAS" : self.__get_alias(), } def __get_alias(self): return list(self.__get_alias_dict().keys()) def __get_alias_dict(self): home = os.path.expanduser("~") dx_alias_file = os.path.join(home, ".sfdx", "alias.json") alias = {} try: if os.path.exists(dx_alias_file): f = open(dx_alias_file) data = json.load(f) alias = data["orgs"] f.close() except Exception as ex: pass return alias class CommandEnv(): def __init__(self, window, workspaceFolder): self.window = window self.workspaceFolder = workspaceFolder def get_env(self): # // ${selectedText} - the current selected text in the active file file = self.window.active_view().file_name() if file is None : file = "" fileBasenameNoExtension, fileExtname = os.path.splitext(os.path.basename(file)) env = { "cwd" : self.workspaceFolder, "workspaceFolder" : self.workspaceFolder, "workspaceFolderBasename" : os.path.basename(self.workspaceFolder), "file" : file, "fileBasenameNoExtension": fileBasenameNoExtension, "fileExtname": fileExtname, "relativeFile" : file.replace(self.workspaceFolder, ""), "fileBasename": os.path.basename(file), "fileDirname" : os.path.dirname(file), "selectedText" : self.__get_sel_text(), } # print(env) return env def __get_sel_text(self): try: view = self.window.active_view() sel = view.sel() region1 = sel[0] selectionText = view.substr(region1) return selectionText except Exception as ex: pass return "" class Cmder(): def run(self, window, command_env, command, console=print, is_os_termial=False, encoding='UTF-8'): self.index = 0 self.window = window self.console = console self.encoding = encoding self.is_os_termial = is_os_termial self.env = command_env self.command = command self.params = self.__get_command_params(command) self.osutil = util.OsUtil() UiWizard(command_params=self.params, window=self.window, callback=self.on_wizard_done).run() def on_wizard_done(self, user_params): command = self.command for key, val in self.env.items(): if type(val) is str: command = command.replace("${%s}" % key, val) msgs = [] for param in self.__get_sys_env(command): command = command.replace(param["param"], param["value"]) if not param["value"]: msgs.append("%s is null! please check it." % param["param"]) for param in user_params: command = command.replace(param["param"], param["value"]) if not param["value"]: msgs.append("%s is null! please check it." % param["param"]) if len(msgs) > 0: self.console("\n".join(msgs)) else: self.console(command) cmds = [self.osutil.get_cd_cmd(self.env["workspaceFolder"]), command] if self.is_os_termial: self.osutil.run_in_os_termial(cmds) else: self.osutil.run_in_sublime_cmd(cmds, encoding=self.encoding) def __get_sys_env(self, command): pattern = r"\${(env)(\s)*:(\s)*([^} ]+)(\s)*}" matchedList = re.findall(pattern, command) sys_env = [] if matchedList: for param in matchedList: key = param[3] sys_env.append({ "param" : "${%s%s:%s%s%s}" % param, "key" : key, "value" : os.getenv(key, default=""), "type" : param[0] }) return sys_env def __get_command_params(self, command): pattern = r"\${(input|select)(\s)*:(\s)*([^} ]+)(\s)*}" matchedList = re.findall(pattern, command) params = [] if matchedList: for param in matchedList: key = param[3] data = { "param" : "${%s%s:%s%s%s}" % param, "key" : key, "value" : "", "type" : param[0] } if data["type"] == "input": if key in self.env: data["value"] = str(self.env[key]) elif data["type"] == "select": data["option"] = data["option-v"] = [] if key in self.env: if isinstance(self.env[key], list): data["option"] = data["option-v"] = self.env[key] params.append(data) return params class UiWizard(): def __init__(self, command_params, window, callback): self.index = 0 self.command_params = command_params self.window = window self.callback = callback def run(self, args=None): if self.index > 0: pre_data = self.command_params[self.index-1] ui_type = pre_data["type"] if ui_type == "input": pre_data["value"] = args elif ui_type == "select": if 0 <= args and args < len(pre_data["option-v"]): pre_data["value"] = pre_data["option-v"][args] if self.index < len(self.command_params): curr_data = self.command_params[self.index] if curr_data["type"] == "input": caption = "Please Input your %s: " % curr_data["key"] self.window.show_input_panel(caption, curr_data["value"], self.run, None, None) elif curr_data["type"] == "select": show_opts = curr_data["option"] self.window.show_quick_panel(show_opts, self.run, sublime.MONOSPACE_FONT) self.index = self.index + 1 else: self.callback(self.command_params) class XyOpenUrlCommand(sublime_plugin.ApplicationCommand): def run(command, url): import webbrowser webbrowser.open_new_tab(url)