From 24c1a6335e3da6a3ecf82f33ac50c2ad66aee346 Mon Sep 17 00:00:00 2001 From: Felix Leitz Date: Mon, 13 Mar 2023 18:45:03 +0100 Subject: [PATCH] vscode: add options for global and user snippets (#3765) Co-authored-by: Felix Leitz --- modules/programs/vscode.nix | 43 +++++++++++++ tests/modules/programs/vscode/default.nix | 1 + tests/modules/programs/vscode/snippets.nix | 71 ++++++++++++++++++++++ 3 files changed, 115 insertions(+) create mode 100644 tests/modules/programs/vscode/snippets.nix diff --git a/modules/programs/vscode.nix b/modules/programs/vscode.nix index cdc66578a..779565d2d 100644 --- a/modules/programs/vscode.nix +++ b/modules/programs/vscode.nix @@ -32,6 +32,8 @@ let tasksFilePath = "${userDir}/tasks.json"; keybindingsFilePath = "${userDir}/keybindings.json"; + snippetDir = "${userDir}/snippets"; + # TODO: On Darwin where are the extensions? extensionPath = ".${extensionDir}/extensions"; @@ -187,6 +189,34 @@ in { or by Visual Studio Code. ''; }; + + languageSnippets = mkOption { + type = jsonFormat.type; + default = { }; + example = { + haskell = { + fixme = { + prefix = [ "fixme" ]; + body = [ "$LINE_COMMENT FIXME: $0" ]; + description = "Insert a FIXME remark"; + }; + }; + }; + description = "Defines user snippets for different languages."; + }; + + globalSnippets = mkOption { + type = jsonFormat.type; + default = { }; + example = { + fixme = { + prefix = [ "fixme" ]; + body = [ "$LINE_COMMENT FIXME: $0" ]; + description = "Insert a FIXME remark"; + }; + }; + description = "Defines global user snippets."; + }; }; }; @@ -243,6 +273,19 @@ in { }; in "${combinedExtensionsDrv}/${subDir}"; })) + + (mkIf (cfg.globalSnippets != { }) + (let globalSnippets = "${snippetDir}/global.code-snippets"; + in { + "${globalSnippets}".source = + jsonFormat.generate "user-snippet-global.code-snippets" + cfg.globalSnippets; + })) + + (lib.mapAttrs' (language: snippet: + lib.nameValuePair "${snippetDir}/${language}.json" { + source = jsonFormat.generate "user-snippet-${language}.json" snippet; + }) cfg.languageSnippets) ]; }; } diff --git a/tests/modules/programs/vscode/default.nix b/tests/modules/programs/vscode/default.nix index 4015121d5..a32768a92 100644 --- a/tests/modules/programs/vscode/default.nix +++ b/tests/modules/programs/vscode/default.nix @@ -2,4 +2,5 @@ vscode-keybindings = ./keybindings.nix; vscode-tasks = ./tasks.nix; vscode-update-checks = ./update-checks.nix; + vscode-snippets = ./snippets.nix; } diff --git a/tests/modules/programs/vscode/snippets.nix b/tests/modules/programs/vscode/snippets.nix new file mode 100644 index 000000000..a7ea44f76 --- /dev/null +++ b/tests/modules/programs/vscode/snippets.nix @@ -0,0 +1,71 @@ +{ pkgs, ... }: + +let + + snippetsDir = if pkgs.stdenv.hostPlatform.isDarwin then + "Library/Application Support/Code/User/snippets" + else + ".config/Code/User/snippets"; + + globalSnippetsPath = "${snippetsDir}/global.code-snippets"; + + globalSnippetsExpectedContent = pkgs.writeText "global.code-snippet" '' + { + "fixme": { + "body": [ + "fixme body in global user snippet" + ], + "description": "Insert a FIXME remark", + "prefix": [ + "fixme" + ] + } + } + ''; + + haskellSnippetsPath = "${snippetsDir}/haskell.json"; + + haskellSnippetsExpectedContent = pkgs.writeText "haskell.json" '' + { + "impl": { + "body": [ + "impl body in user haskell snippet" + ], + "description": "Insert an implementation stub", + "prefix": [ + "impl" + ] + } + } + ''; + +in { + programs.vscode = { + enable = true; + package = pkgs.writeScriptBin "vscode" "" // { pname = "vscode"; }; + globalSnippets = { + fixme = { + prefix = [ "fixme" ]; + body = [ "fixme body in global user snippet" ]; + description = "Insert a FIXME remark"; + }; + }; + languageSnippets = { + haskell = { + impl = { + prefix = [ "impl" ]; + body = [ "impl body in user haskell snippet" ]; + description = "Insert an implementation stub"; + }; + }; + }; + }; + + nmt.script = '' + assertFileExists "home-files/${globalSnippetsPath}" + assertFileContent "home-files/${globalSnippetsPath}" "${globalSnippetsExpectedContent}" + + assertFileExists "home-files/${haskellSnippetsPath}" + assertFileContent "home-files/${haskellSnippetsPath}" "${haskellSnippetsExpectedContent}" + ''; +}