Ejemplo n.º 1
0
def render_result(result_data, test_bundle, reporter):
    # lowercase all the keys since we can't guarantee the casing coming from CFML
    # also convert floats to ints, since CFML might serialize ints to floats
    result_data = preprocess(result_data)
    padToLen = 7 if reporter == "compacttext" else 0
    result_string = sublime.expand_variables(
        RESULT_TEMPLATES[reporter]["results"], filter_stats_dict(result_data, padToLen)
    )

    for bundle in result_data["bundlestats"]:
        if len(test_bundle) and bundle["path"] != test_bundle:
            continue

        result_string += sublime.expand_variables(
            RESULT_TEMPLATES[reporter]["bundle"], filter_stats_dict(bundle)
        )

        if isinstance(bundle["globalexception"], dict):
            result_string += (
                sublime.expand_variables(
                    RESULT_TEMPLATES[reporter]["global_exception"],
                    filter_exception_dict(bundle["globalexception"]),
                )
                + "\n"
            )

        for suite in bundle["suitestats"]:
            result_string += gen_suite_report(bundle, suite, reporter)

    result_string += "\n" + RESULT_TEMPLATES[reporter]["legend"]
    return result_string
Ejemplo n.º 2
0
 def convert(m):
     quote = m.group("quote")
     if quote:
         var = sublime.expand_variables(m.group("quoted_var"), extracted_variables)
         if quote == "'":
             return "'" + escape_squote(var) + "'"
         else:
             return '"' + escape_dquote(var) + '"'
     else:
         return sublime.expand_variables(m.group("var"), extracted_variables)
Ejemplo n.º 3
0
    def run(self, args = []):

        # 替换参数中的环境变量
        env = self.window.extract_variables()
        args = [sublime.expand_variables(x, env) for x in args]

        # 获取【sublime】执行路径
        executable_path = sublime.executable_path()

        # 获取【OSX】下的【subl】目录
        if sublime.platform() == 'osx':
            app_path = executable_path[:executable_path.rfind(".app/") + 5]
            executable_path = app_path + "Contents/SharedSupport/bin/subl"

        # 运行【subl】命令
        subprocess.Popen([executable_path] + args)

        # 修复在【Windows】下窗口推动焦点
        if sublime.platform() == "windows":
            def fix_focus():
                window = sublime.active_window()
                view = window.active_view()
                window.run_command('focus_neighboring_group')
                window.focus_view(view)

            sublime.set_timeout(fix_focus, 300)
Ejemplo n.º 4
0
def build_completion_doc(function_call_params, data):
    cfdoc = dict(CFDOCS_STYLES)
    cfdoc["header"] = data["syntax"].split('(')[0] + "(...)"
    if len(data["returns"]) > 0:
        cfdoc["header"] += ":" + data["returns"]

    cfdoc["description"] = ""
    cfdoc["body"] = ""
    description_params = []
    if len(data["params"]) > 0:
        for index, param in enumerate(data["params"]):

            if function_call_params.named_params:
                active_name = function_call_params.params[function_call_params.current_index][0] or ""
                is_active = active_name.lower() == param["name"].lower()
            else:
                is_active = index == function_call_params.current_index

            if is_active:
                param_variables = {"name": param["name"], "description": param["description"].replace("\n", "<br>"), "values": ""}
                if "values" in param and len(param["values"]):
                    param_variables["values"] = "<em>values:</em> " + ", ".join([str(value) for value in param["values"]])
                if len(param_variables["description"]) > 0 or len(param_variables["values"]) > 0:
                    cfdoc["body"] = sublime.expand_variables("<p>${description}</p><p>${values}</p>", param_variables)
                description_params.append("<span class=\"active\">" + param["name"] + "</span>")
            elif param["required"]:
                description_params.append("<span class=\"required\">" + param["name"] + "</span>")
            else:
                description_params.append("<span class=\"optional\">" + param["name"] + "</span>")

        cfdoc["description"] = "(" + ", ".join(description_params) + ")"

    return cfdoc
def generate_previews(docs, current_index):
    preview_html_variables = dict(docs[current_index].preview_html_variables["html"])
    preview_html_variables["pagination"] = (
        build_pagination(current_index, len(docs)) if len(docs) > 1 else ""
    )
    html = sublime.expand_variables(PREVIEW_TEMPLATE, preview_html_variables)
    return html, docs[current_index].preview_regions
Ejemplo n.º 6
0
def build_cfdoc(function_or_tag, data):
	cfdoc = dict(CFDOCS_STYLES)
	cfdoc["links"] = [{"href": "http://cfdocs.org" + "/" + function_or_tag, "text": "cfdocs.org" + "/" + function_or_tag}]
	cfdoc["header"] = data["syntax"].replace("<","&lt;").replace(">","&gt;")
	if len(data["returns"]) > 0:
		cfdoc["header"] += ":" + data["returns"]

	cfdoc["description"] = "<div class=\"engines\">"
	for engine in sorted(CFDOCS_ENGINES):
		if engine not in data["engines"]:
			continue
		cfdoc["description"] += build_engine_span(engine, data["engines"][engine]["minimum_version"])
	cfdoc["description"] += "</div>"

	cfdoc["description"] += data["description"].replace("<","&lt;").replace(">","&gt;").replace("\n","<br>")

	cfdoc["body"] = ""
	if len(data["params"]) > 0:
		cfdoc["body"] = "<ul>"
		for param in data["params"]:
			param_variables = {"name": param["name"], "description": param["description"].replace("\n","<br>"), "values": ""}
			if "values" in param and len(param["values"]):
				param_variables["values"] = "<em>values:</em> " + ", ".join([str(value) for value in param["values"]])
			cfdoc["body"] += "<li>" + sublime.expand_variables(CFDOCS_PARAM_TEMPLATE, param_variables) + "</li>"
		cfdoc["body"] += "</ul>"

	return cfdoc
Ejemplo n.º 7
0
    def createExecDict(self, sourceDict):
        global custom_var_list

        print("hello")

        project_data = self.window.project_data()
        project_settings = (project_data or {}).get("settings", {})

        # Get the view specific settings
        view_settings = self.window.active_view().settings()

        # Variables to expnd; start with defaults, then add ours
        variables = self.window.extract_variables()

        print(type(variables))

        for custom_var in custom_var_list:
            setting = project_settings.get(custom_var, "")
            variables[custom_var] = view_settings.get(custom_var,
                                                      project_settings.get(custom_var, ""))

        # Create arguments to return by expading variables in the arguments given
        args = sublime.expand_variables(sourceDict, variables)

        # Rename the command parameter to what exec expects
        args["cmd"] = args.pop("command", [])

        return args
Ejemplo n.º 8
0
    def get_working_dir(self):
        build_systems = self.project_data()["build_systems"]

        for build_system in build_systems:
            if "working_dir" in build_system:
               return sublime.expand_variables(build_system["working_dir"], self.extract_variables())

        return None
Ejemplo n.º 9
0
def get_window_env(window: sublime.Window, config: ClientConfig):

    # Create a dictionary of Sublime Text variables
    variables = window.extract_variables()

    # Expand language server command line environment variables
    expanded_args = list(
        sublime.expand_variables(os.path.expanduser(arg), variables)
        for arg in config.binary_args
    )

    # Override OS environment variables
    env = os.environ.copy()
    for var, value in config.env.items():
        # Expand both ST and OS environment variables
        env[var] = os.path.expandvars(sublime.expand_variables(value, variables))

    return expanded_args, env
Ejemplo n.º 10
0
def build_cfdoc_html(function_or_tag, data):
	variables = { "function_or_tag": function_or_tag, "href": "http://cfdocs.org/" + function_or_tag, "params": "" }
	variables["syntax"] = data["syntax"].replace("<","&lt;").replace(">","&gt;")
	variables["description"] = data["description"].replace("<","&lt;").replace(">","&gt;").replace("\n","<br>")

	if len(data["returns"]) > 0:
		variables["syntax"] += ":" + data["returns"]

	if len(data["params"]) > 0:
		variables["params"] = "<ul>"
		for param in data["params"]:
			param_variables = {"name": param["name"], "description": param["description"].replace("\n","<br>"), "values": ""}
			if len(param["values"]):
				param_variables["values"] = "<em>values:</em> " + ", ".join([str(value) for value in param["values"]])
			variables["params"] += "<li>" + sublime.expand_variables(CFDOCS_PARAM_TEMPLATE, param_variables) + "</li>"
		variables["params"] += "</ul>"

	return sublime.expand_variables(CFDOCS_TEMPLATE, variables)
Ejemplo n.º 11
0
def render_result(result_data, test_bundle):
	# lowercase all the keys since we can't guarantee the casing coming from CFML
	result_data = lcase_keys(result_data)
	result_string = sublime.expand_variables(RESULTS_TEMPLATES["results"], filter_stats_dict(result_data)) + "\n"

	for bundle in result_data["bundlestats"]:
		if len(test_bundle) and bundle["path"] != test_bundle:
			continue

		result_string += "\n" + sublime.expand_variables(RESULTS_TEMPLATES["bundle"], filter_stats_dict(bundle)) + "\n"

		if isinstance(bundle["globalexception"], dict):
			result_string += "\n" + sublime.expand_variables(RESULTS_TEMPLATES["global_exception"], filter_exception_dict(bundle["globalexception"])) + "\n"

		for suite in bundle["suitestats"]:
			result_string += "\n" + gen_suite_report(suite)

	result_string += "\n" + RESULTS_TEMPLATES["legend"]
	return result_string
def build_pagination(current_index, total_pages):
    pagination_variables = {"current_page": str(current_index + 1), "total_pages": str(total_pages)}

    previous_index = current_index - 1 if current_index > 0 else total_pages - 1
    pagination_variables["prev"] = "page_" + str(previous_index)

    next_index = current_index + 1 if current_index < total_pages - 1 else 0
    pagination_variables["next"] = "page_" + str(next_index)

    return sublime.expand_variables(PAGINATION_TEMPLATE, pagination_variables)
