Ejemplo n.º 1
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.')
Ejemplo n.º 2
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.')
Ejemplo n.º 3
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,
                )