Skip to content

Commit

Permalink
chore: move split_line_* from repl/cmd.rs to utils/ (sigoden#190)
Browse files Browse the repository at this point in the history
  • Loading branch information
sigoden authored and rooct committed Nov 30, 2023
1 parent c2b92fb commit 952aa3f
Show file tree
Hide file tree
Showing 8 changed files with 225 additions and 222 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ temperature: 1.0 # GPT temperature, between 0 and 2
save: true # Whether to save the message
highlight: true # Set false to turn highlight
light_theme: false # Whether to use a light theme
wrap: no # Specify the text-wrapping mode (*no*, auto, <max-width>)
wrap: no # Specify the text-wrapping mode (no, auto, <max-width>)
wrap_code: false # Whether wrap code block
auto_copy: false # Automatically copy the last output to the clipboard
keybindings: emacs # REPL keybindings. values: emacs, vi
Expand Down
2 changes: 1 addition & 1 deletion config.example.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ temperature: 1.0 # GPT temperature, between 0 and 2
save: true # Whether to save the message
highlight: true # Set false to turn highlight
light_theme: false # Whether to use a light theme
wrap: no # Specify the text-wrapping mode (no*, auto, <max-width>)
wrap: no # Specify the text-wrapping mode (no, auto, <max-width>)
wrap_code: false # Whether wrap code block
auto_copy: false # Automatically copy the last output to the clipboard
keybindings: emacs # REPL keybindings. values: emacs, vi
Expand Down
2 changes: 1 addition & 1 deletion src/cli.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ pub struct Cli {
/// No stream output
#[clap(short = 'S', long)]
pub no_stream: bool,
/// Specify the text-wrapping mode (no*, auto, <max-width>)
/// Specify the text-wrapping mode (no, auto, <max-width>)
#[clap(short = 'w', long)]
pub wrap: Option<String>,
/// Use light theme
Expand Down
2 changes: 1 addition & 1 deletion src/config/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ pub struct Config {
pub dry_run: bool,
/// Whether to use a light theme
pub light_theme: bool,
/// Specify the text-wrapping mode (*no*, auto, <max-width>)
/// Specify the text-wrapping mode (no, auto, <max-width>)
pub wrap: Option<String>,
/// Whether wrap code block
pub wrap_code: bool,
Expand Down
218 changes: 1 addition & 217 deletions src/render/cmd.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ use super::MarkdownRender;

use crate::print_now;
use crate::repl::{ReplyStreamEvent, SharedAbortSignal};
use crate::utils::{spaces, split_line_sematic, split_line_tail};

use anyhow::Result;
use crossbeam::channel::Receiver;
Expand Down Expand Up @@ -65,220 +66,3 @@ pub fn cmd_render_stream(
}
Ok(())
}

fn split_line_sematic(text: &str) -> Option<(String, String)> {
let mut balance: Vec<Kind> = Vec::new();
let chars: Vec<char> = text.chars().collect();
let mut index = 0;
let len = chars.len();
while index < len - 1 {
let ch = chars[index];
if balance.is_empty()
&& ((matches!(ch, ',' | '.' | ';') && chars[index + 1].is_whitespace())
|| matches!(ch, ',' | '。' | ';'))
{
let (output, remain) = chars.split_at(index + 1);
return Some((output.iter().collect(), remain.iter().collect()));
}
if index + 2 < len && do_balance(&mut balance, &chars[index..=index + 2]) {
index += 3;
continue;
}
if do_balance(&mut balance, &chars[index..=index + 1]) {
index += 2;
continue;
}
do_balance(&mut balance, &chars[index..=index]);
index += 1;
}

None
}

pub(crate) fn split_line_tail(text: &str) -> (&str, &str) {
if let Some((head, tail)) = text.rsplit_once('\n') {
(head, tail)
} else {
("", text)
}
}

fn spaces(n: usize) -> String {
" ".repeat(n)
}

#[derive(Debug, Clone, Copy, Eq, PartialEq)]
enum Kind {
ParentheseStart,
ParentheseEnd,
BracketStart,
BracketEnd,
Asterisk,
Asterisk2,
SingleQuota,
DoubleQuota,
Tilde,
Tilde2,
Backtick,
Backtick3,
}

impl Kind {
fn from_chars(chars: &[char]) -> Option<Self> {
let kind = match chars.len() {
1 => match chars[0] {
'(' => Self::ParentheseStart,
')' => Self::ParentheseEnd,
'[' => Self::BracketStart,
']' => Self::BracketEnd,
'*' => Self::Asterisk,
'\'' => Self::SingleQuota,
'"' => Self::DoubleQuota,
'~' => Self::Tilde,
'`' => Self::Backtick,
_ => return None,
},
2 if chars[0] == chars[1] => match chars[0] {
'*' => Self::Asterisk2,
'~' => Self::Tilde2,
_ => return None,
},
3 => {
if chars == ['`', '`', '`'] {
Self::Backtick3
} else {
return None;
}
}
_ => return None,
};
Some(kind)
}
}

fn do_balance(balance: &mut Vec<Kind>, chars: &[char]) -> bool {
Kind::from_chars(chars).map_or(false, |kind| {
let last = balance.last();
match (kind, last) {
(Kind::ParentheseEnd, Some(&Kind::ParentheseStart))
| (Kind::BracketEnd, Some(&Kind::BracketStart))
| (Kind::Asterisk, Some(&Kind::Asterisk))
| (Kind::Asterisk2, Some(&Kind::Asterisk2))
| (Kind::SingleQuota, Some(&Kind::SingleQuota))
| (Kind::DoubleQuota, Some(&Kind::DoubleQuota))
| (Kind::Tilde, Some(&Kind::Tilde))
| (Kind::Tilde2, Some(&Kind::Tilde2))
| (Kind::Backtick, Some(&Kind::Backtick))
| (Kind::Backtick3, Some(&Kind::Backtick3)) => {
balance.pop();
true
}
(
Kind::ParentheseStart
| Kind::BracketStart
| Kind::Asterisk
| Kind::Asterisk2
| Kind::SingleQuota
| Kind::DoubleQuota
| Kind::Tilde
| Kind::Tilde2
| Kind::Backtick
| Kind::Backtick3,
_,
) => {
balance.push(kind);
true
}
_ => false,
}
})
}

#[cfg(test)]
mod tests {
use super::*;

macro_rules! assert_split_line {
($a:literal, $b:literal, true) => {
assert_eq!(
split_line_sematic(&format!("{}{}", $a, $b)),
Some(($a.into(), $b.into()))
);
};
($a:literal, $b:literal, false) => {
assert_eq!(split_line_sematic(&format!("{}{}", $a, $b)), None);
};
}

#[test]
fn test_split_line() {
assert_split_line!(
"Lorem ipsum dolor sit amet,",
" consectetur adipiscing elit.",
true
);
assert_split_line!(
"Lorem ipsum dolor sit amet.",
" consectetur adipiscing elit.",
true
);
assert_split_line!("黃更室幼許刀知,", "波食小午足田世根候法。", true);
assert_split_line!("黃更室幼許刀知。", "波食小午足田世根候法。", true);
assert_split_line!("黃更室幼許刀知;", "波食小午足田世根候法。", true);
assert_split_line!(
"Lorem ipsum (dolor sit amet).",
" consectetur adipiscing elit.",
true
);
assert_split_line!(
"Lorem ipsum dolor sit `amet,",
" consectetur` adipiscing elit.",
false
);
assert_split_line!(
"Lorem ipsum dolor sit ```amet,",
" consectetur``` adipiscing elit.",
false
);
assert_split_line!(
"Lorem ipsum dolor sit *amet,",
" consectetur* adipiscing elit.",
false
);
assert_split_line!(
"Lorem ipsum dolor sit **amet,",
" consectetur** adipiscing elit.",
false
);
assert_split_line!(
"Lorem ipsum dolor sit ~amet,",
" consectetur~ adipiscing elit.",
false
);
assert_split_line!(
"Lorem ipsum dolor sit ~~amet,",
" consectetur~~ adipiscing elit.",
false
);
assert_split_line!(
"Lorem ipsum dolor sit ``amet,",
" consectetur`` adipiscing elit.",
true
);
assert_split_line!(
"Lorem ipsum dolor sit \"amet,",
" consectetur\" adipiscing elit.",
false
);
assert_split_line!(
"Lorem ipsum dolor sit 'amet,",
" consectetur' adipiscing elit.",
false
);
assert_split_line!(
"Lorem ipsum dolor sit amet.",
"consectetur adipiscing elit.",
false
);
}
}
3 changes: 2 additions & 1 deletion src/render/repl.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
use super::{cmd::split_line_tail, MarkdownRender};
use super::MarkdownRender;

use crate::repl::{ReplyStreamEvent, SharedAbortSignal};
use crate::utils::split_line_tail;

use anyhow::Result;
use crossbeam::channel::Receiver;
Expand Down
2 changes: 2 additions & 0 deletions src/utils/mod.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
mod split_line;
mod tiktoken;

pub use self::split_line::*;
pub use self::tiktoken::cl100k_base_singleton;

use chrono::prelude::*;
Expand Down
Loading

0 comments on commit 952aa3f

Please sign in to comment.