{"id":17030442,"url":"https://github.com/vsoch/nushell-plugin-len","last_synced_at":"2025-03-22T20:25:50.391Z","repository":{"id":141667899,"uuid":"215154157","full_name":"vsoch/nushell-plugin-len","owner":"vsoch","description":"An example ls plugin for nushell using golang","archived":false,"fork":false,"pushed_at":"2019-10-16T16:35:46.000Z","size":71,"stargazers_count":2,"open_issues_count":0,"forks_count":0,"subscribers_count":3,"default_branch":"master","last_synced_at":"2024-05-01T21:40:30.375Z","etag":null,"topics":["go","jsonrpc","nushell","plugin"],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/vsoch.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2019-10-14T22:08:58.000Z","updated_at":"2024-06-19T07:35:52.250Z","dependencies_parsed_at":null,"dependency_job_id":"8422378c-c796-4b66-b79c-02798d248b1f","html_url":"https://github.com/vsoch/nushell-plugin-len","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vsoch%2Fnushell-plugin-len","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vsoch%2Fnushell-plugin-len/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vsoch%2Fnushell-plugin-len/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vsoch%2Fnushell-plugin-len/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/vsoch","download_url":"https://codeload.github.com/vsoch/nushell-plugin-len/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":245016280,"owners_count":20547572,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["go","jsonrpc","nushell","plugin"],"created_at":"2024-10-14T08:06:54.753Z","updated_at":"2025-03-22T20:25:50.352Z","avatar_url":"https://github.com/vsoch.png","language":"Go","readme":"# Nushell Plugin in GoLang\n\n![img/nushell-plugin-len.png](img/nushell-plugin-len.png)\n\nThis is an example implementation of a length (len) plugin for Nushell in GoLang. While\nthere are many ways to go about this, I created this particular implementation,\nof course wanting to practice a bit of Go and learn about nushell. This is\nincredibly challenging because GoLang doesn't make it easy to parse nested\nlevels of Json without knowing the structure in advance.\n\n## Build\n\nIf you have Go installed locally, you can use the Makefile to build the plugin\n\n```bash\n$ make\ngo build -o nu_plugin_len\n```\n\n## Test Without Nu\n\nIt's possible to test without nushell by giving json objects to the binary.\nAfter you run it and press enter, here are some functions to interact:\n\n### Config\n\n```bash\n$ ./nu_plugin_len\n{\"method\":\"config\"}\n{\"jsonrpc\":\"2.0\",\"method\":\"response\",\"params\":{\"Ok\":{\"name\":\"len\",\"usage\":\"Return the length of a string\",\"positional\":[],\"rest_positional\":null,\"named\":{},\"is_filter\":true}}}\n```\n\n### Start and End Filter\n\n```bash\n$ ./nu_plugin_len\n{\"method\":\"begin_filter\"}\n{\"jsonrpc\":\"2.0\",\"method\":\"response\",\"params\":{\"Ok\":[]}}\n\n{\"method\":\"end_filter\"}\n{\"jsonrpc\":\"2.0\",\"method\":\"response\",\"params\":{\"Ok\":[]}}\n```\n\n### Calculate Length\n\n```bash\n$ ./nu_plugin_len\n{\"method\":\"begin_filter\"}\n{\"jsonrpc\":\"2.0\",\"method\":\"response\",\"params\":{\"Ok\":[]}}\n\n{\"method\":\"filter\", \"params\": {\"item\": {\"Primitive\": {\"String\": \"oogabooga\"}}}}\n{\"jsonrpc\":\"2.0\",\"method\":\"response\",\"params\":{\"Ok\":[{\"Ok\":{\"Value\":{\"item\":{\"Primitive\":{\"Int\":9}},\"tag\":{\"anchor\":null,\"span\":{\"end\":0,\"start\":0}}}}}]}}\n\n{\"method\":\"end_filter\"}\n{\"jsonrpc\":\"2.0\",\"method\":\"response\",\"params\":{\"Ok\":[]}}\n```\n\nThe above filter works because the script generates a tag (under params) if the\nfilter stream doesn't provide one, however with nushell we actually grab\nthe tag group from the stream and pass it forward. \n\n```bash\n$ ./nu_plugin_len\n{\"method\":\"filter\", \"params\": {\"item\": {\"Primitive\": {\"String\": \"oogabooga\"}}, \"tag\":{\"anchor\":null,\"span\":{\"end\":10,\"start\":12}}}}\n\n{\"jsonrpc\":\"2.0\",\"method\":\"response\",\"params\":{\"Ok\":[{\"Ok\":{\"Value\":{\"item\":{\"Primitive\":{\"Int\":9}},\"tag\":{\"anchor\":null,\"span\":{\"end\":10,\"start\":12}}}}}]}}\n```\n\nIn the above we see the custom start and end are passed forward. Both examples (with and without)\nwill work here, done so that you can test locally without nushell.\n\n## Order of Operations\n\nKeep in mind that when nushell finds the plugin on the path, it's going to:\n\n - discover the plugin by way of being on the path\n - call the \"config\" method to get metadata and register it\n - call begin_filter when it's invoked\n - call filter during invokation\n - call end_filter to finish up\n\nThat's a very high level description, see [the plugin page](https://github.com/nushell/contributor-book/blob/master/en/plugins.md) to read more about discovery and usage.\n\n\n## Logging\n\nNote that since I'm going to be using the plugin in a container, I don't\nmind logging to a temporary file at `/tmp/nu-plugin-len.log`. If you want\nto remove this, remove the logger.* snippets from [main.go](main.go) along\nwith the \"log\" import.\n\n\n## Test With Nu\n\nOnce you are happy, you can install the plugin with Nushell easily via Docker.\nHere we build the container using first GoLang to compile, and then\ncopying the binary into quay.io/nushell/nu-base in /usr/local/bin.\nWe do this so that the plugin is discovered. So first, build the container:\n\n```bash\n$ docker build -t vanessa/nu-plugin-len .\n```\n\nThen shell inside - the default entrypoint is already the nushell.\n\n```bash\n$ docker run -it vanessa/nu-plugin-len\n```\n\nOnce inside, you can use `nu -l trace` to confirm that nu found your plugin.\nHere we see that it did!\n\n```bash\n/code(add/circleci)\u003e nu -l trace\n...\n TRACE nu::cli \u003e Trying \"/usr/local/bin/nu_plugin_len\"\n TRACE nu::cli \u003e processing response (176 bytes)\n TRACE nu::cli \u003e response: {\"jsonrpc\":\"2.0\",\"method\":\"response\",\"params\":{\"Ok\":{\"name\":\"len\",\"usage\":\"Return the length of a string\",\"positional\":[],\"rest_positional\":null,\"named\":{},\"is_filter\":true}}}\n\n TRACE nu::cli \u003e processing Signature { name: \"len\", usage: \"Return the length of a string\", positional: [], rest_positional: None, named: {}, is_filter: true }\n TRACE nu::data::config \u003e config file = /root/.config/nu/config.toml\n```\n\nYou can also (for newer versions of nu \u003e 0.2.0) use help to see the command:\n\n```bash\n/code(master)\u003e help len\nReturn the length of a string\n\nUsage:\n  \u003e len \n\n/code(master)\u003e \n```\n\nTry out calculating the length of something! First, calculate the length of a simple\nstring (piped from echo):\n\n```bash\n/code(master)\u003e echo four | len\n━━━━━━━━━━━\n \u003cunknown\u003e \n───────────\n         4 \n━━━━━━━━━━━\n```\n\nNow let's do a more complex example. Here we are in a directory with one file named \"myname\" that is empty.\n\n```\n/tmp/test\u003e ls\n━━━━━━━━┯━━━━━━┯━━━━━━━━━━┯━━━━━━┯━━━━━━━━━━━━━━━━┯━━━━━━━━━━━━━━━━\n name   │ type │ readonly │ size │ accessed       │ modified \n────────┼──────┼──────────┼──────┼────────────────┼────────────────\n myname │ File │          │  —   │ 41 seconds ago │ 41 seconds ago \n━━━━━━━━┷━━━━━━┷━━━━━━━━━━┷━━━━━━┷━━━━━━━━━━━━━━━━┷━━━━━━━━━━━━━━━━\n```\n\nTry listing, getting the name, and calculating the length.\n\n```bash\n/tmp/test\u003e ls | get name | len\n━━━━━━━━━━━\n \u003cunknown\u003e \n───────────\n         6 \n━━━━━━━━━━━\n```\n\nor test it out with debug.\n\n```bash\nls | get name | len | debug\n\n/tmp/test\u003e ls | get name | len | debug\nTagged { tag: Tag { anchor: None, span: Span { start: 0, end: 2 } }, item: Primitive(Int(BigInt { sign: Plus, data: BigUint { data: [6] } })) }\n━━━━━━━━━━━\n \u003cunknown\u003e \n───────────\n         6 \n━━━━━━━━━━━\n```\n\nAdd another file to see the table get another row\n\n```bash\ntouch four\n```\n```bash\n/tmp/test\u003e ls | get name | len \n━━━┯━━━━━━━━━━━\n # │ \u003cunknown\u003e \n───┼───────────\n 0 │         4 \n 1 │         6 \n━━━┷━━━━━━━━━━━\n```\n\nMind you, I'm not a wizard Go Programmer, but I'd like the community to \nat least have an example to start with! Please contribute to this plugin to make\nit better!\n\n## Docker Hub\n\nIf you don't want to build but just want to play with the plugin,\nyou can pull directly from Docker Hub\n\n```bash\n$ docker pull vanessa/nu-plugin-len\n$ docker run -it vanessa/nu-plugin-len\n```\n\nDon't forget to check out the logging file at `/tmp/nushell-plugin-len.log` if you \nneed to debug!\n\n```bash\n/tmp\u003e cat /tmp/nu_plugin_len.log\nnu_plugin_len 2019/10/16 15:01:02 Request for config map[jsonrpc:2.0 method:config params:[]]\nnu_plugin_len 2019/10/16 15:01:16 Request for begin filter map[jsonrpc:2.0 method:begin_filter params:map[args:map[named:\u003cnil\u003e positional:\u003cnil\u003e] name_tag:map[anchor:\u003cnil\u003e span:map[end:19 start:16]]]]\nnu_plugin_len 2019/10/16 15:01:16 Request for filter map[jsonrpc:2.0 method:filter params:map[item:map[Primitive:map[String:nu_plugin_len.log]] tag:map[anchor:\u003cnil\u003e span:map[end:2 start:0]]]]\nnu_plugin_len 2019/10/16 15:01:16 Request for end filter map[jsonrpc:2.0 method:end_filter params:[]]\n```\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fvsoch%2Fnushell-plugin-len","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fvsoch%2Fnushell-plugin-len","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fvsoch%2Fnushell-plugin-len/lists"}