Beispiel #1
0
    def try_find_prettier_config(self, view):
        try:
            source_file_dir = get_file_abs_dir(view.file_name())
        except:
            source_file_dir = get_st_project_path()
        st_project_path = get_st_project_path()

        #
        # 1. Attempt to use prettier config defined in the 'additional_cli_args' (if exist - ensure it's abs path)

        # check if '--config <filename>' is defined in 'additional_cli_args'
        # parsed_additional_cli_args = parse_additional_cli_args(self.get_additional_cli_args(view))
        additional_cli_arg_config = get_cli_arg_value(self.additional_cli_args,
                                                      "--config")
        if not is_str_none_or_empty(additional_cli_arg_config):
            additional_cli_arg_config = os.path.normpath(
                additional_cli_arg_config)
            if not os.path.isabs(additional_cli_arg_config):
                additional_cli_arg_config = in_source_file_path_or_project_root(
                    source_file_dir, st_project_path,
                    additional_cli_arg_config)
                if additional_cli_arg_config and os.path.exists(
                        additional_cli_arg_config):
                    log_debug(
                        view,
                        "Using Prettier config file defined in 'additional_cli_args' config -> {0}'"
                        "".format(additional_cli_arg_config),
                        True,
                    )
                    return additional_cli_arg_config

                log_warn(
                    "Cannot find Prettier config file defined "
                    "in 'additional_cli_args' -> '--config <path>'.",
                    True,
                )

                return None

        #
        # 2. Attempt to resolve a prettier config path:
        resolved_prettier_config = find_prettier_config(source_file_dir)
        if resolved_prettier_config and os.path.exists(
                resolved_prettier_config):
            log_debug(
                view,
                "Prettier config file discovered at '{0}'".format(
                    resolved_prettier_config),
            )
            return resolved_prettier_config

        log_debug(
            view,
            "Prettier config file not found. "
            "Will use Prettier options defined in Sublime Text '{0}' file.".
            format(SETTINGS_FILENAME),
            True,
        )

        return None
Beispiel #2
0
    def try_find_prettier_config(self, view):
        source_file_dir = get_file_abs_dir(view.file_name())
        st_project_path = get_st_project_path()

        #
        # 1. Check if defined in 'additional_cli_args':
        additional_cli_arg_config = get_cli_arg_value(
            self.get_additional_cli_args(view), '--config')
        if not is_str_none_or_empty(additional_cli_arg_config):
            additional_cli_arg_config = os.path.normpath(
                additional_cli_arg_config)
            if not os.path.isabs(additional_cli_arg_config):
                additional_cli_arg_config = in_source_file_path_or_project_root(
                    source_file_dir, st_project_path,
                    additional_cli_arg_config)
                if additional_cli_arg_config and os.path.exists(
                        additional_cli_arg_config):
                    return additional_cli_arg_config
                return None

        #
        # 2. Attempt to automatically resolve:
        resolved_prettier_config = find_prettier_config(source_file_dir)
        if resolved_prettier_config and os.path.exists(
                resolved_prettier_config):
            return resolved_prettier_config

        return None
