3
3
use std:: collections:: HashMap ;
4
4
use std:: ffi:: CString ;
5
5
use linkroot;
6
- use std:: os:: raw:: c_char;
7
- use { shfunc, getshfunc, doshfunc, Shfunc } ;
6
+ use std:: os:: raw:: { c_char, c_void } ;
7
+ use { shfunc, getshfunc, doshfunc, Shfunc , newlinklist , insertlinknode , linknode } ;
8
8
9
- fn brackets_paint ( buf : & str , widget : & str , cursor : usize ) {
10
- let mut style: & str ;
9
+ pub fn brackets_paint ( buf : & str , widget : & str , cursor : usize ) {
10
+ let mut style: String ;
11
11
let mut level: usize = 0 ;
12
12
let mut matching_pos: usize = 0 ;
13
- let mut bracket_color_size: usize = 0 ;
13
+ let mut bracket_color_size: usize = 5 ; // TODO
14
14
let mut buf_len: usize = 0 ;
15
15
let mut pos: usize = 0 ;
16
16
@@ -29,7 +29,10 @@ fn brackets_paint(buf: &str, widget: &str, cursor: usize) {
29
29
last_of_level. insert ( level, i) ;
30
30
} ,
31
31
')' | ']' | '}' => {
32
- matching_pos = * last_of_level. get ( & level) . unwrap ( ) ;
32
+ let matching_pos = match last_of_level. get ( & level) {
33
+ Some ( val) => * val,
34
+ None => continue
35
+ } ;
33
36
level_pos. insert ( i, level) ;
34
37
level -= 1 ;
35
38
@@ -50,20 +53,21 @@ fn brackets_paint(buf: &str, widget: &str, cursor: usize) {
50
53
}
51
54
}
52
55
53
- for pos in level_pos. values ( ) {
56
+ for pos in level_pos. keys ( ) {
54
57
if matching. contains_key ( pos) {
55
- style = "fg=yellow" ; // TODO
58
+ style = format ! ( "bracket-level-{}" , ( ( level_pos [ pos ] - 1 ) % bracket_color_size ) + 1 ) ;
56
59
} else {
57
- style = "fg=red" ;
60
+ style = "bracket-error" . to_owned ( ) ;
58
61
}
62
+ do_highlight ( * pos, * pos + 1 , & style) ;
59
63
60
64
}
61
65
62
66
if widget != "zle-line-finish" {
63
67
pos = cursor + 1 ;
64
68
if level_pos. get ( & pos) . is_some ( ) && matching. get ( & pos) . is_some ( ) {
65
69
let other_pos = matching[ & pos] ;
66
- do_highlight ( other_pos - 1 , other_pos, "standout" ) ;
70
+ do_highlight ( other_pos, other_pos + 1 , "standout" ) ;
67
71
}
68
72
}
69
73
@@ -78,10 +82,27 @@ fn brackets_match(first: char, second: char) -> bool {
78
82
}
79
83
}
80
84
85
+ #[ cfg( not( test) ) ]
81
86
fn do_highlight ( start : usize , end : usize , style : & str ) {
82
- let func_name = CString :: new ( "_zsh_highlight_add_highlight" ) . unwrap ( ) ;
83
87
unsafe {
84
- let func: Shfunc = getshfunc ( func_name. as_ptr ( ) as * mut c_char ) ;
85
- doshfunc ( func, 0 as * mut linkroot , 1 ) ;
88
+ let func_name = str_to_ptr ( "_zsh_highlight_add_highlight" ) ;
89
+ let func = getshfunc ( func_name as * mut c_char ) ;
90
+
91
+ let list = newlinklist ( ) ;
92
+ insertlinknode ( list, ( * list) . list . as_ref ( ) . last as * const linknode as * mut linknode , func_name) ;
93
+ insertlinknode ( list, ( * list) . list . as_ref ( ) . last as * const linknode as * mut linknode , str_to_ptr ( & start. to_string ( ) ) ) ;
94
+ insertlinknode ( list, ( * list) . list . as_ref ( ) . last as * const linknode as * mut linknode , str_to_ptr ( & end. to_string ( ) ) ) ;
95
+ insertlinknode ( list, ( * list) . list . as_ref ( ) . last as * const linknode as * mut linknode , str_to_ptr ( style) ) ;
96
+
97
+ doshfunc ( func, list as * mut linkroot , 1 ) ;
86
98
}
87
99
}
100
+
101
+ #[ cfg( test) ]
102
+ fn do_highlight ( start : usize , end : usize , style : & str ) {
103
+ }
104
+
105
+
106
+ fn str_to_ptr ( s : & str ) -> * mut c_void {
107
+ CString :: new ( s. to_string ( ) ) . unwrap ( ) . into_raw ( ) as * mut c_void
108
+ }
0 commit comments