### Joyride User Onboarding README.md Template Content Source: https://github.com/betterthantomorrow/joyride/blob/master/dev/doc/CONTENT-CREATION-HELP.md This Markdown content provides a comprehensive `README.md` template designed for new Joyride users. It guides them through initial setup, including creating their first scripts, installing recommended tools like Calva, exploring examples, and understanding the project's directory structure. The goal is to offer a clean and minimal initial experience while providing clear next steps. ```markdown # Welcome to Joyride! 🎸 Joyride lets you script VS Code using ClojureScript. This is your user Joyride directory where you can create scripts that enhance your VS Code experience. ## Getting Started ### 1. Create Your First Script Use VS Code commands to create your first Joyride scripts: - **Create User Activate Script** - Runs automatically when Joyride starts - **Create Hello Joyride User Script** - Example script to run manually ### 2. Install Calva (Recommended) For the best Joyride development experience, install the Calva extension: - Provides syntax highlighting and REPL support - Use `Calva: Start Joyride REPL and Connect` to interact with your scripts ### 3. Explore Examples Check out the Joyride examples repository: https://github.com/BetterThanTomorrow/joyride/tree/master/examples ### 4. Run Scripts - Use `Joyride: Run User Script` to run your scripts - Scripts in this directory can access the full VS Code API ## Directory Structure - `scripts/` - Your Joyride scripts go here - `src/` - Reusable Clojure code (created when needed) - `deps.edn` - Clojure dependencies (created when needed) ## Next Steps - Read the Joyride documentation: https://github.com/BetterThanTomorrow/joyride - Join the Calva community: https://clojurians.slack.com (#calva channel) - Start scripting and have fun! 🎉 ``` -------------------------------- ### Joyride VS Code Development Setup and REPL Connection Source: https://github.com/betterthantomorrow/joyride/blob/master/CONTRIBUTE.md This snippet details the sequence of actions within VS Code to build the Joyride extension, launch the debug host, and connect the necessary REPLs for active development. It covers starting the nREPL server, the Extension Development Host, and establishing Calva REPL connections. ```VS Code 1. In VS Code, Tasks: Run Build Task: cmd/ctrl+shift+b. - This starts the nREPL server - Wait for shadow-cljs to signal that building is done. 2. Start the extension in debug mode: F5 - This starts the Extension Development Host 3. In the extension development host, issue the command Calva: Start Joyride REPL and Connect 4. Back in the Joyride project window: Connect the REPL to the nREPL server and the shadow-cljs build :extension ``` -------------------------------- ### Clojure Initial Installation Behavior E2E Tests Source: https://github.com/betterthantomorrow/joyride/blob/master/dev/doc/CONTENT-CREATION-HELP.md These Clojure `deftest-async` snippets outline E2E test scenarios for verifying the initial installation behavior of the Joyride extension. They focus on ensuring that only `README.md` is created upon first activation and that its content is as expected, all while utilizing the isolated temporary configuration directory. ```clojure (deftest-async minimal-initial-creation (testing "Only README.md is created on first activation" ;; NOTE: Tests automatically use isolated tmp config via ;; VSCODE_JOYRIDE_USER_CONFIG_PATH - real user configs are safe! (p/let [user-config-path (user-abs-joyride-path)] ;; Verify clean state - tmp dir should be empty initially ;; Trigger activation or content creation ;; Assert only README.md exists in user config path ;; Assert no scripts directory exists yet ))) (deftest-async readme-content-validation (testing "README.md contains expected getting started content" ;; Check file exists and has proper content in tmp config dir )) ``` -------------------------------- ### Joyride nREPL Server ClojureScript Example Source: https://github.com/betterthantomorrow/joyride/blob/master/README.md A ClojureScript example file (`hello_joyride.cljs`) demonstrating basic VS Code API interaction and Promise handling. This code is intended for use when connected to the Joyride nREPL server, allowing for interactive development. ```clojure (ns hello-joyride (:require ["vscode" :as vscode] [promesa.core :as p])) (comment (+ 1 2 3 4 5 6 7 8 6) (-> (vscode/window.showInformationMessage "Come on, Join the Joyride!" "Be a Joyrider") (p/then (fn [choice] (println "You choose to:" choice))))) ``` -------------------------------- ### Write to Joyride Output Channel Example Source: https://github.com/betterthantomorrow/joyride/blob/master/doc/api.md An example script demonstrating how to use `joyride.core` functions like `output-channel`, `extension-context`, `*file*`, and `invoked-script` to log information to the Joyride output channel. ```ClojureScript (ns your-awesome-script (:require [joyride.core :as joyride] ...)) (doto (joyride/output-channel) (.show true) (.append "Writing to the ") (.appendLine "Joyride output channel.") (.appendLine (str "Joyride extension path: " (-> (joyride/extension-context) .-extension .-extensionPath))) (.appendLine (str "joyride/*file*: " joyride/*file*)) (.appendLine (str "Invoked script: " (joyride/invoked-script))) (.appendLine "🎉")) ``` -------------------------------- ### Example Workspace Script in Clojure Source: https://github.com/betterthantomorrow/joyride/blob/master/doc/PROJECT_SUMMARY.md Provides an example of a Joyride workspace script, illustrating how to access workspace folders and interact with Node.js modules like `fs` and `path` to perform file operations within the current VS Code workspace. ```clojure (ns workspace-example (:require ["vscode" :as vscode] ["fs" :as fs] ["path" :as path])) (def root-path (-> (first vscode/workspace.workspaceFolders) .-uri .-fsPath)) (fs/writeFileSync (path/join root-path "output.txt") "Generated by Joyride!") ``` -------------------------------- ### Example User Script in Clojure Source: https://github.com/betterthantomorrow/joyride/blob/master/doc/PROJECT_SUMMARY.md Demonstrates a basic Joyride user script written in Clojure, showing how to interact with VS Code APIs (e.g., `vscode/window.showInformationMessage`) and how to ensure code runs only when invoked as a script, not when loaded in a REPL. ```clojure (ns example (:require ["vscode" :as vscode] [joyride.core :as joyride] [promesa.core :as p])) (defn show-message [] (vscode/window.showInformationMessage "Hello from Joyride!")) ;; Only run when invoked as script, not when loaded in REPL (when (= (joyride/invoked-script) joyride/*file*) (show-message)) ``` -------------------------------- ### Local Joyride REPL Tool (`joyride_evaluate_code`) Source: https://github.com/betterthantomorrow/joyride/blob/master/prompts/general/copilot-instructions.md This tool targets the installed Joyride extension in the current VS Code window, not the development version. It is designed for VS Code automation, user interaction through quick input boxes, and providing progress updates, facilitating user involvement in the development process. ```APIDOC Tool Name: joyride_evaluate_code Target Environment: Installed Joyride extension (current VS Code window) Primary Use: VS Code automation, user interaction (quick input boxes), progress updates Usage Context: Involving the user in development, asking questions, showing progress ``` -------------------------------- ### Initialize Joyride Development Dependencies Source: https://github.com/betterthantomorrow/joyride/blob/master/CONTRIBUTE.md This command installs the necessary Node.js dependencies for the Joyride project, preparing the environment for development. ```Shell npm i ``` -------------------------------- ### Joyride Build and Development Commands Source: https://github.com/betterthantomorrow/joyride/blob/master/doc/PROJECT_SUMMARY.md Lists common `npm` commands for building, developing, packaging, and testing the Joyride extension. These commands provide a quick reference for developers to manage the extension's lifecycle from dependency installation to running integration tests. ```bash # Install dependencies npm install # Watch mode for development (starts nREPL server) npm run watch # Build for production npm run release # Package extension npm run package # Run integration tests npm run integration-test # Clean build artifacts npm run clean ``` -------------------------------- ### Joyride User Configuration Settings Source: https://github.com/betterthantomorrow/joyride/blob/master/doc/PROJECT_SUMMARY.md This JSON snippet shows an example of a user setting for the Joyride extension, specifically configuring the nREPL server host address. These settings are typically managed via VS Code's settings UI. ```json { "joyride.nreplHostAddress": "127.0.0.1" } ``` -------------------------------- ### Building Custom Joyride Libraries: Namespace Definition and Activation Source: https://github.com/betterthantomorrow/joyride/blob/master/examples/README.md This example demonstrates how to define a custom ClojureScript namespace (`my-lib`) for a Joyride user script, including required dependencies like `vscode` and `promesa.core`. It also shows how to ensure this custom library is loaded by requiring it from the main `activate.cljs` user script. ```Clojure (ns my-lib (:require ["vscode" :as vscode] [promesa.core :as p])) ``` ```Clojure (ns activate (:require ... [my-lib] ...)) ``` -------------------------------- ### Executing `joyride.runCode` Command via VS Code API Source: https://github.com/betterthantomorrow/joyride/blob/master/doc/api.md Shows a JavaScript example of how to execute the `joyride.runCode` command using `vscode.commands.executeCommand` to retrieve ClojureScript functions like `clj->js`. ```javascript const toJS = await vscode.commands.executeCommand('joyride.runCode', "clj->js"); ``` -------------------------------- ### Integrating with Other VS Code Extension APIs Source: https://github.com/betterthantomorrow/joyride/blob/master/doc/PROJECT_SUMMARY.md This example demonstrates how to access and utilize functionality from other installed VS Code extensions within Joyride scripts. It shows requiring an external extension's API and then calling its specific functions, such as retrieving the current form text from Calva. ```clojure ;; Access other extension APIs ["ext://betterthantomorrow.calva$v0" :refer [repl ranges]] ;; Use extension-specific functionality (def current-form-text (second (ranges.currentForm))) ``` -------------------------------- ### Clojure Backwards Compatibility E2E Tests Source: https://github.com/betterthantomorrow/joyride/blob/master/dev/doc/CONTENT-CREATION-HELP.md These Clojure `deftest-async` snippets outline E2E tests to ensure backwards compatibility for existing Joyride user installations. They verify that pre-existing user content is preserved during activation and that users with older content can still utilize new commands without issues. ```clojure (deftest-async existing-user-content-preserved (testing "Existing user installations are not modified" ;; Pre-populate user config with existing files ;; Trigger activation ;; Assert no files are modified or created )) (deftest-async migration-behavior (testing "Users with old content can still use new commands" ;; Test mixed scenarios where some files exist but not others )) ``` -------------------------------- ### Configure Joyride Keyboard Shortcuts in VS Code Source: https://github.com/betterthantomorrow/joyride/blob/master/doc/configuration.md This JSON snippet illustrates how to customize VS Code keyboard shortcuts for Joyride commands. It includes examples for binding keys to run specific user or workspace scripts, execute inline ClojureScript code, and open the user/workspace script selection menus. It also notes the importance of ordering bindings with arguments before those without. ```json [ ... { "key": "cmd+f1", "command": "joyride.runUserScript", "args": "acme/my_super_script.cljs" }, { "key": "cmd+f2", "command": "joyride.runWorkspaceScript", "args": "my_first_ws_script.cljs" }, { "key": "cmd+f3", "command": "joyride.runCode", "args": "(require '["vscode" :as vscode]) (vscode/window.showInformationMessage \"Hello World!\")" }, { "key": "cmd+alt+",", "command": "joyride.runUserScript" }, { "key": "cmd+alt+.", "command": "joyride.runWorkspaceScript" }, { "key": "ctrl+shift+alt+space", "command": "joyride.runCode" }, ... ] ``` -------------------------------- ### Extension Development Host Joyride REPL Source: https://github.com/betterthantomorrow/joyride/blob/master/prompts/general/copilot-instructions.md This REPL runs specifically inside the Extension Development Host and is intended for testing Joyride's core REPL functionality. Its use is limited to scenarios where modifications are being made to the fundamental REPL features, rather than typical UI or extension work. ```APIDOC Tool Name: Extension Development Host Joyride REPL Target Environment: Joyride REPL inside Extension Development Host (reachable via Backseat Driver) Primary Use: Testing Joyride's core REPL functionality Usage Context: Only when modifying Joyride's core REPL features ``` -------------------------------- ### Using NPM Modules in Joyride Scripts Source: https://github.com/betterthantomorrow/joyride/blob/master/doc/api.md Provides guidelines for integrating NPM modules into Joyride scripts, covering installation requirements, supported package managers, CommonJS format necessity, and how to reload updated modules. ```APIDOC NPM Modules in Joyride Scripts: - Installation: Modules need to be installed in a path from where the script resides, up to the filesystem root. - Recommended locations: /.config/joyride or /.joyride. - Both 'yarn' and 'npm i' are supported. - Format: Modules must be in CommonJS format. - Reloading: Add ':reload' to the require form to reload an updated npm module. ``` -------------------------------- ### Access Joyride Extension API Programmatically Source: https://github.com/betterthantomorrow/joyride/blob/master/doc/PROJECT_SUMMARY.md Documents the JavaScript API exposed by the Joyride extension, allowing other extensions or scripts to interact with its core functionalities. This includes evaluating Clojure code, starting an nREPL server, and retrieving VS Code context values directly. ```APIDOC joyride: Object runCode(code: string): Promise code: The Clojure code string to evaluate. Returns: A Promise that resolves with the evaluation result. startNReplServer(): Promise Returns: A Promise that resolves with the port number of the started nREPL server. getContextValue(key: string): any key: The context key string to retrieve. Returns: The value associated with the context key. ``` -------------------------------- ### Execute Inline Clojure Code via VS Code Command Palette Source: https://github.com/betterthantomorrow/joyride/blob/master/README.md Example of running a single line of ClojureScript code directly from the VS Code Command Palette using the 'Joyride: Run Clojure Code...' command. This is a quick way to test small snippets. ```clojure (require '["vscode" :as vscode]) (vscode/window.showInformationMessage "Hello World!") ``` -------------------------------- ### Creating and Registering Dynamic VS Code Sidecar Extensions Source: https://github.com/betterthantomorrow/joyride/blob/master/doc/PROJECT_SUMMARY.md This snippet illustrates how to programmatically package and install a custom VS Code extension (sidecar) from within Joyride. It also shows how to register custom commands and tree data providers using the VS Code API, enabling dynamic extension capabilities. ```clojure ;; Package and install custom extension manifest (defn install-sidecar!+ [] (-> (exec!+ "npx vsce package" {:cwd sidecar-dir}) (p/then #(exec!+ "code --install-extension my-sidecar.vsix")))) ;; Register custom commands and views (push-disposables! (vscode/commands.registerCommand "my.command" my-handler) (vscode/window.registerTreeDataProvider "my.view" my-provider)) ``` -------------------------------- ### Write a File to Workspace Root in Joyride Source: https://github.com/betterthantomorrow/joyride/blob/master/README.md Demonstrates how to write a file to the VS Code workspace root using Joyride scripts, provided in both ClojureScript and JavaScript. These examples leverage the VS Code API and Node.js 'fs' and 'path' modules. ```clojure (ns example.write-a-file (:require ["fs" :as fs] ["path" :as path] ["vscode" :as vscode] [clojure.string :as str])) (defn info [& xs] (vscode/window.showInformationMessage (str/join " " xs))) (def root-path (-> (first vscode/workspace.workspaceFolders) .-uri .-fsPath)) (info "The root path of this workspace:" root-path) (fs/writeFileSync (path/resolve root-path "test-from-cljs-script.txt") "Written from a Workspace ClojureScript Script!") ``` ```javascript const fs = require("fs"); const path = require("path"); const vscode = require("vscode"); function info(...xs) { vscode.window.showInformationMessage(xs.join(" ")); } const rootPath = vscode.workspace.workspaceFolders[0].uri.fsPath; info("The root path of this workspace:", rootPath); fs.writeFileSync( path.resolve(rootPath, "test-from-js-script.txt"), "Written from a Workspace JavaScript Script!" ); ``` -------------------------------- ### Consistent Error Reporting in Joyride Source: https://github.com/betterthantomorrow/joyride/blob/master/doc/PROJECT_SUMMARY.md This example illustrates a pattern for consistent error reporting in Joyride, utilizing a utility function `utils/say-error`. It demonstrates binding a flag to control error message visibility and passing the error message for display. ```clojure ;; Consistent error reporting (binding [utils/*show-when-said?* true] (utils/say-error (str "Failed: " (.-message error)))) ``` -------------------------------- ### Calva Backseat Driver REPL Tool (`evaluate_clojure_code`) Source: https://github.com/betterthantomorrow/joyride/blob/master/prompts/general/copilot-instructions.md This tool is primarily used for debugging and testing code changes within the Joyride extension that is currently under development, running in the Extension Development Host. It serves as the main interface for investigating and fixing issues in the development version of the extension. ```APIDOC Tool Name: evaluate_clojure_code Target Environment: Joyride extension under development (Extension Development Host) Primary Use: Debugging, testing code changes, investigating issues Usage Context: Main tool for developing and fixing the Joyride extension itself ``` -------------------------------- ### Structural Editing: Convert Midje Arrow to clojure.test/is using rewrite-clj Source: https://github.com/betterthantomorrow/joyride/blob/master/examples/README.md This script demonstrates how to use `rewrite-clj` to transform a selected Midje arrow clause (`=>`) into a `clojure.test/is` form. It showcases parsing S-Expressions and building new forms using syntax-quote. A VSCode keybinding example is provided for quick access. ```Clojure (+ 2 2) => 4 ;; is changed to (is (= 4 (+ 2 2))) ``` ```JSON { "key": "f3", "command": "joyride.runWorkspaceScript", "args": "port_arrow_form.cljs", "when": "editorHasSelection && editorTextFocus && !editorReadOnly && editorLangId == 'clojure'" } ``` -------------------------------- ### VS Code `package.json` `when` Clause Examples for Joyride Contexts Source: https://github.com/betterthantomorrow/joyride/blob/master/dev/doc/CONTENT-CREATION-HELP.md These JSON snippets illustrate how to utilize the newly defined Joyride context variables in VS Code's `package.json` `when` clauses. By prefixing the context variable names with `!joyride.when-contexts/`, developers can conditionally enable or disable commands and UI elements based on the existence of specific Joyride scripts. ```json "when": "!joyride.when-contexts/userActivateScriptExists" "when": "!joyride.when-contexts/userHelloScriptExists" "when": "!joyride.when-contexts/workspaceActivateScriptExists" "when": "!joyride.when-contexts/workspaceHelloScriptExists" ``` -------------------------------- ### Structural Editing: Ignore Clojure Form with Calva Source: https://github.com/betterthantomorrow/joyride/blob/master/examples/README.md This script provides a command to toggle ignoring (Clojure-wise) the current enclosing form. It relies on the Calva VSCode extension to locate and modify the form by adding or removing the `#_` ignore tag. A VSCode keybinding example is provided to integrate this functionality, overriding the default comment shortcut on macOS when no selection is active. ```JSON { "key": "cmd+/", "command": "joyride.runWorkspaceScript", "args": "ignore_form.cljs", "when": "!editorHasSelection && editorTextFocus && !editorReadOnly && editorLangId =~ /clojure|scheme|lisp/" } ``` -------------------------------- ### Clojure Menu Integration E2E Tests Source: https://github.com/betterthantomorrow/joyride/blob/master/dev/doc/CONTENT-CREATION-HELP.md These Clojure `deftest-async` snippets cover E2E tests for menu integration within the Joyride extension. They ensure that the "Run User Script" menu correctly includes "create" options when scripts are absent and that existing workspace script menu behaviors remain consistent with new patterns. ```clojure (deftest-async user-script-menu-shows-create-options (testing "Run User Script menu includes create options when scripts don't exist" ;; Execute runUserScript command (menu version) ;; Check menu options include create commands ;; Select create option, verify file creation )) (deftest-async workspace-script-menu-consistency (testing "Workspace script menus work consistently with new pattern" ;; Verify existing workspace menu behavior still works ;; Test both activate and hello script creation )) ``` -------------------------------- ### Clojure Activation Script Pattern for VS Code Source: https://github.com/betterthantomorrow/joyride/blob/master/doc/PROJECT_SUMMARY.md Shows a robust pattern for writing Joyride activation scripts in Clojure. It includes state management with `atom`, handling disposables for proper resource cleanup, and registering VS Code event listeners to react to editor events. ```clojure (ns user-activate (:require ["vscode" :as vscode] [joyride.core :as joyride])) (defonce !db (atom {:disposables []})) ;; Re-runnable pattern - clear previous disposables (defn- clear-disposables! [] (run! #(.dispose %) (:disposables @!db)) (swap! !db assoc :disposables [])) ;; Register disposables with VS Code for cleanup (defn- push-disposable! [disposable] (swap! !db update :disposables conj disposable) (-> (joyride/extension-context) .-subscriptions (.push disposable))) (defn- my-main [] (clear-disposables!) (push-disposable! (vscode/workspace.onDidOpenTextDocument (fn [doc] (println "Document opened:" (.-fileName doc)))))) (when (= (joyride/invoked-script) joyride/*file*) (my-main)) ``` -------------------------------- ### Joyride Core API Reference Source: https://github.com/betterthantomorrow/joyride/blob/master/doc/api.md Reference documentation for the `joyride.core` namespace, detailing its dynamic variables and functions for interacting with the Joyride environment, including file paths, extension context, and output channels. ```APIDOC joyride.core: *file*: dynamic var holding the absolute path of file where the current evaluation is taking place invoked-script(): function returning the absolute path of the invoked script when running as a script. Otherwise returns `nil`. Example usage: (when (= (joyride/invoked-script) joyride/*file*) (main)) extension-context(): function returning the Joyride ExtensionContext instance output-channel(): function returning the Joyride OutputChannel instance js-properties(js_object): a function returning a sequence of the full JS API of the provided JS object/instance. For use instead of `cljs.core/js-keys` when it doesn't return the full API. user-joyride-dir: a string path with the user/global joyride directory. ``` -------------------------------- ### Clojure File System State E2E Tests Source: https://github.com/betterthantomorrow/joyride/blob/master/dev/doc/CONTENT-CREATION-HELP.md These Clojure `deftest-async` snippets define E2E tests for verifying the file system state changes triggered by Joyride's content creation. They specifically test the timing of `deps.edn` creation when the first script is created and the appropriate creation of the `src` directory and `my_lib.cljs`. ```clojure (deftest-async deps-edn-creation-timing (testing "deps.edn created when first script is created" ;; Start with clean state ;; Create user activate script ;; Assert deps.edn also created ;; Verify deps.edn content matches template )) (deftest-async src-directory-creation (testing "src directory and my_lib.cljs created appropriately" ;; Test when src content should be created ;; May need to be part of hello script creation or separate command )) ``` -------------------------------- ### Define Joyride Keyboard Shortcuts Source: https://github.com/betterthantomorrow/joyride/blob/master/doc/PROJECT_SUMMARY.md Illustrates common keyboard shortcuts for quick access to Joyride commands within VS Code. This JSON snippet shows the typical format for defining keybindings in VS Code's `keybindings.json` file, mapping key combinations to specific Joyride commands. ```json "ctrl+alt+j space" - Run Code "ctrl+alt+j enter" - Evaluate Selection "ctrl+alt+j u" - Run User Script "ctrl+alt+j w" - Run Workspace Script ``` -------------------------------- ### Joyride `when` Clause Contexts Reference Source: https://github.com/betterthantomorrow/joyride/blob/master/doc/api.md Documents the available `when` clause contexts for keyboard shortcut bindings, specifying their keys and boolean types, such as `joyride.isActive` and `joyride.isNReplServerRunning`. ```APIDOC Joyride when Clause Contexts: - joyride.isActive: boolean - Whether the joyRide extension is active or not. - joyride.isNReplServerRunning: boolean - Whether the Joyride nREPL server is running or not. ``` -------------------------------- ### Register New Joyride Commands in package.json Source: https://github.com/betterthantomorrow/joyride/blob/master/dev/doc/CONTENT-CREATION-HELP.md This JSON snippet defines new commands for the Joyride VS Code extension, allowing users to create activate and hello scripts on demand. Each command specifies its unique identifier, display title, category, and a 'when' clause to control its visibility based on the existence of corresponding user or workspace scripts. ```JSON { "command": "joyride.createUserActivateScript", "title": "Create User Activate Script", "category": "Joyride", "when": "!joyride.when-contexts/userActivateScriptExists" }, { "command": "joyride.createUserHelloScript", "title": "Create Hello Joyride User Script", "category": "Joyride", "when": "!joyride.when-contexts/userHelloScriptExists" }, { "command": "joyride.createWorkspaceActivateScript", "title": "Create Workspace Activate Script", "category": "Joyride", "when": "!joyride.when-contexts/workspaceActivateScriptExists" }, { "command": "joyride.createWorkspaceHelloScript", "title": "Create Hello Joyride Workspace Script", "category": "Joyride", "when": "!joyride.when-contexts/workspaceHelloScriptExists" } ``` -------------------------------- ### Execute Joyride Extension Commands Source: https://github.com/betterthantomorrow/joyride/blob/master/doc/PROJECT_SUMMARY.md Demonstrates how to programmatically trigger various Joyride functionalities within VS Code using `vscode.commands.executeCommand`. This includes running arbitrary code, evaluating the current selection, executing user or workspace scripts, and managing the nREPL server lifecycle. ```javascript // Run code dynamically vscode.commands.executeCommand('joyride.runCode', '(+ 1 2 3)') // Evaluate current selection vscode.commands.executeCommand('joyride.evaluateSelection') // Run scripts vscode.commands.executeCommand('joyride.runUserScript', 'my-script.cljs') vscode.commands.executeCommand('joyride.runWorkspaceScript', 'workspace-script.cljs') // Script management vscode.commands.executeCommand('joyride.openUserScript') vscode.commands.executeCommand('joyride.openWorkspaceScript') // nREPL management vscode.commands.executeCommand('joyride.startNReplServer') vscode.commands.executeCommand('joyride.stopNReplServer') vscode.commands.executeCommand('joyride.enableNReplMessageLogging') vscode.commands.executeCommand('joyride.disableNReplMessageLogging') ``` -------------------------------- ### Joyride API Overview Source: https://github.com/betterthantomorrow/joyride/blob/master/doc/api.md Outlines the two main components of the Joyride API: the Extension API and the Scripting API, detailing their primary functions and sub-components. ```APIDOC Joyride API: 1. The Joyride Extension API: - exports - Extension commands - when clause context 2. The Joyride Scripting API: - Scripting lifecycle management - Included clojure library namespaces ``` -------------------------------- ### Joyride Scripting Activation Lifecycle Source: https://github.com/betterthantomorrow/joyride/blob/master/doc/api.md Explains how scripts named `activate.cljs` are automatically executed when Joyride activates, detailing the specific order of execution for user and workspace scripts. ```APIDOC Joyride Scripting Activation Lifecycle: Scripts named 'activate.cljs' are run in this order upon Joyride activation: 1. /activate.cljs 2. /activate.cljs ``` -------------------------------- ### Clojure Command Availability E2E Tests Source: https://github.com/betterthantomorrow/joyride/blob/master/dev/doc/CONTENT-CREATION-HELP.md These Clojure `deftest-async` snippets define E2E tests for the conditional availability of Joyride commands. They verify that commands like "Create User Activate Script" are available when a script doesn't exist, become unavailable after creation, and that the "Create Hello User Script" command follows a similar conditional pattern. ```clojure (deftest-async create-user-activate-command-availability (testing "Create User Activate Script command available when script doesn't exist" ;; Assert command is available in palette ;; Execute command ;; Assert file is created and opened ;; Assert command becomes unavailable )) (deftest-async create-hello-user-script-command-availability (testing "Create Hello User Script command conditional availability" ;; Similar pattern for hello script )) ``` -------------------------------- ### Joyride Extension `exports` API Reference Source: https://github.com/betterthantomorrow/joyride/blob/master/doc/api.md Documents the methods available through the `exports` object of the activated Joyride extension, including `runCode`, `startNReplServer`, and `getContextValue` with their parameters and return types. ```APIDOC Joyride Extension exports API: - joyride.runCode(code: string): Promise - Evaluates the provided string and returns a promise with the result. - startNReplServer(project_root_path?: string): Promise - project_root_path: Optional, defaults to vscode/workspace.rootPath. - Returns a promise resolving to the port where the nREPL server started. - getContextValue(context_key: string): any - context_key: The key of a Joyride when clause context. - Returns the value of a Joyride when clause context or undefined for non-existing keys. ``` -------------------------------- ### Joyride Extension Automatic Content Creation Calls Source: https://github.com/betterthantomorrow/joyride/blob/master/dev/doc/CONTENT-CREATION-HELP.md This ClojureScript snippet shows the function calls responsible for automatically creating initial user and workspace configuration files when the Joyride extension activates. These calls are located in `src/joyride/extension.cljs` and represent the current behavior that the redesign aims to modify. ```ClojureScript (getting-started/maybe-create-user-content+) (getting-started/maybe-create-workspace-config+ false) ``` -------------------------------- ### Joyride Environment Variables Source: https://github.com/betterthantomorrow/joyride/blob/master/doc/PROJECT_SUMMARY.md Documentation for environment variables that can configure Joyride's behavior. ```APIDOC VSCODE_JOYRIDE_USER_CONFIG_PATH: string Description: Overrides the default user configuration path for Joyride. ``` -------------------------------- ### Clojure E2E Test Utility Functions Source: https://github.com/betterthantomorrow/joyride/blob/master/dev/doc/CONTENT-CREATION-HELP.md This Clojure code snippet defines essential utility functions for E2E testing within the Joyride extension. These helpers provide functionality to retrieve the temporary user configuration path, clean the test environment, check file existence asynchronously, determine command availability, and simulate menu interactions, all designed to simplify test development. ```clojure (defn get-test-user-config-path [] ;; Returns the safe tmp config path being used by tests ;; This will be something like /tmp/vscode-test-runner-joyride/user-config/ ) (defn clean-test-user-config! [] ;; Helper to reset the tmp user config directory for tests ;; Safe to use since it only affects the isolated test environment ) (defn file-exists? [path] ;; Promise-based file existence check ) (defn get-command-availability [command-id] ;; Check if command is available in palette ) (defn simulate-menu-interaction [menu-command expected-options] ;; Helper for testing menu flows ) ``` -------------------------------- ### Execute Git Fuzzy Script with Joyride `runCode` Command Source: https://github.com/betterthantomorrow/joyride/blob/master/assets/getting-started-content/user/README.md This ClojureScript expression is designed to be executed by the `joyride.runCode` command. It first requires the `git-fuzzy` namespace, aliasing it as `gz` and ensuring it's reloaded. Then, it calls the `show-git-history!+` function from the `git-fuzzy` library to display the Git history. ```clojure (require '[git-fuzzy :as gz] :reload) (gz/show-git-history!+) ``` -------------------------------- ### Defining and Using Custom ClojureScript Libraries Source: https://github.com/betterthantomorrow/joyride/blob/master/doc/PROJECT_SUMMARY.md This section demonstrates how to create and utilize custom ClojureScript libraries within the Joyride extension. It shows defining a namespace with VS Code API requirements and then requiring and using that library from an activation script or a keyboard shortcut. ```clojure ;; In ~/.config/joyride/src/my_lib.cljs (ns my-lib (:require ["vscode" :as vscode])) (defn find-with-regex-on [] ;; Custom functionality ) ``` ```clojure ;; In ~/.config/joyride/scripts/user_activate.cljs (ns user-activate (:require [my-lib])) ``` ```json { "key": "cmd+f1", "command": "joyride.runCode", "args": "(my-lib/find-with-regex-on)" } ``` -------------------------------- ### Configure VS Code Keybindings for Joyride Scripts Source: https://github.com/betterthantomorrow/joyride/blob/master/README.md Shows how to add custom keyboard shortcuts in VS Code's `keybindings.json` to quickly run specific Joyride workspace scripts (JavaScript and ClojureScript). This allows for rapid execution of frequently used scripts. ```json { "key": "shift+ctrl+alt+j 1", "command": "joyride.runWorkspaceScript", "args": "example/write-a-file.js" } { "key": "shift+ctrl+alt+j 2", "command": "joyride.runWorkspaceScript", "args": "example/write_a_file.cljs" } ``` -------------------------------- ### Shadow-cljs Configuration for Joyride Extension Source: https://github.com/betterthantomorrow/joyride/blob/master/doc/PROJECT_SUMMARY.md This snippet shows the shadow-cljs build configuration for the Joyride extension, targeting a Node.js library. It specifies options for JavaScript provider, native require handling, and defines export points for activation and development hot-reloading. ```clojure {:target :node-library :js-options {:js-provider :shadow :keep-native-requires true :keep-as-require #{"vscode"}} :exports {:activate joyride.extension/activate} :devtools {:before-load-async joyride.extension/before :after-load joyride.extension/after}} ``` -------------------------------- ### Run Joyride Integration Tests from Command Line Source: https://github.com/betterthantomorrow/joyride/blob/master/CONTRIBUTE.md This snippet provides the command-line instruction to execute the full suite of integration tests for the Joyride VS Code extension. It automates the download and launch of VS Code Insiders, test execution, and subsequent closure. ```Shell npm run integration-test ``` -------------------------------- ### Joyride Development and Build Dependencies Source: https://github.com/betterthantomorrow/joyride/blob/master/doc/PROJECT_SUMMARY.md Development-specific Node.js dependencies for Joyride, covering the ClojureScript compiler (shadow-cljs), VS Code testing utilities, and tools for packaging the extension, facilitating the build and release process. ```JSON "shadow-cljs": "^2.18.0", "@vscode/test-electron": "^2.2.3", "vsce": "^2.15.0" ``` -------------------------------- ### Promesa Core Availability in Joyride Source: https://github.com/betterthantomorrow/joyride/blob/master/doc/api.md Details the partial availability of Promesa in Joyride, advising users to consult the Promesa documentation and explaining how to verify supported features by checking the `sci-configs` repository at the specific commit ID used by Joyride. ```APIDOC Promesa Core: Availability: Partially available in Joyride. Usage: Refer to Promesa documentation (https://cljdoc.org/d/funcool/promesa/11.0.678/doc/promises). Supported Features: Depends on the `sci-configs` version Joyride is built with. Verification: Check the `sci-configs` repository at the specific commit ID used by Joyride (e.g., https://github.com/babashka/sci.configs/blob/3cd48a595bace287554b1735bb378bad1d22b931/src/sci/configs/funcool/promesa.cljs). Commit ID: Found in Joyride's `deps.edn` file. ``` -------------------------------- ### Configure VS Code Keyboard Shortcut for Joyride Script Source: https://github.com/betterthantomorrow/joyride/blob/master/assets/getting-started-content/user/README.md This JSON configuration defines a keyboard shortcut in VS Code to execute a specific Joyride command. It binds the key combination `ctrl+alt+j ctrl+alt+g` to the `joyride.runCode` command, passing a ClojureScript expression as arguments to be evaluated. ```json { "key": "ctrl+alt+j ctrl+alt+g", "command": "joyride.runCode", "args": "(require '[git-fuzzy :as gz] :reload) (gz/show-git-history!+)" } ``` -------------------------------- ### Joyride Default Script Locations and Structure Source: https://github.com/betterthantomorrow/joyride/blob/master/doc/PROJECT_SUMMARY.md This snippet illustrates the hierarchical file structure for Joyride user and workspace scripts, including activation scripts and library source directories. Joyride searches for scripts in a specific order, prioritizing workspace-level files over user-level ones for execution. ```Text ~/.config/joyride/ ├── deps.edn ├── scripts/ │ ├── user_activate.cljs │ ├── hello_joyride_user_script.cljs │ └── hello_joyride_user_script.js └── src/ └── my_lib.cljs .joyride/ ├── deps.edn ├── scripts/ │ ├── workspace_activate.cljs │ └── hello_joyride_workspace_script.cljs └── src/ └── workspace_lib.cljs ``` -------------------------------- ### Common Joyride Extension Commands Source: https://github.com/betterthantomorrow/joyride/blob/master/doc/api.md Lists the most frequently used Joyride extension commands that users can execute, such as `runCode`, `evaluatSelection`, `runUserScript`, and `runWorkspaceScript`, which are accessible via the VS Code command palette. ```APIDOC Joyride Extension Commands: - joyride.runCode - joyride.evaluatSelection - joyride.runUserScript - joyride.runWorkspaceScript ``` -------------------------------- ### Require VS Code Extension API in Clojure Source: https://github.com/betterthantomorrow/joyride/blob/master/doc/api.md Illustrates how to require external VS Code extension APIs using the `ext://` prefix, including specifying submodules and referring specific objects, as shown with Calva's API. ```Clojure (ns calva-api (:require ... ["ext://betterthantomorrow.calva$v0" :as calva :refer [repl ranges]]) ...) (def current-form-text (second (ranges.currentForm))) ``` -------------------------------- ### Core ClojureScript and SCI Dependencies for Joyride Source: https://github.com/betterthantomorrow/joyride/blob/master/doc/PROJECT_SUMMARY.md Key Clojure dependencies for the Joyride extension, including ClojureScript itself, the Small Clojure Interpreter (SCI), and SCI configurations, which are fundamental for runtime code evaluation and interactive programming. ```Clojure org.clojure/clojurescript "1.11.132" org.babashka/sci "fbb8e61a8002583fc9300d39e748d1c1b2449b20" org.babashka/sci.configs "8253c69a537bcc82e8ff122e5f905fe9d1e303f0" ``` -------------------------------- ### Joyride Extension API Structure Source: https://github.com/betterthantomorrow/joyride/blob/master/doc/api.md Details the three core components of Joyride's Extension API: the `exports` object, extension commands, and `when` clause contexts, which are accessible to users. ```APIDOC Joyride Extension API Parts: 1. The exports map/object on the activated extension instance. 2. The Joyride extension commands. 3. when clauses contexts. ``` -------------------------------- ### Manage VS Code Extension Lifecycle with Disposables Source: https://github.com/betterthantomorrow/joyride/blob/master/doc/PROJECT_SUMMARY.md Illustrates Clojure patterns for managing the lifecycle of VS Code resources, specifically focusing on registering commands and clearing disposables. This ensures proper cleanup of resources when the extension is deactivated or reloaded, preventing memory leaks. ```clojure ;; Disposable pattern for VS Code resources (defn- register-command! [context command-id var] (let [disposable (vscode/commands.registerCommand command-id var)] (swap! db/!app-db update :disposables conj disposable) (.push (.-subscriptions context) disposable))) ;; Re-runnable activation scripts (defn- clear-disposables! [] (run! #(.dispose %) (:disposables @!db)) (swap! !db assoc :disposables [])) ``` -------------------------------- ### Joyride Model Description Configuration Source: https://github.com/betterthantomorrow/joyride/blob/master/dev/doc/LM_TOOL_STDOUT_AND_ASYNC_IMPROVEMENTS.md This JSON snippet defines the `modelDescription` property, typically found in a `package.json` file for the Joyride project. It outlines the capabilities of executing ClojureScript code within VS Code's Extension API environment, detailing its synchronous default behavior and the specific use case for the `awaitResult` parameter when handling asynchronous results. ```json "modelDescription": "Execute ClojureScript code in VS Code's Extension API environment via Joyride. Thus, you can modify editor behavior, manipulate files, invoke VS Code APIs, and create dynamic workflows. Runs synchronously by default - if you evaluate async code and need the unwrapped result, use the `awaitResult` parameter." ``` -------------------------------- ### Joyride VS Code When Clause Contexts Source: https://github.com/betterthantomorrow/joyride/blob/master/doc/PROJECT_SUMMARY.md Context keys provided by the Joyride extension for use in VS Code 'when' clauses, allowing conditional activation of commands or UI elements. ```APIDOC joyride.isActive: boolean Description: Indicates if the Joyride extension is currently active. joyride.isNReplServerRunning: boolean Description: Indicates if the nREPL server is currently running. ``` -------------------------------- ### Joyride Node.js Runtime Dependencies Source: https://github.com/betterthantomorrow/joyride/blob/master/doc/PROJECT_SUMMARY.md Essential Node.js dependencies for the Joyride VS Code extension, including libraries for VS Code icons, fast directory traversal, and glob pattern matching, used for UI elements and file system operations. ```JSON "@vscode/codicons": "^0.0.30", "fdir": "^5.2.0", "picomatch": "^2.3.1" ``` -------------------------------- ### Joyride Scripting Classpath Search Order Source: https://github.com/betterthantomorrow/joyride/blob/master/doc/api.md Describes the fixed search order for Joyride code source files within the scripting environment, prioritizing workspace-specific paths over user-home paths to locate scripts and modules. ```APIDOC Joyride Scripting Classpath Search Order: 1. /.joyride/src 2. /.joyride/scripts 3. /.config/joyride/src 4. /.config/joyride/scripts ``` -------------------------------- ### Joyride Asynchronous Programming Dependency Source: https://github.com/betterthantomorrow/joyride/blob/master/doc/PROJECT_SUMMARY.md The `funcool/promesa` library is used in Joyride for robust promise and asynchronous handling, essential for managing non-blocking operations and interactions within the VS Code environment. ```Clojure funcool/promesa "11.0.678" ```