├── VERSION ├── apps ├── language_server │ ├── test │ │ ├── fixtures │ │ │ ├── formatter │ │ │ │ ├── symlink │ │ │ │ ├── test │ │ │ │ │ └── .formatter.exs │ │ │ │ ├── apps │ │ │ │ │ └── foo │ │ │ │ │ │ └── .formatter.exs │ │ │ │ ├── lib │ │ │ │ │ └── .formatter.exs │ │ │ │ ├── .formatter.exs │ │ │ │ └── mix.exs │ │ │ ├── no_mixfile │ │ │ │ └── a.ex │ │ │ ├── build_errors_on_external_resource │ │ │ │ ├── lib │ │ │ │ │ ├── template.eex │ │ │ │ │ └── has_error.ex │ │ │ │ └── mix.exs │ │ │ ├── clean │ │ │ │ ├── lib │ │ │ │ │ ├── b.ex │ │ │ │ │ ├── c.ex │ │ │ │ │ └── a.ex │ │ │ │ └── mix.exs │ │ │ ├── dialyzer │ │ │ │ ├── lib │ │ │ │ │ ├── c.ex │ │ │ │ │ ├── b.ex │ │ │ │ │ ├── a.ex │ │ │ │ │ └── suggest.ex │ │ │ │ └── mix.exs │ │ │ ├── references │ │ │ │ ├── lib │ │ │ │ │ ├── b.ex │ │ │ │ │ └── a.ex │ │ │ │ └── mix.exs │ │ │ ├── umbrella │ │ │ │ ├── apps │ │ │ │ │ ├── app2 │ │ │ │ │ │ ├── lib │ │ │ │ │ │ │ ├── app2.ex │ │ │ │ │ │ │ └── app2 │ │ │ │ │ │ │ │ └── foo.ex │ │ │ │ │ │ └── mix.exs │ │ │ │ │ └── app1 │ │ │ │ │ │ ├── lib │ │ │ │ │ │ └── app1.ex │ │ │ │ │ │ └── mix.exs │ │ │ │ └── mix.exs │ │ │ ├── umbrella_dialyzer │ │ │ │ ├── apps │ │ │ │ │ ├── app2 │ │ │ │ │ │ ├── lib │ │ │ │ │ │ │ └── app2.ex │ │ │ │ │ │ └── mix.exs │ │ │ │ │ └── app1 │ │ │ │ │ │ ├── lib │ │ │ │ │ │ └── app1.ex │ │ │ │ │ │ └── mix.exs │ │ │ │ └── mix.exs │ │ │ ├── protocols │ │ │ │ ├── lib │ │ │ │ │ ├── example.ex │ │ │ │ │ └── implementations.ex │ │ │ │ └── mix.exs │ │ │ ├── test_code_lens │ │ │ │ ├── test │ │ │ │ │ └── fixture_test.exs │ │ │ │ └── mix.exs │ │ │ ├── umbrella_test_code_lens │ │ │ │ ├── mix.exs │ │ │ │ └── apps │ │ │ │ │ ├── app │ │ │ │ │ ├── test │ │ │ │ │ │ └── fixture_custom_test.exs │ │ │ │ │ └── mix.exs │ │ │ │ │ └── app1 │ │ │ │ │ ├── test │ │ │ │ │ └── fixture_custom_test.exs │ │ │ │ │ └── mix.exs │ │ │ ├── build_errors │ │ │ │ ├── lib │ │ │ │ │ └── has_error.ex │ │ │ │ └── mix.exs │ │ │ ├── umbrella_test_code_lens_custom_path_and_pattern │ │ │ │ ├── mix.exs │ │ │ │ └── apps │ │ │ │ │ └── app1 │ │ │ │ │ ├── custom_path │ │ │ │ │ └── fixture_custom_test.exs │ │ │ │ │ └── mix.exs │ │ │ ├── test_code_lens_custom_paths_and_pattern │ │ │ │ ├── custom_path │ │ │ │ │ └── fixture_custom_test.exs │ │ │ │ └── mix.exs │ │ │ ├── token_missing_error │ │ │ │ ├── mix.exs │ │ │ │ └── lib │ │ │ │ │ └── has_error.ex │ │ │ └── workspace_symbols │ │ │ │ ├── lib │ │ │ │ └── workspace_symbols.ex │ │ │ │ └── mix.exs │ │ ├── support │ │ │ ├── fixtures │ │ │ │ ├── .elixir_ls │ │ │ │ │ └── .gitkeep │ │ │ │ ├── example_struct.ex │ │ │ │ ├── example_exception.ex │ │ │ │ ├── references_erlang.ex │ │ │ │ ├── remote_function.ex │ │ │ │ ├── example_deprecated_module.ex │ │ │ │ ├── module_deps_e.ex │ │ │ │ ├── example_quoted_defs.ex │ │ │ │ ├── example_docs.ex │ │ │ │ ├── example_default_args.ex │ │ │ │ ├── macro_a.ex │ │ │ │ ├── references_imported.ex │ │ │ │ ├── example_protocol.ex │ │ │ │ ├── references_remote.ex │ │ │ │ ├── uses_macro_a.ex │ │ │ │ ├── example_behaviour.ex │ │ │ │ ├── references_alias.ex │ │ │ │ └── references_referenced.ex │ │ │ ├── references │ │ │ │ ├── simple_module.ex │ │ │ │ ├── module_with_def.ex │ │ │ │ ├── module_with_defmacro.ex │ │ │ │ ├── local_call.ex │ │ │ │ ├── local_macro_call.ex │ │ │ │ ├── struct.ex │ │ │ │ ├── super.ex │ │ │ │ ├── alias.ex │ │ │ │ ├── require_as.ex │ │ │ │ ├── require.ex │ │ │ │ ├── import.ex │ │ │ │ ├── remote_call.ex │ │ │ │ ├── captures.ex │ │ │ │ └── quoted.ex │ │ │ ├── plugins │ │ │ │ ├── phoenix │ │ │ │ │ ├── router.ex │ │ │ │ │ └── page_controller.ex │ │ │ │ └── ecto │ │ │ │ │ ├── uuid.ex │ │ │ │ │ └── migration.ex │ │ │ ├── empty_module.ex │ │ │ ├── use_example.ex │ │ │ ├── same_module.ex │ │ │ ├── case_template_example.ex │ │ │ ├── module_with_builtin_type_shadowing.ex │ │ │ ├── subscriber.ex │ │ │ ├── behaviour_implementations.ex │ │ │ ├── module_with_record.ex │ │ │ ├── module_with_many_clauses.ex │ │ │ ├── module_with_private_types.ex │ │ │ ├── fixture_helpers.ex │ │ │ ├── paths.ex │ │ │ ├── example_protocol.ex │ │ │ ├── macro_generated.ex │ │ │ ├── stuct_with_typespec.ex │ │ │ ├── subscription.ex │ │ │ ├── callback_opaque.ex │ │ │ ├── test_utils.ex │ │ │ ├── module_with_struct.ex │ │ │ ├── platform_test_helpers.ex │ │ │ ├── functions_with_the_same_name.ex │ │ │ ├── module_with_types.ex │ │ │ ├── types_with_multiple_arity.ex │ │ │ ├── module_with_functions.ex │ │ │ ├── references_local_vs_remote.ex │ │ │ └── parser_context_builder.ex │ │ ├── location │ │ │ └── sample_erl │ │ ├── providers │ │ │ └── folding_range │ │ │ │ ├── token_pairs_test.exs │ │ │ │ ├── indentation_test.exs │ │ │ │ ├── comment_block_test.exs │ │ │ │ └── special_token_test.exs │ │ ├── test_helper.exs │ │ └── mix_project_cache_test.exs │ ├── .dialyzer_ignore.exs │ ├── lib │ │ └── language_server │ │ │ ├── lsp │ │ │ └── protocol │ │ │ │ ├── base_types.ex │ │ │ │ ├── type_aliases │ │ │ │ ├── progress_token.ex │ │ │ │ ├── lsp_array.ex │ │ │ │ ├── lsp_object.ex │ │ │ │ ├── change_annotation_identifier.ex │ │ │ │ ├── declaration.ex │ │ │ │ ├── glob_pattern.ex │ │ │ │ ├── definition_link.ex │ │ │ │ ├── prepare_rename_result.ex │ │ │ │ ├── document_selector.ex │ │ │ │ ├── declaration_link.ex │ │ │ │ ├── document_filter.ex │ │ │ │ ├── workspace_document_diagnostic_report.ex │ │ │ │ ├── definition.ex │ │ │ │ └── text_document_content_change_event.ex │ │ │ │ ├── enumerations │ │ │ │ ├── token_format.ex │ │ │ │ ├── prepare_support_default_behavior.ex │ │ │ │ ├── symbol_tag.ex │ │ │ │ ├── completion_item_tag.ex │ │ │ │ ├── inlay_hint_kind.ex │ │ │ │ ├── notebook_cell_kind.ex │ │ │ │ ├── watch_kind.ex │ │ │ │ ├── trace_values.ex │ │ │ │ ├── file_change_type.ex │ │ │ │ ├── file_operation_pattern_kind.ex │ │ │ │ ├── document_highlight_kind.ex │ │ │ │ ├── document_diagnostic_report_kind.ex │ │ │ │ ├── resource_operation_kind.ex │ │ │ │ └── message_type.ex │ │ │ │ ├── structures │ │ │ │ ├── initialized_params.ex │ │ │ │ ├── cancel_params.ex │ │ │ │ ├── moniker_options.ex │ │ │ │ ├── declaration_options.ex │ │ │ │ ├── message_action_item.ex │ │ │ │ ├── document_color_options.ex │ │ │ │ ├── folding_range_options.ex │ │ │ │ ├── implementation_options.ex │ │ │ │ ├── selection_range_options.ex │ │ │ │ ├── set_trace_params.ex │ │ │ │ ├── type_definition_options.ex │ │ │ │ ├── linked_editing_range_options.ex │ │ │ │ ├── work_done_progress_options.ex │ │ │ │ ├── did_change_configuration_registration_options.ex │ │ │ │ ├── hover_options.ex │ │ │ │ ├── reference_options.ex │ │ │ │ ├── registration_params.ex │ │ │ │ ├── semantic_tokens_partial_result.ex │ │ │ │ ├── log_trace_params.ex │ │ │ │ ├── save_options.ex │ │ │ │ ├── work_done_progress_cancel_params.ex │ │ │ │ ├── work_done_progress_create_params.ex │ │ │ │ ├── unregistration_params.ex │ │ │ │ ├── definition_options.ex │ │ │ │ ├── text_document_identifier.ex │ │ │ │ ├── document_highlight_options.ex │ │ │ │ ├── document_formatting_options.ex │ │ │ │ ├── file_create.ex │ │ │ │ ├── file_delete.ex │ │ │ │ ├── did_change_configuration_client_capabilities.ex │ │ │ │ ├── show_document_result.ex │ │ │ │ ├── configuration_params.ex │ │ │ │ ├── inline_value_options.ex │ │ │ │ ├── semantic_tokens_delta_partial_result.ex │ │ │ │ ├── work_done_progress_params.ex │ │ │ │ ├── call_hierarchy_options.ex │ │ │ │ ├── document_range_formatting_options.ex │ │ │ │ ├── notebook_document_identifier.ex │ │ │ │ ├── type_hierarchy_options.ex │ │ │ │ ├── code_description.ex │ │ │ │ ├── configuration_item.ex │ │ │ │ ├── diagnostic_server_cancellation_data.ex │ │ │ │ ├── execute_command_registration_options.ex │ │ │ │ ├── did_change_configuration_params.ex │ │ │ │ ├── file_operation_pattern_options.ex │ │ │ │ ├── work_done_progress_end.ex │ │ │ │ ├── did_change_watched_files_params.ex │ │ │ │ ├── show_document_client_capabilities.ex │ │ │ │ ├── code_lens_client_capabilities.ex │ │ │ │ ├── reference_client_capabilities.ex │ │ │ │ ├── reference_context.ex │ │ │ │ ├── workspace_diagnostic_report.ex │ │ │ │ ├── execute_command_client_capabilities.ex │ │ │ │ ├── partial_result_params.ex │ │ │ │ ├── static_registration_options.ex │ │ │ │ ├── document_formatting_client_capabilities.ex │ │ │ │ ├── did_open_text_document_params.ex │ │ │ │ ├── document_highlight_client_capabilities.ex │ │ │ │ ├── did_close_text_document_params.ex │ │ │ │ ├── file_operation_registration_options.ex │ │ │ │ ├── document_range_formatting_client_capabilities.ex │ │ │ │ ├── location.ex │ │ │ │ ├── did_change_workspace_folders_params.ex │ │ │ │ ├── document_on_type_formatting_client_capabilities.ex │ │ │ │ ├── file_event.ex │ │ │ │ ├── inline_value_client_capabilities.ex │ │ │ │ ├── progress_params.ex │ │ │ │ ├── workspace_diagnostic_report_partial_result.ex │ │ │ │ ├── create_files_params.ex │ │ │ │ ├── delete_files_params.ex │ │ │ │ ├── did_change_watched_files_registration_options.ex │ │ │ │ ├── create_file_options.ex │ │ │ │ ├── document_color_client_capabilities.ex │ │ │ │ ├── log_message_params.ex │ │ │ │ ├── workspace_symbol_registration_options.ex │ │ │ │ ├── moniker_registration_options.ex │ │ │ │ ├── rename_file_options.ex │ │ │ │ ├── regular_expressions_client_capabilities.ex │ │ │ │ ├── semantic_tokens_legend.ex │ │ │ │ ├── show_message_params.ex │ │ │ │ ├── code_lens_options.ex │ │ │ │ ├── execute_command_options.ex │ │ │ │ ├── inline_value_text.ex │ │ │ │ ├── previous_result_id.ex │ │ │ │ ├── workspace_folder.ex │ │ │ │ ├── delete_file_options.ex │ │ │ │ ├── document_link_options.ex │ │ │ │ ├── selection_range_client_capabilities.ex │ │ │ │ ├── semantic_tokens_delta.ex │ │ │ │ ├── unregistration.ex │ │ │ │ ├── versioned_text_document_identifier.ex │ │ │ │ ├── did_save_notebook_document_params.ex │ │ │ │ ├── versioned_notebook_document_identifier.ex │ │ │ │ ├── execution_summary.ex │ │ │ │ └── show_message_request_client_capabilities.ex │ │ │ │ └── notifications │ │ │ │ ├── dollar_log_trace.ex │ │ │ │ ├── dollar_progress.ex │ │ │ │ ├── dollar_set_trace.ex │ │ │ │ ├── dollar_cancel_request.ex │ │ │ │ ├── exit.ex │ │ │ │ ├── notebook_document_did_change.ex │ │ │ │ └── telemetry_event.ex │ │ │ ├── providers │ │ │ ├── code_lens │ │ │ │ └── test │ │ │ │ │ └── test_block.ex │ │ │ ├── folding_range │ │ │ │ └── helpers.ex │ │ │ ├── code_action.ex │ │ │ ├── execute_command │ │ │ │ ├── get_ex_unit_tests_in_file.ex │ │ │ │ ├── mix_clean.ex │ │ │ │ └── restart.ex │ │ │ ├── implementation.ex │ │ │ ├── definition.ex │ │ │ └── code_mod │ │ │ │ └── ast.ex │ │ │ ├── mcp │ │ │ └── supervisor.ex │ │ │ └── dialyzer │ │ │ └── supervisor.ex │ ├── test_fixtures │ │ └── fixtures │ │ │ └── project_with_tests │ │ │ ├── mix.exs │ │ │ └── test │ │ │ ├── error_test.exs │ │ │ └── fixture_test.exs │ └── .gitignore ├── elixir_ls_utils │ ├── test │ │ ├── fixtures │ │ │ └── protocol_messages │ │ │ │ ├── no_body_5 │ │ │ │ ├── no_body_6 │ │ │ │ ├── no_body_4 │ │ │ │ ├── no_body_3 │ │ │ │ ├── no_body_2 │ │ │ │ ├── no_body_1 │ │ │ │ ├── no_body_0 │ │ │ │ ├── invalid_json │ │ │ │ ├── valid_message │ │ │ │ ├── invalid_content_length │ │ │ │ ├── valid_message_utf │ │ │ │ ├── invalid_content_type │ │ │ │ ├── valid_messages │ │ │ │ ├── valid_message_content_type │ │ │ │ └── invalid_after_valid │ │ ├── test_helper.exs │ │ ├── matcher_test.exs │ │ ├── placeholder_test.exs │ │ ├── support │ │ │ ├── module_with_struct.ex │ │ │ └── test_utils.ex │ │ ├── changelog_test.exs │ │ └── launch_test.exs │ ├── lib │ │ ├── mixfile_helpers.ex │ │ └── mix.tasks.elixir_ls.release2.ex │ ├── .formatter.exs │ └── .gitignore └── debug_adapter │ ├── test │ ├── fixtures │ │ ├── mix_project │ │ │ ├── test │ │ │ │ ├── test_helper.exs │ │ │ │ └── mix_project_fixturetest.exs │ │ │ ├── lib │ │ │ │ └── crash.ex │ │ │ ├── src │ │ │ │ └── hello.erl │ │ │ ├── .vscode │ │ │ │ └── launch.json │ │ │ ├── README.md │ │ │ └── .gitignore │ │ └── no_mix_exs │ │ │ └── script.exs │ ├── test_helper.exs │ └── output_test.exs │ ├── .formatter.exs │ ├── .gitignore │ └── lib │ ├── protocol │ └── dap │ │ ├── structures │ │ ├── loaded_sources_arguments.ex │ │ ├── configuration_done_arguments.ex │ │ ├── value_format.ex │ │ ├── pause_arguments.ex │ │ ├── locations_arguments.ex │ │ ├── terminate_threads_arguments.ex │ │ ├── thread.ex │ │ ├── exception_info_arguments.ex │ │ ├── terminate_arguments.ex │ │ ├── step_in_targets_arguments.ex │ │ ├── set_function_breakpoints_arguments.ex │ │ ├── goto_arguments.ex │ │ ├── scopes_arguments.ex │ │ ├── restart_frame_arguments.ex │ │ └── attach_request_arguments.ex │ │ └── enumerations │ │ ├── data_breakpoint_access_type.ex │ │ └── checksum_algorithm.ex │ └── debug_adapter │ ├── error_dictionary.ex │ └── module_info_cache.ex ├── images └── screenshot.png ├── .gitattributes ├── docs ├── getting-started │ ├── nova.md │ ├── kate.md │ ├── sublime.md │ ├── neovim.md │ └── overview.md └── known-issues-limitations.md ├── .dialyzer_ignore.exs ├── .github ├── dependabot.yml └── CONTRIBUTING.md ├── .formatter.exs ├── .editorconfig ├── Dockerfile ├── scripts ├── exec.zsh ├── exec.bash ├── quiet_install.exs ├── debug_adapter.sh ├── elixir_check.sh ├── language_server.sh ├── debug_adapter.bat └── elixir_check.bat ├── dep_versions.exs └── mix.exs /VERSION: -------------------------------------------------------------------------------- 1 | 0.30.0 2 | -------------------------------------------------------------------------------- /apps/language_server/test/fixtures/formatter/symlink: -------------------------------------------------------------------------------- 1 | test -------------------------------------------------------------------------------- /apps/elixir_ls_utils/test/fixtures/protocol_messages/no_body_5: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /apps/elixir_ls_utils/test/fixtures/protocol_messages/no_body_6: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /apps/language_server/test/support/fixtures/.elixir_ls/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /apps/elixir_ls_utils/test/fixtures/protocol_messages/no_body_4: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /apps/elixir_ls_utils/test/fixtures/protocol_messages/no_body_3: -------------------------------------------------------------------------------- 1 | Content-Len -------------------------------------------------------------------------------- /apps/language_server/test/fixtures/no_mixfile/a.ex: -------------------------------------------------------------------------------- 1 | defmodule A do 2 | end 3 | -------------------------------------------------------------------------------- /apps/elixir_ls_utils/test/fixtures/protocol_messages/no_body_2: -------------------------------------------------------------------------------- 1 | Content-Length: 15 -------------------------------------------------------------------------------- /apps/debug_adapter/test/fixtures/mix_project/test/test_helper.exs: -------------------------------------------------------------------------------- 1 | ExUnit.start() 2 | -------------------------------------------------------------------------------- /apps/elixir_ls_utils/test/fixtures/protocol_messages/no_body_1: -------------------------------------------------------------------------------- 1 | Content-Length: 15 2 | -------------------------------------------------------------------------------- /apps/elixir_ls_utils/test/test_helper.exs: -------------------------------------------------------------------------------- 1 | ExUnit.start(exclude: [pending: true]) 2 | -------------------------------------------------------------------------------- /apps/elixir_ls_utils/test/fixtures/protocol_messages/no_body_0: -------------------------------------------------------------------------------- 1 | Content-Length: 15 2 | 3 | -------------------------------------------------------------------------------- /images/screenshot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/elixir-lsp/elixir-ls/HEAD/images/screenshot.png -------------------------------------------------------------------------------- /apps/language_server/test/fixtures/formatter/test/.formatter.exs: -------------------------------------------------------------------------------- 1 | [ 2 | inputs: ["*.exs"] 3 | ] 4 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | # Don't convert batch files' line endings. They should always be CRLF. 2 | *.bat binary 3 | -------------------------------------------------------------------------------- /apps/language_server/test/fixtures/formatter/apps/foo/.formatter.exs: -------------------------------------------------------------------------------- 1 | [ 2 | inputs: ["foo.ex"] 3 | ] 4 | -------------------------------------------------------------------------------- /apps/elixir_ls_utils/test/fixtures/protocol_messages/invalid_json: -------------------------------------------------------------------------------- 1 | Content-Length: 15 2 | 3 | {"some":"value} -------------------------------------------------------------------------------- /apps/elixir_ls_utils/test/fixtures/protocol_messages/valid_message: -------------------------------------------------------------------------------- 1 | Content-Length: 16 2 | 3 | {"some":"value"} -------------------------------------------------------------------------------- /apps/elixir_ls_utils/test/fixtures/protocol_messages/invalid_content_length: -------------------------------------------------------------------------------- 1 | Content-Length: 16 2 | 3 | {"some":"val -------------------------------------------------------------------------------- /apps/language_server/test/fixtures/build_errors_on_external_resource/lib/template.eex: -------------------------------------------------------------------------------- 1 | line 1 2 | <%= , %> 3 | line 3 -------------------------------------------------------------------------------- /apps/language_server/test/fixtures/clean/lib/b.ex: -------------------------------------------------------------------------------- 1 | defmodule B do 2 | def fun do 3 | :error 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /apps/language_server/test/fixtures/clean/lib/c.ex: -------------------------------------------------------------------------------- 1 | defmodule C do 2 | def myfun do 3 | 1 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /apps/language_server/test/fixtures/dialyzer/lib/c.ex: -------------------------------------------------------------------------------- 1 | defmodule C do 2 | def myfun do 3 | 1 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /apps/language_server/test/fixtures/dialyzer/lib/b.ex: -------------------------------------------------------------------------------- 1 | defmodule B do 2 | def fun do 3 | :error 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /apps/language_server/test/fixtures/references/lib/b.ex: -------------------------------------------------------------------------------- 1 | defmodule B do 2 | def my_fun do 3 | :ok 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /apps/debug_adapter/.formatter.exs: -------------------------------------------------------------------------------- 1 | [ 2 | inputs: [ 3 | "*.exs", 4 | "{lib,test,config}/**/*.{ex,exs}" 5 | ] 6 | ] 7 | -------------------------------------------------------------------------------- /apps/elixir_ls_utils/test/fixtures/protocol_messages/valid_message_utf: -------------------------------------------------------------------------------- 1 | Content-Length: 34 2 | 3 | {"some":"👨‍👩‍👦 test"} -------------------------------------------------------------------------------- /apps/language_server/test/fixtures/clean/lib/a.ex: -------------------------------------------------------------------------------- 1 | defmodule A do 2 | def fun do 3 | :ok = B.fun() 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /apps/language_server/test/fixtures/dialyzer/lib/a.ex: -------------------------------------------------------------------------------- 1 | defmodule A do 2 | def fun do 3 | :ok = B.fun() 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /apps/language_server/.dialyzer_ignore.exs: -------------------------------------------------------------------------------- 1 | [ 2 | {"lib/language_server/providers/execute_command/restart.ex", :no_return} 3 | ] 4 | -------------------------------------------------------------------------------- /apps/language_server/test/fixtures/references/lib/a.ex: -------------------------------------------------------------------------------- 1 | defmodule A do 2 | def other_fun do 3 | B.my_fun() 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /apps/language_server/test/support/references/simple_module.ex: -------------------------------------------------------------------------------- 1 | defmodule ElixirSenseExample.References.SimpleModule do 2 | end 3 | -------------------------------------------------------------------------------- /apps/language_server/test/fixtures/formatter/lib/.formatter.exs: -------------------------------------------------------------------------------- 1 | [ 2 | inputs: ["*.ex"], 3 | locals_without_parens: [foo: 1] 4 | ] 5 | -------------------------------------------------------------------------------- /apps/language_server/test/fixtures/umbrella/apps/app2/lib/app2.ex: -------------------------------------------------------------------------------- 1 | defmodule App2 do 2 | def hello do 3 | :app2 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /apps/language_server/test/fixtures/umbrella/apps/app1/lib/app1.ex: -------------------------------------------------------------------------------- 1 | defmodule App1 do 2 | def hello() do 3 | App2.hello() 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /apps/language_server/test/fixtures/umbrella/apps/app2/lib/app2/foo.ex: -------------------------------------------------------------------------------- 1 | defmodule App2.Foo do 2 | def hello do 3 | :foo 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /apps/language_server/test/fixtures/umbrella_dialyzer/apps/app2/lib/app2.ex: -------------------------------------------------------------------------------- 1 | defmodule App2 do 2 | def error do 3 | :error 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /docs/getting-started/nova.md: -------------------------------------------------------------------------------- 1 | # Nova 2 | 3 | ## Setup 4 | 5 | Install the [extension for Nova](https://github.com/raulchedrese/nova-elixir-ls). 6 | -------------------------------------------------------------------------------- /apps/elixir_ls_utils/test/fixtures/protocol_messages/invalid_content_type: -------------------------------------------------------------------------------- 1 | Content-Length: 16 2 | Content-Type: text/plain 3 | 4 | {"some":"value"} -------------------------------------------------------------------------------- /apps/language_server/test/fixtures/protocols/lib/example.ex: -------------------------------------------------------------------------------- 1 | defprotocol Protocols.Example do 2 | @spec some(t) :: any 3 | def some(t) 4 | end 5 | -------------------------------------------------------------------------------- /.dialyzer_ignore.exs: -------------------------------------------------------------------------------- 1 | [ 2 | {"lib/launch.ex", :unknown_function}, 3 | {"lib/language_server/providers/execute_command/restart.ex", :no_return} 4 | ] 5 | -------------------------------------------------------------------------------- /apps/language_server/test/support/fixtures/example_struct.ex: -------------------------------------------------------------------------------- 1 | defmodule ElixirLS.LanguageServer.Fixtures.ExampleStruct do 2 | defstruct [:name] 3 | end 4 | -------------------------------------------------------------------------------- /apps/language_server/test/support/references/module_with_def.ex: -------------------------------------------------------------------------------- 1 | defmodule ElixirSenseExample.References.ModuleWithDef do 2 | def foo(), do: :ok 3 | end 4 | -------------------------------------------------------------------------------- /apps/debug_adapter/test/fixtures/mix_project/lib/crash.ex: -------------------------------------------------------------------------------- 1 | defmodule MixProject.Crash do 2 | def fun_that_raises() do 3 | raise "foo" 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /apps/elixir_ls_utils/test/fixtures/protocol_messages/valid_messages: -------------------------------------------------------------------------------- 1 | Content-Length: 16 2 | 3 | {"some":"value"}Content-Length: 17 4 | 5 | {"some":"value1"} -------------------------------------------------------------------------------- /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | version: 2 2 | updates: 3 | - package-ecosystem: "github-actions" 4 | directory: "/" 5 | schedule: 6 | interval: "weekly" 7 | -------------------------------------------------------------------------------- /apps/elixir_ls_utils/test/matcher_test.exs: -------------------------------------------------------------------------------- 1 | defmodule ElixirLS.Utils.MatcherTest do 2 | use ExUnit.Case, async: true 3 | doctest ElixirLS.Utils.Matcher 4 | end 5 | -------------------------------------------------------------------------------- /apps/language_server/test/fixtures/umbrella_dialyzer/apps/app1/lib/app1.ex: -------------------------------------------------------------------------------- 1 | defmodule App1 do 2 | def check_error() do 3 | :ok = App2.error() 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /apps/language_server/test/support/fixtures/example_exception.ex: -------------------------------------------------------------------------------- 1 | defmodule ElixirLS.LanguageServer.Fixtures.ExampleException do 2 | defexception [:message] 3 | end 4 | -------------------------------------------------------------------------------- /apps/language_server/test/support/plugins/phoenix/router.ex: -------------------------------------------------------------------------------- 1 | defmodule Phoenix.Router do 2 | def get(_route, _plug, _plut_opts, _opts \\ []) do 3 | end 4 | end 5 | -------------------------------------------------------------------------------- /apps/debug_adapter/test/fixtures/mix_project/src/hello.erl: -------------------------------------------------------------------------------- 1 | -module(hello). 2 | -export([hello_world/0]). 3 | 4 | hello_world() -> 5 | io:fwrite("hello, world\n"). 6 | -------------------------------------------------------------------------------- /apps/elixir_ls_utils/lib/mixfile_helpers.ex: -------------------------------------------------------------------------------- 1 | defmodule ElixirLS.Utils.MixfileHelpers do 2 | def mix_exs do 3 | System.get_env("MIX_EXS") || "mix.exs" 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /apps/language_server/test/support/references/module_with_defmacro.ex: -------------------------------------------------------------------------------- 1 | defmodule ElixirSenseExample.References.ModuleWithDefMacro do 2 | defmacro foo_macro(), do: :ok 3 | end 4 | -------------------------------------------------------------------------------- /docs/getting-started/kate.md: -------------------------------------------------------------------------------- 1 | # Kate 2 | 3 | ## Setup 4 | 5 | Use the built-in [LSP client for Kate.](https://kate-editor.org/post/2020/2020-01-01-kate-lsp-client-status/) 6 | -------------------------------------------------------------------------------- /apps/elixir_ls_utils/.formatter.exs: -------------------------------------------------------------------------------- 1 | [ 2 | inputs: [ 3 | "*.exs", 4 | "{lib,config}/**/*.{ex,exs}", 5 | "test/*.exs", 6 | "test/support/**/*.ex" 7 | ] 8 | ] 9 | -------------------------------------------------------------------------------- /apps/language_server/test/fixtures/umbrella/mix.exs: -------------------------------------------------------------------------------- 1 | defmodule Umbrella.Mixfile do 2 | use Mix.Project 3 | 4 | def project do 5 | [apps_path: "apps"] 6 | end 7 | end 8 | -------------------------------------------------------------------------------- /apps/language_server/test/support/fixtures/references_erlang.ex: -------------------------------------------------------------------------------- 1 | defmodule ElixirLS.Test.ReferencesErlang do 2 | def uses_fun do 3 | :ets.new(:my_table, []) 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /apps/language_server/test/support/references/local_call.ex: -------------------------------------------------------------------------------- 1 | defmodule ElixirSenseExample.References.LocalCall do 2 | def foo(), do: :ok 3 | 4 | def bar(), do: foo() 5 | end 6 | -------------------------------------------------------------------------------- /apps/elixir_ls_utils/test/fixtures/protocol_messages/valid_message_content_type: -------------------------------------------------------------------------------- 1 | Content-Length: 16 2 | Content-Type: application/vscode-jsonrpc; charset=utf-8 3 | 4 | {"some":"value"} -------------------------------------------------------------------------------- /apps/language_server/test/fixtures/umbrella_dialyzer/mix.exs: -------------------------------------------------------------------------------- 1 | defmodule UmbrellaDialyzer.Mixfile do 2 | use Mix.Project 3 | 4 | def project do 5 | [apps_path: "apps"] 6 | end 7 | end 8 | -------------------------------------------------------------------------------- /apps/language_server/test/fixtures/test_code_lens/test/fixture_test.exs: -------------------------------------------------------------------------------- 1 | defmodule TestCodeLensTest do 2 | use ExUnit.Case 3 | 4 | test "fixture test" do 5 | assert true 6 | end 7 | end 8 | -------------------------------------------------------------------------------- /apps/language_server/test/fixtures/umbrella_test_code_lens/mix.exs: -------------------------------------------------------------------------------- 1 | defmodule UmbrellaTestCodeLens.Mixfile do 2 | use Mix.Project 3 | 4 | def project do 5 | [apps_path: "apps"] 6 | end 7 | end 8 | -------------------------------------------------------------------------------- /apps/language_server/test/support/empty_module.ex: -------------------------------------------------------------------------------- 1 | defmodule ElixirSenseExample.EmptyModule do 2 | @moduledoc """ 3 | Empty module without other functions 4 | 5 | More moduledoc 6 | """ 7 | end 8 | -------------------------------------------------------------------------------- /apps/language_server/test/support/references/local_macro_call.ex: -------------------------------------------------------------------------------- 1 | defmodule ElixirSenseExample.References.LocalMacroCall do 2 | defmacro foo_macro(), do: :ok 3 | 4 | def bar(), do: foo_macro() 5 | end 6 | -------------------------------------------------------------------------------- /apps/language_server/test/support/references/struct.ex: -------------------------------------------------------------------------------- 1 | defmodule ElixirSenseExample.References.Struct do 2 | defstruct [:foo] 3 | 4 | def abc(), do: %ElixirSenseExample.References.Struct{} 5 | end 6 | -------------------------------------------------------------------------------- /apps/elixir_ls_utils/test/fixtures/protocol_messages/invalid_after_valid: -------------------------------------------------------------------------------- 1 | Content-Length: 16 2 | 3 | {"some":"value"}Content-Length: 16 4 | 5 | {"some":"value1"Content-Length: 16 6 | 7 | {"some":"value"} -------------------------------------------------------------------------------- /apps/language_server/test/support/fixtures/remote_function.ex: -------------------------------------------------------------------------------- 1 | defmodule ElixirLS.Test.RemoteFunction do 2 | def foo(a) do 3 | a 4 | end 5 | 6 | def bar(a) do 7 | a 8 | end 9 | end 10 | -------------------------------------------------------------------------------- /docs/getting-started/sublime.md: -------------------------------------------------------------------------------- 1 | # Sublime 2 | 3 | ## Setup 4 | 5 | Install the extension [LSP-Elixir](https://github.com/sublimelsp/LSP-elixir). 6 | 7 | Note that it does not have debug adapter support. 8 | -------------------------------------------------------------------------------- /apps/language_server/test/support/references/super.ex: -------------------------------------------------------------------------------- 1 | defmodule ElixirSenseExample.References.Super do 2 | use ElixirSenseExample.OverridableFunctions 3 | def test(_x, y), do: super(&super/2, y + 1) 4 | end 5 | -------------------------------------------------------------------------------- /apps/language_server/test/fixtures/formatter/.formatter.exs: -------------------------------------------------------------------------------- 1 | [ 2 | line_length: 20, 3 | subdirectories: [ 4 | "lib", 5 | "test", 6 | "symlink", 7 | "apps/*" 8 | ], 9 | inputs: ["*.ex"] 10 | ] 11 | -------------------------------------------------------------------------------- /apps/language_server/test/fixtures/protocols/lib/implementations.ex: -------------------------------------------------------------------------------- 1 | defimpl Protocols.Example, for: List do 2 | def some(t), do: t 3 | end 4 | 5 | defimpl Protocols.Example, for: String do 6 | def some(t), do: t 7 | end 8 | -------------------------------------------------------------------------------- /apps/language_server/test/fixtures/build_errors/lib/has_error.ex: -------------------------------------------------------------------------------- 1 | defmodule ElixirLS.LanguageServer.Fixtures.BuildErrors.HasError do 2 | def my_fn2 do 3 | # Should cause build error 4 | does_not_exist() 5 | end 6 | end 7 | -------------------------------------------------------------------------------- /apps/language_server/test/support/references/alias.ex: -------------------------------------------------------------------------------- 1 | defmodule ElixirSenseExample.References.Alias do 2 | alias ElixirSenseExample.References.ModuleWithDef 3 | 4 | def abc() do 5 | ModuleWithDef.foo() 6 | end 7 | end 8 | -------------------------------------------------------------------------------- /apps/language_server/test/fixtures/build_errors_on_external_resource/lib/has_error.ex: -------------------------------------------------------------------------------- 1 | defmodule ElixirLS.LanguageServer.Fixtures.BuildErrorsOnExternalResource.HasError do 2 | EEx.compile_file("lib/template.eex", line: 1) 3 | end 4 | -------------------------------------------------------------------------------- /apps/language_server/test/fixtures/umbrella_test_code_lens/apps/app/test/fixture_custom_test.exs: -------------------------------------------------------------------------------- 1 | defmodule App.UmbrellaTestCodeLensTest do 2 | use ExUnit.Case 3 | 4 | test "fixture test" do 5 | assert true 6 | end 7 | end 8 | -------------------------------------------------------------------------------- /apps/language_server/test/fixtures/umbrella_test_code_lens/apps/app1/test/fixture_custom_test.exs: -------------------------------------------------------------------------------- 1 | defmodule App1.UmbrellaTestCodeLensTest do 2 | use ExUnit.Case 3 | 4 | test "fixture test" do 5 | assert true 6 | end 7 | end 8 | -------------------------------------------------------------------------------- /apps/language_server/test/location/sample_erl: -------------------------------------------------------------------------------- 1 | %% 2 | %% %CopyrightBegin% 3 | %% 4 | %% %CopyrightEnd% 5 | %% 6 | 7 | -module(sample_erl). 8 | 9 | -opaque my_type() :: integer(). 10 | 11 | my_function(X) -> 12 | X + 1. 13 | -------------------------------------------------------------------------------- /apps/language_server/test/support/use_example.ex: -------------------------------------------------------------------------------- 1 | defmodule ElixirSenseExample.UseExample do 2 | defmacro __using__(_) do 3 | quote do 4 | def example do 5 | 42 6 | end 7 | end 8 | end 9 | end 10 | -------------------------------------------------------------------------------- /apps/language_server/test/support/same_module.ex: -------------------------------------------------------------------------------- 1 | defmodule ElixirSenseExample.SameModule do 2 | def test_fun(), do: :ok 3 | 4 | defmacro some_test_macro() do 5 | quote do 6 | @attr "val" 7 | end 8 | end 9 | end 10 | -------------------------------------------------------------------------------- /apps/language_server/test/fixtures/umbrella_test_code_lens_custom_path_and_pattern/mix.exs: -------------------------------------------------------------------------------- 1 | defmodule UmbrellaTestCodeLensCustomPathAndPattern.Mixfile do 2 | use Mix.Project 3 | 4 | def project do 5 | [apps_path: "apps"] 6 | end 7 | end 8 | -------------------------------------------------------------------------------- /apps/language_server/test/support/case_template_example.ex: -------------------------------------------------------------------------------- 1 | defmodule ElixirSenseExample.CaseTemplateExample do 2 | use ExUnit.CaseTemplate 3 | 4 | using do 5 | quote do 6 | alias Some.Module 7 | end 8 | end 9 | end 10 | -------------------------------------------------------------------------------- /apps/language_server/test/support/references/require_as.ex: -------------------------------------------------------------------------------- 1 | defmodule ElixirSenseExample.References.RequireAs do 2 | require ElixirSenseExample.References.ModuleWithDefMacro, as: M 3 | 4 | def abc() do 5 | M.foo_macro() 6 | end 7 | end 8 | -------------------------------------------------------------------------------- /apps/language_server/test/fixtures/test_code_lens/mix.exs: -------------------------------------------------------------------------------- 1 | defmodule TestCodeLens.MixProject do 2 | use Mix.Project 3 | 4 | def project do 5 | [app: :test_code_lens, version: "0.1.0"] 6 | end 7 | 8 | def application, do: [] 9 | end 10 | -------------------------------------------------------------------------------- /.formatter.exs: -------------------------------------------------------------------------------- 1 | [ 2 | inputs: [ 3 | "*.exs", 4 | "config/**/*.exs", 5 | "scripts/**/*.exs" 6 | ], 7 | subdirectories: [ 8 | "apps/elixir_ls_utils", 9 | "apps/debug_adapter", 10 | "apps/language_server" 11 | ] 12 | ] 13 | -------------------------------------------------------------------------------- /apps/language_server/lib/language_server/lsp/protocol/base_types.ex: -------------------------------------------------------------------------------- 1 | # codegen: do not edit 2 | defmodule GenLSP.BaseTypes do 3 | @type uri :: String.t() 4 | @type document_uri :: String.t() 5 | @type uinteger :: integer() 6 | @type null :: nil 7 | end 8 | -------------------------------------------------------------------------------- /apps/language_server/test/fixtures/test_code_lens_custom_paths_and_pattern/custom_path/fixture_custom_test.exs: -------------------------------------------------------------------------------- 1 | defmodule TestCodeLensCustomPathsAndPatternTest do 2 | use ExUnit.Case 3 | 4 | test "fixture test" do 5 | assert true 6 | end 7 | end 8 | -------------------------------------------------------------------------------- /apps/language_server/test/fixtures/umbrella/apps/app2/mix.exs: -------------------------------------------------------------------------------- 1 | defmodule App2.Mixfile do 2 | use Mix.Project 3 | 4 | def project do 5 | [app: :app2, version: "0.1.0"] 6 | end 7 | 8 | def application do 9 | [] 10 | end 11 | end 12 | -------------------------------------------------------------------------------- /apps/language_server/test/support/module_with_builtin_type_shadowing.ex: -------------------------------------------------------------------------------- 1 | defmodule ElixirSenseExample.ModuleWithBuiltinTypeShadowing do 2 | @compile {:no_warn_undefined, {B.Callee, :fun, 0}} 3 | def plain_fun do 4 | B.Callee.fun() 5 | end 6 | end 7 | -------------------------------------------------------------------------------- /apps/language_server/test/fixtures/references/mix.exs: -------------------------------------------------------------------------------- 1 | defmodule References.MixProject do 2 | use Mix.Project 3 | 4 | def project do 5 | [app: :references, version: "0.1.0"] 6 | end 7 | 8 | def application do 9 | [] 10 | end 11 | end 12 | -------------------------------------------------------------------------------- /apps/language_server/test/fixtures/umbrella_dialyzer/apps/app2/mix.exs: -------------------------------------------------------------------------------- 1 | defmodule App2.Mixfile do 2 | use Mix.Project 3 | 4 | def project do 5 | [app: :app2, version: "0.1.0"] 6 | end 7 | 8 | def application do 9 | [] 10 | end 11 | end 12 | -------------------------------------------------------------------------------- /apps/language_server/test/support/subscriber.ex: -------------------------------------------------------------------------------- 1 | defmodule ElixirSenseExample.Subscriber do 2 | def some do 3 | ElixirSenseExample.Subscription.check("user", [:a, :b], :c) 4 | ElixirSenseExample.Subscription.check("user", [:a, :b], :c, :s) 5 | end 6 | end 7 | -------------------------------------------------------------------------------- /apps/language_server/test/support/plugins/phoenix/page_controller.ex: -------------------------------------------------------------------------------- 1 | defmodule ExampleWeb.PageController do 2 | def call(_conn, _params) do 3 | end 4 | 5 | def action(_conn, _params) do 6 | end 7 | 8 | def home(_conn, _params) do 9 | end 10 | end 11 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | indent_style = space 5 | indent_size = 2 6 | end_of_line = lf 7 | charset = utf-8 8 | trim_trailing_whitespace = true 9 | insert_final_newline = true 10 | 11 | [*.{md, markdown, eex}] 12 | trim_trailing_whitespace = false 13 | -------------------------------------------------------------------------------- /apps/language_server/lib/language_server/providers/code_lens/test/test_block.ex: -------------------------------------------------------------------------------- 1 | defmodule ElixirLS.LanguageServer.Providers.CodeLens.Test.TestBlock do 2 | @struct_keys [:name, :describe, :line, :module] 3 | 4 | @enforce_keys @struct_keys 5 | defstruct @struct_keys 6 | end 7 | -------------------------------------------------------------------------------- /apps/language_server/test/providers/folding_range/token_pairs_test.exs: -------------------------------------------------------------------------------- 1 | defmodule ElixirLS.LanguageServer.Providers.FoldingRange.TokenPairTest do 2 | use ExUnit.Case 3 | 4 | alias ElixirLS.LanguageServer.Providers.FoldingRange.TokenPair 5 | 6 | doctest(TokenPair) 7 | end 8 | -------------------------------------------------------------------------------- /apps/language_server/test/support/fixtures/example_deprecated_module.ex: -------------------------------------------------------------------------------- 1 | defmodule ElixirLS.LanguageServer.Fixtures.ExampleDeprecatedModule do 2 | @moduledoc "An example deprecated module" 3 | @moduledoc deprecated: "This module will be removed in a futur release" 4 | end 5 | -------------------------------------------------------------------------------- /apps/language_server/test_fixtures/fixtures/project_with_tests/mix.exs: -------------------------------------------------------------------------------- 1 | defmodule ProjectWithTests.MixProject do 2 | use Mix.Project 3 | 4 | def project do 5 | [app: :project_with_tests, version: "0.1.0"] 6 | end 7 | 8 | def application, do: [] 9 | end 10 | -------------------------------------------------------------------------------- /apps/language_server/test/fixtures/umbrella_test_code_lens_custom_path_and_pattern/apps/app1/custom_path/fixture_custom_test.exs: -------------------------------------------------------------------------------- 1 | defmodule UmbrellaTestCodeLensCustomPathAndPatternTest do 2 | use ExUnit.Case 3 | 4 | test "fixture test" do 5 | assert true 6 | end 7 | end 8 | -------------------------------------------------------------------------------- /apps/language_server/test/providers/folding_range/indentation_test.exs: -------------------------------------------------------------------------------- 1 | defmodule ElixirLS.LanguageServer.Providers.FoldingRange.IndentationTest do 2 | use ExUnit.Case 3 | 4 | alias ElixirLS.LanguageServer.Providers.FoldingRange.Indentation 5 | 6 | doctest(Indentation) 7 | end 8 | -------------------------------------------------------------------------------- /apps/language_server/test/support/references/require.ex: -------------------------------------------------------------------------------- 1 | defmodule ElixirSenseExample.References.Require do 2 | require ElixirSenseExample.References.ModuleWithDefMacro 3 | 4 | def abc() do 5 | ElixirSenseExample.References.ModuleWithDefMacro.foo_macro() 6 | end 7 | end 8 | -------------------------------------------------------------------------------- /apps/language_server/test/providers/folding_range/comment_block_test.exs: -------------------------------------------------------------------------------- 1 | defmodule ElixirLS.LanguageServer.Providers.FoldingRange.CommentBlockTest do 2 | use ExUnit.Case 3 | 4 | alias ElixirLS.LanguageServer.Providers.FoldingRange.CommentBlock 5 | 6 | doctest(CommentBlock) 7 | end 8 | -------------------------------------------------------------------------------- /apps/language_server/test/providers/folding_range/special_token_test.exs: -------------------------------------------------------------------------------- 1 | defmodule ElixirLS.LanguageServer.Providers.FoldingRange.SpecialTokenTest do 2 | use ExUnit.Case 3 | 4 | alias ElixirLS.LanguageServer.Providers.FoldingRange.SpecialToken 5 | 6 | doctest(SpecialToken) 7 | end 8 | -------------------------------------------------------------------------------- /apps/language_server/test/fixtures/formatter/mix.exs: -------------------------------------------------------------------------------- 1 | defmodule Formatter.MixProject do 2 | use Mix.Project 3 | 4 | def project do 5 | [ 6 | app: :formatter, 7 | version: "0.1.0" 8 | ] 9 | end 10 | 11 | def application do 12 | [] 13 | end 14 | end 15 | -------------------------------------------------------------------------------- /apps/language_server/test/fixtures/protocols/mix.exs: -------------------------------------------------------------------------------- 1 | defmodule Protocols.MixProject do 2 | use Mix.Project 3 | 4 | def project do 5 | [ 6 | app: :protocols, 7 | version: "0.1.0" 8 | ] 9 | end 10 | 11 | def application do 12 | [] 13 | end 14 | end 15 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | FROM index.docker.io/elixir:alpine 2 | 3 | ARG ELIXIR_LS_VERSION=v0.16.0 4 | ARG MIX_ENV=prod 5 | 6 | ADD . /app 7 | 8 | WORKDIR /app 9 | 10 | # Add build and test dependencies 11 | RUN apk add --no-cache \ 12 | git \ 13 | zsh \ 14 | bash \ 15 | fish 16 | 17 | CMD sh 18 | -------------------------------------------------------------------------------- /apps/language_server/test/fixtures/umbrella_test_code_lens/apps/app/mix.exs: -------------------------------------------------------------------------------- 1 | defmodule App.Mixfile do 2 | use Mix.Project 3 | 4 | def project do 5 | [ 6 | app: :app, 7 | version: "0.1.0" 8 | ] 9 | end 10 | 11 | def application do 12 | [] 13 | end 14 | end 15 | -------------------------------------------------------------------------------- /apps/language_server/test/fixtures/umbrella_test_code_lens/apps/app1/mix.exs: -------------------------------------------------------------------------------- 1 | defmodule App1.Mixfile do 2 | use Mix.Project 3 | 4 | def project do 5 | [ 6 | app: :app1, 7 | version: "0.1.0" 8 | ] 9 | end 10 | 11 | def application do 12 | [] 13 | end 14 | end 15 | -------------------------------------------------------------------------------- /apps/language_server/test/support/behaviour_implementations.ex: -------------------------------------------------------------------------------- 1 | defmodule ElixirSenseExample.DummyBehaviour do 2 | @callback foo() :: any 3 | end 4 | 5 | defmodule ElixirSenseExample.DummyBehaviourImplementation do 6 | @behaviour ElixirSenseExample.DummyBehaviour 7 | def foo(), do: :ok 8 | end 9 | -------------------------------------------------------------------------------- /apps/language_server/test/support/fixtures/module_deps_e.ex: -------------------------------------------------------------------------------- 1 | defmodule ElixirLS.Test.ModuleDepsE do 2 | @moduledoc """ 3 | Test module E for module dependency analysis. 4 | End of the dependency chain. 5 | """ 6 | 7 | def function_in_e(arg) do 8 | {:ok, arg} 9 | end 10 | end 11 | -------------------------------------------------------------------------------- /apps/language_server/test/support/module_with_record.ex: -------------------------------------------------------------------------------- 1 | defmodule ElixirSenseExample.ModuleWithRecord do 2 | require Record 3 | @doc "user docs" 4 | @doc since: "1.0.0" 5 | Record.defrecord(:user, name: "john", age: 25) 6 | @type user :: record(:user, name: String.t(), age: integer) 7 | end 8 | -------------------------------------------------------------------------------- /apps/language_server/test/fixtures/build_errors/mix.exs: -------------------------------------------------------------------------------- 1 | defmodule ElixirLS.LanguageServer.Fixtures.BuildErrors.Mixfile do 2 | use Mix.Project 3 | 4 | def project do 5 | [app: :els_build_errors_test, version: "0.1.0"] 6 | end 7 | 8 | def application do 9 | [] 10 | end 11 | end 12 | -------------------------------------------------------------------------------- /apps/language_server/test/support/references/import.ex: -------------------------------------------------------------------------------- 1 | defmodule ElixirSenseExample.References.Import do 2 | import ElixirSenseExample.References.ModuleWithDef 3 | import ElixirSenseExample.References.ModuleWithDefMacro 4 | 5 | def abc() do 6 | foo() 7 | foo_macro() 8 | end 9 | end 10 | -------------------------------------------------------------------------------- /apps/language_server/test/test_helper.exs: -------------------------------------------------------------------------------- 1 | :persistent_term.put(:language_server_test_mode, true) 2 | Application.ensure_started(:stream_data) 3 | type_inference = Code.ensure_loaded?(ElixirSense.Core.Compiler) 4 | ExUnit.start(exclude: [pending: true, requires_source: true, type_inference: type_inference]) 5 | -------------------------------------------------------------------------------- /apps/language_server/test/support/module_with_many_clauses.ex: -------------------------------------------------------------------------------- 1 | defmodule ElixirSenseExample.ModuleWithManyClauses do 2 | def sum(s \\ nil, f) 3 | def sum(a, nil), do: a 4 | 5 | def sum(a, b) do 6 | a + b 7 | end 8 | 9 | def sum({a, b}, x, y) do 10 | a + b + x + y 11 | end 12 | end 13 | -------------------------------------------------------------------------------- /apps/language_server/test/support/module_with_private_types.ex: -------------------------------------------------------------------------------- 1 | defmodule ModuleWithPrivateTypes do 2 | @opaque opaque_t :: atom 3 | @typep typep_t :: atom 4 | @type type_t :: atom 5 | 6 | @spec just_to_use_typep(typep_t) :: typep_t 7 | def just_to_use_typep(t) do 8 | t 9 | end 10 | end 11 | -------------------------------------------------------------------------------- /apps/language_server/test/support/fixtures/example_quoted_defs.ex: -------------------------------------------------------------------------------- 1 | defmodule ElixirLS.LanguageServer.Fixtures.ExampleQuotedDefs do 2 | @doc """ 3 | quoted def 4 | """ 5 | @spec unquote(:"0abc\"asd")(any, integer) :: :ok 6 | def unquote(:"0abc\"asd")(_example, _arg) do 7 | :ok 8 | end 9 | end 10 | -------------------------------------------------------------------------------- /apps/language_server/test/support/references/remote_call.ex: -------------------------------------------------------------------------------- 1 | defmodule ElixirSenseExample.References.RemoteCall do 2 | def foo(), do: :ok 3 | end 4 | 5 | defmodule ElixirSenseExample.References.RemoteCallCaller do 6 | def abc() do 7 | ElixirSenseExample.References.RemoteCall.foo() 8 | end 9 | end 10 | -------------------------------------------------------------------------------- /apps/language_server/test/support/fixtures/example_docs.ex: -------------------------------------------------------------------------------- 1 | defmodule ElixirLS.LanguageServer.Fixtures.ExampleDocs do 2 | @doc """ 3 | The summary 4 | 5 | This rest 6 | """ 7 | @spec add(a_big_name :: integer, b_big_name :: integer) :: integer 8 | def add(a, b) do 9 | a + b 10 | end 11 | end 12 | -------------------------------------------------------------------------------- /apps/language_server/test/fixtures/token_missing_error/mix.exs: -------------------------------------------------------------------------------- 1 | defmodule ElixirLS.LanguageServer.Fixtures.TokenMissingError.Mixfile do 2 | use Mix.Project 3 | 4 | def project do 5 | [app: :els_token_missing_error_test, version: "0.1.0"] 6 | end 7 | 8 | def application do 9 | [] 10 | end 11 | end 12 | -------------------------------------------------------------------------------- /apps/language_server/test/fixtures/umbrella_test_code_lens_custom_path_and_pattern/apps/app1/mix.exs: -------------------------------------------------------------------------------- 1 | defmodule App1.Mixfile do 2 | use Mix.Project 3 | 4 | def project do 5 | [ 6 | app: :app1, 7 | version: "0.1.0" 8 | ] 9 | end 10 | 11 | def application do 12 | [] 13 | end 14 | end 15 | -------------------------------------------------------------------------------- /apps/language_server/test/support/fixture_helpers.ex: -------------------------------------------------------------------------------- 1 | defmodule ElixirLS.LanguageServer.Test.FixtureHelpers do 2 | def get_path() do 3 | Path.join([__DIR__, "fixtures"]) |> Path.expand() 4 | end 5 | 6 | def get_path(file) do 7 | Path.join([__DIR__, "fixtures", file]) |> Path.expand() 8 | end 9 | end 10 | -------------------------------------------------------------------------------- /apps/debug_adapter/test/test_helper.exs: -------------------------------------------------------------------------------- 1 | :persistent_term.put(:debug_adapter_test_mode, true) 2 | ExUnit.start(exclude: [pending: true]) 3 | 4 | if Version.match?(System.version(), ">= 1.15.0") do 5 | # make sure that OTP debugger modules are in code path 6 | # without starting the app 7 | Mix.ensure_application!(:debugger) 8 | end 9 | -------------------------------------------------------------------------------- /apps/language_server/test/support/fixtures/example_default_args.ex: -------------------------------------------------------------------------------- 1 | defmodule ElixirLS.LanguageServer.Fixtures.ExampleDefaultArgs do 2 | def my_func(text, opts1 \\ [], opts2 \\ []) do 3 | IO.inspect({text, opts1, opts2}) 4 | end 5 | 6 | def func_with_1_arg(text \\ "hi") do 7 | IO.inspect(text) 8 | end 9 | end 10 | -------------------------------------------------------------------------------- /apps/language_server/test/support/paths.ex: -------------------------------------------------------------------------------- 1 | defmodule ElixirLS.LanguageServer.Test.Paths do 2 | alias ElixirLS.LanguageServer.SourceFile 3 | 4 | def to_native_separators(path) do 5 | if SourceFile.Path.windows?() do 6 | String.replace(path, ~r/\//, "\\") 7 | else 8 | path 9 | end 10 | end 11 | end 12 | -------------------------------------------------------------------------------- /apps/language_server/test/fixtures/umbrella/apps/app1/mix.exs: -------------------------------------------------------------------------------- 1 | defmodule App1.Mixfile do 2 | use Mix.Project 3 | 4 | def project do 5 | [app: :app1, version: "0.1.0", deps: deps()] 6 | end 7 | 8 | def application do 9 | [] 10 | end 11 | 12 | defp deps do 13 | [{:app2, in_umbrella: true}] 14 | end 15 | end 16 | -------------------------------------------------------------------------------- /apps/language_server/test/support/fixtures/macro_a.ex: -------------------------------------------------------------------------------- 1 | defmodule ElixirLS.Test.MacroA do 2 | defmacro __using__(_) do 3 | quote do 4 | import ElixirLS.Test.MacroA 5 | 6 | def macro_a_func do 7 | :ok 8 | end 9 | end 10 | end 11 | 12 | def macro_imported_fun do 13 | :ok 14 | end 15 | end 16 | -------------------------------------------------------------------------------- /apps/language_server/test/support/fixtures/references_imported.ex: -------------------------------------------------------------------------------- 1 | defmodule ElixirLS.Test.ReferencesImported do 2 | import ElixirLS.Test.ReferencesReferenced 3 | 4 | def uses_fun do 5 | referenced_fun() 6 | end 7 | 8 | def uses_macro(a) do 9 | referenced_macro a do 10 | :ok 11 | end 12 | end 13 | end 14 | -------------------------------------------------------------------------------- /apps/language_server/test/support/references/captures.ex: -------------------------------------------------------------------------------- 1 | defmodule ElixirSenseExample.References.Captures do 2 | import ElixirSenseExample.References.ModuleWithDef 3 | alias ElixirSenseExample.References.ModuleWithDef, as: M 4 | def abc(), do: :ok 5 | 6 | def foo(x) do 7 | [&abc/0, &M.foo/0, &foo/0] 8 | end 9 | end 10 | -------------------------------------------------------------------------------- /apps/language_server/test/fixtures/build_errors_on_external_resource/mix.exs: -------------------------------------------------------------------------------- 1 | defmodule ElixirLS.LanguageServer.Fixtures.BuildErrorsOnExternalResource.Mixfile do 2 | use Mix.Project 3 | 4 | def project do 5 | [app: :els_build_errors_test, version: "0.1.0"] 6 | end 7 | 8 | def application do 9 | [] 10 | end 11 | end 12 | -------------------------------------------------------------------------------- /apps/language_server/test/fixtures/umbrella_dialyzer/apps/app1/mix.exs: -------------------------------------------------------------------------------- 1 | defmodule App1.Mixfile do 2 | use Mix.Project 3 | 4 | def project do 5 | [app: :app1, version: "0.1.0", deps: deps()] 6 | end 7 | 8 | def application do 9 | [] 10 | end 11 | 12 | defp deps do 13 | [{:app2, in_umbrella: true}] 14 | end 15 | end 16 | -------------------------------------------------------------------------------- /apps/language_server/test/support/fixtures/example_protocol.ex: -------------------------------------------------------------------------------- 1 | defprotocol ElixirLS.LanguageServer.Fixtures.ExampleProtocol do 2 | @moduledoc """ 3 | ExampleProtocol protocol used in tests. 4 | """ 5 | 6 | @doc """ 7 | Does what `my_fun` does for `t` 8 | """ 9 | @spec my_fun(t, integer) :: binary 10 | def my_fun(example, arg) 11 | end 12 | -------------------------------------------------------------------------------- /apps/language_server/test/support/plugins/ecto/uuid.ex: -------------------------------------------------------------------------------- 1 | defmodule Ecto.Type do 2 | @moduledoc """ 3 | Fake Ecto.Type 4 | """ 5 | 6 | @callback fake :: true 7 | end 8 | 9 | defmodule Ecto.UUID do 10 | @moduledoc """ 11 | Fake Ecto.UUID 12 | """ 13 | 14 | @behaviour Ecto.Type 15 | 16 | def fake() do 17 | true 18 | end 19 | end 20 | -------------------------------------------------------------------------------- /apps/elixir_ls_utils/test/placeholder_test.exs: -------------------------------------------------------------------------------- 1 | defmodule ElixirLS.Utils.PlaceholderTest do 2 | use ExUnit.Case, async: true 3 | 4 | @tag :fixture 5 | test "pretend fixture" do 6 | # This test is included to prevent the following error: 7 | # > The --only option was given to "mix test" but no test was executed 8 | :ok 9 | end 10 | end 11 | -------------------------------------------------------------------------------- /apps/language_server/test/support/example_protocol.ex: -------------------------------------------------------------------------------- 1 | defprotocol ElixirSenseExample.ExampleProtocol do 2 | @spec some(t) :: any 3 | def some(t) 4 | end 5 | 6 | defimpl ElixirSenseExample.ExampleProtocol, for: List do 7 | def some(t), do: t 8 | end 9 | 10 | defimpl ElixirSenseExample.ExampleProtocol, for: Map do 11 | def some(t), do: t 12 | end 13 | -------------------------------------------------------------------------------- /scripts/exec.zsh: -------------------------------------------------------------------------------- 1 | # we need to make sure ELS_ELIXIR_OPTS gets splitted by word 2 | # parse it as zsh array 3 | # shellcheck disable=SC3030 4 | # shellcheck disable=SC2296 5 | elixir_opts=("${(z)ELS_ELIXIR_OPTS}") 6 | # shellcheck disable=SC2128 7 | # shellcheck disable=SC2086 8 | exec elixir $elixir_opts --erl "$default_erl_opts $ELS_ERL_OPTS" "$SCRIPTPATH/launch.exs" 9 | -------------------------------------------------------------------------------- /apps/debug_adapter/test/fixtures/mix_project/test/mix_project_fixturetest.exs: -------------------------------------------------------------------------------- 1 | defmodule MixProjectTest do 2 | use ExUnit.Case 3 | doctest MixProject 4 | 5 | @tag :double 6 | test "double" do 7 | assert MixProject.double(2) == 4 8 | end 9 | 10 | @tag :quadruple 11 | test "quadruple" do 12 | assert MixProject.quadruple(2) == 8 13 | end 14 | end 15 | -------------------------------------------------------------------------------- /apps/language_server/test/support/macro_generated.ex: -------------------------------------------------------------------------------- 1 | defmodule ElixirSenseExample.Macros do 2 | defmacro go do 3 | quote do 4 | @type my_type :: nil 5 | def my_fun(), do: :ok 6 | end 7 | end 8 | end 9 | 10 | defmodule ElixirSenseExample.MacroGenerated do 11 | require ElixirSenseExample.Macros 12 | 13 | ElixirSenseExample.Macros.go() 14 | end 15 | -------------------------------------------------------------------------------- /apps/language_server/test/support/plugins/ecto/migration.ex: -------------------------------------------------------------------------------- 1 | defmodule Ecto.Migration do 2 | @moduledoc ~S""" 3 | Fake Migration module. 4 | """ 5 | 6 | @doc """ 7 | Defines a field on the schema with given name and type. 8 | """ 9 | def add(column, type, opts \\ []) when is_atom(column) and is_list(opts) do 10 | {column, type, opts} 11 | end 12 | end 13 | -------------------------------------------------------------------------------- /apps/language_server/lib/language_server/lsp/protocol/type_aliases/progress_token.ex: -------------------------------------------------------------------------------- 1 | # codegen: do not edit 2 | defmodule GenLSP.TypeAlias.ProgressToken do 3 | import SchematicV, warn: false 4 | 5 | @type t :: integer() | String.t() 6 | 7 | @doc false 8 | @spec schematic() :: SchematicV.t() 9 | def schematic() do 10 | oneof([int(), str()]) 11 | end 12 | end 13 | -------------------------------------------------------------------------------- /apps/language_server/test/fixtures/token_missing_error/lib/has_error.ex: -------------------------------------------------------------------------------- 1 | defmodule ElixirLS.LanguageServer.Fixtures.TokenMissingError.HasError do 2 | def my_fn1 do 3 | "no problem here" 4 | end 5 | 6 | def my_fn2 do 7 | for i <- 1..100 do 8 | i + 1 9 | # missing terminator: end 10 | end 11 | 12 | def my_fn3 do 13 | :ok_too 14 | end 15 | end 16 | -------------------------------------------------------------------------------- /apps/language_server/test/support/stuct_with_typespec.ex: -------------------------------------------------------------------------------- 1 | defmodule ElixirSenseExample.IO.Stream do 2 | defstruct [ 3 | :device, 4 | :line_or_bytes, 5 | :raw 6 | ] 7 | 8 | @type t() :: %ElixirSenseExample.IO.Stream{ 9 | device: IO.device(), 10 | line_or_bytes: :line | non_neg_integer(), 11 | raw: boolean() 12 | } 13 | end 14 | -------------------------------------------------------------------------------- /apps/language_server/test/support/subscription.ex: -------------------------------------------------------------------------------- 1 | defmodule ElixirSenseExample.Subscription do 2 | def check(resource, models, user, opts \\ []) 3 | 4 | def check(nil, models, user, opts) do 5 | IO.inspect({nil, models, user, opts}) 6 | end 7 | 8 | def check(resource, models, user, opts) do 9 | IO.inspect({resource, models, user, opts}) 10 | end 11 | end 12 | -------------------------------------------------------------------------------- /scripts/exec.bash: -------------------------------------------------------------------------------- 1 | # we need to make sure ELS_ELIXIR_OPTS gets splitted by word 2 | # parse it as bash array 3 | # shellcheck disable=SC3045 4 | # shellcheck disable=SC3011 5 | IFS=' ' read -ra elixir_opts <<< "$ELS_ELIXIR_OPTS" 6 | # shellcheck disable=SC3054 7 | # shellcheck disable=SC2068 8 | exec elixir ${elixir_opts[@]} --erl "$default_erl_opts $ELS_ERL_OPTS" "$SCRIPTPATH/launch.exs" 9 | -------------------------------------------------------------------------------- /apps/language_server/test/support/callback_opaque.ex: -------------------------------------------------------------------------------- 1 | defmodule ElixirSenseExample.CallbackOpaque do 2 | @moduledoc """ 3 | Behaviour with opaque type in callback 4 | """ 5 | 6 | @typedoc """ 7 | Opaque type 8 | """ 9 | @opaque t(x) :: {term, x} 10 | 11 | @doc """ 12 | Does stuff to opaque arg 13 | """ 14 | @callback do_stuff(t(a), term) :: t(a) when a: any 15 | end 16 | -------------------------------------------------------------------------------- /apps/language_server/test/support/references/quoted.ex: -------------------------------------------------------------------------------- 1 | defmodule ElixirSenseExample.References.Quoted do 2 | def aaa, do: :ok 3 | defmacro bbb, do: :ok 4 | 5 | defmacro foo do 6 | quote do 7 | aaa() 8 | &aaa/0 9 | bbb() 10 | &bbb/0 11 | inspect(1) 12 | &inspect/1 13 | Node.list() 14 | &Node.list/0 15 | end 16 | end 17 | end 18 | -------------------------------------------------------------------------------- /apps/language_server/test/support/fixtures/references_remote.ex: -------------------------------------------------------------------------------- 1 | defmodule ElixirLS.Test.ReferencesRemote do 2 | require ElixirLS.Test.ReferencesReferenced, as: ReferencesReferenced 3 | 4 | def uses_fun do 5 | ReferencesReferenced.referenced_fun() 6 | end 7 | 8 | def uses_macro(a) do 9 | ReferencesReferenced.referenced_macro a do 10 | :ok 11 | end 12 | end 13 | end 14 | -------------------------------------------------------------------------------- /apps/language_server/test/support/test_utils.ex: -------------------------------------------------------------------------------- 1 | defmodule ElixirLS.LanguageServer.Test.TestUtils do 2 | alias GenLSP.Structures.TextEdit 3 | alias ElixirLS.LanguageServer.SourceFile 4 | 5 | def apply_text_edit(text, %TextEdit{} = text_edit) do 6 | %GenLSP.Structures.TextEdit{range: range, new_text: new_text} = text_edit 7 | SourceFile.apply_edit(text, range, new_text) 8 | end 9 | end 10 | -------------------------------------------------------------------------------- /dep_versions.exs: -------------------------------------------------------------------------------- 1 | [ 2 | elixir_sense: "bd6c527fee5725250e68d676c1c19a15bf4906c4", 3 | dialyxir_vendored: "accfec9393079abc4a82b7e79a4997f59f085b67", 4 | jason_v: "f1c10fa9c445cb9f300266122ef18671054b2330", 5 | erl2ex_vendored: "04f93e55f46d35d0aa3c149616f2c7a6a1ad9311", 6 | path_glob_vendored: "965350dc41def7be4a70a23904195c733a2ecc84", 7 | schematic_vendored: "7ecf3cd4b3ee319abf7d0914d325657a1f56cffd" 8 | ] 9 | -------------------------------------------------------------------------------- /apps/debug_adapter/test/fixtures/no_mix_exs/script.exs: -------------------------------------------------------------------------------- 1 | defmodule Abc do 2 | def debug_me() do 3 | a = [1, 2, 3] 4 | b = Enum.map(a, &(&1 + 1)) 5 | b 6 | end 7 | end 8 | 9 | a = [1, 2, 3] 10 | b = Enum.map(a, &(&1 + 1)) 11 | IO.puts("done #{inspect(b)}, #{Abc.debug_me()}") 12 | 13 | Task.start(fn -> 14 | Process.sleep(1000) 15 | IO.puts("done from task #{inspect(b)}, #{Abc.debug_me()}") 16 | end) 17 | -------------------------------------------------------------------------------- /apps/language_server/lib/language_server/lsp/protocol/type_aliases/lsp_array.ex: -------------------------------------------------------------------------------- 1 | # codegen: do not edit 2 | defmodule GenLSP.TypeAlias.LSPArray do 3 | @moduledoc """ 4 | LSP arrays. 5 | @since 3.17.0 6 | """ 7 | 8 | import SchematicV, warn: false 9 | 10 | @type t :: list(any()) 11 | 12 | @doc false 13 | @spec schematic() :: SchematicV.t() 14 | def schematic() do 15 | list(any()) 16 | end 17 | end 18 | -------------------------------------------------------------------------------- /apps/language_server/test/fixtures/workspace_symbols/lib/workspace_symbols.ex: -------------------------------------------------------------------------------- 1 | defmodule ElixirLS.LanguageServer.Fixtures.WorkspaceSymbols do 2 | def some_function(a), do: a 3 | defmacro some_macro(a), do: Macro.expand(a, __CALLER__) 4 | 5 | @callback some_callback(integer) :: atom 6 | @callback some_macrocallback(integer) :: Macro.t() 7 | 8 | @type some_type :: atom 9 | @type some_opaque_type :: atom 10 | end 11 | -------------------------------------------------------------------------------- /apps/language_server/test/support/fixtures/uses_macro_a.ex: -------------------------------------------------------------------------------- 1 | defmodule ElixirLS.Test.UsesMacroA do 2 | use ElixirLS.Test.MacroA 3 | 4 | @inputs [1, 2, 3] 5 | 6 | def my_fun do 7 | macro_a_func() 8 | end 9 | 10 | def my_other_fun do 11 | macro_imported_fun() 12 | end 13 | 14 | for input <- @inputs do 15 | def gen_fun(unquote(input)) do 16 | unquote(input) + 1 17 | end 18 | end 19 | end 20 | -------------------------------------------------------------------------------- /apps/language_server/test/fixtures/test_code_lens_custom_paths_and_pattern/mix.exs: -------------------------------------------------------------------------------- 1 | defmodule TestCodeLensCustomPathsAndPattern.MixProject do 2 | use Mix.Project 3 | 4 | def project do 5 | [ 6 | app: :test_code_lens_custom_paths_and_pattern, 7 | version: "0.1.0", 8 | test_paths: ["custom_path"], 9 | test_pattern: "*_custom_test.exs" 10 | ] 11 | end 12 | 13 | def application, do: [] 14 | end 15 | -------------------------------------------------------------------------------- /apps/language_server/test/support/module_with_struct.ex: -------------------------------------------------------------------------------- 1 | defmodule ElixirSenseExample.ModuleWithStruct do 2 | defstruct [:field_1, field_2: 1] 3 | end 4 | 5 | defmodule ElixirSenseExample.ModuleWithTypedStruct do 6 | @type t :: %ElixirSenseExample.ModuleWithTypedStruct{ 7 | typed_field: %ElixirSenseExample.ModuleWithStruct{}, 8 | other: integer 9 | } 10 | defstruct [:typed_field, other: 1] 11 | end 12 | -------------------------------------------------------------------------------- /apps/language_server/test/support/platform_test_helpers.ex: -------------------------------------------------------------------------------- 1 | defmodule ElixirLS.LanguageServer.Test.PlatformTestHelpers do 2 | def maybe_convert_path_separators(path) do 3 | if is_windows() do 4 | String.replace(path, ~r/\//, "\\") 5 | else 6 | path 7 | end 8 | end 9 | 10 | def is_windows() do 11 | case :os.type() do 12 | {:win32, _} -> true 13 | _ -> false 14 | end 15 | end 16 | end 17 | -------------------------------------------------------------------------------- /apps/elixir_ls_utils/test/support/module_with_struct.ex: -------------------------------------------------------------------------------- 1 | defmodule ElixirLS.Utils.Example.ModuleWithStruct do 2 | defstruct [:field_1, field_2: 1] 3 | end 4 | 5 | defmodule ElixirLS.Utils.Example.ModuleWithTypedStruct do 6 | @type t :: %ElixirLS.Utils.Example.ModuleWithTypedStruct{ 7 | typed_field: %ElixirLS.Utils.Example.ModuleWithStruct{}, 8 | other: integer 9 | } 10 | defstruct [:typed_field, other: 1] 11 | end 12 | -------------------------------------------------------------------------------- /apps/language_server/test/fixtures/clean/mix.exs: -------------------------------------------------------------------------------- 1 | defmodule ElixirLS.LanguageServer.Fixtures.Clean.Mixfile do 2 | use Mix.Project 3 | 4 | def project do 5 | [app: :els_clean_test, version: "0.1.0"] 6 | end 7 | 8 | # Configuration for the OTP application 9 | # 10 | # Type "mix help compile.app" for more information 11 | def application do 12 | # Specify extra applications you'll use from Erlang/Elixir 13 | [] 14 | end 15 | end 16 | -------------------------------------------------------------------------------- /.github/CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | While you can develop ElixirLS on its own, it's easiest to test out changes if you clone the [vscode-elixir-ls](https://github.com/elixir-lsp/vscode-elixir-ls) repository instead. It includes ElixirLS as a Git submodule, so you can make your changes in the submodule directory and launch the extension from the parent directory via the included "Launch Extension local" configuration in `launch.json`. See the README.md on that repo for more details. 2 | -------------------------------------------------------------------------------- /apps/language_server/lib/language_server/lsp/protocol/enumerations/token_format.ex: -------------------------------------------------------------------------------- 1 | # codegen: do not edit 2 | defmodule GenLSP.Enumerations.TokenFormat do 3 | @type t :: String.t() 4 | 5 | import SchematicV, warn: false 6 | 7 | @spec relative() :: String.t() 8 | def relative, do: "relative" 9 | 10 | @doc false 11 | @spec schematic() :: SchematicV.t() 12 | def schematic() do 13 | oneof([ 14 | "relative" 15 | ]) 16 | end 17 | end 18 | -------------------------------------------------------------------------------- /apps/language_server/lib/language_server/lsp/protocol/structures/initialized_params.ex: -------------------------------------------------------------------------------- 1 | # codegen: do not edit 2 | defmodule GenLSP.Structures.InitializedParams do 3 | import SchematicV, warn: false 4 | 5 | use TypedStruct 6 | 7 | @doc """ 8 | ## Fields 9 | 10 | """ 11 | 12 | typedstruct do 13 | end 14 | 15 | @doc false 16 | @spec schematic() :: SchematicV.t() 17 | def schematic() do 18 | schema(__MODULE__, %{}) 19 | end 20 | end 21 | -------------------------------------------------------------------------------- /apps/language_server/lib/language_server/lsp/protocol/type_aliases/lsp_object.ex: -------------------------------------------------------------------------------- 1 | # codegen: do not edit 2 | defmodule GenLSP.TypeAlias.LSPObject do 3 | @moduledoc """ 4 | LSP object definition. 5 | @since 3.17.0 6 | """ 7 | 8 | import SchematicV, warn: false 9 | 10 | @type t :: %{String.t() => any()} 11 | 12 | @doc false 13 | @spec schematic() :: SchematicV.t() 14 | def schematic() do 15 | map(keys: str(), values: any()) 16 | end 17 | end 18 | -------------------------------------------------------------------------------- /apps/language_server/lib/language_server/providers/folding_range/helpers.ex: -------------------------------------------------------------------------------- 1 | defmodule ElixirLS.LanguageServer.Providers.FoldingRange.Helpers do 2 | @moduledoc false 3 | 4 | def first_and_last_of_list([]), do: :empty_list 5 | 6 | def first_and_last_of_list([head]), do: {head, head} 7 | 8 | def first_and_last_of_list([head, last]), do: {head, last} 9 | 10 | def first_and_last_of_list([head | tail]) do 11 | {head, List.last(tail)} 12 | end 13 | end 14 | -------------------------------------------------------------------------------- /apps/language_server/test/fixtures/dialyzer/mix.exs: -------------------------------------------------------------------------------- 1 | defmodule ElixirLS.LanguageServer.Fixtures.Dialyzer.Mixfile do 2 | use Mix.Project 3 | 4 | def project do 5 | [app: :els_dialyzer_test, version: "0.1.0"] 6 | end 7 | 8 | # Configuration for the OTP application 9 | # 10 | # Type "mix help compile.app" for more information 11 | def application do 12 | # Specify extra applications you'll use from Erlang/Elixir 13 | [] 14 | end 15 | end 16 | -------------------------------------------------------------------------------- /apps/language_server/test/support/functions_with_the_same_name.ex: -------------------------------------------------------------------------------- 1 | defmodule ElixirSenseExample.FunctionsWithTheSameName do 2 | @doc "all?/2 docs" 3 | def all?(enumerable, fun \\ fn x -> x end) do 4 | IO.inspect({enumerable, fun}) 5 | end 6 | 7 | @doc "concat/1 docs" 8 | def concat(enumerables) do 9 | IO.inspect(enumerables) 10 | end 11 | 12 | @doc "concat/2 docs" 13 | def concat(left, right) do 14 | IO.inspect({left, right}) 15 | end 16 | end 17 | -------------------------------------------------------------------------------- /docs/known-issues-limitations.md: -------------------------------------------------------------------------------- 1 | # Known Issues / Limitations 2 | 3 | * `.exs` files don't return compilation errors 4 | * "Fetching n dependencies" sometimes gets stuck (remove the `.elixir_ls` directory to fix) 5 | * "Go to definition" does not work within the `scope` of a Phoenix router 6 | * On first launch dialyzer will cause high CPU usage for a considerable time 7 | * Dialyzer does not pick up changes involving remote types (https://github.com/elixir-lsp/elixir-ls/issues/502) 8 | -------------------------------------------------------------------------------- /apps/language_server/test/fixtures/workspace_symbols/mix.exs: -------------------------------------------------------------------------------- 1 | defmodule ElixirLS.LanguageServer.Fixtures.WorkspaceSymbols.Mixfile do 2 | use Mix.Project 3 | 4 | def project do 5 | [app: :els_workspace_symbols_test, version: "0.1.0"] 6 | end 7 | 8 | # Configuration for the OTP application 9 | # 10 | # Type "mix help compile.app" for more information 11 | def application do 12 | # Specify extra applications you'll use from Erlang/Elixir 13 | [] 14 | end 15 | end 16 | -------------------------------------------------------------------------------- /apps/language_server/test_fixtures/fixtures/project_with_tests/test/error_test.exs: -------------------------------------------------------------------------------- 1 | defmodule ErrorTest do 2 | use ExUnit.Case 3 | 4 | defmodule ModuleWithoutTests do 5 | end 6 | 7 | test "fixture test" do 8 | assert true 9 | end 10 | 11 | describe "describe with test" do 12 | test "fixture test" do 13 | assert true 14 | end 15 | end 16 | 17 | describe "describe without test" do 18 | end 19 | 20 | test "this will be a test in future" do 21 | end 22 | -------------------------------------------------------------------------------- /apps/language_server/test_fixtures/fixtures/project_with_tests/test/fixture_test.exs: -------------------------------------------------------------------------------- 1 | defmodule FixtureTest do 2 | use ExUnit.Case 3 | 4 | defmodule ModuleWithoutTests do 5 | end 6 | 7 | test "fixture test" do 8 | assert true 9 | end 10 | 11 | describe "describe with test" do 12 | test "fixture test" do 13 | assert true 14 | end 15 | end 16 | 17 | describe "describe without test" do 18 | end 19 | 20 | test "this will be a test in future" 21 | end 22 | -------------------------------------------------------------------------------- /apps/language_server/lib/language_server/lsp/protocol/type_aliases/change_annotation_identifier.ex: -------------------------------------------------------------------------------- 1 | # codegen: do not edit 2 | defmodule GenLSP.TypeAlias.ChangeAnnotationIdentifier do 3 | @moduledoc """ 4 | An identifier to refer to a change annotation stored with a workspace edit. 5 | """ 6 | 7 | import SchematicV, warn: false 8 | 9 | @type t :: String.t() 10 | 11 | @doc false 12 | @spec schematic() :: SchematicV.t() 13 | def schematic() do 14 | str() 15 | end 16 | end 17 | -------------------------------------------------------------------------------- /apps/elixir_ls_utils/test/support/test_utils.ex: -------------------------------------------------------------------------------- 1 | defmodule ElixirLS.Utils.TestUtils do 2 | import ExUnit.Assertions 3 | 4 | def assert_has_cursor_char(text, line, character) do 5 | char = 6 | String.split(text, ["\r\n", "\r", "\n"]) 7 | |> Enum.at(line + 1) 8 | |> String.graphemes() 9 | |> Enum.at(character) 10 | 11 | assert char == "^" 12 | end 13 | 14 | def assert_match_list(list1, list2) do 15 | assert Enum.sort(list1) == Enum.sort(list2) 16 | end 17 | end 18 | -------------------------------------------------------------------------------- /apps/language_server/test/support/fixtures/example_behaviour.ex: -------------------------------------------------------------------------------- 1 | defmodule ElixirLS.LanguageServer.Fixtures.ExampleBehaviour do 2 | @callback greet_world() :: nil 3 | @callback build_greeting(name :: String.t()) :: String.t() 4 | end 5 | 6 | defmodule ElixirLS.LanguageServer.Fixtures.ExampleBehaviourImpl do 7 | @behaviour ElixirLS.LanguageServer.Fixtures.ExampleBehaviour 8 | 9 | @impl true 10 | def greet_world(), do: nil 11 | 12 | @impl true 13 | def build_greeting(name), do: name 14 | end 15 | -------------------------------------------------------------------------------- /apps/language_server/lib/language_server/mcp/supervisor.ex: -------------------------------------------------------------------------------- 1 | defmodule ElixirLS.LanguageServer.MCP.Supervisor do 2 | use Supervisor 3 | 4 | def start_link(parent \\ self(), name \\ nil, port) do 5 | Supervisor.start_link(__MODULE__, {parent, port}, name: name || __MODULE__) 6 | end 7 | 8 | @impl Supervisor 9 | def init({_parent, port}) do 10 | Supervisor.init( 11 | [ 12 | {ElixirLS.LanguageServer.MCP.TCPServer, port: port} 13 | ], 14 | strategy: :one_for_one 15 | ) 16 | end 17 | end 18 | -------------------------------------------------------------------------------- /apps/language_server/lib/language_server/providers/code_action.ex: -------------------------------------------------------------------------------- 1 | defmodule ElixirLS.LanguageServer.Providers.CodeAction do 2 | alias ElixirLS.LanguageServer.Providers.CodeAction.ReplaceRemoteFunction 3 | alias ElixirLS.LanguageServer.Providers.CodeAction.ReplaceWithUnderscore 4 | 5 | @code_actions [ReplaceRemoteFunction, ReplaceWithUnderscore] 6 | 7 | def code_actions(source_file, uri, diagnostic) do 8 | code_actions = Enum.flat_map(@code_actions, & &1.apply(source_file, uri, diagnostic)) 9 | 10 | {:ok, code_actions} 11 | end 12 | end 13 | -------------------------------------------------------------------------------- /apps/language_server/test/mix_project_cache_test.exs: -------------------------------------------------------------------------------- 1 | defmodule ElixirLS.LanguageServer.MixProjectCacheTest do 2 | use ExUnit.Case, async: true 3 | 4 | alias ElixirLS.LanguageServer.MixProjectCache 5 | 6 | setup do 7 | {:ok, pid} = start_supervised(MixProjectCache) 8 | %{pid: pid} 9 | end 10 | 11 | test "returns not_loaded when state is nil", %{pid: pid} do 12 | assert {:error, :not_loaded} = MixProjectCache.get() 13 | assert {:error, :not_loaded} = MixProjectCache.config() 14 | assert Process.alive?(pid) 15 | end 16 | end 17 | -------------------------------------------------------------------------------- /apps/elixir_ls_utils/test/changelog_test.exs: -------------------------------------------------------------------------------- 1 | defmodule ElixirLS.Utils.ChangelogTest do 2 | use ExUnit.Case, async: true 3 | 4 | test "changelog pull requests are correctly linked" do 5 | contents = File.read!("../../CHANGELOG.md") 6 | 7 | String.split(contents, "\n", trim: true) 8 | |> Enum.each(fn line -> 9 | case Regex.run(~r/\/pull\/(\d+)/, line, capture: :all_but_first) do 10 | [pr_number] -> 11 | assert String.match?(line, ~r/\[.*#{pr_number}\]/) 12 | 13 | _ -> 14 | nil 15 | end 16 | end) 17 | end 18 | end 19 | -------------------------------------------------------------------------------- /apps/language_server/test/support/fixtures/references_alias.ex: -------------------------------------------------------------------------------- 1 | defmodule ElixirLS.Test.ReferencesAlias do 2 | require ElixirLS.Test.ReferencesReferenced, as: ReferencesReferenced 3 | alias ElixirLS.Test.ReferencesReferenced, as: Some 4 | alias Some, as: Other 5 | import Other 6 | 7 | def uses_alias_1 do 8 | ReferencesReferenced 9 | end 10 | 11 | def uses_alias_2 do 12 | Some 13 | end 14 | 15 | def uses_alias_3 do 16 | ElixirLS.Test.ReferencesReferenced 17 | end 18 | 19 | def uses_alias_4 do 20 | uses_attribute() 21 | Other 22 | end 23 | end 24 | -------------------------------------------------------------------------------- /apps/debug_adapter/test/fixtures/mix_project/.vscode/launch.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "0.2.0", 3 | "configurations": [ 4 | { 5 | "type": "mix_task", 6 | "name": "mix (Default task)", 7 | "request": "launch", 8 | "projectDir": "${workspaceRoot}" 9 | }, 10 | { 11 | "type": "mix_task", 12 | "name": "mix test", 13 | "request": "launch", 14 | "task": "test", 15 | "taskArgs": ["--trace"], 16 | "projectDir": "${workspaceRoot}", 17 | "requireFiles": ["test/**/test_helper.exs", "test/**/*_test.exs"] 18 | } 19 | ] 20 | } 21 | -------------------------------------------------------------------------------- /apps/language_server/lib/language_server/lsp/protocol/structures/cancel_params.ex: -------------------------------------------------------------------------------- 1 | # codegen: do not edit 2 | defmodule GenLSP.Structures.CancelParams do 3 | import SchematicV, warn: false 4 | 5 | use TypedStruct 6 | 7 | @doc """ 8 | ## Fields 9 | 10 | * id: The request id to cancel. 11 | """ 12 | 13 | typedstruct do 14 | field(:id, integer() | String.t(), enforce: true) 15 | end 16 | 17 | @doc false 18 | @spec schematic() :: SchematicV.t() 19 | def schematic() do 20 | schema(__MODULE__, %{ 21 | {"id", :id} => oneof([int(), str()]) 22 | }) 23 | end 24 | end 25 | -------------------------------------------------------------------------------- /apps/language_server/lib/language_server/lsp/protocol/enumerations/prepare_support_default_behavior.ex: -------------------------------------------------------------------------------- 1 | # codegen: do not edit 2 | defmodule GenLSP.Enumerations.PrepareSupportDefaultBehavior do 3 | @type t :: 1 4 | 5 | import SchematicV, warn: false 6 | 7 | @doc """ 8 | The client's default behavior is to select the identifier 9 | according the to language's syntax rule. 10 | """ 11 | @spec identifier() :: 1 12 | def identifier, do: 1 13 | 14 | @doc false 15 | @spec schematic() :: SchematicV.t() 16 | def schematic() do 17 | oneof([ 18 | 1 19 | ]) 20 | end 21 | end 22 | -------------------------------------------------------------------------------- /apps/debug_adapter/.gitignore: -------------------------------------------------------------------------------- 1 | # The directory Mix will write compiled artifacts to. 2 | /_build 3 | 4 | # If you run "mix test --cover", coverage assets end up here. 5 | /cover 6 | 7 | # The directory Mix downloads your dependencies sources to. 8 | /deps 9 | 10 | # Where 3rd-party dependencies like ExDoc output generated docs. 11 | /doc 12 | 13 | # Ignore .fetch files in case you like to edit your project deps locally. 14 | /.fetch 15 | 16 | # If the VM crashes, it generates a dump, let's ignore it too. 17 | erl_crash.dump 18 | 19 | # Also ignore archive artifacts (built via "mix archive.build"). 20 | *.ez 21 | -------------------------------------------------------------------------------- /apps/language_server/lib/language_server/lsp/protocol/structures/moniker_options.ex: -------------------------------------------------------------------------------- 1 | # codegen: do not edit 2 | defmodule GenLSP.Structures.MonikerOptions do 3 | import SchematicV, warn: false 4 | 5 | use TypedStruct 6 | 7 | @doc """ 8 | ## Fields 9 | 10 | * work_done_progress 11 | """ 12 | 13 | typedstruct do 14 | field(:work_done_progress, boolean()) 15 | end 16 | 17 | @doc false 18 | @spec schematic() :: SchematicV.t() 19 | def schematic() do 20 | schema(__MODULE__, %{ 21 | optional({"workDoneProgress", :work_done_progress}) => bool() 22 | }) 23 | end 24 | end 25 | -------------------------------------------------------------------------------- /apps/debug_adapter/lib/protocol/dap/structures/loaded_sources_arguments.ex: -------------------------------------------------------------------------------- 1 | # codegen: do not edit 2 | 3 | defmodule GenDAP.Structures.LoadedSourcesArguments do 4 | @moduledoc """ 5 | Arguments for `loadedSources` request. 6 | """ 7 | 8 | import SchematicV, warn: false 9 | 10 | use TypedStruct 11 | 12 | @doc """ 13 | ## Fields 14 | 15 | """ 16 | 17 | typedstruct do 18 | @typedoc "A type defining DAP structure LoadedSourcesArguments" 19 | end 20 | 21 | @doc false 22 | @spec schematic() :: SchematicV.t() 23 | def schematic() do 24 | schema(__MODULE__, %{}) 25 | end 26 | end 27 | -------------------------------------------------------------------------------- /apps/elixir_ls_utils/.gitignore: -------------------------------------------------------------------------------- 1 | # The directory Mix will write compiled artifacts to. 2 | /_build 3 | 4 | # If you run "mix test --cover", coverage assets end up here. 5 | /cover 6 | 7 | # The directory Mix downloads your dependencies sources to. 8 | /deps 9 | 10 | # Where 3rd-party dependencies like ExDoc output generated docs. 11 | /doc 12 | 13 | # Ignore .fetch files in case you like to edit your project deps locally. 14 | /.fetch 15 | 16 | # If the VM crashes, it generates a dump, let's ignore it too. 17 | erl_crash.dump 18 | 19 | # Also ignore archive artifacts (built via "mix archive.build"). 20 | *.ez 21 | -------------------------------------------------------------------------------- /apps/language_server/.gitignore: -------------------------------------------------------------------------------- 1 | # The directory Mix will write compiled artifacts to. 2 | /_build 3 | 4 | # If you run "mix test --cover", coverage assets end up here. 5 | /cover 6 | 7 | # The directory Mix downloads your dependencies sources to. 8 | /deps 9 | 10 | # Where 3rd-party dependencies like ExDoc output generated docs. 11 | /doc 12 | 13 | # Ignore .fetch files in case you like to edit your project deps locally. 14 | /.fetch 15 | 16 | # If the VM crashes, it generates a dump, let's ignore it too. 17 | erl_crash.dump 18 | 19 | # Also ignore archive artifacts (built via "mix archive.build"). 20 | *.ez 21 | -------------------------------------------------------------------------------- /apps/language_server/lib/language_server/dialyzer/supervisor.ex: -------------------------------------------------------------------------------- 1 | defmodule ElixirLS.LanguageServer.Dialyzer.Supervisor do 2 | use Supervisor 3 | 4 | def start_link(parent \\ self(), name \\ nil, root_path, dialyzer_module) do 5 | Supervisor.start_link(__MODULE__, {parent, root_path, dialyzer_module}, 6 | name: name || __MODULE__ 7 | ) 8 | end 9 | 10 | @impl Supervisor 11 | def init({parent, root_path, dialyzer_module}) do 12 | Supervisor.init( 13 | [ 14 | {dialyzer_module, {parent, root_path}} 15 | ], 16 | strategy: :one_for_one 17 | ) 18 | end 19 | end 20 | -------------------------------------------------------------------------------- /apps/language_server/lib/language_server/lsp/protocol/structures/declaration_options.ex: -------------------------------------------------------------------------------- 1 | # codegen: do not edit 2 | defmodule GenLSP.Structures.DeclarationOptions do 3 | import SchematicV, warn: false 4 | 5 | use TypedStruct 6 | 7 | @doc """ 8 | ## Fields 9 | 10 | * work_done_progress 11 | """ 12 | 13 | typedstruct do 14 | field(:work_done_progress, boolean()) 15 | end 16 | 17 | @doc false 18 | @spec schematic() :: SchematicV.t() 19 | def schematic() do 20 | schema(__MODULE__, %{ 21 | optional({"workDoneProgress", :work_done_progress}) => bool() 22 | }) 23 | end 24 | end 25 | -------------------------------------------------------------------------------- /apps/language_server/lib/language_server/lsp/protocol/structures/message_action_item.ex: -------------------------------------------------------------------------------- 1 | # codegen: do not edit 2 | defmodule GenLSP.Structures.MessageActionItem do 3 | import SchematicV, warn: false 4 | 5 | use TypedStruct 6 | 7 | @doc """ 8 | ## Fields 9 | 10 | * title: A short title like 'Retry', 'Open Log' etc. 11 | """ 12 | 13 | typedstruct do 14 | field(:title, String.t(), enforce: true) 15 | end 16 | 17 | @doc false 18 | @spec schematic() :: SchematicV.t() 19 | def schematic() do 20 | schema(__MODULE__, %{ 21 | {"title", :title} => str() 22 | }) 23 | end 24 | end 25 | -------------------------------------------------------------------------------- /apps/language_server/lib/language_server/lsp/protocol/type_aliases/declaration.ex: -------------------------------------------------------------------------------- 1 | # codegen: do not edit 2 | defmodule GenLSP.TypeAlias.Declaration do 3 | @moduledoc """ 4 | The declaration of a symbol representation as one or many {@link Location locations}. 5 | """ 6 | 7 | import SchematicV, warn: false 8 | 9 | @type t :: GenLSP.Structures.Location.t() | list(GenLSP.Structures.Location.t()) 10 | 11 | @doc false 12 | @spec schematic() :: SchematicV.t() 13 | def schematic() do 14 | oneof([GenLSP.Structures.Location.schematic(), list(GenLSP.Structures.Location.schematic())]) 15 | end 16 | end 17 | -------------------------------------------------------------------------------- /apps/language_server/lib/language_server/lsp/protocol/structures/document_color_options.ex: -------------------------------------------------------------------------------- 1 | # codegen: do not edit 2 | defmodule GenLSP.Structures.DocumentColorOptions do 3 | import SchematicV, warn: false 4 | 5 | use TypedStruct 6 | 7 | @doc """ 8 | ## Fields 9 | 10 | * work_done_progress 11 | """ 12 | 13 | typedstruct do 14 | field(:work_done_progress, boolean()) 15 | end 16 | 17 | @doc false 18 | @spec schematic() :: SchematicV.t() 19 | def schematic() do 20 | schema(__MODULE__, %{ 21 | optional({"workDoneProgress", :work_done_progress}) => bool() 22 | }) 23 | end 24 | end 25 | -------------------------------------------------------------------------------- /apps/language_server/lib/language_server/lsp/protocol/structures/folding_range_options.ex: -------------------------------------------------------------------------------- 1 | # codegen: do not edit 2 | defmodule GenLSP.Structures.FoldingRangeOptions do 3 | import SchematicV, warn: false 4 | 5 | use TypedStruct 6 | 7 | @doc """ 8 | ## Fields 9 | 10 | * work_done_progress 11 | """ 12 | 13 | typedstruct do 14 | field(:work_done_progress, boolean()) 15 | end 16 | 17 | @doc false 18 | @spec schematic() :: SchematicV.t() 19 | def schematic() do 20 | schema(__MODULE__, %{ 21 | optional({"workDoneProgress", :work_done_progress}) => bool() 22 | }) 23 | end 24 | end 25 | -------------------------------------------------------------------------------- /apps/language_server/lib/language_server/lsp/protocol/structures/implementation_options.ex: -------------------------------------------------------------------------------- 1 | # codegen: do not edit 2 | defmodule GenLSP.Structures.ImplementationOptions do 3 | import SchematicV, warn: false 4 | 5 | use TypedStruct 6 | 7 | @doc """ 8 | ## Fields 9 | 10 | * work_done_progress 11 | """ 12 | 13 | typedstruct do 14 | field(:work_done_progress, boolean()) 15 | end 16 | 17 | @doc false 18 | @spec schematic() :: SchematicV.t() 19 | def schematic() do 20 | schema(__MODULE__, %{ 21 | optional({"workDoneProgress", :work_done_progress}) => bool() 22 | }) 23 | end 24 | end 25 | -------------------------------------------------------------------------------- /apps/language_server/lib/language_server/lsp/protocol/type_aliases/glob_pattern.ex: -------------------------------------------------------------------------------- 1 | # codegen: do not edit 2 | defmodule GenLSP.TypeAlias.GlobPattern do 3 | @moduledoc """ 4 | The glob pattern. Either a string pattern or a relative pattern. 5 | 6 | @since 3.17.0 7 | """ 8 | 9 | import SchematicV, warn: false 10 | 11 | @type t :: GenLSP.TypeAlias.Pattern.t() | GenLSP.Structures.RelativePattern.t() 12 | 13 | @doc false 14 | @spec schematic() :: SchematicV.t() 15 | def schematic() do 16 | oneof([GenLSP.TypeAlias.Pattern.schematic(), GenLSP.Structures.RelativePattern.schematic()]) 17 | end 18 | end 19 | -------------------------------------------------------------------------------- /apps/language_server/lib/language_server/lsp/protocol/structures/selection_range_options.ex: -------------------------------------------------------------------------------- 1 | # codegen: do not edit 2 | defmodule GenLSP.Structures.SelectionRangeOptions do 3 | import SchematicV, warn: false 4 | 5 | use TypedStruct 6 | 7 | @doc """ 8 | ## Fields 9 | 10 | * work_done_progress 11 | """ 12 | 13 | typedstruct do 14 | field(:work_done_progress, boolean()) 15 | end 16 | 17 | @doc false 18 | @spec schematic() :: SchematicV.t() 19 | def schematic() do 20 | schema(__MODULE__, %{ 21 | optional({"workDoneProgress", :work_done_progress}) => bool() 22 | }) 23 | end 24 | end 25 | -------------------------------------------------------------------------------- /apps/language_server/lib/language_server/lsp/protocol/structures/set_trace_params.ex: -------------------------------------------------------------------------------- 1 | # codegen: do not edit 2 | defmodule GenLSP.Structures.SetTraceParams do 3 | import SchematicV, warn: false 4 | 5 | use TypedStruct 6 | 7 | @doc """ 8 | ## Fields 9 | 10 | * value 11 | """ 12 | 13 | typedstruct do 14 | field(:value, GenLSP.Enumerations.TraceValues.t(), enforce: true) 15 | end 16 | 17 | @doc false 18 | @spec schematic() :: SchematicV.t() 19 | def schematic() do 20 | schema(__MODULE__, %{ 21 | {"value", :value} => GenLSP.Enumerations.TraceValues.schematic() 22 | }) 23 | end 24 | end 25 | -------------------------------------------------------------------------------- /apps/language_server/lib/language_server/lsp/protocol/structures/type_definition_options.ex: -------------------------------------------------------------------------------- 1 | # codegen: do not edit 2 | defmodule GenLSP.Structures.TypeDefinitionOptions do 3 | import SchematicV, warn: false 4 | 5 | use TypedStruct 6 | 7 | @doc """ 8 | ## Fields 9 | 10 | * work_done_progress 11 | """ 12 | 13 | typedstruct do 14 | field(:work_done_progress, boolean()) 15 | end 16 | 17 | @doc false 18 | @spec schematic() :: SchematicV.t() 19 | def schematic() do 20 | schema(__MODULE__, %{ 21 | optional({"workDoneProgress", :work_done_progress}) => bool() 22 | }) 23 | end 24 | end 25 | -------------------------------------------------------------------------------- /apps/debug_adapter/lib/protocol/dap/structures/configuration_done_arguments.ex: -------------------------------------------------------------------------------- 1 | # codegen: do not edit 2 | 3 | defmodule GenDAP.Structures.ConfigurationDoneArguments do 4 | @moduledoc """ 5 | Arguments for `configurationDone` request. 6 | """ 7 | 8 | import SchematicV, warn: false 9 | 10 | use TypedStruct 11 | 12 | @doc """ 13 | ## Fields 14 | 15 | """ 16 | 17 | typedstruct do 18 | @typedoc "A type defining DAP structure ConfigurationDoneArguments" 19 | end 20 | 21 | @doc false 22 | @spec schematic() :: SchematicV.t() 23 | def schematic() do 24 | schema(__MODULE__, %{}) 25 | end 26 | end 27 | -------------------------------------------------------------------------------- /apps/language_server/lib/language_server/lsp/protocol/structures/linked_editing_range_options.ex: -------------------------------------------------------------------------------- 1 | # codegen: do not edit 2 | defmodule GenLSP.Structures.LinkedEditingRangeOptions do 3 | import SchematicV, warn: false 4 | 5 | use TypedStruct 6 | 7 | @doc """ 8 | ## Fields 9 | 10 | * work_done_progress 11 | """ 12 | 13 | typedstruct do 14 | field(:work_done_progress, boolean()) 15 | end 16 | 17 | @doc false 18 | @spec schematic() :: SchematicV.t() 19 | def schematic() do 20 | schema(__MODULE__, %{ 21 | optional({"workDoneProgress", :work_done_progress}) => bool() 22 | }) 23 | end 24 | end 25 | -------------------------------------------------------------------------------- /apps/language_server/lib/language_server/lsp/protocol/structures/work_done_progress_options.ex: -------------------------------------------------------------------------------- 1 | # codegen: do not edit 2 | defmodule GenLSP.Structures.WorkDoneProgressOptions do 3 | import SchematicV, warn: false 4 | 5 | use TypedStruct 6 | 7 | @doc """ 8 | ## Fields 9 | 10 | * work_done_progress 11 | """ 12 | 13 | typedstruct do 14 | field(:work_done_progress, boolean()) 15 | end 16 | 17 | @doc false 18 | @spec schematic() :: SchematicV.t() 19 | def schematic() do 20 | schema(__MODULE__, %{ 21 | optional({"workDoneProgress", :work_done_progress}) => bool() 22 | }) 23 | end 24 | end 25 | -------------------------------------------------------------------------------- /scripts/quiet_install.exs: -------------------------------------------------------------------------------- 1 | Application.put_env(:elixir, :ansi_enabled, false) 2 | Code.eval_file("#{__DIR__}/installer.exs") 3 | 4 | Mix.start() 5 | 6 | # Put mix into quiet mode so it does not print anything to standard out 7 | # especially it makes it surface git command errors such as reported in 8 | # https://github.com/elixir-lsp/vscode-elixir-ls/issues/320 9 | # to standard error 10 | # see implementation in 11 | # https://github.com/elixir-lang/elixir/blob/6f96693b355a9b670f2630fd8e6217b69e325c5a/lib/mix/lib/mix/scm/git.ex#LL304C1-L304C1 12 | Mix.shell(ElixirLS.Shell.Quiet) 13 | 14 | ElixirLS.Installer.install_with_retry() 15 | -------------------------------------------------------------------------------- /apps/debug_adapter/test/fixtures/mix_project/README.md: -------------------------------------------------------------------------------- 1 | # MixProject 2 | 3 | **TODO: Add description** 4 | 5 | ## Installation 6 | 7 | If [available in Hex](https://hex.pm/docs/publish), the package can be installed 8 | by adding `mix_project` to your list of dependencies in `mix.exs`: 9 | 10 | ```elixir 11 | def deps do 12 | [{:mix_project, "~> 0.1.0"}] 13 | end 14 | ``` 15 | 16 | Documentation can be generated with [ExDoc](https://github.com/elixir-lang/ex_doc) 17 | and published on [HexDocs](https://hexdocs.pm). Once published, the docs can 18 | be found at [https://hexdocs.pm/mix_project](https://hexdocs.pm/mix_project). 19 | 20 | -------------------------------------------------------------------------------- /apps/elixir_ls_utils/test/launch_test.exs: -------------------------------------------------------------------------------- 1 | defmodule ElixirLS.Utils.LaunchTest do 2 | use ExUnit.Case, async: true 3 | 4 | test "get_versions returns plain strings" do 5 | versions = ElixirLS.Utils.Launch.get_versions() 6 | 7 | assert is_binary(versions.current_elixir_version) 8 | assert is_binary(versions.current_otp_version) 9 | assert is_binary(versions.compile_elixir_version) 10 | assert is_binary(versions.compile_otp_version) 11 | 12 | for value <- Map.values(versions) do 13 | refute String.starts_with?(value, "\"") 14 | refute String.ends_with?(value, "\"") 15 | end 16 | end 17 | end 18 | -------------------------------------------------------------------------------- /docs/getting-started/neovim.md: -------------------------------------------------------------------------------- 1 | # NeoVim 2 | 3 | ## Setup 4 | 5 | There are several plugins available for NeoVim: 6 | 7 | | Plugin | Notes | 8 | |:--|:--| 9 | | [coc.nvim](https://github.com/neoclide/coc.nvim) | Does not support debug adapter | 10 | | [nvim-dap](https://github.com/mfussenegger/nvim-dap) | Only debug adapter | 11 | | [ALE](https://github.com/w0rp/ale) | Does not support debug adapter or typespec suggestions | 12 | | [elixir-lsp/coc-elixir](https://github.com/elixir-lsp/coc-elixir) | Does not support debug adapter | 13 | | [vim-lsp](https://github.com/prabirshrestha/vim-lsp) | Does not support debug adapter | 14 | -------------------------------------------------------------------------------- /apps/debug_adapter/test/fixtures/mix_project/.gitignore: -------------------------------------------------------------------------------- 1 | # The directory Mix will write compiled artifacts to. 2 | /_build 3 | 4 | # If you run "mix test --cover", coverage assets end up here. 5 | /cover 6 | 7 | # The directory Mix downloads your dependencies sources to. 8 | /deps 9 | 10 | # Where 3rd-party dependencies like ExDoc output generated docs. 11 | /doc 12 | 13 | # Ignore .fetch files in case you like to edit your project deps locally. 14 | /.fetch 15 | 16 | # If the VM crashes, it generates a dump, let's ignore it too. 17 | erl_crash.dump 18 | 19 | # Also ignore archive artifacts (built via "mix archive.build"). 20 | *.ez 21 | -------------------------------------------------------------------------------- /apps/language_server/lib/language_server/lsp/protocol/type_aliases/definition_link.ex: -------------------------------------------------------------------------------- 1 | # codegen: do not edit 2 | defmodule GenLSP.TypeAlias.DefinitionLink do 3 | @moduledoc """ 4 | Information about where a symbol is defined. 5 | 6 | Provides additional metadata over normal {@link Location location} definitions, including the range of 7 | the defining symbol 8 | """ 9 | 10 | import SchematicV, warn: false 11 | 12 | @type t :: GenLSP.Structures.LocationLink.t() 13 | 14 | @doc false 15 | @spec schematic() :: SchematicV.t() 16 | def schematic() do 17 | GenLSP.Structures.LocationLink.schematic() 18 | end 19 | end 20 | -------------------------------------------------------------------------------- /apps/language_server/lib/language_server/lsp/protocol/enumerations/symbol_tag.ex: -------------------------------------------------------------------------------- 1 | # codegen: do not edit 2 | defmodule GenLSP.Enumerations.SymbolTag do 3 | @moduledoc """ 4 | Symbol tags are extra annotations that tweak the rendering of a symbol. 5 | 6 | @since 3.16 7 | """ 8 | 9 | @type t :: 1 10 | 11 | import SchematicV, warn: false 12 | 13 | @doc """ 14 | Render a symbol as obsolete, usually using a strike-out. 15 | """ 16 | @spec deprecated() :: 1 17 | def deprecated, do: 1 18 | 19 | @doc false 20 | @spec schematic() :: SchematicV.t() 21 | def schematic() do 22 | oneof([ 23 | 1 24 | ]) 25 | end 26 | end 27 | -------------------------------------------------------------------------------- /apps/elixir_ls_utils/lib/mix.tasks.elixir_ls.release2.ex: -------------------------------------------------------------------------------- 1 | defmodule Mix.Tasks.ElixirLs.Release2 do 2 | use Mix.Task 3 | 4 | @switches [destination: :string, local: :boolean] 5 | @aliases [o: :destination, l: :local] 6 | 7 | @impl Mix.Task 8 | def run(args) do 9 | {opts, _} = OptionParser.parse!(args, aliases: @aliases, switches: @switches) 10 | destination = Path.expand(opts[:destination] || "release") 11 | 12 | File.rm_rf!(destination) 13 | 14 | File.cp_r!("./scripts", destination) 15 | 16 | unless opts[:local] do 17 | File.cp!("./VERSION", Path.join(destination, "VERSION")) 18 | end 19 | 20 | :ok 21 | end 22 | end 23 | -------------------------------------------------------------------------------- /apps/language_server/lib/language_server/lsp/protocol/structures/did_change_configuration_registration_options.ex: -------------------------------------------------------------------------------- 1 | # codegen: do not edit 2 | defmodule GenLSP.Structures.DidChangeConfigurationRegistrationOptions do 3 | import SchematicV, warn: false 4 | 5 | use TypedStruct 6 | 7 | @doc """ 8 | ## Fields 9 | 10 | * section 11 | """ 12 | 13 | typedstruct do 14 | field(:section, String.t() | list(String.t())) 15 | end 16 | 17 | @doc false 18 | @spec schematic() :: SchematicV.t() 19 | def schematic() do 20 | schema(__MODULE__, %{ 21 | optional({"section", :section}) => oneof([str(), list(str())]) 22 | }) 23 | end 24 | end 25 | -------------------------------------------------------------------------------- /apps/language_server/lib/language_server/lsp/protocol/structures/hover_options.ex: -------------------------------------------------------------------------------- 1 | # codegen: do not edit 2 | defmodule GenLSP.Structures.HoverOptions do 3 | @moduledoc """ 4 | Hover options. 5 | """ 6 | 7 | import SchematicV, warn: false 8 | 9 | use TypedStruct 10 | 11 | @doc """ 12 | ## Fields 13 | 14 | * work_done_progress 15 | """ 16 | 17 | typedstruct do 18 | field(:work_done_progress, boolean()) 19 | end 20 | 21 | @doc false 22 | @spec schematic() :: SchematicV.t() 23 | def schematic() do 24 | schema(__MODULE__, %{ 25 | optional({"workDoneProgress", :work_done_progress}) => bool() 26 | }) 27 | end 28 | end 29 | -------------------------------------------------------------------------------- /apps/language_server/lib/language_server/lsp/protocol/structures/reference_options.ex: -------------------------------------------------------------------------------- 1 | # codegen: do not edit 2 | defmodule GenLSP.Structures.ReferenceOptions do 3 | @moduledoc """ 4 | Reference options. 5 | """ 6 | 7 | import SchematicV, warn: false 8 | 9 | use TypedStruct 10 | 11 | @doc """ 12 | ## Fields 13 | 14 | * work_done_progress 15 | """ 16 | 17 | typedstruct do 18 | field(:work_done_progress, boolean()) 19 | end 20 | 21 | @doc false 22 | @spec schematic() :: SchematicV.t() 23 | def schematic() do 24 | schema(__MODULE__, %{ 25 | optional({"workDoneProgress", :work_done_progress}) => bool() 26 | }) 27 | end 28 | end 29 | -------------------------------------------------------------------------------- /apps/language_server/lib/language_server/lsp/protocol/structures/registration_params.ex: -------------------------------------------------------------------------------- 1 | # codegen: do not edit 2 | defmodule GenLSP.Structures.RegistrationParams do 3 | import SchematicV, warn: false 4 | 5 | use TypedStruct 6 | 7 | @doc """ 8 | ## Fields 9 | 10 | * registrations 11 | """ 12 | 13 | typedstruct do 14 | field(:registrations, list(GenLSP.Structures.Registration.t()), enforce: true) 15 | end 16 | 17 | @doc false 18 | @spec schematic() :: SchematicV.t() 19 | def schematic() do 20 | schema(__MODULE__, %{ 21 | {"registrations", :registrations} => list(GenLSP.Structures.Registration.schematic()) 22 | }) 23 | end 24 | end 25 | -------------------------------------------------------------------------------- /apps/language_server/lib/language_server/lsp/protocol/structures/semantic_tokens_partial_result.ex: -------------------------------------------------------------------------------- 1 | # codegen: do not edit 2 | defmodule GenLSP.Structures.SemanticTokensPartialResult do 3 | @moduledoc """ 4 | @since 3.16.0 5 | """ 6 | 7 | import SchematicV, warn: false 8 | 9 | use TypedStruct 10 | 11 | @doc """ 12 | ## Fields 13 | 14 | * data 15 | """ 16 | 17 | typedstruct do 18 | field(:data, list(GenLSP.BaseTypes.uinteger()), enforce: true) 19 | end 20 | 21 | @doc false 22 | @spec schematic() :: SchematicV.t() 23 | def schematic() do 24 | schema(__MODULE__, %{ 25 | {"data", :data} => list(int()) 26 | }) 27 | end 28 | end 29 | -------------------------------------------------------------------------------- /apps/language_server/lib/language_server/lsp/protocol/structures/log_trace_params.ex: -------------------------------------------------------------------------------- 1 | # codegen: do not edit 2 | defmodule GenLSP.Structures.LogTraceParams do 3 | import SchematicV, warn: false 4 | 5 | use TypedStruct 6 | 7 | @doc """ 8 | ## Fields 9 | 10 | * message 11 | * verbose 12 | """ 13 | 14 | typedstruct do 15 | field(:message, String.t(), enforce: true) 16 | field(:verbose, String.t()) 17 | end 18 | 19 | @doc false 20 | @spec schematic() :: SchematicV.t() 21 | def schematic() do 22 | schema(__MODULE__, %{ 23 | {"message", :message} => str(), 24 | optional({"verbose", :verbose}) => str() 25 | }) 26 | end 27 | end 28 | -------------------------------------------------------------------------------- /apps/debug_adapter/lib/debug_adapter/error_dictionary.ex: -------------------------------------------------------------------------------- 1 | defmodule ElixirLS.DebugAdapter.ErrorDictionary do 2 | @moduledoc """ 3 | Provides mapping from error names to unique integer codes for DAP error messages. 4 | """ 5 | 6 | @codes %{ 7 | "internalServerError" => 1, 8 | "cancelled" => 2, 9 | "invalidRequest" => 3, 10 | "launchError" => 4, 11 | "attachError" => 5, 12 | "invalidArgument" => 6, 13 | "evaluateError" => 7, 14 | "argumentError" => 8, 15 | "runtimeError" => 9, 16 | "notSupported" => 10 17 | } 18 | 19 | @spec code(String.t()) :: integer() 20 | def code(name) do 21 | Map.fetch!(@codes, name) 22 | end 23 | end 24 | -------------------------------------------------------------------------------- /apps/language_server/lib/language_server/lsp/protocol/structures/save_options.ex: -------------------------------------------------------------------------------- 1 | # codegen: do not edit 2 | defmodule GenLSP.Structures.SaveOptions do 3 | @moduledoc """ 4 | Save options. 5 | """ 6 | 7 | import SchematicV, warn: false 8 | 9 | use TypedStruct 10 | 11 | @doc """ 12 | ## Fields 13 | 14 | * include_text: The client is supposed to include the content on save. 15 | """ 16 | 17 | typedstruct do 18 | field(:include_text, boolean()) 19 | end 20 | 21 | @doc false 22 | @spec schematic() :: SchematicV.t() 23 | def schematic() do 24 | schema(__MODULE__, %{ 25 | optional({"includeText", :include_text}) => bool() 26 | }) 27 | end 28 | end 29 | -------------------------------------------------------------------------------- /apps/language_server/lib/language_server/lsp/protocol/structures/work_done_progress_cancel_params.ex: -------------------------------------------------------------------------------- 1 | # codegen: do not edit 2 | defmodule GenLSP.Structures.WorkDoneProgressCancelParams do 3 | import SchematicV, warn: false 4 | 5 | use TypedStruct 6 | 7 | @doc """ 8 | ## Fields 9 | 10 | * token: The token to be used to report progress. 11 | """ 12 | 13 | typedstruct do 14 | field(:token, GenLSP.TypeAlias.ProgressToken.t(), enforce: true) 15 | end 16 | 17 | @doc false 18 | @spec schematic() :: SchematicV.t() 19 | def schematic() do 20 | schema(__MODULE__, %{ 21 | {"token", :token} => GenLSP.TypeAlias.ProgressToken.schematic() 22 | }) 23 | end 24 | end 25 | -------------------------------------------------------------------------------- /apps/language_server/lib/language_server/lsp/protocol/structures/work_done_progress_create_params.ex: -------------------------------------------------------------------------------- 1 | # codegen: do not edit 2 | defmodule GenLSP.Structures.WorkDoneProgressCreateParams do 3 | import SchematicV, warn: false 4 | 5 | use TypedStruct 6 | 7 | @doc """ 8 | ## Fields 9 | 10 | * token: The token to be used to report progress. 11 | """ 12 | 13 | typedstruct do 14 | field(:token, GenLSP.TypeAlias.ProgressToken.t(), enforce: true) 15 | end 16 | 17 | @doc false 18 | @spec schematic() :: SchematicV.t() 19 | def schematic() do 20 | schema(__MODULE__, %{ 21 | {"token", :token} => GenLSP.TypeAlias.ProgressToken.schematic() 22 | }) 23 | end 24 | end 25 | -------------------------------------------------------------------------------- /apps/language_server/lib/language_server/lsp/protocol/type_aliases/prepare_rename_result.ex: -------------------------------------------------------------------------------- 1 | # codegen: do not edit 2 | defmodule GenLSP.TypeAlias.PrepareRenameResult do 3 | import SchematicV, warn: false 4 | 5 | @type t :: GenLSP.Structures.Range.t() | map() | map() 6 | 7 | @doc false 8 | @spec schematic() :: SchematicV.t() 9 | def schematic() do 10 | oneof([ 11 | GenLSP.Structures.Range.schematic(), 12 | map(%{ 13 | {"range", :range} => GenLSP.Structures.Range.schematic(), 14 | {"placeholder", :placeholder} => str() 15 | }), 16 | map(%{ 17 | {"defaultBehavior", :default_behavior} => bool() 18 | }) 19 | ]) 20 | end 21 | end 22 | -------------------------------------------------------------------------------- /apps/language_server/test/support/module_with_types.ex: -------------------------------------------------------------------------------- 1 | defmodule ElixirSenseExample.ModuleWithTypes do 2 | @type pub_type :: integer 3 | @typep priv_type :: integer 4 | @opaque opaque_type :: priv_type 5 | @callback some_callback(integer) :: atom 6 | @macrocallback some_macrocallback(integer) :: atom 7 | 8 | @spec some_fun_priv(integer) :: integer 9 | defp some_fun_priv(a), do: a + 1 10 | 11 | @spec some_fun(integer) :: integer 12 | def some_fun(a), do: some_fun_priv(a) + 1 13 | 14 | @spec some_macro_priv() :: Macro.t() 15 | defmacrop some_macro_priv(), do: :abc 16 | 17 | @spec some_macro(integer) :: Macro.t() 18 | defmacro some_macro(_a), do: some_macro_priv() 19 | end 20 | -------------------------------------------------------------------------------- /apps/language_server/test/support/types_with_multiple_arity.ex: -------------------------------------------------------------------------------- 1 | defmodule ElixirSenseExample.TypesWithMultipleArity do 2 | @typedoc "no params version" 3 | @type my_type :: integer 4 | @typedoc "one param version" 5 | @type my_type(a) :: {integer, a} 6 | @typedoc "two params version" 7 | @type my_type(a, b) :: {integer, a, b} 8 | end 9 | 10 | for i <- 1..1 do 11 | defmodule :"Elixir.ElixirSenseExample.TypesWithMultipleArity#{i}" do 12 | @typedoc "no params version" 13 | @type my_type :: integer 14 | @typedoc "one param version" 15 | @type my_type(a) :: {integer, a} 16 | @typedoc "two params version" 17 | @type my_type(a, b) :: {integer, a, b} 18 | end 19 | end 20 | -------------------------------------------------------------------------------- /apps/language_server/lib/language_server/lsp/protocol/enumerations/completion_item_tag.ex: -------------------------------------------------------------------------------- 1 | # codegen: do not edit 2 | defmodule GenLSP.Enumerations.CompletionItemTag do 3 | @moduledoc """ 4 | Completion item tags are extra annotations that tweak the rendering of a completion 5 | item. 6 | 7 | @since 3.15.0 8 | """ 9 | 10 | @type t :: 1 11 | 12 | import SchematicV, warn: false 13 | 14 | @doc """ 15 | Render a completion as obsolete, usually using a strike-out. 16 | """ 17 | @spec deprecated() :: 1 18 | def deprecated, do: 1 19 | 20 | @doc false 21 | @spec schematic() :: SchematicV.t() 22 | def schematic() do 23 | oneof([ 24 | 1 25 | ]) 26 | end 27 | end 28 | -------------------------------------------------------------------------------- /apps/debug_adapter/lib/protocol/dap/structures/value_format.ex: -------------------------------------------------------------------------------- 1 | # codegen: do not edit 2 | 3 | defmodule GenDAP.Structures.ValueFormat do 4 | @moduledoc """ 5 | Provides formatting information for a value. 6 | """ 7 | 8 | import SchematicV, warn: false 9 | 10 | use TypedStruct 11 | 12 | @doc """ 13 | ## Fields 14 | 15 | * hex: Display the value in hex. 16 | """ 17 | 18 | typedstruct do 19 | @typedoc "A type defining DAP structure ValueFormat" 20 | field(:hex, boolean()) 21 | end 22 | 23 | @doc false 24 | @spec schematic() :: SchematicV.t() 25 | def schematic() do 26 | schema(__MODULE__, %{ 27 | optional({"hex", :hex}) => bool() 28 | }) 29 | end 30 | end 31 | -------------------------------------------------------------------------------- /apps/language_server/lib/language_server/lsp/protocol/notifications/dollar_log_trace.ex: -------------------------------------------------------------------------------- 1 | # codegen: do not edit 2 | defmodule GenLSP.Notifications.DollarLogTrace do 3 | import SchematicV, warn: false 4 | 5 | use TypedStruct 6 | 7 | typedstruct do 8 | field(:method, String.t(), default: "$/logTrace") 9 | field(:jsonrpc, String.t(), default: "2.0") 10 | field(:params, GenLSP.Structures.LogTraceParams.t()) 11 | end 12 | 13 | @doc false 14 | @spec schematic() :: SchematicV.t() 15 | def schematic() do 16 | schema(__MODULE__, %{ 17 | method: "$/logTrace", 18 | jsonrpc: "2.0", 19 | params: GenLSP.Structures.LogTraceParams.schematic() 20 | }) 21 | end 22 | end 23 | -------------------------------------------------------------------------------- /apps/language_server/lib/language_server/lsp/protocol/notifications/dollar_progress.ex: -------------------------------------------------------------------------------- 1 | # codegen: do not edit 2 | defmodule GenLSP.Notifications.DollarProgress do 3 | import SchematicV, warn: false 4 | 5 | use TypedStruct 6 | 7 | typedstruct do 8 | field(:method, String.t(), default: "$/progress") 9 | field(:jsonrpc, String.t(), default: "2.0") 10 | field(:params, GenLSP.Structures.ProgressParams.t()) 11 | end 12 | 13 | @doc false 14 | @spec schematic() :: SchematicV.t() 15 | def schematic() do 16 | schema(__MODULE__, %{ 17 | method: "$/progress", 18 | jsonrpc: "2.0", 19 | params: GenLSP.Structures.ProgressParams.schematic() 20 | }) 21 | end 22 | end 23 | -------------------------------------------------------------------------------- /apps/language_server/lib/language_server/lsp/protocol/notifications/dollar_set_trace.ex: -------------------------------------------------------------------------------- 1 | # codegen: do not edit 2 | defmodule GenLSP.Notifications.DollarSetTrace do 3 | import SchematicV, warn: false 4 | 5 | use TypedStruct 6 | 7 | typedstruct do 8 | field(:method, String.t(), default: "$/setTrace") 9 | field(:jsonrpc, String.t(), default: "2.0") 10 | field(:params, GenLSP.Structures.SetTraceParams.t()) 11 | end 12 | 13 | @doc false 14 | @spec schematic() :: SchematicV.t() 15 | def schematic() do 16 | schema(__MODULE__, %{ 17 | method: "$/setTrace", 18 | jsonrpc: "2.0", 19 | params: GenLSP.Structures.SetTraceParams.schematic() 20 | }) 21 | end 22 | end 23 | -------------------------------------------------------------------------------- /apps/language_server/lib/language_server/lsp/protocol/structures/unregistration_params.ex: -------------------------------------------------------------------------------- 1 | # codegen: do not edit 2 | defmodule GenLSP.Structures.UnregistrationParams do 3 | import SchematicV, warn: false 4 | 5 | use TypedStruct 6 | 7 | @doc """ 8 | ## Fields 9 | 10 | * unregisterations 11 | """ 12 | 13 | typedstruct do 14 | field(:unregisterations, list(GenLSP.Structures.Unregistration.t()), enforce: true) 15 | end 16 | 17 | @doc false 18 | @spec schematic() :: SchematicV.t() 19 | def schematic() do 20 | schema(__MODULE__, %{ 21 | {"unregisterations", :unregisterations} => 22 | list(GenLSP.Structures.Unregistration.schematic()) 23 | }) 24 | end 25 | end 26 | -------------------------------------------------------------------------------- /apps/language_server/lib/language_server/providers/execute_command/get_ex_unit_tests_in_file.ex: -------------------------------------------------------------------------------- 1 | defmodule ElixirLS.LanguageServer.Providers.ExecuteCommand.GetExUnitTestsInFile do 2 | alias ElixirLS.LanguageServer.{SourceFile, ExUnitTestTracer} 3 | @behaviour ElixirLS.LanguageServer.Providers.ExecuteCommand 4 | 5 | @impl ElixirLS.LanguageServer.Providers.ExecuteCommand 6 | def execute([uri], _state) do 7 | path = SourceFile.Path.from_uri(uri) 8 | 9 | case ExUnitTestTracer.get_tests(path) do 10 | {:ok, tests} -> 11 | {:ok, tests} 12 | 13 | {:error, _reason} -> 14 | # TODO catch only Compile and Syntax errors? 15 | {:ok, []} 16 | end 17 | end 18 | end 19 | -------------------------------------------------------------------------------- /apps/language_server/lib/language_server/lsp/protocol/structures/definition_options.ex: -------------------------------------------------------------------------------- 1 | # codegen: do not edit 2 | defmodule GenLSP.Structures.DefinitionOptions do 3 | @moduledoc """ 4 | Server Capabilities for a {@link DefinitionRequest}. 5 | """ 6 | 7 | import SchematicV, warn: false 8 | 9 | use TypedStruct 10 | 11 | @doc """ 12 | ## Fields 13 | 14 | * work_done_progress 15 | """ 16 | 17 | typedstruct do 18 | field(:work_done_progress, boolean()) 19 | end 20 | 21 | @doc false 22 | @spec schematic() :: SchematicV.t() 23 | def schematic() do 24 | schema(__MODULE__, %{ 25 | optional({"workDoneProgress", :work_done_progress}) => bool() 26 | }) 27 | end 28 | end 29 | -------------------------------------------------------------------------------- /apps/language_server/lib/language_server/lsp/protocol/structures/text_document_identifier.ex: -------------------------------------------------------------------------------- 1 | # codegen: do not edit 2 | defmodule GenLSP.Structures.TextDocumentIdentifier do 3 | @moduledoc """ 4 | A literal to identify a text document in the client. 5 | """ 6 | 7 | import SchematicV, warn: false 8 | 9 | use TypedStruct 10 | 11 | @doc """ 12 | ## Fields 13 | 14 | * uri: The text document's uri. 15 | """ 16 | 17 | typedstruct do 18 | field(:uri, GenLSP.BaseTypes.document_uri(), enforce: true) 19 | end 20 | 21 | @doc false 22 | @spec schematic() :: SchematicV.t() 23 | def schematic() do 24 | schema(__MODULE__, %{ 25 | {"uri", :uri} => str() 26 | }) 27 | end 28 | end 29 | -------------------------------------------------------------------------------- /apps/language_server/lib/language_server/lsp/protocol/notifications/dollar_cancel_request.ex: -------------------------------------------------------------------------------- 1 | # codegen: do not edit 2 | defmodule GenLSP.Notifications.DollarCancelRequest do 3 | import SchematicV, warn: false 4 | 5 | use TypedStruct 6 | 7 | typedstruct do 8 | field(:method, String.t(), default: "$/cancelRequest") 9 | field(:jsonrpc, String.t(), default: "2.0") 10 | field(:params, GenLSP.Structures.CancelParams.t()) 11 | end 12 | 13 | @doc false 14 | @spec schematic() :: SchematicV.t() 15 | def schematic() do 16 | schema(__MODULE__, %{ 17 | method: "$/cancelRequest", 18 | jsonrpc: "2.0", 19 | params: GenLSP.Structures.CancelParams.schematic() 20 | }) 21 | end 22 | end 23 | -------------------------------------------------------------------------------- /apps/language_server/lib/language_server/lsp/protocol/structures/document_highlight_options.ex: -------------------------------------------------------------------------------- 1 | # codegen: do not edit 2 | defmodule GenLSP.Structures.DocumentHighlightOptions do 3 | @moduledoc """ 4 | Provider options for a {@link DocumentHighlightRequest}. 5 | """ 6 | 7 | import SchematicV, warn: false 8 | 9 | use TypedStruct 10 | 11 | @doc """ 12 | ## Fields 13 | 14 | * work_done_progress 15 | """ 16 | 17 | typedstruct do 18 | field(:work_done_progress, boolean()) 19 | end 20 | 21 | @doc false 22 | @spec schematic() :: SchematicV.t() 23 | def schematic() do 24 | schema(__MODULE__, %{ 25 | optional({"workDoneProgress", :work_done_progress}) => bool() 26 | }) 27 | end 28 | end 29 | -------------------------------------------------------------------------------- /scripts/debug_adapter.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # Launches the debug adapter. This script must be in the same directory as mix install launch script. 3 | 4 | readlink_f () { 5 | cd "$(dirname "$1")" > /dev/null || exit 1 6 | filename="$(basename "$1")" 7 | if [ -h "$filename" ]; then 8 | readlink_f "$(readlink "$filename")" 9 | else 10 | echo "$(pwd -P)/$filename" 11 | fi 12 | } 13 | 14 | if [ -z "${ELS_INSTALL_PREFIX}" ]; then 15 | dir="$(dirname "$(readlink_f "$0")")" 16 | >&2 echo "running ${dir}/launch.sh" 17 | else 18 | dir=${ELS_INSTALL_PREFIX} 19 | >&2 echo "ELS_INSTALL_PREFIX is set, running ${ELS_INSTALL_PREFIX}/launch.sh" 20 | fi 21 | 22 | export ELS_MODE=debug_adapter 23 | exec "${dir}/launch.sh" 24 | -------------------------------------------------------------------------------- /scripts/elixir_check.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # Checks if elixir is available. This script must be in the same directory as mix install launch script. 3 | 4 | readlink_f () { 5 | cd "$(dirname "$1")" > /dev/null || exit 1 6 | filename="$(basename "$1")" 7 | if [ -h "$filename" ]; then 8 | readlink_f "$(readlink "$filename")" 9 | else 10 | echo "$(pwd -P)/$filename" 11 | fi 12 | } 13 | 14 | if [ -z "${ELS_INSTALL_PREFIX}" ]; then 15 | dir="$(dirname "$(readlink_f "$0")")" 16 | >&2 echo "Running ${dir}/launch.sh" 17 | else 18 | dir=${ELS_INSTALL_PREFIX} 19 | >&2 echo "ELS_INSTALL_PREFIX is set, running ${ELS_INSTALL_PREFIX}/launch.sh" 20 | fi 21 | 22 | export ELS_MODE=elixir_check 23 | exec "${dir}/launch.sh" 24 | -------------------------------------------------------------------------------- /apps/language_server/lib/language_server/lsp/protocol/structures/document_formatting_options.ex: -------------------------------------------------------------------------------- 1 | # codegen: do not edit 2 | defmodule GenLSP.Structures.DocumentFormattingOptions do 3 | @moduledoc """ 4 | Provider options for a {@link DocumentFormattingRequest}. 5 | """ 6 | 7 | import SchematicV, warn: false 8 | 9 | use TypedStruct 10 | 11 | @doc """ 12 | ## Fields 13 | 14 | * work_done_progress 15 | """ 16 | 17 | typedstruct do 18 | field(:work_done_progress, boolean()) 19 | end 20 | 21 | @doc false 22 | @spec schematic() :: SchematicV.t() 23 | def schematic() do 24 | schema(__MODULE__, %{ 25 | optional({"workDoneProgress", :work_done_progress}) => bool() 26 | }) 27 | end 28 | end 29 | -------------------------------------------------------------------------------- /apps/language_server/lib/language_server/lsp/protocol/structures/file_create.ex: -------------------------------------------------------------------------------- 1 | # codegen: do not edit 2 | defmodule GenLSP.Structures.FileCreate do 3 | @moduledoc """ 4 | Represents information on a file/folder create. 5 | 6 | @since 3.16.0 7 | """ 8 | 9 | import SchematicV, warn: false 10 | 11 | use TypedStruct 12 | 13 | @doc """ 14 | ## Fields 15 | 16 | * uri: A file:// URI for the location of the file/folder being created. 17 | """ 18 | 19 | typedstruct do 20 | field(:uri, String.t(), enforce: true) 21 | end 22 | 23 | @doc false 24 | @spec schematic() :: SchematicV.t() 25 | def schematic() do 26 | schema(__MODULE__, %{ 27 | {"uri", :uri} => str() 28 | }) 29 | end 30 | end 31 | -------------------------------------------------------------------------------- /apps/language_server/lib/language_server/lsp/protocol/structures/file_delete.ex: -------------------------------------------------------------------------------- 1 | # codegen: do not edit 2 | defmodule GenLSP.Structures.FileDelete do 3 | @moduledoc """ 4 | Represents information on a file/folder delete. 5 | 6 | @since 3.16.0 7 | """ 8 | 9 | import SchematicV, warn: false 10 | 11 | use TypedStruct 12 | 13 | @doc """ 14 | ## Fields 15 | 16 | * uri: A file:// URI for the location of the file/folder being deleted. 17 | """ 18 | 19 | typedstruct do 20 | field(:uri, String.t(), enforce: true) 21 | end 22 | 23 | @doc false 24 | @spec schematic() :: SchematicV.t() 25 | def schematic() do 26 | schema(__MODULE__, %{ 27 | {"uri", :uri} => str() 28 | }) 29 | end 30 | end 31 | -------------------------------------------------------------------------------- /scripts/language_server.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # Launches the language server. This script must be in the same directory as mix install launch script. 3 | 4 | readlink_f () { 5 | cd "$(dirname "$1")" > /dev/null || exit 1 6 | filename="$(basename "$1")" 7 | if [ -h "$filename" ]; then 8 | readlink_f "$(readlink "$filename")" 9 | else 10 | echo "$(pwd -P)/$filename" 11 | fi 12 | } 13 | 14 | if [ -z "${ELS_INSTALL_PREFIX}" ]; then 15 | dir="$(dirname "$(readlink_f "$0")")" 16 | >&2 echo "Running ${dir}/launch.sh" 17 | else 18 | dir=${ELS_INSTALL_PREFIX} 19 | >&2 echo "ELS_INSTALL_PREFIX is set, running ${ELS_INSTALL_PREFIX}/launch.sh" 20 | fi 21 | 22 | export ELS_MODE=language_server 23 | exec "${dir}/launch.sh" 24 | -------------------------------------------------------------------------------- /apps/debug_adapter/lib/protocol/dap/structures/pause_arguments.ex: -------------------------------------------------------------------------------- 1 | # codegen: do not edit 2 | 3 | defmodule GenDAP.Structures.PauseArguments do 4 | @moduledoc """ 5 | Arguments for `pause` request. 6 | """ 7 | 8 | import SchematicV, warn: false 9 | 10 | use TypedStruct 11 | 12 | @doc """ 13 | ## Fields 14 | 15 | * thread_id: Pause execution for this thread. 16 | """ 17 | 18 | typedstruct do 19 | @typedoc "A type defining DAP structure PauseArguments" 20 | field(:thread_id, integer(), enforce: true) 21 | end 22 | 23 | @doc false 24 | @spec schematic() :: SchematicV.t() 25 | def schematic() do 26 | schema(__MODULE__, %{ 27 | {"threadId", :thread_id} => int() 28 | }) 29 | end 30 | end 31 | -------------------------------------------------------------------------------- /apps/language_server/lib/language_server/lsp/protocol/enumerations/inlay_hint_kind.ex: -------------------------------------------------------------------------------- 1 | # codegen: do not edit 2 | defmodule GenLSP.Enumerations.InlayHintKind do 3 | @moduledoc """ 4 | Inlay hint kinds. 5 | 6 | @since 3.17.0 7 | """ 8 | 9 | @type t :: 1 | 2 10 | 11 | import SchematicV, warn: false 12 | 13 | @doc """ 14 | An inlay hint that for a type annotation. 15 | """ 16 | @spec type() :: 1 17 | def type, do: 1 18 | 19 | @doc """ 20 | An inlay hint that is for a parameter. 21 | """ 22 | @spec parameter() :: 2 23 | def parameter, do: 2 24 | 25 | @doc false 26 | @spec schematic() :: SchematicV.t() 27 | def schematic() do 28 | oneof([ 29 | 1, 30 | 2 31 | ]) 32 | end 33 | end 34 | -------------------------------------------------------------------------------- /apps/language_server/lib/language_server/lsp/protocol/structures/did_change_configuration_client_capabilities.ex: -------------------------------------------------------------------------------- 1 | # codegen: do not edit 2 | defmodule GenLSP.Structures.DidChangeConfigurationClientCapabilities do 3 | import SchematicV, warn: false 4 | 5 | use TypedStruct 6 | 7 | @doc """ 8 | ## Fields 9 | 10 | * dynamic_registration: Did change configuration notification supports dynamic registration. 11 | """ 12 | 13 | typedstruct do 14 | field(:dynamic_registration, boolean()) 15 | end 16 | 17 | @doc false 18 | @spec schematic() :: SchematicV.t() 19 | def schematic() do 20 | schema(__MODULE__, %{ 21 | optional({"dynamicRegistration", :dynamic_registration}) => bool() 22 | }) 23 | end 24 | end 25 | -------------------------------------------------------------------------------- /apps/language_server/lib/language_server/lsp/protocol/structures/show_document_result.ex: -------------------------------------------------------------------------------- 1 | # codegen: do not edit 2 | defmodule GenLSP.Structures.ShowDocumentResult do 3 | @moduledoc """ 4 | The result of a showDocument request. 5 | 6 | @since 3.16.0 7 | """ 8 | 9 | import SchematicV, warn: false 10 | 11 | use TypedStruct 12 | 13 | @doc """ 14 | ## Fields 15 | 16 | * success: A boolean indicating if the show was successful. 17 | """ 18 | 19 | typedstruct do 20 | field(:success, boolean(), enforce: true) 21 | end 22 | 23 | @doc false 24 | @spec schematic() :: SchematicV.t() 25 | def schematic() do 26 | schema(__MODULE__, %{ 27 | {"success", :success} => bool() 28 | }) 29 | end 30 | end 31 | -------------------------------------------------------------------------------- /apps/language_server/lib/language_server/lsp/protocol/structures/configuration_params.ex: -------------------------------------------------------------------------------- 1 | # codegen: do not edit 2 | defmodule GenLSP.Structures.ConfigurationParams do 3 | @moduledoc """ 4 | The parameters of a configuration request. 5 | """ 6 | 7 | import SchematicV, warn: false 8 | 9 | use TypedStruct 10 | 11 | @doc """ 12 | ## Fields 13 | 14 | * items 15 | """ 16 | 17 | typedstruct do 18 | field(:items, list(GenLSP.Structures.ConfigurationItem.t()), enforce: true) 19 | end 20 | 21 | @doc false 22 | @spec schematic() :: SchematicV.t() 23 | def schematic() do 24 | schema(__MODULE__, %{ 25 | {"items", :items} => list(GenLSP.Structures.ConfigurationItem.schematic()) 26 | }) 27 | end 28 | end 29 | -------------------------------------------------------------------------------- /apps/language_server/lib/language_server/lsp/protocol/structures/inline_value_options.ex: -------------------------------------------------------------------------------- 1 | # codegen: do not edit 2 | defmodule GenLSP.Structures.InlineValueOptions do 3 | @moduledoc """ 4 | Inline value options used during static registration. 5 | 6 | @since 3.17.0 7 | """ 8 | 9 | import SchematicV, warn: false 10 | 11 | use TypedStruct 12 | 13 | @doc """ 14 | ## Fields 15 | 16 | * work_done_progress 17 | """ 18 | 19 | typedstruct do 20 | field(:work_done_progress, boolean()) 21 | end 22 | 23 | @doc false 24 | @spec schematic() :: SchematicV.t() 25 | def schematic() do 26 | schema(__MODULE__, %{ 27 | optional({"workDoneProgress", :work_done_progress}) => bool() 28 | }) 29 | end 30 | end 31 | -------------------------------------------------------------------------------- /apps/language_server/lib/language_server/lsp/protocol/structures/semantic_tokens_delta_partial_result.ex: -------------------------------------------------------------------------------- 1 | # codegen: do not edit 2 | defmodule GenLSP.Structures.SemanticTokensDeltaPartialResult do 3 | @moduledoc """ 4 | @since 3.16.0 5 | """ 6 | 7 | import SchematicV, warn: false 8 | 9 | use TypedStruct 10 | 11 | @doc """ 12 | ## Fields 13 | 14 | * edits 15 | """ 16 | 17 | typedstruct do 18 | field(:edits, list(GenLSP.Structures.SemanticTokensEdit.t()), enforce: true) 19 | end 20 | 21 | @doc false 22 | @spec schematic() :: SchematicV.t() 23 | def schematic() do 24 | schema(__MODULE__, %{ 25 | {"edits", :edits} => list(GenLSP.Structures.SemanticTokensEdit.schematic()) 26 | }) 27 | end 28 | end 29 | -------------------------------------------------------------------------------- /apps/language_server/lib/language_server/lsp/protocol/structures/work_done_progress_params.ex: -------------------------------------------------------------------------------- 1 | # codegen: do not edit 2 | defmodule GenLSP.Structures.WorkDoneProgressParams do 3 | import SchematicV, warn: false 4 | 5 | use TypedStruct 6 | 7 | @doc """ 8 | ## Fields 9 | 10 | * work_done_token: An optional token that a server can use to report work done progress. 11 | """ 12 | 13 | typedstruct do 14 | field(:work_done_token, GenLSP.TypeAlias.ProgressToken.t()) 15 | end 16 | 17 | @doc false 18 | @spec schematic() :: SchematicV.t() 19 | def schematic() do 20 | schema(__MODULE__, %{ 21 | optional({"workDoneToken", :work_done_token}) => GenLSP.TypeAlias.ProgressToken.schematic() 22 | }) 23 | end 24 | end 25 | -------------------------------------------------------------------------------- /apps/language_server/lib/language_server/lsp/protocol/enumerations/notebook_cell_kind.ex: -------------------------------------------------------------------------------- 1 | # codegen: do not edit 2 | defmodule GenLSP.Enumerations.NotebookCellKind do 3 | @moduledoc """ 4 | A notebook cell kind. 5 | 6 | @since 3.17.0 7 | """ 8 | 9 | @type t :: 1 | 2 10 | 11 | import SchematicV, warn: false 12 | 13 | @doc """ 14 | A markup-cell is formatted source that is used for display. 15 | """ 16 | @spec markup() :: 1 17 | def markup, do: 1 18 | 19 | @doc """ 20 | A code-cell is source code. 21 | """ 22 | @spec code() :: 2 23 | def code, do: 2 24 | 25 | @doc false 26 | @spec schematic() :: SchematicV.t() 27 | def schematic() do 28 | oneof([ 29 | 1, 30 | 2 31 | ]) 32 | end 33 | end 34 | -------------------------------------------------------------------------------- /apps/language_server/lib/language_server/lsp/protocol/structures/call_hierarchy_options.ex: -------------------------------------------------------------------------------- 1 | # codegen: do not edit 2 | defmodule GenLSP.Structures.CallHierarchyOptions do 3 | @moduledoc """ 4 | Call hierarchy options used during static registration. 5 | 6 | @since 3.16.0 7 | """ 8 | 9 | import SchematicV, warn: false 10 | 11 | use TypedStruct 12 | 13 | @doc """ 14 | ## Fields 15 | 16 | * work_done_progress 17 | """ 18 | 19 | typedstruct do 20 | field(:work_done_progress, boolean()) 21 | end 22 | 23 | @doc false 24 | @spec schematic() :: SchematicV.t() 25 | def schematic() do 26 | schema(__MODULE__, %{ 27 | optional({"workDoneProgress", :work_done_progress}) => bool() 28 | }) 29 | end 30 | end 31 | -------------------------------------------------------------------------------- /apps/language_server/lib/language_server/lsp/protocol/structures/document_range_formatting_options.ex: -------------------------------------------------------------------------------- 1 | # codegen: do not edit 2 | defmodule GenLSP.Structures.DocumentRangeFormattingOptions do 3 | @moduledoc """ 4 | Provider options for a {@link DocumentRangeFormattingRequest}. 5 | """ 6 | 7 | import SchematicV, warn: false 8 | 9 | use TypedStruct 10 | 11 | @doc """ 12 | ## Fields 13 | 14 | * work_done_progress 15 | """ 16 | 17 | typedstruct do 18 | field(:work_done_progress, boolean()) 19 | end 20 | 21 | @doc false 22 | @spec schematic() :: SchematicV.t() 23 | def schematic() do 24 | schema(__MODULE__, %{ 25 | optional({"workDoneProgress", :work_done_progress}) => bool() 26 | }) 27 | end 28 | end 29 | -------------------------------------------------------------------------------- /apps/language_server/lib/language_server/lsp/protocol/structures/notebook_document_identifier.ex: -------------------------------------------------------------------------------- 1 | # codegen: do not edit 2 | defmodule GenLSP.Structures.NotebookDocumentIdentifier do 3 | @moduledoc """ 4 | A literal to identify a notebook document in the client. 5 | 6 | @since 3.17.0 7 | """ 8 | 9 | import SchematicV, warn: false 10 | 11 | use TypedStruct 12 | 13 | @doc """ 14 | ## Fields 15 | 16 | * uri: The notebook document's uri. 17 | """ 18 | 19 | typedstruct do 20 | field(:uri, GenLSP.BaseTypes.uri(), enforce: true) 21 | end 22 | 23 | @doc false 24 | @spec schematic() :: SchematicV.t() 25 | def schematic() do 26 | schema(__MODULE__, %{ 27 | {"uri", :uri} => str() 28 | }) 29 | end 30 | end 31 | -------------------------------------------------------------------------------- /apps/language_server/lib/language_server/lsp/protocol/structures/type_hierarchy_options.ex: -------------------------------------------------------------------------------- 1 | # codegen: do not edit 2 | defmodule GenLSP.Structures.TypeHierarchyOptions do 3 | @moduledoc """ 4 | Type hierarchy options used during static registration. 5 | 6 | @since 3.17.0 7 | """ 8 | 9 | import SchematicV, warn: false 10 | 11 | use TypedStruct 12 | 13 | @doc """ 14 | ## Fields 15 | 16 | * work_done_progress 17 | """ 18 | 19 | typedstruct do 20 | field(:work_done_progress, boolean()) 21 | end 22 | 23 | @doc false 24 | @spec schematic() :: SchematicV.t() 25 | def schematic() do 26 | schema(__MODULE__, %{ 27 | optional({"workDoneProgress", :work_done_progress}) => bool() 28 | }) 29 | end 30 | end 31 | -------------------------------------------------------------------------------- /apps/language_server/lib/language_server/lsp/protocol/type_aliases/document_selector.ex: -------------------------------------------------------------------------------- 1 | # codegen: do not edit 2 | defmodule GenLSP.TypeAlias.DocumentSelector do 3 | @moduledoc """ 4 | A document selector is the combination of one or many document filters. 5 | 6 | @sample `let sel:DocumentSelector = [{ language: 'typescript' }, { language: 'json', pattern: '**∕tsconfig.json' }]`; 7 | 8 | The use of a string as a document filter is deprecated @since 3.16.0. 9 | """ 10 | 11 | import SchematicV, warn: false 12 | 13 | @type t :: list(GenLSP.TypeAlias.DocumentFilter.t()) 14 | 15 | @doc false 16 | @spec schematic() :: SchematicV.t() 17 | def schematic() do 18 | list(GenLSP.TypeAlias.DocumentFilter.schematic()) 19 | end 20 | end 21 | -------------------------------------------------------------------------------- /apps/language_server/lib/language_server/lsp/protocol/type_aliases/declaration_link.ex: -------------------------------------------------------------------------------- 1 | # codegen: do not edit 2 | defmodule GenLSP.TypeAlias.DeclarationLink do 3 | @moduledoc """ 4 | Information about where a symbol is declared. 5 | 6 | Provides additional metadata over normal {@link Location location} declarations, including the range of 7 | the declaring symbol. 8 | 9 | Servers should prefer returning `DeclarationLink` over `Declaration` if supported 10 | by the client. 11 | """ 12 | 13 | import SchematicV, warn: false 14 | 15 | @type t :: GenLSP.Structures.LocationLink.t() 16 | 17 | @doc false 18 | @spec schematic() :: SchematicV.t() 19 | def schematic() do 20 | GenLSP.Structures.LocationLink.schematic() 21 | end 22 | end 23 | -------------------------------------------------------------------------------- /apps/language_server/lib/language_server/lsp/protocol/structures/code_description.ex: -------------------------------------------------------------------------------- 1 | # codegen: do not edit 2 | defmodule GenLSP.Structures.CodeDescription do 3 | @moduledoc """ 4 | Structure to capture a description for an error code. 5 | 6 | @since 3.16.0 7 | """ 8 | 9 | import SchematicV, warn: false 10 | 11 | use TypedStruct 12 | 13 | @doc """ 14 | ## Fields 15 | 16 | * href: An URI to open with more information about the diagnostic error. 17 | """ 18 | 19 | typedstruct do 20 | field(:href, GenLSP.BaseTypes.uri(), enforce: true) 21 | end 22 | 23 | @doc false 24 | @spec schematic() :: SchematicV.t() 25 | def schematic() do 26 | schema(__MODULE__, %{ 27 | {"href", :href} => str() 28 | }) 29 | end 30 | end 31 | -------------------------------------------------------------------------------- /apps/language_server/lib/language_server/lsp/protocol/enumerations/watch_kind.ex: -------------------------------------------------------------------------------- 1 | # codegen: do not edit 2 | defmodule GenLSP.Enumerations.WatchKind do 3 | @type t :: 1 | 2 | 4 4 | 5 | import SchematicV, warn: false 6 | 7 | @doc """ 8 | Interested in create events. 9 | """ 10 | @spec create() :: 1 11 | def create, do: 1 12 | 13 | @doc """ 14 | Interested in change events 15 | """ 16 | @spec change() :: 2 17 | def change, do: 2 18 | 19 | @doc """ 20 | Interested in delete events 21 | """ 22 | @spec delete() :: 4 23 | def delete, do: 4 24 | 25 | @doc false 26 | @spec schematic() :: SchematicV.t() 27 | def schematic() do 28 | oneof([ 29 | 1, 30 | 2, 31 | 4, 32 | int() 33 | ]) 34 | end 35 | end 36 | -------------------------------------------------------------------------------- /apps/language_server/test/fixtures/dialyzer/lib/suggest.ex: -------------------------------------------------------------------------------- 1 | defmodule Suggest do 2 | def no_arg, do: :ok 3 | 4 | def one_arg(arg = %{foo: 1}), do: {:ok, arg} 5 | 6 | def multiple_arities(arg1) do 7 | {:ok, arg1 * 1} 8 | end 9 | 10 | def multiple_arities(arg1, arg2) do 11 | {:ok, arg1 * 1, arg2 * 1} 12 | end 13 | 14 | def default_arg_functions(arg1 \\ 1, arg2 \\ 2) do 15 | {:ok, arg1 * 1, arg2 * 1} 16 | end 17 | 18 | defguard foo(arg) when is_integer(arg) and arg > 0 19 | 20 | defmacro macro(ast) do 21 | ast 22 | end 23 | 24 | def multiple_clauses(arg1) when is_integer(arg1) do 25 | {:ok, arg1 * 1} 26 | end 27 | 28 | def multiple_clauses(arg1) when is_float(arg1) do 29 | {:ok, arg1 * 1.0} 30 | end 31 | end 32 | -------------------------------------------------------------------------------- /apps/language_server/lib/language_server/lsp/protocol/structures/configuration_item.ex: -------------------------------------------------------------------------------- 1 | # codegen: do not edit 2 | defmodule GenLSP.Structures.ConfigurationItem do 3 | import SchematicV, warn: false 4 | 5 | use TypedStruct 6 | 7 | @doc """ 8 | ## Fields 9 | 10 | * scope_uri: The scope to get the configuration section for. 11 | * section: The configuration section asked for. 12 | """ 13 | 14 | typedstruct do 15 | field(:scope_uri, String.t()) 16 | field(:section, String.t()) 17 | end 18 | 19 | @doc false 20 | @spec schematic() :: SchematicV.t() 21 | def schematic() do 22 | schema(__MODULE__, %{ 23 | optional({"scopeUri", :scope_uri}) => str(), 24 | optional({"section", :section}) => str() 25 | }) 26 | end 27 | end 28 | -------------------------------------------------------------------------------- /apps/language_server/lib/language_server/lsp/protocol/structures/diagnostic_server_cancellation_data.ex: -------------------------------------------------------------------------------- 1 | # codegen: do not edit 2 | defmodule GenLSP.Structures.DiagnosticServerCancellationData do 3 | @moduledoc """ 4 | Cancellation data returned from a diagnostic request. 5 | 6 | @since 3.17.0 7 | """ 8 | 9 | import SchematicV, warn: false 10 | 11 | use TypedStruct 12 | 13 | @doc """ 14 | ## Fields 15 | 16 | * retrigger_request 17 | """ 18 | 19 | typedstruct do 20 | field(:retrigger_request, boolean(), enforce: true) 21 | end 22 | 23 | @doc false 24 | @spec schematic() :: SchematicV.t() 25 | def schematic() do 26 | schema(__MODULE__, %{ 27 | {"retriggerRequest", :retrigger_request} => bool() 28 | }) 29 | end 30 | end 31 | -------------------------------------------------------------------------------- /apps/language_server/lib/language_server/lsp/protocol/structures/execute_command_registration_options.ex: -------------------------------------------------------------------------------- 1 | # codegen: do not edit 2 | defmodule GenLSP.Structures.ExecuteCommandRegistrationOptions do 3 | @moduledoc """ 4 | Registration options for a {@link ExecuteCommandRequest}. 5 | """ 6 | 7 | import SchematicV, warn: false 8 | 9 | use TypedStruct 10 | 11 | @doc """ 12 | ## Fields 13 | 14 | * commands: The commands to be executed on the server 15 | """ 16 | 17 | typedstruct do 18 | field(:commands, list(String.t()), enforce: true) 19 | end 20 | 21 | @doc false 22 | @spec schematic() :: SchematicV.t() 23 | def schematic() do 24 | schema(__MODULE__, %{ 25 | {"commands", :commands} => list(str()) 26 | }) 27 | end 28 | end 29 | -------------------------------------------------------------------------------- /apps/language_server/lib/language_server/lsp/protocol/structures/did_change_configuration_params.ex: -------------------------------------------------------------------------------- 1 | # codegen: do not edit 2 | defmodule GenLSP.Structures.DidChangeConfigurationParams do 3 | @moduledoc """ 4 | The parameters of a change configuration notification. 5 | """ 6 | 7 | import SchematicV, warn: false 8 | 9 | use TypedStruct 10 | 11 | @doc """ 12 | ## Fields 13 | 14 | * settings: The actual changed settings 15 | """ 16 | 17 | typedstruct do 18 | field(:settings, GenLSP.TypeAlias.LSPAny.t(), enforce: true) 19 | end 20 | 21 | @doc false 22 | @spec schematic() :: SchematicV.t() 23 | def schematic() do 24 | schema(__MODULE__, %{ 25 | {"settings", :settings} => GenLSP.TypeAlias.LSPAny.schematic() 26 | }) 27 | end 28 | end 29 | -------------------------------------------------------------------------------- /apps/language_server/lib/language_server/lsp/protocol/structures/file_operation_pattern_options.ex: -------------------------------------------------------------------------------- 1 | # codegen: do not edit 2 | defmodule GenLSP.Structures.FileOperationPatternOptions do 3 | @moduledoc """ 4 | Matching options for the file operation pattern. 5 | 6 | @since 3.16.0 7 | """ 8 | 9 | import SchematicV, warn: false 10 | 11 | use TypedStruct 12 | 13 | @doc """ 14 | ## Fields 15 | 16 | * ignore_case: The pattern should be matched ignoring casing. 17 | """ 18 | 19 | typedstruct do 20 | field(:ignore_case, boolean()) 21 | end 22 | 23 | @doc false 24 | @spec schematic() :: SchematicV.t() 25 | def schematic() do 26 | schema(__MODULE__, %{ 27 | optional({"ignoreCase", :ignore_case}) => bool() 28 | }) 29 | end 30 | end 31 | -------------------------------------------------------------------------------- /apps/language_server/lib/language_server/lsp/protocol/structures/work_done_progress_end.ex: -------------------------------------------------------------------------------- 1 | # codegen: do not edit 2 | defmodule GenLSP.Structures.WorkDoneProgressEnd do 3 | import SchematicV, warn: false 4 | 5 | use TypedStruct 6 | 7 | @doc """ 8 | ## Fields 9 | 10 | * kind 11 | * message: Optional, a final message indicating to for example indicate the outcome 12 | of the operation. 13 | """ 14 | 15 | typedstruct do 16 | field(:kind, String.t(), enforce: true) 17 | field(:message, String.t()) 18 | end 19 | 20 | @doc false 21 | @spec schematic() :: SchematicV.t() 22 | def schematic() do 23 | schema(__MODULE__, %{ 24 | {"kind", :kind} => "end", 25 | optional({"message", :message}) => str() 26 | }) 27 | end 28 | end 29 | -------------------------------------------------------------------------------- /apps/language_server/test/support/fixtures/references_referenced.ex: -------------------------------------------------------------------------------- 1 | defmodule ElixirLS.Test.ReferencesReferenced do 2 | def referenced_fun do 3 | referenced_variable = 42 4 | 5 | IO.puts(referenced_variable + 1) 6 | :ok 7 | end 8 | 9 | defmacro referenced_macro(clause, do: expression) do 10 | quote do 11 | if(!unquote(clause), do: unquote(expression)) 12 | end 13 | end 14 | 15 | def uses_fun(_a) do 16 | referenced_fun() 17 | end 18 | 19 | def uses_macro(a) do 20 | referenced_macro a do 21 | :ok 22 | end 23 | end 24 | 25 | @referenced_attribute "123" 26 | 27 | def uses_attribute do 28 | @referenced_attribute 29 | end 30 | 31 | def uses_erlang_fun() do 32 | :ets.new(:abc, []) 33 | end 34 | end 35 | -------------------------------------------------------------------------------- /docs/getting-started/overview.md: -------------------------------------------------------------------------------- 1 | # Getting Started 2 | 3 | The Erlang LS language server works with all text editors and IDEs 4 | which adhere to the _LSP_ protocol. The list of supported editors 5 | include _Emacs_, _Vim_, _VS Code_, _Sublime Text 3_ and more. 6 | 7 | These pages contain all the information needed to configure your 8 | favourite text editor or IDE to use ErlangLS. You will also find 9 | instructions on how to configure the server to recognize the structure 10 | of your projects and to troubleshoot your installation when things do 11 | not work as expected. 12 | 13 | * [Emacs](emacs.md) 14 | * [Kakoune](kakoune.md) 15 | * [Kate](kate.md) 16 | * [Neovim](neovim.md) 17 | * [Nova](nova.md) 18 | * [Sublime Text 3](sublime.md) 19 | * [VS Code](vscode.md) 20 | 21 | -------------------------------------------------------------------------------- /apps/debug_adapter/lib/protocol/dap/structures/locations_arguments.ex: -------------------------------------------------------------------------------- 1 | # codegen: do not edit 2 | 3 | defmodule GenDAP.Structures.LocationsArguments do 4 | @moduledoc """ 5 | Arguments for `locations` request. 6 | """ 7 | 8 | import SchematicV, warn: false 9 | 10 | use TypedStruct 11 | 12 | @doc """ 13 | ## Fields 14 | 15 | * location_reference: Location reference to resolve. 16 | """ 17 | 18 | typedstruct do 19 | @typedoc "A type defining DAP structure LocationsArguments" 20 | field(:location_reference, integer(), enforce: true) 21 | end 22 | 23 | @doc false 24 | @spec schematic() :: SchematicV.t() 25 | def schematic() do 26 | schema(__MODULE__, %{ 27 | {"locationReference", :location_reference} => int() 28 | }) 29 | end 30 | end 31 | -------------------------------------------------------------------------------- /apps/language_server/lib/language_server/lsp/protocol/structures/did_change_watched_files_params.ex: -------------------------------------------------------------------------------- 1 | # codegen: do not edit 2 | defmodule GenLSP.Structures.DidChangeWatchedFilesParams do 3 | @moduledoc """ 4 | The watched files change notification's parameters. 5 | """ 6 | 7 | import SchematicV, warn: false 8 | 9 | use TypedStruct 10 | 11 | @doc """ 12 | ## Fields 13 | 14 | * changes: The actual file events. 15 | """ 16 | 17 | typedstruct do 18 | field(:changes, list(GenLSP.Structures.FileEvent.t()), enforce: true) 19 | end 20 | 21 | @doc false 22 | @spec schematic() :: SchematicV.t() 23 | def schematic() do 24 | schema(__MODULE__, %{ 25 | {"changes", :changes} => list(GenLSP.Structures.FileEvent.schematic()) 26 | }) 27 | end 28 | end 29 | -------------------------------------------------------------------------------- /apps/language_server/lib/language_server/lsp/protocol/structures/show_document_client_capabilities.ex: -------------------------------------------------------------------------------- 1 | # codegen: do not edit 2 | defmodule GenLSP.Structures.ShowDocumentClientCapabilities do 3 | @moduledoc """ 4 | Client capabilities for the showDocument request. 5 | 6 | @since 3.16.0 7 | """ 8 | 9 | import SchematicV, warn: false 10 | 11 | use TypedStruct 12 | 13 | @doc """ 14 | ## Fields 15 | 16 | * support: The client has support for the showDocument 17 | request. 18 | """ 19 | 20 | typedstruct do 21 | field(:support, boolean(), enforce: true) 22 | end 23 | 24 | @doc false 25 | @spec schematic() :: SchematicV.t() 26 | def schematic() do 27 | schema(__MODULE__, %{ 28 | {"support", :support} => bool() 29 | }) 30 | end 31 | end 32 | -------------------------------------------------------------------------------- /apps/debug_adapter/lib/protocol/dap/structures/terminate_threads_arguments.ex: -------------------------------------------------------------------------------- 1 | # codegen: do not edit 2 | 3 | defmodule GenDAP.Structures.TerminateThreadsArguments do 4 | @moduledoc """ 5 | Arguments for `terminateThreads` request. 6 | """ 7 | 8 | import SchematicV, warn: false 9 | 10 | use TypedStruct 11 | 12 | @doc """ 13 | ## Fields 14 | 15 | * thread_ids: Ids of threads to be terminated. 16 | """ 17 | 18 | typedstruct do 19 | @typedoc "A type defining DAP structure TerminateThreadsArguments" 20 | field(:thread_ids, list(integer())) 21 | end 22 | 23 | @doc false 24 | @spec schematic() :: SchematicV.t() 25 | def schematic() do 26 | schema(__MODULE__, %{ 27 | optional({"threadIds", :thread_ids}) => list(int()) 28 | }) 29 | end 30 | end 31 | -------------------------------------------------------------------------------- /apps/debug_adapter/lib/protocol/dap/structures/thread.ex: -------------------------------------------------------------------------------- 1 | # codegen: do not edit 2 | 3 | defmodule GenDAP.Structures.Thread do 4 | @moduledoc """ 5 | A Thread 6 | """ 7 | 8 | import SchematicV, warn: false 9 | 10 | use TypedStruct 11 | 12 | @doc """ 13 | ## Fields 14 | 15 | * id: Unique identifier for the thread. 16 | * name: The name of the thread. 17 | """ 18 | 19 | typedstruct do 20 | @typedoc "A type defining DAP structure Thread" 21 | field(:id, integer(), enforce: true) 22 | field(:name, String.t(), enforce: true) 23 | end 24 | 25 | @doc false 26 | @spec schematic() :: SchematicV.t() 27 | def schematic() do 28 | schema(__MODULE__, %{ 29 | {"id", :id} => int(), 30 | {"name", :name} => str() 31 | }) 32 | end 33 | end 34 | -------------------------------------------------------------------------------- /apps/language_server/lib/language_server/lsp/protocol/notifications/exit.ex: -------------------------------------------------------------------------------- 1 | # codegen: do not edit 2 | defmodule GenLSP.Notifications.Exit do 3 | @moduledoc """ 4 | The exit event is sent from the client to the server to 5 | ask the server to exit its process. 6 | 7 | Message Direction: clientToServer 8 | """ 9 | 10 | import SchematicV, warn: false 11 | 12 | use TypedStruct 13 | 14 | typedstruct do 15 | field(:method, String.t(), default: "exit") 16 | field(:jsonrpc, String.t(), default: "2.0") 17 | field(:params, nil) 18 | end 19 | 20 | @doc false 21 | @spec schematic() :: SchematicV.t() 22 | def schematic() do 23 | schema(__MODULE__, %{ 24 | method: "exit", 25 | jsonrpc: "2.0", 26 | params: nil 27 | }) 28 | end 29 | end 30 | -------------------------------------------------------------------------------- /apps/language_server/lib/language_server/lsp/protocol/structures/code_lens_client_capabilities.ex: -------------------------------------------------------------------------------- 1 | # codegen: do not edit 2 | defmodule GenLSP.Structures.CodeLensClientCapabilities do 3 | @moduledoc """ 4 | The client capabilities of a {@link CodeLensRequest}. 5 | """ 6 | 7 | import SchematicV, warn: false 8 | 9 | use TypedStruct 10 | 11 | @doc """ 12 | ## Fields 13 | 14 | * dynamic_registration: Whether code lens supports dynamic registration. 15 | """ 16 | 17 | typedstruct do 18 | field(:dynamic_registration, boolean()) 19 | end 20 | 21 | @doc false 22 | @spec schematic() :: SchematicV.t() 23 | def schematic() do 24 | schema(__MODULE__, %{ 25 | optional({"dynamicRegistration", :dynamic_registration}) => bool() 26 | }) 27 | end 28 | end 29 | -------------------------------------------------------------------------------- /apps/language_server/lib/language_server/lsp/protocol/structures/reference_client_capabilities.ex: -------------------------------------------------------------------------------- 1 | # codegen: do not edit 2 | defmodule GenLSP.Structures.ReferenceClientCapabilities do 3 | @moduledoc """ 4 | Client Capabilities for a {@link ReferencesRequest}. 5 | """ 6 | 7 | import SchematicV, warn: false 8 | 9 | use TypedStruct 10 | 11 | @doc """ 12 | ## Fields 13 | 14 | * dynamic_registration: Whether references supports dynamic registration. 15 | """ 16 | 17 | typedstruct do 18 | field(:dynamic_registration, boolean()) 19 | end 20 | 21 | @doc false 22 | @spec schematic() :: SchematicV.t() 23 | def schematic() do 24 | schema(__MODULE__, %{ 25 | optional({"dynamicRegistration", :dynamic_registration}) => bool() 26 | }) 27 | end 28 | end 29 | -------------------------------------------------------------------------------- /apps/language_server/lib/language_server/providers/execute_command/mix_clean.ex: -------------------------------------------------------------------------------- 1 | defmodule ElixirLS.LanguageServer.Providers.ExecuteCommand.MixClean do 2 | @behaviour ElixirLS.LanguageServer.Providers.ExecuteCommand 3 | 4 | @impl ElixirLS.LanguageServer.Providers.ExecuteCommand 5 | def execute(_, %{project_dir: nil}) do 6 | {:error, :invalid_request, "No mix project", false} 7 | end 8 | 9 | def execute([clean_deps?], %{project_dir: project_dir}) do 10 | case ElixirLS.LanguageServer.Build.clean(project_dir, clean_deps?) do 11 | :ok -> {:ok, %{}} 12 | :no_mixfile -> {:error, :invalid_request, "No mix.exs in project dir", false} 13 | {:error, reason} -> {:error, :request_failed, "Mix clean failed: #{inspect(reason)}", true} 14 | end 15 | end 16 | end 17 | -------------------------------------------------------------------------------- /apps/debug_adapter/lib/protocol/dap/structures/exception_info_arguments.ex: -------------------------------------------------------------------------------- 1 | # codegen: do not edit 2 | 3 | defmodule GenDAP.Structures.ExceptionInfoArguments do 4 | @moduledoc """ 5 | Arguments for `exceptionInfo` request. 6 | """ 7 | 8 | import SchematicV, warn: false 9 | 10 | use TypedStruct 11 | 12 | @doc """ 13 | ## Fields 14 | 15 | * thread_id: Thread for which exception information should be retrieved. 16 | """ 17 | 18 | typedstruct do 19 | @typedoc "A type defining DAP structure ExceptionInfoArguments" 20 | field(:thread_id, integer(), enforce: true) 21 | end 22 | 23 | @doc false 24 | @spec schematic() :: SchematicV.t() 25 | def schematic() do 26 | schema(__MODULE__, %{ 27 | {"threadId", :thread_id} => int() 28 | }) 29 | end 30 | end 31 | -------------------------------------------------------------------------------- /apps/debug_adapter/lib/protocol/dap/structures/terminate_arguments.ex: -------------------------------------------------------------------------------- 1 | # codegen: do not edit 2 | 3 | defmodule GenDAP.Structures.TerminateArguments do 4 | @moduledoc """ 5 | Arguments for `terminate` request. 6 | """ 7 | 8 | import SchematicV, warn: false 9 | 10 | use TypedStruct 11 | 12 | @doc """ 13 | ## Fields 14 | 15 | * restart: A value of true indicates that this `terminate` request is part of a restart sequence. 16 | """ 17 | 18 | typedstruct do 19 | @typedoc "A type defining DAP structure TerminateArguments" 20 | field(:restart, boolean()) 21 | end 22 | 23 | @doc false 24 | @spec schematic() :: SchematicV.t() 25 | def schematic() do 26 | schema(__MODULE__, %{ 27 | optional({"restart", :restart}) => bool() 28 | }) 29 | end 30 | end 31 | -------------------------------------------------------------------------------- /apps/language_server/lib/language_server/lsp/protocol/notifications/notebook_document_did_change.ex: -------------------------------------------------------------------------------- 1 | # codegen: do not edit 2 | defmodule GenLSP.Notifications.NotebookDocumentDidChange do 3 | import SchematicV, warn: false 4 | 5 | use TypedStruct 6 | 7 | typedstruct do 8 | field(:method, String.t(), default: "notebookDocument/didChange") 9 | field(:jsonrpc, String.t(), default: "2.0") 10 | field(:params, GenLSP.Structures.DidChangeNotebookDocumentParams.t()) 11 | end 12 | 13 | @doc false 14 | @spec schematic() :: SchematicV.t() 15 | def schematic() do 16 | schema(__MODULE__, %{ 17 | method: "notebookDocument/didChange", 18 | jsonrpc: "2.0", 19 | params: GenLSP.Structures.DidChangeNotebookDocumentParams.schematic() 20 | }) 21 | end 22 | end 23 | -------------------------------------------------------------------------------- /apps/language_server/lib/language_server/lsp/protocol/structures/reference_context.ex: -------------------------------------------------------------------------------- 1 | # codegen: do not edit 2 | defmodule GenLSP.Structures.ReferenceContext do 3 | @moduledoc """ 4 | Value-object that contains additional information when 5 | requesting references. 6 | """ 7 | 8 | import SchematicV, warn: false 9 | 10 | use TypedStruct 11 | 12 | @doc """ 13 | ## Fields 14 | 15 | * include_declaration: Include the declaration of the current symbol. 16 | """ 17 | 18 | typedstruct do 19 | field(:include_declaration, boolean(), enforce: true) 20 | end 21 | 22 | @doc false 23 | @spec schematic() :: SchematicV.t() 24 | def schematic() do 25 | schema(__MODULE__, %{ 26 | {"includeDeclaration", :include_declaration} => bool() 27 | }) 28 | end 29 | end 30 | -------------------------------------------------------------------------------- /apps/debug_adapter/lib/protocol/dap/structures/step_in_targets_arguments.ex: -------------------------------------------------------------------------------- 1 | # codegen: do not edit 2 | 3 | defmodule GenDAP.Structures.StepInTargetsArguments do 4 | @moduledoc """ 5 | Arguments for `stepInTargets` request. 6 | """ 7 | 8 | import SchematicV, warn: false 9 | 10 | use TypedStruct 11 | 12 | @doc """ 13 | ## Fields 14 | 15 | * frame_id: The stack frame for which to retrieve the possible step-in targets. 16 | """ 17 | 18 | typedstruct do 19 | @typedoc "A type defining DAP structure StepInTargetsArguments" 20 | field(:frame_id, integer(), enforce: true) 21 | end 22 | 23 | @doc false 24 | @spec schematic() :: SchematicV.t() 25 | def schematic() do 26 | schema(__MODULE__, %{ 27 | {"frameId", :frame_id} => int() 28 | }) 29 | end 30 | end 31 | -------------------------------------------------------------------------------- /apps/language_server/lib/language_server/lsp/protocol/enumerations/trace_values.ex: -------------------------------------------------------------------------------- 1 | # codegen: do not edit 2 | defmodule GenLSP.Enumerations.TraceValues do 3 | @type t :: String.t() 4 | 5 | import SchematicV, warn: false 6 | 7 | @doc """ 8 | Turn tracing off. 9 | """ 10 | @spec off() :: String.t() 11 | def off, do: "off" 12 | 13 | @doc """ 14 | Trace messages only. 15 | """ 16 | @spec messages() :: String.t() 17 | def messages, do: "messages" 18 | 19 | @doc """ 20 | Verbose message tracing. 21 | """ 22 | @spec verbose() :: String.t() 23 | def verbose, do: "verbose" 24 | 25 | @doc false 26 | @spec schematic() :: SchematicV.t() 27 | def schematic() do 28 | oneof([ 29 | "off", 30 | "messages", 31 | "verbose" 32 | ]) 33 | end 34 | end 35 | -------------------------------------------------------------------------------- /apps/language_server/lib/language_server/lsp/protocol/structures/workspace_diagnostic_report.ex: -------------------------------------------------------------------------------- 1 | # codegen: do not edit 2 | defmodule GenLSP.Structures.WorkspaceDiagnosticReport do 3 | @moduledoc """ 4 | A workspace diagnostic report. 5 | 6 | @since 3.17.0 7 | """ 8 | 9 | import SchematicV, warn: false 10 | 11 | use TypedStruct 12 | 13 | @doc """ 14 | ## Fields 15 | 16 | * items 17 | """ 18 | 19 | typedstruct do 20 | field(:items, list(GenLSP.TypeAlias.WorkspaceDocumentDiagnosticReport.t()), enforce: true) 21 | end 22 | 23 | @doc false 24 | @spec schematic() :: SchematicV.t() 25 | def schematic() do 26 | schema(__MODULE__, %{ 27 | {"items", :items} => list(GenLSP.TypeAlias.WorkspaceDocumentDiagnosticReport.schematic()) 28 | }) 29 | end 30 | end 31 | -------------------------------------------------------------------------------- /apps/language_server/lib/language_server/lsp/protocol/structures/execute_command_client_capabilities.ex: -------------------------------------------------------------------------------- 1 | # codegen: do not edit 2 | defmodule GenLSP.Structures.ExecuteCommandClientCapabilities do 3 | @moduledoc """ 4 | The client capabilities of a {@link ExecuteCommandRequest}. 5 | """ 6 | 7 | import SchematicV, warn: false 8 | 9 | use TypedStruct 10 | 11 | @doc """ 12 | ## Fields 13 | 14 | * dynamic_registration: Execute command supports dynamic registration. 15 | """ 16 | 17 | typedstruct do 18 | field(:dynamic_registration, boolean()) 19 | end 20 | 21 | @doc false 22 | @spec schematic() :: SchematicV.t() 23 | def schematic() do 24 | schema(__MODULE__, %{ 25 | optional({"dynamicRegistration", :dynamic_registration}) => bool() 26 | }) 27 | end 28 | end 29 | -------------------------------------------------------------------------------- /apps/language_server/lib/language_server/lsp/protocol/structures/partial_result_params.ex: -------------------------------------------------------------------------------- 1 | # codegen: do not edit 2 | defmodule GenLSP.Structures.PartialResultParams do 3 | import SchematicV, warn: false 4 | 5 | use TypedStruct 6 | 7 | @doc """ 8 | ## Fields 9 | 10 | * partial_result_token: An optional token that a server can use to report partial results (e.g. streaming) to 11 | the client. 12 | """ 13 | 14 | typedstruct do 15 | field(:partial_result_token, GenLSP.TypeAlias.ProgressToken.t()) 16 | end 17 | 18 | @doc false 19 | @spec schematic() :: SchematicV.t() 20 | def schematic() do 21 | schema(__MODULE__, %{ 22 | optional({"partialResultToken", :partial_result_token}) => 23 | GenLSP.TypeAlias.ProgressToken.schematic() 24 | }) 25 | end 26 | end 27 | -------------------------------------------------------------------------------- /apps/language_server/test/support/module_with_functions.ex: -------------------------------------------------------------------------------- 1 | defmodule ElixirSenseExample.ModuleWithFunctions do 2 | def function_arity_zero do 3 | :return_value 4 | end 5 | 6 | def function_arity_one(_) do 7 | nil 8 | end 9 | 10 | defdelegate delegated_function, to: ElixirSenseExample.ModuleWithFunctions.DelegatedModule 11 | defdelegate delegated_function(a), to: ElixirSenseExample.ModuleWithFunctions.DelegatedModule 12 | defdelegate delegated_function(a, b), to: ElixirSenseExample.ModuleWithFunctions.DelegatedModule 13 | 14 | defmodule DelegatedModule do 15 | def delegated_function do 16 | nil 17 | end 18 | 19 | def delegated_function(a) do 20 | a 21 | end 22 | 23 | def delegated_function(a, b) do 24 | {a, b} 25 | end 26 | end 27 | end 28 | -------------------------------------------------------------------------------- /apps/language_server/lib/language_server/lsp/protocol/enumerations/file_change_type.ex: -------------------------------------------------------------------------------- 1 | # codegen: do not edit 2 | defmodule GenLSP.Enumerations.FileChangeType do 3 | @moduledoc """ 4 | The file event type 5 | """ 6 | 7 | @type t :: 1 | 2 | 3 8 | 9 | import SchematicV, warn: false 10 | 11 | @doc """ 12 | The file got created. 13 | """ 14 | @spec created() :: 1 15 | def created, do: 1 16 | 17 | @doc """ 18 | The file got changed. 19 | """ 20 | @spec changed() :: 2 21 | def changed, do: 2 22 | 23 | @doc """ 24 | The file got deleted. 25 | """ 26 | @spec deleted() :: 3 27 | def deleted, do: 3 28 | 29 | @doc false 30 | @spec schematic() :: SchematicV.t() 31 | def schematic() do 32 | oneof([ 33 | 1, 34 | 2, 35 | 3 36 | ]) 37 | end 38 | end 39 | -------------------------------------------------------------------------------- /apps/language_server/lib/language_server/lsp/protocol/structures/static_registration_options.ex: -------------------------------------------------------------------------------- 1 | # codegen: do not edit 2 | defmodule GenLSP.Structures.StaticRegistrationOptions do 3 | @moduledoc """ 4 | Static registration options to be returned in the initialize 5 | request. 6 | """ 7 | 8 | import SchematicV, warn: false 9 | 10 | use TypedStruct 11 | 12 | @doc """ 13 | ## Fields 14 | 15 | * id: The id used to register the request. The id can be used to deregister 16 | the request again. See also Registration#id. 17 | """ 18 | 19 | typedstruct do 20 | field(:id, String.t()) 21 | end 22 | 23 | @doc false 24 | @spec schematic() :: SchematicV.t() 25 | def schematic() do 26 | schema(__MODULE__, %{ 27 | optional({"id", :id}) => str() 28 | }) 29 | end 30 | end 31 | -------------------------------------------------------------------------------- /apps/language_server/lib/language_server/lsp/protocol/structures/document_formatting_client_capabilities.ex: -------------------------------------------------------------------------------- 1 | # codegen: do not edit 2 | defmodule GenLSP.Structures.DocumentFormattingClientCapabilities do 3 | @moduledoc """ 4 | Client capabilities of a {@link DocumentFormattingRequest}. 5 | """ 6 | 7 | import SchematicV, warn: false 8 | 9 | use TypedStruct 10 | 11 | @doc """ 12 | ## Fields 13 | 14 | * dynamic_registration: Whether formatting supports dynamic registration. 15 | """ 16 | 17 | typedstruct do 18 | field(:dynamic_registration, boolean()) 19 | end 20 | 21 | @doc false 22 | @spec schematic() :: SchematicV.t() 23 | def schematic() do 24 | schema(__MODULE__, %{ 25 | optional({"dynamicRegistration", :dynamic_registration}) => bool() 26 | }) 27 | end 28 | end 29 | -------------------------------------------------------------------------------- /apps/language_server/lib/language_server/lsp/protocol/type_aliases/document_filter.ex: -------------------------------------------------------------------------------- 1 | # codegen: do not edit 2 | defmodule GenLSP.TypeAlias.DocumentFilter do 3 | @moduledoc """ 4 | A document filter describes a top level text document or 5 | a notebook cell document. 6 | 7 | @since 3.17.0 - proposed support for NotebookCellTextDocumentFilter. 8 | """ 9 | 10 | import SchematicV, warn: false 11 | 12 | @type t :: 13 | GenLSP.TypeAlias.TextDocumentFilter.t() 14 | | GenLSP.Structures.NotebookCellTextDocumentFilter.t() 15 | 16 | @doc false 17 | @spec schematic() :: SchematicV.t() 18 | def schematic() do 19 | oneof([ 20 | GenLSP.TypeAlias.TextDocumentFilter.schematic(), 21 | GenLSP.Structures.NotebookCellTextDocumentFilter.schematic() 22 | ]) 23 | end 24 | end 25 | -------------------------------------------------------------------------------- /apps/language_server/lib/language_server/lsp/protocol/type_aliases/workspace_document_diagnostic_report.ex: -------------------------------------------------------------------------------- 1 | # codegen: do not edit 2 | defmodule GenLSP.TypeAlias.WorkspaceDocumentDiagnosticReport do 3 | @moduledoc """ 4 | A workspace diagnostic document report. 5 | 6 | @since 3.17.0 7 | """ 8 | 9 | import SchematicV, warn: false 10 | 11 | @type t :: 12 | GenLSP.Structures.WorkspaceFullDocumentDiagnosticReport.t() 13 | | GenLSP.Structures.WorkspaceUnchangedDocumentDiagnosticReport.t() 14 | 15 | @doc false 16 | @spec schematic() :: SchematicV.t() 17 | def schematic() do 18 | oneof([ 19 | GenLSP.Structures.WorkspaceFullDocumentDiagnosticReport.schematic(), 20 | GenLSP.Structures.WorkspaceUnchangedDocumentDiagnosticReport.schematic() 21 | ]) 22 | end 23 | end 24 | -------------------------------------------------------------------------------- /apps/language_server/lib/language_server/lsp/protocol/structures/did_open_text_document_params.ex: -------------------------------------------------------------------------------- 1 | # codegen: do not edit 2 | defmodule GenLSP.Structures.DidOpenTextDocumentParams do 3 | @moduledoc """ 4 | The parameters sent in an open text document notification 5 | """ 6 | 7 | import SchematicV, warn: false 8 | 9 | use TypedStruct 10 | 11 | @doc """ 12 | ## Fields 13 | 14 | * text_document: The document that was opened. 15 | """ 16 | 17 | typedstruct do 18 | field(:text_document, GenLSP.Structures.TextDocumentItem.t(), enforce: true) 19 | end 20 | 21 | @doc false 22 | @spec schematic() :: SchematicV.t() 23 | def schematic() do 24 | schema(__MODULE__, %{ 25 | {"textDocument", :text_document} => GenLSP.Structures.TextDocumentItem.schematic() 26 | }) 27 | end 28 | end 29 | -------------------------------------------------------------------------------- /apps/language_server/lib/language_server/lsp/protocol/structures/document_highlight_client_capabilities.ex: -------------------------------------------------------------------------------- 1 | # codegen: do not edit 2 | defmodule GenLSP.Structures.DocumentHighlightClientCapabilities do 3 | @moduledoc """ 4 | Client Capabilities for a {@link DocumentHighlightRequest}. 5 | """ 6 | 7 | import SchematicV, warn: false 8 | 9 | use TypedStruct 10 | 11 | @doc """ 12 | ## Fields 13 | 14 | * dynamic_registration: Whether document highlight supports dynamic registration. 15 | """ 16 | 17 | typedstruct do 18 | field(:dynamic_registration, boolean()) 19 | end 20 | 21 | @doc false 22 | @spec schematic() :: SchematicV.t() 23 | def schematic() do 24 | schema(__MODULE__, %{ 25 | optional({"dynamicRegistration", :dynamic_registration}) => bool() 26 | }) 27 | end 28 | end 29 | -------------------------------------------------------------------------------- /apps/language_server/lib/language_server/lsp/protocol/type_aliases/definition.ex: -------------------------------------------------------------------------------- 1 | # codegen: do not edit 2 | defmodule GenLSP.TypeAlias.Definition do 3 | @moduledoc """ 4 | The definition of a symbol represented as one or many {@link Location locations}. 5 | For most programming languages there is only one location at which a symbol is 6 | defined. 7 | 8 | Servers should prefer returning `DefinitionLink` over `Definition` if supported 9 | by the client. 10 | """ 11 | 12 | import SchematicV, warn: false 13 | 14 | @type t :: GenLSP.Structures.Location.t() | list(GenLSP.Structures.Location.t()) 15 | 16 | @doc false 17 | @spec schematic() :: SchematicV.t() 18 | def schematic() do 19 | oneof([GenLSP.Structures.Location.schematic(), list(GenLSP.Structures.Location.schematic())]) 20 | end 21 | end 22 | -------------------------------------------------------------------------------- /apps/language_server/lib/language_server/lsp/protocol/structures/did_close_text_document_params.ex: -------------------------------------------------------------------------------- 1 | # codegen: do not edit 2 | defmodule GenLSP.Structures.DidCloseTextDocumentParams do 3 | @moduledoc """ 4 | The parameters sent in a close text document notification 5 | """ 6 | 7 | import SchematicV, warn: false 8 | 9 | use TypedStruct 10 | 11 | @doc """ 12 | ## Fields 13 | 14 | * text_document: The document that was closed. 15 | """ 16 | 17 | typedstruct do 18 | field(:text_document, GenLSP.Structures.TextDocumentIdentifier.t(), enforce: true) 19 | end 20 | 21 | @doc false 22 | @spec schematic() :: SchematicV.t() 23 | def schematic() do 24 | schema(__MODULE__, %{ 25 | {"textDocument", :text_document} => GenLSP.Structures.TextDocumentIdentifier.schematic() 26 | }) 27 | end 28 | end 29 | -------------------------------------------------------------------------------- /apps/language_server/lib/language_server/lsp/protocol/structures/file_operation_registration_options.ex: -------------------------------------------------------------------------------- 1 | # codegen: do not edit 2 | defmodule GenLSP.Structures.FileOperationRegistrationOptions do 3 | @moduledoc """ 4 | The options to register for file operations. 5 | 6 | @since 3.16.0 7 | """ 8 | 9 | import SchematicV, warn: false 10 | 11 | use TypedStruct 12 | 13 | @doc """ 14 | ## Fields 15 | 16 | * filters: The actual filters. 17 | """ 18 | 19 | typedstruct do 20 | field(:filters, list(GenLSP.Structures.FileOperationFilter.t()), enforce: true) 21 | end 22 | 23 | @doc false 24 | @spec schematic() :: SchematicV.t() 25 | def schematic() do 26 | schema(__MODULE__, %{ 27 | {"filters", :filters} => list(GenLSP.Structures.FileOperationFilter.schematic()) 28 | }) 29 | end 30 | end 31 | -------------------------------------------------------------------------------- /apps/language_server/lib/language_server/lsp/protocol/structures/document_range_formatting_client_capabilities.ex: -------------------------------------------------------------------------------- 1 | # codegen: do not edit 2 | defmodule GenLSP.Structures.DocumentRangeFormattingClientCapabilities do 3 | @moduledoc """ 4 | Client capabilities of a {@link DocumentRangeFormattingRequest}. 5 | """ 6 | 7 | import SchematicV, warn: false 8 | 9 | use TypedStruct 10 | 11 | @doc """ 12 | ## Fields 13 | 14 | * dynamic_registration: Whether range formatting supports dynamic registration. 15 | """ 16 | 17 | typedstruct do 18 | field(:dynamic_registration, boolean()) 19 | end 20 | 21 | @doc false 22 | @spec schematic() :: SchematicV.t() 23 | def schematic() do 24 | schema(__MODULE__, %{ 25 | optional({"dynamicRegistration", :dynamic_registration}) => bool() 26 | }) 27 | end 28 | end 29 | -------------------------------------------------------------------------------- /apps/debug_adapter/lib/protocol/dap/enumerations/data_breakpoint_access_type.ex: -------------------------------------------------------------------------------- 1 | # codegen: do not edit 2 | defmodule GenDAP.Enumerations.DataBreakpointAccessType do 3 | @moduledoc """ 4 | This enumeration defines all possible access types for data breakpoints. 5 | """ 6 | 7 | @typedoc "A type defining DAP enumeration DataBreakpointAccessType" 8 | @type t :: String.t() 9 | 10 | import SchematicV, warn: false 11 | 12 | @spec read() :: String.t() 13 | def read, do: "read" 14 | 15 | @spec write() :: String.t() 16 | def write, do: "write" 17 | 18 | @spec read_write() :: String.t() 19 | def read_write, do: "readWrite" 20 | 21 | @doc false 22 | @spec schematic() :: SchematicV.t() 23 | def schematic() do 24 | oneof([ 25 | "read", 26 | "write", 27 | "readWrite" 28 | ]) 29 | end 30 | end 31 | -------------------------------------------------------------------------------- /apps/language_server/lib/language_server/lsp/protocol/structures/location.ex: -------------------------------------------------------------------------------- 1 | # codegen: do not edit 2 | defmodule GenLSP.Structures.Location do 3 | @moduledoc """ 4 | Represents a location inside a resource, such as a line 5 | inside a text file. 6 | """ 7 | 8 | import SchematicV, warn: false 9 | 10 | use TypedStruct 11 | 12 | @doc """ 13 | ## Fields 14 | 15 | * uri 16 | * range 17 | """ 18 | 19 | typedstruct do 20 | field(:uri, GenLSP.BaseTypes.document_uri(), enforce: true) 21 | field(:range, GenLSP.Structures.Range.t(), enforce: true) 22 | end 23 | 24 | @doc false 25 | @spec schematic() :: SchematicV.t() 26 | def schematic() do 27 | schema(__MODULE__, %{ 28 | {"uri", :uri} => str(), 29 | {"range", :range} => GenLSP.Structures.Range.schematic() 30 | }) 31 | end 32 | end 33 | -------------------------------------------------------------------------------- /apps/language_server/lib/language_server/providers/execute_command/restart.ex: -------------------------------------------------------------------------------- 1 | defmodule ElixirLS.LanguageServer.Providers.ExecuteCommand.Restart do 2 | require Logger 3 | alias ElixirLS.LanguageServer.JsonRpc 4 | 5 | @behaviour ElixirLS.LanguageServer.Providers.ExecuteCommand 6 | 7 | @impl ElixirLS.LanguageServer.Providers.ExecuteCommand 8 | def execute(_args, _state) do 9 | {:ok, _pid} = 10 | Task.start(fn -> 11 | Logger.info("ElixirLS restart requested") 12 | 13 | JsonRpc.telemetry( 14 | "lsp_reload", 15 | %{ 16 | "elixir_ls.lsp_reload_reason" => "client_request" 17 | }, 18 | %{} 19 | ) 20 | 21 | Process.sleep(1000) 22 | ElixirLS.LanguageServer.Application.restart() 23 | end) 24 | 25 | {:ok, %{}} 26 | end 27 | end 28 | -------------------------------------------------------------------------------- /apps/language_server/lib/language_server/lsp/protocol/structures/did_change_workspace_folders_params.ex: -------------------------------------------------------------------------------- 1 | # codegen: do not edit 2 | defmodule GenLSP.Structures.DidChangeWorkspaceFoldersParams do 3 | @moduledoc """ 4 | The parameters of a `workspace/didChangeWorkspaceFolders` notification. 5 | """ 6 | 7 | import SchematicV, warn: false 8 | 9 | use TypedStruct 10 | 11 | @doc """ 12 | ## Fields 13 | 14 | * event: The actual workspace folder change event. 15 | """ 16 | 17 | typedstruct do 18 | field(:event, GenLSP.Structures.WorkspaceFoldersChangeEvent.t(), enforce: true) 19 | end 20 | 21 | @doc false 22 | @spec schematic() :: SchematicV.t() 23 | def schematic() do 24 | schema(__MODULE__, %{ 25 | {"event", :event} => GenLSP.Structures.WorkspaceFoldersChangeEvent.schematic() 26 | }) 27 | end 28 | end 29 | -------------------------------------------------------------------------------- /apps/language_server/lib/language_server/lsp/protocol/structures/document_on_type_formatting_client_capabilities.ex: -------------------------------------------------------------------------------- 1 | # codegen: do not edit 2 | defmodule GenLSP.Structures.DocumentOnTypeFormattingClientCapabilities do 3 | @moduledoc """ 4 | Client capabilities of a {@link DocumentOnTypeFormattingRequest}. 5 | """ 6 | 7 | import SchematicV, warn: false 8 | 9 | use TypedStruct 10 | 11 | @doc """ 12 | ## Fields 13 | 14 | * dynamic_registration: Whether on type formatting supports dynamic registration. 15 | """ 16 | 17 | typedstruct do 18 | field(:dynamic_registration, boolean()) 19 | end 20 | 21 | @doc false 22 | @spec schematic() :: SchematicV.t() 23 | def schematic() do 24 | schema(__MODULE__, %{ 25 | optional({"dynamicRegistration", :dynamic_registration}) => bool() 26 | }) 27 | end 28 | end 29 | -------------------------------------------------------------------------------- /apps/language_server/lib/language_server/lsp/protocol/structures/file_event.ex: -------------------------------------------------------------------------------- 1 | # codegen: do not edit 2 | defmodule GenLSP.Structures.FileEvent do 3 | @moduledoc """ 4 | An event describing a file change. 5 | """ 6 | 7 | import SchematicV, warn: false 8 | 9 | use TypedStruct 10 | 11 | @doc """ 12 | ## Fields 13 | 14 | * uri: The file's uri. 15 | * type: The change type. 16 | """ 17 | 18 | typedstruct do 19 | field(:uri, GenLSP.BaseTypes.document_uri(), enforce: true) 20 | field(:type, GenLSP.Enumerations.FileChangeType.t(), enforce: true) 21 | end 22 | 23 | @doc false 24 | @spec schematic() :: SchematicV.t() 25 | def schematic() do 26 | schema(__MODULE__, %{ 27 | {"uri", :uri} => str(), 28 | {"type", :type} => GenLSP.Enumerations.FileChangeType.schematic() 29 | }) 30 | end 31 | end 32 | -------------------------------------------------------------------------------- /apps/language_server/lib/language_server/lsp/protocol/structures/inline_value_client_capabilities.ex: -------------------------------------------------------------------------------- 1 | # codegen: do not edit 2 | defmodule GenLSP.Structures.InlineValueClientCapabilities do 3 | @moduledoc """ 4 | Client capabilities specific to inline values. 5 | 6 | @since 3.17.0 7 | """ 8 | 9 | import SchematicV, warn: false 10 | 11 | use TypedStruct 12 | 13 | @doc """ 14 | ## Fields 15 | 16 | * dynamic_registration: Whether implementation supports dynamic registration for inline value providers. 17 | """ 18 | 19 | typedstruct do 20 | field(:dynamic_registration, boolean()) 21 | end 22 | 23 | @doc false 24 | @spec schematic() :: SchematicV.t() 25 | def schematic() do 26 | schema(__MODULE__, %{ 27 | optional({"dynamicRegistration", :dynamic_registration}) => bool() 28 | }) 29 | end 30 | end 31 | -------------------------------------------------------------------------------- /apps/language_server/lib/language_server/lsp/protocol/structures/progress_params.ex: -------------------------------------------------------------------------------- 1 | # codegen: do not edit 2 | defmodule GenLSP.Structures.ProgressParams do 3 | import SchematicV, warn: false 4 | 5 | use TypedStruct 6 | 7 | @doc """ 8 | ## Fields 9 | 10 | * token: The progress token provided by the client or server. 11 | * value: The progress data. 12 | """ 13 | 14 | typedstruct do 15 | field(:token, GenLSP.TypeAlias.ProgressToken.t(), enforce: true) 16 | field(:value, GenLSP.TypeAlias.LSPAny.t(), enforce: true) 17 | end 18 | 19 | @doc false 20 | @spec schematic() :: SchematicV.t() 21 | def schematic() do 22 | schema(__MODULE__, %{ 23 | {"token", :token} => GenLSP.TypeAlias.ProgressToken.schematic(), 24 | {"value", :value} => GenLSP.TypeAlias.LSPAny.schematic() 25 | }) 26 | end 27 | end 28 | -------------------------------------------------------------------------------- /apps/language_server/lib/language_server/lsp/protocol/structures/workspace_diagnostic_report_partial_result.ex: -------------------------------------------------------------------------------- 1 | # codegen: do not edit 2 | defmodule GenLSP.Structures.WorkspaceDiagnosticReportPartialResult do 3 | @moduledoc """ 4 | A partial result for a workspace diagnostic report. 5 | 6 | @since 3.17.0 7 | """ 8 | 9 | import SchematicV, warn: false 10 | 11 | use TypedStruct 12 | 13 | @doc """ 14 | ## Fields 15 | 16 | * items 17 | """ 18 | 19 | typedstruct do 20 | field(:items, list(GenLSP.TypeAlias.WorkspaceDocumentDiagnosticReport.t()), enforce: true) 21 | end 22 | 23 | @doc false 24 | @spec schematic() :: SchematicV.t() 25 | def schematic() do 26 | schema(__MODULE__, %{ 27 | {"items", :items} => list(GenLSP.TypeAlias.WorkspaceDocumentDiagnosticReport.schematic()) 28 | }) 29 | end 30 | end 31 | -------------------------------------------------------------------------------- /apps/language_server/lib/language_server/lsp/protocol/enumerations/file_operation_pattern_kind.ex: -------------------------------------------------------------------------------- 1 | # codegen: do not edit 2 | defmodule GenLSP.Enumerations.FileOperationPatternKind do 3 | @moduledoc """ 4 | A pattern kind describing if a glob pattern matches a file a folder or 5 | both. 6 | 7 | @since 3.16.0 8 | """ 9 | 10 | @type t :: String.t() 11 | 12 | import SchematicV, warn: false 13 | 14 | @doc """ 15 | The pattern matches a file only. 16 | """ 17 | @spec file() :: String.t() 18 | def file, do: "file" 19 | 20 | @doc """ 21 | The pattern matches a folder only. 22 | """ 23 | @spec folder() :: String.t() 24 | def folder, do: "folder" 25 | 26 | @doc false 27 | @spec schematic() :: SchematicV.t() 28 | def schematic() do 29 | oneof([ 30 | "file", 31 | "folder" 32 | ]) 33 | end 34 | end 35 | -------------------------------------------------------------------------------- /apps/debug_adapter/lib/debug_adapter/module_info_cache.ex: -------------------------------------------------------------------------------- 1 | defmodule ElixirLS.DebugAdapter.ModuleInfoCache do 2 | @moduledoc """ 3 | Caches module_info of interpreted modules. There are cases when module_info call 4 | may deadlock (https://github.com/elixir-lsp/elixir-ls/issues/940) 5 | """ 6 | 7 | use Agent 8 | 9 | def start_link(args) do 10 | Agent.start_link(fn -> args end, name: __MODULE__) 11 | end 12 | 13 | def get(module) do 14 | Agent.get(__MODULE__, & &1[module]) 15 | end 16 | 17 | def store(module) do 18 | Agent.update(__MODULE__, fn map -> 19 | if Map.has_key?(map, module) do 20 | map 21 | else 22 | Map.put(map, module, module.module_info()) 23 | end 24 | end) 25 | end 26 | 27 | def clear() do 28 | Agent.update(__MODULE__, fn _map -> %{} end) 29 | end 30 | end 31 | -------------------------------------------------------------------------------- /apps/language_server/lib/language_server/lsp/protocol/structures/create_files_params.ex: -------------------------------------------------------------------------------- 1 | # codegen: do not edit 2 | defmodule GenLSP.Structures.CreateFilesParams do 3 | @moduledoc """ 4 | The parameters sent in notifications/requests for user-initiated creation of 5 | files. 6 | 7 | @since 3.16.0 8 | """ 9 | 10 | import SchematicV, warn: false 11 | 12 | use TypedStruct 13 | 14 | @doc """ 15 | ## Fields 16 | 17 | * files: An array of all files/folders created in this operation. 18 | """ 19 | 20 | typedstruct do 21 | field(:files, list(GenLSP.Structures.FileCreate.t()), enforce: true) 22 | end 23 | 24 | @doc false 25 | @spec schematic() :: SchematicV.t() 26 | def schematic() do 27 | schema(__MODULE__, %{ 28 | {"files", :files} => list(GenLSP.Structures.FileCreate.schematic()) 29 | }) 30 | end 31 | end 32 | -------------------------------------------------------------------------------- /apps/language_server/lib/language_server/lsp/protocol/structures/delete_files_params.ex: -------------------------------------------------------------------------------- 1 | # codegen: do not edit 2 | defmodule GenLSP.Structures.DeleteFilesParams do 3 | @moduledoc """ 4 | The parameters sent in notifications/requests for user-initiated deletes of 5 | files. 6 | 7 | @since 3.16.0 8 | """ 9 | 10 | import SchematicV, warn: false 11 | 12 | use TypedStruct 13 | 14 | @doc """ 15 | ## Fields 16 | 17 | * files: An array of all files/folders deleted in this operation. 18 | """ 19 | 20 | typedstruct do 21 | field(:files, list(GenLSP.Structures.FileDelete.t()), enforce: true) 22 | end 23 | 24 | @doc false 25 | @spec schematic() :: SchematicV.t() 26 | def schematic() do 27 | schema(__MODULE__, %{ 28 | {"files", :files} => list(GenLSP.Structures.FileDelete.schematic()) 29 | }) 30 | end 31 | end 32 | -------------------------------------------------------------------------------- /apps/language_server/lib/language_server/lsp/protocol/type_aliases/text_document_content_change_event.ex: -------------------------------------------------------------------------------- 1 | # codegen: do not edit 2 | defmodule GenLSP.TypeAlias.TextDocumentContentChangeEvent do 3 | @moduledoc """ 4 | An event describing a change to a text document. If only a text is provided 5 | it is considered to be the full content of the document. 6 | """ 7 | 8 | import SchematicV, warn: false 9 | 10 | @type t :: map() | map() 11 | 12 | @doc false 13 | @spec schematic() :: SchematicV.t() 14 | def schematic() do 15 | oneof([ 16 | map(%{ 17 | {"range", :range} => GenLSP.Structures.Range.schematic(), 18 | optional({"rangeLength", :range_length}) => int(), 19 | {"text", :text} => str() 20 | }), 21 | map(%{ 22 | {"text", :text} => str() 23 | }) 24 | ]) 25 | end 26 | end 27 | -------------------------------------------------------------------------------- /apps/language_server/lib/language_server/lsp/protocol/structures/did_change_watched_files_registration_options.ex: -------------------------------------------------------------------------------- 1 | # codegen: do not edit 2 | defmodule GenLSP.Structures.DidChangeWatchedFilesRegistrationOptions do 3 | @moduledoc """ 4 | Describe options to be used when registered for text document change events. 5 | """ 6 | 7 | import SchematicV, warn: false 8 | 9 | use TypedStruct 10 | 11 | @doc """ 12 | ## Fields 13 | 14 | * watchers: The watchers to register. 15 | """ 16 | 17 | typedstruct do 18 | field(:watchers, list(GenLSP.Structures.FileSystemWatcher.t()), enforce: true) 19 | end 20 | 21 | @doc false 22 | @spec schematic() :: SchematicV.t() 23 | def schematic() do 24 | schema(__MODULE__, %{ 25 | {"watchers", :watchers} => list(GenLSP.Structures.FileSystemWatcher.schematic()) 26 | }) 27 | end 28 | end 29 | -------------------------------------------------------------------------------- /apps/language_server/lib/language_server/providers/implementation.ex: -------------------------------------------------------------------------------- 1 | defmodule ElixirLS.LanguageServer.Providers.Implementation do 2 | @moduledoc """ 3 | textDocument/implementation provider utilizing Elixir Sense 4 | """ 5 | 6 | alias ElixirLS.LanguageServer.{Protocol, Parser} 7 | alias ElixirLS.LanguageServer.Providers.Implementation.Locator 8 | 9 | def implementation( 10 | uri, 11 | %Parser.Context{source_file: source_file, metadata: metadata}, 12 | line, 13 | character, 14 | project_dir 15 | ) do 16 | locations = Locator.implementations(source_file.text, line, character, metadata: metadata) 17 | 18 | results = 19 | for location <- locations, 20 | do: Protocol.Location.to_gen_lsp(location, uri, source_file.text, project_dir) 21 | 22 | {:ok, results} 23 | end 24 | end 25 | -------------------------------------------------------------------------------- /apps/language_server/lib/language_server/lsp/protocol/structures/create_file_options.ex: -------------------------------------------------------------------------------- 1 | # codegen: do not edit 2 | defmodule GenLSP.Structures.CreateFileOptions do 3 | @moduledoc """ 4 | Options to create a file. 5 | """ 6 | 7 | import SchematicV, warn: false 8 | 9 | use TypedStruct 10 | 11 | @doc """ 12 | ## Fields 13 | 14 | * overwrite: Overwrite existing file. Overwrite wins over `ignoreIfExists` 15 | * ignore_if_exists: Ignore if exists. 16 | """ 17 | 18 | typedstruct do 19 | field(:overwrite, boolean()) 20 | field(:ignore_if_exists, boolean()) 21 | end 22 | 23 | @doc false 24 | @spec schematic() :: SchematicV.t() 25 | def schematic() do 26 | schema(__MODULE__, %{ 27 | optional({"overwrite", :overwrite}) => bool(), 28 | optional({"ignoreIfExists", :ignore_if_exists}) => bool() 29 | }) 30 | end 31 | end 32 | -------------------------------------------------------------------------------- /apps/language_server/lib/language_server/lsp/protocol/structures/document_color_client_capabilities.ex: -------------------------------------------------------------------------------- 1 | # codegen: do not edit 2 | defmodule GenLSP.Structures.DocumentColorClientCapabilities do 3 | import SchematicV, warn: false 4 | 5 | use TypedStruct 6 | 7 | @doc """ 8 | ## Fields 9 | 10 | * dynamic_registration: Whether implementation supports dynamic registration. If this is set to `true` 11 | the client supports the new `DocumentColorRegistrationOptions` return value 12 | for the corresponding server capability as well. 13 | """ 14 | 15 | typedstruct do 16 | field(:dynamic_registration, boolean()) 17 | end 18 | 19 | @doc false 20 | @spec schematic() :: SchematicV.t() 21 | def schematic() do 22 | schema(__MODULE__, %{ 23 | optional({"dynamicRegistration", :dynamic_registration}) => bool() 24 | }) 25 | end 26 | end 27 | -------------------------------------------------------------------------------- /apps/language_server/lib/language_server/lsp/protocol/structures/log_message_params.ex: -------------------------------------------------------------------------------- 1 | # codegen: do not edit 2 | defmodule GenLSP.Structures.LogMessageParams do 3 | @moduledoc """ 4 | The log message parameters. 5 | """ 6 | 7 | import SchematicV, warn: false 8 | 9 | use TypedStruct 10 | 11 | @doc """ 12 | ## Fields 13 | 14 | * type: The message type. See {@link MessageType} 15 | * message: The actual message. 16 | """ 17 | 18 | typedstruct do 19 | field(:type, GenLSP.Enumerations.MessageType.t(), enforce: true) 20 | field(:message, String.t(), enforce: true) 21 | end 22 | 23 | @doc false 24 | @spec schematic() :: SchematicV.t() 25 | def schematic() do 26 | schema(__MODULE__, %{ 27 | {"type", :type} => GenLSP.Enumerations.MessageType.schematic(), 28 | {"message", :message} => str() 29 | }) 30 | end 31 | end 32 | -------------------------------------------------------------------------------- /apps/language_server/lib/language_server/lsp/protocol/structures/workspace_symbol_registration_options.ex: -------------------------------------------------------------------------------- 1 | # codegen: do not edit 2 | defmodule GenLSP.Structures.WorkspaceSymbolRegistrationOptions do 3 | @moduledoc """ 4 | Registration options for a {@link WorkspaceSymbolRequest}. 5 | """ 6 | 7 | import SchematicV, warn: false 8 | 9 | use TypedStruct 10 | 11 | @doc """ 12 | ## Fields 13 | 14 | * resolve_provider: The server provides support to resolve additional 15 | information for a workspace symbol. 16 | 17 | @since 3.17.0 18 | """ 19 | 20 | typedstruct do 21 | field(:resolve_provider, boolean()) 22 | end 23 | 24 | @doc false 25 | @spec schematic() :: SchematicV.t() 26 | def schematic() do 27 | schema(__MODULE__, %{ 28 | optional({"resolveProvider", :resolve_provider}) => bool() 29 | }) 30 | end 31 | end 32 | -------------------------------------------------------------------------------- /apps/language_server/lib/language_server/lsp/protocol/enumerations/document_highlight_kind.ex: -------------------------------------------------------------------------------- 1 | # codegen: do not edit 2 | defmodule GenLSP.Enumerations.DocumentHighlightKind do 3 | @moduledoc """ 4 | A document highlight kind. 5 | """ 6 | 7 | @type t :: 1 | 2 | 3 8 | 9 | import SchematicV, warn: false 10 | 11 | @doc """ 12 | A textual occurrence. 13 | """ 14 | @spec text() :: 1 15 | def text, do: 1 16 | 17 | @doc """ 18 | Read-access of a symbol, like reading a variable. 19 | """ 20 | @spec read() :: 2 21 | def read, do: 2 22 | 23 | @doc """ 24 | Write-access of a symbol, like writing to a variable. 25 | """ 26 | @spec write() :: 3 27 | def write, do: 3 28 | 29 | @doc false 30 | @spec schematic() :: SchematicV.t() 31 | def schematic() do 32 | oneof([ 33 | 1, 34 | 2, 35 | 3 36 | ]) 37 | end 38 | end 39 | -------------------------------------------------------------------------------- /apps/language_server/lib/language_server/lsp/protocol/structures/moniker_registration_options.ex: -------------------------------------------------------------------------------- 1 | # codegen: do not edit 2 | defmodule GenLSP.Structures.MonikerRegistrationOptions do 3 | import SchematicV, warn: false 4 | 5 | use TypedStruct 6 | 7 | @doc """ 8 | ## Fields 9 | 10 | * document_selector: A document selector to identify the scope of the registration. If set to null 11 | the document selector provided on the client side will be used. 12 | """ 13 | 14 | typedstruct do 15 | field(:document_selector, GenLSP.TypeAlias.DocumentSelector.t() | nil, enforce: true) 16 | end 17 | 18 | @doc false 19 | @spec schematic() :: SchematicV.t() 20 | def schematic() do 21 | schema(__MODULE__, %{ 22 | {"documentSelector", :document_selector} => 23 | oneof([GenLSP.TypeAlias.DocumentSelector.schematic(), nil]) 24 | }) 25 | end 26 | end 27 | -------------------------------------------------------------------------------- /apps/language_server/lib/language_server/lsp/protocol/structures/rename_file_options.ex: -------------------------------------------------------------------------------- 1 | # codegen: do not edit 2 | defmodule GenLSP.Structures.RenameFileOptions do 3 | @moduledoc """ 4 | Rename file options 5 | """ 6 | 7 | import SchematicV, warn: false 8 | 9 | use TypedStruct 10 | 11 | @doc """ 12 | ## Fields 13 | 14 | * overwrite: Overwrite target if existing. Overwrite wins over `ignoreIfExists` 15 | * ignore_if_exists: Ignores if target exists. 16 | """ 17 | 18 | typedstruct do 19 | field(:overwrite, boolean()) 20 | field(:ignore_if_exists, boolean()) 21 | end 22 | 23 | @doc false 24 | @spec schematic() :: SchematicV.t() 25 | def schematic() do 26 | schema(__MODULE__, %{ 27 | optional({"overwrite", :overwrite}) => bool(), 28 | optional({"ignoreIfExists", :ignore_if_exists}) => bool() 29 | }) 30 | end 31 | end 32 | -------------------------------------------------------------------------------- /apps/language_server/test/support/references_local_vs_remote.ex: -------------------------------------------------------------------------------- 1 | defmodule ElixirSenseExample.ReferencesLocalVsRemote do 2 | defmodule SubModule do 3 | def abc(), do: :ok 4 | 5 | def cde(), do: abc() 6 | end 7 | 8 | @type t :: %ElixirSenseExample.ReferencesLocalVsRemote{ 9 | field: String.t() 10 | } 11 | defstruct field: "" 12 | 13 | def my_fun(arg) do 14 | :ok 15 | end 16 | end 17 | 18 | defmodule ElixirSenseExample.ReferencesLocalVsRemoteCaller do 19 | alias ElixirSenseExample.ReferencesLocalVsRemote, as: M 20 | 21 | @spec process(M.t()) :: :ok 22 | def process(%M{} = struct) do 23 | M.my_fun(struct) 24 | end 25 | 26 | def abc() do 27 | import Enum 28 | require Logger 29 | 30 | Logger.info("abc") 31 | Enum.map([1, 2, 3], fn x -> x + 1 end) 32 | map([1, 2, 3], fn x -> x + 1 end) 33 | end 34 | end 35 | -------------------------------------------------------------------------------- /apps/language_server/lib/language_server/lsp/protocol/structures/regular_expressions_client_capabilities.ex: -------------------------------------------------------------------------------- 1 | # codegen: do not edit 2 | defmodule GenLSP.Structures.RegularExpressionsClientCapabilities do 3 | @moduledoc """ 4 | Client capabilities specific to regular expressions. 5 | 6 | @since 3.16.0 7 | """ 8 | 9 | import SchematicV, warn: false 10 | 11 | use TypedStruct 12 | 13 | @doc """ 14 | ## Fields 15 | 16 | * engine: The engine's name. 17 | * version: The engine's version. 18 | """ 19 | 20 | typedstruct do 21 | field(:engine, String.t(), enforce: true) 22 | field(:version, String.t()) 23 | end 24 | 25 | @doc false 26 | @spec schematic() :: SchematicV.t() 27 | def schematic() do 28 | schema(__MODULE__, %{ 29 | {"engine", :engine} => str(), 30 | optional({"version", :version}) => str() 31 | }) 32 | end 33 | end 34 | -------------------------------------------------------------------------------- /apps/language_server/lib/language_server/lsp/protocol/enumerations/document_diagnostic_report_kind.ex: -------------------------------------------------------------------------------- 1 | # codegen: do not edit 2 | defmodule GenLSP.Enumerations.DocumentDiagnosticReportKind do 3 | @moduledoc """ 4 | The document diagnostic report kinds. 5 | 6 | @since 3.17.0 7 | """ 8 | 9 | @type t :: String.t() 10 | 11 | import SchematicV, warn: false 12 | 13 | @doc """ 14 | A diagnostic report with a full 15 | set of problems. 16 | """ 17 | @spec full() :: String.t() 18 | def full, do: "full" 19 | 20 | @doc """ 21 | A report indicating that the last 22 | returned report is still accurate. 23 | """ 24 | @spec unchanged() :: String.t() 25 | def unchanged, do: "unchanged" 26 | 27 | @doc false 28 | @spec schematic() :: SchematicV.t() 29 | def schematic() do 30 | oneof([ 31 | "full", 32 | "unchanged" 33 | ]) 34 | end 35 | end 36 | -------------------------------------------------------------------------------- /apps/language_server/lib/language_server/lsp/protocol/enumerations/resource_operation_kind.ex: -------------------------------------------------------------------------------- 1 | # codegen: do not edit 2 | defmodule GenLSP.Enumerations.ResourceOperationKind do 3 | @type t :: String.t() 4 | 5 | import SchematicV, warn: false 6 | 7 | @doc """ 8 | Supports creating new files and folders. 9 | """ 10 | @spec create() :: String.t() 11 | def create, do: "create" 12 | 13 | @doc """ 14 | Supports renaming existing files and folders. 15 | """ 16 | @spec rename() :: String.t() 17 | def rename, do: "rename" 18 | 19 | @doc """ 20 | Supports deleting existing files and folders. 21 | """ 22 | @spec delete() :: String.t() 23 | def delete, do: "delete" 24 | 25 | @doc false 26 | @spec schematic() :: SchematicV.t() 27 | def schematic() do 28 | oneof([ 29 | "create", 30 | "rename", 31 | "delete" 32 | ]) 33 | end 34 | end 35 | -------------------------------------------------------------------------------- /apps/language_server/lib/language_server/lsp/protocol/structures/semantic_tokens_legend.ex: -------------------------------------------------------------------------------- 1 | # codegen: do not edit 2 | defmodule GenLSP.Structures.SemanticTokensLegend do 3 | @moduledoc """ 4 | @since 3.16.0 5 | """ 6 | 7 | import SchematicV, warn: false 8 | 9 | use TypedStruct 10 | 11 | @doc """ 12 | ## Fields 13 | 14 | * token_types: The token types a server uses. 15 | * token_modifiers: The token modifiers a server uses. 16 | """ 17 | 18 | typedstruct do 19 | field(:token_types, list(String.t()), enforce: true) 20 | field(:token_modifiers, list(String.t()), enforce: true) 21 | end 22 | 23 | @doc false 24 | @spec schematic() :: SchematicV.t() 25 | def schematic() do 26 | schema(__MODULE__, %{ 27 | {"tokenTypes", :token_types} => list(str()), 28 | {"tokenModifiers", :token_modifiers} => list(str()) 29 | }) 30 | end 31 | end 32 | -------------------------------------------------------------------------------- /apps/language_server/lib/language_server/lsp/protocol/structures/show_message_params.ex: -------------------------------------------------------------------------------- 1 | # codegen: do not edit 2 | defmodule GenLSP.Structures.ShowMessageParams do 3 | @moduledoc """ 4 | The parameters of a notification message. 5 | """ 6 | 7 | import SchematicV, warn: false 8 | 9 | use TypedStruct 10 | 11 | @doc """ 12 | ## Fields 13 | 14 | * type: The message type. See {@link MessageType} 15 | * message: The actual message. 16 | """ 17 | 18 | typedstruct do 19 | field(:type, GenLSP.Enumerations.MessageType.t(), enforce: true) 20 | field(:message, String.t(), enforce: true) 21 | end 22 | 23 | @doc false 24 | @spec schematic() :: SchematicV.t() 25 | def schematic() do 26 | schema(__MODULE__, %{ 27 | {"type", :type} => GenLSP.Enumerations.MessageType.schematic(), 28 | {"message", :message} => str() 29 | }) 30 | end 31 | end 32 | -------------------------------------------------------------------------------- /apps/language_server/lib/language_server/lsp/protocol/structures/code_lens_options.ex: -------------------------------------------------------------------------------- 1 | # codegen: do not edit 2 | defmodule GenLSP.Structures.CodeLensOptions do 3 | @moduledoc """ 4 | Code Lens provider options of a {@link CodeLensRequest}. 5 | """ 6 | 7 | import SchematicV, warn: false 8 | 9 | use TypedStruct 10 | 11 | @doc """ 12 | ## Fields 13 | 14 | * resolve_provider: Code lens has a resolve provider as well. 15 | * work_done_progress 16 | """ 17 | 18 | typedstruct do 19 | field(:resolve_provider, boolean()) 20 | field(:work_done_progress, boolean()) 21 | end 22 | 23 | @doc false 24 | @spec schematic() :: SchematicV.t() 25 | def schematic() do 26 | schema(__MODULE__, %{ 27 | optional({"resolveProvider", :resolve_provider}) => bool(), 28 | optional({"workDoneProgress", :work_done_progress}) => bool() 29 | }) 30 | end 31 | end 32 | -------------------------------------------------------------------------------- /apps/language_server/lib/language_server/lsp/protocol/structures/execute_command_options.ex: -------------------------------------------------------------------------------- 1 | # codegen: do not edit 2 | defmodule GenLSP.Structures.ExecuteCommandOptions do 3 | @moduledoc """ 4 | The server capabilities of a {@link ExecuteCommandRequest}. 5 | """ 6 | 7 | import SchematicV, warn: false 8 | 9 | use TypedStruct 10 | 11 | @doc """ 12 | ## Fields 13 | 14 | * commands: The commands to be executed on the server 15 | * work_done_progress 16 | """ 17 | 18 | typedstruct do 19 | field(:commands, list(String.t()), enforce: true) 20 | field(:work_done_progress, boolean()) 21 | end 22 | 23 | @doc false 24 | @spec schematic() :: SchematicV.t() 25 | def schematic() do 26 | schema(__MODULE__, %{ 27 | {"commands", :commands} => list(str()), 28 | optional({"workDoneProgress", :work_done_progress}) => bool() 29 | }) 30 | end 31 | end 32 | -------------------------------------------------------------------------------- /apps/debug_adapter/lib/protocol/dap/enumerations/checksum_algorithm.ex: -------------------------------------------------------------------------------- 1 | # codegen: do not edit 2 | defmodule GenDAP.Enumerations.ChecksumAlgorithm do 3 | @moduledoc """ 4 | Names of checksum algorithms that may be supported by a debug adapter. 5 | """ 6 | 7 | @typedoc "A type defining DAP enumeration ChecksumAlgorithm" 8 | @type t :: String.t() 9 | 10 | import SchematicV, warn: false 11 | 12 | @spec md5() :: String.t() 13 | def md5, do: "MD5" 14 | 15 | @spec sha1() :: String.t() 16 | def sha1, do: "SHA1" 17 | 18 | @spec sha256() :: String.t() 19 | def sha256, do: "SHA256" 20 | 21 | @spec timestamp() :: String.t() 22 | def timestamp, do: "timestamp" 23 | 24 | @doc false 25 | @spec schematic() :: SchematicV.t() 26 | def schematic() do 27 | oneof([ 28 | "MD5", 29 | "SHA1", 30 | "SHA256", 31 | "timestamp" 32 | ]) 33 | end 34 | end 35 | -------------------------------------------------------------------------------- /apps/language_server/lib/language_server/lsp/protocol/structures/inline_value_text.ex: -------------------------------------------------------------------------------- 1 | # codegen: do not edit 2 | defmodule GenLSP.Structures.InlineValueText do 3 | @moduledoc """ 4 | Provide inline value as text. 5 | 6 | @since 3.17.0 7 | """ 8 | 9 | import SchematicV, warn: false 10 | 11 | use TypedStruct 12 | 13 | @doc """ 14 | ## Fields 15 | 16 | * range: The document range for which the inline value applies. 17 | * text: The text of the inline value. 18 | """ 19 | 20 | typedstruct do 21 | field(:range, GenLSP.Structures.Range.t(), enforce: true) 22 | field(:text, String.t(), enforce: true) 23 | end 24 | 25 | @doc false 26 | @spec schematic() :: SchematicV.t() 27 | def schematic() do 28 | schema(__MODULE__, %{ 29 | {"range", :range} => GenLSP.Structures.Range.schematic(), 30 | {"text", :text} => str() 31 | }) 32 | end 33 | end 34 | -------------------------------------------------------------------------------- /apps/language_server/lib/language_server/lsp/protocol/structures/previous_result_id.ex: -------------------------------------------------------------------------------- 1 | # codegen: do not edit 2 | defmodule GenLSP.Structures.PreviousResultId do 3 | @moduledoc """ 4 | A previous result id in a workspace pull request. 5 | 6 | @since 3.17.0 7 | """ 8 | 9 | import SchematicV, warn: false 10 | 11 | use TypedStruct 12 | 13 | @doc """ 14 | ## Fields 15 | 16 | * uri: The URI for which the client knowns a 17 | result id. 18 | * value: The value of the previous result id. 19 | """ 20 | 21 | typedstruct do 22 | field(:uri, GenLSP.BaseTypes.document_uri(), enforce: true) 23 | field(:value, String.t(), enforce: true) 24 | end 25 | 26 | @doc false 27 | @spec schematic() :: SchematicV.t() 28 | def schematic() do 29 | schema(__MODULE__, %{ 30 | {"uri", :uri} => str(), 31 | {"value", :value} => str() 32 | }) 33 | end 34 | end 35 | -------------------------------------------------------------------------------- /apps/language_server/lib/language_server/lsp/protocol/structures/workspace_folder.ex: -------------------------------------------------------------------------------- 1 | # codegen: do not edit 2 | defmodule GenLSP.Structures.WorkspaceFolder do 3 | @moduledoc """ 4 | A workspace folder inside a client. 5 | """ 6 | 7 | import SchematicV, warn: false 8 | 9 | use TypedStruct 10 | 11 | @doc """ 12 | ## Fields 13 | 14 | * uri: The associated URI for this workspace folder. 15 | * name: The name of the workspace folder. Used to refer to this 16 | workspace folder in the user interface. 17 | """ 18 | 19 | typedstruct do 20 | field(:uri, GenLSP.BaseTypes.uri(), enforce: true) 21 | field(:name, String.t(), enforce: true) 22 | end 23 | 24 | @doc false 25 | @spec schematic() :: SchematicV.t() 26 | def schematic() do 27 | schema(__MODULE__, %{ 28 | {"uri", :uri} => str(), 29 | {"name", :name} => str() 30 | }) 31 | end 32 | end 33 | -------------------------------------------------------------------------------- /apps/debug_adapter/lib/protocol/dap/structures/set_function_breakpoints_arguments.ex: -------------------------------------------------------------------------------- 1 | # codegen: do not edit 2 | 3 | defmodule GenDAP.Structures.SetFunctionBreakpointsArguments do 4 | @moduledoc """ 5 | Arguments for `setFunctionBreakpoints` request. 6 | """ 7 | 8 | import SchematicV, warn: false 9 | 10 | use TypedStruct 11 | 12 | @doc """ 13 | ## Fields 14 | 15 | * breakpoints: The function names of the breakpoints. 16 | """ 17 | 18 | typedstruct do 19 | @typedoc "A type defining DAP structure SetFunctionBreakpointsArguments" 20 | field(:breakpoints, list(GenDAP.Structures.FunctionBreakpoint.t()), enforce: true) 21 | end 22 | 23 | @doc false 24 | @spec schematic() :: SchematicV.t() 25 | def schematic() do 26 | schema(__MODULE__, %{ 27 | {"breakpoints", :breakpoints} => list(GenDAP.Structures.FunctionBreakpoint.schematic()) 28 | }) 29 | end 30 | end 31 | -------------------------------------------------------------------------------- /apps/language_server/lib/language_server/lsp/protocol/enumerations/message_type.ex: -------------------------------------------------------------------------------- 1 | # codegen: do not edit 2 | defmodule GenLSP.Enumerations.MessageType do 3 | @moduledoc """ 4 | The message type 5 | """ 6 | 7 | @type t :: 1 | 2 | 3 | 4 8 | 9 | import SchematicV, warn: false 10 | 11 | @doc """ 12 | An error message. 13 | """ 14 | @spec error() :: 1 15 | def error, do: 1 16 | 17 | @doc """ 18 | A warning message. 19 | """ 20 | @spec warning() :: 2 21 | def warning, do: 2 22 | 23 | @doc """ 24 | An information message. 25 | """ 26 | @spec info() :: 3 27 | def info, do: 3 28 | 29 | @doc """ 30 | A log message. 31 | """ 32 | @spec log() :: 4 33 | def log, do: 4 34 | 35 | @doc false 36 | @spec schematic() :: SchematicV.t() 37 | def schematic() do 38 | oneof([ 39 | 1, 40 | 2, 41 | 3, 42 | 4 43 | ]) 44 | end 45 | end 46 | -------------------------------------------------------------------------------- /apps/language_server/lib/language_server/lsp/protocol/notifications/telemetry_event.ex: -------------------------------------------------------------------------------- 1 | # codegen: do not edit 2 | defmodule GenLSP.Notifications.TelemetryEvent do 3 | @moduledoc """ 4 | The telemetry event notification is sent from the server to the client to ask 5 | the client to log telemetry data. 6 | 7 | Message Direction: serverToClient 8 | """ 9 | 10 | import SchematicV, warn: false 11 | 12 | use TypedStruct 13 | 14 | typedstruct do 15 | field(:method, String.t(), default: "telemetry/event") 16 | field(:jsonrpc, String.t(), default: "2.0") 17 | field(:params, GenLSP.TypeAlias.LSPAny.t()) 18 | end 19 | 20 | @doc false 21 | @spec schematic() :: SchematicV.t() 22 | def schematic() do 23 | schema(__MODULE__, %{ 24 | method: "telemetry/event", 25 | jsonrpc: "2.0", 26 | params: GenLSP.TypeAlias.LSPAny.schematic() 27 | }) 28 | end 29 | end 30 | -------------------------------------------------------------------------------- /apps/language_server/lib/language_server/lsp/protocol/structures/delete_file_options.ex: -------------------------------------------------------------------------------- 1 | # codegen: do not edit 2 | defmodule GenLSP.Structures.DeleteFileOptions do 3 | @moduledoc """ 4 | Delete file options 5 | """ 6 | 7 | import SchematicV, warn: false 8 | 9 | use TypedStruct 10 | 11 | @doc """ 12 | ## Fields 13 | 14 | * recursive: Delete the content recursively if a folder is denoted. 15 | * ignore_if_not_exists: Ignore the operation if the file doesn't exist. 16 | """ 17 | 18 | typedstruct do 19 | field(:recursive, boolean()) 20 | field(:ignore_if_not_exists, boolean()) 21 | end 22 | 23 | @doc false 24 | @spec schematic() :: SchematicV.t() 25 | def schematic() do 26 | schema(__MODULE__, %{ 27 | optional({"recursive", :recursive}) => bool(), 28 | optional({"ignoreIfNotExists", :ignore_if_not_exists}) => bool() 29 | }) 30 | end 31 | end 32 | -------------------------------------------------------------------------------- /apps/language_server/lib/language_server/lsp/protocol/structures/document_link_options.ex: -------------------------------------------------------------------------------- 1 | # codegen: do not edit 2 | defmodule GenLSP.Structures.DocumentLinkOptions do 3 | @moduledoc """ 4 | Provider options for a {@link DocumentLinkRequest}. 5 | """ 6 | 7 | import SchematicV, warn: false 8 | 9 | use TypedStruct 10 | 11 | @doc """ 12 | ## Fields 13 | 14 | * resolve_provider: Document links have a resolve provider as well. 15 | * work_done_progress 16 | """ 17 | 18 | typedstruct do 19 | field(:resolve_provider, boolean()) 20 | field(:work_done_progress, boolean()) 21 | end 22 | 23 | @doc false 24 | @spec schematic() :: SchematicV.t() 25 | def schematic() do 26 | schema(__MODULE__, %{ 27 | optional({"resolveProvider", :resolve_provider}) => bool(), 28 | optional({"workDoneProgress", :work_done_progress}) => bool() 29 | }) 30 | end 31 | end 32 | -------------------------------------------------------------------------------- /apps/language_server/lib/language_server/lsp/protocol/structures/selection_range_client_capabilities.ex: -------------------------------------------------------------------------------- 1 | # codegen: do not edit 2 | defmodule GenLSP.Structures.SelectionRangeClientCapabilities do 3 | import SchematicV, warn: false 4 | 5 | use TypedStruct 6 | 7 | @doc """ 8 | ## Fields 9 | 10 | * dynamic_registration: Whether implementation supports dynamic registration for selection range providers. If this is set to `true` 11 | the client supports the new `SelectionRangeRegistrationOptions` return value for the corresponding server 12 | capability as well. 13 | """ 14 | 15 | typedstruct do 16 | field(:dynamic_registration, boolean()) 17 | end 18 | 19 | @doc false 20 | @spec schematic() :: SchematicV.t() 21 | def schematic() do 22 | schema(__MODULE__, %{ 23 | optional({"dynamicRegistration", :dynamic_registration}) => bool() 24 | }) 25 | end 26 | end 27 | -------------------------------------------------------------------------------- /apps/language_server/lib/language_server/lsp/protocol/structures/semantic_tokens_delta.ex: -------------------------------------------------------------------------------- 1 | # codegen: do not edit 2 | defmodule GenLSP.Structures.SemanticTokensDelta do 3 | @moduledoc """ 4 | @since 3.16.0 5 | """ 6 | 7 | import SchematicV, warn: false 8 | 9 | use TypedStruct 10 | 11 | @doc """ 12 | ## Fields 13 | 14 | * result_id 15 | * edits: The semantic token edits to transform a previous result into a new result. 16 | """ 17 | 18 | typedstruct do 19 | field(:result_id, String.t()) 20 | field(:edits, list(GenLSP.Structures.SemanticTokensEdit.t()), enforce: true) 21 | end 22 | 23 | @doc false 24 | @spec schematic() :: SchematicV.t() 25 | def schematic() do 26 | schema(__MODULE__, %{ 27 | optional({"resultId", :result_id}) => str(), 28 | {"edits", :edits} => list(GenLSP.Structures.SemanticTokensEdit.schematic()) 29 | }) 30 | end 31 | end 32 | -------------------------------------------------------------------------------- /apps/language_server/lib/language_server/lsp/protocol/structures/unregistration.ex: -------------------------------------------------------------------------------- 1 | # codegen: do not edit 2 | defmodule GenLSP.Structures.Unregistration do 3 | @moduledoc """ 4 | General parameters to unregister a request or notification. 5 | """ 6 | 7 | import SchematicV, warn: false 8 | 9 | use TypedStruct 10 | 11 | @doc """ 12 | ## Fields 13 | 14 | * id: The id used to unregister the request or notification. Usually an id 15 | provided during the register request. 16 | * method: The method to unregister for. 17 | """ 18 | 19 | typedstruct do 20 | field(:id, String.t(), enforce: true) 21 | field(:method, String.t(), enforce: true) 22 | end 23 | 24 | @doc false 25 | @spec schematic() :: SchematicV.t() 26 | def schematic() do 27 | schema(__MODULE__, %{ 28 | {"id", :id} => str(), 29 | {"method", :method} => str() 30 | }) 31 | end 32 | end 33 | -------------------------------------------------------------------------------- /apps/language_server/lib/language_server/lsp/protocol/structures/versioned_text_document_identifier.ex: -------------------------------------------------------------------------------- 1 | # codegen: do not edit 2 | defmodule GenLSP.Structures.VersionedTextDocumentIdentifier do 3 | @moduledoc """ 4 | A text document identifier to denote a specific version of a text document. 5 | """ 6 | 7 | import SchematicV, warn: false 8 | 9 | use TypedStruct 10 | 11 | @doc """ 12 | ## Fields 13 | 14 | * version: The version number of this document. 15 | * uri: The text document's uri. 16 | """ 17 | 18 | typedstruct do 19 | field(:version, integer(), enforce: true) 20 | field(:uri, GenLSP.BaseTypes.document_uri(), enforce: true) 21 | end 22 | 23 | @doc false 24 | @spec schematic() :: SchematicV.t() 25 | def schematic() do 26 | schema(__MODULE__, %{ 27 | {"version", :version} => int(), 28 | {"uri", :uri} => str() 29 | }) 30 | end 31 | end 32 | -------------------------------------------------------------------------------- /apps/language_server/lib/language_server/providers/definition.ex: -------------------------------------------------------------------------------- 1 | defmodule ElixirLS.LanguageServer.Providers.Definition do 2 | @moduledoc """ 3 | textDocument/definition provider utilizing Elixir Sense 4 | """ 5 | 6 | alias ElixirLS.LanguageServer.{Protocol, Parser} 7 | alias ElixirLS.LanguageServer.Providers.Definition.Locator 8 | 9 | def definition( 10 | uri, 11 | %Parser.Context{source_file: source_file, metadata: metadata}, 12 | line, 13 | character, 14 | project_dir 15 | ) do 16 | result = 17 | case Locator.definition(source_file.text, line, character, metadata: metadata) do 18 | nil -> 19 | nil 20 | 21 | %ElixirLS.LanguageServer.Location{} = location -> 22 | Protocol.Location.to_gen_lsp(location, uri, source_file.text, project_dir) 23 | end 24 | 25 | {:ok, result} 26 | end 27 | end 28 | -------------------------------------------------------------------------------- /apps/language_server/test/support/parser_context_builder.ex: -------------------------------------------------------------------------------- 1 | defmodule ElixirLS.LanguageServer.Test.ParserContextBuilder do 2 | alias ElixirLS.LanguageServer.SourceFile 3 | alias ElixirLS.LanguageServer.Parser 4 | 5 | def from_path(path, cursor_position \\ nil, language_id \\ "elixir") do 6 | text = File.read!(path) 7 | 8 | source_file = %SourceFile{text: text, version: 1, language_id: language_id} 9 | 10 | %Parser.Context{ 11 | source_file: source_file, 12 | path: path 13 | } 14 | |> Parser.do_parse(cursor_position) 15 | end 16 | 17 | def from_string(text, cursor_position \\ nil, language_id \\ "elixir") do 18 | source_file = %SourceFile{text: text, version: 1, language_id: language_id} 19 | 20 | %Parser.Context{ 21 | source_file: source_file, 22 | path: "nofile" 23 | } 24 | |> Parser.do_parse(cursor_position) 25 | end 26 | end 27 | -------------------------------------------------------------------------------- /apps/debug_adapter/lib/protocol/dap/structures/goto_arguments.ex: -------------------------------------------------------------------------------- 1 | # codegen: do not edit 2 | 3 | defmodule GenDAP.Structures.GotoArguments do 4 | @moduledoc """ 5 | Arguments for `goto` request. 6 | """ 7 | 8 | import SchematicV, warn: false 9 | 10 | use TypedStruct 11 | 12 | @doc """ 13 | ## Fields 14 | 15 | * target_id: The location where the debuggee will continue to run. 16 | * thread_id: Set the goto target for this thread. 17 | """ 18 | 19 | typedstruct do 20 | @typedoc "A type defining DAP structure GotoArguments" 21 | field(:target_id, integer(), enforce: true) 22 | field(:thread_id, integer(), enforce: true) 23 | end 24 | 25 | @doc false 26 | @spec schematic() :: SchematicV.t() 27 | def schematic() do 28 | schema(__MODULE__, %{ 29 | {"targetId", :target_id} => int(), 30 | {"threadId", :thread_id} => int() 31 | }) 32 | end 33 | end 34 | -------------------------------------------------------------------------------- /apps/debug_adapter/lib/protocol/dap/structures/scopes_arguments.ex: -------------------------------------------------------------------------------- 1 | # codegen: do not edit 2 | 3 | defmodule GenDAP.Structures.ScopesArguments do 4 | @moduledoc """ 5 | Arguments for `scopes` request. 6 | """ 7 | 8 | import SchematicV, warn: false 9 | 10 | use TypedStruct 11 | 12 | @doc """ 13 | ## Fields 14 | 15 | * frame_id: Retrieve the scopes for the stack frame identified by `frameId`. The `frameId` must have been obtained in the current suspended state. See 'Lifetime of Object References' in the Overview section for details. 16 | """ 17 | 18 | typedstruct do 19 | @typedoc "A type defining DAP structure ScopesArguments" 20 | field(:frame_id, integer(), enforce: true) 21 | end 22 | 23 | @doc false 24 | @spec schematic() :: SchematicV.t() 25 | def schematic() do 26 | schema(__MODULE__, %{ 27 | {"frameId", :frame_id} => int() 28 | }) 29 | end 30 | end 31 | -------------------------------------------------------------------------------- /apps/language_server/lib/language_server/lsp/protocol/structures/did_save_notebook_document_params.ex: -------------------------------------------------------------------------------- 1 | # codegen: do not edit 2 | defmodule GenLSP.Structures.DidSaveNotebookDocumentParams do 3 | @moduledoc """ 4 | The params sent in a save notebook document notification. 5 | 6 | @since 3.17.0 7 | """ 8 | 9 | import SchematicV, warn: false 10 | 11 | use TypedStruct 12 | 13 | @doc """ 14 | ## Fields 15 | 16 | * notebook_document: The notebook document that got saved. 17 | """ 18 | 19 | typedstruct do 20 | field(:notebook_document, GenLSP.Structures.NotebookDocumentIdentifier.t(), enforce: true) 21 | end 22 | 23 | @doc false 24 | @spec schematic() :: SchematicV.t() 25 | def schematic() do 26 | schema(__MODULE__, %{ 27 | {"notebookDocument", :notebook_document} => 28 | GenLSP.Structures.NotebookDocumentIdentifier.schematic() 29 | }) 30 | end 31 | end 32 | -------------------------------------------------------------------------------- /apps/language_server/lib/language_server/lsp/protocol/structures/versioned_notebook_document_identifier.ex: -------------------------------------------------------------------------------- 1 | # codegen: do not edit 2 | defmodule GenLSP.Structures.VersionedNotebookDocumentIdentifier do 3 | @moduledoc """ 4 | A versioned notebook document identifier. 5 | 6 | @since 3.17.0 7 | """ 8 | 9 | import SchematicV, warn: false 10 | 11 | use TypedStruct 12 | 13 | @doc """ 14 | ## Fields 15 | 16 | * version: The version number of this notebook document. 17 | * uri: The notebook document's uri. 18 | """ 19 | 20 | typedstruct do 21 | field(:version, integer(), enforce: true) 22 | field(:uri, GenLSP.BaseTypes.uri(), enforce: true) 23 | end 24 | 25 | @doc false 26 | @spec schematic() :: SchematicV.t() 27 | def schematic() do 28 | schema(__MODULE__, %{ 29 | {"version", :version} => int(), 30 | {"uri", :uri} => str() 31 | }) 32 | end 33 | end 34 | -------------------------------------------------------------------------------- /mix.exs: -------------------------------------------------------------------------------- 1 | defmodule ElixirLS.Mixfile do 2 | use Mix.Project 3 | 4 | def project do 5 | [ 6 | apps_path: "apps", 7 | aliases: aliases(), 8 | build_embedded: Mix.env() == :prod, 9 | start_permanent: Mix.env() == :prod, 10 | build_per_environment: false, 11 | deps: deps(), 12 | elixir: ">= 1.13.0", 13 | dialyzer: [ 14 | plt_add_apps: [:dialyxir_vendored, :debugger, :dialyzer, :ex_unit, :hex, :mix], 15 | flags: [ 16 | # enable only to verify error handling 17 | # :unmatched_returns, 18 | :error_handling, 19 | :unknown, 20 | :underspecs, 21 | :extra_return, 22 | :missing_return 23 | ] 24 | ] 25 | ] 26 | end 27 | 28 | defp deps do 29 | [] 30 | end 31 | 32 | defp aliases do 33 | [ 34 | test: "cmd mix test" 35 | ] 36 | end 37 | end 38 | -------------------------------------------------------------------------------- /apps/debug_adapter/test/output_test.exs: -------------------------------------------------------------------------------- 1 | defmodule ElixirLS.DebugAdapter.OutputTest do 2 | use ExUnit.Case, async: true 3 | import ElixirLS.DebugAdapter.Protocol.Basic 4 | 5 | alias ElixirLS.DebugAdapter.Output 6 | 7 | setup do 8 | {:ok, capture} = ElixirLS.Utils.PacketCapture.start_link(self()) 9 | {:ok, output} = Output.start(:output_test) 10 | Process.group_leader(output, capture) 11 | 12 | on_exit(fn -> 13 | if Process.alive?(output), do: GenServer.stop(output) 14 | end) 15 | 16 | {:ok, %{output: output}} 17 | end 18 | 19 | test "error response uses provided id", %{output: output} do 20 | req = request(1, "cmd") 21 | Output.send_error_response(output, req, 42, "err", "fmt", %{}, false, false) 22 | 23 | assert_receive %{ 24 | "body" => %{"error" => %{"id" => 42}}, 25 | "seq" => 1, 26 | "request_seq" => 1 27 | } 28 | end 29 | end 30 | -------------------------------------------------------------------------------- /scripts/debug_adapter.bat: -------------------------------------------------------------------------------- 1 | @echo off & setlocal enabledelayedexpansion 2 | 3 | SET ELS_MODE=debug_adapter 4 | 5 | IF EXIST "%APPDATA%\elixir_ls\setup.bat" ( 6 | ECHO "" | CALL "%APPDATA%\elixir_ls\setup.bat" > nul 7 | IF %ERRORLEVEL% NEQ 0 EXIT 1 8 | ) 9 | 10 | @REM Unset MIX_OS_DEPS_COMPILE_PARTITION_COUNT as it pollutes stdout 11 | @REM breaking LSP protocol. See https://github.com/elixir-lsp/elixir-ls/issues/1195 12 | SET MIX_OS_DEPS_COMPILE_PARTITION_COUNT= 13 | 14 | SET MIX_ENV=prod 15 | @REM pipe echo to avoid passing protocol messages to quiet install command 16 | @REM intercept stdout 17 | @REM elixir is a batch script and needs to be called 18 | ECHO "" | CALL elixir "%~dp0quiet_install.exs" > nul 19 | IF %ERRORLEVEL% NEQ 0 EXIT 1 20 | elixir %ELS_ELIXIR_OPTS% --erl "-kernel standard_io_encoding latin1 +sbwt none +sbwtdcpu none +sbwtdio none %ELS_ERL_OPTS%" "%~dp0launch.exs" 21 | -------------------------------------------------------------------------------- /apps/debug_adapter/lib/protocol/dap/structures/restart_frame_arguments.ex: -------------------------------------------------------------------------------- 1 | # codegen: do not edit 2 | 3 | defmodule GenDAP.Structures.RestartFrameArguments do 4 | @moduledoc """ 5 | Arguments for `restartFrame` request. 6 | """ 7 | 8 | import SchematicV, warn: false 9 | 10 | use TypedStruct 11 | 12 | @doc """ 13 | ## Fields 14 | 15 | * frame_id: Restart the stack frame identified by `frameId`. The `frameId` must have been obtained in the current suspended state. See 'Lifetime of Object References' in the Overview section for details. 16 | """ 17 | 18 | typedstruct do 19 | @typedoc "A type defining DAP structure RestartFrameArguments" 20 | field(:frame_id, integer(), enforce: true) 21 | end 22 | 23 | @doc false 24 | @spec schematic() :: SchematicV.t() 25 | def schematic() do 26 | schema(__MODULE__, %{ 27 | {"frameId", :frame_id} => int() 28 | }) 29 | end 30 | end 31 | -------------------------------------------------------------------------------- /apps/language_server/lib/language_server/lsp/protocol/structures/execution_summary.ex: -------------------------------------------------------------------------------- 1 | # codegen: do not edit 2 | defmodule GenLSP.Structures.ExecutionSummary do 3 | import SchematicV, warn: false 4 | 5 | use TypedStruct 6 | 7 | @doc """ 8 | ## Fields 9 | 10 | * execution_order: A strict monotonically increasing value 11 | indicating the execution order of a cell 12 | inside a notebook. 13 | * success: Whether the execution was successful or 14 | not if known by the client. 15 | """ 16 | 17 | typedstruct do 18 | field(:execution_order, GenLSP.BaseTypes.uinteger(), enforce: true) 19 | field(:success, boolean()) 20 | end 21 | 22 | @doc false 23 | @spec schematic() :: SchematicV.t() 24 | def schematic() do 25 | schema(__MODULE__, %{ 26 | {"executionOrder", :execution_order} => int(), 27 | optional({"success", :success}) => bool() 28 | }) 29 | end 30 | end 31 | -------------------------------------------------------------------------------- /apps/language_server/lib/language_server/lsp/protocol/structures/show_message_request_client_capabilities.ex: -------------------------------------------------------------------------------- 1 | # codegen: do not edit 2 | defmodule GenLSP.Structures.ShowMessageRequestClientCapabilities do 3 | @moduledoc """ 4 | Show message request client capabilities 5 | """ 6 | 7 | import SchematicV, warn: false 8 | 9 | use TypedStruct 10 | 11 | @doc """ 12 | ## Fields 13 | 14 | * message_action_item: Capabilities specific to the `MessageActionItem` type. 15 | """ 16 | 17 | typedstruct do 18 | field(:message_action_item, map()) 19 | end 20 | 21 | @doc false 22 | @spec schematic() :: SchematicV.t() 23 | def schematic() do 24 | schema(__MODULE__, %{ 25 | optional({"messageActionItem", :message_action_item}) => 26 | map(%{ 27 | optional({"additionalPropertiesSupport", :additional_properties_support}) => bool() 28 | }) 29 | }) 30 | end 31 | end 32 | -------------------------------------------------------------------------------- /apps/language_server/lib/language_server/providers/code_mod/ast.ex: -------------------------------------------------------------------------------- 1 | defmodule ElixirLS.LanguageServer.Providers.CodeMod.Ast do 2 | alias ElixirLS.LanguageServer.SourceFile 3 | 4 | @type source :: SourceFile.t() | String.t() 5 | @type t :: 6 | atom() 7 | | binary() 8 | | [any()] 9 | | number() 10 | | {any(), any()} 11 | | {atom() | {any(), [any()], atom() | [any()]}, Keyword.t(), atom() | [any()]} 12 | 13 | @spec from(source() | String.t()) :: {:ok, t()} | :error 14 | def from(%SourceFile{text: text}) do 15 | from(text) 16 | end 17 | 18 | def from(text) when is_binary(text) do 19 | case ElixirSense.string_to_quoted(text, {1, 1}) do 20 | {:ok, ast} -> {:ok, ast} 21 | _ -> :error 22 | end 23 | end 24 | 25 | @spec to_string(t()) :: String.t() 26 | def to_string(ast) do 27 | Macro.to_string(ast) 28 | end 29 | end 30 | -------------------------------------------------------------------------------- /apps/debug_adapter/lib/protocol/dap/structures/attach_request_arguments.ex: -------------------------------------------------------------------------------- 1 | # codegen: do not edit 2 | 3 | defmodule GenDAP.Structures.AttachRequestArguments do 4 | @moduledoc """ 5 | Arguments for `attach` request. Additional attributes are implementation specific. 6 | """ 7 | 8 | import SchematicV, warn: false 9 | 10 | @typedoc "A type defining DAP structure AttachRequestArguments" 11 | @type t() :: %{ 12 | optional(:__restart) => 13 | list() | boolean() | integer() | nil | number() | map() | String.t(), 14 | optional(String.t()) => any() 15 | } 16 | 17 | @doc false 18 | @spec schematic() :: SchematicV.t() 19 | def schematic() do 20 | all([ 21 | map(%{ 22 | optional({"__restart", :__restart}) => 23 | oneof([list(), bool(), int(), nil, oneof([int(), float()]), map(), str()]) 24 | }), 25 | map() 26 | ]) 27 | end 28 | end 29 | -------------------------------------------------------------------------------- /scripts/elixir_check.bat: -------------------------------------------------------------------------------- 1 | @echo off & setlocal enabledelayedexpansion 2 | 3 | SET ELS_MODE=elixir_check 4 | 5 | IF EXIST "%APPDATA%\elixir_ls\setup.bat" ( 6 | ECHO "" | CALL "%APPDATA%\elixir_ls\setup.bat" > nul 7 | IF %ERRORLEVEL% NEQ 0 EXIT 1 8 | ) 9 | 10 | @REM Unset MIX_OS_DEPS_COMPILE_PARTITION_COUNT as it pollutes stdout 11 | @REM breaking LSP protocol. See https://github.com/elixir-lsp/elixir-ls/issues/1195 12 | SET MIX_OS_DEPS_COMPILE_PARTITION_COUNT= 13 | 14 | SET MIX_ENV=prod 15 | @REM pipe echo to avoid passing protocol messages to quiet install command 16 | @REM intercept stdout and stderr 17 | @REM elixir is a batch script and needs to be called 18 | ECHO "" | CALL elixir "%~dp0quiet_install.exs" >nul 19 | IF %ERRORLEVEL% NEQ 0 EXIT 1 20 | elixir %ELS_ELIXIR_OPTS% --erl "-kernel standard_io_encoding latin1 +sbwt none +sbwtdcpu none +sbwtdio none %ELS_ERL_OPTS%" "%~dp0launch.exs" 21 | --------------------------------------------------------------------------------