static int editing; // >0 while we are editing a file
-static int cmd_mode; // 0=command 1=insert
+static int cmd_mode; // 0=command 1=insert 2=replace
static int file_modified; // buffer contents changed
static int fn_start; // index of first cmd line file name
static int save_argc; // how many file names on cmd line
static void psb(const char *, ...); // Print Status Buf
static void psbs(const char *, ...); // Print Status Buf in standout mode
static void ni(Byte *); // display messages
-static void edit_status(void); // show file status on status line
+static void compute_edit_status(void); // format file status on status line
static void redraw(int); // force a full screen refresh
static void format_line(Byte*, Byte*, int);
static void refresh(int); // update the terminal from screen[]
if (ch < 1) {
(void) char_insert(text, '\n'); // start empty buf with dummy line
}
- file_modified = FALSE;
+ file_modified = 0;
#ifdef CONFIG_FEATURE_VI_YANKMARK
YDreg = 26; // default Yank/Delete reg
Ureg = 27; // hold orig line for "U" cmd
adding2q = 0;
#endif /* CONFIG_FEATURE_VI_DOT_CMD */
redraw(FALSE); // dont force every col re-draw
- edit_status();
show_status_line();
//------This is the main Vi cmd handling loop -----------------------
(void) char_insert(text, '\n');
ch= 1;
}
- file_modified = FALSE;
+ file_modified = 0;
#ifdef CONFIG_FEATURE_VI_YANKMARK
if (Ureg >= 0 && Ureg < 28 && reg[Ureg] != 0) {
free(reg[Ureg]); // free orig line reg- for 'U'
cfn = (Byte *) bb_xstrdup((char *) args);
} else {
// user wants file status info
- edit_status();
- show_status_line();
+ /* no-op */;
}
} else if (strncasecmp((char *) cmd, "features", i) == 0) { // what features are available
// print out values of all features
// if the insert is before "dot" then we need to update
if (q <= dot)
dot += ch;
- file_modified = TRUE;
+ file_modified++;
}
} else if (strncasecmp((char *) cmd, "rewind", i) == 0) { // rewind cmd line args
if (file_modified && ! useforce) {
}
psb("\"%s\" %dL, %dC", fn, li, l);
if (q == text && r == end - 1 && l == ch)
- file_modified = FALSE;
+ file_modified = 0;
if ((cmd[0] == 'x' || cmd[1] == 'q') && l == ch) {
editing = 0;
}
{
if (dot > text && dot[-1] != '\n')
dot--;
- edit_status(); // show current file status
- show_status_line();
}
static void dot_right(void)
{
if (dot < end - 1 && *dot != '\n')
dot++;
- edit_status(); // show current file status
- show_status_line();
}
static void dot_begin(void)
{
dot = begin_line(dot); // return pointer to first char cur line
- edit_status(); // show current file status
- show_status_line();
}
static void dot_end(void)
{
dot = end_line(dot); // return pointer to last char cur line
- edit_status(); // show current file status
- show_status_line();
}
static Byte *move_to_col(Byte * p, int l)
static void dot_next(void)
{
dot = next_line(dot);
- edit_status(); // show current file status
- show_status_line();
}
static void dot_prev(void)
{
dot = prev_line(dot);
- edit_status(); // show current file status
- show_status_line();
}
static void dot_scroll(int cnt, int dir)
if (dot > q)
dot = begin_line(q); // is dot is below bottom line?
dot_skip_over_ws();
- edit_status(); // show current file status
- show_status_line();
}
static void dot_skip_over_ws(void)
c = get_one_char();
*p = c;
p++;
- file_modified = TRUE; // has the file been modified
+ file_modified++; // has the file been modified
} else if (c == 27) { // Is this an ESC?
cmd_mode = 0;
cmdcnt = 0;
p = text_hole_make(p, 1);
if (p != 0) {
*p = c;
- file_modified = TRUE; // has the file been modified
+ file_modified++; // has the file been modified
p++;
}
return (p);
}
memset(p, ' ', size); // clear new hole
end = end + size; // adjust the new END
- file_modified = TRUE; // has the file been modified
+ file_modified++; // has the file been modified
thm0:
return (p);
}
dest = end - 1; // make sure dest in below end-1
if (end <= text)
dest = end = text; // keep pointers valid
- file_modified = TRUE; // has the file been modified
+ file_modified++; // has the file been modified
thd0:
return (dest);
}
psbs("could not read all of file \"%s\"", fn);
}
if (cnt >= size)
- file_modified = TRUE;
+ file_modified++;
fi0:
return (cnt);
}
static int last_cksum;
int l, cnt, cksum;
- //edit_status();
+ compute_edit_status();
cnt = strlen((char *) status_buffer);
for (cksum= l= 0; l < cnt; l++) { cksum += (int)(status_buffer[l]); }
// don't write the status line unless it changes
vsprintf((char *) status_buffer + strlen((char *) status_buffer), format, args);
strcat((char *) status_buffer, SOn); // Terminal standout mode off
va_end(args);
- show_status_line();
return;
}
va_start(args, format);
vsprintf((char *) status_buffer, format, args);
va_end(args);
- show_status_line();
return;
}
psbs("\'%s\' is not implemented", buf);
}
-static void edit_status(void) // show file status on status line
+static void compute_edit_status(void) // show file status on status line
{
- int cur, tot, percent;
+ int cur, percent;
+ static int tot;
+ static int last_file_modified = -1;
cur = count_lines(text, dot);
- tot = count_lines(text, end - 1);
+
+ /* try and reduce counting */
+ if (file_modified != last_file_modified) {
+ tot = cur + count_lines(dot, end - 1) - 1;
+ last_file_modified = file_modified;
+ }
// current line percent
// ------------- ~~ ----------
// total lines 100
#ifdef CONFIG_FEATURE_VI_READONLY
"%s"
#endif /* CONFIG_FEATURE_VI_READONLY */
+ "%s"
"%s line %d of %d --%d%%--",
(cfn != 0 ? (char *) cfn : "No file"),
#ifdef CONFIG_FEATURE_VI_READONLY
((vi_readonly || readonly) ? " [Read only]" : ""),
#endif /* CONFIG_FEATURE_VI_READONLY */
+ (cmd_mode ? (cmd_mode == 2 ? " [Replace]":" [Insert]") : ""),
(file_modified ? " [modified]" : ""),
cur, tot, percent);
}
#endif /* CONFIG_FEATURE_VI_OPTIMIZE_CURSOR */
}
- edit_status(); // show current file status
- show_status_line();
// write line out to terminal
{
int nic = ce-cs+1;
p = q = save_dot = msg = buf; // quiet the compiler
memset(buf, '\0', 9); // clear buf
+ show_status_line();
+
/* if this is a cursor key, skip these checks */
switch (c) {
case VI_K_UP:
dot_scroll(rows - 2, 1);
break;
case 7: // ctrl-G show current status
- edit_status();
- show_status_line();
break;
case 'h': // h- move left
case VI_K_LEFT: // cursor key Left
do_cmd(c);
} // repeat cnt
dot_left();
- edit_status(); // show current file status
- show_status_line();
break;
case 10: // Newline ^J
case 'j': // j- goto next line, same col
strncasecmp((char *) p, "wq", cnt) == 0 ||
strncasecmp((char *) p, "x", cnt) == 0) {
cnt = file_write(cfn, text, end - 1);
- file_modified = FALSE;
+ file_modified = 0;
psb("\"%s\" %dL, %dC", cfn, count_lines(text, end - 1), cnt);
if (p[0] == 'x' || p[1] == 'q') {
editing = 0;
}
} else if (strncasecmp((char *) p, "file", cnt) == 0 ) {
- edit_status(); // show current file status
- show_status_line();
+ /* no-op */; // show current file status
} else if (sscanf((char *) p, "%d", &j) > 0) {
dot = find_line(j); // go to line # j
dot_skip_over_ws();
case VI_K_INSERT: // Cursor Key Insert
dc_i:
cmd_mode = 1; // start insrting
- psb("-- Insert --");
break;
case 'J': // J- join current and next lines together
if (cmdcnt-- > 2) {
dot_end(); // move to NL
if (dot < end - 1) { // make sure not last char in text[]
*dot++ = ' '; // replace NL with space
- file_modified = TRUE;
+ file_modified++;
while (isblnk(*dot)) { // delete leading WS
dot_delete();
}
case 'R': // R- continuous Replace char
dc5:
cmd_mode = 2;
- psb("-- Replace --");
break;
case 'X': // X- delete char before dot
case 'x': // x- delete the current char
c1 = get_one_char(); // get the replacement char
if (*dot != '\n') {
*dot = c1;
- file_modified = TRUE; // has the file been modified
+ file_modified++; // has the file been modified
}
end_cmd_q(); // stop adding to q
break;
} // repeat cnt
if (islower(*dot)) {
*dot = toupper(*dot);
- file_modified = TRUE; // has the file been modified
+ file_modified++; // has the file been modified
} else if (isupper(*dot)) {
*dot = tolower(*dot);
- file_modified = TRUE; // has the file been modified
+ file_modified++; // has the file been modified
}
dot_right();
end_cmd_q(); // stop adding to q