📄 movement.c
字号:
/* * jmh 991021: This file was originally part of utils.c, but since it was * growing so big, I separated these movement functions. * * New editor name: TDE, the Thomson-Davis Editor. * Author: Frank Davis * Date: June 5, 1991, version 1.0 * Date: July 29, 1991, version 1.1 * Date: October 5, 1991, version 1.2 * Date: January 20, 1992, version 1.3 * Date: February 17, 1992, version 1.4 * Date: April 1, 1992, version 1.5 * Date: June 5, 1992, version 2.0 * Date: October 31, 1992, version 2.1 * Date: April 1, 1993, version 2.2 * Date: June 5, 1993, version 3.0 * Date: August 29, 1993, version 3.1 * Date: November 13, 1993, version 3.2 * Date: June 5, 1994, version 4.0 * Date: December 5, 1998, version 5.0 (jmh) * * This modification of Douglas Thomson's code is released into the * public domain, Frank Davis. You may distribute it freely. */#include "tdestr.h"#include "common.h"#include "define.h"#include "tdefunc.h"TDE_WIN *browser_window; /* current window being used for browsing */static int browser_parse( char *, long *, int * );/* * Stuff for draw mode. */#define G_UP 1 /* G_UP */#define G_DN 2 /* G_LF + G_RT */#define G_LF 4 /* G_DN */#define G_RT 8static char get_g_flag( char, const char * );static char get_g_char( char, const char * );static void set_vert_g_char( TDE_WIN *, char );static void set_horz_g_char( TDE_WIN *, char );/* * Name: first_line * Purpose: move to the first line * Author: Jason Hood * Date: March 27, 2003 * Passed: window: pointer to window * Notes: if the file is empty, will move to EOF. */void first_line( TDE_WIN *window ){ window->ll = window->file_info->line_list->next; window->rline = 1; window->bin_offset = 0;}/* * Name: inc_line * Purpose: move down one line * Author: Jason Hood * Date: November 20, 1999 * Passed: window: pointer to window to move * eof: TRUE if EOF is allowed, FALSE otherwise. * Returns: TRUE if the move occurred * FALSE if already at EOF/last line * Notes: move rline, ll and bin_offset to the next line. */int inc_line( TDE_WIN *window, int eof ){int rc; rc = (window->rline < window->file_info->length + (eof == TRUE)); if (rc) { if (window->rline != 0) window->bin_offset += window->ll->len; ++window->rline; window->ll = window->ll->next; } return( rc );}/* * Name: dec_line * Purpose: move up one line * Author: Jason Hood * Date: November 20, 1999 * Passed: window: pointer to window to move * tof: TRUE if TOF is allowed, FALSE otherwise. * Returns: TRUE if the move occurred * FALSE if already at TOF/first line * Notes: move rline, ll and bin_offset to the previous line. */int dec_line( TDE_WIN *window, int tof ){int rc; rc = (window->rline > 0 + (tof == FALSE)); if (rc) { --window->rline; window->ll = window->ll->prev; if (window->rline != 0) window->bin_offset -= window->ll->len; } return( rc );}/* * Name: move_to_line * Purpose: move the window to a new line * Author: Jason Hood * Date: November 20, 1999 * Passed: window: pointer to window to move * line: line to move to * eof: TRUE if TOF and EOF are valid lines, FALSE otherwise. * Returns: TRUE if the move occurred * FALSE if the line is out of range, position unchanged * Notes: move rline, ll and bin_offset to the specified line. */int move_to_line( TDE_WIN *window, long line, int eof ){int rc;register TDE_WIN *win;long n;line_list_ptr ll;long o; win = window; rc = (line >= 0 + (eof == FALSE) && line <= win->file_info->length + (eof == TRUE)); if (rc) { n = win->rline; if (n != line) { if (line <= 1) { o = 0; ll = win->file_info->line_list; if (line == 1) ll = ll->next; } else { ll = win->ll; o = win->bin_offset; if (line < n) { if (n - line < line - 1) { for (; n > line; n--) { ll = ll->prev; o -= ll->len; } if (line == 0) o += EOF; } else { ll = win->file_info->line_list->next; o = 0; for (n = 1; n < line; n++) { o += ll->len; ll = ll->next; } } } else { if (n == 0) o = -EOF; for (; n < line; n++) { o += ll->len; ll = ll->next; } } } win->rline = line; win->ll = ll; win->bin_offset = o; } } return( rc );}/* * Name: move_display * Purpose: move to a line and display it * Author: Jason Hood * Date: November 24, 1999 * Passed: window: pointer to current window * pos: pointer to window containing new position * Notes: set window's rline, ll, rcol and bin_offset to those in pos. * If the new line is on-screen, move to it, otherwise move the line * to the current cursor position. * * jmh 020815: Billy Chen noted the ruler wasn't being properly updated. * (This is also fixed in some other functions.) */void move_display( TDE_WIN *window, TDE_WIN *pos ){register TDE_WIN *win;TDE_WIN old;long diff;int cline; win = window; dup_window_info( &old, win ); win->rline = pos->rline; win->rcol = pos->rcol; win->ll = pos->ll; win->bin_offset = pos->bin_offset; diff = win->rline - old.rline; if (diff) { cline = win->cline; if (labs( diff ) >= g_display.end_line || check_cline( win, win->cline + (int)diff )) { check_cline( win, cline ); win->file_info->dirty = LOCAL | RULER; } } check_virtual_col( win, win->rcol, win->ccol ); if (!win->file_info->dirty) { if (old.rcol != win->rcol) show_ruler( win ); if (old.rline != win->rline) { update_line( &old ); show_curl_line( win ); } }}/* * Name: prepare_move_up * Purpose: Do the stuff needed to move the cursor up one line. * Date: November 23, 1999 * Passed: window: pointer to current window * Notes: Put all the stuff needed to move the cursor up one line in * one function, so several functions can use the guts of the * algorithm. */int prepare_move_up( TDE_WIN *window ){int rc = OK;register TDE_WIN *win; /* put window pointer in a register */ win = window; if (win->rline > 0) { if (un_copy_line( win->ll, win, TRUE, TRUE ) == ERROR) return( ERROR ); undo_move( win, LineDown ); if (win->cline == win->top_line) { dec_line( win, TRUE ); win->file_info->dirty = LOCAL; } else { update_line( win ); dec_line( win, TRUE ); --win->cline; /* we aren't at top of screen - so move up */ show_curl_line( win ); } } else rc = ERROR; return( rc );}/* * Name: prepare_move_down * Purpose: Do the stuff needed to move the cursor down one line. * Date: June 5, 1991 * Passed: window: pointer to current window * Notes: Put all the stuff needed to move the cursor down one line in * one function, so several functions can use the guts of the * algorithm. * * jmh 991123: don't scroll when on EOF (use ScrollDown instead). */int prepare_move_down( TDE_WIN *window ){int rc = OK;register TDE_WIN *win; /* put window pointer in a register */ win = window; if (win->ll->next != NULL) { if (un_copy_line( win->ll, win, TRUE, TRUE ) == ERROR) return( ERROR ); if (g_status.command == BegNextLine) undo_move( win, (win->rcol == 0) ? LineUp : 0 ); else if (g_status.command == NextLine || g_status.command == EndNextLine) undo_move( win, 0 ); else undo_move( win, LineUp ); if (win->cline == win->bottom_line) { inc_line( win, TRUE ); win->file_info->dirty = LOCAL; } else { update_line( win ); inc_line( win, TRUE ); ++win->cline; /* if not at bottom of screen move down */ show_curl_line( win ); } } else rc = ERROR; return( rc );}/* * Name: home * Purpose: To move the cursor to the left of the current line. * Date: June 5, 1991 * Passed: window: pointer to current window * Notes: this routine is made a little more complicated with cursor sync. * if the g_status.copied flag is set we need to see from what file * the line_buff was copied. */int home( TDE_WIN *window ){register int rcol;register TDE_WIN *win; /* put window pointer in a register */text_ptr p;int len;int tabs;int tab_size; win = window; if (g_status.command == StartOfLine) rcol = 0; else { tabs = win->file_info->inflate_tabs; tab_size = win->file_info->ptab_size; if (g_status.copied && win->file_info == g_status.current_file) { p = g_status.line_buff; len = g_status.line_buff_len; } else { p = win->ll->line; len = win->ll->len; } rcol = (is_line_blank( p, len, tabs )) ? 0 : first_non_blank( p, len, tabs, tab_size ); if (win->rcol == rcol) rcol = 0; } undo_move( win, 0 ); show_ruler_char( win ); check_virtual_col( win, rcol, win->ccol ); cursor_sync( win ); return( OK );}/* * Name: goto_eol * Purpose: To move the cursor to the eol character of the current line. * Date: June 5, 1991 * Passed: window: pointer to current window * Notes: this routine is made a little more complicated with cursor sync. * if the g_status.copied flag is set we need to see from what file * the line_buff was copied. * * jmh 030302: make allowances for being called from StreamCharLeft. * jmh 030303: make allowances for being called from EndNextLine. */int goto_eol( TDE_WIN *window ){register int rcol;register TDE_WIN *win; /* put window pointer in a register */text_ptr p;int len; if (g_status.command_count == 0 || g_status.command == StreamCharLeft || g_status.command == EndNextLine) { win = window; if (g_status.command == EndOfLine) undo_move( win, 0 ); else if (g_status.command == EndNextLine) prepare_move_down( win ); if (g_status.copied && win->file_info == g_status.current_file) { p = g_status.line_buff; len = g_status.line_buff_len; } else { p = win->ll->line; len = win->ll->len; } rcol = find_end( p, len, win->file_info->inflate_tabs, win->file_info->ptab_size ); show_ruler_char( win ); win->ccol = win->start_col + rcol - win->bcol; check_virtual_col( win, rcol, win->ccol ); if (g_status.command != StreamCharLeft) cursor_sync( win ); } return( OK );}/* * Name: goto_top * Purpose: To move the cursor to the top of the current window. * Date: June 5, 1991 * Passed: window: pointer to current window * Notes: If the start of the file occurs before the top of the window, * then the start of the file is moved to the top of the window. */int goto_top( TDE_WIN *window ){register TDE_WIN *win; /* put window pointer in a register */long line;int diff;int empty; if (g_status.command_count == 0) { win = window; diff = win->cline - win->top_line; line = win->rline; empty = (win->file_info->length == 0); if ((diff && (line != 1 || empty)) || (line == 0 && !empty)) { if (un_copy_line( win->ll, win, TRUE, TRUE ) == ERROR) return( ERROR ); undo_move( win, 0 ); update_line( win ); line -= diff; win->cline = win->top_line; if (line == 0 && !empty) { ++line; if (win->cline < win->bottom_line) ++win->cline; } move_to_line( win, line, TRUE ); show_curl_line( win ); } cursor_sync( win ); } return( OK );}/* * Name: goto_bottom * Purpose: To move the cursor to the bottom of the current window. * Date: June 5, 1991
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -