Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
marvel
GitHub Repository: marvel/qnf
Path: blob/master/elisp/emacs-for-python/rope-dist/rope/refactor/sourceutils.py
1415 views
1
from rope.base import ast, codeanalyze
2
3
4
def get_indents(lines, lineno):
5
return codeanalyze.count_line_indents(lines.get_line(lineno))
6
7
8
def find_minimum_indents(source_code):
9
result = 80
10
lines = source_code.split('\n')
11
for line in lines:
12
if line.strip() == '':
13
continue
14
result = min(result, codeanalyze.count_line_indents(line))
15
return result
16
17
18
def indent_lines(source_code, amount):
19
if amount == 0:
20
return source_code
21
lines = source_code.splitlines(True)
22
result = []
23
for l in lines:
24
if l.strip() == '':
25
result.append('\n')
26
continue
27
if amount < 0:
28
indents = codeanalyze.count_line_indents(l)
29
result.append(max(0, indents + amount) * ' ' + l.lstrip())
30
else:
31
result.append(' ' * amount + l)
32
return ''.join(result)
33
34
35
def fix_indentation(code, new_indents):
36
"""Change the indentation of `code` to `new_indents`"""
37
min_indents = find_minimum_indents(code)
38
return indent_lines(code, new_indents - min_indents)
39
40
41
def add_methods(pymodule, class_scope, methods_sources):
42
source_code = pymodule.source_code
43
lines = pymodule.lines
44
insertion_line = class_scope.get_end()
45
if class_scope.get_scopes():
46
insertion_line = class_scope.get_scopes()[-1].get_end()
47
insertion_offset = lines.get_line_end(insertion_line)
48
methods = '\n\n' + '\n\n'.join(methods_sources)
49
indented_methods = fix_indentation(
50
methods, get_indents(lines, class_scope.get_start()) +
51
get_indent(pymodule.pycore))
52
result = []
53
result.append(source_code[:insertion_offset])
54
result.append(indented_methods)
55
result.append(source_code[insertion_offset:])
56
return ''.join(result)
57
58
59
def get_body(pyfunction):
60
"""Return unindented function body"""
61
scope = pyfunction.get_scope()
62
pymodule = pyfunction.get_module()
63
start, end = get_body_region(pyfunction)
64
return fix_indentation(pymodule.source_code[start:end], 0)
65
66
67
def get_body_region(defined):
68
"""Return the start and end offsets of function body"""
69
scope = defined.get_scope()
70
pymodule = defined.get_module()
71
lines = pymodule.lines
72
node = defined.get_ast()
73
start_line = node.lineno
74
if defined.get_doc() is None:
75
start_line = node.body[0].lineno
76
elif len(node.body) > 1:
77
start_line = node.body[1].lineno
78
start = lines.get_line_start(start_line)
79
scope_start = pymodule.logical_lines.logical_line_in(scope.start)
80
if scope_start[1] >= start_line:
81
# a one-liner!
82
# XXX: what if colon appears in a string
83
start = pymodule.source_code.index(':', start) + 1
84
while pymodule.source_code[start].isspace():
85
start += 1
86
end = min(lines.get_line_end(scope.end) + 1, len(pymodule.source_code))
87
return start, end
88
89
90
def get_indent(pycore):
91
project = pycore.project
92
return project.prefs.get('indent_size', 4)
93
94