diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS
index 27cfbc62..728a8c1c 100644
--- a/.github/CODEOWNERS
+++ b/.github/CODEOWNERS
@@ -9,8 +9,8 @@
# This also holds true for GitHub teams.
# Rescript
-*.res @OAGr @quinn-dougherty
-*.resi @OAGr @quinn-dougherty
+*.res @OAGr
+*.resi @OAGr
# Typescript
*.tsx @Hazelfire @OAGr
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index 94e5c796..a7dff9d0 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -19,6 +19,8 @@ jobs:
should_skip_lang: ${{ steps.skip_lang_check.outputs.should_skip }}
should_skip_components: ${{ steps.skip_components_check.outputs.should_skip }}
should_skip_website: ${{ steps.skip_website_check.outputs.should_skip }}
+ should_skip_vscodeext: ${{ steps.skip_vscodeext_check.outputs.should_skip }}
+ should_skip_cli: ${{ steps.skip_cli_check.outputs.should_skip }}
steps:
- id: skip_lang_check
name: Check if the changes are about squiggle-lang src files
@@ -35,6 +37,16 @@ jobs:
uses: fkirc/skip-duplicate-actions@v3.4.1
with:
paths: '["packages/website/**"]'
+ - id: skip_vscodeext_check
+ name: Check if the changes are about vscode extension src files
+ uses: fkirc/skip-duplicate-actions@v3.4.1
+ with:
+ paths: '["packages/vscode-ext/**"]'
+ - id: skip_cli_check
+ name: Check if the changes are about cli src files
+ uses: fkirc/skip-duplicate-actions@v3.4.1
+ with:
+ paths: '["packages/cli/**"]'
lang-lint:
name: Language lint
@@ -158,3 +170,52 @@ jobs:
run: cd ../components && yarn build
- name: Build website assets
run: yarn build
+
+ vscode-ext-lint:
+ name: VS Code extension lint
+ runs-on: ubuntu-latest
+ needs: pre_check
+ if: ${{ needs.pre_check.outputs.should_skip_vscodeext != 'true' }}
+ defaults:
+ run:
+ shell: bash
+ working-directory: packages/vscode-ext
+ steps:
+ - uses: actions/checkout@v2
+ - name: Install dependencies from monorepo level
+ run: cd ../../ && yarn
+ - name: Lint the VSCode Extension source code
+ run: yarn lint
+
+ vscode-ext-build:
+ name: VS Code extension build
+ runs-on: ubuntu-latest
+ needs: pre_check
+ if: ${{ (needs.pre_check.outputs.should_skip_components != 'true') || (needs.pre_check.outputs.should_skip_lang != 'true') }} || (needs.pre_check.outputs.should_skip_vscodeext != 'true') }}
+ defaults:
+ run:
+ shell: bash
+ working-directory: packages/vscode-ext
+ steps:
+ - uses: actions/checkout@v2
+ - name: Install dependencies from monorepo level
+ run: cd ../../ && yarn
+ - name: Build
+ run: yarn compile
+
+ cli-lint:
+ name: CLI lint
+ runs-on: ubuntu-latest
+ needs: pre_check
+ if: ${{ needs.pre_check.outputs.should_skip_cli != 'true' }}
+ defaults:
+ run:
+ shell: bash
+ working-directory: packages/cli
+ steps:
+ - uses: actions/checkout@v2
+ - name: Check javascript, typescript, and markdown lint
+ uses: creyD/prettier_action@v4.2
+ with:
+ dry: true
+ prettier_options: --check packages/cli
diff --git a/.prettierignore b/.prettierignore
index 903390ad..8090b3f3 100644
--- a/.prettierignore
+++ b/.prettierignore
@@ -12,3 +12,4 @@ packages/squiggle-lang/coverage/
packages/squiggle-lang/.cache/
packages/website/build/
packages/squiggle-lang/src/rescript/Reducer/Reducer_Peggy/Reducer_Peggy_GeneratedParser.js
+packages/vscode-ext/media/vendor/
diff --git a/README.md b/README.md
index dafdc4cc..cdc73c28 100644
--- a/README.md
+++ b/README.md
@@ -17,6 +17,7 @@ _An estimation language_.
- [Known bugs](https://www.squiggle-language.com/docs/Discussions/Bugs)
- [Original lesswrong sequence](https://www.lesswrong.com/s/rDe8QE5NvXcZYzgZ3)
- [Author your squiggle models as Observable notebooks](https://observablehq.com/@hazelfire/squiggle)
+- [Use squiggle in VS Code](https://marketplace.visualstudio.com/items?itemName=QURI.vscode-squiggle)
## Our deployments
@@ -39,6 +40,8 @@ the packages can be found in `packages`.
of the calculation.
- `packages/website` is the main descriptive website for squiggle,
it is hosted at `squiggle-language.com`.
+- `packages/vscode-ext` is the VS Code extension for writing estimation functions.
+- `packages/cli` is an experimental way of using imports in squiggle, which is also on [npm](https://www.npmjs.com/package/squiggle-cli-experimental).
# Develop
diff --git a/package.json b/package.json
index 9db41bf5..dcab983e 100644
--- a/package.json
+++ b/package.json
@@ -7,7 +7,7 @@
"lint:all": "prettier --check . && cd packages/squiggle-lang && yarn lint:rescript"
},
"devDependencies": {
- "prettier": "^2.6.2"
+ "prettier": "^2.7.1"
},
"workspaces": [
"packages/*"
diff --git a/packages/cli/.gitignore b/packages/cli/.gitignore
new file mode 100644
index 00000000..03087060
--- /dev/null
+++ b/packages/cli/.gitignore
@@ -0,0 +1,4 @@
+## Artifacts
+*.swp
+/node_modules/
+yarn-error.log
\ No newline at end of file
diff --git a/packages/cli/README.md b/packages/cli/README.md
new file mode 100644
index 00000000..7b0d0038
--- /dev/null
+++ b/packages/cli/README.md
@@ -0,0 +1,22 @@
+## Squiggle CLI
+
+This package can be used to incorporate a very simple `import` system into Squiggle.
+
+To use, write special files with a `.squiggleU` file type. In these files, you can write lines like,
+
+```
+@import(models/gdp_over_time.squiggle, gdpOverTime)
+gdpOverTime(2.5)
+```
+
+The imports will be replaced with the contents of the file in `models/gdp_over_time.squiggle` upon compilation. The `.squiggleU` file will be converted into a `.squiggle` file with the `import` statement having this replacement.
+
+## Running
+
+### `npx squiggle-cli-experimental compile`
+
+Runs compilation in the current directory and all of its subdirectories.
+
+### `npx squiggle-cli-experimental watch`
+
+Watches `.squiggleU` files in the current directory (and subdirectories) and rebuilds them when they are saved. Note that this will _not_ rebuild files when their dependencies are changed, just when they are changed directly.
diff --git a/packages/cli/index.js b/packages/cli/index.js
new file mode 100755
index 00000000..95956b86
--- /dev/null
+++ b/packages/cli/index.js
@@ -0,0 +1,96 @@
+#!/usr/bin/env node
+
+import fs from "fs";
+import path from "path";
+import indentString from "indent-string";
+import chokidar from "chokidar";
+import chalk from "chalk";
+import { Command } from "commander";
+import glob from "glob";
+
+const processFile = (fileName, seen = []) => {
+ const normalizedFileName = path.resolve(fileName);
+ if (seen.includes(normalizedFileName)) {
+ throw new Error(`Recursive dependency for file ${fileName}`);
+ }
+
+ const fileContents = fs.readFileSync(fileName, "utf-8");
+ if (!fileName.endsWith(".squiggleU")) {
+ return fileContents;
+ }
+
+ const regex = /\@import\(\s*([^)]+?)\s*\)/g;
+ const matches = Array.from(fileContents.matchAll(regex)).map((r) =>
+ r[1].split(/\s*,\s*/)
+ );
+ const newContent = fileContents.replaceAll(regex, "");
+ const appendings = [];
+
+ matches.forEach((r) => {
+ const importFileName = r[0];
+ const rename = r[1];
+ const item = fs.statSync(importFileName);
+ if (item.isFile()) {
+ const data = processFile(importFileName, [...seen, normalizedFileName]);
+ if (data) {
+ const importString = `${rename} = {\n${indentString(data, 2)}\n}\n`;
+ appendings.push(importString);
+ }
+ } else {
+ console.log(
+ chalk.red(`Import Error`) +
+ `: ` +
+ chalk.cyan(importFileName) +
+ ` not found in file ` +
+ chalk.cyan(fileName) +
+ `. Make sure the @import file names all exist in this repo.`
+ );
+ }
+ });
+ const imports = appendings.join("\n");
+
+ const newerContent = imports.concat(newContent);
+ return newerContent;
+};
+
+const run = (fileName) => {
+ const content = processFile(fileName);
+ const parsedPath = path.parse(path.resolve(fileName));
+ const newFilename = `${parsedPath.dir}/${parsedPath.name}.squiggle`;
+ fs.writeFileSync(newFilename, content);
+ console.log(chalk.cyan(`Updated ${fileName} -> ${newFilename}`));
+};
+
+const compile = () => {
+ glob("**/*.squiggleU", (_err, files) => {
+ files.forEach(run);
+ });
+};
+
+const watch = () => {
+ chokidar
+ .watch("**.squiggleU")
+ .on("ready", () => console.log(chalk.green("Ready!")))
+ .on("change", (event, _) => {
+ run(event);
+ });
+};
+
+const program = new Command();
+
+program
+ .name("squiggle-utils")
+ .description("CLI to transform squiggle files with @imports")
+ .version("0.0.1");
+
+program
+ .command("watch")
+ .description("watch files and compile on the fly")
+ .action(watch);
+
+program
+ .command("compile")
+ .description("compile all .squiggleU files into .squiggle files")
+ .action(compile);
+
+program.parse();
diff --git a/packages/cli/package.json b/packages/cli/package.json
new file mode 100644
index 00000000..2890d2a4
--- /dev/null
+++ b/packages/cli/package.json
@@ -0,0 +1,21 @@
+{
+ "name": "squiggle-cli-experimental",
+ "version": "0.0.3",
+ "main": "index.js",
+ "homepage": "https://squiggle-language.com",
+ "author": "Quantified Uncertainty Research Institute",
+ "bin": "index.js",
+ "type": "module",
+ "scripts": {
+ "start": "node ."
+ },
+ "license": "MIT",
+ "dependencies": {
+ "chalk": "^5.0.1",
+ "chokidar": "^3.5.3",
+ "commander": "^9.4.0",
+ "fs": "^0.0.1-security",
+ "glob": "^8.0.3",
+ "indent-string": "^5.0.0"
+ }
+}
diff --git a/packages/components/README.md b/packages/components/README.md
index 38e019a1..2b911caa 100644
--- a/packages/components/README.md
+++ b/packages/components/README.md
@@ -20,11 +20,47 @@ Add to `App.js`:
```jsx
import { SquiggleEditor } from "@quri/squiggle-components";
Loading...
, + ssr: false, + } +); + +export function DynamicSquiggleChart({ squiggleString }) { + if (squiggleString == "") { + return null; + } else { + return ( +{children}
-); - -function InputItem{children}
+); diff --git a/packages/components/src/components/ui/Toggle.tsx b/packages/components/src/components/ui/Toggle.tsx new file mode 100644 index 00000000..bbf9a5ee --- /dev/null +++ b/packages/components/src/components/ui/Toggle.tsx @@ -0,0 +1,47 @@ +import { RefreshIcon } from "@heroicons/react/solid"; +import clsx from "clsx"; +import React from "react"; + +type IconType = (props: React.ComponentProps<"svg">) => JSX.Element; + +type Props = { + status: boolean; + onChange: (status: boolean) => void; + texts: [string, string]; + icons: [IconType, IconType]; + spinIcon?: boolean; +}; + +export const Toggle: React.FC