Beispiel #3
0
    def try_find_prettier_config(self, view):
        source_file_dir = get_file_abs_dir(view.file_name())
        st_project_path = get_st_project_path()

        #
        # 1. Attempt to use prettier config defined in the 'additional_cli_args' (if exist - ensure it's abs path)
        additional_cli_arg_config = get_cli_arg_value(
            self.get_additional_cli_args(view), '--config')
        if not is_str_none_or_empty(additional_cli_arg_config):
            additional_cli_arg_config = os.path.normpath(
                additional_cli_arg_config)
            if not os.path.isabs(additional_cli_arg_config):
                additional_cli_arg_config = in_source_file_path_or_project_root(
                    source_file_dir, st_project_path,
                    additional_cli_arg_config)
                if additional_cli_arg_config and os.path.exists(
                        additional_cli_arg_config):
                    return additional_cli_arg_config
                return None

        #
        # 2. Attempt to resolve a prettier config path:
        resolved_prettier_config = find_prettier_config(source_file_dir)
        if resolved_prettier_config and os.path.exists(
                resolved_prettier_config):
            return resolved_prettier_config

        return None
    def try_find_prettier_config(self, view):
        source_file_dir = get_file_abs_dir(view.file_name())
        st_project_path = get_st_project_path()

        #
        # 1. Check if defined in 'additional_cli_args':
        additional_cli_arg_config = get_cli_arg_value(self.additional_cli_args, '--config')
        if not is_str_none_or_empty(additional_cli_arg_config):
            additional_cli_arg_config = os.path.normpath(additional_cli_arg_config)
            if not os.path.isabs(additional_cli_arg_config):
                additional_cli_arg_config = in_source_file_path_or_project_root(
                    source_file_dir, st_project_path, additional_cli_arg_config)
                if additional_cli_arg_config and os.path.exists(additional_cli_arg_config):
                    log_debug(view, "Using Prettier config file defined in additional_cli_args '{0}'"
                              .format(additional_cli_arg_config), True)
                    return additional_cli_arg_config
                log_warn("Could not find Prettier config file defined in additional_cli_args '{0}'"
                         .format(str(additional_cli_arg_config)), True)
                return None

        #
        # 2. Attempt to automatically resolve:
        resolved_prettier_config = find_prettier_config(source_file_dir)
        if resolved_prettier_config and os.path.exists(resolved_prettier_config):
            log_debug(view, "Found Prettier config file '{0}'".format(resolved_prettier_config))
            return resolved_prettier_config

        log_debug(view, "Could not resolve Prettier config file, will use options defined in Sublime Text.", True)

        return None
Beispiel #5
0
    def try_find_prettier_config(self, view):
        source_file_dir = get_file_abs_dir(view.file_name())
        st_project_path = get_st_project_path()

        #
        # 1. Attempt to use prettier config defined in the 'additional_cli_args' (if exist - ensure it's abs path)

        # check if '--config <filename>' is defined in 'additional_cli_args'
        # parsed_additional_cli_args = parse_additional_cli_args(self.get_additional_cli_args(view))
        additional_cli_arg_config = get_cli_arg_value(self.additional_cli_args, '--config')
        if not is_str_none_or_empty(additional_cli_arg_config):
            additional_cli_arg_config = os.path.normpath(additional_cli_arg_config)
            if not os.path.isabs(additional_cli_arg_config):
                additional_cli_arg_config = in_source_file_path_or_project_root(
                    source_file_dir, st_project_path, additional_cli_arg_config)
                if additional_cli_arg_config and os.path.exists(additional_cli_arg_config):
                    log_debug(view, "Using Prettier config defined in 'additional_cli_args' config -> {0}'"
                                    "".format(additional_cli_arg_config))
                    return additional_cli_arg_config
                log_warn("Cannot find Prettier config defined in 'additional_cli_args' -> '--config <path>'.")
                return None

        #
        # 2. Attempt to resolve a prettier config path:
        resolved_prettier_config = find_prettier_config(source_file_dir)
        if resolved_prettier_config and os.path.exists(resolved_prettier_config):
            log_debug(view, "Prettier config resolved at '{0}'".format(resolved_prettier_config))
            return resolved_prettier_config

        log_debug(view, "Unable to resolve a Prettier config file. "
                        "Using options defined in '{0}'.".format(SETTINGS_FILENAME))

        return None
Beispiel #6
0
    def try_find_prettier_config(self, view):
        source_file_dir = get_file_abs_dir(view.file_name())
        st_project_path = get_st_project_path()

        #
        # 1. Attempt to use prettier config defined in the 'additional_cli_args' (if exist - ensure it's abs path)
        additional_cli_arg_config = get_cli_arg_value(self.get_additional_cli_args(view), '--config')
        if not is_str_none_or_empty(additional_cli_arg_config):
            additional_cli_arg_config = os.path.normpath(additional_cli_arg_config)
            if not os.path.isabs(additional_cli_arg_config):
                additional_cli_arg_config = in_source_file_path_or_project_root(
                    source_file_dir, st_project_path, additional_cli_arg_config)
                if not additional_cli_arg_config or not os.path.exists(additional_cli_arg_config):
                    return None

                return additional_cli_arg_config

        #
        # 2. Attempt to resolve a prettier config path:
        resolved_prettier_config = find_prettier_config(source_file_dir)

        if not resolved_prettier_config or not os.path.exists(resolved_prettier_config):
            return None

        # if we get here, a config file was found:
        return resolved_prettier_config
Beispiel #7
0
    def try_find_prettier_config(self, view):
        source_file_dir = get_file_abs_dir(view.file_name())
        st_project_path = get_st_project_path()

        #
        # 1. Attempt to use prettier config defined in the 'additional_cli_args' (if exist - ensure it's abs path)

        # check if '--config <filename>' is defined in 'additional_cli_args'
        # parsed_additional_cli_args = parse_additional_cli_args(self.get_additional_cli_args(view))
        additional_cli_arg_config = get_cli_arg_value(self.additional_cli_args,
                                                      '--config')
        if not is_str_none_or_empty(additional_cli_arg_config):
            additional_cli_arg_config = os.path.normpath(
                additional_cli_arg_config)
            if not os.path.isabs(additional_cli_arg_config):
                additional_cli_arg_config = in_source_file_path_or_project_root(
                    source_file_dir, st_project_path,
                    additional_cli_arg_config)
                if not additional_cli_arg_config or not os.path.exists(
                        additional_cli_arg_config):
                    log_warn(
                        "Cannot find Prettier config defined in 'additional_cli_args' -> '--config <path>'."
                    )
                    return None
                log_debug(
                    view,
                    "Using Prettier config defined in 'additional_cli_args' "
                    "config -> {0}'".format(additional_cli_arg_config))
                return additional_cli_arg_config

        #
        # 2. Attempt to resolve a prettier config path:
        resolved_prettier_config = find_prettier_config(source_file_dir)

        if not resolved_prettier_config or not os.path.exists(
                resolved_prettier_config):
            log_debug(
                view,
                "Unable to resolve a Prettier config file. Using options defined in '{0}'."
                .format(SETTINGS_FILENAME))
            return None

        log_debug(
            view, "Prettier config resolved at '{0}'".format(
                resolved_prettier_config))

        return resolved_prettier_config
Beispiel #8
0
    def run(self,
            edit,
            save_file=False,
            auto_format_prettier_config_path=None):
        view = self.view
        source_file_path = view.file_name()

        if source_file_path is None:
            #
            # Handle file must first be saved:
            if IS_ST3:
                # sublime text 3+: show dialog that includes a save option:
                result = sublime.yes_no_cancel_dialog(
                    '{0}\n\n'
                    'File must first be Saved.'.format(PLUGIN_NAME), 'Save...',
                    "Don't Save")
                if result == sublime.DIALOG_YES:
                    view.run_command('save')
            else:
                # sublime text 2x: limited dialog support, just show error:
                return sublime.error_message(
                    '{0} Error\n\n'
                    'File must first be saved.'.format(PLUGIN_NAME))

        #
        # set paths
        if source_file_path is None:
            # Re-check if file was saved, in case user canceled or closed the save dialog:
            return st_status_message('Save canceled.')

        #
        # Max file size check
        if self.exceeds_max_file_size_limit(source_file_path):
            return st_status_message(
                'Ignored - file too large to format (max_file_size_limit).')

        source_file_dir = get_file_abs_dir(source_file_path)
        st_project_path = str(get_st_project_path())

        #
        # cd to the active sublime text project dir:
        os.chdir(st_project_path)

        #
        # if a `--config <path>` option is set in 'additional_cli_args',
        # no action is necessary. otherwise, try to sniff the config
        # file path:
        parsed_additional_cli_args = parse_additional_cli_args(
            view.window(), self.additional_cli_args)
        has_custom_config_defined = parsed_additional_cli_args.count(
            '--config') > 0
        has_no_config_defined = parsed_additional_cli_args.count(
            '--no-config') > 0
        has_config_precedence_defined = parsed_additional_cli_args.count(
            '--config-precedence') > 0

        prettier_config_path = None
        # only try to resolve prettier config if '--no-config' or '--config' are NOT in 'additional_cli_args'
        if not has_no_config_defined and not has_custom_config_defined:
            if save_file and auto_format_prettier_config_path and os.path.exists(
                    auto_format_prettier_config_path):
                prettier_config_path = auto_format_prettier_config_path
            if not prettier_config_path:
                resolved_prettier_config = self.try_find_prettier_config(view)
                if resolved_prettier_config and os.path.exists(
                        resolved_prettier_config):
                    prettier_config_path = resolved_prettier_config
        if not prettier_config_path or not os.path.exists(
                prettier_config_path):
            prettier_config_path = ''

        #
        # Get node and prettier command paths:
        node_path = self.node_path
        prettier_cli_path = resolve_prettier_cli_path(view, PLUGIN_PATH,
                                                      st_project_path)
        if not prettier_cli_path:
            log_error(
                "Ensure 'prettier' is installed in your environment PATH, "
                "or manually specify an absolute path in your '{0}' file "
                "and the 'prettier_cli_path' setting.".format(
                    SETTINGS_FILENAME))
            return st_status_message(
                'Prettier not found. See console for more details.')

        # try to find a '.prettierignore' file path in the project root
        # if the '--ignore-path' option isn't specified in 'additional_cli_args':
        prettier_ignore_filepath = None
        if not parsed_additional_cli_args.count('--ignore-path') > 0:
            prettier_ignore_filepath = resolve_prettier_ignore_path(
                source_file_dir, st_project_path)

        #
        # Parse prettier options:
        prettier_options = self.parse_prettier_options(
            view, parsed_additional_cli_args, prettier_config_path,
            has_custom_config_defined, has_no_config_defined,
            has_config_precedence_defined, prettier_ignore_filepath,
            source_file_path)

        #
        # Format entire file:
        if not has_selection(view) or save_file is True:
            region = sublime.Region(0, view.size())
            source_text = view.substr(region)
            if is_str_empty_or_whitespace_only(source_text):
                return st_status_message('Nothing to format.')

            result = self.format_code(
                source_text,
                node_path,
                prettier_cli_path,
                prettier_options,
                view,
                provide_cursor=self.disable_prettier_cursor_offset is False,
                is_selection=False)

            if self.has_error:
                self.format_console_error()
                return self.show_status_bar_error()

            new_cursor = None
            if self.disable_prettier_cursor_offset is True:
                prettified_text = result
            else:
                prettified_text, new_cursor = result

            # sanity check to ensure textual content was returned from cmd
            # stdout, not necessarily caught in OSError try/catch
            # exception handler
            if is_str_empty_or_whitespace_only(prettified_text):
                self.error_message = 'No content returned by stdout'
                return self.show_status_bar_error()

            source_modified = False
            prettified_text = trim_trailing_ws_and_lines(prettified_text)

            # Store viewport position to prevent screen jumping (#171):
            previous_position = view.viewport_position()

            if prettified_text:
                if prettified_text == trim_trailing_ws_and_lines(source_text):
                    if self.ensure_newline_at_eof(view, edit) is True:
                        # no formatting changes applied, however, a line
                        # break was needed/inserted at the end of the file:
                        source_modified = True
                else:
                    view.replace(edit, region, prettified_text)
                    self.ensure_newline_at_eof(view, edit)
                    source_modified = True
            else:
                view.replace(edit, region, prettified_text)
                self.ensure_newline_at_eof(view, edit)
                source_modified = True

            # Restore viewport position to prevent screen jumping (#171)
            view.set_viewport_position((0, 0), False)
            view.set_viewport_position(previous_position, False)

            if source_modified:
                if not self.disable_prettier_cursor_offset and new_cursor:
                    view.sel().clear()
                    view.sel().add(sublime.Region(new_cursor))
                # re-run indention detection
                view.run_command('detect_indentation')
                st_status_message('File formatted.')
            else:
                st_status_message('File already formatted.')

            return

        #
        # Format each selection:
        atleast_one_selection_formatted = False
        for region in view.sel():
            if region.empty():
                continue

            source_text = view.substr(region)
            if is_str_empty_or_whitespace_only(source_text):
                st_status_message('Nothing to format in selection.')
                continue

            prettified_text = self.format_code(source_text,
                                               node_path,
                                               prettier_cli_path,
                                               prettier_options,
                                               view,
                                               provide_cursor=False,
                                               is_selection=True)

            if self.has_error:
                self.format_console_error()
                return self.show_status_bar_error()

            # sanity check to ensure textual content was returned from cmd
            # stdout, not necessarily caught in OSError try/catch
            # exception handler
            if is_str_empty_or_whitespace_only(prettified_text):
                self.error_message = 'No content returned by stdout'
                return self.show_status_bar_error()

            prettified_text = trim_trailing_ws_and_lines(prettified_text)
            if prettified_text and prettified_text == trim_trailing_ws_and_lines(
                    source_text):
                st_status_message('Selection(s) already formatted.')
            else:
                atleast_one_selection_formatted = True
                view.replace(edit, region, prettified_text)

        # re-run indention detection
        if atleast_one_selection_formatted:
            view.run_command('detect_indentation')
            st_status_message('Selection(s) formatted.')
