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()
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