[Toybox] [PATCH] Make more(1) usable.
enh
enh at google.com
Sat Apr 4 12:00:36 PDT 2015
Yes, I know, "don't use pending". Sadly, more(1) is pretty useless
without this. It gets confused by long lines or tabs.
This patch also adds the missing prompt between multiple files.
diff --git a/toys/pending/more.c b/toys/pending/more.c
index eb48fa7..f663cdc 100644
--- a/toys/pending/more.c
+++ b/toys/pending/more.c
@@ -32,19 +32,38 @@ static void signal_handler(int sig)
_exit(sig | 128);
}
+static void show_file_header(const char *name)
+{
+ printf(":::::::::::::::::::::::\n%s\n:::::::::::::::::::::::\n", name);
+}
+
+static int await_user_response(FILE *cin, int prompt_len)
+{
+ int input_key;
+
+ while (1) {
+ fflush(NULL);
+ input_key = tolower(getc(cin));
+ printf("\r%*s\r", prompt_len, ""); // Remove previous msg
+ if (strchr(" \nrq", input_key)) {
+ return input_key;
+ }
+ prompt_len =
+ printf("(Enter:Next line Space:Next page Q:Quit R:Show the rest)");
+ }
+}
static void do_cat_operation(int fd, char *name)
{
char *buf = NULL;
- if(toys.optc > 1) printf(":::::::::::::::::::::::\n"
- "%s\n:::::::::::::::::::::::\n",name);
+ if (toys.optc > 1) show_file_header(name);
for (; (buf = get_line(fd)); free(buf)) printf("%s\n", buf);
}
void more_main()
{
- int ch, lines, input_key = 0, disp_more, more_msg_len;
- unsigned rows = 24, cols = 80;
+ int ch, input_key = 0, show_prompt, more_msg_len;
+ unsigned rows = 24, cols = 80, row = 0, col = 0;
struct stat st;
struct termios newf;
FILE *fp, *cin;
@@ -55,7 +74,8 @@ void more_main()
}
TT.cin_fd = fileno(cin);
- tcgetattr(TT.cin_fd,&TT.inf);
+ tcgetattr(TT.cin_fd, &TT.inf);
+
//Prepare terminal for input
memcpy(&newf, &TT.inf, sizeof(struct termios));
newf.c_lflag &= ~(ICANON | ECHO);
@@ -71,46 +91,48 @@ void more_main()
perror_msg("'%s'", *toys.optargs);
continue;
}
- st.st_size = disp_more = more_msg_len = lines = 0;
+ st.st_size = show_prompt = more_msg_len = col = row = 0;
fstat(fileno(fp), &st);
terminal_size(&cols, &rows);
rows--;
- if(toys.optc > 1) {
- printf(":::::::::::::::::::::::\n"
- "%s\n:::::::::::::::::::::::\n",*toys.optargs);
- rows -= 3;
+
+ if (toys.optc > 1) {
+ show_file_header(*toys.optargs);
+ row += 3;
}
while ((ch = getc(fp)) != EOF) {
- if (input_key != 'r' && disp_more) {
- more_msg_len = printf("--More-- ");
+ if (input_key != 'r' && show_prompt) {
+ more_msg_len = printf("--More--");
if (st.st_size)
more_msg_len += printf("(%d%% of %lld bytes)",
(int) (100 * ( (double) ftell(fp) / (double) st.st_size)),
(long long)st.st_size);
- fflush(NULL);
-
- while (1) {
- input_key = getc(cin);
- input_key = tolower(input_key);
- printf("\r%*s\r", more_msg_len, ""); // Remove previous msg
- if (input_key == ' ' || input_key == '\n' || input_key == 'q'
- || input_key == 'r') break;
- more_msg_len = printf("(Enter:Next line Space:Next page
Q:Quit R:Show the rest)");
- }
- more_msg_len = lines = disp_more = 0;
+
+ input_key = await_user_response(cin, more_msg_len);
if (input_key == 'q') goto stop;
+
+ more_msg_len = col = row = show_prompt = 0;
terminal_size(&cols, &rows);
rows--;
}
- if (ch == '\n')
- if (++lines >= rows || input_key == '\n') disp_more = 1;
putchar(ch);
+ if (ch == '\t') col = (col | 0x7) + 1; else col++;
+ if (col == cols) putchar(ch = '\n');
+ if (ch == '\n') {
+ col = 0;
+ if (++row >= rows || input_key == '\n') show_prompt = 1;
+ }
}
fclose(fp);
- fflush(NULL);
- } while (*toys.optargs && *++toys.optargs);
+
+ if (*toys.optargs && *++toys.optargs) {
+ more_msg_len = printf("--More--(Next file: %s)", *toys.optargs);
+ input_key = await_user_response(cin, more_msg_len);
+ if (input_key == 'q') goto stop;
+ }
+ } while (*toys.optargs);
stop:
tcsetattr(TT.cin_fd, TCSANOW, &TT.inf);
1428174036.0
More information about the Toybox
mailing list