Fix #11455 - Implement internal less pager with scr.pager=.. (#11548)

* Use full screen in r_cons_less (last line was not used before)
This commit is contained in:
radare 2018-09-17 12:15:12 +02:00 committed by GitHub
parent c05c85aa9f
commit 945e9566fb
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 44 additions and 21 deletions

View File

@ -1,4 +1,4 @@
/* radare - LGPL - Copyright 2006-2016 - pancake */
/* radare - LGPL - Copyright 2006-2018 - pancake */
#include "r_config.h"
#include "r_util.h" // r_str_hash, r_str_chop, ...

View File

@ -44,7 +44,7 @@ static void cons_stack_free(void *ptr) {
free (s->buf);
if (s->grep) {
R_FREE (s->grep->str);
I.context->grep.str = NULL;
CTX(grep.str) = NULL;
}
free (s->grep);
free (s);
@ -56,10 +56,10 @@ static RConsStack *cons_stack_dump(bool recreate) {
return NULL;
}
if (I.context->buffer) {
data->buf = I.context->buffer;
data->buf_len = I.context->buffer_len;
data->buf_size = I.context->buffer_sz;
if (CTX (buffer)) {
data->buf = CTX (buffer);
data->buf_len = CTX (buffer_len);
data->buf_size = CTX (buffer_sz);
}
data->grep = R_NEW0 (RConsGrep);
@ -109,6 +109,7 @@ static void cons_context_init(RConsContext *context) {
context->break_stack = r_stack_newf (6, break_stack_free);
context->event_interrupt = NULL;
context->event_interrupt_data = NULL;
context->pageable = true;
}
static void cons_context_deinit(RConsContext *context) {
@ -552,7 +553,7 @@ R_API void r_cons_reset_colors() {
}
R_API void r_cons_clear() {
r_cons_strcat (Color_RESET"\x1b[2J");
r_cons_strcat (Color_RESET R_CONS_CLEAR_SCREEN);
I.lines = 0;
}
@ -575,6 +576,7 @@ R_API void r_cons_reset() {
I.lines = 0;
I.lastline = I.context->buffer;
cons_grep_reset (&I.context->grep);
CTX (pageable) = true;
}
R_API const char *r_cons_get_buffer() {
@ -727,13 +729,21 @@ R_API void r_cons_flush(void) {
CTX (lastMode) = false;
}
r_cons_filter ();
if (I.is_interactive && I.fdout == 1) {
/* Use a pager if the output doesn't fit on the terminal window. */
if (I.pager && *I.pager && I.context->buffer_len > 0 && r_str_char_count (I.context->buffer, '\n') >= I.rows) {
if (CTX (pageable) && CTX (buffer) && I.pager && *I.pager && CTX (buffer_len) > 0 && r_str_char_count (CTX (buffer), '\n') >= I.rows) {
I.context->buffer[I.context->buffer_len - 1] = 0;
r_sys_cmd_str_full (I.pager, I.context->buffer, NULL, NULL, NULL);
r_cons_reset ();
if (!strcmp (I.pager, "..")) {
char *str = r_str_ndup (CTX (buffer), CTX (buffer_len));
CTX (pageable) = false;
r_cons_less_str (str, NULL);
r_cons_reset ();
free (str);
return;
} else {
r_sys_cmd_str_full (I.pager, CTX (buffer), NULL, NULL, NULL);
r_cons_reset ();
}
} else if (I.context->buffer_len > CONS_MAX_USER) {
#if COUNT_LINES
int i, lines = 0;

View File

@ -60,9 +60,13 @@ static void printpage (const char *line, int *index, RList **mla, int from, int
color_line (line + index[i], p, mla[i]);
r_strpool_ansi_chop (p, w);
r_cons_reset_colors ();
r_cons_println (p->str);
if (i + 1 == to) {
r_cons_print (p->str);
} else {
r_cons_println (p->str);
}
}
r_strpool_free(p);
r_strpool_free (p);
r_cons_flush ();
}
@ -219,7 +223,7 @@ R_API int r_cons_less_str(const char *str, const char *exitkeys) {
w = h = 0;
while (ui) {
w = r_cons_get_size (&h);
to = R_MIN (lines_count, from + h - 1);
to = R_MIN (lines_count, from + h);
if (from + 3 > lines_count) {
from = lines_count - 3;
}
@ -258,7 +262,7 @@ R_API int r_cons_less_str(const char *str, const char *exitkeys) {
break;
case ' ': from += h; break;
case 'g': from = 0; break;
case 'G': from = lines_count-1-h; break;
case 'G': from = lines_count-h; break;
case -1: // EOF
case 'q': ui = 0; break;
case '\r':

View File

@ -1642,9 +1642,13 @@ static int cb_scr_color_grep(void *user, void *data) {
static int cb_pager(void *user, void *data) {
RCore *core = (RCore *) user;
RConfigNode *node = (RConfigNode *) data;
if (!strcmp (node->value, "?")) {
eprintf ("Usage: scr.pager must be '..' for internal less, or the path to a program in $PATH");
return false;
}
/* Let cons know we have a new pager. */
core->cons->pager = node->value;
free (core->cons->pager);
core->cons->pager = strdup (node->value);
return true;
}
@ -2895,7 +2899,7 @@ R_API int r_core_config_init(RCore *core) {
n = NODECB ("scr.nkey", "flag", &cb_scrnkey);
SETDESC (n, "Select visual seek mode (affects n/N visual commands)");
SETOPTIONS (n, "fun", "hit", "flag", NULL);
SETCB ("scr.pager", "", &cb_pager, "Select pager program (when output overflows the window)");
SETCB ("scr.pager", "", &cb_pager, "System program (or '..') to use when output exceeds screen boundaries");
SETPREF ("scr.randpal", "false", "Random color palete or just get the next one from 'eco'");
SETCB ("scr.color.grep", "false", &cb_scr_color_grep, "Enable colors when using ~grep");
SETPREF ("scr.pipecolor", "false", "Enable colors when using pipes");

View File

@ -1608,6 +1608,7 @@ static int cmd_last(void *data, const char *input) {
default:
eprintf ("Usage: _ print last output\n");
}
return 0;
}
static int cmd_system(void *data, const char *input) {

View File

@ -558,7 +558,9 @@ static int cmd_eval(void *data, const char *input) {
eprintf ("Usage: er [key]\n");
}
break;
case ' ': r_config_eval (core->config, input+1); break;
case ' ':
r_config_eval (core->config, input + 1);
break;
}
return 0;
}

View File

@ -399,6 +399,7 @@ typedef struct r_cons_context_t {
int lastLength;
bool lastMode;
bool lastEnabled;
bool pageable;
} RConsContext;
typedef struct r_cons_t {
@ -500,6 +501,7 @@ typedef struct r_cons_t {
#define R_CONS_KEY_ESC 0x1b
#define R_CONS_CLEAR_LINE "\x1b[2K\r"
#define R_CONS_CLEAR_SCREEN "\x1b[2J\r"
#define Color_BLINK "\x1b[5m"
#define Color_INVERT "\x1b[7m"

View File

@ -46,7 +46,7 @@ int gdbr_check_vcont(libgdbr_t *g);
* remote target's interpreter.
* \returns 0 on success and -1 on failure
*/
int gdbr_send_qRcmd(libgdbr_t *g, const char *cmd, void (*cb_printf) (const char *, ...));
int gdbr_send_qRcmd(libgdbr_t *g, const char *cmd, PrintfCallback cb_printf);
/*!
* \brief attaches to a process

View File

@ -1186,7 +1186,7 @@ void gdbr_invalidate_reg_cache() {
reg_cache.valid = false;
}
int gdbr_send_qRcmd(libgdbr_t *g, const char *cmd, void (*cb_printf) (const char *fmt, ...)) {
int gdbr_send_qRcmd(libgdbr_t *g, const char *cmd, PrintfCallback cb_printf) {
if (!g || !cmd) {
return -1;
}