📄 mined2.c
字号:
/* * Part 2 of the mined editor. *//* ======================================================================== * * Move Commands * * ======================================================================== */#include "mined.h"#include <string.h>/* * Move one line up. */void UP(){ if (y == 0) { /* Top line of screen. Scroll one line */ (void) reverse_scroll(); move_to(x, y); } else /* Move to previous line */ move_to(x, y - 1);}/* * Move one line down. */void DN(){ if (y == last_y) { /* Last line of screen. Scroll one line */ if (bot_line->next == tail && bot_line->text[0] != '\n') { dummy_line(); /* Create new empty line */ DN(); return; } else { (void) forward_scroll(); move_to(x, y); } } else /* Move to next line */ move_to(x, y + 1);}/* * Move left one position. */void LF(){ if (x == 0 && get_shift(cur_line->shift_count) == 0) {/* Begin of line */ if (cur_line->prev != header) { UP(); /* Move one line up */ move_to(LINE_END, y); } } else move_to(x - 1, y);}/* * Move right one position. */void RT(){ if (*cur_text == '\n') { if (cur_line->next != tail) { /* Last char of file */ DN(); /* Move one line down */ move_to(LINE_START, y); } } else move_to(x + 1, y);}/* * Move to coordinates [0, 0] on screen. */void HIGH(){ move_to(0, 0);}/* * Move to coordinates [0, YMAX] on screen. */void LOW(){ move_to(0, last_y);}/* * Move to begin of line. */void BL(){ move_to(LINE_START, y);}/* * Move to end of line. */void EL(){ move_to(LINE_END, y);}/* * GOTO() prompts for a linenumber and moves to that line. */void GOTO(){ int number; LINE *line; if (get_number("Please enter line number.", &number) == ERRORS) return; if (number <= 0 || (line = proceed(header->next, number - 1)) == tail) error("Illegal line number: ", num_out((long) number)); else move_to(x, find_y(line));}/* * 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. */void PD(){ register int i; for (i = 0; i < screenmax; i++) if (forward_scroll() == ERRORS) break; /* EOF reached */ if (y - i < 0) /* Line no longer on screen */ move_to(0, screenmax >> 1); else move_to(0, y - i);}/* * 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. */void PU(){ register int i; for (i = 0; i < screenmax; i++) if (reverse_scroll() == ERRORS) break; /* Top of file reached */ set_cursor(0, ymax); /* Erase very bottom line */#ifdef UNIX tputs(CE, 0, _putchar);#else string_print(blank_line);#endif /* UNIX */ if (y + i > screenmax) /* line no longer on screen */ move_to(0, screenmax >> 1); else move_to(0, y + i);}/* * Go to top of file, scrolling if possible, else redrawing screen. */void HO(){ if (proceed(top_line, -screenmax) == header) PU(); /* It fits. Let PU do it */ else { reset(header->next, 0);/* Reset top_line, etc. */ RD(); /* Display full page */ } move_to(LINE_START, 0);}/* * Go to last line of file, scrolling if possible, else redrawing screen */void EF(){ 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(); /* Display full page */ } move_to(LINE_START, last_y);}/* * Scroll one line up. Leave the cursor on the same line (if possible). */void SU(){ if (top_line->prev == header) /* Top of file. Can't scroll */ return; (void) reverse_scroll(); set_cursor(0, ymax); /* Erase very bottom line */#ifdef UNIX tputs(CE, 0, _putchar);#else string_print(blank_line);#endif /* UNIX */ move_to(x, (y == screenmax) ? screenmax : y + 1);}/* * Scroll one line down. Leave the cursor on the same line (if possible). */void SD(){ if (forward_scroll() != ERRORS) move_to(x, (y == 0) ? 0 : y - 1); else set_cursor(x, y);}/* * Perform a forward scroll. It returns ERRORS if we're at the last line of the * file. */int forward_scroll(){ 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; set_cursor(0, ymax); line_print(bot_line); return FINE;}/* * Perform a backwards scroll. It returns ERRORS if we're at the first line * of the file. */int reverse_scroll(){ 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 */ set_cursor(0, 0);#ifdef UNIX tputs(AL, 0, _putchar);#else string_print(rev_scroll);#endif /* UNIX */ set_cursor(0, 0); line_print(top_line); return FINE;}/* * A word is defined as a number of non-blank characters separated by tabs * spaces or linefeeds. *//* * MP() 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. */void MP(){ move_previous_word(NO_DELETE);}void move_previous_word(remove)FLAG remove;{ register char *begin_line; register char *textp; char start_char = *cur_text; char *start_pos = cur_text;/* Fist check if we're at the beginning of line. */ if (cur_text == cur_line->text) { if (cur_line->prev == header) return; start_char = '\0'; } LF(); 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 */ while (textp != begin_line && alpha(*textp)) textp--;/* Go to the next char if we're not at the beginning of the line */ if (textp != begin_line && *textp != '\n') textp++;/* Find the x-coordinate of this address, and move to it */ move_address(textp); if (remove == DELETE) delete(cur_line, textp, cur_line, start_pos);}/* * MN() 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'. */void MN(){ move_next_word(NO_DELETE);}void move_next_word(remove)FLAG remove;{ register char *textp = cur_text;/* Move to the end of the current word. */ while (*textp != '\n' && alpha(*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) { delete(cur_line, cur_text, cur_line, textp); return; }/* If we're at end of line. move to the first word on the next line. */ if (*textp == '\n' && cur_line->next != tail) { DN(); move_to(LINE_START, y); textp = cur_text; while (*textp != '\n' && white_space(*textp)) textp++; } move_address(textp);}/* ======================================================================== * * Modify Commands * * ======================================================================== *//* * DCC deletes the character under the cursor. If this character is a '\n' the * current line is joined with the next one. * If this character is the only character of the line, the current line will * be deleted. */void DCC(){ if (*cur_text == '\n') delete(cur_line,cur_text, cur_line->next,cur_line->next->text); else delete(cur_line, cur_text, cur_line, cur_text + 1);}/* * DPC deletes the character on the left side of the cursor. If the cursor is * at the beginning of the line, the last character if the previous line is * deleted. */void DPC(){ if (x == 0 && cur_line->prev == header) return; /* Top of file */ LF(); /* Move one left */ DCC(); /* Delete character under cursor */}/* * DLN deletes all characters until the end of the line. If the current * character is a '\n', then delete that char. */void DLN(){ if (*cur_text == '\n') DCC(); else delete(cur_line, cur_text, cur_line, cur_text + length_of(cur_text) -1);}/* * DNW() deletes the next word (as described in MN()) */void DNW(){ if (*cur_text == '\n') DCC(); else move_next_word(DELETE);}/* * DPW() deletes the next word (as described in MP()) */void DPW(){ if (cur_text == cur_line->text) DPC(); else move_previous_word(DELETE);}/* * Insert character `character' at current location. */void S(character)register char character;{ static char buffer[2]; buffer[0] = character;/* Insert the character */ if (insert(cur_line, cur_text, buffer) == ERRORS) return;/* Fix screen */ if (character == '\n') { set_cursor(0, y); if (y == screenmax) { /* Can't use display */ line_print(cur_line); (void) forward_scroll(); } else { reset(top_line, y); /* Reset pointers */ display(0, y, cur_line, last_y - y); } move_to(0, (y == screenmax) ? y : y + 1); } else if (x + 1 == XBREAK)/* If line must be shifted, just call move_to*/ move_to(x + 1, y); else { /* else display rest of line */ put_line(cur_line, x, FALSE); move_to(x + 1, y); }}/* * CTL inserts a control-char at the current location. A message that this * function is called is displayed at the status line. */void CTL(){ register char ctrl; status_line("Enter control character.", NIL_PTR); if ((ctrl = getchar()) >= '\01' && ctrl <= '\037') { S(ctrl); /* Insert the char */ clear_status(); } else error ("Unknown control character", NIL_PTR);}/* * LIB insert a line at the current position and moves back to the end of * the previous line. */void LIB(){ S('\n'); /* Insert the line */ UP(); /* Move one line up */ move_to(LINE_END, y); /* Move to end of this line */}/* * Line_insert() inserts a new line with text pointed to by `string'. * It returns the address of the new line. */LINE *line_insert(line, string, len)register LINE *line;char *string;int len;{ register LINE *new_line;/* Allocate space for LINE structure and text */ new_line = install_line(string, len);/* Install the line into the double linked list */ new_line->prev = line; new_line->next = line->next; line->next = new_line; new_line->next->prev = new_line;/* Increment nlines */ nlines++; return new_line;}/* * Insert() insert the string `string' at the given line and location. */int insert(line, location, string)register LINE *line;char *location, *string;{ register char *bufp = text_buffer; /* Buffer for building line */ register char *textp = line->text; if (length_of(textp) + length_of(string) >= MAX_CHARS) { error("Line too long", NIL_PTR); return ERRORS; } modified = TRUE; /* File has been modified *//* Copy part of line until `location' has been reached */ while (textp != location) *bufp++ = *textp++; /* Insert string at this location */ while (*string != '\0') *bufp++ = *string++; *bufp = '\0'; if (*(string - 1) == '\n') /* Insert a new line */ (void) line_insert(line, location, length_of(location)); else /* Append last part of line */ copy_string(bufp, location);/* Install the new text in this line */ free_space(line->text); line->text = alloc(length_of(text_buffer) + 1); copy_string(line->text, text_buffer); return FINE;}/* * Line_delete() deletes the argument line out of the line list. The pointer to * the next line is returned. */LINE *line_delete(line)register LINE *line;{ register LINE *next_line = line->next;/* Delete the line */ line->prev->next = line->next; line->next->prev = line->prev;/* Free allocated space */ free_space(line->text); free_space((char*)line);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -