/* Formats every line of the current text */ static void txt_format_text(SpaceText *st) { TextLine *linep; if (!st->text) return; for (linep = st->text->lines.first; linep; linep = linep->next) txt_format_line(st, linep, 0); }
static void txt_format_line(SpaceText *st, TextLine *line, int do_next) { FlattenString fs; char *str, *fmt, orig, cont, find, prev = ' '; int len, i; /* Get continuation from previous line */ if(line->prev && line->prev->format != NULL) { fmt= line->prev->format; cont = fmt[strlen(fmt)+1]; /* Just after the null-terminator */ } else cont = 0; /* Get original continuation from this line */ if(line->format != NULL) { fmt= line->format; orig = fmt[strlen(fmt)+1]; /* Just after the null-terminator */ } else orig = 0xFF; flatten_string(st, &fs, line->line); str = fs.buf; len = strlen(str); if(!text_check_format_len(line, len)) { flatten_string_free(&fs); return; } fmt = line->format; while(*str) { /* Handle escape sequences by skipping both \ and next char */ if(*str == '\\') { *fmt = prev; fmt++; str++; if(*str == '\0') break; *fmt = prev; fmt++; str++; continue; } /* Handle continuations */ else if(cont) { /* Triple strings ("""...""" or '''...''') */ if(cont & TXT_TRISTR) { find = (cont & TXT_DBLQUOTSTR) ? '"' : '\''; if(*str==find && *(str+1)==find && *(str+2)==find) { *fmt = 'l'; fmt++; str++; *fmt = 'l'; fmt++; str++; cont = 0; } /* Handle other strings */ } else { find = (cont & TXT_DBLQUOTSTR) ? '"' : '\''; if(*str == find) cont = 0; } *fmt = 'l'; } /* Not in a string... */ else { /* Deal with comments first */ if(prev == '#' || *str == '#') *fmt = '#'; /* Strings */ else if(*str == '"' || *str == '\'') { find = *str; cont = (*str== '"') ? TXT_DBLQUOTSTR : TXT_SNGQUOTSTR; if(*(str+1) == find && *(str+2) == find) { *fmt = 'l'; fmt++; str++; *fmt = 'l'; fmt++; str++; cont |= TXT_TRISTR; } *fmt = 'l'; } /* Whitespace (all ws. has been converted to spaces) */ else if(*str == ' ') *fmt = '_'; /* Numbers (digits not part of an identifier and periods followed by digits) */ else if((prev != 'q' && text_check_digit(*str)) || (*str == '.' && text_check_digit(*(str+1)))) *fmt = 'n'; /* Booleans */ else if(prev != 'q' && (i=find_bool(str)) != -1) if(i>0) { while(i>1) { *fmt = 'n'; fmt++; str++; i--; } *fmt = 'n'; } else *fmt = 'q'; /* Punctuation */ else if(text_check_delim(*str)) *fmt = '!'; /* Identifiers and other text (no previous ws. or delims. so text continues) */ else if(prev == 'q') *fmt = 'q'; /* Not ws, a digit, punct, or continuing text. Must be new, check for special words */ else { /* Special vars(v) or built-in keywords(b) */ if((i=find_specialvar(str)) != -1) prev = 'v'; else if((i=find_builtinfunc(str)) != -1) prev = 'b'; else if((i=find_decorator(str)) != -1) prev = 'v'; /* could have a new color for this */ if(i>0) { while(i>1) { *fmt = prev; fmt++; str++; i--; } *fmt = prev; } else *fmt = 'q'; } } prev = *fmt; fmt++; str++; } /* Terminate and add continuation char */ *fmt = '\0'; fmt++; *fmt = cont; /* Debugging */ //print_format(st, line); /* If continuation has changed and we're allowed, process the next line */ if(cont!=orig && do_next && line->next) { txt_format_line(st, line->next, do_next); } flatten_string_free(&fs); }
void draw_text_main(SpaceText *st, ARegion *ar) { Text *text= st->text; TextLine *tmp; rcti scroll, back; char linenr[12]; int i, x, y, winx, linecount= 0, lineno= 0; int wraplinecount= 0, wrap_skip= 0; /* if no text, nothing to do */ if(!text) return; text_update_drawcache(st, ar); /* make sure all the positional pointers exist */ if(!text->curl || !text->sell || !text->lines.first || !text->lines.last) txt_clean_text(text); if(st->lheight) st->viewlines= (int)ar->winy/st->lheight; else st->viewlines= 0; /* update rects for scroll */ calc_text_rcts(st, ar, &scroll, &back); /* scroll will hold the entire bar size */ /* update syntax formatting if needed */ tmp= text->lines.first; lineno= 0; for(i= 0; i<st->top && tmp; i++) { if(st->showsyntax && !tmp->format) txt_format_line(st, tmp, 0); if(st->wordwrap) { int lines= text_get_visible_lines_no(st, lineno); if (wraplinecount+lines>st->top) { wrap_skip= st->top-wraplinecount; break; } else { wraplinecount+= lines; tmp= tmp->next; linecount++; } } else { tmp= tmp->next; linecount++; } lineno++; } text_font_begin(st); st->cwidth= BLF_fixed_width(mono); st->cwidth= MAX2(st->cwidth, 1); /* draw line numbers background */ if(st->showlinenrs) { x= TXT_OFFSET + TEXTXLOC; UI_ThemeColor(TH_GRID); glRecti((TXT_OFFSET-12), 0, (TXT_OFFSET-5) + TEXTXLOC, ar->winy - 2); } else { st->linenrs_tot= 0; /* not used */ x= TXT_OFFSET; } y= ar->winy-st->lheight; winx= ar->winx - TXT_SCROLL_WIDTH; /* draw cursor */ draw_cursor(st, ar); /* draw the text */ UI_ThemeColor(TH_TEXT); for(i=0; y>0 && i<st->viewlines && tmp; i++, tmp= tmp->next) { if(st->showsyntax && !tmp->format) txt_format_line(st, tmp, 0); if(st->showlinenrs && !wrap_skip) { /* draw line number */ if(tmp == text->curl) UI_ThemeColor(TH_HILITE); else UI_ThemeColor(TH_TEXT); sprintf(linenr, "%d", i + linecount + 1); /* itoa(i + linecount + 1, linenr, 10); */ /* not ansi-c :/ */ text_font_draw(st, TXT_OFFSET - 7, y, linenr); UI_ThemeColor(TH_TEXT); } if(st->wordwrap) { /* draw word wrapped text */ int lines = text_draw_wrapped(st, tmp->line, x, y, winx-x, tmp->format, wrap_skip); y -= lines*st->lheight; } else { /* draw unwrapped text */ text_draw(st, tmp->line, st->left, ar->winx/st->cwidth, 1, x, y, tmp->format); y -= st->lheight; } wrap_skip= 0; } /* draw other stuff */ draw_brackets(st, ar); draw_markers(st, ar); glTranslatef(0.375f, 0.375f, 0.0f); /* XXX scroll requires exact pixel space */ draw_textscroll(st, &scroll, &back); draw_documentation(st, ar); draw_suggestion_list(st, ar); text_font_end(st); }