@ -16,7 +16,16 @@ Terminal::Terminal() : Source::CommonView() {
set_editable ( false ) ;
bold_tag = get_buffer ( ) - > create_tag ( ) ;
bold_tag - > property_weight ( ) = Pango : : WEIGHT_ULTRAHEAVY ;
bold_tag - > property_weight ( ) = Pango : : WEIGHT_BOLD ;
light_tag = get_buffer ( ) - > create_tag ( ) ;
light_tag - > property_weight ( ) = Pango : : WEIGHT_LIGHT ;
italic_tag = get_buffer ( ) - > create_tag ( ) ;
italic_tag - > property_style ( ) = Pango : : STYLE_ITALIC ;
underline_tag = get_buffer ( ) - > create_tag ( ) ;
underline_tag - > property_underline ( ) = Pango : : Underline : : UNDERLINE_SINGLE ;
strikethrough_tag = get_buffer ( ) - > create_tag ( ) ;
strikethrough_tag - > property_strikethrough ( ) = true ;
red_tag = get_buffer ( ) - > create_tag ( ) ;
green_tag = get_buffer ( ) - > create_tag ( ) ;
@ -24,7 +33,7 @@ Terminal::Terminal() : Source::CommonView() {
blue_tag = get_buffer ( ) - > create_tag ( ) ;
magenta_tag = get_buffer ( ) - > create_tag ( ) ;
cyan_tag = get_buffer ( ) - > create_tag ( ) ;
gray _tag = get_buffer ( ) - > create_tag ( ) ;
white _tag = get_buffer ( ) - > create_tag ( ) ;
link_tag = get_buffer ( ) - > create_tag ( ) ;
link_tag - > property_underline ( ) = Pango : : Underline : : UNDERLINE_SINGLE ;
@ -32,8 +41,8 @@ Terminal::Terminal() : Source::CommonView() {
invisible_tag = get_buffer ( ) - > create_tag ( ) ;
invisible_tag - > property_invisible ( ) = true ;
link_mouse_cursor = Gdk : : Cursor : : create ( Gdk : : CursorType : : HAND1 ) ;
default_mouse_cursor = Gdk : : Cursor : : create ( Gdk : : CursorType : : XTERM ) ;
link_mouse_cursor = Gdk : : Cursor : : create ( get_display ( ) , Gdk : : CursorType : : HAND1 ) ;
default_mouse_cursor = Gdk : : Cursor : : create ( get_display ( ) , Gdk : : CursorType : : XTERM ) ;
class DetectPossibleLink {
bool delimiter_found = false , dot_found = false ;
@ -110,7 +119,38 @@ Terminal::Terminal() : Source::CommonView() {
return { } ;
}
} ;
get_buffer ( ) - > signal_insert ( ) . connect ( [ this , detect_possible_link = DetectPossibleLink ( ) , parse_ansi_escape_sequence = ParseAnsiEscapeSequence ( ) , last_color = - 1 , last_color_sequence_mark = std : : shared_ptr < Source : : Mark > ( ) ] ( const Gtk : : TextIter & iter , const Glib : : ustring & text_ , int /*bytes*/ ) mutable {
class Code {
public :
int code = - 1 ;
std : : shared_ptr < Source : : Mark > start_mark ;
} ;
auto code_to_color_tag = [ this ] ( int code ) {
if ( code = = 31 )
return red_tag ;
else if ( code = = 32 )
return green_tag ;
else if ( code = = 33 )
return yellow_tag ;
else if ( code = = 34 )
return blue_tag ;
else if ( code = = 35 )
return magenta_tag ;
else if ( code = = 36 )
return cyan_tag ;
else if ( code = = 37 )
return white_tag ;
return Glib : : RefPtr < Gtk : : TextTag > ( ) ;
} ;
auto code_to_weight_tag = [ this ] ( int code ) {
if ( code = = 1 )
return bold_tag ;
else if ( code = = 2 )
return light_tag ;
return Glib : : RefPtr < Gtk : : TextTag > ( ) ;
} ;
get_buffer ( ) - > signal_insert ( ) . connect ( [ this , code_to_color_tag , code_to_weight_tag ,
detect_possible_link = DetectPossibleLink ( ) , parse_ansi_escape_sequence = ParseAnsiEscapeSequence ( ) ,
color_code = Code ( ) , weight_code = Code ( ) , italic_code = Code ( ) , underline_code = Code ( ) , strikethrough_code = Code ( ) ] ( const Gtk : : TextIter & iter , const Glib : : ustring & text_ , int /*bytes*/ ) mutable {
boost : : optional < Gtk : : TextIter > start_of_text ;
int line_nr_offset = 0 ;
auto get_line_nr = [ & ] {
@ -144,9 +184,31 @@ Terminal::Terminal() : Source::CommonView() {
start . backward_chars ( sequence - > length ) ;
get_buffer ( ) - > apply_tag ( invisible_tag , start , end ) ;
if ( sequence - > command = = ' m ' ) {
int color = - 1 ;
if ( sequence - > arguments . empty ( ) )
color = 0 ;
auto reset = [ & ] {
if ( color_code . start_mark ) {
auto tag = code_to_color_tag ( color_code . code ) ;
if ( tag )
get_buffer ( ) - > apply_tag ( tag , ( * color_code . start_mark ) - > get_iter ( ) , start ) ;
}
if ( weight_code . start_mark ) {
auto tag = code_to_weight_tag ( weight_code . code ) ;
if ( tag )
get_buffer ( ) - > apply_tag ( tag , ( * weight_code . start_mark ) - > get_iter ( ) , start ) ;
}
if ( italic_code . start_mark )
get_buffer ( ) - > apply_tag ( italic_tag , ( * italic_code . start_mark ) - > get_iter ( ) , start ) ;
if ( underline_code . start_mark )
get_buffer ( ) - > apply_tag ( underline_tag , ( * underline_code . start_mark ) - > get_iter ( ) , start ) ;
if ( strikethrough_code . start_mark )
get_buffer ( ) - > apply_tag ( strikethrough_tag , ( * strikethrough_code . start_mark ) - > get_iter ( ) , start ) ;
color_code = { } ;
weight_code = { } ;
italic_code = { } ;
underline_code = { } ;
strikethrough_code = { } ;
} ;
if ( sequence - > arguments . empty ( ) ) // Reset
reset ( ) ;
else {
size_t pos = 0 ;
size_t start_pos = pos ;
@ -154,16 +216,74 @@ Terminal::Terminal() : Source::CommonView() {
pos = sequence - > arguments . find ( " ; " , pos ) ;
try {
auto code = std : : stoi ( sequence - > arguments . substr ( start_pos , pos ! = std : : string : : npos ? pos - start_pos : pos ) ) ;
if ( code = = 39 )
color = 0 ;
else if ( code = = 38 ) {
color = 0 ;
break ; // Do not read next arguments
if ( code = = 0 ) // Reset
reset ( ) ;
else if ( code = = 1 | | code = = 2 ) { // Bold or faint
if ( weight_code . start_mark ) {
auto tag = code_to_weight_tag ( weight_code . code ) ;
if ( tag )
get_buffer ( ) - > apply_tag ( tag , ( * weight_code . start_mark ) - > get_iter ( ) , start ) ;
}
weight_code = { code , std : : make_shared < Source : : Mark > ( end ) } ;
}
else if ( code = = 3 ) // Italic
italic_code = { code , std : : make_shared < Source : : Mark > ( end ) } ;
else if ( code = = 4 ) // Underline
underline_code = { code , std : : make_shared < Source : : Mark > ( end ) } ;
else if ( code = = 9 ) // Strikethrough
strikethrough_code = { code , std : : make_shared < Source : : Mark > ( end ) } ;
else if ( code = = 22 ) { // Normal intensity
if ( weight_code . start_mark ) {
auto tag = code_to_weight_tag ( weight_code . code ) ;
if ( tag )
get_buffer ( ) - > apply_tag ( tag , ( * weight_code . start_mark ) - > get_iter ( ) , start ) ;
}
weight_code = { } ;
}
else if ( code = = 23 ) { // No italic
if ( italic_code . start_mark )
get_buffer ( ) - > apply_tag ( italic_tag , ( * italic_code . start_mark ) - > get_iter ( ) , start ) ;
italic_code = { } ;
}
else if ( code = = 48 | | code = = 58 )
break ; // Do not read next arguments
else if ( code = = 0 | | code = = 2 | | code = = 22 | | ( code > = 30 & & code < = 37 ) )
color = code ;
else if ( code = = 24 ) { // No underline
if ( underline_code . start_mark )
get_buffer ( ) - > apply_tag ( underline_tag , ( * underline_code . start_mark ) - > get_iter ( ) , start ) ;
underline_code = { } ;
}
else if ( code = = 29 ) { // No strikethrough
if ( strikethrough_code . start_mark )
get_buffer ( ) - > apply_tag ( strikethrough_tag , ( * strikethrough_code . start_mark ) - > get_iter ( ) , start ) ;
strikethrough_code = { } ;
}
else if ( code > = 30 & & code < = 37 ) { // Foreground color
if ( color_code . start_mark ) {
auto tag = code_to_color_tag ( color_code . code ) ;
if ( tag )
get_buffer ( ) - > apply_tag ( tag , ( * color_code . start_mark ) - > get_iter ( ) , start ) ;
}
color_code = { code , std : : make_shared < Source : : Mark > ( end ) } ;
}
else if ( code = = 38 ) { // Set specific color not supported
if ( color_code . start_mark ) {
auto tag = code_to_color_tag ( color_code . code ) ;
if ( tag )
get_buffer ( ) - > apply_tag ( tag , ( * color_code . start_mark ) - > get_iter ( ) , start ) ;
}
color_code = { } ;
break ;
}
else if ( code = = 39 ) { // Default color
if ( color_code . start_mark ) {
auto tag = code_to_color_tag ( color_code . code ) ;
if ( tag )
get_buffer ( ) - > apply_tag ( tag , ( * color_code . start_mark ) - > get_iter ( ) , start ) ;
}
color_code = { } ;
}
else if ( code = = 48 ) // Set specific background color not supported
break ;
else if ( code = = 58 ) // Set specific underline color not supported
break ;
}
catch ( . . . ) {
}
@ -173,27 +293,6 @@ Terminal::Terminal() : Source::CommonView() {
start_pos = pos ;
}
}
if ( last_color > = 0 ) {
if ( last_color = = 31 )
get_buffer ( ) - > apply_tag ( red_tag , ( * last_color_sequence_mark ) - > get_iter ( ) , start ) ;
else if ( last_color = = 32 )
get_buffer ( ) - > apply_tag ( green_tag , ( * last_color_sequence_mark ) - > get_iter ( ) , start ) ;
else if ( last_color = = 33 )
get_buffer ( ) - > apply_tag ( yellow_tag , ( * last_color_sequence_mark ) - > get_iter ( ) , start ) ;
else if ( last_color = = 34 )
get_buffer ( ) - > apply_tag ( blue_tag , ( * last_color_sequence_mark ) - > get_iter ( ) , start ) ;
else if ( last_color = = 35 )
get_buffer ( ) - > apply_tag ( magenta_tag , ( * last_color_sequence_mark ) - > get_iter ( ) , start ) ;
else if ( last_color = = 36 )
get_buffer ( ) - > apply_tag ( cyan_tag , ( * last_color_sequence_mark ) - > get_iter ( ) , start ) ;
else if ( last_color = = 37 | | last_color = = 2 )
get_buffer ( ) - > apply_tag ( gray_tag , ( * last_color_sequence_mark ) - > get_iter ( ) , start ) ;
}
if ( color > = 0 ) {
last_color = color ;
last_color_sequence_mark = std : : make_shared < Source : : Mark > ( end ) ;
}
}
}
if ( text [ i ] = = ' \n ' )
@ -540,11 +639,11 @@ void Terminal::configure() {
cyan_tag - > property_foreground_rgba ( ) = rgba ;
rgba . set_rgba ( 0.5 , 0.5 , 0.5 ) ;
factor = light_theme ? 0.6 : 0.4 ;
factor = light_theme ? 0.7 : 0.4 ;
rgba . set_red ( normal_color . get_red ( ) + factor * ( rgba . get_red ( ) - normal_color . get_red ( ) ) ) ;
rgba . set_green ( normal_color . get_green ( ) + factor * ( rgba . get_green ( ) - normal_color . get_green ( ) ) ) ;
rgba . set_blue ( normal_color . get_blue ( ) + factor * ( rgba . get_blue ( ) - normal_color . get_blue ( ) ) ) ;
gray _tag- > property_foreground_rgba ( ) = rgba ;
white _tag- > property_foreground_rgba ( ) = rgba ;
// Set search match style:
get_buffer ( ) - > get_tag_table ( ) - > foreach ( [ ] ( const Glib : : RefPtr < Gtk : : TextTag > & tag ) {