{ "name": "elixir-ls", "displayName": "ElixirLS: Elixir support and debugger", "homepage": "https://github.com/elixir-lsp/elixir-ls", "repository": { "type": "git", "url": "https://github.com/elixir-lsp/vscode-elixir-ls.git" }, "icon": "images/logo.png", "description": "Elixir support with debugger, autocomplete, and more - Powered by ElixirLS.", "author": "The Elixir community", "license": "MIT", "publisher": "JakeBecker", "version": "0.29.3", "engines": { "vscode": "^1.95.0" }, "sponsor": { "url": "https://github.com/sponsors/elixir-lsp" }, "categories": [ "Programming Languages", "Debuggers", "Linters", "Testing", "Formatters" ], "keywords": ["elixir", "mix", "dialyzer", "multi-root ready"], "activationEvents": [ "onLanguage:phoenix-heex", "onLanguage:surface", "workspaceContains:mix.exs", "onDebugResolve:elixir" ], "main": "./out/extension.js", "contributes": { "configurationDefaults": { "[elixir]": { "editor.insertSpaces": true, "editor.tabSize": 2, "editor.wordBasedSuggestions": "off", "editor.formatOnType": true, "editor.trimAutoWhitespace": false, "editor.snippetSuggestions": "inline", "files.trimTrailingWhitespace": true, "files.insertFinalNewline": true, "files.trimFinalNewlines": true }, "[eex]": { "editor.trimAutoWhitespace": false, "editor.snippetSuggestions": "inline", "files.trimTrailingWhitespace": true, "files.insertFinalNewline": true, "files.trimFinalNewlines": true }, "[html-eex]": { "editor.trimAutoWhitespace": false, "editor.snippetSuggestions": "inline", "files.trimTrailingWhitespace": true, "files.insertFinalNewline": true, "files.trimFinalNewlines": true } }, "configuration": { "title": "ElixirLS", "properties": { "elixirLS.autoBuild": { "scope": "resource", "type": "boolean", "default": true, "description": "Trigger ElixirLS build when code is saved" }, "elixirLS.dialyzerEnabled": { "scope": "resource", "type": "boolean", "default": true, "description": "Run ElixirLS's rapid Dialyzer when code is saved" }, "elixirLS.incrementalDialyzer": { "scope": "resource", "type": "boolean", "default": true, "description": "Use OTP incremental dialyzer (available on OTP 26+)" }, "elixirLS.dialyzerWarnOpts": { "scope": "resource", "description": "Dialyzer options to enable or disable warnings - See Dialyzer's documentation for options. Note that the \"race_conditions\" option is unsupported", "type": "array", "uniqueItems": true, "items": { "type": "string", "enum": [ "no_return", "no_unused", "no_unknown", "no_improper_lists", "no_fun_app", "no_match", "no_opaque", "no_fail_call", "no_contracts", "no_behaviours", "no_undefined_callbacks", "unmatched_returns", "error_handling", "no_missing_calls", "specdiffs", "overspecs", "underspecs", "no_underspecs", "extra_return", "no_extra_return", "missing_return", "no_missing_return", "unknown", "overlapping_contract", "opaque_union", "no_opaque_union" ] }, "default": [] }, "elixirLS.dialyzerFormat": { "scope": "resource", "description": "Formatter to use for Dialyzer warnings", "type": "string", "enum": ["dialyzer", "dialyxir_short", "dialyxir_long"], "markdownEnumDescriptions": [ "Original Dialyzer format", "Same as `mix dialyzer --format short`", "Same as `mix dialyzer --format long`" ], "default": "dialyxir_long" }, "elixirLS.envVariables": { "scope": "resource", "type": "object", "description": "Environment variables to use for compilation", "minLength": 0 }, "elixirLS.mixEnv": { "scope": "resource", "type": "string", "description": "Mix environment to use for compilation", "default": "test", "minLength": 1 }, "elixirLS.mixTarget": { "scope": "resource", "type": "string", "description": "Mix target to use for compilation", "minLength": 0 }, "elixirLS.projectDir": { "scope": "resource", "type": "string", "description": "Subdirectory containing Mix project if not in the project root", "minLength": 0, "default": "" }, "elixirLS.stdlibSrcDir": { "scope": "resource", "type": "string", "description": "Subdirectory where the Elixir stdlib resides to allow for source code lookup. E.g. /home/youruser/.asdf/installs/elixir/1.18.2", "minLength": 0, "default": "" }, "elixirLS.useCurrentRootFolderAsProjectDir": { "scope": "resource", "type": "boolean", "description": "Don't try to look for mix.exs in parent directories", "default": false }, "elixirLS.fetchDeps": { "scope": "resource", "type": "boolean", "description": "Automatically fetch project dependencies when compiling.", "default": false }, "elixirLS.suggestSpecs": { "scope": "resource", "type": "boolean", "description": "Suggest @spec annotations inline using Dialyzer's inferred success typings (Requires Dialyzer).", "default": true }, "elixirLS.trace.server": { "scope": "window", "type": "string", "enum": ["off", "messages", "verbose"], "default": "off", "description": "Traces the communication between VS Code and the Elixir language server." }, "elixirLS.autoInsertRequiredAlias": { "scope": "window", "type": "boolean", "description": "Enable auto-insert required alias. This is true (enabled) by default.", "default": true }, "elixirLS.signatureAfterComplete": { "scope": "resource", "type": "boolean", "description": "Show signature help after confirming autocomplete.", "default": true }, "elixirLS.enableTestLenses": { "scope": "resource", "type": "boolean", "description": "Show code lenses to run tests in terminal.", "default": false }, "elixirLS.additionalWatchedExtensions": { "scope": "resource", "type": "array", "description": "Additional file types capable of triggering a build on change", "uniqueItems": true, "items": { "type": "string" }, "default": [] }, "elixirLS.languageServerOverridePath": { "scope": "resource", "type": "string", "description": "Absolute path to alternative ElixirLS release that will override the packaged release", "minLength": 0 }, "elixirLS.dotFormatter": { "scope": "resource", "type": "string", "description": "Path to a custom .formatter.exs file used when formatting documents", "minLength": 0 }, "elixirLS.mcpEnabled": { "scope": "resource", "type": "boolean", "description": "Enable or disable the MCP server", "default": false }, "elixirLS.mcpPort": { "scope": "resource", "type": "integer", "description": "Set a specific port for the MCP server. If not set, uses `3789 + hash(workspace_path)` for predictable port assignment per workspace", "default": 0 } } }, "languages": [ { "id": "elixir", "aliases": ["Elixir", "elixir"], "extensions": [".ex", ".exs"], "filenames": ["mix.lock"], "configuration": "./elixir-language-configuration.json" }, { "id": "eex", "aliases": ["Embedded Elixir", "EEx", "eex"], "extensions": [".eex", ".leex"], "configuration": "./eex-language-configuration.json" }, { "id": "html-eex", "aliases": ["HTML (Embedded Elixir)", "HTML (EEx)"], "extensions": [".html.eex", ".html.leex"], "configuration": "./eex-language-configuration.json" } ], "grammars": [ { "language": "elixir", "scopeName": "source.elixir", "path": "./syntaxes/elixir.json", "unbalancedBracketScopes": [ "keyword.operator.bitwise.elixir", "keyword.operator.other.unbalanced.elixir", "constant.language.symbol.elixir", "constant.language.symbol.single-quoted.elixir", "constant.language.symbol.double-quoted.elixir", "entity.name.function.call.dot.elixir" ], "embeddedLanguages": { "comment.documentation.heredoc.elixir": "markdown" } }, { "language": "eex", "scopeName": "text.elixir", "path": "./syntaxes/eex.json" }, { "language": "html-eex", "scopeName": "text.html.elixir", "path": "./syntaxes/html-eex.json" } ], "breakpoints": [ { "language": "elixir" } ], "debuggers": [ { "type": "mix_task", "label": "Mix Task", "windows": { "program": "debug_adapter.bat" }, "linux": { "program": "debug_adapter.sh" }, "osx": { "program": "debug_adapter.sh" }, "languages": ["elixir"], "configurationAttributes": { "launch": { "required": ["projectDir"], "properties": { "task": { "type": "string", "description": "Mix task name (without arguments)", "default": "run" }, "taskArgs": { "type": "array", "description": "List of arguments for task", "default": [], "items": { "type": "string" } }, "env": { "type": "object", "description": "Environment variables to set before debugging - You may want to set MIX_ENV in here." }, "debugAutoInterpretAllModules": { "type": "boolean", "description": "When debugging, interpret all files. Note: Only interpreted files will be part of the debugging stack traces. However this has a performance impact on large repositories, so if debugging is too slow, disable debugAutoInterpretFiles and use debugInterpretModulesPatterns to specify which files to interpret.", "default": true }, "debugInterpretModulesPatterns": { "type": "array", "description": "The modules to interpret when debugging - For details of interpreting, see the :int module in Erlang. Only modules that are interpreted will show up in the debugger stacktrace. An example of a pattern is: \"MyApp.*\", which will interpret all modules that begin with \"MyApp.\"", "items": { "type": "string", "minLength": 1 } }, "projectDir": { "type": "string", "description": "Project root directory (usually the workspace root)", "default": "${workspaceRoot}" }, "startApps": { "type": "boolean", "description": "Run apps.start before requiring files. This should be set to true for Phoenix tests, but false in most other cases.", "default": false }, "excludeModules": { "type": "array", "description": "Names of modules not to interpret - If a module contains NIFs, you should exclude it. Examples: Some.Module, :erlang_module", "items": { "type": "string", "minLength": 1 }, "uniqueItems": true }, "requireFiles": { "type": "array", "description": "Paths for any .exs files to interpret before debugging in the order they should be loaded. Accepts path wildcards.", "items": { "type": "string" } }, "stackTraceMode": { "type": "string", "description": "Option passed to :int.stack_trace/1. See https://www.erlang.org/doc/man/int#stack_trace-1 for details", "enum": ["all", "no_tail", "false"], "default": "no_tail" }, "exitAfterTaskReturns": { "type": "boolean", "description": "Should the debug session stop when mix task returns. Tasks that return early while the code continues running asynchronously require `false` setting.", "default": true }, "breakOnDbg": { "type": "boolean", "description": "Should the debugger break on Kernel.dbg/2 macro.", "default": true } } }, "attach": { "required": ["projectDir", "remoteNode"], "properties": { "remoteNode": { "type": "string", "description": "Remote OTP node to connect to" }, "env": { "type": "object", "description": "Environment variables to set before debugging - You may want to set MIX_ENV in here." }, "debugAutoInterpretAllModules": { "type": "boolean", "description": "When debugging, interpret all files. Note: Only interpreted files will be part of the debugging stack traces. However this has a performance impact on large repositories, so if debugging is too slow, disable debugAutoInterpretFiles and use debugInterpretModulesPatterns to specify which files to interpret.", "default": true }, "debugInterpretModulesPatterns": { "type": "array", "description": "The modules to interpret when debugging - For details of interpreting, see the :int module in Erlang. Only modules that are interpreted will show up in the debugger stacktrace. An example of a pattern is: \"MyApp.*\", which will interpret all modules that begin with \"MyApp.\"", "items": { "type": "string", "minLength": 1 } }, "projectDir": { "type": "string", "description": "Project root directory (usually the workspace root)", "default": "${workspaceRoot}" }, "excludeModules": { "type": "array", "description": "Names of modules not to interpret - If a module contains NIFs, you should exclude it. Examples: Some.Module, :erlang_module", "items": { "type": "string", "minLength": 1 }, "uniqueItems": true }, "stackTraceMode": { "type": "string", "description": "Option passed to :int.stack_trace/1. See https://www.erlang.org/doc/man/int#stack_trace-1 for details", "enum": ["all", "no_tail", "false"], "default": "no_tail" } } } }, "initialConfigurations": [ { "type": "mix_task", "name": "mix (Default task)", "request": "launch", "projectDir": "${workspaceRoot}" }, { "type": "mix_task", "name": "mix test", "request": "launch", "task": "test", "taskArgs": ["--trace"], "startApps": true, "projectDir": "${workspaceRoot}", "requireFiles": ["test/**/test_helper.exs", "test/**/*_test.exs"] } ], "configurationSnippets": [ { "label": "Elixir Mix", "description": "Launch a Mix task", "body": { "type": "mix_task", "request": "launch", "name": "mix ${1:task}", "task": "${1:task}", "taskArgs": [], "projectDir": "^\"\\${workspaceRoot}\"" } } ] } ], "problemMatchers": [ { "name": "mixCompileError", "owner": "elixir", "fileLocation": ["relative", "${workspaceRoot}"], "severity": "error", "pattern": { "regexp": "^\\*\\* \\((\\w+)\\) (.*):(\\d+): (.*)$", "file": 2, "location": 3, "message": 0 } }, { "name": "mixCompileWarning", "owner": "elixir", "fileLocation": ["relative", "${workspaceRoot}"], "severity": "warning", "pattern": [ { "regexp": "^warning: (.*)$", "message": 1 }, { "regexp": "^ (.*):(\\d+)(.*)$", "file": 1, "location": 2, "message": 3 } ] }, { "name": "mixTestFailure", "owner": "elixir", "fileLocation": ["relative", "${workspaceRoot}"], "severity": "warning", "pattern": [ { "regexp": "^\\s*\\d+\\) (.*)$", "message": 1 }, { "regexp": "^\\s*(.*):(\\d+)$", "file": 1, "location": 2 } ] } ], "commands": [ { "category": "Elixir", "command": "extension.copyDebugInfo", "title": "Copy ElixirLS Debug Info" }, { "category": "Elixir", "command": "extension.expandMacro", "title": "Expand macro" }, { "category": "Elixir", "command": "extension.restart", "title": "Restart language server" }, { "category": "Elixir", "command": "extension.mixClean", "title": "Trigger mix clean in language server" }, { "category": "Elixir", "command": "extension.mixCleanIncludeDeps", "title": "Trigger mix clean --deps in language server" }, { "category": "Elixir", "command": "extension.toPipe", "title": "Transform function call to pipe operator" }, { "category": "Elixir", "command": "extension.fromPipe", "title": "Transform pipe operator to function call" } ], "menus": { "commandPalette": [ { "category": "Elixir", "command": "extension.copyDebugInfo", "when": "editorLangId == elixir || editorLangId == eex || editorLangId == html-eex" }, { "category": "Elixir", "command": "extension.expandMacro", "when": "editorLangId == elixir || editorLangId == eex || editorLangId == html-eex" }, { "category": "Elixir", "command": "extension.restart", "when": "editorLangId == elixir || editorLangId == eex || editorLangId == html-eex" }, { "category": "Elixir", "command": "extension.mixClean", "when": "editorLangId == elixir || editorLangId == eex || editorLangId == html-eex" }, { "category": "Elixir", "command": "extension.mixCleanIncludeDeps", "when": "editorLangId == elixir || editorLangId == eex || editorLangId == html-eex" }, { "category": "Elixir", "command": "extension.toPipe", "when": "editorLangId == elixir || editorLangId == eex || editorLangId == html-eex" }, { "category": "Elixir", "command": "extension.fromPipe", "when": "editorLangId == elixir || editorLangId == eex || editorLangId == html-eex" } ] }, "taskDefinitions": [ { "type": "mix", "required": ["task"], "properties": { "task": { "type": "string", "description": "The Mix task" } } } ], "languageModelTools": [ { "name": "elixir-definition", "displayName": "Elixir Definition Lookup", "modelDescription": "Find and retrieve the source code definition of Elixir/Erlang symbols including modules, functions, types, macros, and callbacks. Returns the actual source code with file location and line numbers for precise code inspection.", "canBeReferencedInPrompt": true, "toolReferenceName": "elixir-definition", "inputSchema": { "type": "object", "required": ["symbol"], "properties": { "symbol": { "type": "string", "description": "The symbol to find definition for. Supports: modules ('MyModule', 'GenServer'), functions ('MyModule.function', 'String.split/2'), types ('@type my_type'), macros ('defmacro'), Erlang modules (':gen_server'), Erlang functions (':lists.map/2'). Use qualified names (Module.function) for best results." } } } }, { "name": "elixir-environment", "displayName": "Elixir Environment Lookup", "modelDescription": "Get comprehensive environment information at a specific code location including current module/function context, available aliases, imports, requires, variables in scope with their inferred types, module attributes, implemented behaviours, and all definitions in the file. Essential for understanding code context and available symbols.", "canBeReferencedInPrompt": true, "toolReferenceName": "elixir-environment", "inputSchema": { "type": "object", "required": ["location"], "properties": { "location": { "type": "string", "description": "Location in the code to analyze context. Formats: 'file.ex:line:column', 'file.ex:line', 'lib/my_module.ex:25:10', 'file:///absolute/path/file.ex:10:5'. Use specific line/column for better variable scope and context analysis. Line numbers start at 1." } } } }, { "name": "elixir-module-dependencies", "displayName": "Elixir Module Dependencies", "modelDescription": "Analyze comprehensive module dependency relationships including direct/reverse dependencies, transitive dependencies, compile-time vs runtime dependencies, imports, aliases, requires, function calls, and struct expansions. Critical for understanding code architecture, impact analysis, and refactoring decisions.", "canBeReferencedInPrompt": true, "toolReferenceName": "elixir-module-dependencies", "inputSchema": { "type": "object", "required": ["module"], "properties": { "module": { "type": "string", "description": "The module name to analyze dependencies for. Supports Elixir modules ('MyApp.MyModule', 'GenServer', 'Enum') and Erlang modules (':gen_server', ':ets'). Returns categorized dependency breakdown showing what the module depends on and what depends on it." } } } }, { "name": "elixir-docs", "displayName": "Elixir Documentation Aggregator", "modelDescription": "Aggregate and return comprehensive documentation for multiple Elixir modules, functions, types, callbacks, or attributes in a single efficient request. Supports both module-level documentation (with function/type listings) and specific symbol documentation with examples and usage patterns.", "canBeReferencedInPrompt": true, "toolReferenceName": "elixir-docs", "inputSchema": { "type": "object", "required": ["modules"], "properties": { "modules": { "type": "array", "description": "List of symbols to get documentation for. Supports: modules ('Enum', 'GenServer'), functions ('String.split/2', 'Enum.map'), types ('Enum.t/0', 'GenServer.on_start/0'), callbacks ('GenServer.handle_call', 'Application.start'), attributes ('@moduledoc', '@doc'). Mix different symbol types for comprehensive API understanding.", "items": { "type": "string" } } } } }, { "name": "elixir-implementation-finder", "displayName": "Elixir Implementation Finder", "modelDescription": "Find all concrete implementations of Elixir behaviours, protocols, callbacks, and delegated functions across the entire codebase. Essential for discovering how abstract interfaces are implemented and understanding polymorphic behavior patterns.", "canBeReferencedInPrompt": true, "toolReferenceName": "elixir-implementation-finder", "inputSchema": { "type": "object", "required": ["symbol"], "properties": { "symbol": { "type": "string", "description": "The symbol to find implementations for. Supports: behaviours ('GenServer', 'Application', 'Supervisor'), protocols ('Enumerable', 'Inspect', 'String.Chars'), callbacks ('GenServer.handle_call', 'Application.start'), functions with @impl annotations. Returns file locations and implementation signatures." } } } }, { "name": "elixir-types", "displayName": "Elixir Type Information", "modelDescription": "Extract comprehensive type information from Elixir modules including @type definitions, @spec annotations, @callback specifications, and Dialyzer inferred contracts. Essential for understanding module interfaces, type safety, function signatures, and behaviour contracts.", "canBeReferencedInPrompt": true, "toolReferenceName": "elixir-types", "inputSchema": { "type": "object", "required": ["module"], "properties": { "module": { "type": "string", "description": "The module name to analyze type information for. Supports Elixir modules ('GenServer', 'MyApp.MyModule', 'Enum') and Erlang modules (':gen_server', ':ets'). Returns detailed type specifications, function signatures, callback definitions, and custom types with their documentation." } } } } ] }, "scripts": { "release-elixir-ls": "cd elixir-ls && mix elixir_ls.release2 -o ../elixir-ls-release", "vscode:prepublish": "npm-run-all release-elixir-ls esbuild-release", "mixcompile": "mix compile", "mixcompile-esbuild": "npm-run-all mixcompile esbuild", "clean": "rimraf ./out", "compile": "tsc -b", "watch": "tsc -b -w", "update-vscode": "node ./node_modules/vscode/bin/install", "pretest": "npm-run-all clean compile", "test": "node ./out/test/runTest.js", "lint": "biome check", "fix-formatting": "biome format --write", "esbuild-release": "npm run esbuild-base -- --minify", "esbuild-base": "esbuild ./src/extension.ts --bundle --outfile=out/extension.js --external:vscode --format=cjs --platform=node", "esbuild": "npm run esbuild-base -- --sourcemap", "esbuild-watch": "npm run esbuild-base -- --sourcemap --watch" }, "devDependencies": { "@biomejs/biome": "^1.9.4", "@types/mocha": "^10.0.10", "@types/node": "^20.17.50", "@types/vscode": "~1.95.0", "@vscode/debugprotocol": "^1.68.0", "@vscode/test-electron": "^2.5.2", "esbuild": "^0.25.8", "glob": "^11.0.3", "mocha": "^11.7.1", "npm-run-all": "^4.1.5", "rimraf": "^6.0.1", "typescript": "~5.9.2" }, "dependencies": { "@vscode/extension-telemetry": "^1.0.0", "vscode-languageclient": "^9.0.1" } }