fresh-editor 0.1.64

A lightweight, fast terminal-based text editor with LSP support and TypeScript plugins
Documentation
{
  description = "Fresh - A lightweight, fast terminal-based text editor with LSP support and TypeScript plugins";

  inputs = {
    nixpkgs.url = "github:NixOS/nixpkgs/nixpkgs-unstable";
    systems.url = "github:nix-systems/default";
    crane.url = "github:ipetkov/crane";
    fenix = {
      url = "github:nix-community/fenix";
      inputs.nixpkgs.follows = "nixpkgs";
    };
    flake-utils = {
      url = "github:numtide/flake-utils";
      inputs.systems.follows = "systems";
    };
  };

  outputs =
    {
      self,
      nixpkgs,
      crane,
      fenix,
      flake-utils,
      ...
    }:
    flake-utils.lib.eachDefaultSystem (
      system:
      let
        inherit (nixpkgs) lib;
        pkgs = import nixpkgs { inherit system; };

        rustToolchain = fenix.packages.${system}.stable.withComponents [
          "cargo"
          "clippy"
          "rust-src"
          "rustc"
          "rustfmt"
        ];
        craneLib = (crane.mkLib pkgs).overrideToolchain rustToolchain;

        # Source filtering: include Cargo files plus additional files
        unfilteredRoot = ./.; # The original, unfiltered source
        src = lib.fileset.toSource {
          root = unfilteredRoot;
          fileset = lib.fileset.unions [
            # Default files from crane (Rust and cargo files)
            (craneLib.fileset.commonCargoSources unfilteredRoot)
            # Also keep any javascript files
            (lib.fileset.fileFilter (file: file.hasExt "js") unfilteredRoot)
            # Keep sublime-syntax grammar files (used by include_str! in grammar_registry.rs)
            (lib.fileset.fileFilter (file: file.hasExt "sublime-syntax") unfilteredRoot)
            ./docs
            ./keymaps
            ./plugins
            ./queries
            ./tests
            ./themes
            ./types
          ];
        };

        # Prefetch rusty_v8 static library to avoid network access during build
        # We validate the hash on the compressed download, then decompress for rusty_v8
        librusty_v8 =
          let
            tag = "142.2.0";
            target = pkgs.stdenv.hostPlatform.rust.rustcTarget;
            hashes = {
              x86_64-unknown-linux-gnu = "sha256-xHmofo8wTNg88/TuC2pX2OHDRYtHncoSvSBnTV65o+0=";
              aarch64-unknown-linux-gnu = "sha256-24q6wX8RTRX1tMGqgcz9/wN3Y+hWxM2SEuVrYhECyS8=";
              x86_64-apple-darwin = "sha256-u7fImeadycU1gS5m+m35WZA/G2SOdPrLOMafY54JwY4=";
              aarch64-apple-darwin = "sha256-XvJ7M5XxOzmevv+nPpy/mvEDD1MfHr986bImvDG0o4U=";
            };
          in
          pkgs.stdenv.mkDerivation {
            name = "librusty_v8-${tag}";
            src = pkgs.fetchurl {
              url = "https://github.com/denoland/rusty_v8/releases/download/v${tag}/librusty_v8_release_${target}.a.gz";
              sha256 = hashes.${target};
            };
            nativeBuildInputs = [ pkgs.gzip ];
            dontUnpack = true;
            installPhase = ''
              gzip -d -c $src > $out
            '';
          };

        # Common arguments for crane builds
        commonArgs = {
          inherit src;
          strictDeps = true;

          nativeBuildInputs = with pkgs; [
            pkg-config
            # For tree-sitter grammars that need C compilation
            clang
          ];

          doCheck = false;
        }
        // commonVars;

        commonVars = {
          # Environment variables
          LIBCLANG_PATH = pkgs.lib.makeLibraryPath [
            pkgs.llvmPackages.libclang.lib
          ];
          # Point to prefetched rusty_v8 library to avoid download during build
          RUSTY_V8_ARCHIVE = librusty_v8;
        };

        # Build dependencies separately for better caching
        cargoArtifacts = craneLib.buildDepsOnly commonArgs;

        # Build the actual package
        fresh = craneLib.buildPackage (
          commonArgs
          // {
            inherit cargoArtifacts;

            # Include runtime assets
            postInstall = ''
              mkdir -p $out/share/fresh-editor

                cp -r queries $out/share/fresh-editor/
                cp -r themes $out/share/fresh-editor/
                cp -r keymaps $out/share/fresh-editor/
                cp -r plugins $out/share/fresh-editor/
            '';
          }
        );
      in
      {
        checks = {
          # Build the package as a check
          inherit fresh;

          # Run clippy
          fresh-clippy = craneLib.cargoClippy (
            commonArgs
            // {
              inherit cargoArtifacts;
              cargoClippyExtraArgs = "--all-targets -- --deny warnings";
            }
          );

          # Run tests
          fresh-test = craneLib.cargoTest (
            commonArgs
            // {
              inherit cargoArtifacts;
            }
          );

          # Check formatting
          fresh-fmt = craneLib.cargoFmt {
            inherit src;
          };
        };

        packages = {
          inherit fresh;
          default = fresh;
        };

        apps.default = {
          type = "app";
          program = "${fresh}/bin/fresh";
          meta.description = "Text editor for your terminal: easy, powerful and fast";
        };

        devShells.default = craneLib.devShell (
          commonVars
          // {
            # Inherit inputs from the main build
            checks = self.checks.${system};

            # Additional development tools
            packages = with pkgs; [
              rustToolchain
              cargo-watch
              cargo-edit

              tree-sitter

              # Useful for debugging
              lldb
            ];
          }
        );
      }
    );
}