Skip to content

Instantly share code, notes, and snippets.

@zeffii
Forked from anonymous/ck_com_shell.py
Last active December 29, 2015 10:19
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save zeffii/7656011 to your computer and use it in GitHub Desktop.
Save zeffii/7656011 to your computer and use it in GitHub Desktop.
import sublime
import sublime_plugin
import subprocess
import threading
import os
from subprocess import Popen, PIPE, STDOUT
"""
// --- these don't require the console prefix %>
[-] chuck --shell : will start ChucK in --shell mode (server) using a new thread.
[-] kill : will end chuck (should end all chucks alive).
// --- these do, because it indicates that you expect an open console.
[-] %> -k : will kill ChucK server thread. (no space between -k)
[ ] %> + this: add shred (current open file), "this" will be reserved
[ ] %> =/- this: replace/remove shred (current open file)
[ ] %> = x.ck: replace shred named x
[ ] %> - x.ck : remove shred named x
[ ] %> = number(s) : replace shred(s) by id, separated by spaces
[ ] %> - number(s) : remove shred(s) by id, separated by spaces
[ ] %> -all : remove all shreds. (no space between -all)
[ ] %> status: will print the status to the python console.
A key combo : will add selection as shred (sends everything enclosed in { }
as an 'on the fly' shred)
"""
def command_dispatcher(thread, commands):
print("doing command:", commands)
thread.shell_process.stdin.write(commands)
thread.shell_process.stdin.write("\x0c")
thread.shell_process.stdin.flush()
def kill_chuck():
subprocess.call(["chuck", "--kill"])
print("ending a chuck process!")
return
def com_parser(line_under_cursor, file_name):
right_side = None
try:
found_content = line_under_cursor.rsplit("//", 1)[1]
found_content = found_content.strip()
if found_content in ("kill", "%> -k"):
return "kill"
if found_content == "chuck --shell":
return "shell"
sides = found_content.split("%>")
right_side = sides[1].strip()
# this will refer to the name of the current file.ck
if "this" in right_side:
right_side = right_side.replace("this", file_name)
except:
print("unparsable")
return
return right_side
class Ck_com_shell(sublime_plugin.TextCommand):
chuck_process = None
chuck_queue = None
chuck_thread = None
def run(self, edit):
view = self.view
file_path = view.file_name()
file_name = os.path.basename(file_path)
selections = view.sel()
if not selections[0].a == selections[0].b:
print("see com shell documentation")
return
sel = view.line(selections[0])
line_under_cursor = view.substr(sel)
commands = com_parser(line_under_cursor, file_name)
if not commands:
return
if commands == "kill":
kill_chuck()
return
# start shell as subprocess in a thread.
elif commands == "shell":
self.chuck_thread = Ck_Shell(["chuck", "--shell"])
self.chuck_thread.daemon = True
self.chuck_thread.start()
return
try:
if self.chuck_thread.isAlive():
print("thread seems alive. ident:", self.chuck_thread.ident)
except:
print("failed to serve:", commands)
print("server seems lost, try: (re)starting it.")
return
finally:
command_dispatcher(self.chuck_thread, commands)
class Ck_Shell(threading.Thread):
shell_process = None
def __init__(self, commands):
self.commands = commands
threading.Thread.__init__(self)
def run(self):
print("starting shell")
self.shell_process = Popen(self.commands,
stdin = PIPE,
stdout= PIPE,
stderr= STDOUT,
shell=True)
print("started")
try:
print(self.shell_process.communicate())
except:
print("no response from subprocess")
# http://eli.thegreenplace.net/2011/12/27/python-threads-communication-and-stopping/
# http://stackoverflow.com/a/165662/1243487
# http://stackoverflow.com/questions/3065060
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment