diff --git a/Cargo.lock b/Cargo.lock index 35f0f63857..f181f32fd5 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -142,7 +142,7 @@ checksum = "c980ee35e870bd1a4d2c8294d4c04d0499e67bca1e4b5cefcc693c2fa00caea9" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.50", ] [[package]] @@ -417,7 +417,7 @@ dependencies = [ "heck", "proc-macro2", "quote", - "syn", + "syn 2.0.50", ] [[package]] @@ -474,6 +474,15 @@ dependencies = [ "windows-sys 0.52.0", ] +[[package]] +name = "coolor" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "37e93977247fb916abeee1ff8c6594c9b421fd9c26c9b720a3944acb2a7de27b" +dependencies = [ + "crossterm", +] + [[package]] name = "core-foundation-sys" version = "0.8.6" @@ -534,6 +543,32 @@ dependencies = [ "itertools 0.10.5", ] +[[package]] +name = "crokey" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "11650f38fa0dc9fae9b4ac5243c4d32992351f82bb5452c5c1fd7e639057b732" +dependencies = [ + "crokey-proc_macros", + "crossterm", + "once_cell", + "serde", + "strict", +] + +[[package]] +name = "crokey-proc_macros" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3588f310d39d0c6f546aaca1e9df18d1dfb961a8bb4042a11b6c5a6b449c1894" +dependencies = [ + "crossterm", + "proc-macro2", + "quote", + "strict", + "syn 1.0.109", +] + [[package]] name = "crossbeam" version = "0.8.4" @@ -842,7 +877,7 @@ checksum = "87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489ac" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.50", ] [[package]] @@ -1195,7 +1230,7 @@ checksum = "d75e7ab728059f595f6ddc1ad8771b8d6a231971ae493d9d5948ecad366ee8bb" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.50", ] [[package]] @@ -1657,6 +1692,7 @@ dependencies = [ "insta", "itertools 0.12.1", "jj-cli", + "jj-docs", "jj-lib", "libc", "maplit", @@ -1671,6 +1707,7 @@ dependencies = [ "serde", "slab", "tempfile", + "termimad", "test-case", "testutils", "textwrap", @@ -1750,7 +1787,7 @@ version = "0.14.0" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.50", ] [[package]] @@ -1781,6 +1818,29 @@ dependencies = [ "rayon", ] +[[package]] +name = "lazy-regex" +version = "3.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5d12be4595afdf58bd19e4a9f4e24187da2a66700786ff660a418e9059937a4c" +dependencies = [ + "lazy-regex-proc_macros", + "once_cell", + "regex", +] + +[[package]] +name = "lazy-regex-proc_macros" +version = "3.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "44bcd58e6c97a7fcbaffcdc95728b393b8d98933bfadad49ed4097845b57ef0b" +dependencies = [ + "proc-macro2", + "quote", + "regex", + "syn 2.0.50", +] + [[package]] name = "lazy_static" version = "1.4.0" @@ -1902,6 +1962,15 @@ dependencies = [ "libc", ] +[[package]] +name = "minimad" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f6c4610f430e49b882fcaad0186134150d4d74fc76080b0a61f7000460c2e268" +dependencies = [ + "once_cell", +] + [[package]] name = "minimal-lexical" version = "0.2.1" @@ -2134,7 +2203,7 @@ dependencies = [ "pest_meta", "proc-macro2", "quote", - "syn", + "syn 2.0.50", ] [[package]] @@ -2266,7 +2335,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ae005bd773ab59b4725093fd7df83fd7892f7d8eafb48dbd7de6e024e4215f9d" dependencies = [ "proc-macro2", - "syn", + "syn 2.0.50", ] [[package]] @@ -2311,7 +2380,7 @@ dependencies = [ "prost", "prost-types", "regex", - "syn", + "syn 2.0.50", "tempfile", "which", ] @@ -2326,7 +2395,7 @@ dependencies = [ "itertools 0.11.0", "proc-macro2", "quote", - "syn", + "syn 2.0.50", ] [[package]] @@ -2451,7 +2520,7 @@ checksum = "5fddb4f8d99b0a2ebafc65a87a69a7b9875e4b1ae1f00db265d300ef7f28bccc" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.50", ] [[package]] @@ -2545,7 +2614,7 @@ dependencies = [ "proc-macro2", "quote", "rust-embed-utils", - "syn", + "syn 2.0.50", "walkdir", ] @@ -2662,7 +2731,7 @@ checksum = "7eb0b34b42edc17f6b7cac84a52a1c5f0e1bb2227e997ca9011ea3dd34e8610b" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.50", ] [[package]] @@ -2778,6 +2847,12 @@ dependencies = [ "windows-sys 0.48.0", ] +[[package]] +name = "strict" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f42444fea5b87a39db4218d9422087e66a85d0e7a0963a439b07bcdf91804006" + [[package]] name = "strsim" version = "0.11.0" @@ -2803,7 +2878,7 @@ dependencies = [ "proc-macro2", "quote", "rustversion", - "syn", + "syn 2.0.50", ] [[package]] @@ -2812,6 +2887,17 @@ version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "81cdd64d312baedb58e21336b31bc043b77e01cc99033ce76ef539f78e965ebc" +[[package]] +name = "syn" +version = "1.0.109" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + [[package]] name = "syn" version = "2.0.50" @@ -2835,6 +2921,22 @@ dependencies = [ "windows-sys 0.52.0", ] +[[package]] +name = "termimad" +version = "0.29.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ad4f1d007842e9364e116ea7a0355b4e35cbe40713feaab6d6cfaa38015a517c" +dependencies = [ + "coolor", + "crokey", + "crossbeam", + "lazy-regex", + "minimad", + "serde", + "thiserror", + "unicode-width", +] + [[package]] name = "terminal_size" version = "0.3.0" @@ -2869,7 +2971,7 @@ dependencies = [ "cfg-if", "proc-macro2", "quote", - "syn", + "syn 2.0.50", ] [[package]] @@ -2880,7 +2982,7 @@ checksum = "5c89e72a01ed4c579669add59014b9a524d609c0c88c6a585ce37485879f6ffb" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.50", "test-case-core", ] @@ -2926,7 +3028,7 @@ checksum = "a953cb265bef375dae3de6663da4d3804eee9682ea80d8e2542529b73c531c81" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.50", ] [[package]] @@ -3028,7 +3130,7 @@ checksum = "5b8a1e28f2deaa14e508979454cb3a223b10b938b45af148bc0986de36f1923b" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.50", ] [[package]] @@ -3097,7 +3199,7 @@ checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.50", ] [[package]] @@ -3297,7 +3399,7 @@ dependencies = [ "once_cell", "proc-macro2", "quote", - "syn", + "syn 2.0.50", "wasm-bindgen-shared", ] @@ -3319,7 +3421,7 @@ checksum = "bae1abb6806dc1ad9e560ed242107c0f6c84335f1749dd4e8ddb012ebd5e25a7" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.50", "wasm-bindgen-backend", "wasm-bindgen-shared", ] diff --git a/Cargo.toml b/Cargo.toml index 52623aeac0..c73b1f9b4f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -99,6 +99,7 @@ smallvec = { version = "1.13.0", features = [ strsim = "0.11.0" syn = "2.0.50" tempfile = "3.10.0" +termimad = "0.29.1" test-case = "3.3.1" textwrap = "0.16.1" thiserror = "1.0.57" diff --git a/cli/Cargo.toml b/cli/Cargo.toml index cb0e83e455..9dd435045a 100644 --- a/cli/Cargo.toml +++ b/cli/Cargo.toml @@ -52,6 +52,7 @@ hex = { workspace = true } indexmap = { workspace = true } itertools = { workspace = true } jj-lib = { workspace = true } +jj-docs = { workspace = true } maplit = { workspace = true } minus = { workspace = true } once_cell = { workspace = true } @@ -64,6 +65,7 @@ scm-record = { workspace = true } serde = { workspace = true } slab = { workspace = true } tempfile = { workspace = true } +termimad = { workspace = true } textwrap = { workspace = true } thiserror = { workspace = true } timeago = { workspace = true } diff --git a/cli/src/commands/docs.rs b/cli/src/commands/docs.rs new file mode 100644 index 0000000000..deaba7a32a --- /dev/null +++ b/cli/src/commands/docs.rs @@ -0,0 +1,66 @@ +// Copyright 2024 The Jujutsu Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +use std::fmt::Debug; +use std::io::Write; + +use jj_docs::DocAssets; + +use crate::cli_util::{user_error, CommandError, CommandHelper}; +use crate::ui::Ui; + +#[derive(clap::Args, Clone, Debug)] +pub(crate) struct DocsArgs { + /// The command to show documentation for + command: Option, +} + +pub fn cmd_docs( + ui: &mut Ui, + _command: &CommandHelper, + args: &DocsArgs, +) -> Result<(), CommandError> { + // just print all the documents in the static map, and the size of the contents + + let cmd = args.command.clone(); + match cmd { + None => { + for name in DocAssets::iter() { + // XXX FIXME (aseipp): show a real document index + let content = DocAssets::get(&name).unwrap(); + writeln!(ui.stdout(), "{}: {} bytes", name, content.len())?; + } + } + Some(command) => { + // print the document for the command, if it exists + if let Some(name) = DocAssets::iter().find(|name| name == &command) { + let skin = termimad::MadSkin::default(); + let content = DocAssets::get(&name).unwrap(); + writeln!( + ui.stdout(), + "{}", + skin.term_text(&String::from_utf8_lossy(&content)) + )?; + return Ok(()); + } else { + return Err(user_error(format!( + "No documentation found for item: {}", + command + ))); + } + } + } + + Ok(()) +} diff --git a/cli/src/commands/mod.rs b/cli/src/commands/mod.rs index 6acca1c5c8..3c2d5da15a 100644 --- a/cli/src/commands/mod.rs +++ b/cli/src/commands/mod.rs @@ -26,6 +26,7 @@ mod debug; mod describe; mod diff; mod diffedit; +mod docs; mod duplicate; mod edit; mod files; @@ -87,6 +88,7 @@ enum Command { Describe(describe::DescribeArgs), Diff(diff::DiffArgs), Diffedit(diffedit::DiffeditArgs), + Docs(docs::DocsArgs), Duplicate(duplicate::DuplicateArgs), Edit(edit::EditArgs), Files(files::FilesArgs), @@ -168,6 +170,7 @@ pub fn run_command(ui: &mut Ui, command_helper: &CommandHelper) -> Result<(), Co Command::Files(sub_args) => files::cmd_files(ui, command_helper, sub_args), Command::Cat(sub_args) => cat::cmd_cat(ui, command_helper, sub_args), Command::Diff(sub_args) => diff::cmd_diff(ui, command_helper, sub_args), + Command::Docs(sub_args) => docs::cmd_docs(ui, command_helper, sub_args), Command::Show(sub_args) => show::cmd_show(ui, command_helper, sub_args), Command::Status(sub_args) => status::cmd_status(ui, command_helper, sub_args), Command::Log(sub_args) => log::cmd_log(ui, command_helper, sub_args), diff --git a/cli/tests/cli-reference@.md.snap b/cli/tests/cli-reference@.md.snap index ef8c9699f1..56a70e4076 100644 --- a/cli/tests/cli-reference@.md.snap +++ b/cli/tests/cli-reference@.md.snap @@ -34,6 +34,7 @@ This document contains the help content for the `jj` command-line program. * [`jj describe`↴](#jj-describe) * [`jj diff`↴](#jj-diff) * [`jj diffedit`↴](#jj-diffedit) +* [`jj docs`↴](#jj-docs) * [`jj duplicate`↴](#jj-duplicate) * [`jj edit`↴](#jj-edit) * [`jj files`↴](#jj-files) @@ -112,6 +113,7 @@ To get started, see the tutorial at https://github.com/martinvonz/jj/blob/main/d * `describe` — Update the change description or other metadata * `diff` — Compare file contents between two revisions * `diffedit` — Touch up the content changes in a revision with a diff editor +* `docs` — * `duplicate` — Create a new change with the same content as an existing one * `edit` — Edit a commit in the working copy * `files` — List files in a revision @@ -674,6 +676,16 @@ See `jj restore` if you want to move entire files from one revision to another. +## `jj docs` + +**Usage:** `jj docs [COMMAND]` + +###### **Arguments:** + +* `` — The command to show documentation for + + + ## `jj duplicate` Create a new change with the same content as an existing one