Esempio n. 1
0
 def run(self, url):
     if url.startswith('https://github.com/jonlabelle/SublimeJsPrettier', 0,
                       47):
         st_status_message('Opening web browser to {0} ...'.format(url))
         webbrowser.open_new_tab(url)
     else:
         st_status_message(
             'Cannot open untrusted addresses in web browser : {0}'.format(
                 url))
Esempio n. 2
0
    def run(self, edit, code="", cursor=None, region=None, save=False):
        view = self.view
        if region:
            region = sublime.Region(*region)
        else:
            region = sublime.Region(0, view.size())

        # 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(code):
            print("Empty content returned to stdout")
            return show_status_bar_error()

        source_modified = False
        source = view.substr(region)
        code = trim_trailing_ws_and_lines(code)
        if code:
            if code == trim_trailing_ws_and_lines(source):
                if 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, code)
                ensure_newline_at_eof(view, edit)
                source_modified = True
        else:
            view.replace(edit, region, code)
            ensure_newline_at_eof(view, edit)
            source_modified = True

        if source_modified:
            view.sel().clear()
            view.sel().add(sublime.Region(cursor))
            st_status_message("File formatted.")
        else:
            st_status_message("File already formatted.")

        if save:
            sublime.set_timeout_async(
                functools.partial(save_view, self.view.id()), 1)
Esempio n. 3
0
 def show_status_bar_error():
     st_status_message(
         'Format failed! Open the console window to inspect errors.')
Esempio n. 4
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.')
Esempio n. 5
0
 def show_status_bar_error():
     st_status_message('Format failed! Open the console window to inspect errors.')
Esempio n. 6
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.')
Esempio n. 7
0
 def run(self):
     clear_cache()
     st_status_message('Cached paths cleared.')
Esempio n. 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('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.')
Esempio n. 9
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,
                )