Skip to content

Commit 1db5b69

Browse files
author
fidgetingbits
committed
initial nix language support
1 parent 962f64f commit 1db5b69

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

62 files changed

+2038
-5
lines changed

data/playground/nix/asserts.nix

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
# https://nixos.org/manual/nix/stable/language/constructs.html#assertions
2+
3+
{ localServer ? false
4+
, httpServer ? false
5+
, sslSupport ? false
6+
, pythonBindings ? false
7+
, javaSwigBindings ? false
8+
, javahlBindings ? false
9+
, stdenv, fetchurl
10+
, openssl ? null, httpd ? null, db4 ? null, expat, swig ? null, j2sdk ? null
11+
}:
12+
13+
assert localerver -> db4 != null;
14+
assert httpServer -> httpd != null && httpd.expat == expat;
15+
assert sslSupport -> openssl != null && (httpServer -> httpd.openssl == openssl);
16+
assert pythonBindings -> swig != null && swig.pythonSupport;
17+
assert javaSwigBindings -> swig != null && swig.javaSupport;
18+
assert javahlBindings -> j2sdk != null;
19+
20+
stdenv.mkDerivation {
21+
(name = "subversion-1.1.1";)
22+
...
23+
openssl = if sslSupport then openssl else null;
24+
...
25+
}

data/playground/nix/attrsets.nix

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
{
2+
a = { a = b; c = d; };
3+
a = {
4+
a = b;
5+
c = d;
6+
};
7+
8+
a = {
9+
a = {
10+
b = 1; };
11+
12+
c = { d = [ "1" 2 ] };
13+
};
14+
15+
a = rec {
16+
a = b;
17+
b = a + 1;
18+
};
19+
}

data/playground/nix/comments.nix

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
# Single-line comment
2+
/*
3+
Multi-line comment
4+
*/
5+
{
6+
a = b; # Inline comment (test)
7+
b = c; # Inline comment 2
8+
}

data/playground/nix/complex.nix

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
{
2+
inputs = {
3+
nixpkgs.url = "github:nixos/nixpkgs/nixos-23.05";
4+
home-manager = {
5+
url = "github:nix-community/home-manager/release-23.05";
6+
inputs.nixpkgs.follows = "nixpkgs";
7+
};
8+
};
9+
10+
outputs = { self, nixpkgs, home-manager }:
11+
let
12+
mkHost = hostName: system:
13+
(({ my-config, zfs-root, pkgs, system, ... }:
14+
nixpkgs.lib.nixosSystem {
15+
inherit system;
16+
modules = [
17+
# Module 0: zfs-root and my-config
18+
./modules
19+
20+
# Module 1: host-specific config, if exist
21+
(if (builtins.pathExists
22+
./hosts/${hostName}/configuration.nix) then
23+
(import ./hosts/${hostName}/configuration.nix { inherit pkgs; })
24+
else
25+
{ })
26+
27+
# Module 2: entry point
28+
(({ my-config, zfs-root, pkgs, lib, ... }: {
29+
inherit my-config zfs-root;
30+
system.configurationRevision = if (self ? rev) then
31+
self.rev
32+
else
33+
throw "refuse to build: git tree is dirty";
34+
system.stateVersion = "23.05";
35+
imports = [
36+
"${nixpkgs}/nixos/modules/installer/scan/not-detected.nix"
37+
# "${nixpkgs}/nixos/modules/profiles/hardened.nix"
38+
# "${nixpkgs}/nixos/modules/profiles/qemu-guest.nix"
39+
];
40+
}) {
41+
inherit my-config zfs-root pkgs;
42+
lib = nixpkgs.lib;
43+
})
44+
45+
# Module 3: home-manager
46+
home-manager.nixosModules.home-manager
47+
{
48+
home-manager.useGlobalPkgs = true;
49+
home-manager.useUserPackages = true;
50+
}
51+
52+
# Module 4: config shared by all hosts
53+
(import ./configuration.nix { inherit pkgs; })
54+
];
55+
})
56+
57+
# configuration input
58+
(import ./hosts/${hostName} {
59+
system = system;
60+
pkgs = nixpkgs.legacyPackages.${system};
61+
}));
62+
in {
63+
nixosConfigurations = {
64+
exampleHost = mkHost "exampleHost" "x86_64-linux";
65+
};
66+
};
67+
}

