@@ -45,6 +45,54 @@ pub mod color {
45
45
pub static BRIGHT_WHITE : Color = 15u16 ;
46
46
}
47
47
48
+ pub mod attr {
49
+ /// Terminal attributes for use with term.attr().
50
+ /// Most attributes can only be turned on and must be turned off with term.reset().
51
+ /// The ones that can be turned off explicitly take a boolean value.
52
+ /// Color is also represented as an attribute for convenience.
53
+ pub enum Attr {
54
+ /// Bold (or possibly bright) mode
55
+ Bold ,
56
+ /// Dim mode, also called faint or half-bright. Often not supported
57
+ Dim ,
58
+ /// Italics mode. Often not supported
59
+ Italic ( bool ) ,
60
+ /// Underline mode
61
+ Underline ( bool ) ,
62
+ /// Blink mode
63
+ Blink ,
64
+ /// Standout mode. Often implemented as Reverse, sometimes coupled with Bold
65
+ Standout ( bool ) ,
66
+ /// Reverse mode, inverts the foreground and background colors
67
+ Reverse ,
68
+ /// Secure mode, also called invis mode. Hides the printed text
69
+ Secure ,
70
+ /// Convenience attribute to set the foreground color
71
+ ForegroundColor ( super :: color:: Color ) ,
72
+ /// Convenience attribute to set the background color
73
+ BackgroundColor ( super :: color:: Color )
74
+ }
75
+ }
76
+
77
+ #[ cfg( not( target_os = "win32" ) ) ]
78
+ priv fn cap_for_attr ( attr : attr:: Attr ) -> & ' static str {
79
+ match attr {
80
+ attr:: Bold => "bold" ,
81
+ attr:: Dim => "dim" ,
82
+ attr:: Italic ( true ) => "sitm" ,
83
+ attr:: Italic ( false ) => "ritm" ,
84
+ attr:: Underline ( true ) => "smul" ,
85
+ attr:: Underline ( false ) => "rmul" ,
86
+ attr:: Blink => "blink" ,
87
+ attr:: Standout ( true ) => "smso" ,
88
+ attr:: Standout ( false ) => "rmso" ,
89
+ attr:: Reverse => "rev" ,
90
+ attr:: Secure => "invis" ,
91
+ attr:: ForegroundColor ( _) => "setaf" ,
92
+ attr:: BackgroundColor ( _) => "setab"
93
+ }
94
+ }
95
+
48
96
#[ cfg( not( target_os = "win32" ) ) ]
49
97
pub struct Terminal {
50
98
num_colors : u16 ,
@@ -124,17 +172,64 @@ impl Terminal {
124
172
}
125
173
false
126
174
}
175
+
176
+ /// Sets the given terminal attribute, if supported.
177
+ /// Returns true if the attribute was supported, false otherwise.
178
+ pub fn attr ( & self , attr : attr:: Attr ) -> bool {
179
+ match attr {
180
+ attr:: ForegroundColor ( c) => self . fg ( c) ,
181
+ attr:: BackgroundColor ( c) => self . bg ( c) ,
182
+ _ => {
183
+ let cap = cap_for_attr ( attr) ;
184
+ let parm = self . ti . strings . find_equiv ( & cap) ;
185
+ if parm. is_some ( ) {
186
+ let s = expand ( * parm. unwrap ( ) , [ ] , & mut Variables :: new ( ) ) ;
187
+ if s. is_ok ( ) {
188
+ self . out . write ( s. unwrap ( ) ) ;
189
+ return true
190
+ } else {
191
+ warn ! ( "%s" , s. unwrap_err( ) ) ;
192
+ }
193
+ }
194
+ false
195
+ }
196
+ }
197
+ }
198
+
199
+ /// Returns whether the given terminal attribute is supported.
200
+ pub fn supports_attr ( & self , attr : attr:: Attr ) -> bool {
201
+ match attr {
202
+ attr:: ForegroundColor ( _) | attr:: BackgroundColor ( _) => {
203
+ self . num_colors > 0
204
+ }
205
+ _ => {
206
+ let cap = cap_for_attr ( attr) ;
207
+ self . ti . strings . find_equiv ( & cap) . is_some ( )
208
+ }
209
+ }
210
+ }
211
+
212
+ /// Resets all terminal attributes and color to the default.
127
213
pub fn reset ( & self ) {
128
- let mut vars = Variables :: new ( ) ;
129
- let s = do self . ti . strings . find_equiv ( & ( "op" ) )
130
- . map_consume_default ( Err ( ~"can' t find terminfo capability `op`") ) |op| {
131
- expand ( copy * op, [ ] , & mut vars)
132
- } ;
214
+ let mut cap = self . ti . strings . find_equiv ( & ( "sgr0" ) ) ;
215
+ if cap. is_none ( ) {
216
+ // are there any terminals that have color/attrs and not sgr0?
217
+ // Try falling back to sgr, then op
218
+ cap = self . ti . strings . find_equiv ( & ( "sgr" ) ) ;
219
+ if cap. is_none ( ) {
220
+ cap = self . ti . strings . find_equiv ( & ( "op" ) ) ;
221
+ }
222
+ }
223
+ let s = do cap. map_consume_default ( Err ( ~"can' t find terminfo capability `sgr0`") ) |op| {
224
+ expand ( * op, [ ] , & mut Variables :: new ( ) )
225
+ } ;
133
226
if s. is_ok ( ) {
134
227
self . out . write ( s. unwrap ( ) ) ;
135
228
} else if self . num_colors > 0 {
136
229
warn ! ( "%s" , s. unwrap_err( ) ) ;
137
230
} else {
231
+ // if we support attributes but not color, it would be nice to still warn!()
232
+ // but it's not worth testing all known attributes just for this.
138
233
debug ! ( "%s" , s. unwrap_err( ) ) ;
139
234
}
140
235
}
@@ -160,6 +255,14 @@ impl Terminal {
160
255
false
161
256
}
162
257
258
+ pub fn attr ( & self , _attr : attr:: Attr ) -> bool {
259
+ false
260
+ }
261
+
262
+ pub fn supports_attr ( & self , _attr : attr:: Attr ) -> bool {
263
+ false
264
+ }
265
+
163
266
pub fn reset ( & self ) {
164
267
}
165
268
}
0 commit comments