|
1 | 1 | { |
2 | | - description = "Minimal reproducible R dev environment (no workspace save, no history)"; |
| 2 | + description = "Opiniated Flake for Developing R Software--for ISCAM"; |
3 | 3 |
|
4 | 4 | inputs = { |
5 | | - nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable"; |
| 5 | + nixpkgs.url = "github:NixOS/nixpkgs/nixpkgs-unstable"; # Unstable to get the latest version of R + packages. Pretty safe. |
6 | 6 | flake-utils.url = "github:numtide/flake-utils"; |
| 7 | + nix-vscode-extensions = { |
| 8 | + url = "github:nix-community/nix-vscode-extensions"; |
| 9 | + inputs.nixpkgs.follows = "nixpkgs"; |
| 10 | + inputs.flake-utils.follows = "flake-utils"; |
| 11 | + }; |
7 | 12 | }; |
8 | 13 |
|
9 | 14 | outputs = |
10 | 15 | { |
11 | 16 | self, |
12 | 17 | nixpkgs, |
13 | 18 | flake-utils, |
| 19 | + nix-vscode-extensions, |
14 | 20 | }: |
15 | | - flake-utils.lib.eachDefaultSystem ( |
| 21 | + flake-utils.lib.eachSystem [ "x86_64-linux" ] ( |
16 | 22 | system: |
17 | 23 | let |
18 | | - pkgs = import nixpkgs { inherit system; }; |
19 | | - Rnosave = pkgs.writeShellScriptBin "R" ( |
20 | | - let |
21 | | - r = pkgs.rWrapper.override { |
22 | | - packages = with pkgs.rPackages; [ |
23 | | - devtools |
24 | | - roxygen2 |
25 | | - testthat |
26 | | - usethis |
27 | | - pkgdown |
28 | | - languageserver |
29 | | - ]; |
| 24 | + pkgs = import nixpkgs { |
| 25 | + inherit system; |
| 26 | + config.allowUnfree = true; |
| 27 | + overlays = [ nix-vscode-extensions.overlays.default ]; |
| 28 | + }; |
| 29 | + |
| 30 | + # List the packages you wish to have installed instead of installing packages interactively |
| 31 | + # Useful links: |
| 32 | + # https://search.nixos.org/packages?channel=unstable&from=0&size=50&sort=relevance&type=packages&query=rPackages. |
| 33 | + # https://nixos.wiki/wiki/R#Install_an_R-package_from_GitHub |
| 34 | + rPkgs = with pkgs.rPackages; [ |
| 35 | + # ! NOTE: ADD YOUR R PACKAGES HERE |
| 36 | + devtools |
| 37 | + roxygen2 |
| 38 | + testthat |
| 39 | + usethis |
| 40 | + pkgdown |
| 41 | + languageserver |
| 42 | + lintr |
| 43 | + withr |
| 44 | + ]; |
| 45 | + |
| 46 | + rWithPkgs = pkgs.rWrapper.override { |
| 47 | + packages = rPkgs; |
| 48 | + }; |
| 49 | + |
| 50 | + # Minimal open-vsx extensions |
| 51 | + # Note that positron-bin will probably lag behind stable release, so extensions which target the latest version of code-oss may not work. |
| 52 | + # e.g. on 20250817, vscode-pull-request-github-116.1 reports that it "is not compatible with Code 1.102.0. Extension requires: ^1.103.0." |
| 53 | + # https://nix-community.github.io/nix4vscode/ |
| 54 | + extensions = with pkgs.open-vsx; [ |
| 55 | + # Default Positron extensions |
| 56 | + github.vscode-pull-request-github |
| 57 | + posit.air-vscode |
| 58 | + quarto.quarto |
| 59 | + |
| 60 | + # ! NOTE: ADD YOUR OPEN-VSX EXTENSIONS HERE |
| 61 | + eamodio.gitlens |
| 62 | + usernamehw.errorlens |
| 63 | + edwinhuish.better-comments-next |
| 64 | + tomoki1207.pdf |
| 65 | + tombi-toml.tombi |
| 66 | + oderwat.indent-rainbow |
| 67 | + robole.marky-stats |
| 68 | + |
| 69 | + # Catppuccin theme extensions |
| 70 | + catppuccin.catppuccin-vsc |
| 71 | + catppuccin.catppuccin-vsc-icons |
| 72 | + ]; |
| 73 | + |
| 74 | + # Declerative Positron settings.json |
| 75 | + # Clear settings by running: $ rm ~/.config/Positron/User/settings.json |
| 76 | + settingsJson = pkgs.writeText "settings.json" ( |
| 77 | + builtins.toJSON { |
| 78 | + "workbench.keybindings.rstudioKeybindings" = true; |
| 79 | + "workbench.colorTheme" = "Catppuccin Mocha"; |
| 80 | + "workbench.iconTheme" = "catppuccin-mocha"; |
| 81 | + "workbench.list.smoothScrolling" = true; |
| 82 | + |
| 83 | + "catppuccin.accentColor" = "pink"; |
| 84 | + |
| 85 | + "catppuccin.colorOverrides" = { |
| 86 | + "mocha" = { |
| 87 | + "base" = "#000000"; |
| 88 | + "mantle" = "#010101"; |
| 89 | + "crust" = "#020202"; |
| 90 | + }; |
30 | 91 | }; |
31 | | - in |
32 | | - '' |
33 | | - exec ${r}/bin/R --no-save --no-restore-data --no-restore-history "$@" |
34 | | - '' |
| 92 | + |
| 93 | + "catppuccin.customUIColors" = { |
| 94 | + "mocha" = { |
| 95 | + "statusBar.foreground" = "accent"; |
| 96 | + }; |
| 97 | + }; |
| 98 | + |
| 99 | + "git.autofetch" = true; |
| 100 | + "git.confirmSync" = false; |
| 101 | + |
| 102 | + "editor.formatOnSave" = true; |
| 103 | + "editor.fontFamily" = "JetBrainsMono Nerd Font"; |
| 104 | + "editor.fontLigatures" = true; |
| 105 | + "editor.semanticHighlighting.enabled" = true; |
| 106 | + "editor.pasteAs.preferences" = [ |
| 107 | + "typst.link" |
| 108 | + "markdown.link" |
| 109 | + ]; |
| 110 | + |
| 111 | + "terminal.integrated.fontFamily" = "IosevkaTerm Nerd Font"; |
| 112 | + |
| 113 | + "positron.plots.darkFilter" = "off"; |
| 114 | + |
| 115 | + "[r]" = { |
| 116 | + "editor.formatOnSave" = true; |
| 117 | + "editor.defaultFormatter" = "Posit.air-vscode"; |
| 118 | + }; |
| 119 | + "[quarto]" = { |
| 120 | + "editor.formatOnSave" = true; |
| 121 | + "editor.defaultFormatter" = "quarto.quarto"; |
| 122 | + }; |
| 123 | + } |
35 | 124 | ); |
| 125 | + |
| 126 | + # Symlink farm of extensions (read-only source) |
| 127 | + extensionsRO = pkgs.buildEnv { |
| 128 | + name = "positron-extensions"; |
| 129 | + paths = extensions; |
| 130 | + pathsToLink = [ "/share/vscode/extensions" ]; |
| 131 | + }; |
| 132 | + |
| 133 | + # FHS environment for Positron |
| 134 | + positronFHS = pkgs.buildFHSEnv { |
| 135 | + name = "positron-fhs"; |
| 136 | + targetPkgs = |
| 137 | + pkgs: with pkgs; [ |
| 138 | + # Core Positron and R |
| 139 | + positron-bin |
| 140 | + R |
| 141 | + air-formatter |
| 142 | + |
| 143 | + # Patched fonts |
| 144 | + nerd-fonts.iosevka-term |
| 145 | + nerd-fonts.jetbrains-mono |
| 146 | + |
| 147 | + # Basic system libraries for dynamic linking |
| 148 | + glibc |
| 149 | + gcc-unwrapped.lib |
| 150 | + stdenv.cc.cc.lib |
| 151 | + zlib |
| 152 | + git |
| 153 | + gcc |
| 154 | + gfortran |
| 155 | + pkg-config |
| 156 | + ]; |
| 157 | + |
| 158 | + runScript = pkgs.writeScript "positron-run" '' |
| 159 | + #!/bin/bash |
| 160 | + set -euo pipefail |
| 161 | +
|
| 162 | + EXT_BASE="''${XDG_CACHE_HOME:-$HOME/.cache}" |
| 163 | + EXT_DST="$EXT_BASE/positron/extensions" |
| 164 | + SRC="${extensionsRO}/share/vscode/extensions" |
| 165 | +
|
| 166 | + CONFIG_BASE="''${XDG_CONFIG_HOME:-$HOME/.config}" |
| 167 | + APP_ID="Positron" |
| 168 | + SETTINGS_DIR="$CONFIG_BASE/$APP_ID/User" |
| 169 | + SETTINGS_FILE="$SETTINGS_DIR/settings.json" |
| 170 | +
|
| 171 | + mkdir -p "$EXT_DST" "$SETTINGS_DIR" |
| 172 | +
|
| 173 | + # rm ~/.config/Positron/User/settings.json |
| 174 | + # Copy settings.json if it doesn't exist |
| 175 | + [ ! -f "$SETTINGS_FILE" ] && cp "${settingsJson}" "$SETTINGS_FILE" |
| 176 | +
|
| 177 | + # Sync extensions (copy if not exists) |
| 178 | + for s in "$SRC"/*; do |
| 179 | + [ -d "$s" ] || continue |
| 180 | + bn="$(basename "$s")" |
| 181 | + [ -d "$EXT_DST/$bn" ] || cp -r "$s" "$EXT_DST/$bn" |
| 182 | + done |
| 183 | +
|
| 184 | + # Set up environment |
| 185 | + export R_HOME='${pkgs.R}/lib/R' |
| 186 | + export R_LIBS_USER='${rWithPkgs}/lib/R/library' |
| 187 | + export PATH="${pkgs.R}/bin:${rWithPkgs}/bin:${pkgs.air-formatter}/bin:$PATH" |
| 188 | +
|
| 189 | + # Run Positron |
| 190 | + exec positron --extensions-dir "$EXT_DST" "$@" |
| 191 | + ''; |
| 192 | + }; |
| 193 | + |
| 194 | + positronWrapper = pkgs.writeShellScriptBin "positron-with-extensions" '' |
| 195 | + exec ${positronFHS}/bin/positron-fhs "$@" |
| 196 | + ''; |
| 197 | + |
| 198 | + rstudioWrapper = pkgs.writeShellScriptBin "rstudio-with-r" '' |
| 199 | + export R_HOME='${pkgs.R}/lib/R' |
| 200 | + export R_LIBS_USER='${rWithPkgs}/lib/R/library' |
| 201 | + export PATH="${pkgs.R}/bin:${rWithPkgs}/bin:${pkgs.air-formatter}/bin:$PATH" |
| 202 | + exec ${pkgs.rstudio}/bin/rstudio "$@" |
| 203 | + ''; |
36 | 204 | in |
37 | 205 | { |
| 206 | + packages.positron = positronWrapper; |
| 207 | + packages.rstudio = rstudioWrapper; |
| 208 | + |
| 209 | + apps.positron = { |
| 210 | + type = "app"; |
| 211 | + program = "${positronWrapper}/bin/positron-with-extensions"; |
| 212 | + meta = { |
| 213 | + description = "Positron IDE with R environment and extensions"; |
| 214 | + platforms = [ "x86_64-linux" ]; |
| 215 | + }; |
| 216 | + }; |
| 217 | + |
| 218 | + apps.rstudio = { |
| 219 | + type = "app"; |
| 220 | + program = "${rstudioWrapper}/bin/rstudio-with-r"; |
| 221 | + meta = { |
| 222 | + description = "RStudio IDE with R environment"; |
| 223 | + platforms = [ "x86_64-linux" ]; |
| 224 | + }; |
| 225 | + }; |
| 226 | + |
38 | 227 | devShells.default = pkgs.mkShell { |
39 | | - packages = [ |
40 | | - Rnosave |
41 | | - pkgs.gcc |
42 | | - pkgs.gfortran |
43 | | - pkgs.pkg-config |
44 | | - ]; |
45 | 228 | shellHook = '' |
46 | | - export R_LIBS_USER="$PWD/.Rlibs" |
47 | | - mkdir -p "$R_LIBS_USER" |
48 | | - export R_HISTFILE=/dev/null |
| 229 | + echo "Use: nix run .#positron or nix run .#rstudio" |
49 | 230 | ''; |
50 | 231 | }; |
51 | 232 | } |
|
0 commit comments