import sys
import json
NUSHELL_VERSION = "0.112.2"
PLUGIN_VERSION = "0.1.1"
def signatures():
return {
"Signature": [
{
"sig": {
"name": "nu-python",
"description": "Signature test for Python",
"extra_description": "",
"required_positional": [
{
"name": "a",
"desc": "required integer value",
"shape": "Int",
},
{
"name": "b",
"desc": "required string value",
"shape": "String",
},
],
"optional_positional": [
{
"name": "opt",
"desc": "Optional number",
"shape": "Int",
}
],
"rest_positional": {
"name": "rest",
"desc": "rest value string",
"shape": "String",
},
"named": [
{
"long": "help",
"short": "h",
"arg": None,
"required": False,
"desc": "Display the help message for this command",
},
{
"long": "flag",
"short": "f",
"arg": None,
"required": False,
"desc": "a flag for the signature",
},
{
"long": "named",
"short": "n",
"arg": "String",
"required": False,
"desc": "named string",
},
],
"input_output_types": [["Any", "Any"]],
"allow_variants_without_examples": True,
"search_terms": ["Python", "Example"],
"is_filter": False,
"creates_scope": False,
"allows_unknown_args": False,
"category": "Experimental",
},
"examples": [],
}
]
}
def process_call(id, plugin_call):
sys.stderr.write(json.dumps(plugin_call, indent=4))
sys.stderr.write("\n")
span = plugin_call["call"]["head"]
def f(x, y):
return {"Int": {"val": x * y, "span": span}}
value = {
"Value": [
{
"List": {
"vals": [
{
"Record": {
"val": {
"one": f(x, 0),
"two": f(x, 1),
"three": f(x, 2),
},
"span": span,
}
}
for x in range(0, 10)
],
"span": span,
}
},
None,
]
}
write_response(id, {"PipelineData": value})
def tell_nushell_encoding():
sys.stdout.write(chr(4))
for ch in "json":
sys.stdout.write(chr(ord(ch)))
sys.stdout.flush()
def tell_nushell_hello():
hello = {
"Hello": {
"protocol": "nu-plugin", "version": NUSHELL_VERSION,
"features": [],
}
}
sys.stdout.write(json.dumps(hello))
sys.stdout.write("\n")
sys.stdout.flush()
def write_response(id, response):
wrapped_response = {
"CallResponse": [
id,
response,
]
}
sys.stdout.write(json.dumps(wrapped_response))
sys.stdout.write("\n")
sys.stdout.flush()
def write_error(id, text, span=None):
error = (
{
"Error": {
"msg": "ERROR from plugin",
"labels": [
{
"text": text,
"span": span,
}
],
}
}
if span is not None
else {
"Error": {
"msg": "ERROR from plugin",
"help": text,
}
}
)
write_response(id, error)
def handle_input(input):
if "Hello" in input:
if input["Hello"]["version"] != NUSHELL_VERSION:
exit(1)
else:
return
elif input == "Goodbye":
exit(0)
elif "Call" in input:
[id, plugin_call] = input["Call"]
if plugin_call == "Metadata":
write_response(
id,
{
"Metadata": {
"version": PLUGIN_VERSION,
}
},
)
elif plugin_call == "Signature":
write_response(id, signatures())
elif "Run" in plugin_call:
process_call(id, plugin_call["Run"])
else:
write_error(id, "Operation not supported: " + str(plugin_call))
else:
sys.stderr.write("Unknown message: " + str(input) + "\n")
exit(1)
def plugin():
tell_nushell_encoding()
tell_nushell_hello()
for line in sys.stdin:
input = json.loads(line)
handle_input(input)
if __name__ == "__main__":
if len(sys.argv) == 2 and sys.argv[1] == "--stdio":
plugin()
else:
print("Run me from inside nushell!")