├── resources ├── icon.png ├── donate-wfp.png ├── with-env-demo.gif └── without-env-demo.gif ├── .github ├── FUNDING.yml ├── workflows │ ├── main.yml │ └── publish.yml ├── ISSUE_TEMPLATE │ ├── feature_request.md │ └── bug_report.md └── pull_request_template.md ├── .gitignore ├── src └── main │ ├── ext │ ├── constants.cljs │ ├── lang.cljs │ ├── nix_env.cljs │ └── actions.cljs │ ├── vscode │ ├── env.cljs │ ├── context.cljs │ ├── command.cljs │ ├── status_bar.cljs │ ├── window.cljs │ └── workspace.cljs │ ├── utils │ ├── helpers.cljs │ └── interop.cljs │ ├── config.cljs │ └── main.cljs ├── .cljfmt.edn ├── .vscodeignore ├── .vscode ├── extensions.json ├── tasks.json ├── settings.json └── launch.json ├── default.nix ├── .markdownlint.jsonc ├── shadow-cljs.edn ├── CONTRIBUTING.md ├── LICENSE ├── CHANGELOG.md ├── package.json ├── CODE_OF_CONDUCT.md └── README.md /resources/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arrterian/nix-env-selector/HEAD/resources/icon.png -------------------------------------------------------------------------------- /resources/donate-wfp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arrterian/nix-env-selector/HEAD/resources/donate-wfp.png -------------------------------------------------------------------------------- /resources/with-env-demo.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arrterian/nix-env-selector/HEAD/resources/with-env-demo.gif -------------------------------------------------------------------------------- /resources/without-env-demo.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arrterian/nix-env-selector/HEAD/resources/without-env-demo.gif -------------------------------------------------------------------------------- /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | # These are supported funding model platforms 2 | custom: "https://secure.wayforpay.com/payment/selector" 3 | 4 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .calva 2 | .clj-kondo 3 | .lsp 4 | .shadow-cljs 5 | dist 6 | node_modules 7 | .vscode-test/ 8 | *.vsix 9 | secrets 10 | -------------------------------------------------------------------------------- /src/main/ext/constants.cljs: -------------------------------------------------------------------------------- 1 | (ns ext.constants) 2 | 3 | (def donate-url "https://aidkit.shop") 4 | (def log-channel "Nix Env Selector") 5 | -------------------------------------------------------------------------------- /.cljfmt.edn: -------------------------------------------------------------------------------- 1 | {:remove-surrounding-whitespace? true 2 | :remove-trailing-whitespace? true 3 | :remove-consecutive-blank-lines? false 4 | :insert-missing-whitespace? true 5 | :align-associative? true} 6 | -------------------------------------------------------------------------------- /.vscodeignore: -------------------------------------------------------------------------------- 1 | .vscode/** 2 | .vscode-test/** 3 | .gitignore 4 | shadow-cljs.edn 5 | default.nix 6 | src/** 7 | .calva/** 8 | .clj-kondo/** 9 | .github/** 10 | .lsp/** 11 | node_modules/** 12 | .shadow-cljs/** 13 | -------------------------------------------------------------------------------- /.vscode/extensions.json: -------------------------------------------------------------------------------- 1 | { 2 | // See http://go.microsoft.com/fwlink/?LinkId=827846 3 | // for the documentation about the extensions.json format 4 | "recommendations": [ 5 | "arrterian.nix-env-selector" 6 | ] 7 | } 8 | -------------------------------------------------------------------------------- /src/main/vscode/env.cljs: -------------------------------------------------------------------------------- 1 | (ns vscode.env 2 | (:require ["vscode" :refer [env Uri]])) 3 | 4 | (set! *warn-on-infer* false) 5 | 6 | (defn open-external-url [url] 7 | (.openExternal env 8 | (.parse Uri url))) 9 | -------------------------------------------------------------------------------- /default.nix: -------------------------------------------------------------------------------- 1 | with (import (fetchTarball "https://github.com/NixOS/nixpkgs/archive/refs/tags/24.05.tar.gz") {}); 2 | 3 | let 4 | nixPackages = [ 5 | nodejs_22 6 | jdk17 7 | ]; 8 | in 9 | pkgs.stdenv.mkDerivation { 10 | name = "vscode-env-selector"; 11 | buildInputs = nixPackages; 12 | } 13 | -------------------------------------------------------------------------------- /src/main/vscode/context.cljs: -------------------------------------------------------------------------------- 1 | (ns vscode.context) 2 | 3 | (set! *warn-on-infer* false) 4 | 5 | (defn subsciribe [ctx cmd] 6 | (.push (.-subscriptions ctx) cmd)) 7 | 8 | (defn global-state [ctx] 9 | (.-globalState ctx)) 10 | 11 | (defn add-to-global-state [ctx key value] 12 | (let [state (global-state ctx)] 13 | (.update state key value))) 14 | 15 | (defn get-from-global-state [ctx key] 16 | (let [state (global-state ctx)] 17 | (.get state key))) 18 | -------------------------------------------------------------------------------- /.vscode/tasks.json: -------------------------------------------------------------------------------- 1 | // See https://go.microsoft.com/fwlink/?LinkId=733558 2 | // for the documentation about the tasks.json format 3 | { 4 | "version": "2.0.0", 5 | "tasks": [ 6 | { 7 | "type": "npm", 8 | "script": "watch", 9 | "problemMatcher": "$tsc-watch", 10 | "isBackground": true, 11 | "presentation": { 12 | "reveal": "never" 13 | }, 14 | "group": { 15 | "kind": "build", 16 | "isDefault": true 17 | } 18 | } 19 | ] 20 | } 21 | -------------------------------------------------------------------------------- /.markdownlint.jsonc: -------------------------------------------------------------------------------- 1 | { 2 | "MD033": { 3 | "allowed_elements": ["p", "img", "kbd"] 4 | }, 5 | "MD013": { 6 | "line_length": 100, 7 | "tables": false 8 | }, 9 | "MD030": { 10 | // Spaces for single-line unordered list items 11 | "ul_single": 3, 12 | // Spaces for single-line ordered list items 13 | "ol_single": 3, 14 | // Spaces for multi-line unordered list items 15 | "ul_multi": 3, 16 | // Spaces for multi-line ordered list items 17 | "ol_multi": 3 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /shadow-cljs.edn: -------------------------------------------------------------------------------- 1 | ;; shadow-cljs configuration 2 | {:source-paths ["src/dev" 3 | "src/main" 4 | "src/test"] 5 | :dependencies [[camel-snake-kebab "0.4.2"] 6 | [funcool/promesa "6.0.0"]] 7 | :builds {:extension 8 | {:target :esm 9 | :output-dir "dist/" 10 | :release {:compiler-options {:optimizations :simple}} 11 | :modules {:main {:exports {:activate main/activate 12 | :deactivate main/deactivate}}} 13 | :js-options {:js-provider :import}}}} 14 | -------------------------------------------------------------------------------- /src/main/vscode/command.cljs: -------------------------------------------------------------------------------- 1 | (ns vscode.command 2 | (:require ["vscode" :refer [commands]] 3 | [vscode.window :as w] 4 | [utils.interop :refer [clj->js' keyword-to-path]])) 5 | 6 | (set! *warn-on-infer* false) 7 | 8 | (defn create [cmd-id handler] 9 | (.registerCommand commands 10 | (keyword-to-path cmd-id) 11 | (clj->js' handler))) 12 | 13 | (defn execute [cmd-id log-channel] 14 | (w/write-log log-channel (str "Executing command: " cmd-id)) 15 | (.executeCommand commands 16 | (keyword-to-path cmd-id))) 17 | -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | // Place your settings in this file to overwrite default and user settings. 2 | { 3 | "editor.detectIndentation": false, 4 | "editor.tabSize": 2, 5 | "editor.insertSpaces": true, 6 | "files.insertFinalNewline": true, 7 | "files.exclude": { 8 | "out": false // set this to true to hide the "out" folder with the compiled JS files 9 | }, 10 | "search.exclude": { 11 | "out": true // set this to false to include "out" folder in search results 12 | }, 13 | "nixEnvSelector.suggestion": false, 14 | "nixEnvSelector.nixFile": "${workspaceRoot}/default.nix", 15 | } 16 | -------------------------------------------------------------------------------- /.github/workflows/main.yml: -------------------------------------------------------------------------------- 1 | name: Env Selector CI 2 | 3 | on: [pull_request] 4 | 5 | jobs: 6 | build: 7 | runs-on: ubuntu-latest 8 | strategy: 9 | matrix: 10 | node-version: [22.x] 11 | 12 | steps: 13 | - uses: actions/checkout@v1 14 | - name: Use Node.js ${{ matrix.node-version }} 15 | uses: actions/setup-node@v1 16 | with: 17 | node-version: ${{ matrix.node-version }} 18 | - name: Use JDK 19 | uses: actions/setup-java@v1 20 | with: 21 | java-version: 17 22 | - name: install and build 23 | run: | 24 | npm install 25 | npm run compile 26 | env: 27 | CI: true 28 | -------------------------------------------------------------------------------- /src/main/utils/helpers.cljs: -------------------------------------------------------------------------------- 1 | (ns utils.helpers 2 | (:require [clojure.string :as s])) 3 | 4 | ;; `workspaceRoot` is deprecated, the new variable name is `workspaceFolder`. 5 | (defn render-workspace [path workspace-root] 6 | (s/replace (s/replace path "${workspaceFolder}" workspace-root) "${workspaceRoot}" workspace-root)) 7 | 8 | (defn unrender-workspace [path workspace-root] 9 | (s/replace path workspace-root "${workspaceFolder}")) 10 | 11 | (defn render-env-status [lang env-path] 12 | (s/replace (-> lang :label :env-selected) 13 | #"%ENV_NAME%" 14 | (if env-path 15 | (last (s/split env-path #"/")) 16 | (-> lang :label :env-custom)))) -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Feature request 3 | about: Suggest an idea for this project 4 | title: "[Feature]: " 5 | labels: enhancement 6 | assignees: arrterian 7 | 8 | --- 9 | 10 | **Is your feature request related to a problem? Please describe.** 11 | A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] 12 | 13 | **Describe the solution you'd like** 14 | A clear and concise description of what you want to happen. 15 | 16 | **Describe alternatives you've considered** 17 | A clear and concise description of any alternative solutions or features you've considered. 18 | 19 | **Additional context** 20 | Add any other context or screenshots about the feature request here. 21 | -------------------------------------------------------------------------------- /src/main/vscode/status_bar.cljs: -------------------------------------------------------------------------------- 1 | (ns vscode.status-bar 2 | (:require ["vscode" :refer [window]] 3 | [utils.interop :refer [keyword-to-path]])) 4 | 5 | (set! *warn-on-infer* false) 6 | 7 | (defn create [aligment, priority] 8 | (.createStatusBarItem window 9 | (cond 10 | (= :left aligment) 1 11 | (= :right aligment) 2 12 | :else 1) 13 | priority)) 14 | 15 | (defn show [{:keys [text command]} status] 16 | ;; (.hide status) 17 | (set! (.-text status) (clj->js text)) 18 | (when command 19 | (set! (.-command status) (keyword-to-path command))) 20 | (.show status)) 21 | 22 | (defn hide [status] 23 | (.hide status)) 24 | -------------------------------------------------------------------------------- /.vscode/launch.json: -------------------------------------------------------------------------------- 1 | // A launch configuration that compiles the extension and then opens it inside a new window 2 | // Use IntelliSense to learn about possible attributes. 3 | // Hover to view descriptions of existing attributes. 4 | // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 5 | { 6 | "version": "0.2.0", 7 | "configurations": [ 8 | { 9 | "name": "Run Extension", 10 | "type": "extensionHost", 11 | "request": "launch", 12 | "runtimeExecutable": "${execPath}", 13 | "args": [ 14 | "--extensionDevelopmentPath=${workspaceFolder}" 15 | ], 16 | "outFiles": [ 17 | "${workspaceFolder}/dist/main.js" 18 | ], 19 | // "preLaunchTask": "npm: watch" 20 | } 21 | ] 22 | } 23 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug report 3 | about: Create a report to help us improve 4 | title: '' 5 | labels: bug 6 | assignees: arrterian 7 | 8 | --- 9 | 10 | **Describe the bug** 11 | A clear and concise description of what the bug is. 12 | 13 | **To Reproduce** 14 | Steps to reproduce the behavior: 15 | 1. Go to '...' 16 | 2. Click on '....' 17 | 3. Scroll down to '....' 18 | 4. See error 19 | 20 | **Expected behavior** 21 | A clear and concise description of what you expected to happen. 22 | 23 | **Screenshots** 24 | If applicable, add screenshots to help explain your problem. 25 | 26 | **Environment:** 27 | - OS: [e.g. Ubuntu 19.04] 28 | - VS Code [e.g. chrome, safari] 29 | - Version [e.g. 0.0.8] 30 | 31 | **Additional context** 32 | Add any other context about the problem here. 33 | -------------------------------------------------------------------------------- /.github/pull_request_template.md: -------------------------------------------------------------------------------- 1 | | Status | Type | Config Change | 2 | | :---: | :---: | :---: | 3 | | Ready/Hold | Feature/Bug/Tooling/Refactor/Hotfix | Yes/No | 4 | 5 | ## Problem 6 | 7 | _What problem are you trying to solve?_ 8 | 9 | ## Solution 10 | 11 | _How did you solve the problem?_ 12 | 13 | ## Other changes (e.g. bug fixes, UI tweaks, small refactors) 14 | 15 | ## Deploy Notes 16 | 17 | _Notes regarding deployment of the contained body of work. These should note any 18 | new dependencies, new scripts, etc._ 19 | 20 | **New config parameters**: 21 | 22 | - `nixEnvSelector.` : config parameter details 23 | 24 | **New scripts**: 25 | 26 | - `script` : script details 27 | 28 | **New dependencies**: 29 | 30 | - `dependency` : dependency details 31 | 32 | **New dev dependencies**: 33 | 34 | - `dependency` : dependency details -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing 2 | 3 | When contributing to this repository, please first discuss the change you wish to make via issue, 4 | email, or any other method with the owners of this repository before making a change. 5 | 6 | Please note we have a code of conduct, please follow it in all your interactions with the project. 7 | 8 | ## Pull Request Process 9 | 10 | 1. Ensure any install or build dependencies are removed before the end of the layer when doing a build. 11 | 2. Update the README.md with details of changes to the interface, this includes new commands and configuration structure changes. 12 | 3. Increase the version numbers in any examples files and the `packages.json` to the new version that this 13 | Pull Request would represent. The versioning scheme we use is [SemVer](http://semver.org/). 14 | 4. Your PR will be merged after code owner review. 15 | -------------------------------------------------------------------------------- /src/main/ext/lang.cljs: -------------------------------------------------------------------------------- 1 | (ns ext.lang) 2 | 3 | (def ^:private lang-eng 4 | {:notification {:env-restored "Original vscode environment will apply after reload" 5 | :env-applied "Applied. Reload your window using command palette" 6 | :env-available "The nix environment is available in your workspace"} 7 | :label {:env-loading "$(loading~spin) Applying environment..." 8 | :env-selected "$(beaker) Environment: %ENV_NAME%" 9 | :env-need-reload "$(beaker) Need reload" 10 | :select-config-placeholder "Select environment config" 11 | :disabled-nix "Disable Nix environment" 12 | :reload "Reload" 13 | :select-env "Select" 14 | :dismiss "Dismiss"}}) 15 | 16 | (def lang lang-eng) 17 | -------------------------------------------------------------------------------- /src/main/vscode/window.cljs: -------------------------------------------------------------------------------- 1 | (ns vscode.window 2 | (:require ["vscode" :refer [window]] 3 | [promesa.core :as p] 4 | [utils.interop :refer [js->clj' clj->js']] 5 | [ext.constants :as constants])) 6 | 7 | (defn show-quick-pick [options items] 8 | (let [pick-result (p/deferred)] 9 | (-> (.showQuickPick window (clj->js' items) (clj->js' options)) 10 | (.then #(p/resolve! pick-result %1) 11 | #(p/reject! pick-result %1))) 12 | (p/chain pick-result 13 | js->clj'))) 14 | 15 | 16 | (defn show-notification [text items] 17 | (let [pick-result (p/deferred)] 18 | (-> (apply (.-showInformationMessage window) (clj->js' (into [text] items))) 19 | (.then #(p/resolve! pick-result %1) 20 | #(p/reject! pick-result %1))) 21 | (p/chain pick-result 22 | js->clj'))) 23 | 24 | 25 | (defn create-log-output-channel [] 26 | (.createOutputChannel window constants/log-channel)) 27 | 28 | (defn write-log [^OutputChannel channel text] 29 | (.appendLine channel text)) 30 | -------------------------------------------------------------------------------- /.github/workflows/publish.yml: -------------------------------------------------------------------------------- 1 | name: 'Release Extension' 2 | 3 | on: 4 | push: 5 | tags: 6 | - '*' 7 | 8 | jobs: 9 | build: 10 | 11 | runs-on: ubuntu-latest 12 | 13 | strategy: 14 | matrix: 15 | node-version: [22.x] 16 | 17 | steps: 18 | - uses: actions/checkout@v1 19 | - name: Use Node.js ${{ matrix.node-version }} 20 | uses: actions/setup-node@v1 21 | with: 22 | node-version: ${{ matrix.node-version }} 23 | - name: Use JDK 24 | uses: actions/setup-java@v1 25 | with: 26 | java-version: 17 27 | - name: Install and Build 28 | run: | 29 | npm install 30 | npm run compile 31 | - name: Publish to Open VSX Registry 32 | continue-on-error: true 33 | uses: HaaLeo/publish-vscode-extension@v0 34 | with: 35 | pat: ${{ secrets.OPEN_VSC_PUBLISH_TOKEN }} 36 | - name: Publish to Visual Studio Marketplace 37 | continue-on-error: true 38 | uses: HaaLeo/publish-vscode-extension@v0 39 | with: 40 | pat: ${{ secrets.VSC_PUBLISH_TOKEN }} 41 | registryUrl: https://marketplace.visualstudio.com 42 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019 Roman Valihura 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /src/main/config.cljs: -------------------------------------------------------------------------------- 1 | (ns config 2 | (:require [vscode.workspace :as workspace] 3 | [utils.helpers :refer [render-workspace]])) 4 | 5 | (defonce config (atom {})) 6 | 7 | (defonce vscode-config (workspace/get-configuration)) 8 | 9 | (defn update-config! [] 10 | (let [workspace-root (first (workspace/get-folders))] 11 | (reset! config {:workspace-root workspace-root 12 | :nix-file (-> (workspace/config-get vscode-config :nix-env-selector/nix-file) 13 | (#(when %1 (render-workspace %1 workspace-root)))) 14 | :suggest-nix? (workspace/config-get vscode-config :nix-env-selector/suggestion) 15 | :nix-packages (workspace/config-get vscode-config :nix-env-selector/packages) 16 | :nix-args (-> (workspace/config-get vscode-config :nix-env-selector/args) 17 | (#(when %1 (render-workspace %1 workspace-root)))) 18 | :nix-shell-path (-> (workspace/config-get vscode-config :nix-env-selector/nix-shell-path) 19 | (#(when %1 (render-workspace %1 workspace-root)))) 20 | :use-flakes (workspace/config-get vscode-config :nix-env-selector/use-flakes)}))) 21 | 22 | (workspace/on-config-change update-config!) 23 | -------------------------------------------------------------------------------- /src/main/vscode/workspace.cljs: -------------------------------------------------------------------------------- 1 | (ns vscode.workspace 2 | (:require ["vscode" :refer [workspace]] 3 | [utils.interop :refer [js->clj' keyword-to-path]] 4 | [promesa.core :as p])) 5 | 6 | (set! *warn-on-infer* false) 7 | 8 | (defn ^:private config-target->number [target] 9 | (cond 10 | (= target :global) 1 11 | (= target :workspace) 2 12 | (= target :workspace-folder) 3 13 | :else (throw (js/Error "Wrong target for updating config.")))) 14 | 15 | (defn ^:private uri-to-string [js-uri] 16 | (.-path js-uri)) 17 | 18 | (defn get-folders [] 19 | (->> (js->clj' (.-workspaceFolders workspace)) 20 | (map (comp uri-to-string :uri)))) 21 | 22 | (defn get-configuration [] 23 | (.getConfiguration workspace)) 24 | 25 | (defn config-get [config param] 26 | (let [js-param (keyword-to-path param)] 27 | (.get config js-param))) 28 | 29 | (defn config-set! [config target key value] 30 | (let [update-result (p/deferred) 31 | target (config-target->number target) 32 | path (keyword-to-path key)] 33 | (-> (.update config path value target) 34 | (.then #(p/resolve! update-result %1)) 35 | (.catch #(p/reject! update-result %1))) 36 | update-result)) 37 | 38 | (defn on-config-change [handler-fn] 39 | (.onDidChangeConfiguration workspace 40 | (fn [_] 41 | (handler-fn)))) 42 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Change Log 2 | 3 | All notable changes to the extension will be documented in this file. 4 | 5 | ## [1.0.0] 6 | 7 | - Rewrite codebase with ClojureScript from scratch 8 | 9 | - Add notification that proposes to use nix config, if the last one is available in the workspace [[ISSUE-28](https://github.com/arrterian/nix-env-selector/issues/28)] 10 | 11 | - Add config parameter `packages` as an alternative to nix-file configuration [[ISSUE-12](https://github.com/arrterian/nix-env-selector/issues/12)] 12 | 13 | - Add ability to pass custom arguments to nix-shell through `args` config parameter [[ISSUE-27](https://github.com/arrterian/nix-env-selector/issues/27)] 14 | 15 | - Add ability to pass custom arguments to nix-shell through `args` config parameter [[ISSUE-27](https://github.com/arrterian/nix-env-selector/issues/27)] 16 | 17 | - Add ability to pass the custom path to `nix-shell` utility through config's `nixShellConfig` parameter [[ISSUE-38](https://github.com/arrterian/nix-env-selector/issues/38)] 18 | 19 | - Fix bug with misbehaving when spaces were presented in nix-config path [[ISSUE-41](https://github.com/arrterian/nix-env-selector/issues/41)] 20 | 21 | ## [0.1.3] 22 | 23 | - Reword README 24 | - Fix typos in the descriptions of config settings 25 | 26 | ## [0.1.2] 27 | 28 | - Update `mocha` to `7.1.1` 29 | 30 | ## [0.1.1] 31 | 32 | - The extension tested under Windows platform. (Thank you [Rasmus Eskola](https://github.com/FruitieX)) 33 | 34 | ## [0.1.0] 35 | 36 | - Add ability use nix-shell with custom attribute parameter (David Turnbull) 37 | 38 | ## [Experimental Release] 39 | 40 | - Initial release 41 | -------------------------------------------------------------------------------- /src/main/main.cljs: -------------------------------------------------------------------------------- 1 | (ns main 2 | (:require [config :refer [config update-config!]] 3 | [promesa.core :as p] 4 | [vscode.status-bar :as status] 5 | [vscode.context :refer [subsciribe]] 6 | [vscode.command :as cmd] 7 | [vscode.window :as w] 8 | [ext.actions :as act] 9 | [ext.nix-env :as env] 10 | [ext.lang :refer [lang]] 11 | [utils.helpers :refer [render-env-status]])) 12 | 13 | (defn activate [ctx] 14 | (let [log-channel (w/create-log-output-channel)] 15 | (w/write-log log-channel "Initializing config...") 16 | (update-config!) 17 | (w/write-log log-channel (str "Loaded config: " @config)) 18 | (let [status-bar (status/create :left 100)] 19 | (if (or (not-empty (:nix-file @config)) (not-empty (:nix-packages @config))) 20 | (try 21 | (-> (env/get-nix-env-sync {:nix-config (:nix-file @config) 22 | :packages (:nix-packages @config) 23 | :args (:nix-args @config) 24 | :nix-shell-path (:nix-shell-path @config) 25 | :use-flakes (:use-flakes @config)} 26 | log-channel) 27 | (env/set-current-env)) 28 | (->> status-bar 29 | (status/show {:text (render-env-status lang (:nix-file @config)) 30 | :command :nix-env-selector/select-env})) 31 | (catch :default e 32 | (w/write-log log-channel (str "Error applying environment: " e)))) 33 | 34 | ;; show notification that nix config available 35 | ;; if workspace contains .nix file(s) 36 | (p/chain (act/get-nix-files (:workspace-root @config)) 37 | #(when (and (:suggest-nix? @config) 38 | (> (count %1) 0)) 39 | (act/show-propose-env-dialog log-channel)))) 40 | 41 | ;; register user commands 42 | (subsciribe ctx (cmd/create :nix-env-selector/select-env (act/select-nix-environment status-bar log-channel))) 43 | (subsciribe ctx (cmd/create :nix-env-selector/hit-env (act/hit-nix-environment status-bar log-channel)))))) 44 | 45 | (defn deactivate []) 46 | -------------------------------------------------------------------------------- /src/main/utils/interop.cljs: -------------------------------------------------------------------------------- 1 | (ns utils.interop 2 | (:require [camel-snake-kebab.core :refer [->kebab-case-keyword ->camelCaseKeyword ->camelCaseString]] 3 | [clojure.walk :refer [postwalk]] 4 | [goog.object :as obj])) 5 | 6 | (defn ^:private numeric-string? [s] 7 | (and (string? s) 8 | (some? (re-matches #"[0-9]+" s)))) 9 | (defn ^:private pascal-case? [s] 10 | (and (string? s) 11 | (contains? #{\A \B \C \D \E \F \G \H \I \J \K \L \M \N \O \P \Q \R \S \T \U \V \W \X \Y \Z} 12 | (first s)))) 13 | 14 | (defn ^:private key->str [k] 15 | (let [n (name k)] 16 | (cond 17 | (pascal-case? n) n 18 | :else (->camelCaseString k)))) 19 | 20 | (defn ^:private convert-map-keys [m f] 21 | (postwalk (fn [x] 22 | (if (map-entry? x) 23 | [(f (key x)) (val x)] 24 | x)) 25 | m)) 26 | 27 | 28 | (defn clj->js' 29 | [obj] 30 | (clj->js (convert-map-keys obj (fn [k] 31 | (if (keyword? k) 32 | (key->str k) 33 | k))))) 34 | 35 | (defn ^:private js-key->clj [k] 36 | (cond 37 | (keyword? k) k 38 | (numeric-string? k) (js/parseInt k) 39 | (pascal-case? k) (keyword k) 40 | :else (->kebab-case-keyword k))) 41 | 42 | (defn js->clj' 43 | [obj] 44 | (let [convert (fn convert [x] 45 | (cond 46 | (seq? x) 47 | (doall (map convert x)) 48 | 49 | (map-entry? x) 50 | (MapEntry. (convert (key x)) (convert (val x)) nil) 51 | 52 | (coll? x) 53 | (into (empty x) (map convert) x) 54 | 55 | (array? x) 56 | (persistent! 57 | (reduce #(conj! %1 (convert %2)) 58 | (transient []) x)) 59 | 60 | (identical? (type x) js/Object) 61 | (persistent! 62 | (reduce (fn [r k] 63 | (if (= "ref" k) 64 | (assoc! r :ref (obj/get x k)) 65 | (assoc! r (js-key->clj k) (convert (obj/get x k))))) 66 | (transient {}) (js-keys x))) 67 | :else x))] 68 | (convert obj))) 69 | 70 | (defn keyword-to-path [key] 71 | (str 72 | (->camelCaseString (namespace key)) 73 | "." 74 | (->camelCaseString (name key)))) -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "nix-env-selector", 3 | "displayName": "Nix Environment Selector", 4 | "description": "Allows switch environment for Visual Studio Code and extensions based on Nix config file.", 5 | "version": "1.1.0", 6 | "keywords": [ 7 | "nix", 8 | "nix-env", 9 | "nix-shell", 10 | "vscode" 11 | ], 12 | "license": "MIT", 13 | "publisher": "arrterian", 14 | "author": { 15 | "name": "Roman Valihura", 16 | "email": "roman.valihura@gmail.com" 17 | }, 18 | "icon": "resources/icon.png", 19 | "engines": { 20 | "vscode": "^1.97.0" 21 | }, 22 | "repository": { 23 | "type": "git", 24 | "url": "https://github.com/arrterian/nix-env-selector.git" 25 | }, 26 | "categories": [ 27 | "Other" 28 | ], 29 | "activationEvents": [ 30 | "*", 31 | "onLanguage" 32 | ], 33 | "main": "./dist/index.js", 34 | "contributes": { 35 | "configuration": { 36 | "title": "Nix Environment Selector", 37 | "properties": { 38 | "nixEnvSelector.nixFile": { 39 | "type": "string", 40 | "default": null, 41 | "description": "Path for nix-shell config" 42 | }, 43 | "nixEnvSelector.suggestion": { 44 | "type": "boolean", 45 | "default": true, 46 | "description": "Shows message with proposal to select env (if available)" 47 | }, 48 | "nixEnvSelector.args": { 49 | "type": "string", 50 | "default": null, 51 | "description": "Additional args for nix-shell (EX: -A some.thing)" 52 | }, 53 | "nixEnvSelector.packages": { 54 | "type": "array", 55 | "default": [], 56 | "description": "Attr for nix-shell config" 57 | }, 58 | "nixEnvSelector.nixShellPath": { 59 | "type": "string", 60 | "default": null, 61 | "description": "Custom path to nix-shell executable" 62 | }, 63 | "nixEnvSelector.nixShellConfig": { 64 | "type": "string", 65 | "deprecationMessage": "[DEPRECATED] Use 'nixFile' instead", 66 | "description": "Path for nix-shell config" 67 | }, 68 | "nixEnvSelector.nixShellConfigAttr": { 69 | "type": "string", 70 | "deprecationMessage": "[DEPRECATED] Use 'args' instead", 71 | "description": "Attribute path (nix-shell -A)" 72 | }, 73 | "nixEnvSelector.useFlakes": { 74 | "type": "boolean", 75 | "default": false, 76 | "description": "Enable support for Nix flakes" 77 | } 78 | } 79 | }, 80 | "commands": [ 81 | { 82 | "command": "nixEnvSelector.selectEnv", 83 | "title": "Nix-Env: Select environment" 84 | }, 85 | { 86 | "command": "nixEnvSelector.hitEnv", 87 | "title": "Nix-Env: Hit environment" 88 | } 89 | ] 90 | }, 91 | "scripts": { 92 | "vscode:prepublish": "echo ***DONE***", 93 | "bundle": "esbuild --bundle dist/main.js --outfile=dist/index.js --external:vscode --platform=node --format=cjs --loader:.svg=file && rm dist/main.js", 94 | "compile": "shadow-cljs release extension && npm run bundle", 95 | "watch": "shadow-cljs watch extension" 96 | }, 97 | "devDependencies": { 98 | "@types/vscode": "^1.97.0", 99 | "@vscode/test-electron": "^2.4.1", 100 | "esbuild": "^0.25.0", 101 | "shadow-cljs": "2.28.21" 102 | } 103 | } 104 | -------------------------------------------------------------------------------- /CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | # Contributor Covenant Code of Conduct 2 | 3 | ## Our Pledge 4 | 5 | In the interest of fostering an open and welcoming environment, we as 6 | contributors and maintainers pledge to making participation in our project and 7 | our community a harassment-free experience for everyone, regardless of age, body 8 | size, disability, ethnicity, sex characteristics, gender identity and expression, 9 | level of experience, education, socio-economic status, nationality, personal 10 | appearance, race, religion, or sexual identity and orientation. 11 | 12 | ## Our Standards 13 | 14 | Examples of behavior that contributes to creating a positive environment 15 | include: 16 | 17 | * Using welcoming and inclusive language 18 | * Being respectful of differing viewpoints and experiences 19 | * Gracefully accepting constructive criticism 20 | * Focusing on what is best for the community 21 | * Showing empathy towards other community members 22 | 23 | Examples of unacceptable behavior by participants include: 24 | 25 | * The use of sexualized language or imagery and unwelcome sexual attention or 26 | advances 27 | * Trolling, insulting/derogatory comments, and personal or political attacks 28 | * Public or private harassment 29 | * Publishing others' private information, such as a physical or electronic 30 | address, without explicit permission 31 | * Other conduct which could reasonably be considered inappropriate in a 32 | professional setting 33 | 34 | ## Our Responsibilities 35 | 36 | Project maintainers are responsible for clarifying the standards of acceptable 37 | behavior and are expected to take appropriate and fair corrective action in 38 | response to any instances of unacceptable behavior. 39 | 40 | Project maintainers have the right and responsibility to remove, edit, or 41 | reject comments, commits, code, wiki edits, issues, and other contributions 42 | that are not aligned to this Code of Conduct, or to ban temporarily or 43 | permanently any contributor for other behaviors that they deem inappropriate, 44 | threatening, offensive, or harmful. 45 | 46 | ## Scope 47 | 48 | This Code of Conduct applies both within project spaces and in public spaces 49 | when an individual is representing the project or its community. Examples of 50 | representing a project or community include using an official project e-mail 51 | address, posting via an official social media account, or acting as an appointed 52 | representative at an online or offline event. Representation of a project may be 53 | further defined and clarified by project maintainers. 54 | 55 | ## Enforcement 56 | 57 | Instances of abusive, harassing, or otherwise unacceptable behavior may be 58 | reported by contacting the project team at roman.valihura@gmail.com. All 59 | complaints will be reviewed and investigated and will result in a response that 60 | is deemed necessary and appropriate to the circumstances. The project team is 61 | obligated to maintain confidentiality with regard to the reporter of an incident. 62 | Further details of specific enforcement policies may be posted separately. 63 | 64 | Project maintainers who do not follow or enforce the Code of Conduct in good 65 | faith may face temporary or permanent repercussions as determined by other 66 | members of the project's leadership. 67 | 68 | ## Attribution 69 | 70 | This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, 71 | available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html 72 | 73 | [homepage]: https://www.contributor-covenant.org 74 | 75 | For answers to common questions about this code of conduct, see 76 | https://www.contributor-covenant.org/faq 77 | -------------------------------------------------------------------------------- /src/main/ext/nix_env.cljs: -------------------------------------------------------------------------------- 1 | (ns ext.nix-env 2 | (:require ["child_process" :refer [exec execSync]] 3 | ["path" :refer [dirname]] 4 | [clojure.string :as s] 5 | [promesa.core :as p] 6 | [vscode.window :as w])) 7 | 8 | (defn ^:private list-to-args [pref-arg list] 9 | (s/join " " (map #(str pref-arg " " %1) list))) 10 | 11 | (defn ^:private has-flake? [dir] 12 | (let [fs (js/require "fs")] 13 | (try 14 | (.existsSync fs (str dir "/flake.nix")) 15 | (catch js/Error _ 16 | false)))) 17 | 18 | (defn ^:private get-shell-env-cmd [{:keys [packages 19 | nix-shell-path 20 | nix-config 21 | args]}] 22 | (str (if (empty? nix-shell-path) 23 | "nix-shell" 24 | (s/replace nix-shell-path #" " "\\ ")) 25 | " " 26 | (cond 27 | (not-empty nix-config) 28 | (str "\"" nix-config "\"") 29 | 30 | (not-empty packages) 31 | (list-to-args "-p" packages) 32 | 33 | :else 34 | (throw (js/Error. "Nix-config or list of packages is necessary"))) 35 | " --run export" 36 | (when args 37 | (str " " args)))) 38 | 39 | (defn ^:private get-flake-env-cmd [{:keys [nix-path dir args]}] 40 | (str (if (empty? nix-path) 41 | "nix" 42 | (s/replace nix-path #" " "\\ ")) 43 | " develop " 44 | (when dir 45 | (str "\"" dir "\"")) 46 | " --command env" 47 | (when args 48 | (str " " args)))) 49 | 50 | (defn ^:private parse-exported-vars [output] 51 | (->> (s/split output #"declare -x") 52 | (filter not-empty) 53 | (map #(-> (s/split (s/trim %1) #"=" 2) 54 | ((fn [[name value]] 55 | [name (try 56 | (js/JSON.parse value) 57 | (catch js/Error _ nil))])))) 58 | (filter not-empty))) 59 | 60 | (defn ^:private parse-env-vars [output] 61 | (->> (s/split output #"\n") 62 | (filter not-empty) 63 | (map #(s/split %1 #"=" 2)) 64 | (filter #(= (count %) 2)) 65 | (map (fn [[name value]] 66 | [name value])))) 67 | 68 | (defn get-nix-env-sync [{:keys [use-flakes] :as options} log-channel] 69 | (let [dir (dirname (:nix-config options)) 70 | is-flake (and use-flakes (has-flake? dir)) 71 | cmd (if is-flake 72 | (get-flake-env-cmd (assoc options :dir dir)) 73 | (get-shell-env-cmd options)) 74 | parser (if is-flake parse-env-vars parse-exported-vars)] 75 | (w/write-log log-channel (str "Running command synchronously: " cmd)) 76 | (-> (execSync (clj->js cmd {:cwd dir})) 77 | (.toString) 78 | (parser)))) 79 | 80 | (defn get-nix-env-async [{:keys [use-flakes] :as options} log-channel] 81 | (let [env-result (p/deferred) 82 | dir (dirname (:nix-config options)) 83 | is-flake (and use-flakes (has-flake? dir)) 84 | cmd (if is-flake 85 | (get-flake-env-cmd (assoc options :dir dir)) 86 | (get-shell-env-cmd options)) 87 | parser (if is-flake parse-env-vars parse-exported-vars)] 88 | (w/write-log log-channel (str "Running command " (if is-flake "with flake" "with nix-shell") ": " cmd)) 89 | (exec (clj->js cmd {:cwd dir}) 90 | (fn [err result stderr] 91 | (if (nil? err) 92 | (p/resolve! env-result result) 93 | (do 94 | (w/write-log log-channel (str "Error applying environment: " stderr)) 95 | (p/reject! env-result err))))) 96 | (p/map parser env-result))) 97 | 98 | (defn set-current-env [env-vars] 99 | (mapv (fn [[name value]] 100 | (aset js/process.env name value)) 101 | env-vars)) 102 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # 🇺🇦 Support Ukraine 🇺🇦 2 | Hi folks, 3 | My name is Roman Valihura. I'm the author of this extension. I'm Ukrainian. 4 | I was born in Ukraine. I'm living here at the moment. 5 | 6 | As you all know Russia invaded my country. 7 | Russia has already killed thousands of civilians and continues the war and terror in Ukraine. 8 | I have the luck that my region is pretty far from the frontline. But even here, I'm living in the air-alarm reality. 9 | The reality where you should wake up in the middle of the night and go into the shelter. Because a rocket flies over your region. 10 | 11 | 12 | Like a lot of Ukrainians now I became a volunteer in this hard time for my country. 13 | We with a team producing Individual First Aid Kits for the Ukrainian army. 14 | If you have a wish and ability to support the activity, you can make a donation on our website, which we made to collect funds for producing First Aid Kits. 15 | 16 | More datails on the [aidkit.shop](https://aidkit.shop) 17 | 18 | Thank you for your attention! 19 | 20 | 21 | # Nix Environment Selector 22 | 23 |

