-
Notifications
You must be signed in to change notification settings - Fork 3
Expand file tree
/
Copy pathsocket_pipe.py
More file actions
107 lines (94 loc) · 3.39 KB
/
Copy pathsocket_pipe.py
File metadata and controls
107 lines (94 loc) · 3.39 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
import threading
import socket
import errno
import sublime, sublime_plugin
import re
# TODO UdpPipe vs TcpPipe?
class SocketPipe(threading.Thread):
def __init__(self, view, host, port, type="tcp", initial=None):
threading.Thread.__init__(self)
self.running = True
self.view = view
self.written_characters = 0
self.buffer = []
self.prompt = 0
self.hist = 0
self.history = []
if type == "tcp":
self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
elif type == "tcp6":
self.sock = socket.socket(socket.AF_INET6, socket.SOCK_STREAM)
elif type == "udp":
self.sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
else:
raise "Invalid type"
self.sock.connect((host, port))
if type == "tcp" or type == "tcp6":
self.sock.settimeout(1)
print("Connected SocketPipe to %s:%s" % (host, port))
if(initial):
print("sending %s" % initial)
self.sock.send(initial.encode('utf-8'))
def go(self):
self.setup_view()
self.update_view()
self.start()
def setup_view(self):
self.view.settings().set("scope_name", "source.clojure")
self.view.settings().set("line_numbers", False)
self.view.settings().set("gutter", False)
self.view.settings().set("word_wrap", False)
def update_view(self):
# prevent editing repl view if a selection is before the prompt
oob = False
self.view.settings().set("noback", False)
for region in self.view.sel():
# backspace is a special case, a sublime-keymap binding checks the 'noback' setting
if region.a == self.prompt and region.b == region.a:
self.view.settings().set("noback", True)
if region.a < self.prompt or region.b < self.prompt:
oob = True
if oob:
self.view.set_read_only(True)
else:
self.view.set_read_only(False)
for b in self.buffer:
self.view.run_command("socket_insert_text", {"content": b})
self.buffer = []
if self.running:
sublime.set_timeout(self.update_view, 100)
def on_close(self):
self.running = False
self.view.set_name(self.view.name() + " [CLOSED]")
try:
self.sock.shutdown(socket.SHUT_RDWR)
self.sock.close()
except:
pass
def record_history(self, s):
rx = re.search("[\\n]*$", s)
if rx:
s = s[:len(rx.group()) * -1]
hlen = len(self.history)
if s != "" and (hlen == 0 or (hlen > 0 and s != self.history[hlen-1])):
self.history.append(s)
self.hist = 0
def send(self, s):
self.record_history(s)
self.sock.send(s.encode('utf-8'))
def write(self, s):
self.buffer.append(s)
def bump(self, s):
self.written_characters += len(s)
def run(self):
while self.running:
try:
read = self.sock.recv(8012)
if(len(read) == 0):
self.on_close()
else:
self.buffer.append(read.decode('utf8'))
except socket.timeout as e:
continue
except socket.error as e:
print(e)