Blame
Date:
Thu May 5 11:20:46 2022 UTC
Message:
rate-limit the update of the download pane
0001
2021-03-02
op
/*
0002
2021-03-02
op
* Copyright (c) 2021 Omar Polo <op@omarpolo.com>
0003
2021-03-02
op
*
0004
2021-03-02
op
* Permission to use, copy, modify, and distribute this software for any
0005
2021-03-02
op
* purpose with or without fee is hereby granted, provided that the above
0006
2021-03-02
op
* copyright notice and this permission notice appear in all copies.
0007
2021-03-02
op
*
0008
2021-03-02
op
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
0009
2021-03-02
op
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
0010
2021-03-02
op
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
0011
2021-03-02
op
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
0012
2021-03-02
op
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
0013
2021-03-02
op
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
0014
2021-03-02
op
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
0015
2021-03-02
op
*/
0016
2021-03-02
op
0017
2021-03-06
op
/*
0018
2021-03-06
op
* Ncurses UI for telescope.
0019
2021-03-06
op
*
0020
2021-03-06
op
* Text scrolling
0021
2021-03-06
op
* ==============
0022
2021-03-06
op
*
0023
2021-03-06
op
* ncurses allows you to scroll a window, but when a line goes out of
0024
2021-03-06
op
* the visible area it's forgotten. We keep a list of formatted lines
0025
2021-03-06
op
* (``visual lines'') that we know fits in the window, and draw them.
0026
2021-03-06
op
*
0027
2021-03-06
op
* This means that on every resize we have to clear our list of lines
0028
2021-03-06
op
* and re-render everything. A clever approach would be to do this
0029
2021-04-24
op
* ``on-demand'', but it's still missing.
0030
2021-03-06
op
*
0031
2021-03-06
op
*/
0032
2021-07-21
op
0033
2021-07-21
op
#include "compat.h"
0034
2021-03-06
op
0035
2021-04-01
op
#include <assert.h>
0036
2021-03-02
op
#include <curses.h>
0037
2021-03-02
op
#include <locale.h>
0038
2021-03-02
op
#include <signal.h>
0039
2021-03-07
op
#include <stdarg.h>
0040
2021-03-02
op
#include <stdlib.h>
0041
2021-03-02
op
#include <string.h>
0042
2021-03-09
op
#include <unistd.h>
0043
2021-03-02
op
0044
2021-07-13
op
#include "defaults.h"
0045
2021-07-12
op
#include "minibuffer.h"
0046
2021-08-14
op
#include "session.h"
0047
2021-07-12
op
#include "telescope.h"
0048
2021-07-12
op
#include "ui.h"
0049
2021-07-12
op
#include "utf8.h"
0050
2021-07-12
op
0051
2021-03-02
op
static struct event stdioev, winchev;
0052
2021-03-02
op
0053
2022-01-18
op
static void set_scroll_position(struct tab *, size_t, size_t);
0054
2022-01-18
op
0055
2021-07-01
op
static void restore_curs_x(struct buffer *);
0056
2021-03-09
op
0057
2021-03-21
op
static int readkey(void);
0058
2021-03-02
op
static void dispatch_stdio(int, short, void*);
0059
2021-03-02
op
static void handle_resize(int, short, void*);
0060
2021-05-17
op
static void handle_resize_nodelay(int, short, void*);
0061
2022-05-05
op
static void handle_download_refresh(int, short, void *);
0062
2021-07-15
op
static void rearrange_windows(void);
0063
2021-07-16
op
static void line_prefix_and_text(struct vline *, char *, size_t, const char **, const char **);
0064
2021-06-21
op
static void print_vline(int, int, WINDOW*, struct vline*);
0065
2021-03-08
op
static void redraw_tabline(void);
0066
2022-01-10
op
static void redraw_window(WINDOW *, int, int, int, int, struct buffer *);
0067
2021-11-05
op
static void redraw_download(void);
0068
2021-04-01
op
static void redraw_help(void);
0069
2021-03-11
op
static void redraw_body(struct tab*);
0070
2021-03-08
op
static void redraw_modeline(struct tab*);
0071
2021-07-12
op
static void redraw_minibuffer(void);
0072
2021-07-12
op
static void do_redraw_echoarea(void);
0073
2021-07-12
op
static void do_redraw_minibuffer(void);
0074
2021-07-14
op
static void do_redraw_minibuffer_compl(void);
0075
2021-07-12
op
static void place_cursor(int);
0076
2021-03-02
op
static void redraw_tab(struct tab*);
0077
2021-03-08
op
static void update_loading_anim(int, short, void*);
0078
2021-03-08
op
static void stop_loading_anim(struct tab*);
0079
2021-07-17
op
0080
2021-07-15
op
static int should_rearrange_windows;
0081
2021-08-18
op
static int show_tab_bar;
0082
2021-07-13
op
static int too_small;
0083
2021-06-19
op
static int x_offset;
0084
2021-06-19
op
0085
2021-07-17
op
struct thiskey thiskey;
0086
2021-07-17
op
struct tab *current_tab;
0087
2021-03-09
op
0088
2021-05-12
op
static struct event resizeev;
0089
2021-05-12
op
static struct timeval resize_timer = { 0, 250000 };
0090
2021-05-12
op
0091
2022-05-05
op
static struct event download_refreshev;
0092
2022-05-05
op
static struct timeval download_refresh_timer = { 0, 250000 };
0093
2022-05-05
op
0094
2021-07-13
op
static WINDOW *tabline, *body, *modeline, *echoarea, *minibuffer;
0095
2021-03-06
op
0096
2021-06-20
op
int body_lines, body_cols;
0097
2021-06-20
op
0098
2021-04-01
op
static WINDOW *help;
0099
2021-07-21
op
/* not static so we can see them from help.c */
0100
2021-07-21
op
struct buffer helpwin;
0101
2021-07-21
op
int help_lines, help_cols;
0102
2021-04-01
op
0103
2021-11-05
op
static WINDOW *download;
0104
2021-11-05
op
/* not static so we can see them from download.c */
0105
2021-11-05
op
struct buffer downloadwin;
0106
2021-11-05
op
int download_lines;
0107
2021-11-27
op
int download_cols;
0108
2021-11-05
op
0109
2021-04-01
op
static int side_window;
0110
2021-07-21
op
static int in_side_window;
0111
2021-04-01
op
0112
2021-03-08
op
static struct timeval loadingev_timer = { 0, 250000 };
0113
2021-03-06
op
0114
2021-03-10
op
static char keybuf[64];
0115
2021-03-09
op
0116
2021-08-12
op
/* XXX: don't forget to init these in main() */
0117
2021-03-09
op
struct kmap global_map,
0118
2021-03-10
op
minibuffer_map,
0119
2021-03-09
op
*current_map,
0120
2021-03-09
op
*base_map;
0121
2021-03-09
op
0122
2021-06-19
op
static inline void
0123
2021-06-21
op
update_x_offset(void)
0124
2021-06-19
op
{
0125
2021-06-19
op
if (olivetti_mode && fill_column < body_cols)
0126
2021-06-19
op
x_offset = (body_cols - fill_column)/2;
0127
2021-06-19
op
else
0128
2021-06-19
op
x_offset = 0;
0129
2021-06-19
op
}
0130
2021-03-14
op
0131
2022-01-18
op
static void
0132
2022-01-18
op
set_scroll_position(struct tab *tab, size_t top, size_t cur)
0133
2022-01-18
op
{
0134
2022-01-18
op
struct line *last;
0135
2022-01-18
op
struct vline *vl;
0136
2022-01-18
op
size_t i = 0;
0137
2022-01-21
op
int topfound = 0;
0138
2022-01-18
op
0139
2022-01-18
op
last = TAILQ_FIRST(&tab->buffer.page.head);
0140
2022-01-18
op
TAILQ_FOREACH(vl, &tab->buffer.head, vlines) {
0141
2022-01-18
op
if (last != vl->parent) {
0142
2022-01-18
op
last = vl->parent;
0143
2022-01-18
op
i++;
0144
2022-01-18
op
}
0145
2022-01-18
op
0146
2022-01-18
op
if (!topfound && i == top) {
0147
2022-01-18
op
topfound = 1;
0148
2022-01-18
op
tab->buffer.top_line = vl;
0149
2022-01-18
op
}
0150
2022-01-18
op
0151
2022-01-21
op
if (i == cur) {
0152
2022-01-18
op
tab->buffer.current_line = vl;
0153
2022-01-18
op
return;
0154
2022-01-18
op
}
0155
2022-01-18
op
}
0156
2022-01-18
op
0157
2022-01-21
op
if (!topfound)
0158
2022-01-18
op
tab->buffer.top_line = TAILQ_FIRST(&tab->buffer.head);
0159
2022-01-21
op
0160
2022-01-21
op
tab->buffer.current_line = tab->buffer.top_line;
0161
2022-01-18
op
}
0162
2022-01-18
op
0163
2021-06-23
op
void
0164
2022-01-18
op
get_scroll_position(struct tab *tab, size_t *top, size_t *cur)
0165
2022-01-18
op
{
0166
2022-01-18
op
struct line *l;
0167
2022-01-18
op
int topfound = 0;
0168
2022-01-18
op
0169
2022-01-18
op
*top = 0;
0170
2022-01-18
op
*cur = 0;
0171
2022-01-18
op
0172
2022-01-18
op
if (tab->buffer.top_line == NULL ||
0173
2022-01-18
op
tab->buffer.current_line == NULL)
0174
2022-01-18
op
return;
0175
2022-01-18
op
0176
2022-01-18
op
TAILQ_FOREACH(l, &tab->buffer.page.head, lines) {
0177
2022-01-18
op
if (tab->buffer.top_line->parent == l)
0178
2022-01-18
op
topfound = 1;
0179
2022-01-18
op
if (tab->buffer.current_line->parent == l)
0180
2022-01-18
op
return;
0181
2022-01-18
op
0182
2022-01-18
op
if (!topfound)
0183
2022-01-18
op
(*top)++;
0184
2022-01-18
op
(*cur)++;
0185
2022-01-18
op
}
0186
2022-01-18
op
}
0187
2022-01-18
op
0188
2022-01-18
op
void
0189
2021-06-23
op
save_excursion(struct excursion *place, struct buffer *buffer)
0190
2021-06-23
op
{
0191
2021-06-23
op
place->curs_x = buffer->curs_x;
0192
2021-06-23
op
place->curs_y = buffer->curs_y;
0193
2021-06-23
op
place->line_off = buffer->line_off;
0194
2021-07-18
op
place->top_line = buffer->top_line;
0195
2021-06-23
op
place->current_line = buffer->current_line;
0196
2021-06-23
op
place->cpoff = buffer->cpoff;
0197
2021-06-23
op
}
0198
2021-06-23
op
0199
2021-06-23
op
void
0200
2021-06-23
op
restore_excursion(struct excursion *place, struct buffer *buffer)
0201
2021-06-23
op
{
0202
2021-06-23
op
buffer->curs_x = place->curs_x;
0203
2021-06-23
op
buffer->curs_y = place->curs_y;
0204
2021-06-23
op
buffer->line_off = place->line_off;
0205
2021-07-18
op
buffer->top_line = place->top_line;
0206
2021-06-23
op
buffer->current_line = place->current_line;
0207
2021-06-23
op
buffer->cpoff = place->cpoff;
0208
2021-03-06
op
}
0209
2021-03-06
op
0210
2021-07-01
op
static void
0211
2021-07-01
op
restore_curs_x(struct buffer *buffer)
0212
2021-03-06
op
{
0213
2021-03-16
op
struct vline *vl;
0214
2021-07-18
op
const char *prfx, *text;
0215
2021-03-16
op
0216
2021-05-17
op
vl = buffer->current_line;
0217
2021-03-16
op
if (vl == NULL || vl->line == NULL)
0218
2021-05-17
op
buffer->curs_x = buffer->cpoff = 0;
0219
2021-07-18
op
else if (vl->parent->data != NULL) {
0220
2021-07-18
op
text = vl->parent->data;
0221
2021-07-18
op
buffer->curs_x = utf8_snwidth(text + 1, buffer->cpoff) + 1;
0222
2021-07-18
op
} else
0223
2021-05-17
op
buffer->curs_x = utf8_snwidth(vl->line, buffer->cpoff);
0224
2021-03-16
op
0225
2021-11-05
op
/* small hack: don't olivetti-mode the download pane */
0226
2021-11-05
op
if (buffer != &downloadwin)
0227
2021-11-05
op
buffer->curs_x += x_offset;
0228
2021-06-19
op
0229
2021-07-17
op
if (vl == NULL)
0230
2021-07-17
op
return;
0231
2021-07-17
op
0232
2021-07-17
op
if (vl->parent->data != NULL)
0233
2021-08-14
op
buffer->curs_x += utf8_swidth_between(vl->parent->line,
0234
2021-08-14
op
vl->parent->data);
0235
2021-07-17
op
else {
0236
2021-03-16
op
prfx = line_prefixes[vl->parent->type].prfx1;
0237
2021-05-17
op
buffer->curs_x += utf8_swidth(prfx);
0238
2021-03-22
op
}
0239
2021-03-09
op
}
0240
2021-03-09
op
0241
2021-07-08
op
void
0242
2021-03-26
op
global_key_unbound(void)
0243
2021-03-26
op
{
0244
2021-03-26
op
message("%s is undefined", keybuf);
0245
2021-03-26
op
}
0246
2021-03-26
op
0247
2021-06-20
op
struct buffer *
0248
2021-05-17
op
current_buffer(void)
0249
2021-03-22
op
{
0250
2021-03-22
op
if (in_minibuffer)
0251
2021-05-17
op
return &ministate.buffer;
0252
2021-11-05
op
if (in_side_window & SIDE_WINDOW_LEFT)
0253
2021-07-21
op
return &helpwin;
0254
2021-11-05
op
if (in_side_window & SIDE_WINDOW_BOTTOM)
0255
2021-11-05
op
return &downloadwin;
0256
2021-07-17
op
return &current_tab->buffer;
0257
2021-03-22
op
}
0258
2021-03-22
op
0259
2021-03-21
op
static int
0260
2021-03-21
op
readkey(void)
0261
2021-03-02
op
{
0262
2021-03-21
op
uint32_t state = 0;
0263
2021-03-08
op
0264
2021-03-21
op
if ((thiskey.key = wgetch(body)) == ERR)
0265
2021-03-21
op
return 0;
0266
2021-03-02
op
0267
2021-12-01
op
thiskey.meta = thiskey.key == '\e';
0268
2021-03-21
op
if (thiskey.meta) {
0269
2021-03-09
op
thiskey.key = wgetch(body);
0270
2021-12-01
op
if (thiskey.key == ERR || thiskey.key == '\e') {
0271
2021-03-11
op
thiskey.meta = 0;
0272
2021-12-01
op
thiskey.key = '\e';
0273
2021-03-11
op
}
0274
2021-03-21
op
}
0275
2021-03-21
op
0276
2021-03-21
op
thiskey.cp = 0;
0277
2021-08-14
op
0278
2021-08-14
op
if ((unsigned int)thiskey.key >= UINT8_MAX)
0279
2021-08-14
op
return 1;
0280
2021-08-14
op
0281
2021-08-14
op
while (1) {
0282
2021-08-14
op
if (!utf8_decode(&state, &thiskey.cp, (uint8_t)thiskey.key))
0283
2021-08-14
op
break;
0284
2021-08-14
op
if ((thiskey.key = wgetch(body)) == ERR) {
0285
2021-08-14
op
message("Error decoding user input");
0286
2021-08-14
op
return 0;
0287
2021-03-21
op
}
0288
2021-03-21
op
}
0289
2021-03-08
op
0290
2021-03-21
op
return 1;
0291
2021-03-21
op
}
0292
2021-03-21
op
0293
2021-03-21
op
static void
0294
2021-03-21
op
dispatch_stdio(int fd, short ev, void *d)
0295
2021-03-21
op
{
0296
2021-11-05
op
int lk;
0297
2021-03-21
op
const char *keyname;
0298
2021-03-21
op
char tmp[5] = {0};
0299
2021-03-21
op
0300
2021-07-13
op
/* TODO: schedule a redraw? */
0301
2021-07-13
op
if (too_small)
0302
2021-07-13
op
return;
0303
2021-07-13
op
0304
2021-03-21
op
if (!readkey())
0305
2021-03-21
op
return;
0306
2021-03-21
op
0307
2021-03-10
op
if (keybuf[0] != '\0')
0308
2021-03-10
op
strlcat(keybuf, " ", sizeof(keybuf));
0309
2021-03-10
op
if (thiskey.meta)
0310
2021-03-10
op
strlcat(keybuf, "M-", sizeof(keybuf));
0311
2021-03-21
op
if (thiskey.cp != 0) {
0312
2021-03-21
op
utf8_encode(thiskey.cp, tmp);
0313
2021-03-10
op
strlcat(keybuf, tmp, sizeof(keybuf));
0314
2021-07-13
op
} else if ((keyname = unkbd(thiskey.key)) != NULL) {
0315
2021-07-13
op
strlcat(keybuf, keyname, sizeof(keybuf));
0316
2021-03-21
op
} else {
0317
2021-07-13
op
tmp[0] = thiskey.key;
0318
2021-07-13
op
strlcat(keybuf, tmp, sizeof(keybuf));
0319
2021-03-10
op
}
0320
2021-03-10
op
0321
2021-11-05
op
lk = lookup_key(&current_map, &thiskey, current_buffer());
0322
2021-11-05
op
if (lk == LK_UNBOUND) {
0323
2021-11-05
op
if (current_map->unhandled_input != NULL)
0324
2021-11-05
op
current_map->unhandled_input();
0325
2021-11-05
op
else
0326
2021-11-05
op
global_key_unbound();
0327
2021-03-02
op
}
0328
2021-11-05
op
if (lk != LK_ADVANCED_MAP) {
0329
2021-11-05
op
current_map = base_map;
0330
2021-11-05
op
strlcpy(keybuf, "", sizeof(keybuf));
0331
2021-11-05
op
}
0332
2021-03-06
op
0333
2021-11-05
op
if (side_window & SIDE_WINDOW_LEFT)
0334
2021-04-01
op
recompute_help();
0335
2021-04-01
op
0336
2021-07-15
op
if (should_rearrange_windows)
0337
2021-07-15
op
rearrange_windows();
0338
2021-07-17
op
redraw_tab(current_tab);
0339
2021-03-06
op
}
0340
2021-03-06
op
0341
2021-03-06
op
static void
0342
2021-03-02
op
handle_resize(int sig, short ev, void *d)
0343
2021-05-12
op
{
0344
2021-05-12
op
if (event_pending(&resizeev, EV_TIMEOUT, NULL)) {
0345
2021-05-12
op
event_del(&resizeev);
0346
2021-05-12
op
}
0347
2021-05-17
op
evtimer_set(&resizeev, handle_resize_nodelay, NULL);
0348
2021-05-12
op
evtimer_add(&resizeev, &resize_timer);
0349
2021-05-12
op
}
0350
2021-05-12
op
0351
2021-05-12
op
static void
0352
2021-05-17
op
handle_resize_nodelay(int s, short ev, void *d)
0353
2021-03-02
op
{
0354
2021-03-02
op
endwin();
0355
2021-03-02
op
refresh();
0356
2021-03-02
op
clear();
0357
2021-07-15
op
0358
2021-07-15
op
rearrange_windows();
0359
2021-07-15
op
}
0360
2021-07-15
op
0361
2022-05-05
op
static void
0362
2022-05-05
op
handle_download_refresh(int s, short v, void *d)
0363
2022-05-05
op
{
0364
2022-05-05
op
if (side_window & SIDE_WINDOW_BOTTOM) {
0365
2022-05-05
op
recompute_downloads();
0366
2022-05-05
op
redraw_tab(current_tab);
0367
2022-05-05
op
}
0368
2022-05-05
op
}
0369
2022-05-05
op
0370
2021-08-18
op
static inline int
0371
2021-08-18
op
should_show_tab_bar(void)
0372
2021-08-18
op
{
0373
2021-08-18
op
if (tab_bar_show == -1)
0374
2021-08-18
op
return 0;
0375
2021-08-18
op
if (tab_bar_show == 0)
0376
2021-08-18
op
return 1;
0377
2021-08-18
op
0378
2021-08-18
op
return TAILQ_NEXT(TAILQ_FIRST(&tabshead), tabs) != NULL;
0379
2021-08-18
op
}
0380
2021-08-18
op
0381
2021-07-15
op
static void
0382
2021-07-15
op
rearrange_windows(void)
0383
2021-07-15
op
{
0384
2021-07-15
op
int lines;
0385
2021-11-05
op
int minibuffer_lines;
0386
2021-03-02
op
0387
2021-07-15
op
should_rearrange_windows = 0;
0388
2021-08-18
op
show_tab_bar = should_show_tab_bar();
0389
2021-07-15
op
0390
2021-07-13
op
lines = LINES;
0391
2021-07-13
op
0392
2021-11-05
op
/* 3 lines for the ui and 12 for the */
0393
2021-07-13
op
if ((too_small = lines < 15)) {
0394
2021-07-13
op
erase();
0395
2021-07-13
op
printw("Window too small.");
0396
2021-07-13
op
refresh();
0397
2021-07-13
op
return;
0398
2021-07-13
op
}
0399
2021-07-13
op
0400
2021-03-06
op
/* move and resize the windows, in reverse order! */
0401
2021-03-06
op
0402
2021-07-14
op
if (in_minibuffer == MB_COMPREAD) {
0403
2021-11-05
op
minibuffer_lines = MIN(10, lines/2);
0404
2021-11-05
op
mvwin(minibuffer, lines - minibuffer_lines, 0);
0405
2021-11-05
op
wresize(minibuffer, minibuffer_lines, COLS);
0406
2021-11-05
op
lines -= minibuffer_lines;
0407
2021-07-14
op
0408
2021-07-14
op
wrap_page(&ministate.compl.buffer, COLS);
0409
2021-07-14
op
}
0410
2021-07-14
op
0411
2021-07-13
op
mvwin(echoarea, --lines, 0);
0412
2021-07-10
op
wresize(echoarea, 1, COLS);
0413
2021-03-06
op
0414
2021-07-13
op
mvwin(modeline, --lines, 0);
0415
2021-03-06
op
wresize(modeline, 1, COLS);
0416
2021-03-06
op
0417
2021-11-05
op
if (side_window & SIDE_WINDOW_BOTTOM) {
0418
2021-11-05
op
download_lines = MIN(5, lines/2);
0419
2021-11-27
op
download_cols = COLS;
0420
2021-11-05
op
mvwin(download, lines - download_lines, 0);
0421
2021-11-27
op
wresize(download, download_lines, download_cols);
0422
2021-11-05
op
lines -= download_lines;
0423
2021-11-05
op
0424
2021-11-27
op
wrap_page(&downloadwin, download_cols);
0425
2021-11-05
op
}
0426
2021-11-05
op
0427
2021-08-18
op
body_lines = show_tab_bar ? --lines : lines;
0428
2021-03-06
op
body_cols = COLS;
0429
2021-04-01
op
0430
2021-08-18
op
/*
0431
2021-08-18
op
* Here we make the assumption that show_tab_bar is either 0
0432
2021-08-18
op
* or 1, and reuse that as argument to mvwin.
0433
2021-08-18
op
*/
0434
2021-11-05
op
if (side_window & SIDE_WINDOW_LEFT) {
0435
2021-04-01
op
help_cols = 0.3 * COLS;
0436
2021-07-13
op
help_lines = lines;
0437
2021-08-18
op
mvwin(help, show_tab_bar, 0);
0438
2021-04-01
op
wresize(help, help_lines, help_cols);
0439
2021-03-06
op
0440
2021-04-01
op
wrap_page(&helpwin, help_cols);
0441
2021-04-01
op
0442
2021-04-01
op
body_cols = COLS - help_cols - 1;
0443
2021-08-18
op
mvwin(body, show_tab_bar, help_cols);
0444
2021-04-01
op
} else
0445
2021-08-18
op
mvwin(body, show_tab_bar, 0);
0446
2021-04-01
op
0447
2021-06-19
op
update_x_offset();
0448
2021-04-01
op
wresize(body, body_lines, body_cols);
0449
2021-04-01
op
0450
2021-08-18
op
if (show_tab_bar)
0451
2021-08-18
op
wresize(tabline, 1, COLS);
0452
2021-03-06
op
0453
2021-07-17
op
wrap_page(&current_tab->buffer, body_cols);
0454
2021-07-17
op
redraw_tab(current_tab);
0455
2021-03-02
op
}
0456
2021-06-29
op
0457
2021-07-16
op
static void
0458
2021-07-16
op
line_prefix_and_text(struct vline *vl, char *buf, size_t len,
0459
2021-07-16
op
const char **prfx_ret, const char **text_ret)
0460
2021-07-16
op
{
0461
2021-07-16
op
int type, i, cont, width;
0462
2021-07-16
op
char *space, *t;
0463
2021-07-16
op
0464
2021-07-16
op
if ((*text_ret = vl->line) == NULL)
0465
2021-07-16
op
*text_ret = "";
0466
2021-07-16
op
0467
2021-07-16
op
cont = vl->flags & L_CONTINUATION;
0468
2021-07-16
op
type = vl->parent->type;
0469
2021-07-16
op
if (!cont)
0470
2021-07-16
op
*prfx_ret = line_prefixes[type].prfx1;
0471
2021-07-16
op
else
0472
2021-07-16
op
*prfx_ret = line_prefixes[type].prfx2;
0473
2021-07-16
op
0474
2021-07-16
op
space = vl->parent->data;
0475
2021-07-16
op
if (!emojify_link || type != LINE_LINK || space == NULL)
0476
2021-07-16
op
return;
0477
2021-03-02
op
0478
2021-07-16
op
if (cont) {
0479
2021-07-16
op
memset(buf, 0, len);
0480
2021-07-16
op
width = utf8_swidth_between(vl->parent->line, space);
0481
2021-07-16
op
for (i = 0; i < width + 1; ++i)
0482
2021-07-16
op
strlcat(buf, " ", len);
0483
2021-07-16
op
} else {
0484
2021-07-16
op
strlcpy(buf, *text_ret, len);
0485
2021-07-16
op
if ((t = strchr(buf, ' ')) != NULL)
0486
2021-07-16
op
*t = '\0';
0487
2021-07-16
op
strlcat(buf, " ", len);
0488
2021-07-16
op
0489
2021-07-16
op
/* skip the emoji */
0490
2021-08-26
op
*text_ret += (space - vl->parent->line) + 1;
0491
2021-07-16
op
}
0492
2021-07-16
op
0493
2021-07-16
op
*prfx_ret = buf;
0494
2021-07-16
op
}
0495
2021-07-18
op
0496
2021-07-18
op
static inline void
0497
2021-07-18
op
print_vline_descr(int width, WINDOW *window, struct vline *vl)
0498
2021-07-18
op
{
0499
2021-07-18
op
int x, y, goal;
0500
2021-07-18
op
0501
2021-11-05
op
switch (vl->parent->type) {
0502
2021-11-05
op
case LINE_COMPL:
0503
2021-11-05
op
case LINE_COMPL_CURRENT:
0504
2021-11-05
op
goal = width/2;
0505
2021-11-05
op
break;
0506
2021-11-05
op
case LINE_DOWNLOAD:
0507
2021-11-05
op
case LINE_DOWNLOAD_DONE:
0508
2021-11-05
op
goal = width/4;
0509
2021-11-05
op
break;
0510
2021-11-05
op
case LINE_HELP:
0511
2021-11-05
op
goal = 8;
0512
2021-11-05
op
break;
0513
2021-11-05
op
default:
0514
2021-11-05
op
return;
0515
2021-11-05
op
}
0516
2021-11-05
op
0517
2021-11-05
op
if (vl->parent->alt == NULL)
0518
2021-11-05
op
return;
0519
2021-11-05
op
0520
2021-11-05
op
(void)y;
0521
2021-11-05
op
getyx(window, y, x);
0522
2021-07-21
op
0523
2021-07-18
op
if (goal <= x)
0524
2021-07-18
op
wprintw(window, " ");
0525
2021-07-18
op
for (; goal > x; ++x)
0526
2021-07-18
op
wprintw(window, " ");
0527
2021-07-18
op
0528
2021-07-18
op
wprintw(window, "%s", vl->parent->alt);
0529
2021-07-18
op
}
0530
2021-07-18
op
0531
2021-07-16
op
/*
0532
2021-07-16
op
* Core part of the rendering. It prints a vline starting from the
0533
2021-07-16
op
* current cursor position. Printing a vline consists of skipping
0534
2021-07-16
op
* `off' columns (for olivetti-mode), print the correct prefix (which
0535
2021-07-16
op
* may be the emoji in case of emojified links-lines), printing the
0536
2021-07-16
op
* text itself, filling until width - off and filling off columns
0537
2021-07-16
op
* again.
0538
2021-07-16
op
*/
0539
2021-03-15
op
static void
0540
2021-06-21
op
print_vline(int off, int width, WINDOW *window, struct vline *vl)
0541
2021-03-06
op
{
0542
2021-07-16
op
/*
0543
2021-07-16
op
* Believe me or not, I've seen emoji ten code points long!
0544
2021-07-16
op
* That means, to stay large, 4*10 bytes + NUL.
0545
2021-07-16
op
*/
0546
2021-07-16
op
char emojibuf[41] = {0};
0547
2021-07-16
op
const char *text, *prfx;
0548
2021-06-24
op
struct line_face *f;
0549
2021-07-16
op
int i, left, x, y;
0550
2021-03-06
op
0551
2021-06-24
op
f = &line_faces[vl->parent->type];
0552
2021-06-24
op
0553
2021-06-21
op
/* unused, set by getyx */
0554
2021-06-21
op
(void)y;
0555
2021-06-21
op
0556
2022-01-10
op
if (vl->parent->type == LINE_FRINGE && fringe_ignore_offset)
0557
2022-01-10
op
off = 0;
0558
2022-01-10
op
0559
2021-07-16
op
line_prefix_and_text(vl, emojibuf, sizeof(emojibuf), &prfx, &text);
0560
2021-03-12
op
0561
2021-06-24
op
wattr_on(window, body_face.left, NULL);
0562
2021-06-21
op
for (i = 0; i < off; i++)
0563
2021-06-21
op
waddch(window, ' ');
0564
2021-06-24
op
wattr_off(window, body_face.left, NULL);
0565
2021-06-24
op
0566
2021-06-24
op
wattr_on(window, f->prefix, NULL);
0567
2021-07-16
op
wprintw(window, "%s", prfx);
0568
2021-06-24
op
wattr_off(window, f->prefix, NULL);
0569
2021-03-17
op
0570
2021-06-24
op
wattr_on(window, f->text, NULL);
0571
2021-07-16
op
wprintw(window, "%s", text);
0572
2021-07-18
op
print_vline_descr(width, window, vl);
0573
2021-06-24
op
wattr_off(window, f->text, NULL);
0574
2021-06-21
op
0575
2021-06-21
op
getyx(window, y, x);
0576
2021-06-21
op
0577
2021-06-21
op
left = width - x;
0578
2021-06-21
op
0579
2021-06-24
op
wattr_on(window, f->trail, NULL);
0580
2021-07-08
op
for (i = 0; i < left - off; ++i)
0581
2021-06-21
op
waddch(window, ' ');
0582
2021-06-24
op
wattr_off(window, f->trail, NULL);
0583
2021-06-21
op
0584
2021-06-24
op
wattr_on(window, body_face.right, NULL);
0585
2021-06-21
op
for (i = 0; i < off; i++)
0586
2021-06-21
op
waddch(window, ' ');
0587
2021-06-24
op
wattr_off(window, body_face.right, NULL);
0588
2021-06-21
op
0589
2021-03-06
op
}
0590
2021-03-06
op
0591
2021-03-06
op
static void
0592
2021-03-08
op
redraw_tabline(void)
0593
2021-03-08
op
{
0594
2021-03-10
op
struct tab *tab;
0595
2021-04-22
op
size_t toskip, ots, tabwidth, space, x;
0596
2021-07-16
op
int current, y, truncated, pair;
0597
2021-03-13
op
const char *title;
0598
2021-03-16
op
char buf[25];
0599
2021-03-10
op
0600
2021-06-21
op
x = 0;
0601
2021-06-21
op
0602
2021-06-21
op
/* unused, but setted by a getyx */
0603
2021-06-21
op
(void)y;
0604
2021-06-21
op
0605
2021-04-22
op
tabwidth = sizeof(buf)+1;
0606
2021-04-22
op
space = COLS-2;
0607
2021-04-22
op
0608
2021-03-16
op
toskip = 0;
0609
2021-03-16
op
TAILQ_FOREACH(tab, &tabshead, tabs) {
0610
2021-03-16
op
toskip++;
0611
2021-07-17
op
if (tab == current_tab)
0612
2021-03-16
op
break;
0613
2021-03-16
op
}
0614
2021-04-22
op
0615
2022-01-04
op
if (toskip * tabwidth <= space)
0616
2021-04-22
op
toskip = 0;
0617
2021-04-22
op
else {
0618
2021-04-22
op
ots = toskip;
0619
2021-03-16
op
toskip--;
0620
2021-08-26
op
while (toskip != 0 &&
0621
2021-04-22
op
(ots - toskip+1) * tabwidth < space)
0622
2021-04-22
op
toskip--;
0623
2021-04-22
op
}
0624
2021-03-10
op
0625
2021-03-16
op
werase(tabline);
0626
2021-06-24
op
wattr_on(tabline, tab_face.background, NULL);
0627
2021-03-16
op
wprintw(tabline, toskip == 0 ? " " : "<");
0628
2021-06-24
op
wattr_off(tabline, tab_face.background, NULL);
0629
2021-03-16
op
0630
2021-03-16
op
truncated = 0;
0631
2021-03-10
op
TAILQ_FOREACH(tab, &tabshead, tabs) {
0632
2021-03-16
op
if (truncated)
0633
2021-03-16
op
break;
0634
2021-03-16
op
if (toskip != 0) {
0635
2021-03-16
op
toskip--;
0636
2021-03-16
op
continue;
0637
2021-03-16
op
}
0638
2021-03-16
op
0639
2021-03-16
op
getyx(tabline, y, x);
0640
2021-03-16
op
if (x + sizeof(buf)+2 >= (size_t)COLS)
0641
2021-03-16
op
truncated = 1;
0642
2021-03-16
op
0643
2021-07-17
op
current = tab == current_tab;
0644
2021-03-11
op
0645
2021-05-17
op
if (*(title = tab->buffer.page.title) == '\0')
0646
2021-03-13
op
title = tab->hist_cur->h;
0647
2021-03-13
op
0648
2021-05-12
op
if (tab->flags & TAB_URGENT)
0649
2021-05-12
op
strlcpy(buf, "!", sizeof(buf));
0650
2021-05-12
op
else
0651
2021-05-12
op
strlcpy(buf, " ", sizeof(buf));
0652
2021-05-12
op
0653
2021-08-26
op
if (strlcat(buf, title, sizeof(buf)) >= sizeof(buf)) {
0654
2021-03-16
op
/* truncation happens */
0655
2021-03-16
op
strlcpy(&buf[sizeof(buf)-4], "...", 4);
0656
2021-03-16
op
} else {
0657
2021-03-16
op
/* pad with spaces */
0658
2021-03-16
op
while (strlcat(buf, " ", sizeof(buf)) < sizeof(buf))
0659
2021-03-16
op
/* nop */ ;
0660
2021-03-16
op
}
0661
2021-03-16
op
0662
2021-07-16
op
pair = current ? tab_face.current : tab_face.tab;
0663
2021-07-16
op
wattr_on(tabline, pair, NULL);
0664
2021-03-16
op
wprintw(tabline, "%s", buf);
0665
2021-07-16
op
wattr_off(tabline, pair, NULL);
0666
2021-07-16
op
0667
2021-07-16
op
wattr_on(tabline, tab_face.background, NULL);
0668
2021-03-16
op
if (TAILQ_NEXT(tab, tabs) != NULL)
0669
2021-07-23
op
wprintw(tabline, "┃");
0670
2021-07-16
op
wattr_off(tabline, tab_face.background, NULL);
0671
2021-03-10
op
}
0672
2021-03-16
op
0673
2021-06-24
op
wattr_on(tabline, tab_face.background, NULL);
0674
2021-04-22
op
for (; x < (size_t)COLS; ++x)
0675
2021-03-16
op
waddch(tabline, ' ');
0676
2021-03-16
op
if (truncated)
0677
2021-03-16
op
mvwprintw(tabline, 0, COLS-1, ">");
0678
2021-06-24
op
wattr_off(tabline, tab_face.background, NULL);
0679
2021-03-17
op
}
0680
2021-07-05
op
0681
2021-07-05
op
/*
0682
2021-07-05
op
* Compute the first visible line around vl. Try to search forward
0683
2021-07-05
op
* until the end of the buffer; if a visible line is not found, search
0684
2021-07-05
op
* backward. Return NULL if no viable line was found.
0685
2021-07-05
op
*/
0686
2021-07-14
op
struct vline *
0687
2021-07-05
op
adjust_line(struct vline *vl, struct buffer *buffer)
0688
2021-07-05
op
{
0689
2021-07-05
op
struct vline *t;
0690
2021-03-17
op
0691
2021-07-14
op
if (vl == NULL)
0692
2021-07-14
op
return NULL;
0693
2021-07-14
op
0694
2021-07-05
op
if (!(vl->parent->flags & L_HIDDEN))
0695
2021-07-05
op
return vl;
0696
2021-07-05
op
0697
2021-07-05
op
/* search forward */
0698
2021-07-05
op
for (t = vl;
0699
2021-07-05
op
t != NULL && t->parent->flags & L_HIDDEN;
0700
2021-07-05
op
t = TAILQ_NEXT(t, vlines))
0701
2021-07-05
op
; /* nop */
0702
2021-07-05
op
0703
2021-07-05
op
if (t != NULL)
0704
2021-07-05
op
return t;
0705
2021-07-05
op
0706
2021-07-05
op
/* search backward */
0707
2021-07-05
op
for (t = vl;
0708
2021-07-05
op
t != NULL && t->parent->flags & L_HIDDEN;
0709
2021-07-05
op
t = TAILQ_PREV(t, vhead, vlines))
0710
2021-07-05
op
; /* nop */
0711
2021-07-05
op
0712
2021-07-05
op
return t;
0713
2021-07-05
op
}
0714
2021-07-05
op
0715
2021-04-01
op
static void
0716
2021-08-14
op
redraw_window(WINDOW *win, int off, int height, int width,
0717
2022-01-10
op
int show_fringe, struct buffer *buffer)
0718
2021-04-01
op
{
0719
2021-07-20
op
struct vline *vl;
0720
2022-01-10
op
int onscreen = 0, l = 0;
0721
2021-07-01
op
0722
2021-07-01
op
restore_curs_x(buffer);
0723
2021-06-20
op
0724
2021-06-20
op
/*
0725
2021-07-01
op
* TODO: ignoring buffer->force_update and always
0726
2021-07-01
op
* re-rendering. In theory we can recompute the y position
0727
2021-07-01
op
* without a re-render, and optimize here. It's not the only
0728
2021-07-01
op
* optimisation possible here, wscrl wolud also be an
0729
2021-07-01
op
* interesting one.
0730
2021-06-20
op
*/
0731
2021-04-01
op
0732
2021-07-01
op
again:
0733
2021-04-01
op
werase(win);
0734
2021-07-01
op
buffer->curs_y = 0;
0735
2021-06-20
op
0736
2021-05-17
op
if (TAILQ_EMPTY(&buffer->head))
0737
2021-07-05
op
goto end;
0738
2021-07-05
op
0739
2021-07-14
op
if (buffer->top_line == NULL)
0740
2021-07-14
op
buffer->top_line = TAILQ_FIRST(&buffer->head);
0741
2021-07-14
op
0742
2021-07-05
op
buffer->top_line = adjust_line(buffer->top_line, buffer);
0743
2021-07-05
op
if (buffer->top_line == NULL)
0744
2021-06-20
op
goto end;
0745
2021-04-01
op
0746
2021-07-05
op
buffer->current_line = adjust_line(buffer->current_line, buffer);
0747
2021-07-05
op
0748
2021-06-29
op
for (vl = buffer->top_line; vl != NULL; vl = TAILQ_NEXT(vl, vlines)) {
0749
2021-07-05
op
if (vl->parent->flags & L_HIDDEN)
0750
2021-07-05
op
continue;
0751
2021-07-05
op
0752
2021-06-21
op
wmove(win, l, 0);
0753
2021-07-14
op
print_vline(off, width, win, vl);
0754
2021-07-01
op
0755
2021-07-01
op
if (vl == buffer->current_line)
0756
2021-07-01
op
onscreen = 1;
0757
2021-07-01
op
0758
2021-07-01
op
if (!onscreen)
0759
2021-07-01
op
buffer->curs_y++;
0760
2021-07-01
op
0761
2021-04-01
op
l++;
0762
2021-04-01
op
if (l == height)
0763
2021-04-01
op
break;
0764
2021-07-01
op
}
0765
2021-07-01
op
0766
2021-07-01
op
if (!onscreen) {
0767
2021-07-01
op
for (; vl != NULL; vl = TAILQ_NEXT(vl, vlines)) {
0768
2021-07-01
op
if (vl == buffer->current_line)
0769
2021-07-01
op
break;
0770
2021-07-05
op
if (vl->parent->flags & L_HIDDEN)
0771
2021-07-05
op
continue;
0772
2021-07-01
op
buffer->line_off++;
0773
2021-07-01
op
buffer->top_line = TAILQ_NEXT(buffer->top_line, vlines);
0774
2021-07-01
op
}
0775
2021-07-01
op
0776
2021-07-14
op
if (vl != NULL)
0777
2021-07-14
op
goto again;
0778
2021-04-01
op
}
0779
2021-04-01
op
0780
2021-07-01
op
buffer->last_line_off = buffer->line_off;
0781
2021-07-01
op
buffer->force_redraw = 0;
0782
2021-06-20
op
end:
0783
2022-01-10
op
for (; show_fringe && l < height; l++)
0784
2022-01-10
op
print_vline(off, width, win, &fringe);
0785
2022-01-10
op
0786
2021-05-17
op
wmove(win, buffer->curs_y, buffer->curs_x);
0787
2021-11-05
op
}
0788
2021-11-05
op
0789
2021-11-05
op
static void
0790
2021-11-05
op
redraw_download(void)
0791
2021-11-05
op
{
0792
2022-01-10
op
redraw_window(download, 0, download_lines, COLS, 0, &downloadwin);
0793
2021-04-01
op
}
0794
2021-04-01
op
0795
2021-04-01
op
static void
0796
2021-04-01
op
redraw_help(void)
0797
2021-04-01
op
{
0798
2022-01-10
op
redraw_window(help, 0, help_lines, help_cols, 1, &helpwin);
0799
2021-04-01
op
}
0800
2021-04-01
op
0801
2021-04-01
op
static void
0802
2021-04-01
op
redraw_body(struct tab *tab)
0803
2021-04-01
op
{
0804
2021-06-21
op
static struct tab *last_tab;
0805
2021-06-21
op
0806
2021-06-21
op
if (last_tab != tab)
0807
2021-06-21
op
tab->buffer.force_redraw =1;
0808
2021-06-21
op
last_tab = tab;
0809
2021-06-21
op
0810
2022-01-10
op
redraw_window(body, x_offset, body_lines, body_cols, 1, &tab->buffer);
0811
2021-04-01
op
}
0812
2021-04-01
op
0813
2021-03-17
op
static inline char
0814
2021-03-17
op
trust_status_char(enum trust_state ts)
0815
2021-03-17
op
{
0816
2021-03-17
op
switch (ts) {
0817
2021-07-21
op
case TS_UNKNOWN: return '-';
0818
2021-03-17
op
case TS_UNTRUSTED: return '!';
0819
2021-07-06
op
case TS_TEMP_TRUSTED: return '!';
0820
2021-03-17
op
case TS_TRUSTED: return 'v';
0821
2021-03-17
op
case TS_VERIFIED: return 'V';
0822
2021-06-21
op
default: return 'X';
0823
2021-03-17
op
}
0824
2021-03-08
op
}
0825
2021-03-08
op
0826
2021-03-08
op
static void
0827
2021-03-06
op
redraw_modeline(struct tab *tab)
0828
2021-03-06
op
{
0829
2021-07-21
op
struct buffer *buffer;
0830
2021-03-11
op
double pct;
0831
2021-03-06
op
int x, y, max_x, max_y;
0832
2021-07-21
op
const char *mode;
0833
2021-03-08
op
const char *spin = "-\\|/";
0834
2021-03-06
op
0835
2021-07-21
op
buffer = current_buffer();
0836
2021-07-21
op
mode = buffer->page.name;
0837
2021-07-21
op
0838
2021-03-13
op
werase(modeline);
0839
2021-06-24
op
wattr_on(modeline, modeline_face.background, NULL);
0840
2021-03-06
op
wmove(modeline, 0, 0);
0841
2021-03-06
op
0842
2022-01-06
op
wprintw(modeline, "-%c%c- %s ",
0843
2021-03-22
op
spin[tab->loading_anim_step],
0844
2021-03-17
op
trust_status_char(tab->trust),
0845
2021-03-16
op
mode == NULL ? "(none)" : mode);
0846
2021-03-11
op
0847
2021-07-21
op
pct = (buffer->line_off + buffer->curs_y) * 100.0
0848
2021-07-21
op
/ buffer->line_max;
0849
2021-07-21
op
0850
2021-07-21
op
if (buffer->line_max <= (size_t)body_lines)
0851
2021-08-26
op
wprintw(modeline, "All ");
0852
2021-07-21
op
else if (buffer->line_off == 0)
0853
2021-08-26
op
wprintw(modeline, "Top ");
0854
2021-07-21
op
else if (buffer->line_off + body_lines >= buffer->line_max)
0855
2021-03-11
op
wprintw(modeline, "Bottom ");
0856
2021-03-11
op
else
0857
2021-03-11
op
wprintw(modeline, "%.0f%% ", pct);
0858
2021-03-11
op
0859
2022-01-13
op
wprintw(modeline, "%zu/%zu %s ",
0860
2021-07-21
op
buffer->line_off + buffer->curs_y,
0861
2021-07-21
op
buffer->line_max,
0862
2021-03-13
op
tab->hist_cur->h);
0863
2021-03-11
op
0864
2021-03-06
op
getyx(modeline, y, x);
0865
2021-03-06
op
getmaxyx(modeline, max_y, max_x);
0866
2021-03-06
op
0867
2021-03-06
op
(void)y;
0868
2021-03-06
op
(void)max_y;
0869
2021-03-06
op
0870
2021-03-06
op
for (; x < max_x; ++x)
0871
2021-03-06
op
waddstr(modeline, "-");
0872
2021-06-15
op
0873
2021-06-24
op
wattr_off(modeline, modeline_face.background, NULL);
0874
2021-03-09
op
}
0875
2021-03-09
op
0876
2021-03-09
op
static void
0877
2021-07-12
op
redraw_minibuffer(void)
0878
2021-03-09
op
{
0879
2021-07-10
op
wattr_on(echoarea, minibuffer_face.background, NULL);
0880
2021-07-10
op
werase(echoarea);
0881
2021-03-21
op
0882
2021-07-12
op
if (in_minibuffer)
0883
2021-07-12
op
do_redraw_minibuffer();
0884
2021-07-12
op
else
0885
2021-07-12
op
do_redraw_echoarea();
0886
2021-03-10
op
0887
2021-07-14
op
if (in_minibuffer == MB_COMPREAD)
0888
2021-07-14
op
do_redraw_minibuffer_compl();
0889
2021-07-14
op
0890
2021-07-12
op
wattr_off(echoarea, minibuffer_face.background, NULL);
0891
2021-07-12
op
}
0892
2021-03-10
op
0893
2021-07-12
op
static void
0894
2021-07-12
op
do_redraw_echoarea(void)
0895
2021-07-12
op
{
0896
2021-07-17
op
struct vline *vl;
0897
2021-03-10
op
0898
2021-03-21
op
if (ministate.curmesg != NULL)
0899
2021-08-26
op
wprintw(echoarea, "%s", ministate.curmesg);
0900
2021-07-12
op
else if (*keybuf != '\0')
0901
2021-07-10
op
waddstr(echoarea, keybuf);
0902
2021-07-12
op
else {
0903
2021-07-12
op
/* If nothing else, show the URL at point */
0904
2021-07-17
op
vl = current_tab->buffer.current_line;
0905
2021-07-17
op
if (vl != NULL && vl->parent->type == LINE_LINK)
0906
2021-07-17
op
waddstr(echoarea, vl->parent->alt);
0907
2021-03-18
op
}
0908
2021-07-12
op
}
0909
2021-03-13
op
0910
2021-07-12
op
static void
0911
2021-07-12
op
do_redraw_minibuffer(void)
0912
2021-07-12
op
{
0913
2021-07-24
op
struct buffer *cmplbuf, *buffer;
0914
2021-07-12
op
size_t off_y, off_x = 0;
0915
2021-07-12
op
const char *start, *c;
0916
2021-06-15
op
0917
2021-07-24
op
cmplbuf = &ministate.compl.buffer;
0918
2021-07-24
op
buffer = &ministate.buffer;
0919
2021-07-24
op
(void)off_y; /* unused, set by getyx */
0920
2021-07-12
op
0921
2021-07-15
op
wmove(echoarea, 0, 0);
0922
2021-07-15
op
0923
2021-07-15
op
if (in_minibuffer == MB_COMPREAD)
0924
2022-01-13
op
wprintw(echoarea, "(%2zu) ",
0925
2021-07-24
op
cmplbuf->line_max);
0926
2021-07-15
op
0927
2021-07-15
op
wprintw(echoarea, "%s", ministate.prompt);
0928
2021-07-12
op
if (ministate.hist_cur != NULL)
0929
2021-07-12
op
wprintw(echoarea, "(%zu/%zu) ",
0930
2021-07-12
op
ministate.hist_off + 1,
0931
2021-07-12
op
ministate.history->len);
0932
2021-07-12
op
0933
2021-07-12
op
getyx(echoarea, off_y, off_x);
0934
2021-07-12
op
0935
2021-07-12
op
start = ministate.hist_cur != NULL
0936
2021-07-12
op
? ministate.hist_cur->h
0937
2021-07-12
op
: ministate.buf;
0938
2021-07-24
op
c = utf8_nth(buffer->current_line->line, buffer->cpoff);
0939
2021-07-12
op
while (utf8_swidth_between(start, c) > (size_t)COLS/2) {
0940
2021-07-12
op
start = utf8_next_cp(start);
0941
2021-07-12
op
}
0942
2021-07-12
op
0943
2021-07-12
op
waddstr(echoarea, start);
0944
2021-07-12
op
0945
2021-07-12
op
if (ministate.curmesg != NULL)
0946
2021-07-12
op
wprintw(echoarea, " [%s]", ministate.curmesg);
0947
2021-07-12
op
0948
2021-07-12
op
wmove(echoarea, 0, off_x + utf8_swidth_between(start, c));
0949
2021-07-14
op
}
0950
2021-07-14
op
0951
2021-07-14
op
static void
0952
2021-07-14
op
do_redraw_minibuffer_compl(void)
0953
2021-07-14
op
{
0954
2022-01-10
op
redraw_window(minibuffer, 0, 10, COLS, 1,
0955
2021-07-14
op
&ministate.compl.buffer);
0956
2021-07-12
op
}
0957
2021-07-12
op
0958
2021-07-12
op
/*
0959
2021-07-12
op
* Place the cursor in the right ncurses window. If soft is 1, use
0960
2021-07-12
op
* wnoutrefresh (which shouldn't cause any I/O); otherwise use
0961
2021-07-12
op
* wrefresh.
0962
2021-07-12
op
*/
0963
2021-07-12
op
static void
0964
2021-07-12
op
place_cursor(int soft)
0965
2021-07-12
op
{
0966
2021-07-12
op
int (*touch)(WINDOW *);
0967
2021-07-12
op
0968
2021-07-12
op
if (soft)
0969
2021-07-12
op
touch = wnoutrefresh;
0970
2021-07-12
op
else
0971
2021-07-12
op
touch = wrefresh;
0972
2021-07-12
op
0973
2021-07-12
op
if (in_minibuffer) {
0974
2021-11-05
op
if (side_window & SIDE_WINDOW_LEFT)
0975
2021-07-21
op
touch(help);
0976
2021-11-05
op
if (side_window & SIDE_WINDOW_BOTTOM)
0977
2021-11-05
op
touch(download);
0978
2021-07-21
op
touch(body);
0979
2021-07-21
op
touch(echoarea);
0980
2021-11-05
op
} else if (in_side_window & SIDE_WINDOW_LEFT) {
0981
2021-07-12
op
touch(body);
0982
2021-07-12
op
touch(echoarea);
0983
2021-11-05
op
if (in_side_window & SIDE_WINDOW_BOTTOM)
0984
2021-11-05
op
touch(download);
0985
2021-07-21
op
touch(help);
0986
2021-11-05
op
} else if (in_side_window & SIDE_WINDOW_BOTTOM) {
0987
2021-11-05
op
touch(body);
0988
2021-11-05
op
touch(echoarea);
0989
2021-11-05
op
if (in_side_window & SIDE_WINDOW_LEFT)
0990
2021-07-21
op
touch(help);
0991
2021-11-05
op
touch(download);
0992
2021-11-05
op
} else {
0993
2021-11-05
op
if (side_window & SIDE_WINDOW_LEFT)
0994
2021-11-05
op
touch(help);
0995
2021-11-05
op
if (side_window & SIDE_WINDOW_BOTTOM)
0996
2021-11-05
op
touch(download);
0997
2021-07-12
op
touch(echoarea);
0998
2021-07-12
op
touch(body);
0999
2021-07-12
op
}
1000
2021-03-06
op
}
1001
2021-03-06
op
1002
2021-03-06
op
static void
1003
2021-03-06
op
redraw_tab(struct tab *tab)
1004
2021-03-06
op
{
1005
2021-07-13
op
if (too_small)
1006
2021-07-13
op
return;
1007
2021-07-13
op
1008
2021-11-05
op
if (side_window & SIDE_WINDOW_LEFT) {
1009
2021-04-01
op
redraw_help();
1010
2021-04-01
op
wnoutrefresh(help);
1011
2021-04-01
op
}
1012
2021-04-01
op
1013
2021-11-05
op
if (side_window & SIDE_WINDOW_BOTTOM) {
1014
2021-11-05
op
redraw_download();
1015
2021-11-05
op
wnoutrefresh(download);
1016
2021-11-05
op
}
1017
2021-11-05
op
1018
2021-08-18
op
if (show_tab_bar)
1019
2021-08-18
op
redraw_tabline();
1020
2021-08-18
op
1021
2021-03-11
op
redraw_body(tab);
1022
2021-03-11
op
redraw_modeline(tab);
1023
2021-07-12
op
redraw_minibuffer();
1024
2021-03-11
op
1025
2021-04-01
op
wnoutrefresh(tabline);
1026
2021-04-01
op
wnoutrefresh(modeline);
1027
2021-03-11
op
1028
2021-07-14
op
if (in_minibuffer == MB_COMPREAD)
1029
2021-07-14
op
wnoutrefresh(minibuffer);
1030
2021-07-14
op
1031
2021-07-12
op
place_cursor(1);
1032
2021-04-01
op
1033
2021-04-01
op
doupdate();
1034
2021-07-17
op
1035
2021-07-17
op
if (set_title)
1036
2021-08-14
op
dprintf(1, "\033]2;%s - Telescope\a",
1037
2021-07-17
op
current_tab->buffer.page.title);
1038
2021-03-11
op
}
1039
2021-03-06
op
1040
2021-06-20
op
void
1041
2021-03-08
op
start_loading_anim(struct tab *tab)
1042
2021-03-08
op
{
1043
2021-03-22
op
if (tab->loading_anim)
1044
2021-03-08
op
return;
1045
2021-03-22
op
tab->loading_anim = 1;
1046
2021-03-22
op
evtimer_set(&tab->loadingev, update_loading_anim, tab);
1047
2021-03-22
op
evtimer_add(&tab->loadingev, &loadingev_timer);
1048
2021-03-08
op
}
1049
2021-03-08
op
1050
2021-03-08
op
static void
1051
2021-03-08
op
update_loading_anim(int fd, short ev, void *d)
1052
2021-03-08
op
{
1053
2021-03-08
op
struct tab *tab = d;
1054
2021-03-08
op
1055
2021-03-22
op
tab->loading_anim_step = (tab->loading_anim_step+1)%4;
1056
2021-03-09
op
1057
2021-07-17
op
if (tab == current_tab) {
1058
2021-03-16
op
redraw_modeline(tab);
1059
2021-03-16
op
wrefresh(modeline);
1060
2021-03-16
op
wrefresh(body);
1061
2021-03-16
op
if (in_minibuffer)
1062
2021-07-10
op
wrefresh(echoarea);
1063
2021-03-16
op
}
1064
2021-03-08
op
1065
2021-03-22
op
evtimer_add(&tab->loadingev, &loadingev_timer);
1066
2021-03-08
op
}
1067
2021-03-08
op
1068
2021-03-08
op
static void
1069
2021-03-08
op
stop_loading_anim(struct tab *tab)
1070
2021-03-08
op
{
1071
2021-03-22
op
if (!tab->loading_anim)
1072
2021-03-08
op
return;
1073
2021-03-22
op
evtimer_del(&tab->loadingev);
1074
2021-03-22
op
tab->loading_anim = 0;
1075
2021-03-22
op
tab->loading_anim_step = 0;
1076
2021-03-18
op
1077
2021-07-17
op
if (tab != current_tab)
1078
2021-03-18
op
return;
1079
2021-03-09
op
1080
2021-03-09
op
redraw_modeline(tab);
1081
2021-03-09
op
1082
2021-03-09
op
wrefresh(modeline);
1083
2021-03-09
op
wrefresh(body);
1084
2021-03-09
op
if (in_minibuffer)
1085
2021-07-10
op
wrefresh(echoarea);
1086
2021-03-09
op
}
1087
2021-03-09
op
1088
2021-07-15
op
int
1089
2021-07-15
op
ui_print_colors(void)
1090
2021-07-15
op
{
1091
2021-07-15
op
int colors = 0, pairs = 0, can_change = 0;
1092
2021-07-15
op
int columns = 16, lines, color, i, j;
1093
2021-07-15
op
1094
2021-07-15
op
initscr();
1095
2021-07-15
op
if (has_colors()) {
1096
2021-07-15
op
start_color();
1097
2021-07-15
op
use_default_colors();
1098
2021-07-15
op
1099
2021-07-15
op
colors = COLORS;
1100
2021-07-15
op
pairs = COLOR_PAIRS;
1101
2021-07-15
op
can_change = can_change_color();
1102
2021-07-15
op
}
1103
2021-07-15
op
endwin();
1104
2021-07-15
op
1105
2021-07-15
op
printf("Term info:\n");
1106
2021-07-15
op
printf("TERM=%s COLORS=%d COLOR_PAIRS=%d can_change_colors=%d\n",
1107
2021-07-15
op
getenv("TERM"), colors, pairs, can_change);
1108
2021-07-15
op
printf("\n");
1109
2021-07-15
op
1110
2021-07-15
op
if (colors == 0) {
1111
2021-07-15
op
printf("No color support\n");
1112
2021-07-15
op
return 0;
1113
2021-07-15
op
}
1114
2021-07-15
op
1115
2021-07-15
op
printf("Available colors:\n\n");
1116
2021-07-15
op
lines = (colors - 1) / columns + 1;
1117
2021-07-15
op
color = 0;
1118
2021-07-15
op
for (i = 0; i < lines; ++i) {
1119
2021-07-15
op
for (j = 0; j < columns; ++j, ++color) {
1120
2021-07-15
op
printf("\033[0;38;5;%dm %03d", color, color);
1121
2021-07-15
op
}
1122
2021-07-15
op
printf("\n");
1123
2021-07-15
op
}
1124
2021-07-15
op
1125
2021-07-15
op
printf("\033[0m");
1126
2021-07-15
op
fflush(stdout);
1127
2021-07-15
op
return 0;
1128
2021-03-02
op
}
1129
2021-03-02
op
1130
2021-03-18
op
int
1131
2021-07-08
op
ui_init()
1132
2021-03-18
op
{
1133
2021-03-02
op
setlocale(LC_ALL, "");
1134
2021-07-21
op
1135
2021-08-12
op
if (TAILQ_EMPTY(&global_map.m)) {
1136
2021-08-12
op
fprintf(stderr, "no keys defined!\n");
1137
2021-08-12
op
return 0;
1138
2021-08-12
op
}
1139
2021-08-12
op
1140
2021-07-21
op
minibuffer_init();
1141
2021-03-22
op
1142
2021-11-05
op
/* initialize download window */
1143
2021-11-05
op
TAILQ_INIT(&downloadwin.head);
1144
2021-11-05
op
TAILQ_INIT(&downloadwin.page.head);
1145
2021-11-05
op
1146
2021-04-01
op
/* initialize help window */
1147
2021-04-01
op
TAILQ_INIT(&helpwin.head);
1148
2021-08-12
op
TAILQ_INIT(&helpwin.page.head);
1149
2021-04-01
op
1150
2021-03-09
op
base_map = &global_map;
1151
2021-03-09
op
current_map = &global_map;
1152
2021-03-09
op
1153
2021-03-02
op
initscr();
1154
2021-06-21
op
1155
2021-06-21
op
if (enable_colors) {
1156
2021-06-21
op
if (has_colors()) {
1157
2021-06-21
op
start_color();
1158
2021-06-21
op
use_default_colors();
1159
2021-06-21
op
} else
1160
2021-06-21
op
enable_colors = 0;
1161
2021-06-21
op
}
1162
2021-06-21
op
1163
2021-06-24
op
config_apply_style();
1164
2021-06-24
op
1165
2021-03-02
op
raw();
1166
2021-03-02
op
noecho();
1167
2021-03-02
op
nonl();
1168
2021-03-02
op
intrflush(stdscr, FALSE);
1169
2021-03-02
op
1170
2021-08-18
op
if ((tabline = newwin(1, 1, 0, 0)) == NULL)
1171
2021-03-06
op
return 0;
1172
2021-08-18
op
if ((body = newwin(1, 1, 0, 0)) == NULL)
1173
2021-03-06
op
return 0;
1174
2021-08-18
op
if ((modeline = newwin(1, 1, 0, 0)) == NULL)
1175
2021-07-13
op
return 0;
1176
2021-08-18
op
if ((echoarea = newwin(1, 1, 0, 0)) == NULL)
1177
2021-08-18
op
return 0;
1178
2021-08-18
op
if ((minibuffer = newwin(1, 1, 0, 0)) == NULL)
1179
2021-03-06
op
return 0;
1180
2021-11-05
op
if ((download = newwin(1, 1, 0, 0)) == NULL)
1181
2021-11-05
op
return 0;
1182
2021-08-18
op
if ((help = newwin(1, 1, 0, 0)) == NULL)
1183
2021-04-01
op
return 0;
1184
2021-03-06
op
1185
2021-06-21
op
wbkgd(body, body_face.body);
1186
2021-11-05
op
wbkgd(download, download_face.background);
1187
2021-07-10
op
wbkgd(echoarea, minibuffer_face.background);
1188
2021-06-19
op
1189
2021-06-19
op
update_x_offset();
1190
2021-03-06
op
1191
2021-03-09
op
keypad(body, TRUE);
1192
2021-06-21
op
scrollok(body, FALSE);
1193
2021-03-06
op
1194
2021-03-02
op
/* non-blocking input */
1195
2021-03-06
op
wtimeout(body, 0);
1196
2021-07-21
op
wtimeout(help, 0);
1197
2021-03-02
op
1198
2021-03-06
op
mvwprintw(body, 0, 0, "");
1199
2021-03-02
op
1200
2021-12-30
op
return 1;
1201
2021-12-30
op
}
1202
2021-12-30
op
1203
2021-12-30
op
void
1204
2021-12-30
op
ui_main_loop(void)
1205
2021-12-30
op
{
1206
2021-07-16
op
evtimer_set(&resizeev, handle_resize, NULL);
1207
2022-05-05
op
evtimer_set(&download_refreshev, handle_download_refresh, NULL);
1208
2021-07-16
op
1209
2021-03-02
op
event_set(&stdioev, 0, EV_READ | EV_PERSIST, dispatch_stdio, NULL);
1210
2021-03-02
op
event_add(&stdioev, NULL);
1211
2021-03-02
op
1212
2021-03-02
op
signal_set(&winchev, SIGWINCH, handle_resize, NULL);
1213
2021-03-02
op
signal_add(&winchev, NULL);
1214
2021-07-17
op
1215
2021-07-17
op
switch_to_tab(current_tab);
1216
2021-08-18
op
rearrange_windows();
1217
2022-04-24
op
1218
2022-04-24
op
event_dispatch();
1219
2021-03-02
op
}
1220
2021-03-02
op
1221
2021-03-02
op
void
1222
2021-03-08
op
ui_on_tab_loaded(struct tab *tab)
1223
2021-03-08
op
{
1224
2021-03-08
op
stop_loading_anim(tab);
1225
2021-03-13
op
message("Loaded %s", tab->hist_cur->h);
1226
2021-03-18
op
1227
2022-01-18
op
if (tab->hist_cur->current_off != 0 &&
1228
2022-01-18
op
tab->buffer.current_line == TAILQ_FIRST(&tab->buffer.head)) {
1229
2022-01-18
op
set_scroll_position(tab, tab->hist_cur->line_off,
1230
2022-01-18
op
tab->hist_cur->current_off);
1231
2022-01-18
op
redraw_tab(tab);
1232
2022-01-18
op
return;
1233
2022-01-18
op
}
1234
2022-01-18
op
1235
2021-08-18
op
if (show_tab_bar)
1236
2021-08-18
op
redraw_tabline();
1237
2021-08-18
op
1238
2021-03-18
op
wrefresh(tabline);
1239
2021-07-12
op
place_cursor(0);
1240
2021-03-08
op
}
1241
2021-03-08
op
1242
2021-03-08
op
void
1243
2021-03-02
op
ui_on_tab_refresh(struct tab *tab)
1244
2021-03-02
op
{
1245
2021-05-17
op
wrap_page(&tab->buffer, body_cols);
1246
2021-07-17
op
if (tab == current_tab)
1247
2021-03-18
op
redraw_tab(tab);
1248
2021-07-01
op
else
1249
2021-05-12
op
tab->flags |= TAB_URGENT;
1250
2021-11-05
op
}
1251
2021-11-05
op
1252
2021-11-05
op
void
1253
2021-11-05
op
ui_on_download_refresh(void)
1254
2021-11-05
op
{
1255
2022-05-05
op
if (event_pending(&download_refreshev, EV_TIMEOUT, NULL))
1256
2022-05-05
op
return;
1257
2022-05-05
op
1258
2022-05-05
op
evtimer_set(&download_refreshev, handle_download_refresh, NULL);
1259
2022-05-05
op
evtimer_add(&download_refreshev, &download_refresh_timer);
1260
2021-03-02
op
}
1261
2021-03-02
op
1262
2022-02-24
op
void
1263
2022-02-24
op
ui_remotely_open_link(const char *uri)
1264
2022-02-24
op
{
1265
2022-02-24
op
new_tab(uri, NULL, NULL);
1266
2022-02-24
op
ui_on_tab_refresh(current_tab);
1267
2022-02-24
op
1268
2022-02-24
op
/* ring the bell */
1269
2022-02-24
op
printf("\a");
1270
2022-02-24
op
fflush(stdout);
1271
2022-02-24
op
}
1272
2022-02-24
op
1273
2021-06-20
op
const char *
1274
2021-06-20
op
ui_keyname(int k)
1275
2021-06-20
op
{
1276
2021-06-20
op
return keyname(k);
1277
2021-06-20
op
}
1278
2021-06-20
op
1279
2021-03-02
op
void
1280
2021-11-05
op
ui_toggle_side_window(int kind)
1281
2021-06-20
op
{
1282
2021-11-05
op
if (in_side_window & kind)
1283
2021-11-05
op
ui_other_window();
1284
2021-11-05
op
1285
2021-11-05
op
side_window ^= kind;
1286
2021-11-05
op
if (side_window & SIDE_WINDOW_LEFT)
1287
2021-06-20
op
recompute_help();
1288
2021-11-05
op
if (side_window & SIDE_WINDOW_BOTTOM)
1289
2021-11-05
op
recompute_downloads();
1290
2021-06-20
op
1291
2021-06-20
op
/*
1292
2021-06-20
op
* ugly hack, but otherwise the window doesn't get updated
1293
2021-07-15
op
* until I call rearrange_windows a second time (e.g. via
1294
2021-07-15
op
* C-l). I will be happy to know why something like this is
1295
2021-07-15
op
* needed.
1296
2021-06-20
op
*/
1297
2021-07-15
op
rearrange_windows();
1298
2021-07-15
op
rearrange_windows();
1299
2021-06-20
op
}
1300
2021-06-20
op
1301
2021-06-20
op
void
1302
2021-11-05
op
ui_show_downloads_pane(void)
1303
2021-11-05
op
{
1304
2021-11-05
op
if (!(side_window & SIDE_WINDOW_BOTTOM))
1305
2021-11-05
op
ui_toggle_side_window(SIDE_WINDOW_BOTTOM);
1306
2021-11-05
op
}
1307
2021-11-05
op
1308
2021-11-05
op
void
1309
2021-06-20
op
ui_schedule_redraw(void)
1310
2021-06-20
op
{
1311
2021-07-15
op
should_rearrange_windows = 1;
1312
2021-06-20
op
}
1313
2021-06-20
op
1314
2021-06-20
op
void
1315
2022-02-07
op
ui_require_input(struct tab *tab, int hide, void (*fn)(void))
1316
2021-03-11
op
{
1317
2021-03-11
op
/* TODO: hard-switching to another tab is ugly */
1318
2021-03-11
op
switch_to_tab(tab);
1319
2021-03-11
op
1320
2021-08-03
op
enter_minibuffer(sensible_self_insert, fn, exit_minibuffer,
1321
2022-04-13
op
&ir_history, NULL, NULL, 0);
1322
2021-03-11
op
strlcpy(ministate.prompt, "Input required: ",
1323
2021-03-11
op
sizeof(ministate.prompt));
1324
2021-03-11
op
redraw_tab(tab);
1325
2021-03-11
op
}
1326
2021-03-11
op
1327
2021-03-11
op
void
1328
2021-07-21
op
ui_after_message_hook(void)
1329
2021-07-21
op
{
1330
2021-07-21
op
redraw_minibuffer();
1331
2021-07-21
op
place_cursor(0);
1332
2021-07-21
op
}
1333
2021-07-21
op
1334
2021-07-21
op
void
1335
2021-07-06
op
ui_yornp(const char *prompt, void (*fn)(int, struct tab *),
1336
2021-07-06
op
struct tab *data)
1337
2021-03-25
op
{
1338
2021-07-12
op
yornp(prompt, fn, data);
1339
2021-07-17
op
redraw_tab(current_tab);
1340
2021-03-25
op
}
1341
2021-03-25
op
1342
2021-03-25
op
void
1343
2021-07-13
op
ui_read(const char *prompt, void (*fn)(const char*, struct tab *),
1344
2021-08-29
op
struct tab *data, const char *input)
1345
2021-05-17
op
{
1346
2021-07-21
op
minibuffer_read(prompt, fn, data);
1347
2021-08-29
op
1348
2021-08-29
op
if (input != NULL) {
1349
2021-08-29
op
strlcpy(ministate.buf, input, sizeof(ministate.buf));
1350
2021-08-29
op
cmd_move_end_of_line(&ministate.buffer);
1351
2021-08-29
op
}
1352
2021-08-29
op
1353
2021-07-17
op
redraw_tab(current_tab);
1354
2021-07-15
op
}
1355
2021-07-15
op
1356
2021-07-15
op
void
1357
2021-07-21
op
ui_other_window(void)
1358
2021-07-21
op
{
1359
2021-11-05
op
if (in_side_window & SIDE_WINDOW_LEFT &&
1360
2021-11-05
op
side_window & SIDE_WINDOW_BOTTOM)
1361
2021-11-05
op
in_side_window = SIDE_WINDOW_BOTTOM;
1362
2021-11-05
op
else if (in_side_window)
1363
2021-11-05
op
in_side_window = 0;
1364
2021-11-05
op
else if (!in_side_window && side_window & SIDE_WINDOW_LEFT)
1365
2021-11-05
op
in_side_window = SIDE_WINDOW_LEFT;
1366
2021-11-05
op
else if (!in_side_window && side_window)
1367
2021-11-05
op
in_side_window = SIDE_WINDOW_BOTTOM;
1368
2021-07-21
op
else
1369
2021-07-21
op
message("No other window to select");
1370
2021-07-21
op
}
1371
2021-07-21
op
1372
2021-07-21
op
void
1373
2021-07-15
op
ui_suspend(void)
1374
2021-07-15
op
{
1375
2021-07-15
op
endwin();
1376
2021-07-15
op
1377
2021-07-15
op
kill(getpid(), SIGSTOP);
1378
2021-07-15
op
1379
2021-07-15
op
refresh();
1380
2021-07-15
op
clear();
1381
2021-07-15
op
rearrange_windows();
1382
2021-03-15
op
}
1383
2021-03-15
op
1384
2021-03-15
op
void
1385
2021-03-02
op
ui_end(void)
1386
2021-03-02
op
{
1387
2021-03-02
op
endwin();
1388
2021-03-02
op
}
Omar Polo