Usually I use jq to discover what scripts a node project uses like this:
jq '.scripts' package.json
This is fine, and I can always find it be reverse-searching
my shell history using C-r .scr
but there's a more
automated way to handle this. g-plane
wrote a Rust package to handle autocompletions for Yarn in
zsh... and it works wonderfully.
tldr; https://github.com/g-plane/zsh-yarn-autocompletions
The run
, remove
, and add
commands are auto-completable
(and yarn add
is even configurable!).
The fact that add
is configurable is really nice because
it means I can set it up with my favorite and most-used
packages like
[gatsby-mdx(https://github.com/ChristopherBiscardi/gatsby-mdx)
and
gatsby-plugin-emotion
We can see how it works by looking at
src/scripts.rs.
The code does what you might expect, finds a package.json
,
opens it, pulls the scripts
key out (using serde), and
returns it.
use std::env;use std::fs::File;use std::collections::HashMap;extern crate serde;extern crate serde_json;#[derive(Deserialize)]struct Pkg {scripts: Option<HashMap<String, String>>,}pub fn fetch_npm_scripts() -> String {let mut path = String::new();match env::var("PWD") {Ok(pwd) => {path.push_str(&pwd);path.push_str("/package.json");}Err(_) => {return String::new();}}let file = File::open(path);if let Err(_) = file {return String::new();}let package: Result<Pkg, _> = serde_json::from_reader(file.unwrap());if let Err(_) = package {return String::new();}let package = package.unwrap();match package.scripts {Some(scripts) => scripts.keys().map(|script| script.to_string()).collect::<Vec<String>>().join("\n"),None => String::new(),}}#[test]fn test_fetch_scripts() {let output = fetch_npm_scripts();let output = output.trim();let mut scripts: Vec<&str> = output.split('\n').collect();scripts.sort();assert_eq!(scripts, ["build", "commit", "dev", "lint"]);}