vi: some simplifications
function old new delta file_insert 301 315 +14 init_text_buffer 179 171 -8 colon 2889 2878 -11 file_size 37 - -37 ------------------------------------------------------------------------------ (add/remove: 0/1 grow/shrink: 1/2 up/down: 14/-56) Total: -42 bytes Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
This commit is contained in:
parent
e7430867a8
commit
32afd3aa60
236
editors/vi.c
236
editors/vi.c
@ -491,7 +491,6 @@ struct globals {
|
||||
} while (0)
|
||||
|
||||
|
||||
static int init_text_buffer(char *); // init from file or create new
|
||||
static void edit_file(char *); // edit one file
|
||||
static void do_cmd(int); // execute a command
|
||||
static int next_tabstop(int);
|
||||
@ -543,7 +542,6 @@ static void cookmode(void); // return to "cooked" mode on tty
|
||||
static int mysleep(int);
|
||||
static int readit(void); // read (maybe cursor) key from stdin
|
||||
static int get_one_char(void); // read 1 char from stdin
|
||||
static int file_size(const char *); // what is the byte size of "fn"
|
||||
#if !ENABLE_FEATURE_VI_READONLY
|
||||
#define file_insert(fn, p, update_ro_status) file_insert(fn, p)
|
||||
#endif
|
||||
@ -578,8 +576,8 @@ static char *char_search(char *, const char *, int, int); // search for pattern
|
||||
#if ENABLE_FEATURE_VI_COLON
|
||||
static char *get_one_address(char *, int *); // get colon addr, if present
|
||||
static char *get_address(char *, int *, int *); // get two colon addrs, if present
|
||||
static void colon(char *); // execute the "colon" mode cmds
|
||||
#endif
|
||||
static void colon(char *); // execute the "colon" mode cmds
|
||||
#if ENABLE_FEATURE_VI_USE_SIGNALS
|
||||
static void winch_sig(int); // catch window size changes
|
||||
static void suspend_sig(int); // catch ctrl-Z
|
||||
@ -725,32 +723,29 @@ int vi_main(int argc, char **argv)
|
||||
static int init_text_buffer(char *fn)
|
||||
{
|
||||
int rc;
|
||||
int size = file_size(fn); // file size. -1 means does not exist.
|
||||
|
||||
flush_undo_data();
|
||||
modified_count = 0;
|
||||
last_modified_count = -1;
|
||||
#if ENABLE_FEATURE_VI_YANKMARK
|
||||
/* init the marks */
|
||||
memset(mark, 0, sizeof(mark));
|
||||
#endif
|
||||
|
||||
/* allocate/reallocate text buffer */
|
||||
free(text);
|
||||
text_size = size + 10240;
|
||||
text_size = 10240;
|
||||
screenbegin = dot = end = text = xzalloc(text_size);
|
||||
|
||||
if (fn != current_filename) {
|
||||
free(current_filename);
|
||||
current_filename = xstrdup(fn);
|
||||
}
|
||||
if (size < 0) {
|
||||
rc = file_insert(fn, text, 1);
|
||||
if (rc < 0) {
|
||||
// file doesnt exist. Start empty buf with dummy line
|
||||
char_insert(text, '\n', NO_UNDO);
|
||||
rc = 0;
|
||||
} else {
|
||||
rc = file_insert(fn, text, 1);
|
||||
}
|
||||
modified_count = 0;
|
||||
last_modified_count = -1;
|
||||
#if ENABLE_FEATURE_VI_YANKMARK
|
||||
/* init the marks. */
|
||||
memset(mark, 0, sizeof(mark));
|
||||
#endif
|
||||
return rc;
|
||||
}
|
||||
|
||||
@ -1018,13 +1013,71 @@ static void setops(const char *args, const char *opname, int flg_no,
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* FEATURE_VI_COLON */
|
||||
|
||||
// buf must be no longer than MAX_INPUT_LEN!
|
||||
static void colon(char *buf)
|
||||
{
|
||||
#if !ENABLE_FEATURE_VI_COLON
|
||||
/* Simple ":cmd" handler with minimal set of commands */
|
||||
char *p = buf;
|
||||
int cnt;
|
||||
|
||||
if (*p == ':')
|
||||
p++;
|
||||
cnt = strlen(p);
|
||||
if (cnt == 0)
|
||||
return;
|
||||
if (strncmp(p, "quit", cnt) == 0
|
||||
|| strncmp(p, "q!", cnt) == 0
|
||||
) {
|
||||
if (modified_count && p[1] != '!') {
|
||||
status_line_bold("No write since last change (:%s! overrides)", p);
|
||||
} else {
|
||||
editing = 0;
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (strncmp(p, "write", cnt) == 0
|
||||
|| strncmp(p, "wq", cnt) == 0
|
||||
|| strncmp(p, "wn", cnt) == 0
|
||||
|| (p[0] == 'x' && !p[1])
|
||||
) {
|
||||
cnt = file_write(current_filename, text, end - 1);
|
||||
if (cnt < 0) {
|
||||
if (cnt == -1)
|
||||
status_line_bold("Write error: %s", strerror(errno));
|
||||
} else {
|
||||
modified_count = 0;
|
||||
last_modified_count = -1;
|
||||
status_line("'%s' %dL, %dC",
|
||||
current_filename,
|
||||
count_lines(text, end - 1), cnt
|
||||
);
|
||||
if (p[0] == 'x' || p[1] == 'q' || p[1] == 'n'
|
||||
|| p[0] == 'X' || p[1] == 'Q' || p[1] == 'N'
|
||||
) {
|
||||
editing = 0;
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (strncmp(p, "file", cnt) == 0) {
|
||||
last_status_cksum = 0; // force status update
|
||||
return;
|
||||
}
|
||||
if (sscanf(p, "%d", &cnt) > 0) {
|
||||
dot = find_line(cnt);
|
||||
dot_skip_over_ws();
|
||||
return;
|
||||
}
|
||||
not_implemented(p);
|
||||
#else
|
||||
|
||||
char c, *orig_buf, *buf1, *q, *r;
|
||||
char *fn, cmd[MAX_INPUT_LEN], args[MAX_INPUT_LEN];
|
||||
int i, l, li, ch, b, e;
|
||||
int useforce, forced = FALSE;
|
||||
int i, l, li, b, e;
|
||||
int useforce;
|
||||
|
||||
// :3154 // if (-e line 3154) goto it else stay put
|
||||
// :4,33w! foo // write a portion of buffer to file "foo"
|
||||
@ -1046,7 +1099,7 @@ static void colon(char *buf)
|
||||
if (*buf == ':')
|
||||
buf++; // move past the ':'
|
||||
|
||||
li = ch = i = 0;
|
||||
li = i = 0;
|
||||
b = e = -1;
|
||||
q = text; // assume 1,$ for the range
|
||||
r = end - 1;
|
||||
@ -1127,6 +1180,8 @@ static void colon(char *buf)
|
||||
dot = yank_delete(q, r, 1, YANKDEL, ALLOW_UNDO); // save, then delete lines
|
||||
dot_skip_over_ws();
|
||||
} else if (strncmp(cmd, "edit", i) == 0) { // Edit a file
|
||||
int size;
|
||||
|
||||
// don't edit, if the current file has been modified
|
||||
if (modified_count && !useforce) {
|
||||
status_line_bold("No write since last change (:%s! overrides)", cmd);
|
||||
@ -1144,8 +1199,7 @@ static void colon(char *buf)
|
||||
goto ret;
|
||||
}
|
||||
|
||||
if (init_text_buffer(fn) < 0)
|
||||
goto ret;
|
||||
size = init_text_buffer(fn);
|
||||
|
||||
#if ENABLE_FEATURE_VI_YANKMARK
|
||||
if (Ureg >= 0 && Ureg < 28) {
|
||||
@ -1161,12 +1215,14 @@ static void colon(char *buf)
|
||||
li = count_lines(text, end - 1);
|
||||
status_line("'%s'%s"
|
||||
IF_FEATURE_VI_READONLY("%s")
|
||||
" %dL, %dC", current_filename,
|
||||
(file_size(fn) < 0 ? " [New file]" : ""),
|
||||
" %dL, %dC",
|
||||
current_filename,
|
||||
(size < 0 ? " [New file]" : ""),
|
||||
IF_FEATURE_VI_READONLY(
|
||||
((readonly_mode) ? " [Readonly]" : ""),
|
||||
)
|
||||
li, ch);
|
||||
li, (int)(end - text)
|
||||
);
|
||||
} else if (strncmp(cmd, "file", i) == 0) { // what File is this
|
||||
if (b != -1 || e != -1) {
|
||||
status_line_bold("No address allowed on this command");
|
||||
@ -1255,6 +1311,8 @@ static void colon(char *buf)
|
||||
}
|
||||
editing = 0;
|
||||
} else if (strncmp(cmd, "read", i) == 0) { // read file into text[]
|
||||
int size;
|
||||
|
||||
fn = args;
|
||||
if (!fn[0]) {
|
||||
status_line_bold("No filename given");
|
||||
@ -1268,23 +1326,24 @@ static void colon(char *buf)
|
||||
q = next_line(q);
|
||||
{ // dance around potentially-reallocated text[]
|
||||
uintptr_t ofs = q - text;
|
||||
ch = file_insert(fn, q, 0);
|
||||
size = file_insert(fn, q, /*update_ro:*/ 0);
|
||||
q = text + ofs;
|
||||
}
|
||||
if (ch < 0)
|
||||
if (size < 0)
|
||||
goto ret; // nothing was inserted
|
||||
// how many lines in text[]?
|
||||
li = count_lines(q, q + ch - 1);
|
||||
li = count_lines(q, q + size - 1);
|
||||
status_line("'%s'"
|
||||
IF_FEATURE_VI_READONLY("%s")
|
||||
" %dL, %dC", fn,
|
||||
" %dL, %dC",
|
||||
fn,
|
||||
IF_FEATURE_VI_READONLY((readonly_mode ? " [Readonly]" : ""),)
|
||||
li, ch);
|
||||
if (ch > 0) {
|
||||
li, size
|
||||
);
|
||||
if (size > 0) {
|
||||
// if the insert is before "dot" then we need to update
|
||||
if (q <= dot)
|
||||
dot += ch;
|
||||
// modified_count++;
|
||||
dot += size;
|
||||
}
|
||||
} else if (strncmp(cmd, "rewind", i) == 0) { // rewind cmd line args
|
||||
if (modified_count && !useforce) {
|
||||
@ -1409,6 +1468,9 @@ static void colon(char *buf)
|
||||
|| strncmp(cmd, "wn", i) == 0
|
||||
|| (cmd[0] == 'x' && !cmd[1])
|
||||
) {
|
||||
int size;
|
||||
//int forced = FALSE;
|
||||
|
||||
// is there a file name to write to?
|
||||
if (args[0]) {
|
||||
fn = args;
|
||||
@ -1421,34 +1483,33 @@ static void colon(char *buf)
|
||||
#endif
|
||||
// how many lines in text[]?
|
||||
li = count_lines(q, r);
|
||||
ch = r - q + 1;
|
||||
// see if file exists- if not, its just a new file request
|
||||
if (useforce) {
|
||||
size = r - q + 1;
|
||||
//if (useforce) {
|
||||
// if "fn" is not write-able, chmod u+w
|
||||
// sprintf(syscmd, "chmod u+w %s", fn);
|
||||
// system(syscmd);
|
||||
forced = TRUE;
|
||||
}
|
||||
// forced = TRUE;
|
||||
//}
|
||||
l = file_write(fn, q, r);
|
||||
if (useforce && forced) {
|
||||
//if (useforce && forced) {
|
||||
// chmod u-w
|
||||
// sprintf(syscmd, "chmod u-w %s", fn);
|
||||
// system(syscmd);
|
||||
forced = FALSE;
|
||||
}
|
||||
// forced = FALSE;
|
||||
//}
|
||||
if (l < 0) {
|
||||
if (l == -1)
|
||||
status_line_bold_errno(fn);
|
||||
} else {
|
||||
status_line("'%s' %dL, %dC", fn, li, l);
|
||||
if (q == text && r == end - 1 && l == ch) {
|
||||
if (q == text && r == end - 1 && l == size) {
|
||||
modified_count = 0;
|
||||
last_modified_count = -1;
|
||||
}
|
||||
if ((cmd[0] == 'x' || cmd[1] == 'q' || cmd[1] == 'n'
|
||||
|| cmd[0] == 'X' || cmd[1] == 'Q' || cmd[1] == 'N'
|
||||
)
|
||||
&& l == ch
|
||||
&& l == size
|
||||
) {
|
||||
editing = 0;
|
||||
}
|
||||
@ -1475,9 +1536,8 @@ static void colon(char *buf)
|
||||
colon_s_fail:
|
||||
status_line(":s expression missing delimiters");
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif /* FEATURE_VI_COLON */
|
||||
}
|
||||
|
||||
static void Hit_Return(void)
|
||||
{
|
||||
@ -2851,17 +2911,6 @@ static char *get_input_line(const char *prompt)
|
||||
#undef buf
|
||||
}
|
||||
|
||||
static int file_size(const char *fn) // what is the byte size of "fn"
|
||||
{
|
||||
struct stat st_buf;
|
||||
int cnt;
|
||||
|
||||
cnt = -1;
|
||||
if (fn && stat(fn, &st_buf) == 0) // see if file exists
|
||||
cnt = (int) st_buf.st_size;
|
||||
return cnt;
|
||||
}
|
||||
|
||||
// might reallocate text[]!
|
||||
static int file_insert(const char *fn, char *p, int update_ro_status)
|
||||
{
|
||||
@ -2869,42 +2918,40 @@ static int file_insert(const char *fn, char *p, int update_ro_status)
|
||||
int fd, size;
|
||||
struct stat statbuf;
|
||||
|
||||
/* Validate file */
|
||||
if (stat(fn, &statbuf) < 0) {
|
||||
status_line_bold_errno(fn);
|
||||
goto fi0;
|
||||
}
|
||||
if (!S_ISREG(statbuf.st_mode)) {
|
||||
// This is not a regular file
|
||||
status_line_bold("'%s' is not a regular file", fn);
|
||||
goto fi0;
|
||||
}
|
||||
if (p < text || p > end) {
|
||||
status_line_bold("Trying to insert file outside of memory");
|
||||
goto fi0;
|
||||
return cnt;
|
||||
}
|
||||
|
||||
// read file to buffer
|
||||
fd = open(fn, O_RDONLY);
|
||||
if (fd < 0) {
|
||||
status_line_bold_errno(fn);
|
||||
goto fi0;
|
||||
return cnt;
|
||||
}
|
||||
|
||||
/* Validate file */
|
||||
if (fstat(fd, &statbuf) < 0) {
|
||||
status_line_bold_errno(fn);
|
||||
goto fi;
|
||||
}
|
||||
if (!S_ISREG(statbuf.st_mode)) {
|
||||
status_line_bold("'%s' is not a regular file", fn);
|
||||
goto fi;
|
||||
}
|
||||
size = (statbuf.st_size < INT_MAX ? (int)statbuf.st_size : INT_MAX);
|
||||
p += text_hole_make(p, size);
|
||||
cnt = safe_read(fd, p, size);
|
||||
cnt = full_read(fd, p, size);
|
||||
if (cnt < 0) {
|
||||
status_line_bold_errno(fn);
|
||||
p = text_hole_delete(p, p + size - 1, NO_UNDO); // un-do buffer insert
|
||||
} else if (cnt < size) {
|
||||
// There was a partial read, shrink unused space text[]
|
||||
p = text_hole_delete(p + cnt, p + size - 1, NO_UNDO); // un-do buffer insert
|
||||
// There was a partial read, shrink unused space
|
||||
p = text_hole_delete(p + cnt, p + size - 1, NO_UNDO);
|
||||
status_line_bold("can't read '%s'", fn);
|
||||
}
|
||||
// if (cnt >= size)
|
||||
// modified_count++;
|
||||
fi:
|
||||
close(fd);
|
||||
fi0:
|
||||
|
||||
#if ENABLE_FEATURE_VI_READONLY
|
||||
if (update_ro_status
|
||||
&& ((access(fn, W_OK) < 0) ||
|
||||
@ -3821,50 +3868,7 @@ static void do_cmd(int c)
|
||||
break;
|
||||
case ':': // :- the colon mode commands
|
||||
p = get_input_line(":"); // get input line- use "status line"
|
||||
#if ENABLE_FEATURE_VI_COLON
|
||||
colon(p); // execute the command
|
||||
#else
|
||||
if (*p == ':')
|
||||
p++; // move past the ':'
|
||||
cnt = strlen(p);
|
||||
if (cnt <= 0)
|
||||
break;
|
||||
if (strncmp(p, "quit", cnt) == 0
|
||||
|| strncmp(p, "q!", cnt) == 0 // delete lines
|
||||
) {
|
||||
if (modified_count && p[1] != '!') {
|
||||
status_line_bold("No write since last change (:%s! overrides)", p);
|
||||
} else {
|
||||
editing = 0;
|
||||
}
|
||||
} else if (strncmp(p, "write", cnt) == 0
|
||||
|| strncmp(p, "wq", cnt) == 0
|
||||
|| strncmp(p, "wn", cnt) == 0
|
||||
|| (p[0] == 'x' && !p[1])
|
||||
) {
|
||||
cnt = file_write(current_filename, text, end - 1);
|
||||
if (cnt < 0) {
|
||||
if (cnt == -1)
|
||||
status_line_bold("Write error: %s", strerror(errno));
|
||||
} else {
|
||||
modified_count = 0;
|
||||
last_modified_count = -1;
|
||||
status_line("'%s' %dL, %dC", current_filename, count_lines(text, end - 1), cnt);
|
||||
if (p[0] == 'x' || p[1] == 'q' || p[1] == 'n'
|
||||
|| p[0] == 'X' || p[1] == 'Q' || p[1] == 'N'
|
||||
) {
|
||||
editing = 0;
|
||||
}
|
||||
}
|
||||
} else if (strncmp(p, "file", cnt) == 0) {
|
||||
last_status_cksum = 0; // force status update
|
||||
} else if (sscanf(p, "%d", &j) > 0) {
|
||||
dot = find_line(j); // go to line # j
|
||||
dot_skip_over_ws();
|
||||
} else { // unrecognized cmd
|
||||
not_implemented(p);
|
||||
}
|
||||
#endif /* !FEATURE_VI_COLON */
|
||||
break;
|
||||
case '<': // <- Left shift something
|
||||
case '>': // >- Right shift something
|
||||
|
Loading…
Reference in New Issue
Block a user