1
1
mirror of https://github.com/wez/wezterm.git synced 2024-11-26 16:34:23 +03:00

wezterm-ssh: process Include statements

refs: https://github.com/wez/wezterm/issues/824
This commit is contained in:
Wez Furlong 2021-05-28 21:30:26 -07:00
parent 0b1b30c73a
commit 3093fb3eb6
4 changed files with 73 additions and 6 deletions

1
Cargo.lock generated
View File

@ -4994,6 +4994,7 @@ dependencies = [
"base64",
"dirs-next",
"filedescriptor",
"filenamegen",
"k9",
"log",
"portable-pty",

View File

@ -12,6 +12,7 @@ usually the best available version.
As features stabilize some brief notes about them will accumulate here.
* Fixed: ssh client would read `/etc/ssh/config` rather than the proper `/etc/ssh/ssh_config`
* Updated: ssh client now processes `Include` statements in ssh config
* x11: support for [VoidSymbol](config/keys.md#voidsymbol) in key assignments. Thanks to [@digitallyserviced](https://github.com/digitallyserviced)! [#759](https://github.com/wez/wezterm/pull/759)
* Fixed: UTF8-encoded-C1 control codes were not always recognized as control codes, and could result in a panic when later attempting to update the line. [#768](https://github.com/wez/wezterm/issues/768)
* Fixed: `wezterm cli split-pane` didn't use the current working dir of the source pane. [#766](https://github.com/wez/wezterm/issues/766)

View File

@ -15,6 +15,7 @@ anyhow = "1.0"
base64 = "0.13"
dirs-next = "2.0"
filedescriptor = { version="0.8", path = "../filedescriptor" }
filenamegen = "0.2"
log = "0.4"
portable-pty = { version="0.5", path = "../pty" }
regex = "1"

View File

@ -140,10 +140,70 @@ struct ParsedConfigFile {
}
impl ParsedConfigFile {
fn parse(s: &str) -> Self {
fn parse(s: &str, cwd: Option<&Path>) -> Self {
let mut options = ConfigMap::new();
let mut groups = vec![];
Self::parse_impl(s, cwd, &mut options, &mut groups);
Self { options, groups }
}
fn do_include(
pattern: &str,
cwd: Option<&Path>,
options: &mut ConfigMap,
groups: &mut Vec<MatchGroup>,
) {
match filenamegen::Glob::new(&pattern) {
Ok(g) => {
match cwd
.as_ref()
.map(|p| p.to_path_buf())
.or_else(|| std::env::current_dir().ok())
{
Some(cwd) => {
for path in g.walk(&cwd) {
let path = if path.is_absolute() {
path
} else {
cwd.join(path)
};
match std::fs::read_to_string(&path) {
Ok(data) => {
Self::parse_impl(&data, Some(&cwd), options, groups);
}
Err(err) => {
log::error!(
"error expanding `Include {}`: unable to open {}: {:#}",
pattern,
path.display(),
err
);
}
}
}
}
None => {
log::error!(
"error expanding `Include {}`: unable to determine cwd",
pattern
);
}
}
}
Err(err) => {
log::error!("error expanding `Include {}`: {:#}", pattern, err);
}
}
}
fn parse_impl(
s: &str,
cwd: Option<&Path>,
options: &mut ConfigMap,
groups: &mut Vec<MatchGroup>,
) {
for line in s.lines() {
let line = line.trim();
if line.is_empty() || line.starts_with('#') {
@ -177,6 +237,11 @@ impl ParsedConfigFile {
patterns
}
if k == "include" {
Self::do_include(v, cwd, options, groups);
continue;
}
if k == "host" {
let patterns = parse_pattern_list(v);
groups.push(MatchGroup {
@ -253,8 +318,6 @@ impl ParsedConfigFile {
}
}
}
Self { options, groups }
}
/// Apply configuration values that match the specified hostname to target,
@ -337,14 +400,15 @@ impl Config {
/// and add that to the list of configs.
pub fn add_config_string(&mut self, config_string: &str) {
self.config_files
.push(ParsedConfigFile::parse(config_string));
.push(ParsedConfigFile::parse(config_string, None));
}
/// Open `path`, read its contents and parse it as an `ssh_config` file,
/// adding that to the list of configs
pub fn add_config_file<P: AsRef<Path>>(&mut self, path: P) {
if let Ok(data) = std::fs::read_to_string(path) {
self.config_files.push(ParsedConfigFile::parse(&data));
if let Ok(data) = std::fs::read_to_string(path.as_ref()) {
self.config_files
.push(ParsedConfigFile::parse(&data, path.as_ref().parent()));
}
}