📄 mined1.c
字号:
#ifdef UNIX tputs(SO, 0, _putchar);#else string_print (rev_video);#endif /* UNIX */ putchar(*textp++ + '\100');#ifdef UNIX tputs(SE, 0, _putchar);#else string_print (normal_video);#endif /* UNIX */ } else putchar(*textp++); count++; } }/* If line is longer than XBREAK chars, print the shift_mark */ if (count == XBREAK && *textp != '\n') putchar(textp[1]=='\n' ? *textp : SHIFT_MARK);/* Clear the rest of the line is clear_line is TRUE */ if (clear_line == TRUE) {#ifdef UNIX tputs(CE, 0, _putchar);#else string_print(blank_line);#endif /* UNIX */ putchar('\n'); }}/* * Flush the I/O buffer on filedescriptor fd. */int flush_buffer(fd)int fd;{ if (out_count <= 0) /* There is nothing to flush */ return FINE;#ifdef UNIX if (fd == STD_OUT) { printf("%.*s", out_count, screen); _flush(); } else#endif /* UNIX */ if (write(fd, screen, out_count) != out_count) { bad_write(fd); return ERRORS; } clear_buffer(); /* Empty buffer */ return FINE;}/* * Bad_write() is called when a write failed. Notify the user. */void bad_write(fd)int fd;{ if (fd == STD_OUT) /* Cannot write to terminal? */ exit(1); clear_buffer(); build_string(text_buffer, "Command aborted: %s (File incomplete)", (errno == ENOSPC || errno == -ENOSPC) ? "No space on device" : "Write error"); error(text_buffer, NIL_PTR);}/* * Catch the SIGQUIT signal (^\) send to mined. It turns on the quitflag. */void catch(sig)int sig;{/* Reset the signal */ signal(SIGQUIT, catch); quit = TRUE;}/* * Abort_mined() will leave mined. Confirmation is asked first. */void abort_mined(){ quit = FALSE;/* Ask for confirmation */ status_line("Really abort? ", NIL_PTR); if (getchar() != 'y') { clear_status(); return; }/* Reset terminal */ raw_mode(OFF); set_cursor(0, ymax); putchar('\n'); flush();#ifdef UNIX abort();#else exit(1);#endif /* UNIX */}#define UNDEF _POSIX_VDISABLE/* * Set and reset tty into CBREAK or old mode according to argument `state'. It * also sets all signal characters (except for ^\) to UNDEF. ^\ is caught. */void raw_mode(state)FLAG state;{ static struct termios old_tty; static struct termios new_tty; if (state == OFF) { tcsetattr(input_fd, TCSANOW, &old_tty); return; }/* Save old tty settings */ tcgetattr(input_fd, &old_tty);/* Set tty to CBREAK mode */ tcgetattr(input_fd, &new_tty); new_tty.c_lflag &= ~(ICANON|ECHO|ECHONL); new_tty.c_iflag &= ~(IXON|IXOFF);/* Unset signal chars, leave only SIGQUIT set to ^\ */ new_tty.c_cc[VINTR] = new_tty.c_cc[VSUSP] = UNDEF; new_tty.c_cc[VQUIT] = '\\' & 037; signal(SIGQUIT, catch); /* Which is caught */ tcsetattr(input_fd, TCSANOW, &new_tty);}/* * Panic() is called with an error number and a message. It is called when * something unrecoverable has happened. * It writes the message to the terminal, resets the tty and exits. * Ask the user if he wants to save his file. */void panic(message)register char *message;{ extern char yank_file[];#ifdef UNIX tputs(CL, 0, _putchar); build_string(text_buffer, "%s\nError code %d\n", message, errno);#else build_string(text_buffer, "%s%s\nError code %d\n", enter_string, message, errno);#endif /* UNIX */ (void) write(STD_OUT, text_buffer, length_of(text_buffer)); if (loading == FALSE) XT(); /* Check if file can be saved */ else (void) unlink(yank_file); raw_mode(OFF);#ifdef UNIX abort();#else exit(1);#endif /* UNIX */}char *alloc(bytes)int bytes;{ char *p; p = malloc((unsigned) bytes); if (p == NIL_PTR) { if (loading == TRUE) panic("File too big."); panic("Out of memory."); } return(p);}void free_space(p)char *p;{ free(p);}/* ======================================================================== * * Main loops * * ======================================================================== *//* The mapping between input codes and functions. */void (*key_map[256])() = { /* map ASCII characters to functions */ /* 000-017 */ MA, BL, MP, YA, SD, RD, MN, IF, DPC, S, S, DT, LR, S, DNW,LIB, /* 020-037 */ DPW, WB, GR, SH, DLN, SU, VI, XWT, XT, PT, EL, ESC, I, GOTO, HIGH, LOW, /* 040-057 */ S, S, S, S, S, S, S, S, S, S, S, S, S, S, S, S, /* 060-077 */ S, S, S, S, S, S, S, S, S, S, S, S, S, S, S, S, /* 100-117 */ S, S, S, S, S, S, S, S, S, S, S, S, S, S, S, S, /* 120-137 */ S, S, S, S, S, S, S, S, S, S, S, S, S, S, S, S, /* 140-157 */ S, S, S, S, S, S, S, S, S, S, S, S, S, S, S, S, /* 160-177 */ S, S, S, S, S, S, S, S, S, S, S, S, S, S, S, DCC, /* 200-217 */ S, S, S, S, S, S, S, S, S, S, S, S, S, S, S, S, /* 220-237 */ S, S, S, S, S, S, S, S, S, S, S, S, S, S, S, S, /* 240-257 */ S, S, S, S, S, S, S, S, S, S, S, S, S, S, S, S, /* 260-277 */ S, S, S, S, S, S, S, S, S, S, S, S, S, S, S, S, /* 300-317 */ S, S, S, S, S, S, S, S, S, S, S, S, S, S, S, S, /* 320-337 */ S, S, S, S, S, S, S, S, S, S, S, S, S, S, S, S, /* 340-357 */ S, S, S, S, S, S, S, S, S, S, S, S, S, S, S, S, /* 360-377 */ S, S, S, S, S, S, S, S, S, S, S, S, S, S, S, S,};int nlines; /* Number of lines in file */LINE *header; /* Head of line list */LINE *tail; /* Last line in line list */LINE *cur_line; /* Current line in use */LINE *top_line; /* First line of screen */LINE *bot_line; /* Last line of screen */char *cur_text; /* Current char on current line in use */int last_y; /* Last y of screen. Usually SCREENMAX */char screen[SCREEN_SIZE]; /* Output buffer for "writes" and "reads" */int x, y; /* x, y coordinates on screen */FLAG modified = FALSE; /* Set when file is modified */FLAG stat_visible; /* Set if status_line is visible */FLAG writable; /* Set if file cannot be written */FLAG loading; /* Set if we are loading a file. */FLAG quit = FALSE; /* Set when quit character is typed */FLAG rpipe = FALSE; /* Set if file should be read from stdin */int input_fd = 0; /* Fd for command input */int out_count; /* Index in output buffer */char file_name[LINE_LEN]; /* Name of file in use */char text_buffer[MAX_CHARS]; /* Buffer for modifying text *//* Escape sequences. */#ifdef UNIXchar *CE, *VS, *SO, *SE, *CL, *AL, *CM;#elsechar *enter_string = "\033[H\033[J"; /* String printed on entering mined */char *pos_string = "\033[%d;%dH"; /* Absolute cursor position */char *rev_scroll = "\033M"; /* String for reverse scrolling */char *rev_video = "\033[7m"; /* String for starting reverse video */char *normal_video = "\033[m"; /* String for leaving reverse video */char *blank_line = "\033[K"; /* Clear line to end */#endif /* UNIX *//* * Yank variables. */FLAG yank_status = NOT_VALID; /* Status of yank_file */char yank_file[] = "/tmp/mined.XXXXXX";long chars_saved; /* Nr of chars in buffer *//* * Initialize is called when a another file is edited. It free's the allocated * space and sets modified back to FALSE and fixes the header/tail pointer. */void initialize(){ register LINE *line, *next_line;/* Delete the whole list */ for (line = header->next; line != tail; line = next_line) { next_line = line->next; free_space(line->text); free_space((char*)line); }/* header and tail should point to itself */ line->next = line->prev = line; x = y = 0; rpipe = modified = FALSE;}/* * Basename() finds the absolute name of the file out of a given path_name. */char *basename(path)char *path;{ register char *ptr = path; register char *last = NIL_PTR; while (*ptr != '\0') { if (*ptr == '/') last = ptr; ptr++; } if (last == NIL_PTR) return path; if (*(last + 1) == '\0') { /* E.g. /usr/tmp/pipo/ */ *last = '\0'; return basename(path);/* Try again */ } return last + 1;}/* * Load_file loads the file `file' into core. If file is a NIL_PTR or the file * couldn't be opened, just some initializations are done, and a line consisting * of a `\n' is installed. */void load_file(file)char *file;{ register LINE *line = header; register int len; long nr_of_chars = 0L; int fd = -1; /* Filedescriptor for file */ nlines = 0; /* Zero lines to start with *//* Open file */ writable = TRUE; /* Benefit of the doubt */ if (file == NIL_PTR) { if (rpipe == FALSE) status_line("No file.", NIL_PTR); else { fd = 0; file = "standard input"; } file_name[0] = '\0'; } else { copy_string(file_name, file); /* Save file name */ if (access(file, 0) < 0) /* Cannot access file. */ status_line("New file ", file); else if ((fd = open(file, 0)) < 0) status_line("Cannot open ", file); else if (access(file, 2) != 0) /* Set write flag */ writable = FALSE; }/* Read file */ loading = TRUE; /* Loading file, so set flag */ if (fd >= 0) { status_line("Reading ", file); while ((len = get_line(fd, text_buffer)) != ERRORS) { line = line_insert(line, text_buffer, len); nr_of_chars += (long) len; } if (nlines == 0) /* The file was empty! */ line = line_insert(line, "\n", 1); clear_buffer(); /* Clear output buffer */ cur_line = header->next; fstatus("Read", nr_of_chars); (void) close(fd); /* Close file */ } else /* Just install a "\n" */ (void) line_insert(line, "\n", 1); reset(header->next, 0); /* Initialize pointers *//* Print screen */ display (0, 0, header->next, last_y); move_to (0, 0); flush(); /* Flush buffer */ loading = FALSE; /* Stop loading, reset flag */}/* * Get_line reads one line from filedescriptor fd. If EOF is reached on fd, * get_line() returns ERRORS, else it returns the length of the string. */int get_line(fd, buffer)int fd;register char *buffer;{ static char *last = NIL_PTR; static char *current = NIL_PTR; static int read_chars; register char *cur_pos = current; char *begin = buffer; do { if (cur_pos == last) { if ((read_chars = read(fd, screen, SCREEN_SIZE)) <= 0) break; last = &screen[read_chars]; cur_pos = screen; } if (*cur_pos == '\0') *cur_pos = ' '; } while ((*buffer++ = *cur_pos++) != '\n'); current = cur_pos; if (read_chars <= 0) { if (buffer == begin) return ERRORS; if (*(buffer - 1) != '\n') if (loading == TRUE) /* Add '\n' to last line of file */ *buffer++ = '\n'; else { *buffer = '\0'; return NO_LINE; } } *buffer = '\0'; return buffer - begin;}/* * Install_line installs the buffer into a LINE structure It returns a pointer * to the allocated structure. */LINE *install_line(buffer, length)char *buffer;int length;{ register LINE *new_line = (LINE *) alloc(sizeof(LINE)); new_line->text = alloc(length + 1); new_line->shift_count = 0; copy_string(new_line->text, buffer); return new_line;}void main(argc, argv)int argc;char *argv[];{/* mined is the Minix editor. */ register int index; /* Index in key table */ struct winsize winsize;#ifdef UNIX get_term(); tputs(VS, 0, _putchar); tputs(CL, 0, _putchar);#else string_print(enter_string); /* Hello world */#endif /* UNIX */ if (ioctl(STD_OUT, TIOCGWINSZ, &winsize) == 0 && winsize.ws_row != 0) { ymax = winsize.ws_row - 1; screenmax = ymax - 1; } if (!isatty(0)) { /* Reading from pipe */ if (argc != 1) { write(2, "Cannot find terminal.\n", 22); exit (1); } rpipe = TRUE; modified = TRUE; /* Set modified so he can write */ open_device(); } raw_mode(ON); /* Set tty to appropriate mode */ header = tail = (LINE *) alloc(sizeof(LINE)); /* Make header of list*/ header->text = NIL_PTR; header->next = tail->prev = header;/* Load the file (if any) */ if (argc < 2) load_file(NIL_PTR); else { (void) get_file(NIL_PTR, argv[1]); /* Truncate filename */ load_file(argv[1]); } /* Main loop of the editor. */ for (;;) { index = getchar(); if (stat_visible == TRUE) clear_status(); if (quit == TRUE) abort_mined(); else { /* Call the function for this key */ (*key_map[index])(index); flush(); /* Flush output (if any) */ if (quit == TRUE) quit = FALSE; } } /* NOTREACHED */}/* ======================================================================== * * Miscellaneous * * ======================================================================== *//* * Redraw the screen
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -