Coverage for C:\leo.repo\leo-editor\leo\plugins\importers\elisp.py: 77%
Shortcuts on this page
r m x toggle line displays
j k next/prev highlighted chunk
0 (zero) top of page
1 (one) first highlighted chunk
Shortcuts on this page
r m x toggle line displays
j k next/prev highlighted chunk
0 (zero) top of page
1 (one) first highlighted chunk
1#@+leo-ver=5-thin
2#@+node:ekr.20140723122936.18141: * @file ../plugins/importers/elisp.py
3"""The @auto importer for the elisp language."""
4import re
5from typing import Any, Dict, List
6from leo.core import leoGlobals as g
7from leo.plugins.importers import linescanner
8Importer = linescanner.Importer
9#@+others
10#@+node:ekr.20161127184128.2: ** class Elisp_Importer
11class Elisp_Importer(Importer):
12 """The importer for the elisp lanuage."""
14 def __init__(self, importCommands, **kwargs):
15 """Elisp_Importer.__init__"""
16 # Init the base class.
17 super().__init__(
18 importCommands,
19 language='lisp',
20 state_class=Elisp_ScanState,
21 strict=False,
22 )
24 #@+others
25 #@+node:ekr.20170205195239.1: *3* elisp_i.get_new_dict
26 #@@nobeautify
28 def get_new_dict(self, context):
29 """elisp state dictionary for the given context."""
30 comment, block1, block2 = self.single_comment, self.block1, self.block2
32 def add_key(d, pattern, data):
33 key = pattern[0]
34 aList = d.get(key,[])
35 aList.append(data)
36 d[key] = aList
38 d: Dict[str, List[Any]]
40 if context:
41 d = {
42 # key kind pattern ends?
43 '\\': [('len+1', '\\', None),],
44 '"': [('len', '"', context == '"'),],
45 # "'": [('len', "'", context == "'"),],
46 }
47 if block1 and block2:
48 add_key(d, block2, ('len', block2, True))
49 # Bug fix: 2016/12/04: the tuple contained block1, not block2.
50 else:
51 # Not in any context.
52 d = {
53 # key kind pattern new-ctx deltas
54 '\\':[('len+1', '\\', context, None),],
55 '"': [('len', '"', '"', None),],
56 # "'": [('len', "'", "'", None),],
57 '{': [('len', '{', context, (1,0,0)),],
58 '}': [('len', '}', context, (-1,0,0)),],
59 '(': [('len', '(', context, (0,1,0)),],
60 ')': [('len', ')', context, (0,-1,0)),],
61 '[': [('len', '[', context, (0,0,1)),],
62 ']': [('len', ']', context, (0,0,-1)),],
63 }
64 if comment:
65 add_key(d, comment, ('all', comment, '', None))
66 if block1 and block2:
67 add_key(d, block1, ('len', block1, block1, None))
68 return d
69 #@+node:ekr.20161127184128.4: *3* elisp_i.clean_headline
70 elisp_clean_pattern = re.compile(r'^\s*\(\s*defun\s+([\w_-]+)')
72 def clean_headline(self, s, p=None):
73 """Return a cleaned up headline s."""
74 m = self.elisp_clean_pattern.match(s)
75 if m and m.group(1):
76 return 'defun %s' % m.group(1)
77 return s.strip()
78 #@+node:ekr.20161127185851.1: *3* elisp_i.starts_block
79 def starts_block(self, i, lines, new_state, prev_state):
80 """True if the new state starts a block."""
81 line = lines[i]
82 return self.elisp_clean_pattern.match(line)
83 #@+node:ekr.20170205194802.1: *3* elisp_i.trace_status
84 def trace_status(self, line, new_state, prev_state, stack, top):
85 """Print everything important in the i.gen_lines loop."""
86 if line.isspace() or line.strip().startswith(';'):
87 return # for elisp
88 print('')
89 try:
90 g.trace(repr(line))
91 except Exception:
92 g.trace(f" top.p: {g.toUnicode(top.p.h)}")
93 # print('len(stack): %s' % len(stack))
94 print(' new_state: %s' % new_state)
95 print('prev_state: %s' % prev_state)
96 # print(' top.state: %s' % top.state)
97 g.printList(stack)
98 #@-others
99#@+node:ekr.20161127184128.6: ** class Elisp_ScanState
100class Elisp_ScanState:
101 """A class representing the state of the elisp line-oriented scan."""
103 def __init__(self, d=None):
104 """Elisp_ScanState.__init__"""
105 if d:
106 prev = d.get('prev')
107 self.context = prev.context
108 self.parens = prev.parens
109 else:
110 self.context = ''
111 self.parens = 0
113 def __repr__(self):
114 """Elisp_ScanState.__repr__"""
115 return "Elisp_ScanState context: %r parens: %s" % (
116 self.context, self.parens)
118 __str__ = __repr__
120 #@+others
121 #@+node:ekr.20161127184128.7: *3* elisp_state.level
122 def level(self):
123 """Elisp_ScanState.level."""
124 return self.parens
126 #@+node:ekr.20161127184128.8: *3* elisp_state.update
127 def update(self, data):
128 """
129 Elisp_ScanState.update
131 Update the state using the 6-tuple returned by i.scan_line.
132 Return i = data[1]
133 """
134 context, i, delta_c, delta_p, delta_s, bs_nl = data
135 # All ScanState classes must have a context ivar.
136 self.context = context
137 self.parens += delta_p
138 return i
139 #@-others
140#@-others
141importer_dict = {
142 'func': Elisp_Importer.do_import(),
143 # Also clojure, clojurescript
144 'extensions': ['.el', '.clj', '.cljs', '.cljc',],
145}
146#@@language python
147#@@tabwidth -4
148#@-leo