oxalica / nil

NIx Language server, an incremental analysis assistant for writing in Nix.
Apache License 2.0
1.32k stars 39 forks source link

Support additional builtin (global) names with `scopedImport` #72

Open sivizius opened 1 year ago

sivizius commented 1 year ago

Due to the scopedImport-builtin, nix-files can be imported with additional symbols. I use this mechanic for constructors e.g. here: https://github.com/sivizius/nixfiles/blob/development/services/printing/default.nix: It prevents importing such files from an unintended place while reducing some boilerplate like { Constructor, ... }:/with (import ./constructors.nix)/let inherit(import ./constructors) …;/…. Perhaps rust-like attributes, e.g. #![with(Foo,Bar)], might be a solution.

Besides scopedImport, the scope of a nix-file depends on other factors like version and settings (e.g. enableNativeCode enables __importNative and __exec, pureEval enables __currentTime and __currentSystem). On the other hand one might prefer an explicit let inherit(builtins) trace; in trace … over the usage of e.g. __trace. However, let inherit(builtins) true false null; in … is too much boilerplate.

Therefore I suggest to add an option implicitScope which defaults to null but could be set to e.g. [ "builtins", "false", "null", "true" ]. The former should mean: Determine implicit scope as before; and the latter: Throw undefined_name for every symbol not defined as a parameter, in a let … in, in implicitScope or with #![with(…)]…unless with is used, which IMHO should not be used outside foo = with bar; [ baz ]; anyway. I further suggest to allow type-parameters, e.g. #![with(foo:string,bar:int->bool)] and "implicitScope": [ "builtins:set", "false:bool", "null:null", "true:bool" ].