Skip to content

Commit d63a298

Browse files
committed
refactor get code mechanisum
1 parent 736563c commit d63a298

11 files changed

+143
-102
lines changed
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
{
2+
"target": "send_code_exec",
3+
"code": "%run \"$file\"",
4+
"selector": "source.python"
5+
}
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
{
2+
"target": "send_code_exec",
3+
"code": "include(\"$file\");",
4+
"selector": "source.julia"
5+
}
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
{
2+
"target": "send_code_exec",
3+
"code": "source(\"$file\")",
4+
"selector": "source.r"
5+
}
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
{
2+
"target": "send_code_exec",
3+
"code": "Rcpp::sourceCpp(\"$file\")",
4+
"selector": "source.c++.rcpp"
5+
}

code_getter/getter.py

Lines changed: 96 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,34 @@
11
import sublime
22
import re
3+
import os
34
from ..settings import Settings
45

56

7+
def escape_dquote(cmd):
8+
cmd = cmd.replace('\\', '\\\\')
9+
cmd = cmd.replace('"', '\\"')
10+
return cmd
11+
12+
13+
def escape_squote(cmd):
14+
cmd = cmd.replace('\\', '\\\\')
15+
cmd = cmd.replace("\'", "\'")
16+
return cmd
17+
18+
19+
PATTERN = re.compile(r"""
20+
(?P<quote>["'])
21+
(?P<quoted_var>
22+
\$ (?: [_a-z][_a-z0-9]* | \{[^}]*\} )
23+
)
24+
(?P=quote)
25+
|
26+
(?P<var>
27+
\$ (?: [_a-z][_a-z0-9]* | \{[^}]*\} )
28+
)
29+
""", re.VERBOSE)
30+
31+
632
class CodeGetter:
733

834
def __init__(self, view):
@@ -51,7 +77,7 @@ def advance(self, s):
5177
pt = view.text_point(view.rowcol(nextpt.begin())[0], 0)
5278
view.sel().add(sublime.Region(pt, pt))
5379

54-
def get_text(self):
80+
def get_code(self):
5581
view = self.view
5682
cmd = ''
5783
moved = False
@@ -72,6 +98,37 @@ def get_text(self):
7298

7399
return cmd
74100

101+
def get_code_above(self):
102+
line = int(self.get_line())
103+
if not line or line <= 1:
104+
return
105+
view = self.view
106+
region = sublime.Region(0, view.line(view.text_point(line - 2, 0)).end())
107+
return view.substr(region)
108+
109+
def get_selection(self):
110+
view = self.view
111+
word = view.substr(view.sel()[0])
112+
if not word:
113+
word = view.substr(view.word(view.sel()[0].begin()))
114+
return word
115+
116+
def get_line(self):
117+
view = self.view
118+
if len(view.sel()) == 1:
119+
row, _ = view.rowcol(view.sel()[0].begin())
120+
return str(row + 1)
121+
122+
def get_current_folder(self):
123+
view = self.view
124+
fname = view.file_name()
125+
window = view.window()
126+
if fname:
127+
fname = os.path.realpath(fname)
128+
for folder in window.folders():
129+
if fname.startswith(os.path.realpath(folder) + os.sep):
130+
return folder
131+
75132
def find_inline(self, pattern, pt, scope="-string, -comment"):
76133
while True:
77134
result = self.view.find(pattern, pt)
@@ -166,6 +223,41 @@ def block_expand(self, s):
166223

167224
return s
168225

226+
def resolve(self, code):
227+
view = self.view
228+
window = view.window()
229+
extracted_variables = window.extract_variables()
230+
231+
variable_getter = {
232+
"line": self.get_line,
233+
"selection": self.get_selection,
234+
"current_folder": self.get_current_folder
235+
}
236+
237+
for v, getter in variable_getter.items():
238+
value = getter()
239+
if value is not None:
240+
extracted_variables[v] = value
241+
242+
def convert(m):
243+
quote = m.group("quote")
244+
var = m.group("quoted_var") if quote else m.group("var")
245+
if var == "$code_above":
246+
var = self.get_code_above()
247+
else:
248+
var = sublime.expand_variables(var, extracted_variables)
249+
250+
if quote == "'":
251+
return "'" + escape_squote(var) + "'"
252+
elif quote == '"':
253+
return '"' + escape_dquote(var) + '"'
254+
else:
255+
return var
256+
257+
code = PATTERN.sub(convert, code)
258+
259+
return code
260+
169261

170262
class RCodeGetter(CodeGetter):
171263

@@ -312,7 +404,9 @@ def expand_line(self, s):
312404
s = sublime.Region(s.end() + 1, end.begin() - 1)
313405
return s
314406

407+
def get_code_above(self):
408+
pass
315409

316-
class RMarkDownCodeGetter(MarkDownCodeGetter):
317410

411+
class RMarkDownCodeGetter(MarkDownCodeGetter):
318412
pass

