Exemple #1
0
def format_nb(notebook_filename, dry_run=False):
    print('Formatting {}...'.format(notebook_filename), end='')
    with open(notebook_filename, 'r') as f:
        notebook = nbformat.read(f, as_version=nbformat.NO_CONVERT)
    nbformat.validate(notebook)

    changed = False

    for cell in notebook.cells:
        if cell['cell_type'] != 'code':
            continue

        src = cell['source']
        lines = src.split('\n')
        if len(lines) <= 0 or '# noqa' in lines[0]:
            continue

        formatted_src, did_change = FormatCode(src, style_config=style_file)
        if formatted_src.endswith('\n'):
            formatted_src = formatted_src[:-1]  # remove last newline
            did_change = True
        if did_change:
            cell['source'] = formatted_src
            changed = True

    if changed:
        if dry_run:
            print(' (reformatted)')
        else:
            with open(notebook_filename, 'w') as f:
                nbformat.write(notebook, f, version=nbformat.NO_CONVERT)
            print()
    else:
        print()
Exemple #2
0
    def rpc_lsp_formatter_yapf(self, args: List[Any]) -> Any:
        buf_path: Optional[str]
        buf_root_dir: str
        default_config_path: str
        fmt_ranges: Optional[List[List[int]]]
        buf_lines: List[str]
        buf_path, buf_root_dir, default_config_path, fmt_ranges, buf_lines = args

        try:
            from yapf.yapflib.yapf_api import FormatCode
            from yapf.yapflib import file_resources
            from yapf.yapflib.errors import YapfError
            from lib2to3.pgen2.parse import ParseError as ParseError2to3
        except ModuleNotFoundError as err:
            raise pynvim.ErrorResponse('yapf is not installed: {}'.format(err))

        # The following code is essentially a reimplementation of
        # <https://github.com/google/yapf/blob/v0.31.0/yapf/__init__.py#L82-L114>.
        try:
            buf_dir = os.path.dirname(
                buf_path) if buf_path is not None else buf_root_dir
            config_path = default_config_path
            if buf_dir is not None:
                # This thing is actually not possible to pull off just through shelling
                # out to Yapf because it only has an option to override the config
                # globally and without any regard for project-local settings.
                config_path = file_resources.GetDefaultStyleForDir(
                    buf_dir, default_config_path)

            if buf_root_dir is not None and buf_path is not None:
                # It should be mentioned that this function doesn't look for files in
                # parent directories, which is a shame.
                excluded_patterns = file_resources.GetExcludePatternsForDir(
                    buf_root_dir)
                if buf_path.startswith(buf_root_dir):
                    buf_path = buf_path[len(buf_root_dir):]
                if file_resources.IsIgnored(buf_path, excluded_patterns):
                    return None

            # TODO: comment here about normalization of newlines by yapf and how a
            # string takes up less space than an array of them when encoded also how
            # Vim handles BOM
            buf_text = '\n'.join(buf_lines) + '\n'

            try:
                fmt_text, changed = FormatCode(
                    buf_text,
                    filename=buf_path if buf_path is not None else '<unknown>',
                    style_config=config_path,
                    lines=fmt_ranges,
                    verify=False)
            except ParseError2to3 as err:
                # lineno, offset = err.context[1]
                # raise pynvim.ErrorResponse(
                #   'yapf: syntax error on {}:{}: {}'.format(lineno, offset, err.msg)
                # )
                return None
            except SyntaxError as err:
                # raise pynvim.ErrorResponse(
                #   'yapf: syntax error on {}:{}: {}'.format(err.lineno, err.offset, err.msg)
                # )
                return None
            if not changed:
                return None

            # TODO: write a continuation of that comment here as well
            fmt_lines = (fmt_text[:-1]
                         if fmt_text.endswith('\n') else fmt_text).split('\n')
            changed, common_lines_from_start, common_lines_from_end = (
                dotfiles.utils.simple_line_diff(buf_lines, fmt_lines))
            if not changed:
                return None
            if common_lines_from_start > 0:
                fmt_lines = fmt_lines[common_lines_from_start:]
            if common_lines_from_end > 0:
                fmt_lines = fmt_lines[:-common_lines_from_end]
            return (common_lines_from_start, common_lines_from_end, fmt_lines)

        except YapfError as err:
            # <https://github.com/google/yapf/blob/5fda04e1cdf50f548e121173337e07cc5304b752/yapf/__init__.py#L363-L365>
            # raise pynvim.ErrorResponse('yapf: {}'.format(err))
            return None