pager history buffer: add config option, keep buffer on resize
This commit is contained in:
parent
d0104660c8
commit
e08238d5a0
@ -323,6 +323,13 @@ def scrollback_lines(x):
|
||||
return x
|
||||
|
||||
|
||||
def size_mb(x):
|
||||
x = int(x)
|
||||
if x < 0 or x > 2 ** 12 - 1:
|
||||
raise ValueError('Size {} is in MB (positive & <4GB)'.format(x))
|
||||
return x
|
||||
|
||||
|
||||
o('scrollback_lines', 2000, option_type=scrollback_lines, long_text=_('''
|
||||
Number of lines of history to keep in memory for scrolling back. Memory is allocated
|
||||
on demand. Negative numbers are (effectively) infinite scrollback. Note that using
|
||||
@ -336,6 +343,13 @@ use can handle ANSI escape sequences for colors and text formatting.
|
||||
INPUT_LINE_NUMBER in the command line above will be replaced by an integer
|
||||
representing which line should be at the top of the screen.'''))
|
||||
|
||||
o('scrollback_pager_history_size', 10, option_type=size_mb, long_text=_('''
|
||||
Separate scrollback history size, used only for pager, in MB.
|
||||
This separate buffer is not available for interactive scrolling but will be
|
||||
prepended to the pager program when viewing scrollback.
|
||||
The current implementation stores one character in 4 bytes, so approximatively
|
||||
2500 lines per megabyte at 100 chars per line'''))
|
||||
|
||||
o('wheel_scroll_multiplier', 5.0, long_text=_('''
|
||||
Modify the amount scrolled by the mouse wheel. Note this is only used for low
|
||||
precision scrolling devices, not for high precision scrolling on platforms such
|
||||
|
||||
@ -185,7 +185,7 @@ typedef struct {
|
||||
|
||||
index_type xnum, ynum, num_segments;
|
||||
HistoryBufSegment *segments;
|
||||
PagerHistoryBuf pagerhist;
|
||||
PagerHistoryBuf *pagerhist;
|
||||
Line *line;
|
||||
index_type start_of_data, count;
|
||||
} HistoryBuf;
|
||||
@ -262,7 +262,7 @@ const char* base64_decode(const uint32_t *src, size_t src_sz, uint8_t *dest, siz
|
||||
Line* alloc_line();
|
||||
Cursor* alloc_cursor();
|
||||
LineBuf* alloc_linebuf(unsigned int, unsigned int);
|
||||
HistoryBuf* alloc_historybuf(unsigned int, unsigned int);
|
||||
HistoryBuf* alloc_historybuf(unsigned int, unsigned int, unsigned int);
|
||||
ColorProfile* alloc_color_profile();
|
||||
PyObject* create_256_color_table();
|
||||
PyObject* parse_bytes_dump(PyObject UNUSED *, PyObject *);
|
||||
|
||||
@ -54,12 +54,24 @@ attrptr(HistoryBuf *self, index_type y) {
|
||||
seg_ptr(line_attrs, 1);
|
||||
}
|
||||
|
||||
static inline PagerHistoryBuf*
|
||||
alloc_pagerhist(unsigned int pagerhist_sz) {
|
||||
PagerHistoryBuf *ph;
|
||||
if (!pagerhist_sz) return NULL;
|
||||
pagerhist_sz *= 1024*1024;
|
||||
ph = PyMem_Calloc(1, sizeof(PagerHistoryBuf));
|
||||
ph->bufsize = pagerhist_sz / sizeof(Py_UCS4);
|
||||
ph->buffer = PyMem_RawMalloc(pagerhist_sz);
|
||||
if (!ph->buffer) { PyMem_Free(ph); return NULL; }
|
||||
return ph;
|
||||
}
|
||||
|
||||
static PyObject *
|
||||
new(PyTypeObject *type, PyObject *args, PyObject UNUSED *kwds) {
|
||||
HistoryBuf *self;
|
||||
unsigned int xnum = 1, ynum = 1;
|
||||
unsigned int xnum = 1, ynum = 1, pagerhist_sz = 0;
|
||||
|
||||
if (!PyArg_ParseTuple(args, "II", &ynum, &xnum)) return NULL;
|
||||
if (!PyArg_ParseTuple(args, "II|I", &ynum, &xnum, &pagerhist_sz)) return NULL;
|
||||
|
||||
if (xnum == 0 || ynum == 0) {
|
||||
PyErr_SetString(PyExc_ValueError, "Cannot create an empty history buffer");
|
||||
@ -74,10 +86,7 @@ new(PyTypeObject *type, PyObject *args, PyObject UNUSED *kwds) {
|
||||
add_segment(self);
|
||||
self->line = alloc_line();
|
||||
self->line->xnum = xnum;
|
||||
self->pagerhist.start = self->pagerhist.end = self->pagerhist.bufend = 0;
|
||||
self->pagerhist.buffer = PyMem_RawMalloc(1024*1024*10);
|
||||
self->pagerhist.bufsize = 1024*1024*10 / sizeof(Py_UCS4);
|
||||
// abort if allocation failed?
|
||||
self->pagerhist = alloc_pagerhist(pagerhist_sz);
|
||||
}
|
||||
|
||||
return (PyObject*)self;
|
||||
@ -92,7 +101,8 @@ dealloc(HistoryBuf* self) {
|
||||
PyMem_Free(self->segments[i].line_attrs);
|
||||
}
|
||||
PyMem_Free(self->segments);
|
||||
PyMem_Free(self->pagerhist.buffer);
|
||||
if (self->pagerhist) PyMem_Free(self->pagerhist->buffer);
|
||||
PyMem_Free(self->pagerhist);
|
||||
Py_TYPE(self)->tp_free((PyObject*)self);
|
||||
}
|
||||
|
||||
@ -139,8 +149,8 @@ historybuf_clear(HistoryBuf *self) {
|
||||
|
||||
static inline void
|
||||
pagerhist_push(HistoryBuf *self) {
|
||||
PagerHistoryBuf *ph = &self->pagerhist;
|
||||
if (!ph->buffer) return;
|
||||
PagerHistoryBuf *ph = self->pagerhist;
|
||||
if (!ph) return;
|
||||
Line l = {.xnum=self->xnum};
|
||||
init_line(self, self->start_of_data, &l);
|
||||
if (ph->start != ph->end && !l.continued) {
|
||||
@ -241,10 +251,10 @@ get_line(HistoryBuf *self, index_type y, Line *l) { init_line(self, index_of(sel
|
||||
|
||||
static PyObject *
|
||||
pagerhist_as_text(HistoryBuf *self, PyObject *callback) {
|
||||
PagerHistoryBuf *ph = &self->pagerhist;
|
||||
PagerHistoryBuf *ph = self->pagerhist;
|
||||
PyObject *ret = NULL, *t = NULL;
|
||||
Py_UCS4 *buf = NULL;
|
||||
if (!ph->buffer) Py_RETURN_NONE;
|
||||
if (!ph) Py_RETURN_NONE;
|
||||
|
||||
index_type num = (ph->bufend ? ph->bufend : ph->end) - ph->start;
|
||||
buf = ph->buffer + ph->start;
|
||||
@ -340,8 +350,8 @@ PyTypeObject HistoryBuf_Type = {
|
||||
|
||||
INIT_TYPE(HistoryBuf)
|
||||
|
||||
HistoryBuf *alloc_historybuf(unsigned int lines, unsigned int columns) {
|
||||
return (HistoryBuf*)new(&HistoryBuf_Type, Py_BuildValue("II", lines, columns), NULL);
|
||||
HistoryBuf *alloc_historybuf(unsigned int lines, unsigned int columns, unsigned int pagerhist_sz) {
|
||||
return (HistoryBuf*)new(&HistoryBuf_Type, Py_BuildValue("III", lines, columns, pagerhist_sz), NULL);
|
||||
}
|
||||
// }}}
|
||||
|
||||
|
||||
@ -107,7 +107,7 @@ new(PyTypeObject *type, PyObject *args, PyObject UNUSED *kwds) {
|
||||
self->color_profile = alloc_color_profile();
|
||||
self->main_linebuf = alloc_linebuf(lines, columns); self->alt_linebuf = alloc_linebuf(lines, columns);
|
||||
self->linebuf = self->main_linebuf;
|
||||
self->historybuf = alloc_historybuf(MAX(scrollback, lines), columns);
|
||||
self->historybuf = alloc_historybuf(MAX(scrollback, lines), columns, OPT(scrollback_pager_history_size));
|
||||
self->main_grman = grman_alloc();
|
||||
self->alt_grman = grman_alloc();
|
||||
self->grman = self->main_grman;
|
||||
@ -165,8 +165,9 @@ screen_dirty_sprite_positions(Screen *self) {
|
||||
|
||||
static inline HistoryBuf*
|
||||
realloc_hb(HistoryBuf *old, unsigned int lines, unsigned int columns) {
|
||||
HistoryBuf *ans = alloc_historybuf(lines, columns);
|
||||
HistoryBuf *ans = alloc_historybuf(lines, columns, 0);
|
||||
if (ans == NULL) { PyErr_NoMemory(); return NULL; }
|
||||
ans->pagerhist = old->pagerhist; old->pagerhist = NULL;
|
||||
historybuf_rewrap(old, ans);
|
||||
return ans;
|
||||
}
|
||||
|
||||
@ -367,6 +367,7 @@ PYWRAP1(set_options) {
|
||||
S(dynamic_background_opacity, PyObject_IsTrue);
|
||||
S(inactive_text_alpha, PyFloat_AsDouble);
|
||||
S(window_padding_width, PyFloat_AsDouble);
|
||||
S(scrollback_pager_history_size, PyLong_AsLong);
|
||||
S(cursor_shape, PyLong_AsLong);
|
||||
S(url_style, PyLong_AsUnsignedLong);
|
||||
S(tab_bar_edge, PyLong_AsLong);
|
||||
|
||||
@ -19,6 +19,7 @@ typedef struct {
|
||||
unsigned int open_url_modifiers;
|
||||
unsigned int rectangle_select_modifiers;
|
||||
unsigned int url_style;
|
||||
unsigned int scrollback_pager_history_size;
|
||||
char_type select_by_word_characters[256]; size_t select_by_word_characters_count;
|
||||
color_type url_color, background, active_border_color, inactive_border_color, bell_border_color;
|
||||
double repaint_delay, input_delay;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user