forked from dobkeratops/rustfind
-
Notifications
You must be signed in to change notification settings - Fork 0
/
text_formatting.rs
84 lines (78 loc) · 2.95 KB
/
text_formatting.rs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
/// tags: pretty print,code formatting,brace indentation, json braces, brackets,nesting
pub trait Indent {
fn indent(&self,tab_size:int,max_line_size:int)->Self;
}
impl Indent for StrBuf {
fn indent(&self,tabsize:int, linesize:int)->StrBuf {
// todo-write as iterators.
fn change_indent(c:u8)->int{
match c as char {
'{'|'('|'['=> 1,
'}'|')'|']'=> -1,
_ => 0
}
}
let mut a=StrBuf::from_str("");
let mut i=0;
let mut indent=0;
let len=self.len();
while i<len {
// skip leading whitespace. we are on a newline.
// todo - use iterator, rust strings can't be indexed efficiently, its utf8 codepoints..
while i<len && (self.as_bytes()[i]==' 'as u8 || self.as_bytes()[i]=='\t'as u8) { i+=1;}
// measure line size from here
let mut dii=0;
if change_indent(self.as_bytes()[i])<0 { indent-=1;dii=1}/*TODO-more elegant*/
let mut cur_linesize=indent*tabsize;
let mut ii=i;
let mut inner_brace_level=indent;
let mut last_open=len;
let first_base_delim=len;
while inner_brace_level>=indent && ii<len {
let c=self.as_bytes()[ii];
if c=='\n'as u8 {break};
if cur_linesize >= linesize {break};
cur_linesize+=1;
let di=change_indent(c);
if di>0 && inner_brace_level==indent {last_open=ii;};
inner_brace_level+=di;
if inner_brace_level==indent {
if di<0 ||c==','as u8||c==';'as u8 {
last_open=ii;
}
if c==','as u8||c==';'as u8 && first_base_delim==len {
//first_base_delim=ii;
}
}
ii+=1
}
{
let mut ii=0;
while ii<tabsize*indent { a.push_char(' '); ii+=1 }
}
indent+=dii; // the extra one we considered.
let init_indent=indent;
if cur_linesize<linesize
{
// copy the line. we dont overstep
while i<len && self.as_bytes()[i]!='\n'as u8 && indent>=init_indent && i<=first_base_delim && i<=last_open{
let c=self.as_bytes()[i];
indent+=change_indent(c);
a.push_char(c as char);
i+=1;
}
}
else {
// copy the line until the lines' last opening
while i<len && indent>=init_indent && i<=last_open && i<=first_base_delim{
let c=self.as_bytes()[i];
indent+=change_indent(c);
a.push_char(c as char);
i+=1;
}
}
a.push_char('\n');
}
a
}
}