📄 mined.doc
字号:
Mined can be called with or without argument and the function load_file() is called with these arguments. load_file() checks if the file exists if it can be read and if it is writable and sets the writable flag accordingly. If the file can be read, load_file() reads a line from the file and stores this line into a structure by calling install_line() and line_insert() which installs the line into the double linked list, until the end of the file is reached. Lines are read by the function get_line(), which buffers the reading in blocks of SCREEN_SIZE. Load_file() also initializes the LINE * variables described above. 3.3 Moving around. Several commands are implemented for moving through the file. Moving up (UP), down (DN) left (LF) and right (RT) are done by the arrow keys. Moving one line below the screen scrolls the screen one line up. Moving one line above the screen scrolls the screen one line down. The functions forward_scroll() and reverse_scroll() take care of that. Several other move functions exist: move to begin of line (BL), end of line (EL) top of screen (HIGH), bottom of screen (LOW), top of file (HO), end of file (EF), scroll one page down (PD), scroll one page up (PU), scroll one line down (SD), scroll one line up (SU) and move to a certain line number (GOTO). Two functions called MN() and MP() each move one word further or backwards. A word is a number of non-blanks seperated by a space, a tab or a linefeed. 3.4 Modifying text. The modifying commands can be separated into two modes. The first being inserting text, and the other deleting text. Two functions are created for these purposes: insert() and delete(). Both are capable of deleting or inserting large amounts of text as well as one character. Insert() must be given the line and location at which the text must be inserted. Is doesn't make any difference whether this text contains linefeeds or not. Delete() must be given a pointer to the start line, a pointer from where deleting should start on that line and the same information about the end position. The last character of the file will never be deleted. Delete() will make the necessary changes to the screen after deleting, but insert() won't. The functions for modifying text are: insert one char (S), insert a file (file_insert(fd)), insert a linefeed and put cursor back to end of line (LIB), delete character under the cursor (DCC), delete before cursor (even linefeed) (DPC), delete next word (DNW), delete previous word (DPW) and delete to end of line (if the cursor is at a linefeed delete line) (DLN). 3.5 Yanking. A few utilities are provided for yanking pieces of text. The function MA() marks the current position in the file. This is done by setting LINE * mark_line and char * mark_text to the current position. Yanking of text can be done in two modes. The first mode just copies the text from the mark to the current position (or visa versa) into a buffer (YA) and the second also deletes the text (DT). Both functions call the function set_up() with the delete flag on or off. Set_up() checks if the marked position is still a valid one (by using check_mark() and legal()), and then calls the function yank() with a start and end position in the file. This function copies the text into a scratch_file as indicated by the variable yank_file. This scratch_file is made unique by the function scratch_file(). At the end of copying yank will (if necessary) delete the text. A global flag called yank_status keeps track of the buffer (or file) status. It is initialized on NOT_VALID and set to EMPTY (by set_up()) or VALID (by yank()). Several things can be done with the buffer. It can be inserted somewhere else in the file (PT) or it can be copied into another file (WB), which will be prompted for. 3.6 Search and replace routines. Searching for strings and replacing strings are done by regular expressions. For any expression the function compile() is called with as argument the expression to compile. Compile() returns a pointer to a structure which looks like this: typedef struct regex { union { char * err_mess; int * expression; } result; char status; char * start_ptr; char * end_ptr; } REGEX; If something went wrong during compiling (e.g. an illegal expression was given), the function reg_error() is called, which sets the status field to REG_ERROR and the err_mess field to the error message. If the match must be anchored at the beginning of the line (end of line), the status field is set to BEGIN_LINE (END_LINE). If none of these special cases are true, the field is set to 0 and the function finished() is called. Finished() allocates space to hold the compiled expression and copies this expression into the expression field of the union (bcopy()). Matching is done by the routines match() and line_check(). Match() takes as argument the REGEX * program, a pointer to the startposition on the current line, and a flag indicating FORWARD or REVERSE search. Match() checks out the whole file until a match is found. If match is found it returns a pointer to the line in which the match was found else it returns a NIL_LINE. Line_check() takes the same arguments, but return either MATCH or NO_MATCH. During checking, the start_ptr and end_ptr fields of the REGEX structure are assigned to the start and end of the match. Both functions try to find a match by walking through the line character by character. For each possibility, the function check_string() is called with as arguments the REGEX * program and the string to search in. It starts walking through the expression until the end of the expression or the end of the string is reached. Whenever a * is encountered, this position of the string is marked, the maximum number of matches are performed and the function star() is called in order to try to find the longest match possible. Star() takes as arguments the REGEX program, the current position of the string, the marked position and the current position of the expression Star() walks from the current position of the string back to the marked position, and calls string_check() in order to find a match. It returns MATCH or NO_MATCH, just as string_check() does. Searching is now easy. Both search routines (forward (SF) and backwards search (SR)) call search() with an apropiate message and a flag indicating FORWARD or REVERSE search. Search() will get an expression from the user by calling get_expression(). Get_expression() returns a pointer to a REGEX structure or NIL_REG upon errors and prompts for the expression. If no expression if given, the previous is used instead. After that search will call match(), and if a match is found, we can move to that place in the file by the functions find_x() and find_y() which will find display the match on the screen. Replacing can be done in two ways. A global replace (GR) or a line replace (LR). Both functions call change() with a message and a flag indicating global or line replacement. Change() will prompt for the expression and for the replacement. Every & in the replacement pattern means substitute the match instead. An & can be escaped by a \. When a match is found, the function substitute() will perform the substitution. 3.6 Miscellaneous commands. A few commands haven't be discussed yet. These are redraw the screen (RD) fork a shell (SH), print file status (FS), write file to disc (WT), insert a file at current position (IF), leave editor (XT) and visit another file (VI). The last two functions will check if the file has been modified. If it has, they will ask if you want to save the file by calling ask_save(). The function REPT() will repeat a command n times. It will prompt for the number. Aborting the loop can be done by sending the ^\ signal. 3.7 Utility functions. Several functions exists for internal use. First allocation routines: alloc(bytes) and newline() will return a pointer to free data space if the given size. If there is no more memory available, the function panic() is called. Signal handling: The only signal that can be sent to mined is the SIGQUIT signal. This signal, functions as a general abort command. Mined will abort if the signal is given during the main loop. The function abort_mined() takes care of that. Panic() is a function with as argument a error message. It will print the message and the error number set by the kernel (errno) and will ask if the file must be saved or not. It resets the terminal (raw_mode()) and exits. String handling routines like copy_string(to, from), length_of(string) and build_string(buffer, format, arg1, arg2, ...). The latter takes a description of the string out out the format field and puts the result in the buffer. (It works like printf (3), but then into a string). The functions status_line(string1, string2), error(string1, string2), clear_status() and bottom_line() all print information on the status line. Get_string(message, buffer) reads a string and getchar() reads one character from the terminal. Num_out((long) number) prints the number into a 11 digit field without leading zero's. It returns a pointer to the resulting string. File_status() prints all file information on the status line. Set_cursor(x, y) prints the string to put the cursor at coordinates x and y. Output is done by four functions: writeline(fd,string), clear_buffer() write_char(fd, c) and flush_buffer(fd). Three defines are provided to write on filedescriptor STD_OUT (terminal) which is used normally: string_print(string), putchar(c) and flush(). All these functions use the global I/O buffer screen and the global index for this array called out_count. In this way I/O can be buffered, so that reads or writes can be done in blocks of SCREEN_SIZE size. The following functions all handle internal line maintenance. The function proceed(start_line, count) returns the count'th line after start_line. If count is negative, the count'th line before the start_line is returned. If header or tail is encountered then that will be returned. Display(x, y, start_line, count) displays count lines starting at coordinates [x, y] and beginning at start_line. If the header or tail is encountered, empty lines are displayed instead. The function reset(head_line, ny) reset top_line, last_y, bot_line, cur_line and y-coordinate. This is not a neat way to do the maintenance, but it sure saves a lot of code. It is usually used in combination with display(). Put_line(line, offset, clear_line), prints a line (skipping characters according to the line->shift_size field) until XBREAK - offset characters are printed or a '\n' is encountered. If clear_line is TRUE, spaces are printed until XBREAK - offset characters. Line_print(line) is a #define from put_line(line, 0, TRUE). Moving is done by the functions move_to(x, y), move_addres(address) and move(x, adress, y). This function is the most important one in mined. New_y must be between 0 and last_y, new_x can be about anything, address must be a pointer to an character on the current line (or y). Move_to() first adjust the y coordinate together with cur_line. If an address is given, it finds the corresponding x-coordinate. If an new x-coordinate was given, it will try to locate the corresponding character. After that it sets the shift_count field of cur_line to an apropiate number according to new_x. The only thing left to do now is to assign the new values to cur_line, cur_text, x and y. 4. Summary of commands. See seperate file mined.help .+===========================================================================+
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -