diff --git a/docs/user/README.md b/docs/user/README.md deleted file mode 100644 index 14ca6fd6425..00000000000 --- a/docs/user/README.md +++ /dev/null @@ -1,280 +0,0 @@ -[github-releases]: https://github.com/rust-analyzer/rust-analyzer/releases - -The main interface to rust-analyzer is the -[LSP](https://microsoft.github.io/language-server-protocol/) implementation. To -install lsp server, you have three options: - -* **Preferred and default:** install the plugin/extension for your IDE and it will ask your permission to automatically download the latest lsp server for you from [GitHub releases][github-releases]. (See docs to find out whether this is implemented for your editor below). -* Manually download prebuilt binaries from [GitHub releases][github-releases] - * `ra_lsp_server-linux` for Linux - * `ra_lsp_server-mac` for Mac - * `ra_lsp_server-windows.exe` for Windows -* Clone the repository and build from sources -```bash -$ git clone git@github.com:rust-analyzer/rust-analyzer && cd rust-analyzer -$ cargo xtask install --server # or cargo install --path ./crates/ra_lsp_server -``` - -This way you will get a binary named `ra_lsp_server` (with os suffix for prebuilt binaries) -which you should be able to use with any LSP-compatible editor. - -We make use of custom extensions to LSP, so special client-side support is required to take full -advantage of rust-analyzer. This repository contains support code for VS Code. - -Rust Analyzer needs sources of rust standard library to work, so -you might also need to execute - -``` -$ rustup component add rust-src -``` - -See [./features.md](./features.md) document for a list of features that are available. - -## VS Code - -### Prerequisites - -You will need the most recent version of VS Code: we don't try to -maintain compatibility with older versions yet. - -### Installation from prebuilt binaries - -We ship prebuilt binaries for Linux, Mac and Windows via -[GitHub releases][github-releases]. -In order to use them you need to install the client VSCode extension. - -Publishing to VS Code marketplace is currently WIP. Thus, you need to manually download -`rust-analyzer-0.1.0.vsix` file from latest [GitHub release][github-releases]. - -After you downloaded the `.vsix` file you can install it from the terminal - -``` -$ code --install-extension rust-analyzer-0.1.0.vsix -``` - -Or open VS Code, press Ctrl+Shift+P, and search for the following command: - -Install from VSIX command - -Press Enter and go to `rust-analyzer-0.1.0.vsix` file through the file explorer. - -Then open some Rust project and you should -see an info message pop-up. - -Download now message - - -Click `Download now`, wait until the progress is 100% and you are ready to go. - -For updates you need to remove installed binary -``` -rm -rf ${HOME}/.config/Code/User/globalStorage/matklad.rust-analyzer -``` - -`"Download latest language server"` command for VSCode and automatic updates detection is currently WIP. - - -### Installation from sources - -In order to build the VS Code plugin from sources, you need to have node.js and npm with -a minimum version of 12 installed. Please refer to -[node.js and npm documentation](https://nodejs.org) for installation instructions. - -The experimental VS Code plugin can be built and installed by executing the -following commands: - -``` -$ git clone https://github.com/rust-analyzer/rust-analyzer.git --depth 1 -$ cd rust-analyzer -$ cargo xtask install -``` - -After that you need to amend your `settings.json` file to explicitly specify the -path to `ra_lsp_server` that you've just built. -```json -{ - "rust-analyzer.raLspServerPath": "ra_lsp_server" -} -``` -This should work on all platforms, otherwise if installed `ra_lsp_server` is not available through your `$PATH` then see how to configure it [here](#setting-up-the-PATH-variable). - - -The automatic installation is expected to *just work* for common cases, if it -doesn't, report bugs! - -**Note** [#1831](https://github.com/rust-analyzer/rust-analyzer/issues/1831): If you are using the popular -[Vim emulation plugin](https://github.com/VSCodeVim/Vim), you will likely -need to turn off the `rust-analyzer.enableEnhancedTyping` setting. -(// TODO: This configuration is no longer available, enhanced typing shoud be disabled via removing Enter key binding, [see this issue](https://github.com/rust-analyzer/rust-analyzer/issues/3051)) - -If you have an unusual setup (for example, `code` is not in the `PATH`), you -should adapt these manual installation instructions: - -``` -$ git clone https://github.com/rust-analyzer/rust-analyzer.git --depth 1 -$ cd rust-analyzer -$ cargo install --path ./crates/ra_lsp_server/ --force --locked -$ cd ./editors/code -$ npm install -$ npm run package -$ code --install-extension ./rust-analyzer-0.1.0.vsix -``` - -It's better to remove existing Rust plugins to avoid interference. - -Beyond basic LSP features, there are some extension commands which you can -invoke via Ctrl+Shift+P or bind to a shortcut. See [./features.md](./features.md) -for details. - -For updates, pull the latest changes from the master branch, run `cargo xtask install` again, and **restart** VS Code instance. -See [microsoft/vscode#72308](https://github.com/microsoft/vscode/issues/72308) for why a full restart is needed. - -### VS Code Remote - -You can also use `rust-analyzer` with the Visual Studio Code Remote extensions -(Remote SSH, Remote WSL, Remote Containers). In this case, however, you have to -manually install the `.vsix` package: - -1. Build the extension on the remote host using the instructions above (ignore the - error if `code` cannot be found in your PATH: VSCode doesn't need to be installed - on the remote host). -2. In Visual Studio Code open a connection to the remote host. -3. Open the Extensions View (`View > Extensions`, keyboard shortcut: `Ctrl+Shift+X`). -4. From the top-right kebab menu (`ยทยทยท`) select `Install from VSIX...` -5. Inside the `rust-analyzer` directory find the `editors/code` subdirectory and choose - the `rust-analyzer-0.1.0.vsix` file. -6. Restart Visual Studio Code and re-establish the connection to the remote host. - -In case of errors please make sure that `~/.cargo/bin` is in your `PATH` on the remote -host. - -### Settings - -* `rust-analyzer.highlightingOn`: enables experimental syntax highlighting. - Colors can be configured via `editor.tokenColorCustomizations`. - As an example, [Pale Fire](https://github.com/matklad/pale-fire/) color scheme tweaks rust colors. -* `rust-analyzer.enableEnhancedTyping`: by default, rust-analyzer intercepts the - `Enter` key to make it easier to continue comments. Note that it may conflict with VIM emulation plugin. -* `rust-analyzer.raLspServerPath`: path to `ra_lsp_server` executable, when absent or `null` defaults to prebuilt binary path -* `rust-analyzer.enableCargoWatchOnStartup`: prompt to install & enable `cargo - watch` for live error highlighting (note, this **does not** use rust-analyzer) -* `rust-analyzer.excludeGlobs`: a list of glob-patterns for exclusion (see globset [docs](https://docs.rs/globset) for syntax). - Note: glob patterns are applied to all Cargo packages and a rooted at a package root. - This is not very intuitive and a limitation of a current implementation. -* `rust-analyzer.useClientWatching`: use client provided file watching instead - of notify watching. -* `rust-analyzer.cargo-watch.command`: `cargo-watch` command. (e.g: `clippy` will run as `cargo watch -x clippy` ) -* `rust-analyzer.cargo-watch.arguments`: cargo-watch check arguments. - (e.g: `--features="shumway,pdf"` will run as `cargo watch -x "check --features="shumway,pdf""` ) -* `rust-analyzer.cargo-watch.ignore`: list of patterns for cargo-watch to ignore (will be passed as `--ignore`) -* `rust-analyzer.trace.server`: enables internal logging -* `rust-analyzer.trace.cargo-watch`: enables cargo-watch logging -* `RUST_SRC_PATH`: environment variable that overwrites the sysroot -* `rust-analyzer.featureFlags` -- a JSON object to tweak fine-grained behavior: - ```jsonc - { - // Show diagnostics produced by rust-analyzer itself. - "lsp.diagnostics": true, - // Automatically insert `()` and `<>` when completing functions and types. - "completion.insertion.add-call-parenthesis": true, - // Enable completions like `.if`, `.match`, etc. - "completion.enable-postfix": true, - // Show notification when workspace is fully loaded - "notifications.workspace-loaded": true, - // Show error when no Cargo.toml was found - "notifications.cargo-toml-not-found": true, - } - ``` - - -## Emacs - -* install recent version of `emacs-lsp` package by following the instructions [here][emacs-lsp] -* set `lsp-rust-server` to `'rust-analyzer` -* run `lsp` in a Rust buffer -* (Optionally) bind commands like `lsp-rust-analyzer-join-lines`, `lsp-extend-selection` and `lsp-rust-analyzer-expand-macro` to keys - -[emacs-lsp]: https://github.com/emacs-lsp/lsp-mode - - -## Vim and NeoVim (coc-rust-analyzer) - -* Install coc.nvim by following the instructions at [coc.nvim][] (nodejs required) -* Run `:CocInstall coc-rust-analyzer` to install [coc-rust-analyzer], this extension implements _most_ of the features supported in the VSCode extension: - - same configurations as VSCode extension, `rust-analyzer.raLspServerPath`, `rust-analyzer.enableCargoWatchOnStartup` etc. - - same commands too, `rust-analyzer.analyzerStatus`, `rust-analyzer.startCargoWatch` etc. - - highlighting and inlay_hints are not implemented yet - -[coc.nvim]: https://github.com/neoclide/coc.nvim -[coc-rust-analyzer]: https://github.com/fannheyward/coc-rust-analyzer - -## Vim and NeoVim (LanguageClient-neovim) - -* Install LanguageClient-neovim by following the instructions [here][lang-client-neovim] - - The github project wiki has extra tips on configuration - -* Configure by adding this to your vim/neovim config file (replacing the existing rust specific line if it exists): - -```vim -let g:LanguageClient_serverCommands = { -\ 'rust': ['ra_lsp_server'], -\ } -``` - -[lang-client-neovim]: https://github.com/autozimu/LanguageClient-neovim - -## NeoVim (nvim-lsp) - -NeoVim 0.5 (not yet released) has built in language server support. For a quick start configuration -of rust-analyzer, use [neovim/nvim-lsp](https://github.com/neovim/nvim-lsp#rust_analyzer). -Once `neovim/nvim-lsp` is installed, use `lua require'nvim_lsp'.rust_analyzer.setup({})` in your `init.vim`. - - -## Sublime Text 3 - -Prequisites: - -`LSP` package. - -Installation: - -* Invoke the command palette with Ctrl+Shift+P -* Type `LSP Settings` to open the LSP preferences editor -* Add the following LSP client definition to your settings: - -```json -"rust-analyzer": { - "command": ["ra_lsp_server"], - "languageId": "rust", - "scopes": ["source.rust"], - "syntaxes": [ - "Packages/Rust/Rust.sublime-syntax", - "Packages/Rust Enhanced/RustEnhanced.sublime-syntax" - ], - "initializationOptions": { - "featureFlags": { - } - }, -} -``` - -* You can now invoke the command palette and type LSP enable to locally/globally enable the rust-analyzer LSP (type LSP enable, then choose either locally or globally, then select rust-analyzer) - - - -### Setting up the `PATH` variable - -On Unix systems, `rustup` adds `~/.cargo/bin` to `PATH` by modifying the shell's -startup file. Depending on your configuration, your Desktop Environment might not -actually load it. If you find that `rust-analyzer` only runs when starting the -editor from the terminal, you will have to set up your `PATH` variable manually. - -There are a couple of ways to do that: - -- for Code, set `rust-analyzer.raLspServerPath` to `~/.cargo/bin` (the `~` is - automatically resolved by the extension) -- copy the binary to a location that is already in `PATH`, e.g. `/usr/local/bin` -- on Linux, use PAM to configure the `PATH` variable, by e.g. putting - `PATH DEFAULT=/usr/local/bin:/usr/bin:/usr/local/sbin:/usr/sbin:@{HOME}/.cargo/bin:@{HOME}/.local/bin` - in your `~/.pam_environment` file; note that this might interfere with other - defaults set by the system administrator via `/etc/environment`. diff --git a/docs/user/readme.adoc b/docs/user/readme.adoc new file mode 100644 index 00000000000..b9ecc705557 --- /dev/null +++ b/docs/user/readme.adoc @@ -0,0 +1,152 @@ += User Manual +:toc: preamble +:sectanchors: +:page-layout: post + + +// Master copy of this document lives in the https://github.com/rust-analyzer/rust-analyzer repository + +At it's core, rust-analyzer is a *library* for semantic analysis of the Rust code as it changes over time. +This manual focuses on a specific usage of the library -- the implementation of +https://microsoft.github.io/language-server-protocol/[Language Server Protocol]. +LSP allows various code editors, like VS Code, Emacs or Vim, to implement semantic feature like completion or goto definition by talking to an external language server process. + +== Installation + +In theory, one should be able to just install the server binary and have it automatically work with any editor. +We are not there yet, so some editor specific setup is required. + +=== VS Code + +This the best supported editor at the moment. +rust-analyzer plugin for VS Code is maintained +https://github.com/rust-analyzer/rust-analyzer/tree/master/editors/code[in tree]. + +You can install the latest release of the plugin from +https://marketplace.visualstudio.com/items?itemName=matklad.rust-analyzer[the marketplace]. +By default, the plugin will download the latest version of the server as well. + +image::https://user-images.githubusercontent.com/36276403/74103174-a40df100-4b52-11ea-81f4-372c70797924.png[] + +The server binary is stored in `~/.config/Code/User/globalStorage/matklad.rust-analyzer`. + +Note that we only support the latest version of VS Code. + +==== Updates + +The extension will be updated automatically as new versions become available. +The server update functionality is in progress. +For the time being, the workaround is to remove the binary from `globalStorage` and to restart the extension. + +==== Building From Source + +Alternatively, both the server and the plugin can be installed from source: + +[source] +---- +$ git clone https://github.com/rust-analyzer/rust-analyzer.git && cs rust-analyzer +$ cargo xtask install +---- + +You'll need Cargo, nodejs and npm for this. +To make VS Code use the freshly build server, add this to the settings: + +[source,json] +---- +{ "rust-analyzer.raLspServerPath": "ra_lsp_server" } +---- + +Note that installing via `xtask install` does not work for VS Code Remote, instead you'll need to install the `.vsix` manually. + +=== Language Server Binary + +Other editors generally require `ra_lsp_server` binary to be in `$PATH`. +You can download pre-build binary from +https://github.com/rust-analyzer/rust-analyzer/releases[relases] +page, or you can install it from source using the following command: + +[source,bash] +---- +$ cargo xtask install --server +---- + +=== Emacs + +Emacs support is maintained https://github.com/emacs-lsp/lsp-mode/blob/master/lsp-rust.el[upstream]. + +1. Install recent version of `emacs-lsp` package by following the instructions https://github.com/emacs-lsp/lsp-mode[here]. +2. Set `lsp-rust-server` to `'rust-analyzer`. +3. Run `lsp` in a Rust buffer. +4. (Optionally) bind commands like `lsp-rust-analyzer-join-lines`, `lsp-extend-selection` and `lsp-rust-analyzer-expand-macro` to keys. + +=== Vim + +The are several LSP client implementations for vim: + +==== coc-rust-analyzer + +1. Install coc.nvim by following the instructions at + https://github.com/neoclide/coc.nvim[coc.nvim] + (nodejs required) +2. Run `:CocInstall coc-rust-analyzer` to install + https://github.com/fannheyward/coc-rust-analyzer[coc-rust-analyzer], + this extension implements _most_ of the features supported in the VSCode extension: + * same configurations as VSCode extension, `rust-analyzer.raLspServerPath`, `rust-analyzer.enableCargoWatchOnStartup` etc. + * same commands too, `rust-analyzer.analyzerStatus`, `rust-analyzer.startCargoWatch` etc. + * highlighting and inlay_hints are not implemented yet + +==== LanguageClient-neovim + +1. Install LanguageClient-neovim by following the instructions + https://github.com/autozimu/LanguageClient-neovim[here] + * The github project wiki has extra tips on configuration + +2. Configure by adding this to your vim/neovim config file (replacing the existing rust specific line if it exists): ++ +[source,vim] +---- +let g:LanguageClient_serverCommands = { +\ 'rust': ['ra_lsp_server'], +\ } +---- + +==== nvim-lsp + +NeoVim 0.5 (not yet released) has built in language server support. +For a quick start configuration of rust-analyzer, use https://github.com/neovim/nvim-lsp#rust_analyzer[neovim/nvim-lsp]. +Once `neovim/nvim-lsp` is installed, use `lua require'nvim_lsp'.rust_analyzer.setup({})` in your `init.vim`. + +=== Sublime Text 3 + +Prerequisites: + +`LSP` package. + +Installation: + +1. Invoke the command palette with Ctrl+Shift+P +2. Type `LSP Settings` to open the LSP preferences editor +3. Add the following LSP client definition to your settings: ++ +[source,json] +---- +"rust-analyzer": { + "command": ["ra_lsp_server"], + "languageId": "rust", + "scopes": ["source.rust"], + "syntaxes": [ + "Packages/Rust/Rust.sublime-syntax", + "Packages/Rust Enhanced/RustEnhanced.sublime-syntax" + ], + "initializationOptions": { + "featureFlags": { + } + }, +} +---- + +4. You can now invoke the command palette and type LSP enable to locally/globally enable the rust-analyzer LSP (type LSP enable, then choose either locally or globally, then select rust-analyzer) + +== Usage + +See https://github.com/rust-analyzer/rust-analyzer/blob/master/docs/user/features.md[features.md]. diff --git a/xtask/src/lib.rs b/xtask/src/lib.rs index d2ef2e95b74..25b64301c77 100644 --- a/xtask/src/lib.rs +++ b/xtask/src/lib.rs @@ -9,7 +9,7 @@ use anyhow::Context; use std::{ - env, fs, + env, io::Write, path::{Path, PathBuf}, process::{Command, Stdio}, @@ -17,7 +17,7 @@ use crate::{ codegen::Mode, - not_bash::{pushd, run}, + not_bash::{fs2, pushd, rm_rf, run}, }; pub use anyhow::Result; @@ -139,7 +139,7 @@ pub fn run_pre_cache() -> Result<()> { } } - fs::remove_file("./target/.rustc_info.json")?; + fs2::remove_file("./target/.rustc_info.json")?; let to_delete = ["ra_", "heavy_test"]; for &dir in ["./target/debug/deps", "target/debug/.fingerprint"].iter() { for entry in Path::new(dir).read_dir()? { @@ -153,22 +153,20 @@ pub fn run_pre_cache() -> Result<()> { Ok(()) } -fn rm_rf(path: &Path) -> Result<()> { - if path.is_file() { fs::remove_file(path) } else { fs::remove_dir_all(path) } - .with_context(|| format!("failed to remove {:?}", path)) -} +pub fn run_release(dry_run: bool) -> Result<()> { + if !dry_run { + run!("git switch release")?; + run!("git fetch upstream")?; + run!("git reset --hard upstream/master")?; + run!("git push")?; + } -pub fn run_release() -> Result<()> { - run!("git switch release")?; - run!("git fetch upstream")?; - run!("git reset --hard upstream/master")?; - run!("git push")?; - - let changelog_dir = project_root().join("../rust-analyzer.github.io/thisweek/_posts"); + let website_root = project_root().join("../rust-analyzer.github.io"); + let changelog_dir = website_root.join("./thisweek/_posts"); let today = run!("date --iso")?; let commit = run!("git rev-parse HEAD")?; - let changelog_n = fs::read_dir(changelog_dir.as_path())?.count(); + let changelog_n = fs2::read_dir(changelog_dir.as_path())?.count(); let contents = format!( "\ @@ -191,7 +189,9 @@ pub fn run_release() -> Result<()> { ); let path = changelog_dir.join(format!("{}-changelog-{}.adoc", today, changelog_n)); - fs::write(&path, &contents)?; + fs2::write(&path, &contents)?; + + fs2::copy(project_root().join("./docs/user/readme.adoc"), website_root.join("manual.adoc"))?; Ok(()) } diff --git a/xtask/src/main.rs b/xtask/src/main.rs index 7ca727bde9b..a7dffe2cc87 100644 --- a/xtask/src/main.rs +++ b/xtask/src/main.rs @@ -93,8 +93,9 @@ fn main() -> Result<()> { run_pre_cache() } "release" => { + let dry_run = args.contains("--dry-run"); args.finish()?; - run_release() + run_release(dry_run) } _ => { eprintln!( diff --git a/xtask/src/not_bash.rs b/xtask/src/not_bash.rs index 56d6c6c2d83..3e30e7279ff 100644 --- a/xtask/src/not_bash.rs +++ b/xtask/src/not_bash.rs @@ -4,12 +4,45 @@ env, ffi::OsStr, fs, - path::PathBuf, + path::{Path, PathBuf}, process::{Command, Stdio}, }; use anyhow::{bail, Context, Result}; +pub mod fs2 { + use std::{fs, path::Path}; + + use anyhow::{Context, Result}; + + pub fn read_dir>(path: P) -> Result { + let path = path.as_ref(); + fs::read_dir(path).with_context(|| format!("Failed to read {}", path.display())) + } + + pub fn write, C: AsRef<[u8]>>(path: P, contents: C) -> Result<()> { + let path = path.as_ref(); + fs::write(path, contents).with_context(|| format!("Failed to write {}", path.display())) + } + + pub fn copy, Q: AsRef>(from: P, to: Q) -> Result { + let from = from.as_ref(); + let to = to.as_ref(); + fs::copy(from, to) + .with_context(|| format!("Failed to copy {} to {}", from.display(), to.display())) + } + + pub fn remove_file>(path: P) -> Result<()> { + let path = path.as_ref(); + fs::remove_file(path).with_context(|| format!("Failed to remove file {}", path.display())) + } + + pub fn remove_dir_all>(path: P) -> Result<()> { + let path = path.as_ref(); + fs::remove_dir_all(path).with_context(|| format!("Failed to remove dir {}", path.display())) + } +} + macro_rules! _run { ($($expr:expr),*) => { run!($($expr),*; echo = true) @@ -41,6 +74,15 @@ pub fn rm(glob: &str) -> Result<()> { Ok(()) } +pub fn rm_rf(path: impl AsRef) -> Result<()> { + let path = path.as_ref(); + if path.is_file() { + fs2::remove_file(path) + } else { + fs2::remove_dir_all(path) + } +} + pub fn ls(glob: &str) -> Result> { let cwd = Env::with(|env| env.cwd()); let mut res = Vec::new(); @@ -90,7 +132,7 @@ fn run_process_inner(cmd: &str, echo: bool) -> Result { bail!("{}", output.status) } - Ok(stdout) + Ok(stdout.trim().to_string()) } // FIXME: some real shell lexing here