Beispiel #9
0
    def run(self, edit, save_file=False, auto_format_prettier_config_path=None):
        view = self.view
        source_file_path = view.file_name()

        if source_file_path is None:
            #
            # Handle file must first be saved:
            if IS_ST3:
                # sublime text 3+: show dialog that includes a save option:
                result = sublime.yes_no_cancel_dialog(
                    '{0}\n\n'
                    'File must first be Saved.'.format(PLUGIN_NAME),
                    'Save...', "Don't Save")
                if result == sublime.DIALOG_YES:
                    view.run_command('save')
            else:
                # sublime text 2x: limited dialog support, just show error:
                return sublime.error_message(
                    '{0} Error\n\n'
                    'File must first be saved.'.format(PLUGIN_NAME))

        #
        # set paths
        if source_file_path is None:
            # Re-check if file was saved, in case user canceled or closed the save dialog:
            return st_status_message('Save canceled.')

        #
        # Max file size check
        if self.exceeds_max_file_size_limit(source_file_path):
            return st_status_message('Maximum file size reached.')

        source_file_dir = get_file_abs_dir(source_file_path)
        st_project_path = str(get_st_project_path())

        #
        # cd to the active sublime text project dir:
        os.chdir(st_project_path)

        #
        # if a `--config <path>` option is set in 'additional_cli_args',
        # no action is necessary. otherwise, try to sniff the config
        # file path:
        parsed_additional_cli_args = parse_additional_cli_args(self.additional_cli_args)
        has_custom_config_defined = parsed_additional_cli_args.count('--config') > 0
        has_no_config_defined = parsed_additional_cli_args.count('--no-config') > 0
        has_config_precedence_defined = parsed_additional_cli_args.count('--config-precedence') > 0

        prettier_config_path = None
        if not has_no_config_defined:
            if save_file and auto_format_prettier_config_path and os.path.exists(auto_format_prettier_config_path):
                prettier_config_path = auto_format_prettier_config_path
            if not prettier_config_path:
                resolved_prettier_config = self.try_find_prettier_config(view)
                if resolved_prettier_config and os.path.exists(resolved_prettier_config):
                    prettier_config_path = resolved_prettier_config
        if not prettier_config_path or not os.path.exists(prettier_config_path):
            prettier_config_path = ''
            has_custom_config_defined = False

        #
        # Get node and prettier command paths:
        node_path = self.node_path
        prettier_cli_path = resolve_prettier_cli_path(view, PLUGIN_PATH, st_project_path)
        if not prettier_cli_path:
            log_error(
                "Ensure 'prettier' is installed in your environment PATH, "
                "or manually specify an absolute path in your '{0}' file "
                "and the 'prettier_cli_path' setting.".format(SETTINGS_FILENAME))
            return st_status_message('Prettier not found. Open console for more details.')

        # try to find a '.prettierignore' file path in the project root
        # if the '--ignore-path' option isn't specified in 'additional_cli_args':
        prettier_ignore_filepath = None
        if not parsed_additional_cli_args.count('--ignore-path') > 0:
            prettier_ignore_filepath = resolve_prettier_ignore_path(source_file_dir, st_project_path)

        #
        # Parse prettier options:
        prettier_options = self.parse_prettier_options(
            view, parsed_additional_cli_args, prettier_config_path,
            has_custom_config_defined, has_no_config_defined,
            has_config_precedence_defined, prettier_ignore_filepath,
            source_file_path)

        #
        # Format entire file:
        if not has_selection(view) or save_file is True:
            region = sublime.Region(0, view.size())
            source = view.substr(region)
            if is_str_empty_or_whitespace_only(source):
                return st_status_message('Nothing to format in file.')

            transformed = self.format_code(source, node_path, prettier_cli_path, prettier_options, view)
            if self.has_error:
                self.format_console_error()
                return self.show_status_bar_error()

            # sanity check to ensure textual content was returned from cmd
            # stdout, not necessarily caught in OSError try/catch
            # exception handler
            if is_str_empty_or_whitespace_only(transformed):
                self.error_message = 'Empty content returned to stdout'
                return self.show_status_bar_error()

            source_modified = False
            transformed = trim_trailing_ws_and_lines(transformed)
            if transformed:
                if transformed == trim_trailing_ws_and_lines(source):
                    if self.ensure_newline_at_eof(view, edit) is True:
                        # no formatting changes applied, however, a line
                        # break was needed/inserted at the end of the file:
                        source_modified = True
                else:
                    view.replace(edit, region, transformed)
                    self.ensure_newline_at_eof(view, edit)
                    source_modified = True
            else:
                view.replace(edit, region, transformed)
                self.ensure_newline_at_eof(view, edit)
                source_modified = True

            if source_modified:
                st_status_message('File formatted.')
            else:
                st_status_message('File already formatted.')
            return

        #
        # Format each selection:
        for region in view.sel():
            if region.empty():
                continue

            source = view.substr(region)
            if is_str_empty_or_whitespace_only(source):
                st_status_message('Nothing to format in selection.')
                continue

            transformed = self.format_code(source, node_path, prettier_cli_path, prettier_options, view)
            if self.has_error:
                self.format_console_error()
                return self.show_status_bar_error()

            # sanity check to ensure textual content was returned from cmd
            # stdout, not necessarily caught in OSError try/catch
            # exception handler
            if is_str_empty_or_whitespace_only(transformed):
                self.error_message = 'Empty content returned to stdout'
                return self.show_status_bar_error()

            transformed = trim_trailing_ws_and_lines(transformed)
            if transformed and transformed == trim_trailing_ws_and_lines(source):
                st_status_message('Selection(s) already formatted.')
            else:
                view.replace(edit, region, transformed)
                st_status_message('Selection(s) formatted.')