24 | nix-env-selector-logo 29 |

30 | 31 |

32 | Extension that lets you use environments declared in .nix files in Visual Studio Code. 33 |

34 | 35 | ## Motivation 36 | 37 | Nix package manager provides a way of creating isolated 38 | environments with a specific configuration of packages. 39 | These environments are usually activated in the terminal 40 | and are not convenient to use within an IDE. 41 | 42 | One option is to run `nix-shell` on the command line and then 43 | launch `code` within the activated shell. 44 | However, this process can quickly become tedious. 45 | `Nix Environment Selector` provides an alternative: can automatically apply the environment. 46 | 47 | ## Getting started 48 | 49 | - Install [Nix package manager](https://nixos.org/nix/). 50 | - Restart VS Code (to make sure that `nix-shell` is in the PATH) 51 | - [Install the extension](https://marketplace.visualstudio.com/items?itemName=arrterian.nix-env-selector). 52 | - Create the Nix environment config (like `default.nix` or `shell.nix` or `flake.nix`) in 53 | the root of your project's workspace. 54 | - Open Command Palette (Ctrl + Shift + P) 55 | and run `Nix-Env: Select Environment` command. 56 | - Choose the Nix environment you'd like to apply. 57 | - Wait for the environment to build. 58 | - Restart VS Code to apply the built environment. 59 | 60 | ## Example 61 | 62 | ### Haskell project 63 | 64 | To run a Haskell application you need to have **GHC** (Haskell compiler) installed. 65 | With Nix package manager we can create an isolated environment containing only 66 | the GHC version and the dependencies that the project needs without 67 | polluting the user's environment. 68 | 69 | Environment configuration in `shell.nix`: 70 | 71 | ```nix 72 | { pkgs ? import { } }: 73 | with pkgs; 74 | 75 | let 76 | haskellDeps = ps: with ps; [ 77 | base 78 | lens 79 | mtl 80 | random 81 | ]; 82 | haskellEnv = haskell.packages.ghc865.ghcWithPackages haskellDeps; 83 | in mkShell { 84 | buildInputs = [ 85 | haskellEnv 86 | haskellPackages.cabal-install 87 | gdb 88 | ]; 89 | } 90 | ``` 91 | 92 | Now let's try to open our project in Visual Studio Code. 93 | 94 | ![Without Env Demo](resources/without-env-demo.gif) 95 | 96 | As you can see VS Code can't find the GHC compiler. Let's apply 97 | the environment declared in `shell.nix`. 98 | 99 | ![With Env Demo](resources/with-env-demo.gif) 100 | 101 | Bingo 🎉🎉🎉. Everything is working now 😈 102 | 103 | ## Configuration 104 | 105 | You can configure the extension in `.vscode/settings.json` 106 | file (located in the root of the workspace). Here are the configuration settings: 107 | 108 | | Setting | Default | Description | 109 | | ----------------------------- | ------- | ------------------------------------------------------------- | 110 | | `nixEnvSelector.nixFile` | null | Path to the Nix config file | 111 | | `nixEnvSelector.packages` | [] | List packages using as `-p` nix-shell args | 112 | | `nixEnvSelector.args` | null | Custom args string for nix-shell. EX: `-A --pure` | 113 | | `nixEnvSelector.nixShellPath` | null | Custom path for nix-shell executable | 114 | | `nixEnvSelector.useFlakes` | false | Enable support for `flake.nix` | 115 | 116 | 117 | ## Supported Platforms 118 | 119 | - MacOS 120 | - Linux 121 | - Windows (with `Remote - WSL` extension) 122 | 123 | ## Support 124 | 125 | If you like the extension and want to support author, click the button bellow. 126 | 127 | 130 | donate 135 | 136 | 137 | ## License 138 | 139 | [MIT](LICENSE) 140 | -------------------------------------------------------------------------------- /src/main/ext/actions.cljs: -------------------------------------------------------------------------------- 1 | (ns ext.actions 2 | (:require ["fs" :refer [readdir]] 3 | [config :refer [config vscode-config]] 4 | [vscode.window :as w] 5 | [vscode.command :as cmd] 6 | [vscode.workspace :as workspace] 7 | [vscode.status-bar :as status-bar] 8 | [ext.lang :as l] 9 | [ext.nix-env :as env] 10 | [promesa.core :as p] 11 | [utils.helpers :refer [unrender-workspace]])) 12 | 13 | (defn get-nix-files [workspace-root] 14 | (let [files-res (p/deferred)] 15 | (readdir workspace-root 16 | (fn [err result] 17 | (if (nil? err) 18 | (p/resolve! files-res result) 19 | (p/reject! files-res err)))) 20 | (p/map #(filter (fn [file] 21 | (-> (re-matches #"(?i).*\.nix" file) 22 | (nil?) 23 | (not))) %1) 24 | files-res))) 25 | 26 | (defn show-propose-env-dialog [log-channel] 27 | (let [select-label (-> l/lang :label :select-env) 28 | dismiss-label (-> l/lang :label :dismiss) 29 | dialog (w/show-notification (-> l/lang :notification :env-available) 30 | [select-label dismiss-label])] 31 | (p/mapcat dialog 32 | #((cond 33 | (= select-label %1) (cmd/execute :nix-env-selector/select-env log-channel) 34 | (= dismiss-label %1) (workspace/config-set! vscode-config 35 | :workspace 36 | :nix-env-selector/suggestion 37 | false)))))) 38 | 39 | (defn show-reload-dialog [] 40 | (let [reload-message (-> l/lang :notification :env-applied)] 41 | (w/show-notification reload-message []))) 42 | 43 | (defn load-env-by-path [nix-path status log-channel] 44 | (when nix-path 45 | (w/write-log log-channel (str "Loading env in path: " nix-path)) 46 | (status-bar/show {:text (-> l/lang :label :env-loading)} 47 | status) 48 | (->> (env/get-nix-env-async {:nix-config nix-path 49 | :args (:nix-args @config) 50 | :nix-shell-path (:nix-shell-path @config) 51 | :use-flakes (:use-flakes @config)} 52 | log-channel) 53 | (p/map (fn [env-vars] 54 | (when env-vars 55 | (env/set-current-env env-vars) 56 | :ok))) 57 | (p/map (fn [result] 58 | (when result 59 | (status-bar/show {:text (-> l/lang :label :env-need-reload) 60 | :command :nix-env-selector/select-env} status)))) 61 | (p/mapcat show-reload-dialog)))) 62 | 63 | (defn hit-nix-environment [status log-channel] 64 | (w/write-log log-channel "Running action: Hit environment") 65 | (fn [] 66 | (-> (:nix-file @config) 67 | (load-env-by-path status log-channel)))) 68 | 69 | (defn select-nix-environment [status log-channel] 70 | (w/write-log log-channel "Running action: Select environment") 71 | (fn [] 72 | (->> (get-nix-files (:workspace-root @config)) 73 | (p/mapcat #(w/show-quick-pick {:place-holder (-> l/lang :label :select-config-placeholder)} 74 | (into [{:id "disable" 75 | :label (-> l/lang :label :disabled-nix)}] 76 | (map (fn [file-name] 77 | {:id file-name 78 | :label file-name}) %1)))) 79 | (p/map (fn [nix-file-name] 80 | (cond 81 | (= "disable" (:id nix-file-name)) 82 | (do 83 | (w/write-log log-channel "Selected to disable Nix environment") 84 | (status-bar/hide status) 85 | (workspace/config-set! vscode-config 86 | :workspace 87 | :nix-env-selector/nix-file 88 | js/undefined) 89 | (workspace/config-set! vscode-config 90 | :workspace 91 | :nix-env-selector/suggestion 92 | false)) 93 | 94 | (not-empty nix-file-name) 95 | (let [nix-file (str (:workspace-root @config) "/" (:id nix-file-name))] 96 | (w/write-log log-channel (str "Selected Nix file: " nix-file)) 97 | (workspace/config-set! vscode-config 98 | :workspace 99 | :nix-env-selector/nix-file 100 | (unrender-workspace nix-file (:workspace-root @config))) 101 | nix-file)))) 102 | (p/mapcat #(load-env-by-path %1 status log-channel)) 103 | (p/error #(js/console.error %))))) 104 | --------------------------------------------------------------------------------