Ejemplo n.º 13
0
def start_client(window: sublime.Window, project_path: str, config: ClientConfig):

    if config.name in client_start_listeners:
        handler_startup_hook = client_start_listeners[config.name]
        if not handler_startup_hook(window):
            return

    if settings.show_status_messages:
        window.status_message("Starting " + config.name + "...")
    debug("starting in", project_path)

    # Create a dictionary of Sublime Text variables
    variables = window.extract_variables()

    # Expand language server command line environment variables
    expanded_args = list(
        sublime.expand_variables(os.path.expanduser(arg), variables)
        for arg in config.binary_args
    )

    # Override OS environment variables
    env = os.environ.copy()
    for var, value in config.env.items():
        # Expand both ST and OS environment variables
        env[var] = os.path.expandvars(sublime.expand_variables(value, variables))

    # TODO: don't start process if tcp already up or command empty?
    process = start_server(expanded_args, project_path, env)
    if not process:
        window.status_message("Could not start " + config.name + ", disabling")
        debug("Could not start", config.binary_args, ", disabling")
        return None

    if config.tcp_port is not None:
        client = attach_tcp_client(config.tcp_port, process, settings)
    else:
        client = attach_stdio_client(process, settings)

    if not client:
        window.status_message("Could not connect to " + config.name + ", disabling")
        return None

    return client
Ejemplo n.º 14
0
def expandConfig(path):
	# get project name
	project_name = sublime.active_window().project_file_name()
	if project_name:
		variables = {
		   'project_dir': os.path.dirname(project_name)
		}
		# permit '${project_dir}' to allow a configuration file
		# relative to the project to be specified.
		path = sublime.expand_variables(path, variables)
	return os.path.expandvars(path)
Ejemplo n.º 15
0
def get_working_dir():
    window = sublime.active_window()

    if window.project_data():
        build_systems = window.project_data()["build_systems"]
        for build_system in build_systems:
            if "working_dir" in build_system:
               return sublime.expand_variables(build_system["working_dir"], window.extract_variables())

    view = window.active_view()
    return os.path.dirname(view.file_name())
Ejemplo n.º 16
0
 def recursive_replace(variables, value):
     if isinstance(value, str):
         value = sublime.expand_variables(value, variables)
         return os.path.expanduser(value)
     elif isinstance(value, Mapping):
         return {key: recursive_replace(variables, val)
                 for key, val in value.items()}
     elif isinstance(value, Sequence):
         return [recursive_replace(variables, item)
                 for item in value]
     else:
         return value
Ejemplo n.º 17
0
def build_completion_doc(function_call_params, data):
    cfdoc = {"side_color": SIDE_COLOR, "html": {}}
    cfdoc["html"]["header"] = build_cfdoc_header(data, False)

    cfdoc["html"]["body"] = ""

    description_params = []
    if len(data["params"]) > 0:
        for index, param in enumerate(data["params"]):

            if function_call_params.named_params:
                active_name = (
                    function_call_params.params[function_call_params.current_index][0]
                    or ""
                )
                is_active = active_name.lower() == param["name"].lower()
            else:
                is_active = index == function_call_params.current_index

            if is_active:
                param_variables = {
                    "name": param["name"],
                    "description": param["description"].replace("\n", "<br>"),
                    "values": "",
                }
                if "type" in param and len(param["type"]):
                    param_variables["name"] += ": " + param["type"]
                if "values" in param and len(param["values"]):
                    param_variables["values"] = "<em>values:</em> " + ", ".join(
                        [str(value) for value in param["values"]]
                    )
                if (
                    len(param_variables["description"]) > 0
                    or len(param_variables["values"]) > 0
                ):
                    cfdoc["html"]["body"] = sublime.expand_variables(
                        "<p>${description}</p><p>${values}</p>", param_variables
                    )
                description_params.append(
                    '<span class="active">' + param["name"] + "</span>"
                )
            elif param["required"]:
                description_params.append(
                    '<span class="required">' + param["name"] + "</span>"
                )
            else:
                description_params.append(
                    '<span class="optional">' + param["name"] + "</span>"
                )

        cfdoc["html"]["arguments"] = "(" + ", ".join(description_params) + ")"

    return cfdoc
Ejemplo n.º 18
0
def expand(view, path):
    """Expand the given path
    """

    window = view.window()
    if window is not None:
        tmp = sublime.expand_variables(path, window.extract_variables())
        tmp = os.path.expanduser(os.path.expandvars(tmp))
    else:
        return path

    return tmp
Ejemplo n.º 19
0
Archivo: DKit.py Proyecto: yazd/DKit
def start_server():
    global server_process
    global client_path

    out = call(client_path + " -q", shell=True, stdout=PIPE)
    if out == 0:
        print("Already running!")
        return

    global plugin_settings
    plugin_settings = sublime.load_settings('DKit.sublime-settings')

    global server_port
    server_port = read_settings('dcd_port', 9166)
    dcd_path = read_settings('dcd_path', '')

    global server_path
    server_path = os.path.join(dcd_path, 'dcd-server' + ('.exe' if sys.platform == 'win32' else ''))
    client_path = os.path.join(dcd_path, 'dcd-client' + ('.exe' if sys.platform == 'win32' else ''))
    server_path = sublime.expand_variables(server_path, sublime.active_window().extract_variables())
    client_path = sublime.expand_variables(client_path, sublime.active_window().extract_variables())

    if not os.path.exists(server_path):
        sublime.error_message('DCD server doesn\'t exist in the path specified:\n' + server_path + '\n\nSetup the path in DCD package settings and then restart sublime to get things working.')
        return False

    if not os.path.exists(client_path):
        sublime.error_message('DCD client doesn\'t exist in the path specified:\n' + client_path + '\n\nSetup the path in DCD package settings and then restart sublime to get things working.')
        return False

    include_paths = read_all_settings('include_paths')
    include_paths = ['-I"' + p + '"' for p in include_paths]

    args = ['"%s"' % server_path]
    args.extend(include_paths)
    args.extend(['-p' + str(server_port)])

    print('Restarting DCD server...')
    server_process = Popen(get_shell_args(args), shell=True)
    return True
Ejemplo n.º 20
0
def pep8_params():
    """Return params for the autopep8 module."""
    user_settings = get_user_settings()
    env_vars = sublime.active_window().extract_variables()

    params = ['-d']  # args for preview
    # read settings
    for opt in AUTOPEP8_OPTIONS:
        opt_value = user_settings.get(opt, '')
        if opt_value == '' or opt_value is None:
            continue
        if opt_value and opt in ('exclude', 'global-config'):
            opt_value = sublime.expand_variables(opt_value, env_vars)

        if opt in ('exclude', 'global-config'):
            if opt_value:
                opt_value = sublime.expand_variables(opt_value, env_vars)
                params.append('--{0}={1}'.format(opt, opt_value))
        elif opt in ('ignore', 'select'):
            # remove white spaces as autopep8 does not trim them
            opt_value = ','.join(param.strip()
                                 for param in opt_value.split(','))
            params.append('--{0}={1}'.format(opt, opt_value))
        elif opt in ('ignore-local-config', 'hang-closing'):
            if opt_value:
                params.append('--{0}'.format(opt))
        else:
            params.append('--{0}={1}'.format(opt, opt_value))

    # use verbose==2 to catch non-fixed issues
    params.extend(['--verbose'] * 2)

    # autopep8.parse_args required at least one positional argument,
    # fake-file parent folder is used as location for local configs.
    params.append(sublime.expand_variables('${folder}/fake-file', env_vars))

    logger.info('pep8_params: %s', params)
    args = autopep8.parse_args(params, apply_config=True)
    return args
Ejemplo n.º 21
0
    def run(self, edit, saving=False):

        view = self.view
        global_settings = sublime.load_settings(__name__ + '.sublime-settings')
        build_on_save = view.settings().get('build_on_save', global_settings.get('build_on_save', False))
        filter_execute = view.settings().get('filter_execute', global_settings.get('filter_execute', []))

        if saving and not build_on_save:
            return

        for filter, execute in filter_execute:
            if re.search(filter, view.file_name()):
                view.window().run_command("exec", {"cmd": sublime.expand_variables(execute,view.window().extract_variables())})
Ejemplo n.º 22
0
  def get_opt(view):
    settings = Complete.get_settings()
    additional_lang_opts = settings.get("additional_language_options", {})
    language = get_language(view)
    project_settings = view.settings()
    include_opts = settings.get("include_options", []) + project_settings.get("cc_include_options", [])

    # seach for .clang_complete file and add lines to options
    target_file = ".clang_complete"
    directory = os.path.dirname(view.file_name())
    path = os.path.join(directory, target_file)
    target_exists = False

    # search up the tree from the active file
    i = 0
    while(directory != os.path.dirname(directory) and i < 15):
      target_exists = os.path.isfile(path)
      if target_exists == True:
        break;
      directory = os.path.dirname(directory)
      path = os.path.join(directory, target_file)
      i = i + 1

    if os.path.isfile(path) == True:
      print("adding options from ", path)

      lines = [line.rstrip('\n') for line in open(path)]

      # resolve relative paths in options
      for line in lines:
        m = re.match("(-I)([^$]+)", line)
        if m != None and os.path.isabs(m.group(2)) == False:
          absOptPath = os.path.join(os.path.dirname(path), m.group(2))
          line = m.group(1) + absOptPath
        include_opts = include_opts + [line]

    window = sublime.active_window()
    variables = window.extract_variables()
    include_opts = sublime.expand_variables(include_opts, variables)

    opt = [drivers[language]]
    if language in additional_lang_opts:
      for v in additional_lang_opts[language]:
        opt.append(v)

    for v in include_opts:
      opt.append(v)
    print("clang options: ", opt)
    return opt
