# clojure-lsp

## 概要

clojure-lspは、Clojure/ClojureScript向けの[Language Server Protocol (LSP)](https://microsoft.github.io/language-server-protocol/)実装です。エディタ上でのコード補完、定義へのジャンプ、リファクタリングなどの高度な編集機能を提供し、Cursiveのような静的解析アプローチでコードを分析します。また、CLI/APIを通じてエディタ外からもプログラム的に利用できます。

## 主な機能

| 機能カテゴリ | 説明 |
| --- | --- |
| コード補完 | 関数、変数、キーワード、ライブラリ名とバージョンの補完、スニペット |
| ナビゲーション | 定義へのジャンプ、実装の検索、宣言の検索、参照の検索 |
| リファクタリング | シンボルのリネーム、ns整理(clean-ns)、フォーマット、各種コードアクション |
| 診断 | clj-kondoによる静的解析、カスタムリンター、未使用public var検出 |
| ドキュメント | ホバー時のドキュメント表示、ClojureDocs統合 |
| Java連携 | Javaクラスの定義ジャンプ、Javaメソッドの補完 |
| セマンティックトークン | 構文ハイライト用のトークン情報提供 |
| コールハイアラーキー | 関数の呼び出し階層表示 |
| CLI/API | エディタ外からのformat、clean-ns、diagnostics、rename、references、dump操作 |

## 技術スタック

### コア

- 言語: Clojure 1.12.4
- プロトコル: Language Server Protocol (LSP)
- ランタイム: JVM / GraalVM Native Image

### 主要ライブラリ

- **clj-kondo**: 静的解析エンジン
- **rewrite-clj**: Clojureコードの解析・変換
- **cljfmt**: コードフォーマッター
- **clj-depend**: 依存関係分析
- **lsp4clj**: LSPプロトコル実装基盤
- **core.async**: 非同期処理
- **babashka/fs**: ファイルシステム操作
- **babashka/sci**: Small Clojure Interpreter
- **timbre**: ロギング
- **OpenTelemetry**: テレメトリ・トレーシング

## ディレクトリ構成

```
clojure-lsp/
├── lib/                    # コアライブラリ（API・機能実装）
│   ├── src/
│   │   └── clojure_lsp/
│   │       ├── api.clj              # パブリックAPI
│   │       ├── internal_api.clj     # 内部API
│   │       ├── handlers.clj         # LSPハンドラ
│   │       ├── startup.clj          # 起動・初期化
│   │       ├── config.clj           # 設定管理
│   │       ├── db.clj               # データベース
│   │       ├── kondo.clj            # clj-kondo統合
│   │       ├── queries.clj          # 解析クエリ
│   │       ├── parser.clj           # パーサー
│   │       ├── dep_graph.clj        # 依存グラフ
│   │       ├── classpath.clj        # クラスパス解決
│   │       └── feature/             # 機能実装
│   │           ├── completion.clj       # 補完
│   │           ├── diagnostics.clj      # 診断
│   │           ├── code_actions.clj     # コードアクション
│   │           ├── rename.clj           # リネーム
│   │           ├── hover.clj            # ホバー
│   │           ├── format.clj           # フォーマット
│   │           └── ...
│   └── test/               # libのテスト
├── cli/                    # CLI実行部
│   ├── src/
│   │   └── clojure_lsp/
│   │       ├── main.clj             # CLIエントリポイント
│   │       └── server.clj           # LSPサーバー実装
│   ├── integration-test/   # 統合テスト
│   └── test/               # cliのテスト
├── test-helper/            # テストヘルパー
├── docs/                   # ドキュメント
├── images/                 # ロゴ等の画像
├── scripts/                # ビルド・リリーススクリプト
├── deps.edn                # ルートの依存関係定義
├── bb.edn                  # Babashka設定
├── mkdocs.yml              # ドキュメントサイト設定
├── flake.nix               # Nix flake設定
└── CHANGELOG.md            # 変更履歴
```

## セットアップ

### 必要条件

- Java 11以上（JVMで実行する場合）
- Clojure CLI tools（開発する場合）

### インストール

**Homebrew (macOS/Linux):**
```bash
brew install clojure-lsp/brew/clojure-lsp-native
```

**スクリプト:**
```bash
sudo bash < <(curl -s https://raw.githubusercontent.com/clojure-lsp/clojure-lsp/master/install)
```

**Nix:**
```bash
nix run github:clojure-lsp/clojure-lsp
```

**Arch Linux:**
```bash
yay -S clojure-lsp-bin
```

**Windows (Scoop):**
```bash
scoop install clojure-lsp
```

**ネイティブバイナリ（推奨）:**

[GitHub Releases](https://github.com/clojure-lsp/clojure-lsp/releases)から`clojure-lsp-native-<os>-<arch>.zip`をダウンロードして展開。

### 設定

プロジェクトルートまたはホームディレクトリに`.lsp/config.edn`を配置して設定をカスタマイズできます。

```edn
{:clean {:ns-inner-blocks-indentation :keep}
 :hover {:hide-file-location? false}
 :linters {:clj-kondo {:level :on}
           :clojure-lsp/unused-public-var {:level :info}}}
```

## 開発

### 依存関係のインストール

```bash
clojure -P
```

### LSPサーバーの起動（開発用）

```bash
clojure -M:dev:run
```

### テストの実行

```bash
# 単体テスト
clojure -M:test

# 統合テスト
cd cli && clojure -M:integration-test
```

### ビルド

```bash
# JARビルド
clojure -T:build jar

# ネイティブイメージビルド（GraalVM必要）
clojure -T:build native
```

### リンターとフォーマッター

```bash
# clj-kondoによるリント
clj-kondo --lint src

# cljfmtによるフォーマット
clojure -M:cljfmt check
clojure -M:cljfmt fix
```

### デバッグ

`cli/dev`にデバッグ用の設定があります。`:debug`エイリアスを使用してnREPL、async-profiler、memory-meterを利用できます。

```bash
clojure -M:dev:debug
```
