nagi.tomlでアプリの設定をまとめる
複数ファイルのアプリでは、入口ファイルやRust連携の引数をnagi.tomlに保存できます。CLIとVS Codeは同じ設定を使います。
最小のプロジェクト
新しいフォルダーに、次の2ファイルを置きます。
my-app/
nagi.toml
main.nagi
nagi.toml:
entry = "main.nagi"
main.nagi(完全なコード):
def main():
print("Hello, Nagi project!")
my-appで実行します。nagicにPATHを通していない場合は、ビルド済みコンパイラの絶対パスを使ってください。
nagic check
nagic run
checkは型検査、runはビルドして実行します。lowerとbuildも同じ設定を使います。ソースの指定を省くと、現在のフォルダーから親へさかのぼり、最も近いnagi.tomlを選びます。my-app/srcなどの子フォルダーからも使えます。
IDE向けのnagic symbols --project my-appは、読み込んだソースの関数・class・ローカル変数の参照位置と定義先をJSONで標準出力へ返します。ビルドや生成ファイルの書き込みは行いません。構文・importが読み込めれば、型エラーがあっても定義位置を取得できます。
JSONには関数の引数・戻り値・async、classのフィールドも含みます。型検査で確認できた変数の型はlocals、式の型・範囲・その型のフィールドはexpressionsに入ります。位置は元ファイルの1始まりの行・UTF-16列です。確定しない型は出力しません。これは編集補助の情報で、checkの成功を示すものではありません。
symbols --editor-inputでは標準入力の{"files":[{"file":"main.nagi","text":"..."}]}で既存のNagi/Lowファイルの編集中の内容を指定できます。相対パスはターミナルの作業フォルダー基準です。ディスクへ書き込まずに読み込み時のソースを置き換えます。このオプションはsymbols専用で、設定ファイルは保存済みのものを使います。
別の場所から選ぶ場合:
nagic run --project my-app
nagic check --project my-app/nagi.toml
実行したアプリの作業フォルダーはnagi.tomlのある場所です。たとえば相対パスdata.sqliteはそこに作られ、呼び出したターミナルの場所によって変わりません。exeを直接実行するときは、そのプロセスの作業フォルダーが使われます。
Rustと手書きLowを追加する
entry = "src/main.nagi"
native = ["native/math.low"]
[rust]
file = "native/bridge.rs"
[rust.dependencies]
serde_json = "1.0"
| 設定 | 内容 |
|---|---|
entry |
必須。実行・検査の入口となる.nagiまたは.low |
native |
任意。統合する手書きLowファイルの配列 |
rust.file |
任意。native moduleとして組み込むRustファイル1つ |
rust.dependencies |
任意。依存名とCargoのversion文字列またはtableの対応 |
ファイルの相対パスはすべてnagi.toml基準です。entry以外は省略できます。存在しない設定名、型の違い、空のパス、依存の重複はエラーになります。従来のversion文字列はそのまま使えます。Rustの型や実装との一致はbuildまたはrunで検査します。
ローカルcrateとfeatureを指定する
依存ごとにtableも使えます。次はローカルRustライブラリのサンプルの設定です。
entry = "library-pricing.nagi"
[rust]
file = "native.rs"
[rust.dependencies]
pricing = { version = "0.1", path = "engine", package = "nagi-pricing-engine", features = ["volume-discount"], default-features = false }
| tableの項目 | 内容 |
|---|---|
version |
Cargoのversion指定。pathと併記した場合もCargoがversionの一致を検査する |
path |
ローカルcrateのディレクトリ。nagi.tomlの場所を基準に解決する |
package |
実際のCargo package名。上の例ではRustからpricing::で参照する |
features |
有効にするfeature名の配列。空の配列も指定できる |
default-features |
その依存宣言で既定featureを有効にするか。省略時はCargoの既定値true |
versionかpathの少なくとも一方が必要です。git・registry・workspace・target別依存・dev/build依存・optionalは未対応です。
pathは生成先やターミナルの場所にかかわらず、設定ファイル基準です。check・lower・symbolsはCargoを呼ばず、依存を取得せず、依存crateの存在確認も行いません。Rust crateをまだ用意していなくてもNagi側を検査できます。実際のpath、crateのAPI、依存解決はbuild/runでCargoが検査します。
Cargoは同じpackageへの依存経路でfeatureを統合します。default-features = falseを指定しても、別の経路が求める既定featureまで無効にはなりません。
再ビルドでは生成先の既存Cargo.lockを保持します。lockは解決したversionを記録しますが、ローカルcrateのソースは固定しません。固定した解決でビルドする場合は、サンプルのディレクトリでcargo build --release --locked --manifest-path build/library-pricing/Cargo.tomlを使えます。nagic build --lockedは未対応です。
動く例は Rust連携サンプルです。リポジトリのルートから:
.\target\release\nagic.exe run --project test-nagi-code/rust-bridge
CRC32、JSON整形、asyncのRust関数を呼びます。タスク管理サイトも入口を設定済みです。
コマンド引数との優先順位
nagic run main.nagiのようにソースだけを明示した場合は、従来どおりそのファイルを単独で処理します。近くにnagi.tomlがあっても自動では読みません。
| 指定 | 動作 |
|---|---|
--project DIR / --project FILE |
その設定を使う |
SOURCE --project DIR |
設定を読み、入口だけSOURCEに変更。SOURCEはターミナルの作業フォルダー基準 |
--rust FILE |
設定のrust.fileを上書き |
--rust-dep NAME=VERSION |
同じ名前の依存全体をversion文字列に置換。別の名前なら追加 |
--native FILE.low |
設定のnativeに追加 |
--out DIR |
生成Low・Rust・Cargo.tomlの出力先を変更 |
--no-project |
自動探索を使わない。SOURCEの指定が必要 |
--rust-depで同名のtableを置換すると、元のpath・package・features・default-featuresは残りません。CLIではversion文字列だけを指定できます。
引数内の相対パスはターミナルの作業フォルダー基準です。SOURCE・--project・--rust・--out・同名の--rust-depの重複はエラーです。--projectと--no-projectは同時に使えません。
プロジェクトの生成コードはbuild/<入口のファイル名>/、exeはbuild/native-target/release/に出力します。たとえばmain.nagiならnagi-main.exe(Linuxではnagi-main)です。プロジェクトごとにビルド先を分けるため、別のアプリもmain.nagiという名前を使えます。NAGI_NATIVE_TARGET_DIRでexeのビルド先を変更できます。
VS Codeで使う
Nagi拡張の0.1.1以降では、開いている.nagi / .lowから親へ最も近いnagi.tomlを探します。補助ファイルを開いた状態でも、型検査・Low変換・ビルド・実行はentryから行います。import先のエラーは元のファイルに表示します。
nagi.tomlを保存すると開いているNagiファイルを再検査します。プロジェクト内に未保存のファイルがある間は自動検査を待ち、手動コマンドではそのプロジェクトの編集中ファイルを保存してから処理します。入口からimportされていないNagiファイルは、そのプロジェクトの検査対象に入りません。
コンパイラの場所だけはVS Codeのnagi.compilerPathかPATHで指定します。従来のnagi.rustFile・nagi.rustDependencies・nagi.nativeFilesもコマンド引数として使え、上の優先順位に従います。nagi.rustDependenciesの値はversion文字列だけです。依存tableはnagi.tomlに書きます。アプリごとの設定にはnagi.tomlを使うと、VS Codeとターミナルで同じ条件を再現できます。
拡張0.1.5以降と最新版のnagicでは、F12でプロジェクト内の関数・class・import先・ローカル変数の定義へ移動できます。引数・for・caseの名前も対象です。入口から読み込まれるHigh・Lowを扱い、開いているソースの未保存の変更もメモリ上で読みます。構文やimportを読めない場合は、保存済みの古い位置へ移動しません。新規ファイルとnagi.tomlの変更は保存してから使います。
宣言やローカル変数の型のホバー、関数・class・型とフィールドの補完、引数ヒントも使えます。これらは一度保存したファイルの未保存の編集も読みます。import先や手書きLowの未保存の内容も対象です。書きかけで解析できない場合は「保存済み」と示して宣言の候補を出し、ローカル型とフィールド候補は出しません。操作例と拡張の設定を参照してください。