Ejemplo n.º 23
0
def expand_variables(str, vars):
    try:
        return sublime.expand_variables(str, vars)
    except AttributeError as e:
        def repl(match):
            replacement = vars.get(match.group(1), None)

            if replacement is None:
                default = match.group(2)
                if default is not None:
                    return expand_variables(default,vars)

            return replacement

        return re.sub(r'\${([\w-]+)(?:[^}]*)?}', repl, str)
Ejemplo n.º 24
0
def replace_variables(value, variables):
    if hasattr(sublime, "expand_variables"):  # ST3, Build 3068
        # stringify dict
        for k in variables.keys():
            variables[k] = str(variables[k])
        return sublime.expand_variables(value, variables)
    else:
        # sort keys after length, to get $file_path before $file
        keys = list(variables.keys())
        keys.sort(key=len, reverse=True)
        for k in keys:
            key = "${%s}" % k
            if key in value:
                value = value.replace(key, str(variables[k]))
    return value
Ejemplo n.º 25
0
    def expand_all(input_path, wildcard_values={}, current_folder=''):
        """Expand everything in this path.

        This returns a list of canonical paths.
        """
        expanded_path = path.expandvars(input_path)
        expanded_path = sublime.expand_variables(expanded_path, wildcard_values)
        expanded_path = File.canonical_path(expanded_path, current_folder)
        from glob import glob
        all_paths = glob(expanded_path)
        if len(all_paths) > 0 and all_paths[0] != input_path:
            log.debug("Populated '%s' to '%s'", input_path, all_paths)
            return all_paths
        elif expanded_path != input_path:
            log.debug("Populated '%s' to '%s'", input_path, expanded_path)
        return [expanded_path]
Ejemplo n.º 26
0
 def get_completions(self, view, prefix):
     skip_deleted = Pref.forget_deleted_files
     # completion import files
     if view.scope_name(view.sel()[0].a) == "source.mac import.file.mac ":
         currentImport = [os.path.splitext(basename(view.substr(s).lower().strip()))[0] for s in view.find_by_selector('import.file.mac')]
         pfiles = self.ffiles
         lfile = [self.create_var_completion(os.path.splitext(basename(fil))[0],"File") for fil in pfiles if os.path.splitext(basename(fil.lower()))[0] not in currentImport]
         lfile = self.without_duplicates(list(lfile))
         lfile.sort()
         return lfile
     # start with default completions
     completions = list(Pref.always_on_auto_completions)
     # word completion from xml
     if "string.quoted.double" in view.scope_name(view.sel()[0].a):
         for stype, word in self.filesxml.items():
             for x in word:
                 completions.append(self.create_var_completion(x, stype))
     else:
         self.get_files_import(view.file_name(), True)
         # append these from indexed files
         already_in = []
         for file, data in self.files.items():
             if basename(file).lower() not in already_im or norm_path_string(
                 sublime.expand_variables("$folder", sublime.active_window().extract_variables())) not in file.lower():
                 continue
             if not skip_deleted or (skip_deleted and os.path.lexists(file)):
                 location = basename(file)
                 for function in data:
                     if prefix.lower() in function[self.NAME].lower():
                         already_in.append(function[self.NAME])
                         completion = self.create_function_completion(
                             function, location)
                         completions.append(completion)
         # current file
         location = basename(view.file_name()) if view.file_name() else ''
         if debug:
             print (view.file_name())
         # append functions from current view that yet have not been saved
         [completions.append(self.create_function_completion(self.parse_line(view.substr(view.line(selection))), location)) for selection in view.find_by_selector('entity.name.function') if view.substr(selection) not in already_in and (already_in.append(view.substr(selection)) or True)]
         # append "var" names from current file
         vars = []
         [view.substr(selection) for selection in view.find_all('([var\s+]|\.|\()(\w+)\s*[=|:]', 0, '$2', vars)]
         [completions.append(self.create_var_completion(var, location)) for var in list(set(vars)) if len(var) > 1 and var not in already_in and (already_in.append(var) or True)]
         # append "globals from CommonVariables.mac"
         [completions.append(self.create_var_completion(var, "Global")) for var in list(set(self.get_globals(view))) if len(var) > 1 and var not in already_in]
         completions = self.without_duplicates(completions)
     return completions
Ejemplo n.º 27
0
  def command_variables(args, view, command, format=True):
    if format and args.get("format"):
      command = args["format"].replace('${input}', command)

    for region in view.sel():
      (row,col) = view.rowcol(view.sel()[0].begin())

      command = command.replace('${row}', str(row+1))
      command = command.replace('${region}', view.substr(region))
      break

    # packages, platform, file, file_path, file_name, file_base_name,
    # file_extension, folder, project, project_path, project_name,
    # project_base_name, project_extension.
    command = sublime.expand_variables(command, sublime.active_window().extract_variables())

    return command
Ejemplo n.º 28
0
def expandVariables(window, *strs, forSublime=True, forEnv=True):
    view = window.active_view()
    sublimeVariables = window.extract_variables()

    extendVariables = {k: kFn(view) for k, kFn in _extendVariableKeys.items()}

    for cmd, cmdFn in _extendVariableCmds.items():
        extendVariables.update({
            k+cmd: cmdFn(v) for k, v in sublimeVariables.items()
        })

    sublimeVariables.update(extendVariables)

    retStrs = [sublime.expand_variables(s, sublimeVariables)
               for s in strs] if forSublime else strs
    retStrs = Os.expandVariables(*retStrs) if forEnv else retStrs

    return retStrs
    def split_match(self, match):
        """Override to ignore errors reported in imported files."""
        match, line, col, error, warning, message, near = super().split_match(match)

        folders = sublime.expand_variables("$folder", sublime.active_window().extract_variables())
        project_data = sublime.active_window().project_data()
        project_folder = [x["path"] for x in project_data["folders"]]

        match_filename = basename(match.groupdict()["filename"])
        linted_filename = basename(self.filename)

        if match_filename != linted_filename:
            print(_make_text_safeish("Ошибка в другом файле: " + match_filename))
            return None, None, None, None, None, "", None
        if len([i for i in project_folder if i in self.filename]) == 0:
            print(_make_text_safeish("Файл не в проекте: " + linted_filename))
            return None, None, None, None, None, "", None

        return match, line, col, error, warning, message, near
Ejemplo n.º 30
0
    def cmd(self, path="-"):
        php_interpreter = self.settings.get('php_path') or self.which('php.exe') or self.which('php')
        phpcsfixer = self.settings.get('path') or self.locate_php_cs_fixer()

        if php_interpreter is None:
            msg = "php interpreter not found, set PATH environment variable or set php in settings"
            raise Exception(msg)

        if phpcsfixer is None:
            msg = "php interpreter not found, set PATH environment variable or set php in settings"
            raise Exception(msg)

        args = ["--using-cache=off"]

        configs = self.settings.get('config')
        rules = self.settings.get('rules')
        if configs:
            if not type(configs) is list:
                configs = [configs]

            variables = self.get_active_window_variables()

            for config in configs:
                config_path = sublime.expand_variables(config, variables)
                if config_path.startswith("~"):
                    config_path = config_path.replace('~', os.environ["HOME"])

                if self.is_readable_file(config_path):
                    args.append('--config=' + config_path)
                    self.log_to_console("Using config: " + config_path)
                    break

        if rules:
            if isinstance(rules, list):
                rules = rules.join(",")

            if isinstance(rules, str):
                args.append("--rules=" + rules)
                self.log_to_console("Using rules: " + rules)

        self.log_to_console(php_interpreter + " '" + phpcsfixer + "' fix " + path + " " + ' '.join(args))
        return php_interpreter + " '" + phpcsfixer + "' fix " + path + " " + ' '.join(args)
Ejemplo n.º 31
0
def get_initialize_params(
    workspace_folders: List[WorkspaceFolder],
    config: ClientConfig,
    variables: Dict[str, str] = dict()) -> dict:
    first_folder = workspace_folders[0] if workspace_folders else None
    capabilities = {
        "textDocument": {
            "synchronization": {
                "dynamicRegistration": True,  # exceptional
                "didSave": True,
                "willSave": True,
                "willSaveWaitUntil": True
            },
            "hover": {
                "dynamicRegistration": True,
                "contentFormat": ["markdown", "plaintext"]
            },
            "completion": {
                "dynamicRegistration": True,
                "completionItem": {
                    "snippetSupport": True
                },
                "completionItemKind": {
                    "valueSet": completion_item_kinds
                }
            },
            "signatureHelp": {
                "dynamicRegistration": True,
                "signatureInformation": {
                    "documentationFormat": ["markdown", "plaintext"],
                    "parameterInformation": {
                        "labelOffsetSupport": True
                    }
                }
            },
            "references": {
                "dynamicRegistration": True
            },
            "documentHighlight": {
                "dynamicRegistration": True
            },
            "documentSymbol": {
                "dynamicRegistration": True,
                "hierarchicalDocumentSymbolSupport": True,
                "symbolKind": {
                    "valueSet": symbol_kinds
                }
            },
            "formatting": {
                "dynamicRegistration": True  # exceptional
            },
            "rangeFormatting": {
                "dynamicRegistration": True
            },
            "declaration": {
                "dynamicRegistration": True,
                "linkSupport": True
            },
            "definition": {
                "dynamicRegistration": True,
                "linkSupport": True
            },
            "typeDefinition": {
                "dynamicRegistration": True,
                "linkSupport": True
            },
            "implementation": {
                "dynamicRegistration": True,
                "linkSupport": True
            },
            "codeAction": {
                "dynamicRegistration": True,
                "codeActionLiteralSupport": {
                    "codeActionKind": {
                        "valueSet": []
                    }
                }
            },
            "rename": {
                "dynamicRegistration": True
            },
            "colorProvider": {
                "dynamicRegistration": True  # exceptional
            },
            "publishDiagnostics": {
                "relatedInformation": True
            }
        },
        "workspace": {
            "applyEdit": True,
            "didChangeConfiguration": {
                "dynamicRegistration": True
            },
            "executeCommand": {},
            "workspaceEdit": {
                "documentChanges": True,
                "failureHandling": "abort",
            },
            "workspaceFolders": True,
            "symbol": {
                "dynamicRegistration": True,  # exceptional
                "symbolKind": {
                    "valueSet": symbol_kinds
                }
            },
            "configuration": True
        },
        "window": {
            "workDoneProgress": True
        }
    }

    if config.experimental_capabilities is not None:
        capabilities['experimental'] = config.experimental_capabilities

    initializeParams = {
        "processId":
        os.getpid(),
        "clientInfo": {
            "name": "Sublime Text LSP",
            "version": ".".join(map(str, __version__))
        },
        "rootUri":
        first_folder.uri() if first_folder else None,
        "rootPath":
        first_folder.path if first_folder else None,
        "workspaceFolders":
        [folder.to_lsp()
         for folder in workspace_folders] if workspace_folders else None,
        "capabilities":
        capabilities
    }
    if config.init_options is not None:
        initializeParams['initializationOptions'] = sublime.expand_variables(
            config.init_options.get(), variables)

    return initializeParams
