📄 movement.c
字号:
if (win->rline < new_line) { if (un_copy_line( win->ll, win, TRUE, TRUE ) == ERROR) return( ERROR ); undo_move( win, 0 ); set_marker( win ); /* remember previous position */ move_to_line( win, new_line, TRUE ); display_current_window( win ); } cursor_sync( win ); return( OK );}/* * Name: goto_position * Purpose: To move the cursor to a particular line in the file * Date: June 5, 1991 * Modified: November 13, 1993, Frank Davis per Byrial Jensen * August 11, 1997, Jason Hood - can use -ve numbers to go from eof * -1 is last line, -2 second last... * August 12, 1997, Jason Hood - reposition for real tabs * Passed: window: pointer to current window * * jmh 990921: allow an optional ":col" to move to a column position (0 is at * eol, -1 is last character, etc). The line can be omitted, in * which case the current is used. If the first character is "+" * treat it as a binary offset. Uses strtol() instead of atol() so * hex values can be entered. * jmh 990923: corrected binary offset values. * jmh 991124: allow column values on TOF/EOF lines. */int goto_position( TDE_WIN *window ){long number; /* line number selected */file_infos *file;TDE_WIN w;int rcol;int rc;char answer[MAX_COLS+2];char temp[MAX_COLS+2];char *colon; /* * find out where we are going */ *answer = '\0'; /* * Position (line:col or +offset) : */ if (get_name( find11, window->bottom_line, answer, &h_line ) <= 0) return( ERROR ); if (un_copy_line( window->ll, window, TRUE, TRUE ) == ERROR) return( ERROR ); rc = OK; dup_window_info( &w, window ); file = w.file_info; rcol = w.rcol; number = strtol( answer, &colon, 0 ); if (*answer == '+') { if (number > w.bin_offset) { if (w.rline > file->length) number = w.bin_offset; else while (w.bin_offset + w.ll->len < number && inc_line( &w, FALSE )) ; } else if (number < w.bin_offset) { if (w.bin_offset - number < number) { while (w.bin_offset - w.ll->prev->len > number && dec_line( &w, FALSE )) ; } else { first_line( &w ); while (w.bin_offset + w.ll->len < number) inc_line( &w, FALSE ); } } rcol = (int)(number - w.bin_offset); if (w.rline == file->length && rcol > w.ll->len) rcol = w.ll->len; if (file->inflate_tabs) rcol = detab_adjust_rcol( w.ll->line, rcol, file->ptab_size ); } else { if (number < 0) number += file->length + 1; if ((number == 0 && *colon == ':') || move_to_line( &w, number, FALSE )) { if (*colon == ':') { rcol = atoi( colon + 1 ); if (rcol > MAX_LINE_LENGTH) rcol = w.rcol; else if (rcol <= 0) rcol += find_end( w.ll->line, w.ll->len, file->inflate_tabs, file->ptab_size ); else rcol--; } } else rc = ERROR; } if (rc == OK) { undo_move( window, 0 ); set_marker( window ); /* remember previous position */ w.rcol = rcol; move_display( window, &w ); } else { /* * out of range. must be in the range 1 - */ sprintf( temp, "%s%ld", find12, file->length ); error( WARNING, window->bottom_line, temp ); } return( rc );}/* * Name: set_marker * Purpose: To set file marker * Date: December 28, 1991 * Passed: window: pointer to current window * Modified: August 9, 1997, Jason Hood - added block markers * September 13, 1997, Jason Hood - added previous position * July 18, 1998, Jason Hood - added macro marker * July 28, 1998, Jason Hood - removed block markers (see goto_marker) * * jmh 021028: store cline. */int set_marker( TDE_WIN *window ){register MARKER *marker; /* put the marker in a register */ if (g_status.command >= SetMark1 && g_status.command <= SetMark3) marker = &window->file_info->marker[g_status.command - SetMark1 + 1]; else if (g_status.command == MacroMark) marker = &g_status.macro_mark; else marker = &window->file_info->marker[0]; marker->rline = window->rline; marker->cline = window->cline; marker->rcol = window->rcol; marker->ccol = window->ccol; marker->bcol = window->bcol; marker->marked = TRUE; return( OK );}/* * Name: goto_marker * Purpose: To goto a file marker * Date: December 28, 1991 * Modified: November 13, 1993, Frank Davis per Byrial Jensen * Modified: August 9, 1997, Jason Hood - added block markers * August 11, 1997, Jason Hood - move cursor to line if on screen * Passed: window: pointer to current window * * jmh 980728: Create block markers on the fly. * jmh 980801: If already at the block marker, move to the other one (ie. if * at top-left corner, move to top-right; if at bottom-right, * move to bottom-left). * jmh 021028: restore cline; * default to previous position (due to isearch). * jmh 021210: set cline correctly for move to first page block. * jmh 030224: fixed cline again. * jmh 030327: only use the marker's cline if the rline is off-screen. */int goto_marker( TDE_WIN *window ){int m;file_infos *file;MARKER *marker, prev;register TDE_WIN *win; /* put window pointer in a register */TDE_WIN w;int rc; win = window; file = win->file_info; m = -1; if (g_status.command >= GotoMark1 && g_status.command <= GotoMark3) { m = g_status.command - GotoMark1 + 1; marker = &file->marker[m]; } else if (g_status.command == MacroMark) marker = &g_status.macro_mark; else if (g_status.command == BlockBegin || g_status.command == BlockEnd) { marker = &prev; if (g_status.marked && g_status.marked_file == file) { prev.marked = TRUE; prev.ccol = win->ccol; prev.bcol = win->bcol; if (g_status.command == BlockBegin) { prev.rline = file->block_br; prev.rcol = (win->rline == file->block_br && win->rcol == file->block_bc) ? file->block_ec : file->block_bc; } else { prev.rline = file->block_er; prev.rcol = (win->rline == file->block_er && win->rcol == file->block_ec) ? file->block_bc : file->block_ec; } prev.cline = win->cline; } else prev.marked = FALSE; } else { prev = file->marker[0]; marker = &prev; } if (marker->marked) { if (un_copy_line( win->ll, win, TRUE, TRUE ) == ERROR) return( ERROR ); if (marker->rline != win->rline && marker->rcol != win->rcol) undo_move( win, 0 ); /* * Remember the previous position, but not if it's a macro mark */ if (g_status.command != MacroMark) set_marker( win ); if (marker->rline > file->length) marker->rline = file->length; if (marker->rline < 1) marker->rline = 1; dup_window_info( &w, win ); move_to_line( &w, marker->rline, FALSE ); w.rcol = marker->rcol; win->ccol = marker->ccol; if (win->bcol != marker->bcol) { win->bcol = marker->bcol; file->dirty = LOCAL | RULER; } move_display( win, &w ); if (win->cline == w.cline && file->dirty) check_cline( win, marker->cline ); rc = OK; } else { /* * Don't display a warning for the block markers and previous position */ if (m > 0) { if (m == 10) m = 0; utils13[UTILS13_NO_SLOT] = (char)('0' + m); /* * marker not set */ error( WARNING, win->bottom_line, utils13 ); } rc = ERROR; } return( rc );}/*************************** Drawing mode **************************/#define G_V (G_UP|G_DN)#define G_H (G_LF|G_RT)/* * Given a character in graphic_char[], return its component lines. */static const char g_flag[] = { G_V, G_UP|G_RT, G_H|G_UP, G_UP|G_LF, G_V|G_RT, G_V|G_H, G_V|G_LF, G_DN|G_RT, G_H|G_DN, G_DN|G_LF, G_H };/* * Given component lines, return a character in graphic_char[]. */static const char g_char[] = { 0, 0, 0, VERTICAL_LINE, 0, CORNER_RIGHT_DOWN, CORNER_RIGHT_UP, RIGHT_T, 0, CORNER_LEFT_DOWN, CORNER_LEFT_UP, LEFT_T, HORIZONTAL_LINE, BOTTOM_T, TOP_T, INTERSECTION };/* * Name: get_g_flag * Purpose: determine the line drawing components of a character * Author: Jason Hood * Date: October 19, 1999 * Passed: c: character being tested * gc: graphic set being used * Returns: components of c * Notes: ASCII and block sets need to be treated separately. */static char get_g_flag( char c, const char* gc ){char *pos;char f = 0; if (gc == graphic_char[0]) { /* ASCII */ if (c == gc[INTERSECTION]) f = G_H | G_V; else if (c == gc[VERTICAL_LINE]) f = G_V; else if (c == gc[HORIZONTAL_LINE]) f = G_H; } else if (gc == graphic_char[5]) { /* Block */ if (c == gc[5]) f = G_H | G_V; else if (c == gc[8]) f = G_H; } else if ((pos = memchr( gc, c, 11 )) != NULL) f = g_flag[(int)(pos - (char *)gc)]; return( f );}/* * Name: get_g_char * Purpose: to return a character based on line components * Author: Jason Hood * Date: October 21, 1999 * Passed: c: components being requested * gc: graphic set being used * Returns: graphic character * Notes: Block characters are still a nuisance. */static char get_g_char( char c, const char *gc ){static const char block_char[] = { 0, 0, 0, 5, 0, 8, 5, 5, 0, 8, 5, 5, 8, 8, 5, 5 }; if (gc == graphic_char[5]) return( gc[(int)block_char[(int)c]] ); return( gc[(int)g_char[(int)c]] );}/* * Name: set_vert_g_char * Purpose: draw a vertical line * Author: Jason Hood * Date: October 21, 1999 * Passed: win: pointer to current window * d: direction to draw * Notes: call before (G_UP or G_DN) and after (~G_DN or ~G_UP) the movement. */static void set_vert_g_char( TDE_WIN *win, char d ){int rcol = win->rcol;const char *gc = graphic_char[abs( mode.graphics ) - 1];int c0, c1, c2;text_ptr b = g_status.line_buff;int len; copy_line( win->ll, win, TRUE ); len = g_status.line_buff_len; c0 = c1 = c2 = 0; if (rcol < len) c1 = get_g_flag( b[rcol], gc ); if (rcol > 0 && rcol-1 < len) c0 = get_g_flag( b[rcol-1], gc ); if (rcol+1 < len) c2 = get_g_flag( b[rcol+1], gc ); if (d == G_UP || d == G_DN) { c1 |= d; if (c0 & G_RT) c1 |= G_LF; if (c2 & G_LF) c1 |= G_RT; if (c1 == d) c1 = G_V; } else { if (c1 & G_H) { c1 |= ~d; if (!(c0 & G_RT)) c1 &= ~G_LF; if (!(c2 & G_LF)) c1 &= ~G_RT; } } if (c1 != 0) { if (rcol >= len) { memset( b + len, ' ', rcol - len ); g_status.line_buff_len = rcol + 1; } b[rcol] = get_g_char( (char)c1, gc ); win->ll->type |= DIRTY; win->file_info->dirty = GLOBAL; show_changed_line( win ); }}/* * Name: set_horz_g_char * Purpose: draw a horizontal line * Author: Jason Hood * Date: October 21, 1999 * Passed: win: pointer to current window * d: direction to draw * Notes: call before the movement. Have to treat block graphics separately. */static void set_horz_g_char( TDE_WIN *win, char d ){int rcol = win->rcol;const char *gc = graphic_char[abs( mode.graphics ) - 1];text_ptr b = g_status.line_buff;char f0, f1, f2, t0, t1, t2;text_ptr s;int len;int o; copy_line( win->ll, win, TRUE ); len = g_status.line_buff_len; f0 = f1 = f2 = 0; t0 = t1 = t2 = 0; o = (d == G_LF) ? -1 : 1; if (rcol < len) f1 = get_g_flag( b[rcol], gc ); if (rcol+o < len) t1 = get_g_flag( b[rcol+o], gc ); if (win->rline > 1) { len = win->ll->prev->len; s = detab_a_line( win->ll->prev->line, &len, win->file_info->inflate_tabs, win->file_info->ptab_size ); if (rcol < len) f0 = get_g_flag( s[rcol], gc ); if (rcol+o < len) t0 = get_g_flag( s[rcol+o], gc ); } len = win->ll->next->len; if (len != EOF) { s = detab_a_line( win->ll->next->line, &len, win->file_info->inflate_tabs, win->file_info->ptab_size ); if (rcol < len) f2 = get_g_flag( s[rcol], gc ); if (rcol+o < len) { t2 = get_g_flag( s[rcol+o], gc ); if (gc == graphic_char[5] && t2 == G_H) t2 |= G_UP; } } f1 |= d; if (f0 & G_DN) f1 |= G_UP; if (f2 & G_UP) f1 |= G_DN; if (f1 == d) f1 = G_H; if (rcol >= g_status.line_buff_len) { memse
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -