mirror of
https://github.com/atuinsh/atuin.git
synced 2025-06-20 18:07:57 +02:00
fix(import/zsh): zsh use a special format to escape some characters (#1490)
* fix(import/zsh): zsh use a special format to escape some characters
unescape those correctly rather than throw them away.
zsh side code:
9f57ca4ac8/Src/utils.c (L4889-L4900)
* fix code style
This commit is contained in:
parent
434e8238d8
commit
c37147d619
@ -1,6 +1,7 @@
|
|||||||
// import old shell history!
|
// import old shell history!
|
||||||
// automatically hoover up all that we can find
|
// automatically hoover up all that we can find
|
||||||
|
|
||||||
|
use std::borrow::Cow;
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
|
|
||||||
use async_trait::async_trait;
|
use async_trait::async_trait;
|
||||||
@ -61,16 +62,16 @@ impl Importer for Zsh {
|
|||||||
|
|
||||||
let mut counter = 0;
|
let mut counter = 0;
|
||||||
for b in unix_byte_lines(&self.bytes) {
|
for b in unix_byte_lines(&self.bytes) {
|
||||||
let s = match std::str::from_utf8(b) {
|
let s = match unmetafy(b) {
|
||||||
Ok(s) => s,
|
Some(s) => s,
|
||||||
Err(_) => continue, // we can skip past things like invalid utf8
|
_ => continue, // we can skip past things like invalid utf8
|
||||||
};
|
};
|
||||||
|
|
||||||
if let Some(s) = s.strip_suffix('\\') {
|
if let Some(s) = s.strip_suffix('\\') {
|
||||||
line.push_str(s);
|
line.push_str(s);
|
||||||
line.push_str("\\\n");
|
line.push_str("\\\n");
|
||||||
} else {
|
} else {
|
||||||
line.push_str(s);
|
line.push_str(&s);
|
||||||
let command = std::mem::take(&mut line);
|
let command = std::mem::take(&mut line);
|
||||||
|
|
||||||
if let Some(command) = command.strip_prefix(": ") {
|
if let Some(command) = command.strip_prefix(": ") {
|
||||||
@ -116,6 +117,26 @@ fn parse_extended(line: &str, counter: i64) -> History {
|
|||||||
imported.build().into()
|
imported.build().into()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn unmetafy(line: &[u8]) -> Option<Cow<str>> {
|
||||||
|
if line.contains(&0x83) {
|
||||||
|
let mut s = Vec::with_capacity(line.len());
|
||||||
|
let mut is_meta = false;
|
||||||
|
for ch in line {
|
||||||
|
if *ch == 0x83 {
|
||||||
|
is_meta = true;
|
||||||
|
} else if is_meta {
|
||||||
|
is_meta = false;
|
||||||
|
s.push(*ch ^ 32);
|
||||||
|
} else {
|
||||||
|
s.push(*ch)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
String::from_utf8(s).ok().map(Cow::Owned)
|
||||||
|
} else {
|
||||||
|
std::str::from_utf8(line).ok().map(Cow::Borrowed)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod test {
|
mod test {
|
||||||
use itertools::assert_equal;
|
use itertools::assert_equal;
|
||||||
@ -188,4 +209,21 @@ cargo update
|
|||||||
],
|
],
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[tokio::test]
|
||||||
|
async fn test_parse_metafied() {
|
||||||
|
let bytes =
|
||||||
|
b"echo \xe4\xbd\x83\x80\xe5\xa5\xbd\nls ~/\xe9\x83\xbf\xb3\xe4\xb9\x83\xb0\n".to_vec();
|
||||||
|
|
||||||
|
let mut zsh = Zsh { bytes };
|
||||||
|
assert_eq!(zsh.entries().await.unwrap(), 2);
|
||||||
|
|
||||||
|
let mut loader = TestLoader::default();
|
||||||
|
zsh.load(&mut loader).await.unwrap();
|
||||||
|
|
||||||
|
assert_equal(
|
||||||
|
loader.buf.iter().map(|h| h.command.as_str()),
|
||||||
|
["echo 你好", "ls ~/音乐"],
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user