Beispiel #10
0
    def run(self,
            edit,
            save_file=False,
            auto_format_prettier_config_path=None):
        view = self.view
        source_file_path = view.file_name()

        if source_file_path is None:
            #
            # Handle file must first be saved:
            if IS_ST3:
                # sublime text 3+: show dialog that includes a save option:
                result = sublime.yes_no_cancel_dialog(
                    '{0}\n\n'
                    'File must first be Saved.'.format(PLUGIN_NAME), 'Save...',
                    "Don't Save")
                if result == sublime.DIALOG_YES:
                    view.run_command('save')
            else:
                # sublime text 2x: limited dialog support, just show error:
                return sublime.error_message(
                    '{0} Error\n\n'
                    'File must first be saved.'.format(PLUGIN_NAME))

        #
        # set paths
        if source_file_path is None:
            # Re-check if file was saved, in case user canceled or closed the save dialog:
            return st_status_message('Save canceled.')

        #
        # Max file size check
        if self.exceeds_max_file_size_limit(source_file_path):
            return st_status_message('Maximum file size reached.')

        source_file_dir = get_file_abs_dir(source_file_path)
        st_project_path = get_st_project_path()

        #
        # cd to the active sublime text project dir:
        os.chdir(str(st_project_path))

        #
        # if a `--config <path>` option is set in 'additional_cli_args',
        # no action is necessary. otherwise, try to sniff the config
        # file path:
        parsed_additional_cli_args = parse_additional_cli_args(
            self.additional_cli_args)
        has_custom_config_defined = parsed_additional_cli_args.count(
            '--config') > 0
        has_no_config_defined = parsed_additional_cli_args.count(
            '--no-config') > 0
        has_config_precedence_defined = parsed_additional_cli_args.count(
            '--config-precedence') > 0

        prettier_config_path = None
        if not has_no_config_defined:
            if save_file and auto_format_prettier_config_path and os.path.exists(
                    auto_format_prettier_config_path):
                prettier_config_path = auto_format_prettier_config_path
            if not prettier_config_path:
                custom_prettier_config = get_cli_arg_value(
                    self.additional_cli_args, '--config')
                if custom_prettier_config and not os.path.exists(
                        custom_prettier_config):
                    prettier_config_path = custom_prettier_config
            if not prettier_config_path:
                prettier_config_path = resolve_prettier_config(view)

        #
        # Get node and prettier command paths:
        node_path = self.node_path
        prettier_cli_path = resolve_prettier_cli_path(view, PLUGIN_PATH)
        if prettier_cli_path is None:
            return st_status_message(
                "Error\n\n"
                "Command not found: 'prettier'\n\n"
                "Ensure 'prettier' is installed in your environment PATH, "
                "or manually specify an absolute path in your '{0}' file "
                "and the 'prettier_cli_path' setting.".format(
                    SETTINGS_FILENAME))

        # try to find a '.prettierignore' file path in the project root
        # if the '--ignore-path' option isn't specified in 'additional_cli_args':
        prettier_ignore_filepath = None
        if not parsed_additional_cli_args.count('--ignore-path') > 0:
            prettier_ignore_filepath = resolve_prettier_ignore_path(
                source_file_dir, st_project_path)

        #
        # Parse prettier options:
        prettier_options = self.parse_prettier_options(
            view, parsed_additional_cli_args, prettier_config_path,
            has_custom_config_defined, has_no_config_defined,
            has_config_precedence_defined, prettier_ignore_filepath,
            source_file_path)

        #
        # Format entire file:
        if not has_selection(view) or save_file is True:
            region = sublime.Region(0, view.size())
            source = view.substr(region)
            if is_str_empty_or_whitespace_only(source):
                return st_status_message('Nothing to format in file.')

            transformed = self.format_code(source, node_path,
                                           prettier_cli_path, prettier_options,
                                           view)
            if self.has_error:
                self.format_console_error()
                return self.show_status_bar_error()

            # sanity check to ensure textual content was returned from cmd
            # stdout, not necessarily caught in OSError try/catch
            # exception handler
            if is_str_empty_or_whitespace_only(transformed):
                self.error_message = 'Empty content returned to stdout'
                return self.show_status_bar_error()

            source_modified = False
            transformed = trim_trailing_ws_and_lines(transformed)
            if transformed:
                if transformed == trim_trailing_ws_and_lines(source):
                    if self.ensure_newline_at_eof(view, edit) is True:
                        # no formatting changes applied, however, a line
                        # break was needed/inserted at the end of the file:
                        source_modified = True
                else:
                    view.replace(edit, region, transformed)
                    self.ensure_newline_at_eof(view, edit)
                    source_modified = True
            else:
                view.replace(edit, region, transformed)
                self.ensure_newline_at_eof(view, edit)
                source_modified = True

            if source_modified:
                st_status_message('File formatted.')
            else:
                st_status_message('File already formatted.')
            return

        #
        # Format each selection:
        for region in view.sel():
            if region.empty():
                continue

            source = view.substr(region)
            if is_str_empty_or_whitespace_only(source):
                st_status_message('Nothing to format in selection.')
                continue

            transformed = self.format_code(source, node_path,
                                           prettier_cli_path, prettier_options,
                                           view)
            if self.has_error:
                self.format_console_error()
                return self.show_status_bar_error()

            # sanity check to ensure textual content was returned from cmd
            # stdout, not necessarily caught in OSError try/catch
            # exception handler
            if is_str_empty_or_whitespace_only(transformed):
                self.error_message = 'Empty content returned to stdout'
                return self.show_status_bar_error()

            transformed = trim_trailing_ws_and_lines(transformed)
            if transformed and transformed == trim_trailing_ws_and_lines(
                    source):
                st_status_message('Selection(s) already formatted.')
            else:
                view.replace(edit, region, transformed)
                st_status_message('Selection(s) formatted.')