exec.py

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
import sublime_plugin
2+
3+
4+
class SendCodeExecCommand(sublime_plugin.WindowCommand):
5+
6+
def run(self, code=None, prog=None):
7+
self.window.active_view().run_command(
8+
"send_code",
9+
{"code": code, "prog": prog}
10+
)
11+
12+
13+
# backward compatibility
14+
class SendCodeBuildCommand(SendCodeExecCommand):
15+
pass

send_code.py

Lines changed: 12 additions & 80 deletions
Original file line numberDiff line numberDiff line change
@@ -1,97 +1,29 @@
11
import sublime
22
import sublime_plugin
3-
import os
4-
import re
53

64
from .code_getter import CodeGetter
75
from .code_sender import CodeSender
86

97

10-
def escape_dquote(cmd):
11-
cmd = cmd.replace('\\', '\\\\')
12-
cmd = cmd.replace('"', '\\"')
13-
return cmd
14-
15-
16-
def escape_squote(cmd):
17-
cmd = cmd.replace('\\', '\\\\')
18-
cmd = cmd.replace("\'", "\'")
19-
return cmd
20-
21-
22-
PATTERN = re.compile(r"""
23-
(?P<quote>["'])
24-
(?P<quoted_var>
25-
\$ (?: [_a-z][_a-z0-9]* | \{[^}]*\} )
26-
)
27-
(?P=quote)
28-
|
29-
(?P<var>
30-
\$ (?: [_a-z][_a-z0-9]* | \{[^}]*\} )
31-
)
32-
""", re.VERBOSE)
33-
34-
358
class SendCodeCommand(sublime_plugin.TextCommand):
369

37-
def resolve(self, cmd):
38-
view = self.view
39-
window = view.window()
40-
extracted_variables = window.extract_variables()
41-
if len(view.sel()) == 1:
42-
row, _ = view.rowcol(view.sel()[0].begin())
43-
extracted_variables["line"] = str(row + 1)
44-
45-
word = view.substr(view.sel()[0])
46-
if not word:
47-
word = view.substr(view.word(view.sel()[0].begin()))
48-
extracted_variables["selection"] = word
49-
50-
fname = view.file_name()
51-
if fname:
52-
fname = os.path.realpath(fname)
53-
for folder in window.folders():
54-
if fname.startswith(os.path.realpath(folder) + os.sep):
55-
extracted_variables["current_folder"] = folder
56-
break
57-
58-
def convert(m):
59-
quote = m.group("quote")
60-
if quote:
61-
var = sublime.expand_variables(m.group("quoted_var"), extracted_variables)
62-
if quote == "'":
63-
return "'" + escape_squote(var) + "'"
64-
else:
65-
return '"' + escape_dquote(var) + '"'
66-
else:
67-
return sublime.expand_variables(m.group("var"), extracted_variables)
68-
69-
cmd = PATTERN.sub(convert, cmd)
70-
71-
return cmd
72-
73-
def run(self, edit, cmd=None, prog=None, confirmation=None):
74-
# set CodeGetter before get_text() because get_text may change cursor locations.
10+
def run(self, edit, code=None, cmd=None, prog=None, resolve=True, confirmation=None):
11+
# set CodeSender before get_code() because get_code may change cursor locations.
7512

7613
if confirmation:
7714
ok = sublime.ok_cancel_dialog(confirmation)
7815
if not ok:
7916
return
8017

81-
sender = CodeSender.initialize(self.view, prog=prog, from_view=cmd is None)
82-
if cmd:
83-
cmd = self.resolve(cmd)
84-
else:
85-
getter = CodeGetter.initialize(self.view)
86-
cmd = getter.get_text()
87-
88-
sublime.set_timeout_async(lambda: sender.send_text(cmd))
18+
if not code and cmd:
19+
print("SendCode: argument `cmd` is deprecated, use `code` instead.")
20+
code = cmd
8921

22+
getter = CodeGetter.initialize(self.view)
23+
sender = CodeSender.initialize(self.view, prog=prog, from_view=code is None)
24+
if code and resolve:
25+
code = getter.resolve(code)
26+
else:
27+
code = getter.get_code()
9028

91-
class SendCodeBuildCommand(sublime_plugin.WindowCommand):
92-
93-
def run(self, cmd=None, prog=None):
94-
self.window.active_view().run_command(
95-
"send_code",
96-
{"cmd": cmd, "prog": prog}
97-
)
29+
sublime.set_timeout_async(lambda: sender.send_text(code))

support/IPython - Source File.sublime-build

Lines changed: 0 additions & 5 deletions
This file was deleted.

support/Julia - Source File.sublime-build

Lines changed: 0 additions & 5 deletions
This file was deleted.

support/R - Source File.sublime-build

Lines changed: 0 additions & 5 deletions
This file was deleted.

0 commit comments

Comments
 (0)