home *** CD-ROM | disk | FTP | other *** search
- /*
- ** navigate.c
- **
- ** Ed, Version 1.51, Copyright (c) 1992-94 SoftCircuits
- ** Redistributed by permission.
- */
-
- #include <stdio.h>
- #include <pictor.h>
- #include "ed.h"
-
- /*
- ** shows the current row/column on the status bar
- */
- void show_status()
- {
- xprintf(statusbar,"%-24.24s\xB3 <F1>=Help <F10>=Exit [%c] "
- "%s Row %-6dCol %-5d",filename,(modified) ? '*' : ' ',
- (insert_mode) ? "INS" : "OVR",file_row + 1,file_col + 1);
-
- } /* show_status */
-
- /*
- ** displays one line of text at the specified row
- */
- void show_line(LINE *line,int row)
- {
- int i,col,tab_cols;
-
- vcolor(edit_color);
- setvpos(row,edit_left);
-
- /* scan line up to point visible on screen */
- col = 0;
- for(i = 0;col < left_col && i < line->len;i++) {
- if(line->text[i] == '\t')
- col = NEXT_TAB(col);
- else col++;
- }
-
- /* write out any unfinished tab */
- if(col > left_col)
- vrepc(' ',col - left_col);
-
- /* write visible portion of line */
- for( ;col < (left_col + EDIT_COLS)
- && i < line->len;i++) {
-
- if(line->text[i] == '\t') {
- tab_cols = (tab_size - (col % tab_size));
- if((col + tab_cols) > (left_col + EDIT_COLS))
- tab_cols = ((left_col + EDIT_COLS) - col);
- vrepc(' ',tab_cols);
- col += tab_cols;
- }
- else {
- vputc(line->text[i]);
- col++;
- }
- }
-
- /* fill remaining columns with spaces */
- if(col < (left_col + EDIT_COLS))
- vrepc(' ',(left_col + EDIT_COLS) - ((col > left_col) ? col : left_col));
-
- } /* show_line */
-
- /*
- ** repaints the edit window
- */
- void show_text()
- {
- int i;
- LINE *line = top_line;
-
- /* write line buffers */
- for(i = edit_top;i <= edit_bottom && line;i++) {
- show_line(line,i);
- line = line->next;
- }
-
- /* clear remaining lines (if any) */
- for( ;i <= edit_bottom;i++) {
- setvpos(i,edit_left);
- vrepc(' ',EDIT_COLS);
- }
-
- } /* show_text */
-
- /*
- ** sets file_col to represent line_ndx
- */
- void set_file_col()
- {
- int i;
-
- /* count columns up to line_ndx */
- for(file_col = 0,i = 0;i < line_ndx;i++) {
- if(curr_line->text[i] == '\t')
- file_col = NEXT_TAB(file_col);
- else
- file_col++;
- }
-
- } /* set_file_col */
-
- /*
- ** sets line_ndx to represent pref_col
- ** if pref_col exceeds the number of line columns,
- ** line_ndx is set to the end of the line
- */
- void set_line_ndx()
- {
- int col = 0;
-
- /* count line index up to pref_col */
- for(line_ndx = 0;line_ndx < curr_line->len;line_ndx++) {
- if(curr_line->text[line_ndx] == '\t')
- col = NEXT_TAB(col);
- else
- col++;
- if(col > pref_col)
- break;
- }
-
- } /* set_line_ndx */
-
- /*
- ** updates the edit cursor
- ** screen is updated if indicated by update_state
- ** horizontal scrolling is performed if required
- **
- ** if set_pref_col is non-zero, the preferred
- ** column (pref_col) is set to match file_col
- */
- void update_cursor(int set_pref_col)
- {
- /* determine actual column */
- set_file_col();
-
- /* make current column the preferred column */
- if(set_pref_col)
- pref_col = file_col;
-
- /* check for horizontal scroll */
- if(file_col < left_col) {
- left_col = file_col;
- update_state = UPDATE_REPAINT;
- }
- else if((file_col - EDIT_COLS) >= left_col) {
- left_col = ((file_col - EDIT_COLS) + 1);
- update_state = UPDATE_REPAINT;
- }
-
- /* update screen */
- switch(update_state) {
- case UPDATE_REPAINT:
- show_text();
- break;
- case UPDATE_SCROLLUP:
- vcolor(edit_color);
- scroll(1,edit_top,edit_left,EDIT_ROWS,EDIT_COLS);
- show_line(curr_line,edit_bottom);
- break;
- case UPDATE_SCROLLDN:
- vcolor(edit_color);
- scroll(-1,edit_top,edit_left,EDIT_ROWS,EDIT_COLS);
- show_line(curr_line,edit_top);
- break;
- }
-
- /* set cursor position */
- setcurs((file_row - top_row) + edit_top,
- (file_col - left_col) + edit_left);
-
- /* update status bar */
- show_status();
-
- update_state = UPDATE_NOUPDATE;
-
- } /* update_cursor */
-
- /*
- ** moves left one character -- screen is not updated
- */
- void _left()
- {
- if(line_ndx > 0) {
- /* move left */
- line_ndx--;
- }
- else if(curr_line->prev != NULL) {
- /* wrap to previous line */
- _up();
- line_ndx = curr_line->len;
- }
-
- } /* _left */
-
- /*
- ** moves right one character -- screen is not updated
- */
- void _right()
- {
- if(line_ndx < curr_line->len) {
- /* move right */
- line_ndx++;
- }
- else if(curr_line->next != NULL) {
- /* wrap to next line */
- _down();
- line_ndx = 0;
- }
-
- } /* _right */
-
- /*
- ** moves up one line -- screen is not updated
- */
- void _up()
- {
- curr_line = curr_line->prev;
- file_row--;
-
- /* scroll if required */
- if(file_row < top_row) {
- top_line = top_line->prev;
- top_row--;
- update_state = UPDATE_SCROLLDN;
- }
-
- /* set line_ndx to match column in previous line */
- set_line_ndx();
-
- } /* _up */
-
- /*
- ** moves down one line -- screen is not updated
- */
- void _down()
- {
- curr_line = curr_line->next;
- file_row++;
-
- /* scroll if required */
- if((file_row - top_row) >= EDIT_ROWS) {
- top_line = top_line->next;
- top_row++;
- update_state = UPDATE_SCROLLUP;
- }
-
- /* set line_ndx to match column in previous line */
- set_line_ndx();
-
- } /* _down */
-
- /*
- ** moves one character left
- */
- void cursor_left()
- {
- if(line_ndx > 0 || curr_line->prev != NULL) {
- _left();
- update_cursor(TRUE);
- }
- } /* cursor_left */
-
- /*
- ** moves one character right
- */
- void cursor_right()
- {
- if(line_ndx < curr_line->len || curr_line->next != NULL) {
- _right();
- update_cursor(TRUE);
- }
- } /* cursor_left */
-
- /*
- ** moves one line up
- */
- void cursor_up()
- {
- if(curr_line->prev != NULL) {
- _up();
- update_cursor(FALSE);
- }
- } /* cursor_up */
-
- /*
- ** moves one line down
- */
- void cursor_down()
- {
- if(curr_line->next != NULL) {
- _down();
- update_cursor(FALSE);
- }
- } /* cursor_down */
-
- /*
- ** moves up one screen
- */
- void page_up()
- {
- int i;
-
- if(curr_line->prev != NULL) {
- /* change cursor position */
- for(i = 0;curr_line->prev != NULL && i < EDIT_ROWS;i++) {
- curr_line = curr_line->prev;
- file_row--;
- }
- /* change scroll position */
- if(top_line->prev != NULL) {
- for(i = 0;top_line->prev != NULL && i < EDIT_ROWS;i++) {
- top_line = top_line->prev;
- top_row--;
- }
- update_state = UPDATE_REPAINT;
- }
-
- /* set line_ndx to match column in prev line */
- set_line_ndx();
- update_cursor(FALSE);
- }
-
- } /* page_up */
-
- /*
- ** moves down one screen
- */
- void page_down()
- {
- int i;
-
- if(curr_line->next != NULL) {
- /* change cursor position */
- for(i = 0;curr_line->next != NULL && i < EDIT_ROWS;i++) {
- curr_line = curr_line->next;
- file_row++;
- }
- /* change scroll position */
- if(top_line->next != NULL) {
- for(i = 0;top_line->next != NULL && i < EDIT_ROWS;i++) {
- top_line = top_line->next;
- top_row++;
- }
- update_state = UPDATE_REPAINT;
- }
-
- /* set line_ndx to match column in prev line */
- set_line_ndx();
- update_cursor(FALSE);
- }
-
- } /* page_down */
-
- /*
- ** moves to the start of the first line
- */
- void file_home()
- {
- /* if not already at file home */
- if(curr_line->prev != NULL || file_col > 0) {
- /* set displayed lines */
- if(top_line->prev != NULL) {
- top_line = head;
- top_row = 0;
- update_state = UPDATE_REPAINT;
- }
-
- /* set current line */
- curr_line = head;
- file_row = 0;
- line_ndx = 0;
- update_cursor(TRUE);
- }
-
- } /* file_home */
-
- /*
- ** moves to the end of the last line
- */
- void file_end()
- {
- /* if not already at file end */
- if(curr_line->next != NULL || file_col < curr_line->len) {
- /* set displayed lines */
- if(top_line->next != NULL) {
- top_line = tail;
- top_row = (num_lines - 1);
- update_state = UPDATE_REPAINT;
- }
-
- /* set current line */
- curr_line = tail;
- file_row = (num_lines - 1);
- line_ndx = curr_line->len;
- update_cursor(TRUE);
- }
-
- } /* file_end */
-