data/playground/nix/functions.nix

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
{
2+
# Anonymous function
3+
a = foo: (foo + 1);
4+
x = a: b: a + b;
5+
6+
# Non-built-in function
7+
ba = test( foo: bar: {
8+
b = foo;
9+
});
10+
11+
# Built-in function
12+
x = map (x: y: x + x) [ 1 2 3 ];
13+
}

data/playground/nix/lists.nix

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
{
2+
foo = [ "a" a/b/c "b" ];
3+
bar = [ A
4+
B
5+
C # foo
6+
];
7+
}

data/playground/nix/statements.nix

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
{
2+
key = if a then b else c;
3+
key =
4+
if a
5+
then b
6+
else c;
7+
8+
a = b; # Inline comment (test)
9+
b = c; # Inline comment 2
10+
a = 1 + 1;
11+
a = a/b/c ? 0;
12+
a = b: b + 1;
13+
14+
foo = let
15+
a = b;
16+
c = d;
17+
in
18+
{
19+
output = b;
20+
};
21+
22+
bar = let
23+
a = 1;
24+
b = 2;
25+
in a + b;
26+
27+
bar =
28+
with key;
29+
let
30+
a = key;
31+
in
32+
a;
33+
34+
a = x: x + 1;
35+
b = x: y: x + y + 1;
36+
}

data/playground/nix/strings.nix

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
{
2+
a = "double quoted string";
3+
b = ''two single quote string'';
4+
c = ''
5+
multi-line
6+
quote string'';
7+
d = "Interpolated ${value} string";
8+
e = "Escaped \${string} ";
9+
f = ''
10+
"Nested"
11+
string
12+
'';
13+
}

