Path: blob/master/elisp/emacs-for-python/rope-dist/rope/refactor/sourceutils.py
1415 views
from rope.base import ast, codeanalyze123def get_indents(lines, lineno):4return codeanalyze.count_line_indents(lines.get_line(lineno))567def find_minimum_indents(source_code):8result = 809lines = source_code.split('\n')10for line in lines:11if line.strip() == '':12continue13result = min(result, codeanalyze.count_line_indents(line))14return result151617def indent_lines(source_code, amount):18if amount == 0:19return source_code20lines = source_code.splitlines(True)21result = []22for l in lines:23if l.strip() == '':24result.append('\n')25continue26if amount < 0:27indents = codeanalyze.count_line_indents(l)28result.append(max(0, indents + amount) * ' ' + l.lstrip())29else:30result.append(' ' * amount + l)31return ''.join(result)323334def fix_indentation(code, new_indents):35"""Change the indentation of `code` to `new_indents`"""36min_indents = find_minimum_indents(code)37return indent_lines(code, new_indents - min_indents)383940def add_methods(pymodule, class_scope, methods_sources):41source_code = pymodule.source_code42lines = pymodule.lines43insertion_line = class_scope.get_end()44if class_scope.get_scopes():45insertion_line = class_scope.get_scopes()[-1].get_end()46insertion_offset = lines.get_line_end(insertion_line)47methods = '\n\n' + '\n\n'.join(methods_sources)48indented_methods = fix_indentation(49methods, get_indents(lines, class_scope.get_start()) +50get_indent(pymodule.pycore))51result = []52result.append(source_code[:insertion_offset])53result.append(indented_methods)54result.append(source_code[insertion_offset:])55return ''.join(result)565758def get_body(pyfunction):59"""Return unindented function body"""60scope = pyfunction.get_scope()61pymodule = pyfunction.get_module()62start, end = get_body_region(pyfunction)63return fix_indentation(pymodule.source_code[start:end], 0)646566def get_body_region(defined):67"""Return the start and end offsets of function body"""68scope = defined.get_scope()69pymodule = defined.get_module()70lines = pymodule.lines71node = defined.get_ast()72start_line = node.lineno73if defined.get_doc() is None:74start_line = node.body[0].lineno75elif len(node.body) > 1:76start_line = node.body[1].lineno77start = lines.get_line_start(start_line)78scope_start = pymodule.logical_lines.logical_line_in(scope.start)79if scope_start[1] >= start_line:80# a one-liner!81# XXX: what if colon appears in a string82start = pymodule.source_code.index(':', start) + 183while pymodule.source_code[start].isspace():84start += 185end = min(lines.get_line_end(scope.end) + 1, len(pymodule.source_code))86return start, end878889def get_indent(pycore):90project = pycore.project91return project.prefs.get('indent_size', 4)929394