![]() |
VOOZH | about |
dotnet add package ClojureCLR.NRepl --version 0.1.0
NuGet\Install-Package ClojureCLR.NRepl -Version 0.1.0
<PackageReference Include="ClojureCLR.NRepl" Version="0.1.0" />
<PackageVersion Include="ClojureCLR.NRepl" Version="0.1.0" />Directory.Packages.props
<PackageReference Include="ClojureCLR.NRepl" />Project file
paket add ClojureCLR.NRepl --version 0.1.0
#r "nuget: ClojureCLR.NRepl, 0.1.0"
#:package ClojureCLR.NRepl@0.1.0
#addin nuget:?package=ClojureCLR.NRepl&version=0.1.0Install as a Cake Addin
#tool nuget:?package=ClojureCLR.NRepl&version=0.1.0Install as a Cake Tool
一个基于 C# 实现的 nREPL 服务器,专为 ClojureCLR 设计。支持 CIDER、Calva 等标准 nREPL 客户端。
Type/Member(例如 Enumerable/Where),前提是已 import 对应类型dotnet run --project cli/clojureCLR-nrepl-cli.csproj
服务器将在 127.0.0.1:1667 启动。
先安装 Clojure.Main(一次):
dotnet tool install --global Clojure.Main --version 1.12.3-alpha4
准备依赖与本地构建(一次):
dotnet build -c Debug clojureCLR-nrepl.csproj
dotnet restore examples/clojureclr-demo.csproj
运行:
Clojure.Main -i examples/run-core.clj -e "(demo.run-core/-main)"
可选环境变量:
NREPL_ENABLE(默认开启;设为 0/false 可禁用)NREPL_HOST(默认 127.0.0.1)NREPL_PORT(默认 1667)注意:clojure.core.async.clrfix 在 CLR 上依赖 clojure.tools.analyzer.clr。以上脚本会从本机 NuGet cache 加载两者。
依赖清单(与 examples/run-core.clj 保持一致):
clojure.core.async.clrfix 1.7.701-clrfix2clojure.tools.analyzer.clr 1.3.2clojure.tools.analyzer 1.1.1clojure.tools.reader 1.3.7clojure.core.memoize 1.1.266clojure.core.cache 1.1.234clojure.data.priority-map 1.2.0使用 Clojure 直接驱动 .NET HttpListener,无需 C# Web 框架:
Clojure.Main -i examples/run-webservice.clj -e "(demo.run-webservice/-main)"
默认监听 http://127.0.0.1:8080/,可用环境变量覆盖:
WEB_HOST=127.0.0.1 WEB_PORT=8081 Clojure.Main -i examples/run-webservice.clj -e "(demo.run-webservice/-main)"
可选开启 nREPL(默认关闭):
NREPL_ENABLE=1 NREPL_PORT=1667 Clojure.Main -i examples/run-webservice.clj -e "(demo.run-webservice/-main)"
路由示例:
GET / → hello from ClojureCLRGET /health → {"ok":true}POST /echo → 原样返回请求体准备依赖(一次):
dotnet restore examples/specter-demo/specter-demo.csproj
运行:
Clojure.Main -i examples/run-specter.clj -e "(demo.run-specter/-main)"
可选开启 nREPL(默认关闭):
NREPL_ENABLE=1 NREPL_PORT=1667 Clojure.Main -i examples/run-specter.clj -e "(demo.run-specter/-main)"
使用 ASP.NET Core Minimal API,入口与路由均为 Clojure 代码:
Clojure.Main -i examples/run-webservice-minimal.clj -e "(demo.run-webservice-minimal/-main)"
默认使用 ASPNETCORE_URLS(若未设置,按 ASP.NET Core 默认值)。例如:
ASPNETCORE_URLS=http://127.0.0.1:8082 Clojure.Main -i examples/run-webservice-minimal.clj -e "(demo.run-webservice-minimal/-main)"
可选开启 nREPL(默认关闭):
NREPL_ENABLE=1 NREPL_PORT=1667 Clojure.Main -i examples/run-webservice-minimal.clj -e "(demo.run-webservice-minimal/-main)"
路由示例:
GET / → hello from ClojureCLR (minimal api)GET /health → {"ok":true}POST /echo → 原样返回请求体只启动 nREPL,适合作为所有项目的起点:
Clojure.Main -i examples/run-repl-only.clj -e "(demo.run-repl-only/-main)"
带有 nREPL 的跨平台 Avalonia todo 示例,支持 Reagent 风格的组件函数、atom 订阅和 reaction:
准备依赖(一次):
dotnet restore examples/avalonia-demo/avalonia-demo.csproj
运行:
dotnet run --project examples/avalonia-demo/avalonia-demo.csproj
可选环境变量:
NREPL_ENABLE=1 NREPL_PORT=1667 dotnet run --project examples/avalonia-demo/avalonia-demo.csproj
nREPL 连接后交互示例:
;; 查看状态和 todo 列表
(app.core/get-status)
(app.core/list-todos)
;; 修改标题 / 消息 / 草稿
(app.core/set-title "Reagent 风格 Todo")
(app.core/show-message "组件函数返回 Hiccup,订阅 atom 自动驱动 UI")
(app.core/set-draft "补一个 clear-completed 命令")
;; 添加和切换 todo
(app.core/add-draft-todo)
(app.core/add-todo "支持 active 过滤" "只看未完成项" "ui")
(app.core/set-filter :active)
更多命令见 examples/avalonia-demo/README.md。
这个示例在 C# 中同时使用:
com.rpl.specter.clr(cljr 包)Newtonsoft.Json(C# 包)运行:
dotnet run --project examples/csharp-host/csharp-host.csproj
可直接复制的模板,适合新项目起步:
dotnet run --project examples/starter/starter.csproj
更多说明见:
详细使用指南:
- 5 分钟快速上手
- 完整使用文档
- ClojureCLR 与 C# 深度互操作与高级系统编程
- 架构概览
- 仓库结构与构建
CIDER (Emacs):
M-x cider-connect-clj
Host: 127.0.0.1
Port: 1667
Calva (VS Code):
Cmd/Ctrl+Shift+P → "Calva: Connect to a Running REPL Server"127.0.0.1:1667命令行测试:
# 使用 Python 测试脚本
python3 test_nrepl.py
| 操作 | 说明 | 状态 |
|---|---|---|
eval |
代码求值 | ✅ |
clone |
创建新会话 | ✅ |
close |
关闭会话 | ✅ |
ls-sessions |
列出会话 | ✅ |
describe |
服务器能力描述 | ✅ |
interrupt |
中断执行 | ✅ |
load-file |
加载文件 | ✅ |
stdin |
标准输入 | ✅ |
| 操作 | 说明 | CIDER 使用场景 | 状态 |
|---|---|---|---|
complete |
自动补全 | M-TAB 补全代码 |
✅ |
info |
符号信息查询 | C-c C-d C-d 查看文档 |
✅ |
eldoc |
函数参数提示 | Minibuffer 显示参数 | ✅ |
补全能力(摘要):
Type/Member(已导入类型或完整类型名). 形式(接收者为命名空间中可解析的符号;局部绑定不支持)info/eldoc 支持 CLR 静态成员(实例成员依赖客户端上下文,可能不稳定).
├── src/
│ ├── BencodeCodec.cs # Bencode 编解码
│ ├── NReplServer.Core.cs # 连接/协议/消息分发
│ ├── NReplServer.Eval.cs # eval 与命名空间切换
│ ├── NReplServer.SessionHandlers.cs # clone/ls-sessions/interrupt/load-file
│ ├── NReplServer.Completion.cs # 补全入口
│ ├── NReplServer.Completion.Dot.cs # 点调用补全
│ ├── NReplServer.Completion.Cache.cs # 反射缓存
│ ├── NReplServer.Info.cs # info 处理
│ ├── NReplServer.Eldoc.cs # eldoc 入口
│ ├── NReplServer.Eldoc.Dot.cs # 点调用 eldoc
│ ├── NReplServer.Eldoc.Clr.cs # CLR 静态成员 eldoc
│ ├── NReplServer.Utilities.cs # 通用工具
│ ├── NReplServer.Parsing.cs # 补全/eldoc 解析
│ └── NReplSession.cs # 会话模型
├── cli/
│ ├── Program.cs # CLI 入口
│ └── clojureCLR-nrepl-cli.csproj # CLI 项目
├── tests/
│ ├── BencodeCodecTests.cs # 编解码测试
│ ├── ServerIntegrationTests.cs # 基本协议测试
│ └── clojureCLR-nrepl.Tests.csproj # 测试项目
├── examples/
│ ├── run-core.clj # core.async + nREPL demo
│ ├── run-specter.clj # Specter demo
│ ├── run-webservice.clj # HttpListener demo
│ ├── run-webservice-minimal.clj # Minimal API demo
│ ├── run-repl-only.clj # 最简 nREPL 起点
│ ├── nrepl_util.clj # nREPL 启停工具
│ ├── avalonia-demo/ # Avalonia UI + nREPL demo
│ ├── specter-demo/ # Specter 示例工程
│ ├── webservice/ # HttpListener 示例工程
│ └── webservice-minimal/ # Minimal API 示例工程
│ ├── csharp-host/ # C# Host 示例(cljr + C# 包)
│ └── starter/ # 模板化 starter
├── packages/
│ └── specter-clr/ # Specter CLR 包
├── docs/ # 其他文档
├── clojureCLR-nrepl.csproj # 库项目(NuGet 包)
├── test_nrepl.py # Python 测试脚本
└── README.md # 本文档
in-ns 和跨会话命名空间保持// 处理 nREPL 消息
private string HandleMessage(NetworkStream stream, Dictionary<string, object> request,
string sessionId, bool useLengthPrefix, Session session)
{
var op = request.GetValueOrDefault("op") as string;
switch (op)
{
case "eval": HandleEval(...); break;
case "complete": HandleComplete(...); break;
case "eldoc": HandleEldoc(...); break;
// ...
}
}
| 功能 | 说明 | CIDER 集成 |
|---|---|---|
ns-path |
查找命名空间文件路径 | 跳转到定义 |
apropos |
符号搜索 | M-x cider-apropos |
macroexpand |
宏展开 | M-x cider-macroexpand |
classpath |
类路径查询 | 检查依赖 |
| 功能 | 说明 | CIDER 集成 |
|---|---|---|
refresh/clear |
代码热重载 | M-x cider-ns-refresh |
test |
运行测试 | M-x cider-test-run-tests |
format |
代码格式化 | M-x cider-format-buffer |
spec |
Clojure Spec 支持 | Spec 检查 |
| 功能 | 说明 | CIDER 集成 |
|---|---|---|
fn-deps/fn-refs |
函数依赖/引用 | 代码分析 |
xrefs |
交叉引用 | 重构支持 |
clojuredocs-lookup |
查询 ClojureDocs | 社区文档 |
analyze-last-stacktrace |
异常堆栈分析 | 错误美化 |
HandleMessage 中添加新的 case:case "new-op":
HandleNewOp(stream, request, sessionId, useLengthPrefix, session);
break;
private void HandleNewOp(NetworkStream stream, Dictionary<string, object> request,
string sessionId, bool useLengthPrefix, Session session)
{
var id = GetId(request);
// ... 实现逻辑
SendResponse(stream, new Dictionary<string, object>
{
["id"] = id,
["session"] = sessionId,
["result"] = result,
["status"] = new List<string> { "done" }
}, useLengthPrefix);
}
CreateDescribeResponse 声明支持的操作# 运行服务器
dotnet run --project cli/clojureCLR-nrepl-cli.csproj &
# 运行单元测试
dotnet test tests/clojureCLR-nrepl.Tests.csproj -c Release
# 运行 Python 测试
python3 test_nrepl.py
# 或使用 clj-nrepl-eval
clj-nrepl-eval --port 1667 "(+ 1 2 3)"
直接连接 CIDER/Calva 进行 ClojureCLR 项目开发,享受完整的 IDE 支持。
将服务器嵌入 Unity 项目,运行时热重载 Clojure 脚本。
为现有 .NET 应用提供 Clojure 脚本能力,nREPL 作为管理接口。
结合 Clojure 的数据处理能力和 .NET 的性能,进行交互式数据分析。
MIT License - 详见 LICENSE 文件
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net8.0 net8.0 is compatible. net8.0-android net8.0-android was computed. net8.0-browser net8.0-browser was computed. net8.0-ios net8.0-ios was computed. net8.0-maccatalyst net8.0-maccatalyst was computed. net8.0-macos net8.0-macos was computed. net8.0-tvos net8.0-tvos was computed. net8.0-windows net8.0-windows was computed. net9.0 net9.0 was computed. net9.0-android net9.0-android was computed. net9.0-browser net9.0-browser was computed. net9.0-ios net9.0-ios was computed. net9.0-maccatalyst net9.0-maccatalyst was computed. net9.0-macos net9.0-macos was computed. net9.0-tvos net9.0-tvos was computed. net9.0-windows net9.0-windows was computed. net10.0 net10.0 was computed. net10.0-android net10.0-android was computed. net10.0-browser net10.0-browser was computed. net10.0-ios net10.0-ios was computed. net10.0-maccatalyst net10.0-maccatalyst was computed. net10.0-macos net10.0-macos was computed. net10.0-tvos net10.0-tvos was computed. net10.0-windows net10.0-windows was computed. |
This package is not used by any NuGet packages.
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated |
|---|---|---|
| 0.1.0 | 112 | 3/20/2026 |