annotate rust/rhg/src/ui.rs @ 49513:467d9df98c68

rhg: centralize PlainInfo
author Arseniy Alekseyev <aalekseyev@janestreet.com>
date Thu, 22 Sep 2022 17:16:54 -0400
parents 6939d5ed20e0
children 364e78389653
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
48733
39c447e03dbc rhg: Add support for colored output
Simon Sapin <simon.sapin@octobus.net>
parents: 48731
diff changeset
1 use crate::color::ColorConfig;
39c447e03dbc rhg: Add support for colored output
Simon Sapin <simon.sapin@octobus.net>
parents: 48731
diff changeset
2 use crate::color::Effect;
45984
fada33872b5b rhg: use `format_bytes!` for error messages
Rapha?l Gom?s <rgomes@octobus.net>
parents: 45528
diff changeset
3 use format_bytes::format_bytes;
48733
39c447e03dbc rhg: Add support for colored output
Simon Sapin <simon.sapin@octobus.net>
parents: 48731
diff changeset
4 use format_bytes::write_bytes;
48730
1aaf11e35aec rhg: Pass a &Config to Ui::new
Simon Sapin <simon.sapin@octobus.net>
parents: 48729
diff changeset
5 use hg::config::Config;
49513
467d9df98c68 rhg: centralize PlainInfo
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 49512
diff changeset
6 use hg::config::PlainInfo;
48731
f591b377375f rhg: Make Ui::new falliable, add Ui::new_infallible
Simon Sapin <simon.sapin@octobus.net>
parents: 48730
diff changeset
7 use hg::errors::HgError;
45528
66756b34c06e rhg: add a `DebugData` `Command` to prepare the `rhg debugdata` subcommand
Antoine Cezar <antoine.cezar@octobus.net>
parents: 45440
diff changeset
8 use std::borrow::Cow;
45049
513b3ef277a3 rhg: add RootCommand using hg-core FindRoot operation to prepare `hg root`
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
9 use std::io;
45362
eb55274d3650 rhg: add buffered stdout writing possibility
Antoine Cezar <antoine.cezar@octobus.net>
parents: 45049
diff changeset
10 use std::io::{ErrorKind, Write};
45049
513b3ef277a3 rhg: add RootCommand using hg-core FindRoot operation to prepare `hg root`
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
11
45362
eb55274d3650 rhg: add buffered stdout writing possibility
Antoine Cezar <antoine.cezar@octobus.net>
parents: 45049
diff changeset
12 pub struct Ui {
eb55274d3650 rhg: add buffered stdout writing possibility
Antoine Cezar <antoine.cezar@octobus.net>
parents: 45049
diff changeset
13 stdout: std::io::Stdout,
eb55274d3650 rhg: add buffered stdout writing possibility
Antoine Cezar <antoine.cezar@octobus.net>
parents: 45049
diff changeset
14 stderr: std::io::Stderr,
48733
39c447e03dbc rhg: Add support for colored output
Simon Sapin <simon.sapin@octobus.net>
parents: 48731
diff changeset
15 colors: Option<ColorConfig>,
45362
eb55274d3650 rhg: add buffered stdout writing possibility
Antoine Cezar <antoine.cezar@octobus.net>
parents: 45049
diff changeset
16 }
45049
513b3ef277a3 rhg: add RootCommand using hg-core FindRoot operation to prepare `hg root`
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
17
513b3ef277a3 rhg: add RootCommand using hg-core FindRoot operation to prepare `hg root`
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
18 /// The kind of user interface error
513b3ef277a3 rhg: add RootCommand using hg-core FindRoot operation to prepare `hg root`
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
19 pub enum UiError {
513b3ef277a3 rhg: add RootCommand using hg-core FindRoot operation to prepare `hg root`
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
20 /// The standard output stream cannot be written to
513b3ef277a3 rhg: add RootCommand using hg-core FindRoot operation to prepare `hg root`
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
21 StdoutError(io::Error),
513b3ef277a3 rhg: add RootCommand using hg-core FindRoot operation to prepare `hg root`
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
22 /// The standard error stream cannot be written to
513b3ef277a3 rhg: add RootCommand using hg-core FindRoot operation to prepare `hg root`
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
23 StderrError(io::Error),
513b3ef277a3 rhg: add RootCommand using hg-core FindRoot operation to prepare `hg root`
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
24 }
513b3ef277a3 rhg: add RootCommand using hg-core FindRoot operation to prepare `hg root`
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
25
513b3ef277a3 rhg: add RootCommand using hg-core FindRoot operation to prepare `hg root`
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
26 /// The commandline user interface
513b3ef277a3 rhg: add RootCommand using hg-core FindRoot operation to prepare `hg root`
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
27 impl Ui {
48733
39c447e03dbc rhg: Add support for colored output
Simon Sapin <simon.sapin@octobus.net>
parents: 48731
diff changeset
28 pub fn new(config: &Config) -> Result<Self, HgError> {
48731
f591b377375f rhg: Make Ui::new falliable, add Ui::new_infallible
Simon Sapin <simon.sapin@octobus.net>
parents: 48730
diff changeset
29 Ok(Ui {
48733
39c447e03dbc rhg: Add support for colored output
Simon Sapin <simon.sapin@octobus.net>
parents: 48731
diff changeset
30 // If using something else, also adapt `isatty()` below.
48731
f591b377375f rhg: Make Ui::new falliable, add Ui::new_infallible
Simon Sapin <simon.sapin@octobus.net>
parents: 48730
diff changeset
31 stdout: std::io::stdout(),
48733
39c447e03dbc rhg: Add support for colored output
Simon Sapin <simon.sapin@octobus.net>
parents: 48731
diff changeset
32
48731
f591b377375f rhg: Make Ui::new falliable, add Ui::new_infallible
Simon Sapin <simon.sapin@octobus.net>
parents: 48730
diff changeset
33 stderr: std::io::stderr(),
48733
39c447e03dbc rhg: Add support for colored output
Simon Sapin <simon.sapin@octobus.net>
parents: 48731
diff changeset
34 colors: ColorConfig::new(config)?,
48731
f591b377375f rhg: Make Ui::new falliable, add Ui::new_infallible
Simon Sapin <simon.sapin@octobus.net>
parents: 48730
diff changeset
35 })
f591b377375f rhg: Make Ui::new falliable, add Ui::new_infallible
Simon Sapin <simon.sapin@octobus.net>
parents: 48730
diff changeset
36 }
f591b377375f rhg: Make Ui::new falliable, add Ui::new_infallible
Simon Sapin <simon.sapin@octobus.net>
parents: 48730
diff changeset
37
f591b377375f rhg: Make Ui::new falliable, add Ui::new_infallible
Simon Sapin <simon.sapin@octobus.net>
parents: 48730
diff changeset
38 /// Default to no color if color configuration errors.
f591b377375f rhg: Make Ui::new falliable, add Ui::new_infallible
Simon Sapin <simon.sapin@octobus.net>
parents: 48730
diff changeset
39 ///
f591b377375f rhg: Make Ui::new falliable, add Ui::new_infallible
Simon Sapin <simon.sapin@octobus.net>
parents: 48730
diff changeset
40 /// Useful when we’re already handling another error.
48733
39c447e03dbc rhg: Add support for colored output
Simon Sapin <simon.sapin@octobus.net>
parents: 48731
diff changeset
41 pub fn new_infallible(config: &Config) -> Self {
45362
eb55274d3650 rhg: add buffered stdout writing possibility
Antoine Cezar <antoine.cezar@octobus.net>
parents: 45049
diff changeset
42 Ui {
48733
39c447e03dbc rhg: Add support for colored output
Simon Sapin <simon.sapin@octobus.net>
parents: 48731
diff changeset
43 // If using something else, also adapt `isatty()` below.
45362
eb55274d3650 rhg: add buffered stdout writing possibility
Antoine Cezar <antoine.cezar@octobus.net>
parents: 45049
diff changeset
44 stdout: std::io::stdout(),
48733
39c447e03dbc rhg: Add support for colored output
Simon Sapin <simon.sapin@octobus.net>
parents: 48731
diff changeset
45
45362
eb55274d3650 rhg: add buffered stdout writing possibility
Antoine Cezar <antoine.cezar@octobus.net>
parents: 45049
diff changeset
46 stderr: std::io::stderr(),
48733
39c447e03dbc rhg: Add support for colored output
Simon Sapin <simon.sapin@octobus.net>
parents: 48731
diff changeset
47 colors: ColorConfig::new(config).unwrap_or(None),
45362
eb55274d3650 rhg: add buffered stdout writing possibility
Antoine Cezar <antoine.cezar@octobus.net>
parents: 45049
diff changeset
48 }
eb55274d3650 rhg: add buffered stdout writing possibility
Antoine Cezar <antoine.cezar@octobus.net>
parents: 45049
diff changeset
49 }
eb55274d3650 rhg: add buffered stdout writing possibility
Antoine Cezar <antoine.cezar@octobus.net>
parents: 45049
diff changeset
50
eb55274d3650 rhg: add buffered stdout writing possibility
Antoine Cezar <antoine.cezar@octobus.net>
parents: 45049
diff changeset
51 /// Returns a buffered handle on stdout for faster batch printing
eb55274d3650 rhg: add buffered stdout writing possibility
Antoine Cezar <antoine.cezar@octobus.net>
parents: 45049
diff changeset
52 /// operations.
eb55274d3650 rhg: add buffered stdout writing possibility
Antoine Cezar <antoine.cezar@octobus.net>
parents: 45049
diff changeset
53 pub fn stdout_buffer(&self) -> StdoutBuffer<std::io::StdoutLock> {
eb55274d3650 rhg: add buffered stdout writing possibility
Antoine Cezar <antoine.cezar@octobus.net>
parents: 45049
diff changeset
54 StdoutBuffer::new(self.stdout.lock())
45049
513b3ef277a3 rhg: add RootCommand using hg-core FindRoot operation to prepare `hg root`
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
55 }
513b3ef277a3 rhg: add RootCommand using hg-core FindRoot operation to prepare `hg root`
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
56
513b3ef277a3 rhg: add RootCommand using hg-core FindRoot operation to prepare `hg root`
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
57 /// Write bytes to stdout
513b3ef277a3 rhg: add RootCommand using hg-core FindRoot operation to prepare `hg root`
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
58 pub fn write_stdout(&self, bytes: &[u8]) -> Result<(), UiError> {
45362
eb55274d3650 rhg: add buffered stdout writing possibility
Antoine Cezar <antoine.cezar@octobus.net>
parents: 45049
diff changeset
59 let mut stdout = self.stdout.lock();
45049
513b3ef277a3 rhg: add RootCommand using hg-core FindRoot operation to prepare `hg root`
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
60
45439
fbc373b7cbc3 rhg: fix `clippy` warnings
Antoine Cezar <antoine.cezar@octobus.net>
parents: 45367
diff changeset
61 stdout.write_all(bytes).or_else(handle_stdout_error)?;
45049
513b3ef277a3 rhg: add RootCommand using hg-core FindRoot operation to prepare `hg root`
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
62
45439
fbc373b7cbc3 rhg: fix `clippy` warnings
Antoine Cezar <antoine.cezar@octobus.net>
parents: 45367
diff changeset
63 stdout.flush().or_else(handle_stdout_error)
45049
513b3ef277a3 rhg: add RootCommand using hg-core FindRoot operation to prepare `hg root`
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
64 }
513b3ef277a3 rhg: add RootCommand using hg-core FindRoot operation to prepare `hg root`
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
65
513b3ef277a3 rhg: add RootCommand using hg-core FindRoot operation to prepare `hg root`
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
66 /// Write bytes to stderr
513b3ef277a3 rhg: add RootCommand using hg-core FindRoot operation to prepare `hg root`
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
67 pub fn write_stderr(&self, bytes: &[u8]) -> Result<(), UiError> {
45362
eb55274d3650 rhg: add buffered stdout writing possibility
Antoine Cezar <antoine.cezar@octobus.net>
parents: 45049
diff changeset
68 let mut stderr = self.stderr.lock();
45049
513b3ef277a3 rhg: add RootCommand using hg-core FindRoot operation to prepare `hg root`
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
69
45439
fbc373b7cbc3 rhg: fix `clippy` warnings
Antoine Cezar <antoine.cezar@octobus.net>
parents: 45367
diff changeset
70 stderr.write_all(bytes).or_else(handle_stderr_error)?;
45049
513b3ef277a3 rhg: add RootCommand using hg-core FindRoot operation to prepare `hg root`
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
71
45439
fbc373b7cbc3 rhg: fix `clippy` warnings
Antoine Cezar <antoine.cezar@octobus.net>
parents: 45367
diff changeset
72 stderr.flush().or_else(handle_stderr_error)
45049
513b3ef277a3 rhg: add RootCommand using hg-core FindRoot operation to prepare `hg root`
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
73 }
48176
38deb65d4441 rhg: add ui.plain() and check it before showing relative paths in status
Pulkit Goyal <7895pulkit@gmail.com>
parents: 46591
diff changeset
74
48733
39c447e03dbc rhg: Add support for colored output
Simon Sapin <simon.sapin@octobus.net>
parents: 48731
diff changeset
75 /// Write bytes to stdout with the given label
39c447e03dbc rhg: Add support for colored output
Simon Sapin <simon.sapin@octobus.net>
parents: 48731
diff changeset
76 ///
39c447e03dbc rhg: Add support for colored output
Simon Sapin <simon.sapin@octobus.net>
parents: 48731
diff changeset
77 /// Like the optional `label` parameter in `mercurial/ui.py`,
39c447e03dbc rhg: Add support for colored output
Simon Sapin <simon.sapin@octobus.net>
parents: 48731
diff changeset
78 /// this label influences the color used for this output.
39c447e03dbc rhg: Add support for colored output
Simon Sapin <simon.sapin@octobus.net>
parents: 48731
diff changeset
79 pub fn write_stdout_labelled(
39c447e03dbc rhg: Add support for colored output
Simon Sapin <simon.sapin@octobus.net>
parents: 48731
diff changeset
80 &self,
39c447e03dbc rhg: Add support for colored output
Simon Sapin <simon.sapin@octobus.net>
parents: 48731
diff changeset
81 bytes: &[u8],
39c447e03dbc rhg: Add support for colored output
Simon Sapin <simon.sapin@octobus.net>
parents: 48731
diff changeset
82 label: &str,
39c447e03dbc rhg: Add support for colored output
Simon Sapin <simon.sapin@octobus.net>
parents: 48731
diff changeset
83 ) -> Result<(), UiError> {
39c447e03dbc rhg: Add support for colored output
Simon Sapin <simon.sapin@octobus.net>
parents: 48731
diff changeset
84 if let Some(colors) = &self.colors {
39c447e03dbc rhg: Add support for colored output
Simon Sapin <simon.sapin@octobus.net>
parents: 48731
diff changeset
85 if let Some(effects) = colors.styles.get(label.as_bytes()) {
39c447e03dbc rhg: Add support for colored output
Simon Sapin <simon.sapin@octobus.net>
parents: 48731
diff changeset
86 if !effects.is_empty() {
39c447e03dbc rhg: Add support for colored output
Simon Sapin <simon.sapin@octobus.net>
parents: 48731
diff changeset
87 return self
39c447e03dbc rhg: Add support for colored output
Simon Sapin <simon.sapin@octobus.net>
parents: 48731
diff changeset
88 .write_stdout_with_effects(bytes, effects)
39c447e03dbc rhg: Add support for colored output
Simon Sapin <simon.sapin@octobus.net>
parents: 48731
diff changeset
89 .or_else(handle_stdout_error);
39c447e03dbc rhg: Add support for colored output
Simon Sapin <simon.sapin@octobus.net>
parents: 48731
diff changeset
90 }
39c447e03dbc rhg: Add support for colored output
Simon Sapin <simon.sapin@octobus.net>
parents: 48731
diff changeset
91 }
39c447e03dbc rhg: Add support for colored output
Simon Sapin <simon.sapin@octobus.net>
parents: 48731
diff changeset
92 }
39c447e03dbc rhg: Add support for colored output
Simon Sapin <simon.sapin@octobus.net>
parents: 48731
diff changeset
93 self.write_stdout(bytes)
39c447e03dbc rhg: Add support for colored output
Simon Sapin <simon.sapin@octobus.net>
parents: 48731
diff changeset
94 }
39c447e03dbc rhg: Add support for colored output
Simon Sapin <simon.sapin@octobus.net>
parents: 48731
diff changeset
95
39c447e03dbc rhg: Add support for colored output
Simon Sapin <simon.sapin@octobus.net>
parents: 48731
diff changeset
96 fn write_stdout_with_effects(
39c447e03dbc rhg: Add support for colored output
Simon Sapin <simon.sapin@octobus.net>
parents: 48731
diff changeset
97 &self,
39c447e03dbc rhg: Add support for colored output
Simon Sapin <simon.sapin@octobus.net>
parents: 48731
diff changeset
98 bytes: &[u8],
39c447e03dbc rhg: Add support for colored output
Simon Sapin <simon.sapin@octobus.net>
parents: 48731
diff changeset
99 effects: &[Effect],
39c447e03dbc rhg: Add support for colored output
Simon Sapin <simon.sapin@octobus.net>
parents: 48731
diff changeset
100 ) -> io::Result<()> {
39c447e03dbc rhg: Add support for colored output
Simon Sapin <simon.sapin@octobus.net>
parents: 48731
diff changeset
101 let stdout = &mut self.stdout.lock();
39c447e03dbc rhg: Add support for colored output
Simon Sapin <simon.sapin@octobus.net>
parents: 48731
diff changeset
102 let mut write_line = |line: &[u8], first: bool| {
39c447e03dbc rhg: Add support for colored output
Simon Sapin <simon.sapin@octobus.net>
parents: 48731
diff changeset
103 // `line` does not include the newline delimiter
39c447e03dbc rhg: Add support for colored output
Simon Sapin <simon.sapin@octobus.net>
parents: 48731
diff changeset
104 if !first {
39c447e03dbc rhg: Add support for colored output
Simon Sapin <simon.sapin@octobus.net>
parents: 48731
diff changeset
105 stdout.write_all(b"\n")?;
39c447e03dbc rhg: Add support for colored output
Simon Sapin <simon.sapin@octobus.net>
parents: 48731
diff changeset
106 }
39c447e03dbc rhg: Add support for colored output
Simon Sapin <simon.sapin@octobus.net>
parents: 48731
diff changeset
107 if line.is_empty() {
39c447e03dbc rhg: Add support for colored output
Simon Sapin <simon.sapin@octobus.net>
parents: 48731
diff changeset
108 return Ok(());
39c447e03dbc rhg: Add support for colored output
Simon Sapin <simon.sapin@octobus.net>
parents: 48731
diff changeset
109 }
39c447e03dbc rhg: Add support for colored output
Simon Sapin <simon.sapin@octobus.net>
parents: 48731
diff changeset
110 /// 0x1B == 27 == 0o33
39c447e03dbc rhg: Add support for colored output
Simon Sapin <simon.sapin@octobus.net>
parents: 48731
diff changeset
111 const ASCII_ESCAPE: &[u8] = b"\x1b";
39c447e03dbc rhg: Add support for colored output
Simon Sapin <simon.sapin@octobus.net>
parents: 48731
diff changeset
112 write_bytes!(stdout, b"{}[0", ASCII_ESCAPE)?;
39c447e03dbc rhg: Add support for colored output
Simon Sapin <simon.sapin@octobus.net>
parents: 48731
diff changeset
113 for effect in effects {
39c447e03dbc rhg: Add support for colored output
Simon Sapin <simon.sapin@octobus.net>
parents: 48731
diff changeset
114 write_bytes!(stdout, b";{}", effect)?;
39c447e03dbc rhg: Add support for colored output
Simon Sapin <simon.sapin@octobus.net>
parents: 48731
diff changeset
115 }
39c447e03dbc rhg: Add support for colored output
Simon Sapin <simon.sapin@octobus.net>
parents: 48731
diff changeset
116 write_bytes!(stdout, b"m")?;
39c447e03dbc rhg: Add support for colored output
Simon Sapin <simon.sapin@octobus.net>
parents: 48731
diff changeset
117 stdout.write_all(line)?;
39c447e03dbc rhg: Add support for colored output
Simon Sapin <simon.sapin@octobus.net>
parents: 48731
diff changeset
118 write_bytes!(stdout, b"{}[0m", ASCII_ESCAPE)
39c447e03dbc rhg: Add support for colored output
Simon Sapin <simon.sapin@octobus.net>
parents: 48731
diff changeset
119 };
39c447e03dbc rhg: Add support for colored output
Simon Sapin <simon.sapin@octobus.net>
parents: 48731
diff changeset
120 let mut lines = bytes.split(|&byte| byte == b'\n');
39c447e03dbc rhg: Add support for colored output
Simon Sapin <simon.sapin@octobus.net>
parents: 48731
diff changeset
121 if let Some(first) = lines.next() {
39c447e03dbc rhg: Add support for colored output
Simon Sapin <simon.sapin@octobus.net>
parents: 48731
diff changeset
122 write_line(first, true)?;
39c447e03dbc rhg: Add support for colored output
Simon Sapin <simon.sapin@octobus.net>
parents: 48731
diff changeset
123 for line in lines {
39c447e03dbc rhg: Add support for colored output
Simon Sapin <simon.sapin@octobus.net>
parents: 48731
diff changeset
124 write_line(line, false)?
39c447e03dbc rhg: Add support for colored output
Simon Sapin <simon.sapin@octobus.net>
parents: 48731
diff changeset
125 }
39c447e03dbc rhg: Add support for colored output
Simon Sapin <simon.sapin@octobus.net>
parents: 48731
diff changeset
126 }
39c447e03dbc rhg: Add support for colored output
Simon Sapin <simon.sapin@octobus.net>
parents: 48731
diff changeset
127 stdout.flush()
39c447e03dbc rhg: Add support for colored output
Simon Sapin <simon.sapin@octobus.net>
parents: 48731
diff changeset
128 }
48729
99b1dfc06571 rhg: Add support for HGPLAINEXPECT
Simon Sapin <simon.sapin@octobus.net>
parents: 48513
diff changeset
129 }
99b1dfc06571 rhg: Add support for HGPLAINEXPECT
Simon Sapin <simon.sapin@octobus.net>
parents: 48513
diff changeset
130
49513
467d9df98c68 rhg: centralize PlainInfo
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 49512
diff changeset
131 // TODO: pass the PlainInfo to call sites directly and
467d9df98c68 rhg: centralize PlainInfo
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 49512
diff changeset
132 // delete this function
48733
39c447e03dbc rhg: Add support for colored output
Simon Sapin <simon.sapin@octobus.net>
parents: 48731
diff changeset
133 pub fn plain(opt_feature: Option<&str>) -> bool {
49513
467d9df98c68 rhg: centralize PlainInfo
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 49512
diff changeset
134 let plain_info = PlainInfo::from_env();
467d9df98c68 rhg: centralize PlainInfo
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 49512
diff changeset
135 match opt_feature {
467d9df98c68 rhg: centralize PlainInfo
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 49512
diff changeset
136 None => plain_info.is_plain(),
467d9df98c68 rhg: centralize PlainInfo
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 49512
diff changeset
137 Some(feature) => plain_info.is_feature_plain(feature),
48176
38deb65d4441 rhg: add ui.plain() and check it before showing relative paths in status
Pulkit Goyal <7895pulkit@gmail.com>
parents: 46591
diff changeset
138 }
45049
513b3ef277a3 rhg: add RootCommand using hg-core FindRoot operation to prepare `hg root`
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
139 }
45362
eb55274d3650 rhg: add buffered stdout writing possibility
Antoine Cezar <antoine.cezar@octobus.net>
parents: 45049
diff changeset
140
eb55274d3650 rhg: add buffered stdout writing possibility
Antoine Cezar <antoine.cezar@octobus.net>
parents: 45049
diff changeset
141 /// A buffered stdout writer for faster batch printing operations.
eb55274d3650 rhg: add buffered stdout writing possibility
Antoine Cezar <antoine.cezar@octobus.net>
parents: 45049
diff changeset
142 pub struct StdoutBuffer<W: Write> {
eb55274d3650 rhg: add buffered stdout writing possibility
Antoine Cezar <antoine.cezar@octobus.net>
parents: 45049
diff changeset
143 buf: io::BufWriter<W>,
eb55274d3650 rhg: add buffered stdout writing possibility
Antoine Cezar <antoine.cezar@octobus.net>
parents: 45049
diff changeset
144 }
eb55274d3650 rhg: add buffered stdout writing possibility
Antoine Cezar <antoine.cezar@octobus.net>
parents: 45049
diff changeset
145
eb55274d3650 rhg: add buffered stdout writing possibility
Antoine Cezar <antoine.cezar@octobus.net>
parents: 45049
diff changeset
146 impl<W: Write> StdoutBuffer<W> {
eb55274d3650 rhg: add buffered stdout writing possibility
Antoine Cezar <antoine.cezar@octobus.net>
parents: 45049
diff changeset
147 pub fn new(writer: W) -> Self {
eb55274d3650 rhg: add buffered stdout writing possibility
Antoine Cezar <antoine.cezar@octobus.net>
parents: 45049
diff changeset
148 let buf = io::BufWriter::new(writer);
eb55274d3650 rhg: add buffered stdout writing possibility
Antoine Cezar <antoine.cezar@octobus.net>
parents: 45049
diff changeset
149 Self { buf }
eb55274d3650 rhg: add buffered stdout writing possibility
Antoine Cezar <antoine.cezar@octobus.net>
parents: 45049
diff changeset
150 }
eb55274d3650 rhg: add buffered stdout writing possibility
Antoine Cezar <antoine.cezar@octobus.net>
parents: 45049
diff changeset
151
eb55274d3650 rhg: add buffered stdout writing possibility
Antoine Cezar <antoine.cezar@octobus.net>
parents: 45049
diff changeset
152 /// Write bytes to stdout buffer
eb55274d3650 rhg: add buffered stdout writing possibility
Antoine Cezar <antoine.cezar@octobus.net>
parents: 45049
diff changeset
153 pub fn write_all(&mut self, bytes: &[u8]) -> Result<(), UiError> {
45439
fbc373b7cbc3 rhg: fix `clippy` warnings
Antoine Cezar <antoine.cezar@octobus.net>
parents: 45367
diff changeset
154 self.buf.write_all(bytes).or_else(handle_stdout_error)
45362
eb55274d3650 rhg: add buffered stdout writing possibility
Antoine Cezar <antoine.cezar@octobus.net>
parents: 45049
diff changeset
155 }
eb55274d3650 rhg: add buffered stdout writing possibility
Antoine Cezar <antoine.cezar@octobus.net>
parents: 45049
diff changeset
156
eb55274d3650 rhg: add buffered stdout writing possibility
Antoine Cezar <antoine.cezar@octobus.net>
parents: 45049
diff changeset
157 /// Flush bytes to stdout
eb55274d3650 rhg: add buffered stdout writing possibility
Antoine Cezar <antoine.cezar@octobus.net>
parents: 45049
diff changeset
158 pub fn flush(&mut self) -> Result<(), UiError> {
45439
fbc373b7cbc3 rhg: fix `clippy` warnings
Antoine Cezar <antoine.cezar@octobus.net>
parents: 45367
diff changeset
159 self.buf.flush().or_else(handle_stdout_error)
45362
eb55274d3650 rhg: add buffered stdout writing possibility
Antoine Cezar <antoine.cezar@octobus.net>
parents: 45049
diff changeset
160 }
eb55274d3650 rhg: add buffered stdout writing possibility
Antoine Cezar <antoine.cezar@octobus.net>
parents: 45049
diff changeset
161 }
45366
10c36ead86f8 rhg: extract function handle_stdout_error
Antoine Cezar <antoine.cezar@octobus.net>
parents: 45362
diff changeset
162
10c36ead86f8 rhg: extract function handle_stdout_error
Antoine Cezar <antoine.cezar@octobus.net>
parents: 45362
diff changeset
163 /// Sometimes writing to stdout is not possible, try writing to stderr to
10c36ead86f8 rhg: extract function handle_stdout_error
Antoine Cezar <antoine.cezar@octobus.net>
parents: 45362
diff changeset
164 /// signal that failure, otherwise just bail.
10c36ead86f8 rhg: extract function handle_stdout_error
Antoine Cezar <antoine.cezar@octobus.net>
parents: 45362
diff changeset
165 fn handle_stdout_error(error: io::Error) -> Result<(), UiError> {
10c36ead86f8 rhg: extract function handle_stdout_error
Antoine Cezar <antoine.cezar@octobus.net>
parents: 45362
diff changeset
166 if let ErrorKind::BrokenPipe = error.kind() {
10c36ead86f8 rhg: extract function handle_stdout_error
Antoine Cezar <antoine.cezar@octobus.net>
parents: 45362
diff changeset
167 // This makes `| head` work for example
10c36ead86f8 rhg: extract function handle_stdout_error
Antoine Cezar <antoine.cezar@octobus.net>
parents: 45362
diff changeset
168 return Ok(());
10c36ead86f8 rhg: extract function handle_stdout_error
Antoine Cezar <antoine.cezar@octobus.net>
parents: 45362
diff changeset
169 }
10c36ead86f8 rhg: extract function handle_stdout_error
Antoine Cezar <antoine.cezar@octobus.net>
parents: 45362
diff changeset
170 let mut stderr = io::stderr();
10c36ead86f8 rhg: extract function handle_stdout_error
Antoine Cezar <antoine.cezar@octobus.net>
parents: 45362
diff changeset
171
10c36ead86f8 rhg: extract function handle_stdout_error
Antoine Cezar <antoine.cezar@octobus.net>
parents: 45362
diff changeset
172 stderr
45984
fada33872b5b rhg: use `format_bytes!` for error messages
Rapha?l Gom?s <rgomes@octobus.net>
parents: 45528
diff changeset
173 .write_all(&format_bytes!(
fada33872b5b rhg: use `format_bytes!` for error messages
Rapha?l Gom?s <rgomes@octobus.net>
parents: 45528
diff changeset
174 b"abort: {}\n",
fada33872b5b rhg: use `format_bytes!` for error messages
Rapha?l Gom?s <rgomes@octobus.net>
parents: 45528
diff changeset
175 error.to_string().as_bytes()
fada33872b5b rhg: use `format_bytes!` for error messages
Rapha?l Gom?s <rgomes@octobus.net>
parents: 45528
diff changeset
176 ))
45439
fbc373b7cbc3 rhg: fix `clippy` warnings
Antoine Cezar <antoine.cezar@octobus.net>
parents: 45367
diff changeset
177 .map_err(UiError::StderrError)?;
45366
10c36ead86f8 rhg: extract function handle_stdout_error
Antoine Cezar <antoine.cezar@octobus.net>
parents: 45362
diff changeset
178
45439
fbc373b7cbc3 rhg: fix `clippy` warnings
Antoine Cezar <antoine.cezar@octobus.net>
parents: 45367
diff changeset
179 stderr.flush().map_err(UiError::StderrError)?;
45366
10c36ead86f8 rhg: extract function handle_stdout_error
Antoine Cezar <antoine.cezar@octobus.net>
parents: 45362
diff changeset
180
10c36ead86f8 rhg: extract function handle_stdout_error
Antoine Cezar <antoine.cezar@octobus.net>
parents: 45362
diff changeset
181 Err(UiError::StdoutError(error))
10c36ead86f8 rhg: extract function handle_stdout_error
Antoine Cezar <antoine.cezar@octobus.net>
parents: 45362
diff changeset
182 }
45367
53af26aa5951 rhg: handle broken pipe error for stderr
Antoine Cezar <antoine.cezar@octobus.net>
parents: 45366
diff changeset
183
53af26aa5951 rhg: handle broken pipe error for stderr
Antoine Cezar <antoine.cezar@octobus.net>
parents: 45366
diff changeset
184 /// Sometimes writing to stderr is not possible.
53af26aa5951 rhg: handle broken pipe error for stderr
Antoine Cezar <antoine.cezar@octobus.net>
parents: 45366
diff changeset
185 fn handle_stderr_error(error: io::Error) -> Result<(), UiError> {
53af26aa5951 rhg: handle broken pipe error for stderr
Antoine Cezar <antoine.cezar@octobus.net>
parents: 45366
diff changeset
186 // A broken pipe should not result in a error
53af26aa5951 rhg: handle broken pipe error for stderr
Antoine Cezar <antoine.cezar@octobus.net>
parents: 45366
diff changeset
187 // like with `| head` for example
53af26aa5951 rhg: handle broken pipe error for stderr
Antoine Cezar <antoine.cezar@octobus.net>
parents: 45366
diff changeset
188 if let ErrorKind::BrokenPipe = error.kind() {
53af26aa5951 rhg: handle broken pipe error for stderr
Antoine Cezar <antoine.cezar@octobus.net>
parents: 45366
diff changeset
189 return Ok(());
53af26aa5951 rhg: handle broken pipe error for stderr
Antoine Cezar <antoine.cezar@octobus.net>
parents: 45366
diff changeset
190 }
53af26aa5951 rhg: handle broken pipe error for stderr
Antoine Cezar <antoine.cezar@octobus.net>
parents: 45366
diff changeset
191 Err(UiError::StdoutError(error))
53af26aa5951 rhg: handle broken pipe error for stderr
Antoine Cezar <antoine.cezar@octobus.net>
parents: 45366
diff changeset
192 }
45528
66756b34c06e rhg: add a `DebugData` `Command` to prepare the `rhg debugdata` subcommand
Antoine Cezar <antoine.cezar@octobus.net>
parents: 45440
diff changeset
193
66756b34c06e rhg: add a `DebugData` `Command` to prepare the `rhg debugdata` subcommand
Antoine Cezar <antoine.cezar@octobus.net>
parents: 45440
diff changeset
194 /// Encode rust strings according to the user system.
66756b34c06e rhg: add a `DebugData` `Command` to prepare the `rhg debugdata` subcommand
Antoine Cezar <antoine.cezar@octobus.net>
parents: 45440
diff changeset
195 pub fn utf8_to_local(s: &str) -> Cow<[u8]> {
66756b34c06e rhg: add a `DebugData` `Command` to prepare the `rhg debugdata` subcommand
Antoine Cezar <antoine.cezar@octobus.net>
parents: 45440
diff changeset
196 // TODO encode for the user's system //
66756b34c06e rhg: add a `DebugData` `Command` to prepare the `rhg debugdata` subcommand
Antoine Cezar <antoine.cezar@octobus.net>
parents: 45440
diff changeset
197 let bytes = s.as_bytes();
66756b34c06e rhg: add a `DebugData` `Command` to prepare the `rhg debugdata` subcommand
Antoine Cezar <antoine.cezar@octobus.net>
parents: 45440
diff changeset
198 Cow::Borrowed(bytes)
66756b34c06e rhg: add a `DebugData` `Command` to prepare the `rhg debugdata` subcommand
Antoine Cezar <antoine.cezar@octobus.net>
parents: 45440
diff changeset
199 }
48733
39c447e03dbc rhg: Add support for colored output
Simon Sapin <simon.sapin@octobus.net>
parents: 48731
diff changeset
200
48770
f19be290756a rhg: signal when falling back in logs
Rapha?l Gom?s <rgomes@octobus.net>
parents: 48734
diff changeset
201 /// Decode user system bytes to Rust string.
f19be290756a rhg: signal when falling back in logs
Rapha?l Gom?s <rgomes@octobus.net>
parents: 48734
diff changeset
202 pub fn local_to_utf8(s: &[u8]) -> Cow<str> {
f19be290756a rhg: signal when falling back in logs
Rapha?l Gom?s <rgomes@octobus.net>
parents: 48734
diff changeset
203 // TODO decode from the user's system
f19be290756a rhg: signal when falling back in logs
Rapha?l Gom?s <rgomes@octobus.net>
parents: 48734
diff changeset
204 String::from_utf8_lossy(s)
f19be290756a rhg: signal when falling back in logs
Rapha?l Gom?s <rgomes@octobus.net>
parents: 48734
diff changeset
205 }
f19be290756a rhg: signal when falling back in logs
Rapha?l Gom?s <rgomes@octobus.net>
parents: 48734
diff changeset
206
48733
39c447e03dbc rhg: Add support for colored output
Simon Sapin <simon.sapin@octobus.net>
parents: 48731
diff changeset
207 /// Should formatted output be used?
39c447e03dbc rhg: Add support for colored output
Simon Sapin <simon.sapin@octobus.net>
parents: 48731
diff changeset
208 ///
39c447e03dbc rhg: Add support for colored output
Simon Sapin <simon.sapin@octobus.net>
parents: 48731
diff changeset
209 /// Note: rhg does not have the formatter mechanism yet,
39c447e03dbc rhg: Add support for colored output
Simon Sapin <simon.sapin@octobus.net>
parents: 48731
diff changeset
210 /// but this is also used when deciding whether to use color.
39c447e03dbc rhg: Add support for colored output
Simon Sapin <simon.sapin@octobus.net>
parents: 48731
diff changeset
211 pub fn formatted(config: &Config) -> Result<bool, HgError> {
39c447e03dbc rhg: Add support for colored output
Simon Sapin <simon.sapin@octobus.net>
parents: 48731
diff changeset
212 if let Some(formatted) = config.get_option(b"ui", b"formatted")? {
39c447e03dbc rhg: Add support for colored output
Simon Sapin <simon.sapin@octobus.net>
parents: 48731
diff changeset
213 Ok(formatted)
39c447e03dbc rhg: Add support for colored output
Simon Sapin <simon.sapin@octobus.net>
parents: 48731
diff changeset
214 } else {
39c447e03dbc rhg: Add support for colored output
Simon Sapin <simon.sapin@octobus.net>
parents: 48731
diff changeset
215 isatty(config)
39c447e03dbc rhg: Add support for colored output
Simon Sapin <simon.sapin@octobus.net>
parents: 48731
diff changeset
216 }
39c447e03dbc rhg: Add support for colored output
Simon Sapin <simon.sapin@octobus.net>
parents: 48731
diff changeset
217 }
39c447e03dbc rhg: Add support for colored output
Simon Sapin <simon.sapin@octobus.net>
parents: 48731
diff changeset
218
39c447e03dbc rhg: Add support for colored output
Simon Sapin <simon.sapin@octobus.net>
parents: 48731
diff changeset
219 fn isatty(config: &Config) -> Result<bool, HgError> {
39c447e03dbc rhg: Add support for colored output
Simon Sapin <simon.sapin@octobus.net>
parents: 48731
diff changeset
220 Ok(if config.get_bool(b"ui", b"nontty")? {
39c447e03dbc rhg: Add support for colored output
Simon Sapin <simon.sapin@octobus.net>
parents: 48731
diff changeset
221 false
39c447e03dbc rhg: Add support for colored output
Simon Sapin <simon.sapin@octobus.net>
parents: 48731
diff changeset
222 } else {
39c447e03dbc rhg: Add support for colored output
Simon Sapin <simon.sapin@octobus.net>
parents: 48731
diff changeset
223 atty::is(atty::Stream::Stdout)
39c447e03dbc rhg: Add support for colored output
Simon Sapin <simon.sapin@octobus.net>
parents: 48731
diff changeset
224 })
39c447e03dbc rhg: Add support for colored output
Simon Sapin <simon.sapin@octobus.net>
parents: 48731
diff changeset
225 }