Ejemplo n.º 32
0
 def expand(s):
     return sublime.expand_variables(s, self.window.extract_variables())
Ejemplo n.º 33
0
def expand_schema_location(document):
    schema = exalt.file_to_uri(
        os.path.join(exalt.get_plugin_path(), "tests/fixtures/schemas"))

    return sublime.expand_variables(document, {"schema": schema})
Ejemplo n.º 34
0
def _recExpand(envdict):
    expanded = {key : expand_variables(val, envdict) for key, val in envdict.items()}
    return expanded if expanded == envdict else _recExpand(expanded)
Ejemplo n.º 35
0
def swiftformat(view, edit, use_selection):
    # Load settings file
    settings = sublime.load_settings(SETTINGS_FILENAME)

    # Build command to execute
    command = ""
    settings_keys = [
        "swiftformat_bin_path",
        "use_config_file",
        "swiftversion",
        "rules",
        "disable",
        "options",
        "raw_options",
    ]

    # Parse settings
    for key in settings_keys:
        value = settings.get(key)

        if value:
            # Binary path
            if key == "swiftformat_bin_path":
                command += "{}".format(value)

            # Config file
            elif key == "use_config_file":
                # Extract Sublime window's variables
                variables = view.window().extract_variables()
                # Iterate directories to find config file
                for candidate in settings.get("config_paths"):
                    config_file = sublime.expand_variables(
                        candidate, variables)
                    if is_file_readable(config_file):
                        command += ' --config "{}"'.format(config_file)
                        break

            # Formatting options
            elif key == "options":
                for (k, v) in settings.get(key).items():
                    if v:
                        command += ' --{0} "{1}"'.format(k, v)

            # Raw options
            elif key == "raw_options":
                for v in settings.get(key):
                    if v:
                        command += " {}".format(v)

            # CLI options
            else:
                command += ' --{0} "{1}"'.format(key, value)

    # Print command to be executed to the console of ST
    print("Swift Format executed command: {}".format(command))

    #
    # Execute Format
    #
    def format_text(target_text, selection, region):
        # Open subprocess with the command
        with Popen(command, shell=True, stdin=PIPE, stdout=PIPE,
                   stderr=PIPE) as popen:
            # Write selection into stdin, then ensure the descriptor is closed
            popen.stdin.write(target_text.encode("utf-8"))
            popen.stdin.close()

            # Read stdout and stderr
            stdout = popen.stdout.read().decode("utf-8")
            stderr = popen.stderr.read().decode("utf-8")

            # Catch some keywords in stderr
            command_succeeded = "successfully" in stderr
            syntax_error = "Unexpected" in stderr

            # Replace with the result only if no error has been caught
            if command_succeeded:
                view.replace(edit, selection, stdout)

            # Present alert: `swiftformat` not found
            if "not found" in stderr:
                sublime.error_message(
                    "Swift Format\n" + stderr +
                    "Specify absolute path to 'swiftformat' in the settings")
                return command_succeeded

            # Present alert: Unknown error
            if not command_succeeded and not syntax_error:
                sublime.error_message("Swift Format\n" + stderr)
                return command_succeeded

            # Update Phantoms
            update_phantoms(view, stderr, region)

            return command_succeeded

    # Prevent needles iteration as much as possible
    has_selection = any([not r.empty() for r in view.sel()])
    if (settings.get("format_selection_only")
            or use_selection) and has_selection:
        for region in view.sel():
            if region.empty():
                continue

            # Break at the first error
            if not format_text(view.substr(region), region, region):
                break

    else:
        # Don't format entire file when use_selection is true
        if use_selection:
            return

        # Use entire region/string of view
        selection = sublime.Region(0, view.size())
        target_text = view.substr(selection)
        format_text(target_text, selection, None)
Ejemplo n.º 36
0
 def build_folder_expanded(self, window):
     variables = window.extract_variables()
     build_folder = sublime.expand_variables(self.build_folder, variables)
     return build_folder.format(**self.data())
def build_doc_html(inline_doc, doc_type):
    template = DOC_TEMPLATE if doc_type != "completion_doc" else COMPLETION_DOC_TEMPLATE
    html = sublime.expand_variables(template, inline_doc)
    if doc_type == "completion_doc":
        html = html.replace('<div class="body"></div>', "")
    return html
Ejemplo n.º 38
0
    def run(self,
            config_name=None,
            cmd=None,
            cwd=None,
            working_dir=None,
            env={},
            title=None,
            panel_name=None,
            tag=None):
        config = None

        st_vars = self.window.extract_variables()

        if config_name:
            config = self.get_config_by_name(config_name)
        elif cmd:
            config = {
                "name": "Terminus",
                "cmd": cmd,
                "env": env,
                "title": title
            }
        else:
            self.show_configs()
            return

        cmd = config["cmd"]
        if isinstance(cmd, str):
            cmd = [cmd]

        if cmd:
            cmd = sublime.expand_variables(cmd, st_vars)

        if "env" in config:
            _env = config["env"]
        else:
            _env = {}

        if sys.platform.startswith("win"):
            pass

        else:
            settings = sublime.load_settings("Terminus.sublime-settings")
            if "TERM" not in _env:
                _env["TERM"] = settings.get("unix_term", "linux")

            if _env["TERM"] not in [
                    "linux", "xterm", "xterm-16color", "xterm-256color"
            ]:
                raise Exception("{} is not supported.".format(_env["TERM"]))

            if "LANG" not in _env:
                if "LANG" in os.environ:
                    _env["LANG"] = os.environ["LANG"]
                else:
                    _env["LANG"] = settings.get("unix_lang", "en_US.UTF-8")

        _env.update(env)

        if not cwd and working_dir:
            cwd = working_dir

        if cwd:
            cwd = sublime.expand_variables(cwd, st_vars)

        if not cwd:
            if self.window.folders():
                cwd = self.window.folders()[0]
            else:
                cwd = os.path.expanduser("~")

        if not os.path.isdir(cwd):
            raise Exception("{} does not exist".format(cwd))

        if not title:
            title = config["name"]

        if panel_name:
            self.window.destroy_output_panel(panel_name)  # do not reuse
            terminus_view = self.window.get_output_panel(panel_name)
        else:
            terminus_view = self.window.new_file()

        sublime.set_timeout(lambda: terminus_view.run_command(
            "terminus_activate", {
                "cmd": cmd,
                "cwd": cwd,
                "env": _env,
                "title": title,
                "panel_name": panel_name,
                "tag": tag
            }))

        if panel_name:
            self.window.run_command("show_panel",
                                    {"panel": "output.{}".format(panel_name)})
            self.window.focus_view(terminus_view)
Ejemplo n.º 39
0
    def run_async(
            self,
            config_name=None,
            cmd=None,
            shell_cmd=None,
            cwd=None,
            working_dir=None,
            env={},
            title=None,
            show_in_panel=None,
            panel_name=None,
            focus=True,
            tag=None,
            file_regex=None,
            line_regex=None,
            pre_window_hooks=[],
            post_window_hooks=[],
            post_view_hooks=[],
            auto_close=True,
            cancellable=False,
            timeit=False,
            paths=[],
            ):
        config = None

        st_vars = self.window.extract_variables()

        if config_name == "<ask>":
            self.show_configs()
            return

        if config_name:
            config = self.get_config_by_name(config_name)
        elif cmd or shell_cmd:
            config = {}
        else:
            config = self.get_config_by_name("Default")

        config_name = config["name"] if config else None

        if config_name:
            default_title = config_name
        else:
            default_title = DEFAULT_TITLE

        if config and "cmd" in config and "shell_cmd" in config:
            raise Exception(
                "both `cmd` are `shell_cmd` are specified in config {}".format(config_name))

        if cmd and shell_cmd:
            raise Exception("both `cmd` are `shell_cmd` are passed to terminus_open")

        if shell_cmd is not None or ("shell_cmd" in config and config["shell_cmd"]):
            if shell_cmd is None:
                shell_cmd = config["shell_cmd"]

            if not isinstance(shell_cmd, str):
                raise ValueError("shell_cmd should be a string")
            # mimic exec target
            if sys.platform.startswith("win"):
                comspec = os.environ.get("COMSPEC", "cmd.exe")
                cmd_to_run = [comspec, "/c"] + shlex_split(shell_cmd)
            elif sys.platform == "darwin":
                cmd_to_run = ["/usr/bin/env", "bash", "-l", "-c", shell_cmd]
            else:
                cmd_to_run = ["/usr/bin/env", "bash", "-c", shell_cmd]

        elif cmd is not None or ("cmd" in config and config["cmd"]):

            if cmd is None:
                cmd = config["cmd"]

            cmd_to_run = cmd

        else:
            raise Exception("both `cmd` are `shell_cmd` are empty")

        if cmd_to_run is None:
            raise ValueError("cannot determine command to run")

        if isinstance(cmd_to_run, str):
            cmd_to_run = [cmd_to_run]

        cmd_to_run = sublime.expand_variables(cmd_to_run, st_vars)

        if env:
            config["env"] = env

        if "env" in config:
            _env = config["env"]
        else:
            _env = {}

        _env["TERMINUS_SUBLIME"] = "1"  # for backward compatibility
        _env["TERM_PROGRAM"] = "Terminus-Sublime"

        if sys.platform.startswith("win"):
            pass

        else:
            settings = sublime.load_settings("Terminus.sublime-settings")
            if "TERM" not in _env:
                _env["TERM"] = settings.get("unix_term", "linux")

            if _env["TERM"] not in ["linux", "xterm", "xterm-16color", "xterm-256color"]:
                raise Exception("{} is not supported.".format(_env["TERM"]))

            if "LANG" not in _env:
                if "LANG" in os.environ:
                    _env["LANG"] = os.environ["LANG"]
                else:
                    _env["LANG"] = settings.get("unix_lang", "en_US.UTF-8")

        _env.update(env)

        # paths is passed if this was invoked from the side bar context menu
        if paths:
            cwd = paths[0]
            if not os.path.isdir(cwd):
                cwd = os.path.dirname(cwd)
        else:
            if not cwd and working_dir:
                cwd = working_dir

            if cwd:
                cwd = sublime.expand_variables(cwd, st_vars)

        if not cwd:
            if self.window.folders():
                cwd = self.window.folders()[0]
            else:
                cwd = os.path.expanduser("~")

        if not os.path.isdir(cwd):
            home = os.path.expanduser("~")
            if home:
                cwd = home

        if not os.path.isdir(cwd):
            raise Exception("{} does not exist".format(cwd))

        if show_in_panel is None and panel_name:
            show_in_panel = True

        terminal = None
        window = self.window
        view = None

        if tag:
            terminal = Terminal.from_tag(tag)

        if not terminal and show_in_panel and panel_name:
            view = window.find_output_panel(panel_name)
            if view:
                terminal = Terminal.from_id(view.id())

        if terminal:
            # cleanup existing terminal
            view = terminal.view
            # avoid terminus_cleanup
            view.settings().set("terminus_view.finished", True)
            terminal.close()

        if not view:
            if not panel_name:
                panel_name = available_panel_name(window, DEFAULT_PANEL)

            if show_in_panel:
                view = window.get_output_panel(panel_name)
            else:
                view = window.new_file()

        # pre_window_hooks
        for hook in pre_window_hooks:
            window.run_command(*hook)

        view.run_command(
            "terminus_activate",
            {
                "cmd": cmd_to_run,
                "cwd": cwd,
                "env": _env,
                "default_title": default_title,
                "title": title,
                "show_in_panel": show_in_panel,
                "panel_name": panel_name,
                "tag": tag,
                "auto_close": auto_close,
                "cancellable": cancellable,
                "timeit": timeit,
                "file_regex": file_regex,
                "line_regex": line_regex
            })

        if show_in_panel:
            window.run_command("show_panel", {"panel": "output.{}".format(panel_name)})

        if focus:
            window.focus_view(view)

        # post_window_hooks
        for hook in post_window_hooks:
            window.run_command(*hook)

        # post_view_hooks
        for hook in post_view_hooks:
            view.run_command(*hook)
Ejemplo n.º 40
0
def expand(window: sublime.Window, d) -> 'Any':
    return sublime.expand_variables(d, window.extract_variables())
Ejemplo n.º 41
0
    def on_text_command(self, view, command_name, args):
        # print('command_name', command_name, 'args', args)
        result_full_regex = view.settings().get('result_full_regex')

        # print('result_full_regex', result_full_regex)
        if result_full_regex and command_name == 'drag_select' and 'event' in args:
            global g_last_click_time
            global g_last_click_buttons

            clicks_buttons = args['event']
            new_click = time.time()

            if clicks_buttons == g_last_click_buttons:
                click_time = new_click - g_last_click_time

                if click_time < 0.6:
                    view_selections = view.sel()

                    if view_selections:
                        full_line = view.substr(
                            view.full_line(view_selections[0]))

                        # print('Double clicking', click_time, 'full_line', full_line )
                        full_regex_object = re.compile(result_full_regex)
                        matchobject = full_regex_object.search(full_line)

                        if matchobject:
                            groupindex = full_regex_object.groupindex

                            # https://github.com/SublimeTextIssues/Core/issues/227
                            filename = matchobject.group('file').strip(
                                ' ') if 'file' in groupindex else None
                            line = matchobject.group('line').strip(
                                ' ') if 'line' in groupindex else "0"
                            column = matchobject.group('column').strip(
                                ' ') if 'column' in groupindex else "0"

                            window = view.window() or sublime.active_window()
                            extract_variables = window.extract_variables()

                            # github.com/SublimeTextIssues/Core/issues/1482
                            active_view = window.active_view()
                            group, view_index = window.get_view_index(
                                active_view)
                            window.set_view_index(active_view, group, 0)

                            # https://github.com/SublimeTextIssues/Core/issues/938
                            result_replaceby = view.settings().get(
                                'result_replaceby', {})
                            result_real_dir = view.settings().get(
                                'result_real_dir', [os.path.abspath('.')])

                            if filename:
                                assert isinstance(
                                    result_real_dir, list
                                ), "Error: '%s' must be an instance of list!" % result_real_dir

                                for possible_root in result_real_dir:
                                    real_dir_file = os.path.join(
                                        possible_root, filename)
                                    real_dir_file = sublime.expand_variables(
                                        real_dir_file, extract_variables)
                                    real_dir_file = self.replaceby(
                                        real_dir_file, result_replaceby)

                                    if os.path.exists(real_dir_file):
                                        filepath = real_dir_file
                                        break

                                else:
                                    base_dir_file = view.settings().get(
                                        'result_base_dir')
                                    filepath = os.path.join(
                                        base_dir_file, filename)
                                    filepath = sublime.expand_variables(
                                        filepath, extract_variables)
                                    filepath = self.replaceby(
                                        filepath, result_replaceby)

                                filepath = os.path.normpath(filepath)

                            else:
                                filepath = active_view.file_name()

                            print('[exec] Opening', filename, line, column,
                                  'file', filepath, real_dir_file)

                            fileview = window.open_file(
                                filepath + ":" + line + ":" + column,
                                sublime.ENCODED_POSITION | sublime.FORCE_GROUP)

                            # https://github.com/SublimeTextIssues/Core/issues/2506
                            restore_view(fileview, window, lambda: None)
                            window.set_view_index(active_view, group,
                                                  view_index)

                            # window.focus_group( group )
                            # window.focus_view( fileview )

            g_last_click_time = new_click
            g_last_click_buttons = clicks_buttons
Ejemplo n.º 42
0
    def load_configurations(self) -> None:
        variables = extract_variables(self.window)
        adapters = {}

        def load_adapter(adapter_name, adapter_json):
            adapter_json = sublime.expand_variables(adapter_json, variables)

            # if its a string then it points to a json file with configuration in it
            # otherwise it is the configuration
            try:
                if isinstance(adapter_json, str):
                    with open(adapter_json) as json_data:
                        adapter_json = json.load(json_data, )
                        adapter_json = sublime.expand_variables(
                            adapter_json, variables)
            except Exception as e:
                core.display(
                    'Failed when opening debug adapter configuration file {}'.
                    format(e))
                raise e

            try:
                adapter = AdapterConfiguration.from_json(
                    adapter_name, adapter_json)
                adapters[adapter.type] = adapter
            except Exception as e:
                core.display(
                    'There was an error creating a AdapterConfiguration {}'.
                    format(e))

        for adapter_name, adapter_json in get_setting(
                self.window.active_view(), 'adapters', {}).items():
            load_adapter(adapter_name, adapter_json)

        for adapter_name, adapter_json in get_setting(
                self.window.active_view(), 'adapters_custom', {}).items():
            load_adapter(adapter_name, adapter_json)

        configurations = []
        configurations_json = []  #type: list
        data = self.window.project_data()
        if data:
            configurations_json = data.setdefault('settings', {}).setdefault(
                'debug.configurations', [])
            configurations_json = sublime.expand_variables(
                configurations_json, variables)

        for index, configuration_json in enumerate(configurations_json):
            configuration = Configuration.from_json(configuration_json)
            configuration.index = index
            configurations.append(configuration)

        self.adapters = adapters
        self.configurations = configurations
        self.configuration = self.persistance.load_configuration_option(
            configurations)

        if self.configuration:
            self.debugger_panel.set_name(self.configuration.name)
        else:
            self.debugger_panel.set_name('select config')

        assert self.view
        self.view.settings().set('font_size',
                                 get_setting(self.view, 'ui_scale', 12))
Ejemplo n.º 43
0
    def run(self, base_file, user_file=None, default=None):
        """
        :param base_file:
            A unicode string of the path to the base settings file. Typically
            this will be in the form: "${packages}/PackageName/Package.sublime-settings"

        :param user_file:
            An optional file path to the user's editable version of the settings
            file. If not provided, the filename from base_file will be appended
            to "${packages}/User/".

        :param default:
            An optional unicode string of the default contents if the user
            version of the settings file does not yet exist. Use "$0" to place
            the cursor.
        """

        if base_file is None:
            raise ValueError(
                'No base_file argument was passed to edit_settings')

        platform_name = {
            'osx': 'OSX',
            'windows': 'Windows',
            'linux': 'Linux',
        }[sublime.platform()]

        variables = {
            'packages': '${packages}',
            'platform': platform_name,
        }

        base_file = sublime.expand_variables(base_file.replace('\\', '\\\\'),
                                             variables)
        if user_file is not None:
            user_file = sublime.expand_variables(
                user_file.replace('\\', '\\\\'), variables)

        base_path = base_file.replace('${packages}', 'res://Packages')
        is_resource = base_path.startswith('res://')
        file_name = os.path.basename(base_file)
        resource_exists = is_resource and base_path[
            6:] in sublime.find_resources(file_name)
        filesystem_exists = (not is_resource) and os.path.exists(base_path)

        if not resource_exists and not filesystem_exists:
            sublime.error_message('The settings file "' + base_path +
                                  '" could not be opened')
            return

        if user_file is None:
            user_package_path = os.path.join(sublime.packages_path(), 'User')
            user_file = os.path.join(user_package_path, file_name)

            # If the user path does not exist, and it is a supported
            # platform-variant file path, then try and non-platform-variant
            # file path.
            if not os.path.exists(os.path.join(user_package_path, file_name)):
                for suffix in {
                        '.sublime-keymap', '.sublime-mousemap', '.sublime-menu'
                }:
                    platform_suffix = ' (%s)%s' % (platform_name, suffix)
                    if not file_name.endswith(platform_suffix):
                        continue
                    non_platform_file_name = file_name[:-len(platform_suffix
                                                             )] + suffix
                    non_platform_path = os.path.join(user_package_path,
                                                     non_platform_file_name)
                    if os.path.exists(non_platform_path):
                        user_file = non_platform_path
                        break

        sublime.run_command('new_window')
        new_window = sublime.active_window()

        new_window.run_command(
            'set_layout', {
                'cols': [0.0, 0.5, 1.0],
                'rows': [0.0, 1.0],
                'cells': [[0, 0, 1, 1], [1, 0, 2, 1]]
            })
        new_window.focus_group(0)
        new_window.run_command('open_file', {'file': base_file})
        new_window.focus_group(1)
        new_window.run_command('open_file', {
            'file': user_file,
            'contents': default
        })

        new_window.set_tabs_visible(True)
        new_window.set_sidebar_visible(False)

        base_view = new_window.active_view_in_group(0)
        user_view = new_window.active_view_in_group(1)

        base_settings = base_view.settings()
        base_settings.set('edit_settings_view', 'base')
        base_settings.set('edit_settings_other_view_id', user_view.id())

        user_settings = user_view.settings()
        user_settings.set('edit_settings_view', 'user')
        user_settings.set('edit_settings_other_view_id', base_view.id())
        if not os.path.exists(user_file):
            user_view.set_scratch(True)
            user_settings.set('edit_settings_default',
                              default.replace('$0', ''))
Ejemplo n.º 44
0
def expand_path(path):
    variables = sublime.active_window().extract_variables()
    path = sublime.expand_variables(path, variables)
    return os.path.expanduser(os.path.expandvars(path))
Ejemplo n.º 45
0
def build_doc_html(inline_doc):
    if "links" in inline_doc:
        inline_doc["links"] = build_links(inline_doc["links"])
    return sublime.expand_variables(DOC_TEMPLATE, inline_doc)
Ejemplo n.º 46
0
 def settings(self):
     """Load the platform-specific plugin settings for commands to use."""
     env_vars = self.window.extract_variables()
     filename = 'Conda (${platform}).sublime-settings'
     expanded = sublime.expand_variables(filename, env_vars)
     return sublime.load_settings(expanded)
Ejemplo n.º 47
0
 def source_folder_expanded(self, window):
     variables = window.extract_variables()
     build_folder = sublime.expand_variables(
         self._data.get('source_folder', ''), variables)
     return build_folder
Ejemplo n.º 48
0
    def run_async(self,
                  config_name=None,
                  cmd=None,
                  cwd=None,
                  working_dir=None,
                  env={},
                  title=None,
                  panel_name=None,
                  tag=None,
                  pre_window_hooks=[],
                  post_window_hooks=[],
                  post_view_hooks=[],
                  auto_close=True):
        config = None

        st_vars = self.window.extract_variables()

        if not config_name and not cmd:
            self.show_configs()
            return

        if config_name:
            config = self.get_config_by_name(config_name)
        else:
            config = {"name": "Terminus"}
        if cmd:
            config["cmd"] = cmd
        if env:
            config["env"] = env

        cmd = config["cmd"]
        if isinstance(cmd, str):
            cmd = [cmd]

        if cmd:
            cmd = sublime.expand_variables(cmd, st_vars)

        if "env" in config:
            _env = config["env"]
        else:
            _env = {}

        _env["TERMINUS_SUBLIME"] = "1"

        if sys.platform.startswith("win"):
            pass

        else:
            settings = sublime.load_settings("Terminus.sublime-settings")
            if "TERM" not in _env:
                _env["TERM"] = settings.get("unix_term", "linux")

            if _env["TERM"] not in [
                    "linux", "xterm", "xterm-16color", "xterm-256color"
            ]:
                raise Exception("{} is not supported.".format(_env["TERM"]))

            if "LANG" not in _env:
                if "LANG" in os.environ:
                    _env["LANG"] = os.environ["LANG"]
                else:
                    _env["LANG"] = settings.get("unix_lang", "en_US.UTF-8")

        _env.update(env)

        if not cwd and working_dir:
            cwd = working_dir

        if cwd:
            cwd = sublime.expand_variables(cwd, st_vars)

        if not cwd:
            if self.window.folders():
                cwd = self.window.folders()[0]
            else:
                cwd = os.path.expanduser("~")

        if not os.path.isdir(cwd):
            home = os.path.expanduser("~")
            if home:
                cwd = home

        if not os.path.isdir(cwd):
            raise Exception("{} does not exist".format(cwd))

        if not title:
            title = config["name"]

        # pre_window_hooks
        for hook in pre_window_hooks:
            self.window.run_command(*hook)

        if panel_name:
            panel_name = available_panel_name(self.window, panel_name)
            terminus_view = self.window.get_output_panel(panel_name)
        else:
            terminus_view = self.window.new_file()

        terminus_view.run_command(
            "terminus_activate", {
                "cmd": cmd,
                "cwd": cwd,
                "env": _env,
                "title": title,
                "panel_name": panel_name,
                "tag": tag,
                "auto_close": auto_close
            })

        if panel_name:
            self.window.run_command("show_panel",
                                    {"panel": "output.{}".format(panel_name)})
            self.window.focus_view(terminus_view)

        # post_window_hooks
        for hook in post_window_hooks:
            self.window.run_command(*hook)

        # post_view_hooks
        for hook in post_view_hooks:
            terminus_view.run_command(*hook)
    def run(self, **kwargs):

        if 'is_parent_setting' in kwargs and kwargs.get('is_parent_setting'):
            del kwargs['is_parent_setting']
            if 'base_file' in kwargs:
                kwargs['file'] = kwargs.get('base_file')
                del kwargs['base_file']

            expanded_target_directory = sublime.expand_variables(
                os.path.dirname(kwargs.get('file')),
                self.window.extract_variables())
            if not os.path.exists(expanded_target_directory):
                os.makedirs(expanded_target_directory)

            try:
                expanded_source_path = sublime.expand_variables(
                    kwargs.get('file'), self.window.extract_variables())
                # package_name = os.path.basename(os.path.dirname(expanded_source_path.replace(sublime.packages_path(), '')))
                resource_path = 'Packages' + expanded_source_path.replace(
                    sublime.packages_path(), '')
                sublime.load_resource(resource_path)
                if 'default' in kwargs:
                    del kwargs['default']
            except IOError:
                if 'default' in kwargs:
                    kwargs['contents'] = kwargs.get('default')
                    del kwargs['default']

            self.window.run_command('open_file', kwargs)

        else:
            if 'user_file' in kwargs:
                expanded_target_directory = sublime.expand_variables(
                    os.path.dirname(kwargs.get('user_file')),
                    self.window.extract_variables())
                if not os.path.exists(expanded_target_directory):
                    os.makedirs(expanded_target_directory)

            try:
                expanded_source_path = sublime.expand_variables(
                    kwargs.get('base_file'), self.window.extract_variables())
                # package_name = os.path.basename(os.path.dirname(expanded_source_path.replace(sublime.packages_path(), '')))
                resource_path = 'Packages' + expanded_source_path.replace(
                    sublime.packages_path(), '')
                sublime.load_resource(resource_path)

                self.window.run_command('edit_settings', kwargs)
            except IOError:
                if 'user_file' in kwargs:
                    kwargs['file'] = kwargs.get('user_file')
                    del kwargs['user_file']
                else:
                    # expanded_source_path = sublime.expand_variables(kwargs.get('base_file'), self.window.extract_variables())
                    # kwargs['file'] = expanded_source_path.replace(sublime.packages_path(), os.path.join(sublime.packages_path(), 'User'))
                    kwargs['file'] = os.path.join(
                        sublime.packages_path(), 'User',
                        os.path.basename(kwargs.get('base_file')))
                del kwargs['base_file']
                if 'default' in kwargs:
                    kwargs['contents'] = kwargs.get('default')
                    del kwargs['default']

                self.window.run_command('open_file', kwargs)
Ejemplo n.º 50
0
def run_formatter(view, formatter):

    (row, col) = view.rowcol(view.sel()[0].begin())
    filename = view.file_name()
    formatter_name = formatter["name"]
    window = view.window()
    folders = window.folders()

    if len(folders) == 1:
        root_dir = folders[0]
    else:
        root_dir = os.path.dirname(filename)

    debug("using root dir as", root_dir)
    window.status_message("%s: formatting…" % formatter_name)

    command = formatter["command"]

    if is_debug() and formatter["debug"]:
        command += formatter["debug"]

    config_file = find_config_file(formatter, root_dir)
    context = expand_formatter_variables(formatter, {
        "file": filename,
        "config": config_file
    })

    try:
        if not config_file:
            del context["config"]
            index = command.index("$config")
            command.pop(index)
            command.pop(index - 1)
    except ValueError:
        debug("command doesn't expect a config file")

    debug("raw command:", command)

    command = [sublime.expand_variables(arg, context) for arg in command]

    debug("using command:", command)

    with subprocess.Popen(command,
                          stdout=subprocess.PIPE,
                          cwd=root_dir,
                          universal_newlines=True) as result:
        result.wait()

        if is_debug():
            debug("== Command output ==")

            for line in result.stdout:
                debug("=>", line.rstrip())

            debug("== End of Command output ==")

    return_code = result.returncode
    debug("%s command finished with exit(%d)" % (formatter_name, return_code))

    if return_code != 0:
        debug(
            "some commands exit with nonzero status to indicate that there are issues that couldn't be automatically fixed."
        )

    window.status_message("%s: done." % formatter_name if return_code ==
                          0 else "%s: error." % formatter_name)
Ejemplo n.º 51
0
Archivo: main.py Proyecto: gobijan/LSP
def start_client(window: sublime.Window, project_path: str, config: ClientConfig):

    if config.name in client_start_listeners:
        handler_startup_hook = client_start_listeners[config.name]
        if not handler_startup_hook(window):
            return

    if settings.show_status_messages:
        window.status_message("Starting " + config.name + "...")
    debug("starting in", project_path)

    # Create a dictionary of Sublime Text variables
    variables = window.extract_variables()

    # Expand language server command line environment variables
    expanded_args = list(
        sublime.expand_variables(os.path.expanduser(arg), variables)
        for arg in config.binary_args
    )

    # Override OS environment variables
    env = os.environ.copy()
    for var, value in config.env.items():
        # Expand both ST and OS environment variables
        env[var] = os.path.expandvars(sublime.expand_variables(value, variables))

    # TODO: don't start process if tcp already up or command empty?
    process = start_server(expanded_args, project_path, env)
    if not process:
        window.status_message("Could not start " + config.name + ", disabling")
        debug("Could not start", config.binary_args, ", disabling")
        return None

    if config.tcp_port is not None:
        client = attach_tcp_client(config.tcp_port, process, settings)
    else:
        client = attach_stdio_client(process, settings)

    if not client:
        window.status_message("Could not connect to " + config.name + ", disabling")
        return None

    client.set_crash_handler(lambda: handle_server_crash(window, config))
    client.set_error_display_handler(lambda msg: sublime.status_message(msg))

    initializeParams = {
        "processId": os.getpid(),
        "rootUri": filename_to_uri(project_path),
        "rootPath": project_path,
        "capabilities": {
            "textDocument": {
                "synchronization": {
                    "didSave": True
                },
                "hover": {
                    "contentFormat": ["markdown", "plaintext"]
                },
                "completion": {
                    "completionItem": {
                        "snippetSupport": True
                    },
                    "completionItemKind": {
                        "valueSet": [
                            CompletionItemKind.Text,
                            CompletionItemKind.Method,
                            CompletionItemKind.Function,
                            CompletionItemKind.Constructor,
                            CompletionItemKind.Field,
                            CompletionItemKind.Variable,
                            CompletionItemKind.Class,
                            CompletionItemKind.Interface,
                            CompletionItemKind.Module,
                            CompletionItemKind.Property,
                            CompletionItemKind.Unit,
                            CompletionItemKind.Value,
                            CompletionItemKind.Enum,
                            CompletionItemKind.Keyword,
                            CompletionItemKind.Snippet,
                            CompletionItemKind.Color,
                            CompletionItemKind.File,
                            CompletionItemKind.Reference
                            ]
                    }
                },
                "signatureHelp": {
                    "signatureInformation": {
                        "documentationFormat": ["markdown", "plaintext"]
                    }
                },
                "references": {},
                "documentHighlight": {},
                "documentSymbol": {
                    "symbolKind": {
                        "valueSet": [
                            SymbolKind.File,
                            SymbolKind.Module,
                            SymbolKind.Namespace,
                            SymbolKind.Package,
                            SymbolKind.Class,
                            SymbolKind.Method,
                            SymbolKind.Property,
                            SymbolKind.Field,
                            # SymbolKind.Constructor,
                            # SymbolKind.Enum,
                            SymbolKind.Interface,
                            SymbolKind.Function,
                            SymbolKind.Variable,
                            SymbolKind.Constant
                            # SymbolKind.String,
                            # SymbolKind.Number,
                            # SymbolKind.Boolean,
                            # SymbolKind.Array
                            ]
                    }
                },
                "formatting": {},
                "rangeFormatting": {},
                "definition": {},
                "codeAction": {},
                "rename": {}
            },
            "workspace": {
                "applyEdit": True,
                "didChangeConfiguration": {}
            }
        }
    }
    if config.init_options:
        initializeParams['initializationOptions'] = config.init_options

    client.send_request(
        Request.initialize(initializeParams),
        lambda result: handle_initialize_result(result, client, window, project_path, config))
    return client
Ejemplo n.º 52
0
def expand_variables(string):
    """Expand typical sublime variables in the given string."""

    window = sublime.active_window()
    env = window.extract_variables()
    return sublime.expand_variables(string, env)
Ejemplo n.º 53
0
    def __call__(self, edit):

        # prepare popen arguments
        cmd = get_setting(self.view, "black_command")
        if not cmd:
            # always show error in popup
            msg = "Black command not configured. Problem with settings?"
            sublime.error_message(msg)
            raise Exception(msg)

        cmd = os.path.expanduser(cmd)

        cmd = sublime.expand_variables(cmd, sublime.active_window().extract_variables())

        # set  black in input/ouput mode with -
        self.cmd = [cmd, "-"]

        # Line length option
        line_length = get_setting(self.view, "line_length")
        if line_length is not None:
            self.cmd += ["-l", str(line_length)]

        # win32: hide console window
        if sys.platform in ("win32", "cygwin"):
            self.popen_startupinfo = subprocess.STARTUPINFO()
            self.popen_startupinfo.dwFlags = subprocess.CREATE_NEW_CONSOLE | subprocess.STARTF_USESHOWWINDOW
            self.popen_startupinfo.wShowWindow = subprocess.SW_HIDE
        else:
            self.popen_startupinfo = None

        # get encoding of current file
        encoding = self.view.encoding()
        if encoding == "Undefined":
            encoding = get_encoding_from_file(self.view)
        if not encoding:
            encoding = get_setting(self.view, "default_encoding", "utf-8")

        # select the whole file en encode it
        # encoding in popen starts with python 3.6
        all_file = sublime.Region(0, self.view.size())
        content = self.view.substr(all_file)
        content = content.encode(encoding)

        # modifying the locale is necessary to keep the click library happy on OSX
        env = os.environ.copy()
        if locale.getdefaultlocale() == (None, None):
            if platform.system() == "Darwin":
                env["LC_CTYPE"] = "UTF-8"

        try:
            p = subprocess.Popen(
                self.cmd,
                env=env,
                stdin=subprocess.PIPE,
                stdout=subprocess.PIPE,
                stderr=subprocess.PIPE,
                startupinfo=self.popen_startupinfo,
            )
            out, err = p.communicate(input=content)

        except OSError as err:
            msg = "You may need to install Black and/or configure 'black_command' in Sublack's Settings."
            sublime.error_message("OSError: %s\n\n%s" % (err, msg))
            return

        if p.returncode == 0:
            self.view.replace(edit, all_file, out.decode(encoding))
            if get_setting(self.view, "debug"):
                print("[SUBLACK] : %s" % err.decode(encoding))

        else:
            print("[SUBLACK] Black did not run succesfully: %s" % err.decode(encoding))
            return
Ejemplo n.º 54
0
def start_client(window: sublime.Window, config: ClientConfig):
    project_path = get_project_path(window)
    if project_path is None:
        return None

    if settings.show_status_messages:
        window.status_message("Starting " + config.name + "...")
    debug("starting in", project_path)

    # Create a dictionary of Sublime Text variables
    variables = window.extract_variables()

    # Expand language server command line environment variables
    expanded_args = list(
        sublime.expand_variables(os.path.expanduser(arg), variables)
        for arg in config.binary_args)

    # Override OS environment variables
    env = os.environ.copy()
    for var, value in config.env.items():
        # Expand both ST and OS environment variables
        env[var] = os.path.expandvars(
            sublime.expand_variables(value, variables))

    # TODO: don't start process if tcp already up or command empty?
    process = start_server(expanded_args, project_path, env)
    if not process:
        window.status_message("Could not start " + config.name + ", disabling")
        debug("Could not start", config.binary_args, ", disabling")
        return None

    if config.tcp_port is not None:
        client = attach_tcp_client(config.tcp_port, process, project_path)
    else:
        client = attach_stdio_client(process, project_path)

    if not client:
        window.status_message("Could not connect to " + config.name +
                              ", disabling")
        return None

    client.set_crash_handler(lambda: handle_server_crash(window, config))

    initializeParams = {
        "processId": client.process.pid if client.process else None,
        "rootUri": filename_to_uri(project_path),
        "rootPath": project_path,
        "capabilities": {
            "textDocument": {
                "completion": {
                    "completionItem": {
                        "snippetSupport": True
                    }
                },
                "synchronization": {
                    "didSave": True
                }
            },
            "workspace": {
                "applyEdit": True
            }
        }
    }
    if config.init_options:
        initializeParams['initializationOptions'] = config.init_options

    client.send_request(
        Request.initialize(initializeParams), lambda result:
        handle_initialize_result(result, client, window, config))
    return client
Ejemplo n.º 55
0
    def run_async(self,
                  config_name=None,
                  cmd=None,
                  shell_cmd=None,
                  cwd=None,
                  working_dir=None,
                  env={},
                  title=None,
                  panel_name=None,
                  focus=True,
                  tag=None,
                  file_regex=None,
                  line_regex=None,
                  pre_window_hooks=[],
                  post_window_hooks=[],
                  post_view_hooks=[],
                  auto_close=True,
                  cancellable=False,
                  timeit=False):
        config = None

        st_vars = self.window.extract_variables()

        if config_name == "<ask>":
            self.show_configs()
            return

        if config_name:
            config = self.get_config_by_name(config_name)
        else:
            config = self.get_config_by_name("Default")

        if cmd and shell_cmd:
            raise ValueError("both cmd and shell_cmd are not empty")

        if not cmd and shell_cmd:
            if not isinstance(shell_cmd, str):
                raise ValueError("shell_cmd should be a string")
            # mimic exec target
            if sys.platform.startswith("win"):
                comspec = os.environ.get("COMSPEC", "cmd.exe")
                cmd = [comspec, "/c"] + shlex_split(shell_cmd)
            elif sys.platform == "darwin":
                cmd = ["/usr/bin/env", "bash", "-l", "-c", shell_cmd]
            else:
                cmd = ["/usr/bin/env", "bash", "-c", shell_cmd]

        if not cmd:
            cmd = config["cmd"]

        if cmd and isinstance(cmd, str):
            cmd = [cmd]

        if cmd:
            cmd = sublime.expand_variables(cmd, st_vars)

        if env:
            config["env"] = env

        if "env" in config:
            _env = config["env"]
        else:
            _env = {}

        _env["TERMINUS_SUBLIME"] = "1"  # for backward compatibility
        _env["TERM_PROGRAM"] = "Terminus-Sublime"

        if sys.platform.startswith("win"):
            pass

        else:
            settings = sublime.load_settings("Terminus.sublime-settings")
            if "TERM" not in _env:
                _env["TERM"] = settings.get("unix_term", "linux")

            if _env["TERM"] not in [
                    "linux", "xterm", "xterm-16color", "xterm-256color"
            ]:
                raise Exception("{} is not supported.".format(_env["TERM"]))

            if "LANG" not in _env:
                if "LANG" in os.environ:
                    _env["LANG"] = os.environ["LANG"]
                else:
                    _env["LANG"] = settings.get("unix_lang", "en_US.UTF-8")

        _env.update(env)

        if not cwd and working_dir:
            cwd = working_dir

        if cwd:
            cwd = sublime.expand_variables(cwd, st_vars)

        if not cwd:
            if self.window.folders():
                cwd = self.window.folders()[0]
            else:
                cwd = os.path.expanduser("~")

        if not os.path.isdir(cwd):
            home = os.path.expanduser("~")
            if home:
                cwd = home

        if not os.path.isdir(cwd):
            raise Exception("{} does not exist".format(cwd))

        # pre_window_hooks
        for hook in pre_window_hooks:
            self.window.run_command(*hook)

        if panel_name:
            if panel_name == DEFAULT_PANEL:
                panel_name = available_panel_name(self.window, panel_name)

            terminus_view = self.window.get_output_panel(panel_name)
            terminal = Terminal.from_id(terminus_view.id())
            if terminal:
                terminal.close()
                terminus_view.run_command("terminus_nuke")
                terminus_view.settings().erase("terminus_view")
                terminus_view.settings().erase("terminus_view.closed")
                terminus_view.settings().erase("terminus_view.viewport_y")
        else:
            terminus_view = self.window.new_file()

        terminus_view.run_command(
            "terminus_activate", {
                "config_name": config["name"],
                "cmd": cmd,
                "cwd": cwd,
                "env": _env,
                "title": title,
                "panel_name": panel_name,
                "tag": tag,
                "auto_close": auto_close,
                "cancellable": cancellable,
                "timeit": timeit,
                "file_regex": file_regex,
                "line_regex": line_regex
            })

        if panel_name:
            self.window.run_command("show_panel",
                                    {"panel": "output.{}".format(panel_name)})
            if focus:
                self.window.focus_view(terminus_view)

        # post_window_hooks
        for hook in post_window_hooks:
            self.window.run_command(*hook)

        # post_view_hooks
        for hook in post_view_hooks:
            terminus_view.run_command(*hook)
Ejemplo n.º 56
0
def expandStr(value):
    """Expand ${name}s and $NAMEs. Empty string if key not found"""
    return expand_variables(os.path.expandvars(value), flower.ENV)
Ejemplo n.º 57
0
def expand_path(path):
    if path and isinstance(path, str):
        variables = sublime.active_window().extract_variables()
        path = sublime.expand_variables(path, variables)
        return abspath(expanduser(expandvars(path)))
    return path
Ejemplo n.º 58
0
def build_cfdoc_error(function_or_tag, data):
    return sublime.expand_variables(CFDOCS_ERROR_TEMPLATE, data)
Ejemplo n.º 59
0
def get_settings(view, name, default=None):
    """Get settings
    """

    global ENVIRON_HOOK_INVALID

    if view is None:
        return default

    plugin_settings = sublime.load_settings('Anaconda.sublime-settings')

    if (name in ('python_interpreter', 'extra_paths')
            and not ENVIRON_HOOK_INVALID[view.id()]):
        if view.window() is not None and view.window().folders():
            allow_multiple_env_hooks = get_settings(
                view, 'anaconda_allow_project_environment_hooks', False)
            if allow_multiple_env_hooks:
                dirname = os.path.dirname(view.file_name())
            else:
                dirname = view.window().folders()[0]
            while True:
                environfile = os.path.join(dirname, '.anaconda')
                if os.path.exists(environfile) and os.path.isfile(environfile):
                    # print("Environ found on %s" % environfile)
                    with open(environfile, 'r') as jsonfile:
                        try:
                            data = json.loads(jsonfile.read())
                        except Exception as error:
                            sublime.error_message(
                                "Anaconda Message:\n"
                                "I found an .anaconda environment file in {} "
                                "path but it doesn't seems to be a valid JSON "
                                "file.\n\nThat means that your .anaconda "
                                "hook file is being ignored.".format(
                                    environfile))
                            logging.error(error)
                            ENVIRON_HOOK_INVALID[view.id()] = True
                            break  # stop loop
                        else:
                            r = data.get(
                                name,
                                view.settings().get(
                                    name, plugin_settings.get(name, default)))
                            w = view.window()
                            if w is not None:
                                return sublime.expand_variables(
                                    r, w.extract_variables())

                            return r
                else:
                    parts = os.path.split(dirname)
                    if len(parts[1]) > 0:
                        dirname = os.path.dirname(dirname)
                    else:
                        break  # stop loop

    r = view.settings().get(name, plugin_settings.get(name, default))
    if name == 'python_interpreter':
        r = expand(view, r)
    elif name == 'extra_paths':
        if isinstance(r, (list, tuple)):
            r = [expand(view, e) for e in r]
        else:
            r = expand(view, r)

    return r
Ejemplo n.º 60
0
    def _launch(self, base, override, diff_args):
        shell_cmd = diff_args.get("shell_cmd")
        env = diff_args.get("env", {})
        working_dir = diff_args.get("working_dir", "")

        if not shell_cmd:
            raise ValueError("shell_cmd is required")

        if not isinstance(shell_cmd, str):
            raise ValueError("shell_cmd must be a string")

        variables = self.window.extract_variables()
        variables["base"] = base
        variables["override"] = override

        # Don't expand vars in env; we let python do that for us.
        shell_cmd = sublime.expand_variables(shell_cmd, variables)
        working_dir = sublime.expand_variables(working_dir, variables)

        if working_dir == "" and self.window.active_view():
            path = os.path.dirname(self.window.active_view().file_name() or "")
            if os.path.isdir(path):
                working_dir = path

        log("Running %s", shell_cmd)

        # Hide the console window on Windows
        startupinfo = None
        if os.name == "nt":
            startupinfo = subprocess.STARTUPINFO()
            startupinfo.dwFlags |= subprocess.STARTF_USESHOWWINDOW

        process_env = os.environ.copy()
        process_env.update(env)
        for var, value in process_env.items():
            process_env[var] = os.path.expandvars(value)

        # Might not exist, but that is a user error. We checked before auto
        # changing it.
        if working_dir != "":
            os.chdir(working_dir)

        if sys.platform == "win32":
            # Use shell=True on Windows, so shell_cmd is passed through with the correct escaping
            self.proc = subprocess.Popen(shell_cmd,
                                         stdout=subprocess.DEVNULL,
                                         stderr=subprocess.DEVNULL,
                                         stdin=subprocess.DEVNULL,
                                         startupinfo=startupinfo,
                                         env=process_env,
                                         shell=True)
        elif sys.platform == "darwin":
            # Use a login shell on OSX, otherwise the users expected env vars won't be setup
            self.proc = subprocess.Popen(
                ["/usr/bin/env", "bash", "-l", "-c", shell_cmd],
                stdout=subprocess.DEVNULL,
                stderr=subprocess.DEVNULL,
                stdin=subprocess.DEVNULL,
                startupinfo=startupinfo,
                env=process_env,
                shell=False)
        elif sys.platform == "linux":
            # Explicitly use /bin/bash on Linux, to keep Linux and OSX as
            # similar as possible. A login shell is explicitly not used for
            # linux, as it's not required
            self.proc = subprocess.Popen(
                ["/usr/bin/env", "bash", "-c", shell_cmd],
                stdout=subprocess.DEVNULL,
                stderr=subprocess.DEVNULL,
                stdin=subprocess.DEVNULL,
                startupinfo=startupinfo,
                env=process_env,
                shell=False)