📄 utils.c
字号:
window->cur_count = (int)count; if (file->dirty & LOCAL) show_curl_line( window ); } /* * now update the line in all other windows */ if (file->dirty & NOT_LOCAL) { changed_line = window->rline; above = window->prev; below = window->next; while (above || below) { if (above) { dup_window_info( &w, above ); above = above->prev; } else if (below) { dup_window_info( &w, below ); below = below->next; } /* * is this window the changed file and is it visible? */ if (w.file_info == file && w.visible) { /* * calculate file lines at top and bottom of screen. * the changed line may not be the curl in other windows. */ line_on_screen = FALSE; rline = 0; top_line = w.rline - (w.cline - w.top_line); bottom_line = w.rline + (w.bottom_line - w.cline); if (changed_line == w.rline) line_on_screen = CURLINE; else if (changed_line < w.rline && changed_line + count >= top_line) { line_on_screen = NOTCURLINE; rline = w.rline; while (w.rline > changed_line && w.rline > top_line) { w.ll = w.ll->prev; --w.rline; --w.cline; } count -= w.rline - changed_line; } else if (changed_line > w.rline && changed_line <= bottom_line) { line_on_screen = NOTCURLINE; while (w.rline < changed_line) { w.ll = w.ll->next; ++w.rline; ++w.cline; } } /* * display the changed line if on screen */ if (line_on_screen) { if (line_on_screen == NOTCURLINE) update_line( &w ); else show_curl_line( &w ); i = w.bottom_line - w.cline; if (i > count) i = (int)count; while (i != 0) { w.ll = w.ll->next; ++w.rline; ++w.cline; if (w.rline == rline) show_curl_line( &w ); else update_line( &w ); --i; } } } } } file->dirty = FALSE;}/* * Name: show_curl_line * Purpose: show current line in curl color * Date: January 16, 1992 * Passed: window: pointer to current window * jmh 980724: use a global variable to indicate the current line * jmh 980801: display the lines changed by syntax highlighting (caused by * the NOT_LOCAL update in show_changed_line). * jmh 991031: don't use current line when swapping. * jmh 050720: moved above test into display_current_window. */void show_curl_line( TDE_WIN *window ){TDE_WIN w;register int cur_count; if (window->visible && g_status.screen_display) { g_status.cur_line = TRUE; update_line( window ); g_status.cur_line = FALSE; cur_count = window->cur_count; if (cur_count > 0) { dup_window_info( &w, window ); do { w.ll = w.ll->next; ++w.rline; ++w.cline; update_line( &w ); } while (--cur_count != 0); window->cur_count = 0; } }}/* * Name: update_line * Purpose: Display the current line in window * Date: June 5, 1991 * Passed: window: pointer to current window * Notes: Show string starting at column zero and if needed blank rest * of line. * jmh: September 8, 1997 - added syntax highlighting. * jmh 980725: added not-eol display (ie. line extends beyond window edge) * jmh 980816: display break point in the hilited file color. * jmh 991027: combined all display routines into one, moved to utils.c. * jmh 991028: display the swap region. * jmh 991108: display line number (using ruler coloring). * jmh 030330: fix bug with line number. * jmh 031027: break point and swap have their own colors. */void update_line( TDE_WIN *window ){file_infos *file;line_list_ptr ll; /* current line being displayed */text_ptr text; /* position to begin display */int len;long rline;long br;text_t line_char[MAX_COLS]; /* characters to display */unsigned char line_attr[MAX_LINE_LENGTH+8]; /* color of every char. in line */text_ptr lchar;unsigned char *lattr; /* color of every char. on-screen */int blank = 0; /* color to blank out the screen line */int block;int max_col;int block_line;int line_block;int break_point;int show_eol;int show_neol;int bc;int ec;int swap_line;int line_swap;int nlen; ll = window->ll; if (ll->len == EOF || !g_status.screen_display) return; file = window->file_info; rline = window->rline; max_col = window->end_col + 1 - window->start_col; block = file->block_type; br = file->block_br; block_line = (block > NOTMARKED && rline >= br && rline <= file->block_er); line_block = ((block == LINE && block_line) || (block == STREAM && ((rline > br && rline < file->block_er) || (rline == file->block_er && file->block_ec == -1 && rline != file->block_br)))); break_point = (rline == file->break_point); swap_line = (rline <= swap_er && rline >= swap_br); line_swap = (swap_line && swap_bc == -1); /* * figure which line to display. * actually, we could be displaying any line in any file. we display * the line_buffer only if window->ll == g_status.buff_node * and window->ll->line has been copied to g_status.line_buff. */ if (g_status.copied && ll == g_status.buff_node) { text = g_status.line_buff; len = g_status.line_buff_len; } else { text = ll->line; len = ll->len; } if (file->inflate_tabs) text = tabout( text, &len, file->ptab_size, mode.show_eol ); nlen = (mode.line_numbers) ? file->len_len : 0; lchar = line_char + nlen; lattr = line_attr + nlen; if (window->syntax && !line_block && !break_point && !line_swap) blank = syntax_attr( text, len, ll->type, lattr, file->syntax ); /* * lets look at the base column. if the line to display is shorter * than the base column, then set text to eol and we can't see the * eol either. */ show_eol = (mode.show_eol == 1); bc = window->bcol; if (bc > 0) { text += bc; lattr += bc; len -= bc; if (len < 0) { len = 0; show_eol = FALSE; } } /* * for display purposes, set the line length to screen width if line * is longer than screen. */ show_neol = (mode.show_eol == 2 && len > max_col); if (len > max_col) len = max_col; memset( line_char, ' ', nlen + max_col ); my_memcpy( lchar, text, len ); if (show_eol) { if (len < max_col) lchar[len] = EOL_CHAR; } else if (show_neol) lchar[max_col - 1] = NEOL_CHAR; if (nlen) { long n = rline; if (ruler_win.rline != -1) n = labs( n - ruler_win.rline ) + 1; my_ltoa( n, (char *)lchar - numlen( n ) - 1, 10 ); lchar[-1] = HALF_SPACE; block = (g_status.cur_line) ? Color( Pointer ) : Color( Ruler ); memset( lattr - nlen, block, nlen - 1 ); bc = (window->syntax) ? syntax_color[0] /* COL_NORMAL */ : Color( Text ); lattr[-1] = (block >> 4) | (bc & 0xf0); } block = Color( Block ); if (line_block) memset( lattr, block, max_col ); else if (line_swap) memset( lattr, Color( Swap ), max_col ); else { if (window->syntax && !break_point) memset( lattr + len, blank, max_col - len ); else { blank = (break_point) ? Color( BP ) : (g_status.cur_line && !mode.cursor_cross) ? Color( Curl ) : (ll->type & DIRTY) ? Color( Dirty ) : Color( Text ); memset( lattr, blank, max_col ); } if (block_line) { bc = file->block_bc; ec = file->block_ec; if (file->block_type == STREAM) { if (rline == br && (br != file->block_er || ec == -1)) ec = bc + max_col; else if (rline == file->block_er && br != file->block_er) bc = 0; } memset( line_attr+nlen + bc, block, ec - bc + 1 ); } if (swap_line) memset( line_attr+nlen + swap_bc, Color( Swap ), swap_ec - swap_bc + 1 ); } if (found_rline == rline) memset( line_attr+nlen + found_rcol, Color( Help ), found_vlen ); /* * Popup ruler */ if (ruler_win.rline != -1) { if (window->cline == ruler1 || window->cline == ruler2 || window->rline == ruler_win.rline) make_popup_ruler( window, lchar, lattr, max_col, ruler1, ruler2 ); } /* * Set the cursor cross. */ else if (mode.cursor_cross) { blank = Color( Cross ); line_attr[nlen + window->rcol] ^= blank; if (g_status.cur_line) { bc = max_col; do lattr[--bc] ^= blank; while (bc != 0); } } display_line( line_char, lattr - nlen, nlen + max_col, window->cline, window->left );}/* * Name: dup_window_info * Purpose: Copy window info from one window pointer to another * Date: June 5, 1991 * Passed: dw: destination window * sw: source window */void dup_window_info( TDE_WIN *dw, TDE_WIN *sw ){ memcpy( dw, sw, sizeof( TDE_WIN ) );}/* * Name: adjust_windows_cursor * Purpose: A change has been made, make sure pointers are not ahead of * or behind file. * Date: June 5, 1991 * Passed: window: pointer to current window * line_change: number of lines add to or subtracted from file * Notes: If a file has been truncated in one window and there is another * window open to the same file and its current line is near the * end, the current line is reset to the last line of the file. * jmh 991126: adjust other windows' rline (keep the same line, not the same * line number); * corrected other windows' bin_offset value (have to recalculate * from the beginning). */void adjust_windows_cursor( TDE_WIN *window, long line_change ){register TDE_WIN *next;file_infos *file;long rline;long length;long i;MARKER *marker;int ndiff; if (line_change == 0) return; file = window->file_info; rline = window->rline; length = file->length; for (next = g_status.window_list; next != NULL; next = next->next) { if (next->file_info == file && next != window && next->rline > rline) { i = next->rline + line_change; if (i > length + 1) i = length + 1; first_line( next ); move_to_line( next, i, TRUE ); check_cline( next, next->cline ); file->dirty = NOT_LOCAL; } } /* * jmh 050715: doing a block delete or move requires using the block line. */ if (g_status.command == DeleteBlock || g_status.command == MoveBlock) rline = file->block_er; /* * now adjust any markers. */ for (i = 0; i < NO_MARKERS; i++) { marker = &file->marker[ (int) i ]; if (marker->rline > rline) { marker->rline += line_change; if (marker->rline < 1L) marker->rline = 1L; else if (marker->rline > length) marker->rline = length; } } /* * adjust the break point. */ if (file->break_point > rline) { file->break_point += line_change; if (file->break_point < 1L || file->break_point > length) file->break_point = 0; } /* * check if the width of the line numbers have changed. */ if (mode.line_numbers) { ndiff = numlen( length ) + 1 - file->len_len; if (ndiff != 0) { file->len_len += ndiff; for (next = g_status.window_list; next != NULL; next = next->next) { if (next->file_info == file) { next->start_col += ndiff; next->ccol += ndiff; if (next->ccol > next->end_col) next->ccol = next->end_col; } } file->dirty = GLOBAL; } }}/* * Name: first_non_blank * Purpose: To find the column of the first non-blank character * Date: June 5, 1991 * Passed: s: the string to search * len: length of string * tabs: do tabs count as blanks? * tab_size: size of tabs * Returns: the first non-blank column */int first_non_blank( text_ptr s, int len, int tabs, int tab_size ){register int count = 0; if (len > 0) { if (tabs) { do { if (*s == ' ') ++count; else if (*s == '\t') count += tab_size - (count % tab_size); else break; s++; } while (--len != 0); } else { while (*s++ == ' ' && --len != 0)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -