diff --git a/.devcontainer/Readme.md b/.devcontainer/Readme.md deleted file mode 100644 index aedd08ae7..000000000 --- a/.devcontainer/Readme.md +++ /dev/null @@ -1,13 +0,0 @@ -## Using VSCode devcontainers - -Official tutorial: https://code.visualstudio.com/docs/devcontainers/tutorial - -### Recommended Settings for macOS - -Some of these are defaults: - - Recommended settings for macOS (some of these are defaults): - - General: - - "Choose file sharing implementation for your containers": VirtioFS (better IO performance) - - Resources: - - CPUs: Allow docker to use most or all of your CPUs - - Memory: Allow docker to use most or all of your memory diff --git a/.github/PULL_REQUEST_TEMPLATE/release_branch.md b/.github/PULL_REQUEST_TEMPLATE/release_branch.md new file mode 100644 index 000000000..b64dadbef --- /dev/null +++ b/.github/PULL_REQUEST_TEMPLATE/release_branch.md @@ -0,0 +1,7 @@ +* **Explanation**: +* **Scope**: +* **Issue**: +* **Original PR**: +* **Risk**: +* **Testing**: +* **Reviewer**: diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 9f01e1f3b..1f98e5a7d 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,11 +1,166 @@ -By submitting a pull request, you represent that you have the right to license -your contribution to Apple and the community, and agree by submitting the patch -that your contributions are licensed under the [Swift -license](https://swift.org/LICENSE.txt). +# Contributing ---- +This document contains notes about development and testing of SourceKit-LSP. -Before submitting the pull request, please make sure you have [tested your -changes](https://github.com/apple/swift/blob/main/docs/ContinuousIntegration.md) -and that they follow the Swift project [guidelines for contributing -code](https://swift.org/contributing/#contributing-code). +## Building & Testing + +SourceKit-LSP is a SwiftPM package, so you can build and test it using anything that supports packages - opening in Xcode, Visual Studio Code with [Swift for Visual Studio Code](https://marketplace.visualstudio.com/items?itemName=sswg.swift-lang) installed, or through the command line using `swift build` and `swift test`. See below for extra instructions for Linux and Windows + +SourceKit-LSP builds with the latest released Swift version and all its tests pass or, if unsupported by the latest Swift version, are skipped. Using the `main` development branch of SourceKit-LSP with an older Swift versions is not supported. + +> [!TIP] +> SourceKit-LSP’s logging is usually very useful to debug test failures. On macOS these logs are written to the system log by default. To redirect them to stderr, build SourceKit-LSP with the `SOURCEKITLSP_FORCE_NON_DARWIN_LOGGER` environment variable set to `1`: +> - In VS Code: Add the following to your `settings.json`: +> ```json +> "swift.swiftEnvironmentVariables": { "SOURCEKITLSP_FORCE_NON_DARWIN_LOGGER": "1" }, +> ``` +> - In Xcode +> 1. Product -> Scheme -> Edit Scheme… +> 2. Select the Arguments tab in the Run section +> 3. Add a `SOURCEKITLSP_FORCE_NON_DARWIN_LOGGER` environment variable with value `1` +> - On the command line: Set the `SOURCEKITLSP_FORCE_NON_DARWIN_LOGGER` environment variable to `1` when running tests, e.g by running `SOURCEKITLSP_FORCE_NON_DARWIN_LOGGER=1 swift test --parallel` + +> [!TIP] +> Other useful environment variables during test execution are: +> - `SKIP_LONG_TESTS`: Skips tests that usually take longer than 1 second to execute. This significantly speeds up test time, especially with `swift test --parallel` +> - `SOURCEKITLSP_KEEP_TEST_SCRATCH_DIR`: Does not delete the temporary files created during test execution. Allows inspection of the test projects after the test finishes. + +### Linux + +The following dependencies of SourceKit-LSP need to be installed on your system +- libsqlite3-dev libncurses5-dev python3 + +You need to add `/usr/lib/swift` and `/usr/lib/swift/Block` C++ search paths to your `swift build` invocation that SourceKit-LSP’s dependencies build correctly. Assuming that your Swift toolchain is installed to `/`, the build command is + +```sh +$ swift build -Xcxx -I/usr/lib/swift -Xcxx -I/usr/lib/swift/Block +``` + +### Windows + +You must provide the following dependencies for SourceKit-LSP: +- SQLite3 ninja + +```cmd +> swift build -Xcc -I -Xlinker -L -Xcc -I%SDKROOT%\usr\include -Xcc -I%SDKROOT%\usr\include\Block +``` + +The header and library search paths must be passed to the build by absolute path. This allows the clang importer and linker to find the dependencies. + +Additionally, as SourceKit-LSP depends on libdispatch and the Blocks runtime, which are part of the SDK, but not in the default search path, need to be explicitly added. + +### Devcontainer + +You can develop SourceKit-LSP inside a devcontainer, which is essentially a Linux container that has all of SourceKit-LSP’s dependencies pre-installed. The [official tutorial](https://code.visualstudio.com/docs/devcontainers/tutorial) contains information of how to set up devcontainers in VS Code. + +Recommended Docker settings for macOS are: +- General + - "Choose file sharing implementation for your containers": VirtioFS (better IO performance) +- Resources + - CPUs: Allow docker to use most or all of your CPUs + - Memory: Allow docker to use most or all of your memory + +## Using a locally-built sourcekit-lsp in an editor + +If you want test your changes to SourceKit-LSP inside your editor, you can point it to your locally-built `sourcekit-lsp` executable. The exact steps vary by editor. For VS Code, you can add the following to your `settings.json`. + +```json +"swift.sourcekit-lsp.serverPath": "/path/to/sourcekit-lsp/.build/arm64-apple-macosx/debug/sourcekit-lsp", +``` + +> [!TIP] +> The easiest way to debug SourceKit-LSP is usually to write a test case that reproduces the behavior and then debug that. If that’s not possible, you can attach LLDB to the sourcekit-lsp launched by your and set breakpoints to debug. To do so on the command line, run +> ```bash +> $ lldb --wait-for --attach-name sourcekit-lsp +> ``` +> +> If you are developing SourceKit-LSP in Xcode, go to Debug -> Attach to Process by PID or Name. + +## Selecting a Toolchain + +When SourceKit-LSP is installed as part of a toolchain, it finds the Swift version to use relative to itself. When building SourceKit-LSP locally, it picks a default toolchain on your system, which usually corresponds to the toolchain that is used if you invoke `swift` without any specified path. + +To adjust the toolchain that should be used by SourceKit-LSP (eg. because you want to use new `sourcekitd` features that are only available in a Swift open source toolchain snapshot but not your default toolchain), set the `SOURCEKIT_TOOLCHAIN_PATH` environment variable to your toolchain when running SourceKit-LSP. + +## Logging + +SourceKit-LSP has extensive logging to the system log on macOS and to `/var/logs/sourcekit-lsp` or stderr on other platforms. + +To show the logs on macOS, run +```sh +log show --last 1h --predicate 'subsystem CONTAINS "org.swift.sourcekit-lsp"' --info --debug +``` +Or to stream the logs as they are produced: +``` +log stream --predicate 'subsystem CONTAINS "org.swift.sourcekit-lsp"' --level debug +``` + +SourceKit-LSP masks data that may contain private information such as source file names and contents by default. To enable logging of this information, run + +```sh +sudo log config --subsystem org.swift.sourcekit-lsp --mode private_data:on +``` + +To enable more verbose logging on non-macOS platforms, launch sourcekit-lsp with the `SOURCEKITLSP_LOG_LEVEL` environment variable set to `debug`. + + +## Formatting + +SourceKit-LSP is formatted using [swift-format](http://github.com/apple/swift-format) to ensure a consistent style. + +To format your changes run the formatter using the following command +```bash +swift package format-source-code +``` + +If you are developing SourceKit-LSP in VS Code, you can also run the *Run swift-format* task from *Tasks: Run tasks* in the command palette. + +## Authoring commits + +Prefer to squash the commits of your PR (*pull request*) and avoid adding commits like “Address review comments”. This creates a clearer git history, which doesn’t need to record the history of how the PR evolved. + +We prefer to not squash commits when merging a PR because, especially for larger PRs, it sometimes makes sense to split the PR into multiple self-contained chunks of changes. For example, a PR might do a refactoring first before adding a new feature or fixing a bug. This separation is useful for two reasons: +- During review, the commits can be reviewed individually, making each review chunk smaller +- In case this PR introduced a bug that is identified later, it is possible to check if it resulted from the refactoring or the actual change, thereby making it easier find the lines that introduce the issue. + +## Opening a PR + +To submit a PR you don't need permissions on this repo, instead you can fork the repo and create a PR through your forked version. + +For more information and instructions, read the GitHub docs on [forking a repo](https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/working-with-forks/fork-a-repo). + +Once you've pushed your branch, you should see an option on this repository's page to create a PR from a branch in your fork. + +## Opening a PR for Release Branch + +In order for a pull request to be considered for inclusion in a release branch (e.g. `release/6.0`) after it has been cut, it must meet the following requirements: + +1. The title of the PR should start with the tag `[{swift version number}]`. For example, `[6.0]` for the Swift 6.0 release branch. + +1. The PR description must include the following information: + + ```md + * **Explanation**: A description of the issue being fixed or enhancement being made. This can be brief, but it should be clear. + * **Scope**: An assessment of the impact/importance of the change. For example, is the change a source-breaking language change, etc. + * **Issue**: The GitHub Issue link if the change fixes/implements an issue/enhancement. + * **Original PR**: Pull Request link from the `main` branch. + * **Risk**: What is the (specific) risk to the release for taking this change? + * **Testing**: What specific testing has been done or needs to be done to further validate any impact of this change? + * **Reviewer**: One or more code owners for the impacted components should review the change. Technical review can be delegated by a code owner or otherwise requested as deemed appropriate or useful. + ``` + +> [!TIP] +> The PR description can be generated using the [release_branch.md](https://github.com/apple/swift-syntax/blob/main/.github/PULL_REQUEST_TEMPLATE/release_branch.md) [pull request template](https://docs.github.com/en/communities/using-templates-to-encourage-useful-issues-and-pull-requests/about-issue-and-pull-request-templates). To use this template when creating a PR, you need to add the query parameter: +> ``` +> ?expand=1&template=release_branch.md +> ``` +> to the PR URL, as described in the [GitHub documentation on using query parameters to create a pull request](https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/proposing-changes-to-your-work-with-pull-requests/using-query-parameters-to-create-a-pull-request). +> This is necessary because GitHub does not currently provide a UI to choose a PR template. + +All changes going into a release branch must go through pull requests that are approved and merged by the corresponding release manager. + +## Review and CI Testing + +After you opened your PR, a maintainer will review it and test your changes in CI (*Continuous Integration*) by adding a `@swift-ci Please test` comment on the pull request. Once your PR is approved and CI has passed, the maintainer will merge your pull request. + +Only contributors with [commit access](https://www.swift.org/contributing/#commit-access) are able to approve pull requests and trigger CI. diff --git a/Documentation/Client_Development.md b/Documentation/Client_Development.md deleted file mode 100644 index fda88644f..000000000 --- a/Documentation/Client_Development.md +++ /dev/null @@ -1,16 +0,0 @@ -# Build a SourceKit-LSP Client - -Here are some critical hints that may help developers of editors or language plugins in adopting SourceKit-LSP: - -* Remember that SourceKit-LSP is at an early stage: - * It is [not yet](https://forums.swift.org/t/what-does-sourcekit-lsp-support/54424) a complete or necessarily accurate reflection of the LSP. - * Logs from `stdErr` may be insufficient for debugging your interaction with `sourcekit-lsp`. - * [Currently](https://github.com/apple/sourcekit-lsp/issues/529), you have to [open a document](https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#textDocument_didOpen) before sending document-based requests. -* You can use `sourcekit-lsp` with Swift packages but [not (yet) with Xcode projects](https://forums.swift.org/t/xcode-project-support/20927). -* [Don't](https://forums.swift.org/t/how-do-you-build-a-sandboxed-editor-that-uses-sourcekit-lsp/40906) attempt to use `sourcekit-lsp` in [a sandboxed context](https://developer.apple.com/documentation/xcode/configuring-the-macos-app-sandbox): - * As with most developer tooling, `sourcekit-lsp` relies on other system- and language tools that it would not be allowed to access from within an app sandbox. -* Strictly adhere to the format specification of LSP packets, including their [header- and content part](https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#headerPart). -* Piece LSP packets together from the `stdOut` data: - * `sourcekit-lsp` outputs LSP packets to `stdOut`, but: Single chunks of data output do not correspond to single packets. `stdOut` rather delivers a stream of data. You have to buffer that stream in some form and detect individual LSP packets in it. -* Provide the current system environment variables to `sourcekit-lsp`: - * `sourcekit-lsp` must read some current environment variables of the system, so [don't wipe them all out](https://forums.swift.org/t/making-a-sourcekit-lsp-client-find-references-fails-solved/57426) when providing modified or additional variables. diff --git a/Documentation/Development.md b/Documentation/Development.md deleted file mode 100644 index ce3cfbb96..000000000 --- a/Documentation/Development.md +++ /dev/null @@ -1,136 +0,0 @@ -# Development - -This document contains notes about development and testing of SourceKit-LSP. - -## Table of Contents - -* [Getting Started Developing SourceKit-LSP](#getting-started-developing-sourcekit-lsp) -* [Building SourceKit-LSP](#building-sourcekit-lsp) -* [Toolchains](#toolchains) -* [Debugging](#debugging) -* [Writing Tests](#writing-tests) - -## Getting Started Developing SourceKit-LSP - -For maximum compatibility with toolchain components such as the Swift Package Manager, the only supported way to develop SourceKit-LSP is with the latest toolchain snapshot. We make an effort to keep the build and tests working with the latest release of Swift, but this is not always possible. - -1. Install the latest "Trunk Development (main)" toolchain snapshot from https://swift.org/download/#snapshots. **If you're looking for swift-5.x**, use the `swift-5.x-branch` of SourceKit-LSP with the latest swift-5.x toolchain snapshot. See [Toolchains](#toolchains) for more information. - -2. Build the language server executable `sourcekit-lsp` using `swift build`. See [Building](#building-sourcekit-lsp) for more information. - -3. Configure your editor to use the newly built `sourcekit-lsp` executable and the toolchain snapshot. See [Editors](../Editors) for more information about editor integration. - -4. Build the project you are editing with `swift build` using the toolchain snapshot. The language server depends on the build to provide module dependencies and to update the global index. - -## Building SourceKit-LSP - -Install the latest snapshot from https://swift.org/download/#snapshots. SourceKit-LSP builds with the latest toolchain snapshot of the corresponding branch (e.g. to build the *main* branch, use the latest *main* snapshot of the toolchain). See [Toolchains](#toolchains) for more information about supported toolchains. - -SourceKit-LSP is built using the [Swift Package Manager](https://github.com/apple/swift-package-manager). For a standard debug build on the command line: - -### macOS - -```sh -$ export TOOLCHAINS=swift -$ swift package update -$ swift build -``` - -### Linux - -Install the following dependencies of SourceKit-LSP: - -* libsqlite3-dev libncurses5-dev python3 - -```sh -$ swift package update -$ swift build -Xcxx -I/usr/lib/swift -Xcxx -I/usr/lib/swift/Block -``` - -After building, the server will be located at `.build/debug/sourcekit-lsp`, or a similar path, if you passed any custom options to `swift build`. Editors will generally need to be provided with this path in order to run the newly built server - see [Editors](../Editors) for more information about configuration. - -SourceKit-LSP is designed to build against the latest SwiftPM, so if you run into any issue make sure you have the most up-to-date dependencies by running `swift package update`. - -### Windows - -The user must provide the following dependencies for SourceKit-LSP: -- SQLite3 -- ninja - -```cmd -> swift build -Xcc -I -Xlinker -L -Xcc -I%SDKROOT%\usr\include -Xcc -I%SDKROOT%\usr\include\Block -``` - -The header and library search paths must be passed to the build by absolute -path. This allows the clang importer and linker to find the dependencies. - -Additionally, as SourceKit-LSP depends on libdispatch and the Blocks runtime, -which are part of the SDK, but not in the default search path, need to be -explicitly added. - -### Docker - -SourceKit-LSP should run out of the box using the [Swift official Docker images](https://swift.org/download/#docker). To build `sourcekit-lsp` from source and run its test suite, follow the steps in the *Linux* section. In the official docker images, the toolchain is located at `/`. - -If you are seeing slow compile times, you will most likely need to increase the memory available to the Docker container. - -## Toolchains - -SourceKit-LSP depends on tools such as `sourcekitd` and `clangd`, which it loads at runtime from an installed toolchain. - -### Recommended Toolchain - -Use the latest toolchain snapshot from https://swift.org/download/#snapshots. SourceKit-LSP is designed to be used with the latest toolchain snapshot of the corresponding branch. - -| SourceKit-LSP branch | Toolchain | -|:---------------------|:----------| -| main | Trunk Development (main) | -| swift-5.2-branch | Swift 5.2 Development | -| swift-5.1-branch | Swift 5.1.1+ | - -*Note*: there is no branch of SourceKit-LSP that supports Swift 5.0. - -### Selecting the Toolchain - -After installing the toolchain, SourceKit-LSP needs to know the path to the toolchain. - -* On macOS, the toolchain is installed in `/Library/Developer/Toolchains/` with an `.xctoolchain` extension. The most recently installed toolchain is symlinked as `/Library/Developer/Toolchains/swift-latest.xctoolchain`. If you opted to install for the current user only in the installer, the same paths will be under the home directory, e.g. `~/Library/Developer/Toolchains/`. - -* On Linux, the toolchain is wherever the snapshot's `.tar.gz` file was extracted. - -Your editor may have a way to configure the toolchain path directly via a configuration setting, or it may allow you to override the process environment variables used when launching `sourcekit-lsp`. See [Editors](../Editors) for more information. - -Otherwise, the simplest way to configure the toolchain is to set the following environment variable to the absolute path of the toolchain. - -```sh -SOURCEKIT_TOOLCHAIN_PATH= -``` - -## Debugging - -You can attach LLDB to SourceKit-LSP and set breakpoints to debug. You may want to instruct LLDB to wait for the sourcekit-lsp process to launch and then start your editor, which will typically launch -SourceKit-LSP as soon as you open a Swift file: - -```sh -$ lldb -w -n sourcekit-lsp -``` - -If you are using the Xcode project, go to Debug, Attach to Process by PID or Name. - -### Print SourceKit Logs - -You can configure SourceKit-LSP to print log information from SourceKit to stderr by setting the following environment variable: - -```sh -SOURCEKIT_LOGGING="N" -``` - -Where "N" configures the log verbosity and is one of the following numbers: 0 (error), 1 (warning), 2 (info), or 3 (debug). - -## Writing Tests - -As much as is practical, all code should be covered by tests. New tests can be added under the `Tests` directory and should use `XCTest`. The rest of this section will describe the additional tools available in the `SKTestSupport` module to make it easier to write good and efficient tests. - -### Long tests - -Tests that run longer than approx. 1 second are only executed if the the `SOURCEKIT_LSP_ENABLE_LONG_TESTS` environment variable is set to `YES` or `1`. This, in particular, includes the crash recovery tests. diff --git a/Documentation/Editor Integration.md b/Documentation/Editor Integration.md new file mode 100644 index 000000000..43191cf52 --- /dev/null +++ b/Documentation/Editor Integration.md @@ -0,0 +1,56 @@ +# Editor Integration + +Most modern text editors support the [Language Server Protocol](https://microsoft.github.io/language-server-protocol/) (LSP) and many have support for Swift through SourceKit-LSP. https://www.swift.org/tools has a list of some popular editors and how to set them up. This page covers any editors not listed there. + +## BBEdit + +Support for LSP is built in to BBEdit 14.0 and later. + +If `sourcekit-lsp` is in your `$PATH` or is discoverable by using `xcrun --find sourcekit-lsp`, BBEdit will use it automatically. Otherwise you can manually configure BBEdit to use a suitable `sourcekit-lsp` as needed. + +You can read more about BBEdit's LSP support and configuration hints [here](https://www.barebones.com/support/bbedit/lsp-notes.html). + +## Sublime Text + +Before using SourceKit-LSP with Sublime Text, you will need to install the [LSP](https://packagecontrol.io/packages/LSP), [LSP-SourceKit](https://github.com/sublimelsp/LSP-SourceKit) and [Swift-Next](https://github.com/Swift-Next/Swift-Next) packages from Package Control. Then toggle the server on by typing in command palette `LSP: Enable Language Server Globally` or `LSP: Enable Language Server in Project`. + +## Theia Cloud IDE + +You can use SourceKit-LSP with Theia by using the `theiaide/theia-swift` image. To use the image you need to have [Docker](https://docs.docker.com/get-started/) installed first. + +The following command pulls the image and runs Theia IDE on http://localhost:3000 with the current directory as a workspace. + +```bash +$ docker run -it -p 3000:3000 -v "$(pwd):/home/project:cached" theiaide/theia-swift:next +``` + +You can pass additional arguments to Theia after the image name, for example to enable debugging: + +```bash +$ docker run -it -p 3000:3000 --expose 9229 -p 9229:9229 -v "$(pwd):/home/project:cached" theiaide/theia-swift:next --inspect=0.0.0.0:9229 +``` + +Image Variants +- `theiaide/theia-swift:latest`: This image is based on the latest stable released version. +- `theiaide/theia-swift:next`: This image is based on the nightly published version. + +The `theia-swift-docker` source is located at [theia-apps](https://github.com/theia-ide/theia-apps). + +## Other Editors + +SourceKit-LSP should work with any editor that supports the [Language Server Protocol](https://microsoft.github.io/language-server-protocol/) (LSP). Each editor has its own mechanism for configuring an LSP server, so consult your editor's documentation for the specifics. In general, you can configure your editor to use SourceKit-LSP for Swift, C, C++, Objective-C and Objective-C++ files; the editor will need to be configured to find the `sourcekit-lsp` executable from your installed Swift toolchain, which expects to communicate with the editor over `stdin` and `stdout`. + +## Building a new SourceKit-LSP Client + +If you are building a new SourceKit-LSP client for an editor, here are some critical hints that may help you. Some of these are general hints for development of an LSP client. + +- SourceKit-LSP has extensive logging. See the [Logging section in CONTRIBUTING.md](../CONTRIBUTING.md#logging) for more information. +- You have to [open a document](https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#textDocument_didOpen) before sending document-based requests. +- You can use SourceKit-LSP with Swift packages but [not (yet) with Xcode projects](https://forums.swift.org/t/xcode-project-support/20927). +- [Don't](https://forums.swift.org/t/how-do-you-build-a-sandboxed-editor-that-uses-sourcekit-lsp/40906) attempt to use Sourcekit-LSP in [a sandboxed context](https://developer.apple.com/documentation/xcode/configuring-the-macos-app-sandbox): + - As with most developer tooling, SourceKit-LSP relies on other system- and language tools that it would not be allowed to access from within an app sandbox. +- Strictly adhere to the format specification of LSP packets, including their [header- and content part](https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#headerPart). +- Piece LSP packets together from the stdout data: + - SourceKit-LSP outputs LSP packets to stdout, but: Single chunks of data output do not correspond to single packets. stdout rather delivers a stream of data. You have to buffer that stream in some form and detect individual LSP packets in it. +- Provide the current system environment variables to SourceKit-LSP: + - SourceKit-LSP must read some current environment variables of the system, so [don't wipe them all out](https://forums.swift.org/t/making-a-sourcekit-lsp-client-find-references-fails-solved/57426) when providing modified or additional variables. diff --git a/Documentation/Files_To_Reindex.md b/Documentation/Files To Reindex.md similarity index 100% rename from Documentation/Files_To_Reindex.md rename to Documentation/Files To Reindex.md diff --git a/Editors/README.md b/Editors/README.md deleted file mode 100644 index 5fece4076..000000000 --- a/Editors/README.md +++ /dev/null @@ -1,180 +0,0 @@ -# Editor Integration - -This document contains information about how to configure an editor to use SourceKit-LSP. If your editor is not listed below, but it supports the [Language Server Protocol](https://microsoft.github.io/language-server-protocol/) (LSP), see [Other Editors](#other-editors). - -In general, you will need to know where to find the `sourcekit-lsp` server executable. Some examples: - -* With Xcode 11.4+ - * `xcrun sourcekit-lsp` - run the server - * `xcrun --find sourcekit-lsp` - get the full path to the server -* Toolchain from Swift.org - * Linux - * You will find `sourcekit-lsp` in the `bin` directory of the toolchain. - * macOS - * `xcrun --toolchain swift sourcekit-lsp` - run the server - * `xcrun --toolchain swift --find sourcekit-lsp` - get the full path to the server -* Built from source - * `.build///sourcekit-lsp` - -## Visual Studio Code - -The [Swift for Visual Studio Code extension](https://marketplace.visualstudio.com/items?itemName=sswg.swift-lang) uses SourceKit-LSP for code completion, jump to definition and error annotations. Install the extension from the marketplace to add it to your VSCode environment. - -## Sublime Text - -Before using SourceKit-LSP with Sublime Text, you will need to install the [LSP](https://packagecontrol.io/packages/LSP), [LSP-SourceKit](https://github.com/sublimelsp/LSP-SourceKit) and [Swift-Next](https://github.com/Swift-Next/Swift-Next) packages from Package Control. Then toggle the server on by typing in command palette `LSP: Enable Language Server Globally` or `LSP: Enable Language Server in Project`. - -## Emacs - -There is an Emacs client for SourceKit-LSP in the [main Emacs LSP repository](https://github.com/emacs-lsp/lsp-sourcekit). - -## Vim 8 or Neovim - -All methods below assume `sourcekit-lsp` is in your `PATH`. If it's not then replace `sourcekit-lsp` with the absolute path to the sourcekit-lsp executable. - -### vim-lsp - -Install [vim-lsp](https://github.com/prabirshrestha/vim-lsp). In your `.vimrc`, configure vim-lsp to use sourcekit-lsp for Swift source files like so: - -```viml -if executable('sourcekit-lsp') - au User lsp_setup call lsp#register_server({ - \ 'name': 'sourcekit-lsp', - \ 'cmd': {server_info->['sourcekit-lsp']}, - \ 'whitelist': ['swift'], - \ }) -endif -``` - -In order for vim to recognize Swift files, you need to configure the filetype. Otherwise, `:LspStatus` will show that sourcekit-lsp is not running even if a Swift file is open. - -If you are already using a Swift plugin for vim, like [swift.vim](https://github.com/keith/swift.vim), this may be setup already. Otherwise, you can set the filetype manually: - -```viml -augroup filetype - au! BufRead,BufNewFile *.swift set ft=swift -augroup END -``` - -That's it! As a test, open a swift file, put cursor on top of a symbol in normal mode and -run `:LspDefinition`. More commands are documented [here](https://github.com/prabirshrestha/vim-lsp#supported-commands). - -There are many Vim solutions for code completion. For instance, you may want to use LSP for omnifunc: - -```viml -autocmd FileType swift setlocal omnifunc=lsp#complete -``` - -With this added in `.vimrc`, you can use `` in insert mode to trigger sourcekit-lsp completion. - -### coc.nvim - -With [coc.nvim installed](https://github.com/neoclide/coc.nvim#quick-start), the easiest is to use the [coc-sourcekit](https://github.com/klaaspieter/coc-sourcekit) plugin: - -```vim -:CocInstall coc-sourcekit -``` - -Alternatively open your coc config (`:CocConfig` in vim) and add: - -```json - "languageserver": { - "sourcekit-lsp": { - "filetypes": ["swift"], - "command": "sourcekit-lsp", - } - } -``` - -As a test, open a Swift file, put the cursor on top of a symbol in normal mode and run: - -``` -:call CocAction('jumpDefinition') -``` - -### Neovim 0.8 and above -since version 0.8, neovim has native LSP support, which can be used to connect to sourcekit-lsp directly. To do so, add the following to -a .lua config file (such as `lua/swift.lua`): - -```lua -require'lspconfig'.sourcekit.setup{ - cmd = {'$TOOLCHAIN_PATH/usr/bin/sourcekit-lsp'} -} -``` -where `$TOOLCHAIN_PATH` is the path to your active toolchain (for example, `/Library/Developer/Toolchains/swift-latest.xctoolchain`). This should enable -the lsp server directly, and you can test it by opening a swift file and running `:LspInfo`--you should get a window popping up saying "1 client attached to this buffer" and be able to do navigation and such. - -The default LSP commands are not bound to many keys, so it is also useful to create some keybindings to help with various LSP activities. Here are some -of the known lsp commands that work with `sourcekit-lsp`: - -```lua -vim.api.nvim_create_autocmd('LspAttach', { - group = vim.api.nvim_create_augroup('UserLspConfig', {}), - callback = function(ev) - --enable omnifunc completion - vim.bo[ev.buf].omnifunc = 'v:lua.vim.lsp.omnifunc' - - -- buffer local mappings - local opts = { buffer = ev.buf } - -- go to definition - vim.keymap.set('n','gd',vim.lsp.buf.definition,opts) - --puts doc header info into a float page - vim.keymap.set('n','K',vim.lsp.buf.hover,opts) - - -- workspace management. Necessary for multi-module projects - vim.keymap.set('n','wa',vim.lsp.buf.add_workspace_folder, opts) - vim.keymap.set('n','wr',vim.lsp.buf.remove_workspace_folder, opts) - vim.keymap.set('n','wl',function() - print(vim.inspect(vim.lsp.buf.list_workspace_folders())) - end,opts) - - -- add LSP code actions - vim.keymap.set({'n','v'},'ca',vim.lsp.buf.code_action,opts) - - -- find references of a type - vim.keymap.set('n','gr',vim.lsp.buf.references,opts) - end, -}) -``` - -Further information on neovim's LSP integration(including detailed information on configuration) can be found [in neovim's documentation](https://neovim.io/doc/user/lsp.html). - - -## Theia Cloud IDE - -You can use SourceKit-LSP with Theia by using the `theiaide/theia-swift` image. To use the image you need to have [Docker](https://docs.docker.com/get-started/) installed first. - -The following command pulls the image and runs Theia IDE on http://localhost:3000 with the current directory as a workspace. - - docker run -it -p 3000:3000 -v "$(pwd):/home/project:cached" theiaide/theia-swift:next - -You can pass additional arguments to Theia after the image name, for example to enable debugging: - - docker run -it -p 3000:3000 --expose 9229 -p 9229:9229 -v "$(pwd):/home/project:cached" theiaide/theia-swift:next --inspect=0.0.0.0:9229 - -Image Variants - -`theiaide/theia-swift:latest` -This image is based on the latest stable released version. - -`theiaide/theia-swift:next` -This image is based on the nightly published version. - -theia-swift-docker source [theia-apps](https://github.com/theia-ide/theia-apps) - -## BBEdit - -Support for LSP is built in to BBEdit 14.0 and later. - -If `sourcekit-lsp` is in your `$PATH` or is discoverable by using `xcrun --find sourcekit-lsp`, BBEdit will use it automatically. Otherwise you can manually configure BBEdit to use a suitable `sourcekit-lsp` as needed. - -You can read more about BBEdit's LSP support and configuration hints [here](https://www.barebones.com/support/bbedit/lsp-notes.html). - -## Other Editors - -SourceKit-LSP should work with any editor that supports the [Language Server Protocol](https://microsoft.github.io/language-server-protocol/) -(LSP). Each editor has its own mechanism for configuring an LSP server, so consult your editor's -documentation for the specifics. In general, you can configure your editor to use SourceKit-LSP for -Swift, C, C++, Objective-C and Objective-C++ files; the editor will need to be configured to find -the `sourcekit-lsp` executable (see the top-level [README](https://github.com/apple/sourcekit-lsp) for build instructions), which -expects to communicate with the editor over `stdin` and `stdout`. diff --git a/README.md b/README.md index e3c8a87c2..f9537b471 100644 --- a/README.md +++ b/README.md @@ -1,60 +1,18 @@ # SourceKit-LSP -SourceKit-LSP is an implementation of the [Language Server Protocol](https://microsoft.github.io/language-server-protocol/) (LSP) for Swift and C-based languages. It provides features like code-completion and jump-to-definition to editors that support LSP. SourceKit-LSP is built on top of [sourcekitd](https://github.com/apple/swift/tree/main/tools/SourceKit) and [clangd](https://clang.llvm.org/extra/clangd.html) for high-fidelity language support, and provides a powerful source code index as well as cross-language support. SourceKit-LSP supports projects that use the Swift Package Manager. +SourceKit-LSP is an implementation of the [Language Server Protocol](https://microsoft.github.io/language-server-protocol/) (LSP) for Swift and C-based languages. It provides intelligent editor functionality like code-completion and jump-to-definition to editors that support LSP. SourceKit-LSP is built on top of [sourcekitd](https://github.com/apple/swift/tree/main/tools/SourceKit) and [clangd](https://clang.llvm.org/extra/clangd.html) for high-fidelity language support, and provides a powerful source code index as well as cross-language support. SourceKit-LSP supports projects that use the Swift Package Manager and projects that generate a `compile_commands.json` file, such as CMake. ## Getting Started -The SourceKit-LSP server is included with the Swift toolchain. Depending on how you installed Swift, you may already have SourceKit-LSP. Make sure you build your package with the same toolchain as you use sourcekit-lsp from to ensure compatibility. +https://www.swift.org/tools has a list of popular editors that support LSP and can thus be hooked up to SourceKit-LSP to provide intelligent editor functionality as well as set-up guides. -1. Get SourceKit-LSP with a Swift toolchain +## Reporting Issues - 1. If you have installed Xcode 11.4+ or the corresponding Command Line Tools package, the SourceKit-LSP server is included and can be run with `xcrun sourcekit-lsp`. +If you should hit any issues while using SwiftSyntax, we appreciate bug reports on [GitHub Issue](https://github.com/apple/swift-syntax/issues). - 2. If you are using a [toolchain from Swift.org](https://swift.org/download/), the SourceKit-LSP server is included and can be run with `xcrun --toolchain swift sourcekit-lsp` on macOS, or using the full path to the `sourcekit-lsp` executable on Linux. +> [!IMPORTANT] +> SourceKit-LSP does not update its global index in the background or build Swift modules in the background. Thus, a lot of cross-module or global functionality is limited if the project hasn't been built recently. To update the index or rebuild the Swift modules, build the project. - 3. If your toolchain did not come with SourceKit-LSP, see [Development](Documentation/Development.md) for how to build it from source. +## Contributing -2. Configure your editor to use SourceKit-LSP. See [Editors](Editors) for more information about editor integration. - -3. Build the project you are working on with `swift build` using the same toolchain as the SourceKit-LSP server. The language server depends on the build to provide module dependencies and to update the global index. - -## Development - -For more information about developing SourceKit-LSP itself, see [Development](Documentation/Development.md). For information about developing SourceKit-LSP clients (like editors or their language plugins), see [Client Development](Documentation/Client_Development.md). - -## Indexing While Building - -SourceKit-LSP uses a global index called [IndexStoreDB](https://github.com/apple/indexstore-db) to provide features that cross file or module boundaries, such as jump-to-definition or find-references. To efficiently create an index of your source code we use a technique called "indexing while building". When the project is compiled for debugging using `swift build`, the compiler (swiftc or clang) automatically produces additional raw index data that is read by our indexer. Producing this information during compilation saves work and ensures that any time the project is built the index is updated and fully accurate. - -In the future we intend to also provide automatic background indexing so that we can update the index in between builds or to include code that's not always built like unit tests. In the meantime, building your project should bring our index up to date. - -## Status - -SourceKit-LSP is still in early development, so you may run into rough edges with any of the features. The following table shows the status of various features when using the latest development toolchain snapshot. See [Caveats](#caveats) for important known issues you may run into. - -| Feature | Status | Notes | -|---------|:------:|-------| -| Swift | ✅ | | -| C/C++/ObjC | ✅ | Uses [clangd](https://clangd.llvm.org/) | -| Code completion | ✅ | | -| Quick Help (Hover) | ✅ | | -| Diagnostics | ✅ | | -| Fix-its | ✅ | | -| Jump to Definition | ✅ | | -| Find References | ✅ | | -| Background Indexing | ❌ | Build project to update the index using [Indexing While Building](#indexing-while-building) | -| Workspace Symbols | ✅ | | -| Rename | ❌ | | -| Local Refactoring | ✅ | | -| Formatting | ✅ | Whole file only | -| Folding | ✅ | | -| Syntax Highlighting | ✅ | Both syntactic and semantic tokens | -| Document Symbols | ✅ | | -| Call Hierarchy | ✅ | | -| Type Hierarchy | ✅ | | - - -### Caveats - -* SourceKit-LSP does not update its global index in the background, but instead relies on indexing-while-building to provide data. This only affects global queries like find-references and jump-to-definition. - * **Workaround**: build the project to update the index +Start contributing to SwiftSyntax see [this guide](CONTRIBUTING.md) for more information.