diff --git a/Cargo.lock b/Cargo.lock index 837b53cd65..f3298f0308 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -148,6 +148,19 @@ version = "0.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e9d4ee0d472d1cd2e28c97dfa124b3d8d992e10eb0a035f33f5d12e3a177ba3b" +[[package]] +name = "ammonia" +version = "4.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ab99eae5ee58501ab236beb6f20f6ca39be615267b014899c89b2f0bc18a459" +dependencies = [ + "html5ever", + "maplit", + "once_cell", + "tendril", + "url", +] + [[package]] name = "android-tzdata" version = "0.1.1" @@ -371,7 +384,7 @@ dependencies = [ "fuzzy", "globset", "gpui", - "handlebars", + "handlebars 4.5.0", "heed", "html_to_markdown 0.1.0", "http_client", @@ -858,7 +871,7 @@ dependencies = [ "futures-util", "log", "pin-project-lite", - "tungstenite", + "tungstenite 0.20.1", ] [[package]] @@ -1390,7 +1403,7 @@ dependencies = [ "sha1", "sync_wrapper", "tokio", - "tokio-tungstenite", + "tokio-tungstenite 0.20.1", "tower", "tower-layer", "tower-service", @@ -1541,7 +1554,7 @@ dependencies = [ "bitflags 2.6.0", "cexpr", "clang-sys", - "itertools 0.10.5", + "itertools 0.12.1", "lazy_static", "lazycell", "proc-macro2", @@ -2229,6 +2242,16 @@ dependencies = [ "anstyle", "clap_lex", "strsim", + "terminal_size", +] + +[[package]] +name = "clap_complete" +version = "4.5.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "531d7959c5bbb6e266cecdd0f20213639c3a5c3e4d615f97db87661745f781ff" +dependencies = [ + "clap", ] [[package]] @@ -3273,6 +3296,17 @@ dependencies = [ "util", ] +[[package]] +name = "dbus" +version = "0.9.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1bb21987b9fb1613058ba3843121dd18b163b254d8a6e797e144cbac14d96d1b" +dependencies = [ + "libc", + "libdbus-sys", + "winapi", +] + [[package]] name = "deflate64" version = "0.1.9" @@ -3466,6 +3500,20 @@ dependencies = [ "libloading", ] +[[package]] +name = "docs_preprocessor" +version = "0.1.0" +dependencies = [ + "anyhow", + "clap", + "mdbook", + "regex", + "serde", + "serde_json", + "settings", + "util", +] + [[package]] name = "dotenvy" version = "0.15.7" @@ -3585,6 +3633,18 @@ dependencies = [ "serde", ] +[[package]] +name = "elasticlunr-rs" +version = "3.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41e83863a500656dfa214fee6682de9c5b9f03de6860fec531235ed2ae9f6571" +dependencies = [ + "regex", + "serde", + "serde_derive", + "serde_json", +] + [[package]] name = "elliptic-curve" version = "0.12.3" @@ -4945,6 +5005,20 @@ dependencies = [ "thiserror", ] +[[package]] +name = "handlebars" +version = "5.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d08485b96a0e6393e9e4d1b8d48cf74ad6c063cd905eb33f42c1ce3f0377539b" +dependencies = [ + "log", + "pest", + "pest_derive", + "serde", + "serde_json", + "thiserror", +] + [[package]] name = "hashbrown" version = "0.12.3" @@ -6146,6 +6220,16 @@ version = "0.2.158" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d8adc4bb1803a324070e64a98ae98f38934d91957a99cfb3a43dcbc01bc56439" +[[package]] +name = "libdbus-sys" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "06085512b750d640299b79be4bad3d2fa90a9c00b1fd9e1b46364f66f0485c72" +dependencies = [ + "cc", + "pkg-config", +] + [[package]] name = "libfuzzer-sys" version = "0.4.7" @@ -6176,7 +6260,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4979f22fdb869068da03c9f7528f8297c6fd2606bc3a4affe42e6a823fdb8da4" dependencies = [ "cfg-if", - "windows-targets 0.48.5", + "windows-targets 0.52.6", ] [[package]] @@ -6435,6 +6519,12 @@ dependencies = [ "libc", ] +[[package]] +name = "maplit" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3e2e65a1a2e43cfcb47a895c4c8b10d1f4a61097f9f254f183aee60cad9c651d" + [[package]] name = "markdown" version = "0.1.0" @@ -6541,6 +6631,42 @@ dependencies = [ "digest", ] +[[package]] +name = "mdbook" +version = "0.4.40" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b45a38e19bd200220ef07c892b0157ad3d2365e5b5a267ca01ad12182491eea5" +dependencies = [ + "ammonia", + "anyhow", + "chrono", + "clap", + "clap_complete", + "elasticlunr-rs", + "env_logger", + "futures-util", + "handlebars 5.1.2", + "ignore", + "log", + "memchr", + "notify", + "notify-debouncer-mini", + "once_cell", + "opener", + "pathdiff", + "pulldown-cmark", + "regex", + "serde", + "serde_json", + "shlex", + "tempfile", + "tokio", + "toml 0.5.11", + "topological-sort", + "walkdir", + "warp", +] + [[package]] name = "media" version = "0.1.0" @@ -6624,6 +6750,16 @@ version = "0.3.17" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" +[[package]] +name = "mime_guess" +version = "2.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f7c44f8e672c00fe5308fa235f821cb4198414e1c77935c1ab6948d3fd78550e" +dependencies = [ + "mime", + "unicase", +] + [[package]] name = "minimal-lexical" version = "0.2.1" @@ -6868,6 +7004,15 @@ version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0676bb32a98c1a483ce53e500a81ad9c3d5b3f7c920c28c24e9cb0980d0b5bc8" +[[package]] +name = "normpath" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c8911957c4b1549ac0dc74e30db9c8b0e66ddcd6d7acc33098f4c63a64a6d7ed" +dependencies = [ + "windows-sys 0.59.0", +] + [[package]] name = "notifications" version = "0.1.0" @@ -6904,6 +7049,17 @@ dependencies = [ "windows-sys 0.48.0", ] +[[package]] +name = "notify-debouncer-mini" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5d40b221972a1fc5ef4d858a2f671fb34c75983eb385463dff3780eeff6a9d43" +dependencies = [ + "crossbeam-channel", + "log", + "notify", +] + [[package]] name = "ntapi" version = "0.4.1" @@ -7234,6 +7390,18 @@ dependencies = [ "strum", ] +[[package]] +name = "opener" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d0812e5e4df08da354c851a3376fead46db31c2214f849d3de356d774d057681" +dependencies = [ + "bstr", + "dbus", + "normpath", + "windows-sys 0.59.0", +] + [[package]] name = "openssl" version = "0.10.66" @@ -8320,9 +8488,16 @@ checksum = "76979bea66e7875e7509c4ec5300112b316af87fa7a252ca91c448b32dfe3993" dependencies = [ "bitflags 2.6.0", "memchr", + "pulldown-cmark-escape", "unicase", ] +[[package]] +name = "pulldown-cmark-escape" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd348ff538bc9caeda7ee8cad2d1d48236a1f443c1fa3913c6a02fe0043b1dd3" + [[package]] name = "qoi" version = "0.4.1" @@ -10964,6 +11139,16 @@ dependencies = [ "windows 0.58.0", ] +[[package]] +name = "terminal_size" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "21bebf2b7c9e0a515f6e0f8c51dc0f8e4696391e6f1ff30379559f8365fb0df7" +dependencies = [ + "rustix 0.38.34", + "windows-sys 0.48.0", +] + [[package]] name = "terminal_view" version = "0.1.0" @@ -11385,7 +11570,19 @@ dependencies = [ "futures-util", "log", "tokio", - "tungstenite", + "tungstenite 0.20.1", +] + +[[package]] +name = "tokio-tungstenite" +version = "0.21.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c83b561d025642014097b66e6c1bb422783339e0909e4429cde4749d1990bc38" +dependencies = [ + "futures-util", + "log", + "tokio", + "tungstenite 0.21.0", ] [[package]] @@ -11481,6 +11678,12 @@ dependencies = [ "winnow 0.6.18", ] +[[package]] +name = "topological-sort" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ea68304e134ecd095ac6c3574494fc62b909f416c4fca77e440530221e549d3d" + [[package]] name = "tower" version = "0.4.13" @@ -11875,6 +12078,25 @@ dependencies = [ "utf-8", ] +[[package]] +name = "tungstenite" +version = "0.21.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ef1a641ea34f399a848dea702823bbecfb4c486f911735368f1f137cb8257e1" +dependencies = [ + "byteorder", + "bytes 1.7.1", + "data-encoding", + "http 1.1.0", + "httparse", + "log", + "rand 0.8.5", + "sha1", + "thiserror", + "url", + "utf-8", +] + [[package]] name = "typeid" version = "1.0.0" @@ -12320,6 +12542,34 @@ dependencies = [ "try-lock", ] +[[package]] +name = "warp" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4378d202ff965b011c64817db11d5829506d3404edeadb61f190d111da3f231c" +dependencies = [ + "bytes 1.7.1", + "futures-channel", + "futures-util", + "headers", + "http 0.2.12", + "hyper", + "log", + "mime", + "mime_guess", + "percent-encoding", + "pin-project", + "scoped-tls", + "serde", + "serde_json", + "serde_urlencoded", + "tokio", + "tokio-tungstenite 0.21.0", + "tokio-util", + "tower-service", + "tracing", +] + [[package]] name = "wasi" version = "0.9.0+wasi-snapshot-preview1" diff --git a/Cargo.toml b/Cargo.toml index 400e43159c..01eba239f1 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -24,6 +24,7 @@ members = [ "crates/db", "crates/dev_server_projects", "crates/diagnostics", + "crates/docs_preprocessor", "crates/editor", "crates/extension", "crates/extension_api", @@ -165,7 +166,7 @@ members = [ # Tooling # - "tooling/xtask", + "tooling/xtask" ] default-members = ["crates/zed"] diff --git a/crates/docs_preprocessor/Cargo.toml b/crates/docs_preprocessor/Cargo.toml new file mode 100644 index 0000000000..0e47e3357d --- /dev/null +++ b/crates/docs_preprocessor/Cargo.toml @@ -0,0 +1,26 @@ +[package] +name = "docs_preprocessor" +version = "0.1.0" +edition = "2021" +publish = false +license = "GPL-3.0-or-later" + +[dependencies] +anyhow.workspace = true +clap.workspace = true +mdbook = "0.4.40" +serde.workspace = true +serde_json.workspace = true +settings.workspace = true +regex.workspace = true +util.workspace = true + +[lints] +workspace = true + +[lib] +path = "src/docs_preprocessor.rs" + +[[bin]] +name = "docs_preprocessor" +path = "src/main.rs" diff --git a/crates/docs_preprocessor/LICENSE-GPL b/crates/docs_preprocessor/LICENSE-GPL new file mode 120000 index 0000000000..89e542f750 --- /dev/null +++ b/crates/docs_preprocessor/LICENSE-GPL @@ -0,0 +1 @@ +../../LICENSE-GPL \ No newline at end of file diff --git a/crates/docs_preprocessor/src/docs_preprocessor.rs b/crates/docs_preprocessor/src/docs_preprocessor.rs new file mode 100644 index 0000000000..dcb0873879 --- /dev/null +++ b/crates/docs_preprocessor/src/docs_preprocessor.rs @@ -0,0 +1,93 @@ +use anyhow::Result; +use mdbook::book::{Book, BookItem}; +use mdbook::errors::Error; +use mdbook::preprocess::{Preprocessor, PreprocessorContext as MdBookContext}; +use settings::KeymapFile; +use std::sync::Arc; +use util::asset_str; + +mod templates; + +use templates::{ActionTemplate, KeybindingTemplate, Template}; + +pub struct PreprocessorContext { + macos_keymap: Arc, + linux_keymap: Arc, +} + +impl PreprocessorContext { + pub fn new() -> Result { + let macos_keymap = Arc::new(load_keymap("keymaps/default-macos.json")?); + let linux_keymap = Arc::new(load_keymap("keymaps/default-linux.json")?); + Ok(Self { + macos_keymap, + linux_keymap, + }) + } + + pub fn find_binding(&self, os: &str, action: &str) -> Option { + let keymap = match os { + "macos" => &self.macos_keymap, + "linux" => &self.linux_keymap, + _ => return None, + }; + + keymap.blocks().iter().find_map(|block| { + block.bindings().iter().find_map(|(keystroke, a)| { + if a.to_string() == action { + Some(keystroke.to_string()) + } else { + None + } + }) + }) + } +} + +fn load_keymap(asset_path: &str) -> Result { + let content = asset_str::(asset_path); + KeymapFile::parse(content.as_ref()) +} + +pub struct ZedDocsPreprocessor { + context: PreprocessorContext, + templates: Vec>, +} + +impl ZedDocsPreprocessor { + pub fn new() -> Result { + let context = PreprocessorContext::new()?; + let templates: Vec> = vec![ + Box::new(KeybindingTemplate::new()), + Box::new(ActionTemplate::new()), + ]; + Ok(Self { context, templates }) + } + + fn process_content(&self, content: &str) -> String { + let mut processed = content.to_string(); + for template in &self.templates { + processed = template.process(&self.context, &processed); + } + processed + } +} + +impl Preprocessor for ZedDocsPreprocessor { + fn name(&self) -> &str { + "zed-docs-preprocessor" + } + + fn run(&self, _ctx: &MdBookContext, mut book: Book) -> Result { + book.for_each_mut(|item| { + if let BookItem::Chapter(chapter) = item { + chapter.content = self.process_content(&chapter.content); + } + }); + Ok(book) + } + + fn supports_renderer(&self, renderer: &str) -> bool { + renderer != "not-supported" + } +} diff --git a/crates/docs_preprocessor/src/main.rs b/crates/docs_preprocessor/src/main.rs new file mode 100644 index 0000000000..488b99c55d --- /dev/null +++ b/crates/docs_preprocessor/src/main.rs @@ -0,0 +1,58 @@ +use anyhow::{Context, Result}; +use clap::{Arg, ArgMatches, Command}; +use docs_preprocessor::ZedDocsPreprocessor; +use mdbook::preprocess::{CmdPreprocessor, Preprocessor}; +use std::io::{self, Read}; +use std::process; + +pub fn make_app() -> Command { + Command::new("zed-docs-preprocessor") + .about("Preprocesses Zed Docs content to provide rich action & keybinding support and more") + .subcommand( + Command::new("supports") + .arg(Arg::new("renderer").required(true)) + .about("Check whether a renderer is supported by this preprocessor"), + ) +} + +fn main() -> Result<()> { + let matches = make_app().get_matches(); + + let preprocessor = + ZedDocsPreprocessor::new().context("Failed to create ZedDocsPreprocessor")?; + + if let Some(sub_args) = matches.subcommand_matches("supports") { + handle_supports(&preprocessor, sub_args); + } else { + handle_preprocessing(&preprocessor)?; + } + + Ok(()) +} + +fn handle_preprocessing(pre: &dyn Preprocessor) -> Result<()> { + let mut stdin = io::stdin(); + let mut input = String::new(); + stdin.read_to_string(&mut input)?; + + let (ctx, book) = CmdPreprocessor::parse_input(input.as_bytes())?; + + let processed_book = pre.run(&ctx, book)?; + + serde_json::to_writer(io::stdout(), &processed_book)?; + + Ok(()) +} + +fn handle_supports(pre: &dyn Preprocessor, sub_args: &ArgMatches) -> ! { + let renderer = sub_args + .get_one::("renderer") + .expect("Required argument"); + let supported = pre.supports_renderer(renderer); + + if supported { + process::exit(0); + } else { + process::exit(1); + } +} diff --git a/crates/docs_preprocessor/src/templates.rs b/crates/docs_preprocessor/src/templates.rs new file mode 100644 index 0000000000..fc169951ab --- /dev/null +++ b/crates/docs_preprocessor/src/templates.rs @@ -0,0 +1,25 @@ +use crate::PreprocessorContext; +use regex::Regex; +use std::collections::HashMap; + +mod action; +mod keybinding; + +pub use action::*; +pub use keybinding::*; + +pub trait Template { + fn key(&self) -> &'static str; + fn regex(&self) -> Regex; + fn parse_args(&self, args: &str) -> HashMap; + fn render(&self, context: &PreprocessorContext, args: &HashMap) -> String; + + fn process(&self, context: &PreprocessorContext, content: &str) -> String { + self.regex() + .replace_all(content, |caps: ®ex::Captures| { + let args = self.parse_args(&caps[1]); + self.render(context, &args) + }) + .into_owned() + } +} diff --git a/crates/docs_preprocessor/src/templates/action.rs b/crates/docs_preprocessor/src/templates/action.rs new file mode 100644 index 0000000000..7f67065c67 --- /dev/null +++ b/crates/docs_preprocessor/src/templates/action.rs @@ -0,0 +1,50 @@ +use crate::PreprocessorContext; +use regex::Regex; +use std::collections::HashMap; + +use super::Template; + +pub struct ActionTemplate; + +impl ActionTemplate { + pub fn new() -> Self { + ActionTemplate + } +} + +impl Template for ActionTemplate { + fn key(&self) -> &'static str { + "action" + } + + fn regex(&self) -> Regex { + Regex::new(&format!(r"\{{#{}(.*?)\}}", self.key())).unwrap() + } + + fn parse_args(&self, args: &str) -> HashMap { + let mut map = HashMap::new(); + map.insert("name".to_string(), args.trim().to_string()); + map + } + + fn render(&self, _context: &PreprocessorContext, args: &HashMap) -> String { + let name = args.get("name").map(String::as_str).unwrap_or_default(); + + let formatted_name = name + .chars() + .enumerate() + .map(|(i, c)| { + if i > 0 && c.is_uppercase() { + format!(" {}", c.to_lowercase()) + } else { + c.to_string() + } + }) + .collect::() + .trim() + .to_string() + .replace("::", ":"); + + format!("{}", formatted_name) + } +} diff --git a/crates/docs_preprocessor/src/templates/keybinding.rs b/crates/docs_preprocessor/src/templates/keybinding.rs new file mode 100644 index 0000000000..518bea2358 --- /dev/null +++ b/crates/docs_preprocessor/src/templates/keybinding.rs @@ -0,0 +1,36 @@ +use crate::PreprocessorContext; +use regex::Regex; +use std::collections::HashMap; + +use super::Template; + +pub struct KeybindingTemplate; + +impl KeybindingTemplate { + pub fn new() -> Self { + KeybindingTemplate + } +} + +impl Template for KeybindingTemplate { + fn key(&self) -> &'static str { + "kb" + } + + fn regex(&self) -> Regex { + Regex::new(&format!(r"\{{#{}(.*?)\}}", self.key())).unwrap() + } + + fn parse_args(&self, args: &str) -> HashMap { + let mut map = HashMap::new(); + map.insert("action".to_string(), args.trim().to_string()); + map + } + + fn render(&self, context: &PreprocessorContext, args: &HashMap) -> String { + let action = args.get("action").map(String::as_str).unwrap_or(""); + let macos_binding = context.find_binding("macos", action).unwrap_or_default(); + let linux_binding = context.find_binding("linux", action).unwrap_or_default(); + format!("{macos_binding}|{linux_binding}") + } +} diff --git a/crates/settings/src/keymap_file.rs b/crates/settings/src/keymap_file.rs index ebc75a1281..eb271e1b5e 100644 --- a/crates/settings/src/keymap_file.rs +++ b/crates/settings/src/keymap_file.rs @@ -22,10 +22,34 @@ pub struct KeymapBlock { bindings: BTreeMap, } +impl KeymapBlock { + pub fn context(&self) -> Option<&str> { + self.context.as_deref() + } + + pub fn bindings(&self) -> &BTreeMap { + &self.bindings + } +} + #[derive(Debug, Deserialize, Default, Clone)] #[serde(transparent)] pub struct KeymapAction(Value); +impl ToString for KeymapAction { + fn to_string(&self) -> String { + match &self.0 { + Value::String(s) => s.clone(), + Value::Array(arr) => arr + .iter() + .map(|v| v.to_string()) + .collect::>() + .join(", "), + _ => self.0.to_string(), + } + } +} + impl JsonSchema for KeymapAction { fn schema_name() -> String { "KeymapAction".into() @@ -135,6 +159,10 @@ impl KeymapFile { serde_json::to_value(root_schema).unwrap() } + + pub fn blocks(&self) -> &[KeymapBlock] { + &self.0 + } } fn no_action() -> Box { diff --git a/docs/README.md b/docs/README.md index e510cb2589..a79d5706c2 100644 --- a/docs/README.md +++ b/docs/README.md @@ -10,6 +10,13 @@ To preview the docs locally you will need to install [mdBook](https://rust-lang. mdbook serve docs ``` +## Preprocessor + +We have a custom mdbook preprocessor for interfacing with our crates (`crates/docs_preprocessor`). + +If for some reason you need to bypass the docs preprocessor, you can comment out `[preprocessor.zed_docs_preprocessor] +` from the `book.toml`.: + ## Images and videos To add images or videos to the docs, upload them to another location (e.g., zed.dev, GitHub's asset storage) and then link out to them from the docs. @@ -25,4 +32,32 @@ Putting binary assets such as images in the Git repository will bloat the reposi The table of contents files (`theme/page-toc.js` and `theme/page-doc.css`) were initially generated by [`mdbook-pagetoc`](https://crates.io/crates/mdbook-pagetoc). -Since all these preprocessor does is generate the static assets, we don't need to keep it around once they have been generated. +Since all this preprocessor does does is generate the static assets, we don't need to keep it around once they have been generated. + +## Referencing Keybindings and Actions + +When referencing keybindings or actions, use the following formats: + +### Keybindings: + +`{#kb scope::Action}` - e.g., `{#kb zed::OpenSettings}`. + +This will output a code element like: `Cmd+,|Ctrl+,`. We then use a client-side plugin to show the actual keybinding based on the user's platform. + +By using the action name, we can ensure that the keybinding is always up-to-date rather than hardcoding the keybinding. + +### Actions: + +`{#action scope::Action}` - e.g., `{#action zed::OpenSettings}`. + +This will render a human-readable version of the action name, e.g., "zed: open settings", and will allow us to implement things like additional context on hover, etc. + +### Creating New Templates + +New templates can be created by implementing the `Template` trait for your desired template in the `docs_preprocessor` crate. + +### References + +- Template Trait: crates/docs_preprocessor/src/templates.rs +- Example template: crates/docs_preprocessor/src/templates/keybinding.rs +- Client-side plugins: docs/theme/plugins.js diff --git a/docs/book.toml b/docs/book.toml index b5b118cc07..fac0e64fe2 100644 --- a/docs/book.toml +++ b/docs/book.toml @@ -22,3 +22,12 @@ enable = false "/python.html" = "/docs/languages/python.html" "/adding-new-languages.html" = "/docs/extensions/languages.html" "/language-model-integration.html" = "/docs/assistant/assistant.html" +"/assistant.html" = "/docs/assistant/assistant.html" + +# Our custom preprocessor for expanding commands like `{#kb action::ActionName}`, +# and other docs-related functions. +# +# Comment the below section out if you need to bypass the preprocessor for some reason. +[preprocessor.zed_docs_preprocessor] +command = "cargo run -p docs_preprocessor --" +renderer = ["html"] diff --git a/docs/src/assistant/assistant-panel.md b/docs/src/assistant/assistant-panel.md index c688f933b6..72d5013a59 100644 --- a/docs/src/assistant/assistant-panel.md +++ b/docs/src/assistant/assistant-panel.md @@ -2,7 +2,8 @@ The assistant panel provides you with a way to interact with large language models. The assistant is useful for various tasks, such as generating code, asking questions about existing code, and even writing plaintext, such as emails and documentation. -To open the assistant panel, toggle the right dock by using the `workspace: toggle right dock` action in the command palette or by using the cmd-r|ctrl-alt-b shortcut. +To open the assistant panel, toggle the right dock by using the {#action workspace::ToggleRightDock} action in the command palette or by using the +{#kb workspace::ToggleRightDock} shortcut. > **Note**: A custom [key binding](../key-bindings.md) can be set to toggle the right dock. @@ -10,9 +11,9 @@ Once you have [configured a provider](./configuration.md#providers), you can int ![](https://private-user-images.githubusercontent.com/1714999/359287532-abd8f918-e65f-44ce-a853-1e90f852e206.png?jwt=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJnaXRodWIuY29tIiwiYXVkIjoicmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbSIsImtleSI6ImtleTUiLCJleHAiOjE3MjQxMDk2OTIsIm5iZiI6MTcyNDEwOTM5MiwicGF0aCI6Ii8xNzE0OTk5LzM1OTI4NzUzMi1hYmQ4ZjkxOC1lNjVmLTQ0Y2UtYTg1My0xZTkwZjg1MmUyMDYucG5nP1gtQW16LUFsZ29yaXRobT1BV1M0LUhNQUMtU0hBMjU2JlgtQW16LUNyZWRlbnRpYWw9QUtJQVZDT0RZTFNBNTNQUUs0WkElMkYyMDI0MDgxOSUyRnVzLWVhc3QtMSUyRnMzJTJGYXdzNF9yZXF1ZXN0JlgtQW16LURhdGU9MjAyNDA4MTlUMjMxNjMyWiZYLUFtei1FeHBpcmVzPTMwMCZYLUFtei1TaWduYXR1cmU9MDhlMjZhMjI0NjM3M2JiZmEzMWU5ZWIwYWRjZjhkNTI3NTkyM2JlNmNjODcyMjg3YjkxNjIxNmI5ZTk1ZWRjZCZYLUFtei1TaWduZWRIZWFkZXJzPWhvc3QmYWN0b3JfaWQ9MCZrZXlfaWQ9MCZyZXBvX2lkPTAifQ.NiiQkF65VvBKCJs_zNxmjpyvKGK6Hw1aIWA3Xc87XRs) -To create a new context editor, press cmd-n|ctrl-n or use the menu in the top right of the assistant panel and select the `New Context` option. +To create a new context editor, press {#kb workspace::NewFile} or use the menu in the top right of the assistant panel and select the `New Context` option. -In the context editor, select a model from one of the configured providers, type a message in the `You` block, and submit with cmd-enter|ctrl-enter. +In the context editor, select a model from one of the configured providers, type a message in the `You` block, and submit with {#kb assistant::Assist}. ### Interacting with the Assistant @@ -30,11 +31,11 @@ To begin, select a model and type a message in a `You` block. As you type, the remaining tokens count for the selected model is updated. -Inserting text from an editor is as simple as highlighting the text and running `assistant: quote selection` (cmd+shift+>|ctrl+shift+>); Zed will wrap it in a fenced code block if it is code. +Inserting text from an editor is as simple as highlighting the text and running `assistant: quote selection` ({#kb assistant::QuoteSelection}); Zed will wrap it in a fenced code block if it is code. ![Quoting a selection](https://zed.dev/img/assistant/quoting-a-selection.png) -To submit a message, use cmd-enter|ctrl-enter (`assistant: assist`). Unlike typical chat applications where pressing enter would submit the message, in the assistant editor, our goal was to make it feel as close to a regular editor as possible. So, pressing enter simply inserts a new line. +To submit a message, use {#kb assistant::Assist}(`assistant: assist`). Unlike typical chat applications where pressing enter would submit the message, in the assistant editor, our goal was to make it feel as close to a regular editor as possible. So, pressing {#kb editor::Newline} simply inserts a new line. After submitting a message, the assistant's response will be streamed below, in an `Assistant` message block. @@ -53,12 +54,12 @@ Simple back-and-forth conversations work well with the assistant. However, there The assistant gives you the flexibility to have control over the context. You can freely edit any previous text, including the responses from the assistant. If you want to remove a message block entirely, simply place your cursor at the beginning of the block and use the `delete` key. A typical workflow might involve making edits and adjustments throughout the context to refine your inquiry or provide additional information. Here's an example: 1. Write text in a `You` block. -2. Submit the message with cmd-enter|ctrl-enter. +2. Submit the message with {#kb assistant::Assist}. 3. Receive an `Assistant` response that doesn't meet your expectations. 4. Cancel the response with escape. 5. Erase the content of the `Assistant` message block and remove the block entirely. 6. Add additional context to your original message. -7. Submit the message with cmd-enter|ctrl-enter. +7. Submit the message with {#kb assistant::Assist}. Being able to edit previous messages gives you control over how tokens are used. You don't need to start up a new context to correct a mistake or to add additional information, and you don't have to waste tokens by submitting follow-up corrections. diff --git a/docs/src/configuring-zed.md b/docs/src/configuring-zed.md index 75ec466a6d..8169d24e1e 100644 --- a/docs/src/configuring-zed.md +++ b/docs/src/configuring-zed.md @@ -13,9 +13,9 @@ Consider renaming `zed: Open Local Settings` to `zed: Open Project Settings`. TBD: Add settings documentation about how settings are merged as overlays. E.g. project>local>default. Note how settings that are maps are merged, but settings that are arrays are replaced and must include the defaults. --> -Your settings file can be opened with cmd-,|ctrl-,. By default it is located at `~/.config/zed/settings.json`, though if you have XDG_CONFIG_HOME in your environment on Linux it will be at `$XDG_CONFIG_HOME/zed/settings.json` instead. +Your settings file can be opened with {#kb zed::OpenSettings}. By default it is located at `~/.config/zed/settings.json`, though if you have XDG_CONFIG_HOME in your environment on Linux it will be at `$XDG_CONFIG_HOME/zed/settings.json` instead. -This configuration is merged with any local configuration inside your projects. You can open the project settings by running `zed: Open Local Settings` from the command palette. This will create a `.zed` directory containing`.zed/settings.json`. +This configuration is merged with any local configuration inside your projects. You can open the project settings by running {#action zed::OpenLocalSettings} from the command palette. This will create a `.zed` directory containing`.zed/settings.json`. Although most projects will only need one settings file at the root, you can add more local settings files for subdirectories as needed. Not all settings can be set in local files, just those that impact the behavior of the editor and language tooling. For example you can set `tab_size`, `formatter` etc. but not `theme`, `vim_mode` and similar. @@ -23,7 +23,7 @@ The syntax for configuration files is a super-set of JSON that allows `//` comme ## Default settings -You can find the default settings for your current Zed by running `zed: Open Default Settings` from the command palette. +You can find the default settings for your current Zed by running {#action zed::OpenDefaultSettings} from the command palette. Extensions that provide language servers may also provide default settings for those language servers. diff --git a/docs/src/getting-started.md b/docs/src/getting-started.md index c032662ca3..3e7d28d587 100644 --- a/docs/src/getting-started.md +++ b/docs/src/getting-started.md @@ -42,7 +42,7 @@ If this script is insufficient for your use case or you run into problems runnin The Command Palette is the main way to access functionality in Zed, and its keybinding is the first one you should make yourself familiar with. -To open the Command Palette, use cmd-shift-p|ctrl-shift-p. +To open the Command Palette, use {#kb command_palette::Toggle}. The Command Palette allows you to access pretty much any functionality that's available in Zed. @@ -54,11 +54,11 @@ Any time you see instructions that include commands of the form `zed: ...` or `e ## Configure Zed -Use cmd-,|ctrl-, to open your custom settings to set things like fonts, formatting settings, per-language settings, and more. +Use {#kb zed::OpenSettings} to open your custom settings to set things like fonts, formatting settings, per-language settings, and more. On macOS, you can access the default configuration using the `Zed > Settings > Open Default Settings` menu item. See [Configuring Zed](./configuring-zed.md) for all available settings. -On Linux, you can access the default configuration via the Command Palette. Open it with ctrl-shift-p and type in `zed: open default settings` and then hit return. +On Linux, you can access the default configuration via the Command Palette. Open it with {#kb zed::OpenDefaultSettings} and type in `zed: open default settings` and then hit return. ## Set up your key bindings diff --git a/docs/src/telemetry.md b/docs/src/telemetry.md index 57de114abe..1584cc07b6 100644 --- a/docs/src/telemetry.md +++ b/docs/src/telemetry.md @@ -4,7 +4,9 @@ Zed collects anonymous telemetry data to help the team understand how people are ## Configuring Telemetry Settings -You have full control over what data is sent out by Zed. To enable or disable some or all telemetry types, open your `settings.json` file via `zed: open settings` from the command palette. Insert and tweak the following: +You have full control over what data is sent out by Zed. To enable or disable some or all telemetry types, open your `settings.json` file via {#action zed::OpenSettings}({#kb zed::OpenSettings}) from the command palette. + +Insert and tweak the following: ```json "telemetry": { @@ -13,7 +15,7 @@ You have full control over what data is sent out by Zed. To enable or disable so }, ``` -The telemetry settings can also be configured via the `welcome` screen, which can be invoked via the `workspace: welcome` action in the command palette. +The telemetry settings can also be configured via the welcome screen, which can be invoked via the {#action workspace::Welcome} action in the command palette. ## Dataflow @@ -44,7 +46,7 @@ Usage Data does not include any of Your software code or sensitive project detai Usage Data is associated with a secure random telemetry ID which may be linked to Your email address. This linkage currently serves two purposes: (1) it allows Zed to analyze usage patterns over time while maintaining Your privacy; and (2) it enables Zed to reach out to specific user groups for feedback and improvement suggestions. -You can audit the metrics data that Zed has reported by running the command `zed: open telemetry log` from the command palette, or clicking `Help > View Telemetry Log` in the application menu. +You can audit the metrics data that Zed has reported by running the command {#action zed::OpenTelemetryLog} from the command palette, or clicking `Help > View Telemetry Log` in the application menu. You can see the full list of the event types and exactly the data sent for each by inspecting the `Event` enum and the associated structs in [crates/telemetry_events/src/telemetry_events.rs](https://github.com/zed-industries/zed/blob/main/crates/telemetry_events/src/telemetry_events.rs#L63] in the zed repo.