packages/common/src/extensionDependencies.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ export const extensionDependencies = [
66
"scala-lang.scala", // scala
77
"mrob95.vscode-talonscript", // talon
88
"jrieken.vscode-tree-sitter-query", // scm
9+
"bbenoist.nix", // nix
910

1011
// Necessary for the `drink cell` and `pour cell` tests
1112
"ms-toolsai.jupyter",

packages/cursorless-engine/src/processTargets/modifiers/surroundingPair/findSurroundingPairParseTreeBased.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,10 @@ export function findSurroundingPairParseTreeBased(
6666
) {
6767
const document: TextDocument = editor.document;
6868

69-
const individualDelimiters = getIndividualDelimiters(delimiters);
69+
const individualDelimiters = getIndividualDelimiters(
70+
document.languageId,
71+
delimiters,
72+
);
7073

7174
const delimiterTextToDelimiterInfoMap = Object.fromEntries(
7275
individualDelimiters.map((individualDelimiter) => [

packages/cursorless-engine/src/processTargets/modifiers/surroundingPair/findSurroundingPairTextBased.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,10 @@ export function findSurroundingPairTextBased(
7474
const document: TextDocument = editor.document;
7575
const fullRange = allowableRange ?? document.range;
7676

77-
const individualDelimiters = getIndividualDelimiters(delimiters);
77+
const individualDelimiters = getIndividualDelimiters(
78+
editor.document.languageId,
79+
delimiters,
80+
);
7881

7982
const delimiterTextToDelimiterInfoMap = Object.fromEntries(
8083
individualDelimiters.map((individualDelimiter) => [

packages/cursorless-engine/src/processTargets/modifiers/surroundingPair/delimiterMaps.ts renamed to packages/cursorless-engine/src/processTargets/modifiers/surroundingPair/getDelimiterMaps.ts

Lines changed: 40 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import {
55

66
type IndividualDelimiterText = string | string[];
77

8-
export const delimiterToText: Record<
8+
const delimiterToText: Record<
99
SimpleSurroundingPairName,
1010
[IndividualDelimiterText, IndividualDelimiterText]
1111
> = {
@@ -25,6 +25,26 @@ export const delimiterToText: Record<
2525
squareBrackets: ["[", "]"],
2626
};
2727

28+
const delimiterToTextNix: Record<
29+
SimpleSurroundingPairName,
30+
[IndividualDelimiterText, IndividualDelimiterText]
31+
> = {
32+
angleBrackets: [
33+
["</", "<"],
34+
[">", "/>"],
35+
],
36+
backtickQuotes: ["`", "`"],
37+
curlyBrackets: [["{", "${"], "}"],
38+
doubleQuotes: ['"', '"'],
39+
escapedDoubleQuotes: ['\\"', '\\"'],
40+
escapedParentheses: ["\\(", "\\)"],
41+
escapedSquareBrackets: ["\\[", "\\]"],
42+
escapedSingleQuotes: ["\\'", "\\'"],
43+
parentheses: [["(", "$("], ")"],
44+
singleQuotes: ["''", "''"],
45+
squareBrackets: ["[", "]"],
46+
};
47+
2848
export const leftToRightMap: Record<string, string> = Object.fromEntries(
2949
Object.values(delimiterToText),
3050
);
@@ -46,3 +66,22 @@ export const complexDelimiterMap: Record<
4666
"angleBrackets",
4767
],
4868
};
69+
70+
/**
71+
* Given a language id, returns a list of all possible delimiters
72+
* for that language.
73+
* @param languageId The language id
74+
* @returns A list of all possible delimiters for that language
75+
*/
76+
export function getSimpleDelimiterMap(
77+
languageId: string,
78+
): Record<
79+
SimpleSurroundingPairName,
80+
[IndividualDelimiterText, IndividualDelimiterText]
81+
> {
82+
if (languageId == "nix") {
83+
return delimiterToTextNix;
84+
} else {
85+
return delimiterToText;
86+
}
87+
}

packages/cursorless-engine/src/processTargets/modifiers/surroundingPair/getIndividualDelimiters.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { SimpleSurroundingPairName } from "@cursorless/common";
22
import { IndividualDelimiter } from "./types";
3-
import { delimiterToText } from "./delimiterMaps";
3+
import { getSimpleDelimiterMap } from "./getDelimiterMaps";
44
import { concat, uniq } from "lodash";
55
import { isString } from "../../../util/type";
66

@@ -13,8 +13,10 @@ import { isString } from "../../../util/type";
1313
* @returns A list of information about all possible left / right delimiter instances
1414
*/
1515
export function getIndividualDelimiters(
16+
languageId: string,
1617
delimiters: SimpleSurroundingPairName[],
1718
): IndividualDelimiter[] {
19+
const delimiterToText = getSimpleDelimiterMap(languageId);
1820
return delimiters.flatMap((delimiter) => {
1921
const [leftDelimiter, rightDelimiter] = delimiterToText[delimiter];
2022

packages/cursorless-engine/src/processTargets/modifiers/surroundingPair/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ import getTextFragmentExtractor from "../../../languages/getTextFragmentExtracto
99
import { Target } from "../../../typings/target.types";
1010
import { SurroundingPairTarget } from "../../targets";
1111
import { getContainingScopeTarget } from "../getContainingScopeTarget";
12-
import { complexDelimiterMap } from "./delimiterMaps";
12+
import { complexDelimiterMap } from "./getDelimiterMaps";
1313
import { SurroundingPairInfo } from "./extractSelectionFromSurroundingPairOffsets";
1414
import { findSurroundingPairParseTreeBased } from "./findSurroundingPairParseTreeBased";
1515
import { findSurroundingPairTextBased } from "./findSurroundingPairTextBased";
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
languageId: nix
2+
command:
3+
version: 6
4+
spokenForm: change arg
5+
action:
6+
name: clearAndSetSelection
7+
target:
8+
type: primitive
9+
modifiers:
10+
- type: containingScope
11+
scopeType: {type: argumentOrParameter}
12+
usePrePhraseSnapshot: true
13+
initialState:
14+
documentContents: |-
15+
{ pkgs, ... }:
16+
{ a = 1; }
17+
selections:
18+
- anchor: {line: 0, character: 10}
19+
active: {line: 0, character: 10}
20+
marks: {}
21+
finalState:
22+
documentContents: |-
23+
:
24+
{ a = 1; }
25+
selections:
26+
- anchor: {line: 0, character: 0}
27+
active: {line: 0, character: 0}
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
languageId: nix
2+
command:
3+
version: 6
4+
spokenForm: change arg
5+
action:
6+
name: clearAndSetSelection
7+
target:
8+
type: primitive
9+
modifiers:
10+
- type: containingScope
11+
scopeType: {type: argumentOrParameter}
12+
usePrePhraseSnapshot: true
13+
initialState:
14+
documentContents: |-
15+
{ pkgs, ... }:
16+
{ a = 1; }
17+
selections:
18+
- anchor: {line: 1, character: 4}
19+
active: {line: 1, character: 4}
20+
marks: {}
21+
finalState:
22+
documentContents: |-
23+
:
24+
{ a = 1; }
25+
selections:
26+
- anchor: {line: 0, character: 0}
27+
active: {line: 0, character: 0}

0 commit comments

Comments
 (0)