Beispiel #11
0
    def run(self,
            edit,
            save_file=False,
            auto_format_prettier_config_path=None):
        view = self.view
        source_file_path = view.file_name()

        sublime.status_message("Formatting code...")

        # if source_file_path is None:
        #
        # Handle file must first be saved:
        # if IS_ST3:
        #     # sublime text 3+: show dialog that includes a save option:
        #     result = sublime.yes_no_cancel_dialog(
        #         '{0}\n\n'
        #         'File must first be Saved.'.format(PLUGIN_NAME),
        #         'Save...', "Don't Save")
        #     if result == sublime.DIALOG_YES:
        #         view.run_command('save')
        # else:
        #     # sublime text 2x: limited dialog support, just show error:
        #     return sublime.error_message(
        #         '{0} Error\n\n'
        #         'File must first be saved.'.format(PLUGIN_NAME))

        #
        # set paths
        # if source_file_path is None:
        # Re-check if file was saved, in case user canceled or closed the save dialog:
        # return st_status_message("Save canceled.")

        #
        # Max file size check
        if self.exceeds_max_file_size_limit():
            return st_status_message("Maximum file size reached.")

        st_project_path = str(get_st_project_path())
        try:
            source_file_dir = get_file_abs_dir(source_file_path)
        except:
            source_file_dir = st_project_path

        #
        # cd to the active sublime text project dir:
        os.chdir(st_project_path)

        #
        # if a `--config <path>` option is set in 'additional_cli_args',
        # no action is necessary. otherwise, try to sniff the config
        # file path:
        parsed_additional_cli_args = parse_additional_cli_args(
            self.additional_cli_args)
        has_custom_config_defined = parsed_additional_cli_args.count(
            "--config") > 0
        has_no_config_defined = parsed_additional_cli_args.count(
            "--no-config") > 0
        has_config_precedence_defined = (
            parsed_additional_cli_args.count("--config-precedence") > 0)

        prettier_config_path = None
        # only try to resolve prettier config if '--no-config' or '--config' are NOT in 'additional_cli_args'
        if not has_no_config_defined and not has_custom_config_defined:
            if (save_file and auto_format_prettier_config_path
                    and os.path.exists(auto_format_prettier_config_path)):
                prettier_config_path = auto_format_prettier_config_path
            if not prettier_config_path:
                resolved_prettier_config = self.try_find_prettier_config(view)
                if resolved_prettier_config and os.path.exists(
                        resolved_prettier_config):
                    prettier_config_path = resolved_prettier_config
        if not prettier_config_path or not os.path.exists(
                prettier_config_path):
            prettier_config_path = ""

        #
        # Get node and prettier command paths:
        node_path = self.node_path
        prettier_cli_path = resolve_prettier_cli_path(view, PLUGIN_PATH,
                                                      st_project_path)
        if not prettier_cli_path:
            log_error(
                "Ensure 'prettier' is installed in your environment PATH, "
                "or manually specify an absolute path in your '{0}' file "
                "and the 'prettier_cli_path' setting.".format(
                    SETTINGS_FILENAME))
            return st_status_message(
                "Prettier not found. Open console for more details.")

        # try to find a '.prettierignore' file path in the project root
        # if the '--ignore-path' option isn't specified in 'additional_cli_args':
        prettier_ignore_filepath = None
        if not parsed_additional_cli_args.count("--ignore-path") > 0:
            prettier_ignore_filepath = resolve_prettier_ignore_path(
                source_file_dir, st_project_path)

        #
        # Parse prettier options:
        prettier_options = self.parse_prettier_options(
            view,
            parsed_additional_cli_args,
            prettier_config_path,
            has_custom_config_defined,
            has_no_config_defined,
            has_config_precedence_defined,
            prettier_ignore_filepath,
            source_file_path,
        )

        #
        # Format entire file:
        if not has_selection(view) or save_file is True:
            region = sublime.Region(0, view.size())
            source = view.substr(region)
            if is_str_empty_or_whitespace_only(source):
                return st_status_message("Nothing to format in file.")

            sublime.set_timeout_async(
                functools.partial(
                    self.format_code,
                    source,
                    node_path,
                    prettier_cli_path,
                    prettier_options,
                    self.view.id(),
                    provide_cursor=True,
                    save=save_file,
                ),
                10,
            )
        else:
            for region in view.sel():
                if region.empty():
                    continue

                source = view.substr(region)
                if is_str_empty_or_whitespace_only(source):
                    st_status_message("Nothing to format in selection.")
                    continue

                sublime.set_timeout_async(
                    functools.partial(
                        self.format_code,
                        source,
                        node_path,
                        prettier_cli_path,
                        prettier_options,
                        self.view.id(),
                        region=region,
                    ),
                    5,
                )