📄 mined2.c
字号:
/* ================================================================== * * Editor mined * * Part 2 * * ================================================================== */#include "mined.h"/* ================================================================== * * Definitions specific for mined2.c * * ================================================================== */#ifndef copycommand# ifdef vms# define copycommand "copy %s %s"# endif# ifdef msdos# define copycommand "copy %s %s > nul:"# endif#endif/* * viewonlyerr () outputs an error message with a beep */voidviewonlyerr (){ ring_bell (); error ("View only mode", NIL_PTR);}FLAG yank_status = NOT_VALID; /* Status of yank_file *//* ================================================================== * * Forward declarations * * ================================================================== */FLAG delete_text ();void file_insert ();void search ();void re_search ();void prev_search ();void search_for ();void yank ();FLAG compile ();int reverse_scroll ();int find_y ();int forward_scroll ();int insert ();int legal ();int line_check ();int check_string ();int in_list ();int star ();FLAG checkmark ();/* ================================================================== * * Move Commands * * ================================================================== *//* * Move one line up. */voidMUP (){ if (hop_flag > 0) HIGH (); else if (y == 0) { /* Top line of screen. Scroll one line */ if (reverse_scroll (TRUE) != ERRORS) { move_y (y); } } else /* Move to previous line */ move_y (y - 1);}/* * Move one line down. */voidMDN (){ if (hop_flag > 0) LOW (); else if (y == last_y) { /* Last line of screen. Scroll one line */ if (bot_line->next == tail && bot_line->text [0] != '\n') { /* dummy_line (); don't create new empty line ! */ /* MDN (); */ return; } else { (void) forward_scroll (TRUE); move_y (y); } } else /* Move to next line */ move_y (y + 1);}/* * Move left one position. */voidMLF (){ if (hop_flag > 0) BLINE (); else if (x == 0 && get_shift (cur_line->shift_count) == 0) {/* Begin of line */ if (cur_line->prev != header) { MUP (); /* Move one line up */ move_to (LINE_END, y); } } else move_to (x - 1, y);}/* * Move right one position. */voidMRT (){ if (hop_flag > 0) ELINE (); else if (* cur_text == '\n') { if (cur_line->next != tail) { /* Last char of file */ MDN (); /* Move one line down */ move_to (LINE_START, y); } } else move_to (x + 1, y);}/* * Move to top of screen */voidHIGH (){ move_y (0);}/* * Move to bottom of screen */voidLOW (){ move_y (last_y);}/* * Move to begin of line. */voidBLINE (){ move_to (LINE_START, y);}/* * Move to end of line. */voidELINE (){ move_to (LINE_END, y);}/* * GOTO () prompts for a linenumber and moves to that line. */voidgoline (number) int number;{ LINE * line; if (number <= 0 || (line = proceed (header->next, number - 1)) == tail) error ("Illegal line number: ", num_out ((long) number)); else { clear_status (); move_y (find_y (line)); }}voidgoproz (number) int number;{ goline (number * total_lines / 100);}voidGOTO (){ uchar c; char end; int number; if (! char_ready_within (500)) status_msg ("HOP ... command (fortified) or line number..."); if (quit == TRUE) return; c = readchar (); if (quit == TRUE) return; if ('0' <= c && c <= '9') { end = get_number ("Please continue line number...", c, & number); if (end == '%') goproz (number); else if (end != ERRORS) goline (number); return; } else { clear_status (); hop_flag = 1; (* key_map [c]) (c); return; }}/* * Scroll forward one page or to eof, whatever comes first. (Bot_line becomes * top_line of display.) Try to leave the cursor on the same line. If this is * not possible, leave cursor on the line halfway the page. */voidPD (){ register int i; int new_y; if (hop_flag > 0) {hop_flag = 0; EFILE (); return;} for (i = 0; i < SCREENMAX; i ++) if (forward_scroll (page_scroll) == ERRORS) break; /* EOF reached */ if (y - i < 0) /* Line no longer on screen */ new_y = (page_stay == TRUE) ? 0 : SCREENMAX >> 1; else new_y = y - i; if (page_scroll == FALSE) display (0, top_line, last_y, new_y); move_y (new_y);}/* * Scroll backwards one page or to top of file, whatever comes first. * (Top_line becomes bot_line of display). * The very bottom line (YMAX) is always blank. * Try to leave the cursor on the same line. * If this is not possible, leave cursor on the line halfway the page. */voidPU (){ register int i; int new_y; if (hop_flag > 0) {hop_flag = 0; BFILE (); return;} for (i = 0; i < SCREENMAX; i ++) { if (reverse_scroll (page_scroll) == ERRORS) /* should also flag reverse_scroll that clearing of bottom line is not desired */ break; /* Top of file reached */ } if (y + i > SCREENMAX) /* line no longer on screen */ new_y = (page_stay == TRUE) ? last_y : SCREENMAX >> 1; else new_y = y + i; if (can_scroll_reverse == TRUE && page_scroll == TRUE) { set_cursor (0, YMAX); /* Erase very bottom line */ clear_lastline (); } else display (0, top_line, last_y, new_y); move_y (new_y);}/* * Go to top of file, scrolling if possible, else redrawing screen. */voidBFILE (){ if (proceed (top_line, - SCREENMAX) == header) PU (); /* It fits. Let PU do it */ else { reset (header->next, 0);/* Reset top_line, etc. */ RD_y (0); /* Display full page */ } move_to (LINE_START, 0);}/* * Go to last position of text, scrolling if possible, else redrawing screen */voidEFILE (){ /* if (tail->prev->text [0] != '\n') dummy_line (); */ if (proceed (bot_line, SCREENMAX) == tail) PD (); /* It fits. Let PD do it */ else { reset (proceed (tail->prev, - SCREENMAX), SCREENMAX); RD_y (last_y); /* Display full page */ } move_to (LINE_END /* not START ("EFILE"!) */, last_y);}/* * Scroll one line up. Leave the cursor on the same line (if possible). */voidSU (){ register int i; if (hop_flag > 0) { hop_flag = 0; for (i = 0; i < (SCREENMAX >> 1); i ++) SU (); return; } if (reverse_scroll (TRUE) != ERRORS) { /* else we are at top of file */ move_y ((y == SCREENMAX) ? SCREENMAX : y + 1); }}/* * Scroll one line down. Leave the cursor on the same line (if possible). */voidSD (){ register int i; if (hop_flag > 0) { hop_flag = 0; for (i = 0; i < (SCREENMAX >> 1); i ++) SD (); return; } if (forward_scroll (TRUE) != ERRORS) move_y ((y == 0) ? 0 : y - 1);}/* * Perform a forward scroll. It returns ERRORS if we're at the last line of * the file. */intforward_scroll (update) FLAG update;{ if (bot_line->next == tail) /* Last line of file. No dice */ return ERRORS; top_line = top_line->next; bot_line = bot_line->next; cur_line = cur_line->next;/* Perform the scroll on screen */ if (update == TRUE) { scroll_forward (); set_cursor (0, SCREENMAX); line_print (bot_line); } return FINE;}/* * Perform a backwards scroll. It returns ERRORS if we're at the first line * of the file. It updates the display completely if update is TRUE. * Otherwise it leaves that to the caller (page up function). */intreverse_scroll (update) FLAG update;{ if (top_line->prev == header) return ERRORS; /* Top of file. Can't scroll */ if (last_y != SCREENMAX) /* Reset last_y if necessary */ last_y ++; else bot_line = bot_line->prev; /* Else adjust bot_line */ top_line = top_line->prev; cur_line = cur_line->prev;/* Perform the scroll on screen */ if (update == TRUE) if (can_scroll_reverse == TRUE) { set_cursor (0, 0); scroll_reverse (); set_cursor (0, YMAX); /* Erase very bottom line */ clear_lastline (); set_cursor (0, 0); line_print (top_line); } else display (0, top_line, last_y, y); return FINE;}/*----------------------* * Word moves * *----------------------*//* * A word was previously defined as a number of non-blank characters * separated by tabs, spaces or linefeeds. * By consulting idfchar (), sequences of real letters only or digits * or underlines are recognized as words. */extern int idfchar ();/* * BSEN () and ESEN () look for the beginning or end of the current sentence. */voidBSEN (){ search_for ("[;.]", REVERSE);}voidESEN (){ search_for ("[;.]", FORWARD);}/* * SIDF () searches for the identifier at the current position */voidSIDF (method) FLAG method;{ char idf_buf [MAX_CHARS]; /* identifier to search for */ char * idf_buf_poi = idf_buf; char * idf_poi; if (! alpha (* cur_text)) { error ("No identifier", NIL_PTR); return; } else { idf_poi = cur_text; while (alpha (* idf_poi) && idf_poi != cur_line->text) idf_poi --; if (! alpha (* idf_poi)) idf_poi ++; while (alpha (* idf_poi)) * idf_buf_poi ++ = * idf_poi ++; * idf_buf_poi = '\0'; search_for (idf_buf, method); }}/* * MPW () moves to the start of the previous word. A word is defined as a * number of non-blank characters separated by tabs spaces or linefeeds. */voidmove_previous_word (remove) FLAG remove;{ register char * begin_line; register char * textp; char start_char = * cur_text; char * start_pos = cur_text; FLAG idfsearch; if (remove == DELETE && viewonly == TRUE) {viewonlyerr (); return;}/* First check if we're at the beginning of line. */ if (cur_text == cur_line->text) { if (cur_line->prev == header) return; start_char = '\0'; } MLF (); begin_line = cur_line->text; textp = cur_text;/* Check if we're in the middle of a word. */ if (!alpha (* textp) || !alpha (start_char)) { while (textp != begin_line && (white_space (* textp) || * textp == '\n')) textp --; }/* Now we're at the end of previous word. Skip non-blanks until a blank comes */ if (idfchar (* textp)) { idfsearch = TRUE; while (textp != begin_line && idfchar (* textp)) textp --; } else { idfsearch = FALSE; while (textp != begin_line && alpha (* textp) && !idfchar (* textp)) textp --; }/* Go to the next char if we're not at the beginning of the line *//* At the beginning of the line, check whether to stay or to go to the word */ if (textp != begin_line && * textp != '\n') textp ++; else if (textp == begin_line && * textp != '\n' && ((idfsearch == TRUE) ? !idfchar (* textp) /* : white_space (* textp) */ : (!alpha (* textp) || idfchar (* textp)))) { textp ++; if (white_space (* textp) || textp == start_pos) /* no word there or not moved, so go back */ textp --; }/* Find the x-coordinate of this address, and move to it */ move_address (textp, y); if (remove == DELETE) (void) delete_text (cur_line, textp, cur_line, start_pos);}voidMPW (){ if (hop_flag > 0) BSEN (); else move_previous_word (NO_DELETE);}/* * MNW () moves to the start of the next word. A word is defined as a number of * non-blank characters separated by tabs spaces or linefeeds. Always keep in * mind that the pointer shouldn't pass the '\n'. */voidmove_next_word (remove) FLAG remove;{ register char * textp = cur_text; if (remove == DELETE && viewonly == TRUE) {viewonlyerr (); return;}/* Move to the end of the current word. */ if (idfchar (* textp)) while (* textp != '\n' && idfchar (* textp)) textp ++; else while (alpha (* textp) && !idfchar (* textp)) textp ++;/* Skip all white spaces */ while (* textp != '\n' && white_space (* textp)) textp ++;/* If we're deleting, delete the text in between */ if (remove == DELETE) { (void) delete_text (cur_line, cur_text, cur_line, textp); return; }/* If we're at end of line, move to the beginning of (first word on) the next line */ if (* textp == '\n' && cur_line->next != tail) { MDN (); move_to (LINE_START, y); textp = cur_text;/* while (* textp != '\n' && white_space (* textp)) *//* textp ++; */ } move_address (textp, y);}voidMNW (){ if (hop_flag > 0) ESEN (); else move_next_word (NO_DELETE);}/* * find_y () checks if the matched line is on the current page. If it is, it * returns the new y coordinate, else it displays the correct page with the * matched line in the middle and returns the new y value; */int
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -