Skip to content

Commit b23ae5a

Browse files
committed
add buffer yanking, clean up input functions
1 parent 190e1e7 commit b23ae5a

9 files changed

Lines changed: 150 additions & 124 deletions

File tree

build/Makefile

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
TOXIC_VERSION = 0.4.4
1+
TOXIC_VERSION = 0.4.5
22
REV = $(shell git rev-list HEAD --count)
33
VERSION = $(TOXIC_VERSION)_r$(REV)
44

@@ -15,7 +15,7 @@ MANFILES = toxic.1 toxic.conf.5
1515

1616
LIBS = libtoxcore ncursesw
1717

18-
CFLAGS = -std=gnu99 -pthread -Wall
18+
CFLAGS = -std=gnu99 -pthread -Wall -g
1919
CFLAGS += -DTOXICVER="\"$(VERSION)\"" -DHAVE_WIDECHAR -D_XOPEN_SOURCE_EXTENDED
2020
CFLAGS += -DPACKAGE_DATADIR="\"$(abspath $(DATADIR))\""
2121
CFLAGS += $(USER_CFLAGS)

src/chat.c

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,10 @@
2020
*
2121
*/
2222

23+
#ifndef _GNU_SOURCE
24+
#define _GNU_SOURCE /* needed for wcswidth() */
25+
#endif
26+
2327
#include <stdlib.h>
2428
#include <string.h>
2529
#include <time.h>
@@ -847,7 +851,7 @@ static void chat_onDraw(ToxWindow *self, Tox *m)
847851
int y, x;
848852
getyx(self->window, y, x);
849853
(void) x;
850-
int new_x = ctx->start ? x2 - 1 : ctx->pos;
854+
int new_x = ctx->start ? x2 - 1 : wcswidth(ctx->line, ctx->pos);
851855
wmove(self->window, y + 1, new_x);
852856

853857
wrefresh(self->window);

src/groupchat.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121
*/
2222

2323
#ifndef _GNU_SOURCE
24-
#define _GNU_SOURCE /* needed for strcasestr() */
24+
#define _GNU_SOURCE /* needed for strcasestr() and wcswidth() */
2525
#endif
2626

2727
#include <stdlib.h>
@@ -474,7 +474,7 @@ static void groupchat_onDraw(ToxWindow *self, Tox *m)
474474
int y, x;
475475
getyx(self->window, y, x);
476476
(void) x;
477-
int new_x = ctx->start ? x2 - 1 : ctx->pos;
477+
int new_x = ctx->start ? x2 - 1 : wcswidth(ctx->line, ctx->pos);
478478
wmove(self->window, y + 1, new_x);
479479

480480
wrefresh(self->window);

src/input.c

Lines changed: 59 additions & 90 deletions
Original file line numberDiff line numberDiff line change
@@ -37,190 +37,155 @@ void input_new_char(ToxWindow *self, wint_t key, int x, int y, int mx_x, int mx_
3737
{
3838
ChatContext *ctx = self->chatwin;
3939

40-
if (ctx->len >= MAX_STR_SIZE - 1) {
41-
beep();
42-
return;
43-
}
44-
4540
int cur_len = wcwidth(key);
4641

4742
/* this is the only place we need to do this check */
48-
if (cur_len == -1)
43+
if (cur_len == -1) {
44+
beep();
4945
return;
46+
}
5047

51-
add_char_to_buf(ctx, key);
48+
if (add_char_to_buf(ctx, key) == -1) {
49+
beep();
50+
return;
51+
}
5252

5353
if (x + cur_len >= mx_x) {
5454
int s_len = wcwidth(ctx->line[ctx->start]);
55-
int cdiff = cur_len - s_len;
56-
ctx->start += 1 + MAX(0, cdiff);
57-
wmove(self->window, y, wcswidth(&ctx->line[ctx->start], mx_x));
58-
} else {
59-
wmove(self->window, y, x + cur_len);
55+
ctx->start += 1 + MAX(0, cur_len - s_len);
6056
}
6157
}
6258

6359
/* delete a char via backspace key from input field and buffer */
64-
static void input_backspace(ToxWindow *self, int x, int y, int mx_x, int mx_y)
60+
static void input_backspace(ToxWindow *self, int x, int mx_x)
6561
{
6662
ChatContext *ctx = self->chatwin;
6763

68-
if (ctx->pos <= 0) {
64+
if (del_char_buf_bck(ctx) == -1) {
6965
beep();
7066
return;
7167
}
7268

7369
int cur_len = wcwidth(ctx->line[ctx->pos - 1]);
74-
75-
del_char_buf_bck(ctx);
76-
7770
int s_len = wcwidth(ctx->line[ctx->start - 1]);
78-
int cdiff = s_len - cur_len;
7971

80-
if (ctx->start && (x >= mx_x - cur_len)) {
81-
ctx->start = MAX(0, ctx->start - 1 + cdiff);
82-
wmove(self->window, y, wcswidth(&ctx->line[ctx->start], mx_x));
83-
} else if (ctx->start && (ctx->pos == ctx->len)) {
72+
if (ctx->start && (x >= mx_x - cur_len))
73+
ctx->start = MAX(0, ctx->start - 1 + (s_len - cur_len));
74+
else if (ctx->start && (ctx->pos == ctx->len))
8475
ctx->start = MAX(0, ctx->start - cur_len);
85-
wmove(self->window, y, wcswidth(&ctx->line[ctx->start], mx_x));
86-
} else if (ctx->start) {
76+
else if (ctx->start)
8777
ctx->start = MAX(0, ctx->start - cur_len);
88-
} else {
89-
wmove(self->window, y, x - cur_len);
90-
}
9178
}
9279

9380
/* delete a char via delete key from input field and buffer */
9481
static void input_delete(ToxWindow *self)
9582
{
96-
ChatContext *ctx = self->chatwin;
97-
98-
if (ctx->pos >= ctx->len) {
83+
if (del_char_buf_frnt(self->chatwin) == -1)
9984
beep();
100-
return;
101-
}
102-
103-
del_char_buf_frnt(ctx);
10485
}
10586

10687
/* deletes entire line before cursor from input field and buffer */
107-
static void input_discard(ToxWindow *self, int mx_y)
88+
static void input_discard(ToxWindow *self)
10889
{
109-
ChatContext *ctx = self->chatwin;
110-
111-
if (ctx->pos <= 0) {
90+
if (discard_buf(self->chatwin) == -1)
11291
beep();
113-
return;
114-
}
115-
116-
discard_buf(ctx);
117-
wmove(self->window, mx_y - CURS_Y_OFFSET, 0);
11892
}
11993

12094
/* deletes entire line after cursor from input field and buffer */
12195
static void input_kill(ChatContext *ctx)
12296
{
123-
if (ctx->pos != ctx->len) {
124-
kill_buf(ctx);
97+
if (kill_buf(ctx) == -1)
98+
beep();
99+
}
100+
101+
static void input_yank(ToxWindow *self, int x, int mx_x)
102+
{
103+
ChatContext *ctx = self->chatwin;
104+
105+
if (yank_buf(ctx) == -1) {
106+
beep();
125107
return;
126108
}
127109

128-
beep();
110+
int yank_cols = MAX(0, wcswidth(ctx->yank, ctx->yank_len));
111+
112+
if (x + yank_cols >= mx_x) {
113+
int rmdr = MAX(0, (x + yank_cols) - mx_x);
114+
int s_len = wcswidth(&ctx->line[ctx->start], rmdr);
115+
ctx->start += s_len + 1;
116+
}
129117
}
130118

131119
/* moves cursor/line position to end of line in input field and buffer */
132-
static void input_mv_end(ToxWindow *self, int x, int y, int mx_x, int mx_y)
120+
static void input_mv_end(ToxWindow *self, int y, int mx_x)
133121
{
134122
ChatContext *ctx = self->chatwin;
135123

136124
ctx->pos = ctx->len;
137125

138126
int wlen = wcswidth(ctx->line, sizeof(ctx->line));
139127
ctx->start = MAX(0, 1 + (mx_x * (wlen / mx_x) - mx_x) + (wlen % mx_x));
140-
141-
int llen = wcswidth(&ctx->line[ctx->start], mx_x);
142-
int new_x = wlen >= mx_x ? mx_x - 1 : llen;
143-
144-
wmove(self->window, y, new_x);
145128
}
146129

147130
/* moves cursor/line position to start of line in input field and buffer */
148-
static void input_mv_home(ToxWindow *self, int mx_y)
131+
static void input_mv_home(ToxWindow *self)
149132
{
150133
ChatContext *ctx = self->chatwin;
151134

152-
if (ctx->pos <= 0) {
153-
beep();
135+
if (ctx->pos <= 0)
154136
return;
155-
}
156137

157138
ctx->pos = 0;
158139
ctx->start = 0;
159-
wmove(self->window, mx_y - CURS_Y_OFFSET, 0);
160140
}
161141

162142
/* moves cursor/line position left in input field and buffer */
163-
static void input_mv_left(ToxWindow *self, int x, int y, int mx_x, int mx_y)
143+
static void input_mv_left(ToxWindow *self, int x, int mx_x)
164144
{
165145
ChatContext *ctx = self->chatwin;
166146

167-
if (ctx->pos <= 0) {
168-
beep();
147+
if (ctx->pos <= 0)
169148
return;
170-
}
171149

172150
int cur_len = wcwidth(ctx->line[ctx->pos - 1]);
173151

174152
--ctx->pos;
175153

176154
int s_len = wcwidth(ctx->line[ctx->start - 1]);
177-
int cdiff = s_len - cur_len;
178155

179-
if (ctx->start && (x >= mx_x - cur_len)) {
180-
ctx->start = MAX(0, ctx->start - 1 + cdiff);
181-
wmove(self->window, y, wcswidth(&ctx->line[ctx->start], mx_x));
182-
} else if (ctx->start && (ctx->pos == ctx->len)) {
156+
if (ctx->start && (x >= mx_x - cur_len))
157+
ctx->start = MAX(0, ctx->start - 1 + (s_len - cur_len));
158+
else if (ctx->start && (ctx->pos == ctx->len))
183159
ctx->start = MAX(0, ctx->start - cur_len);
184-
wmove(self->window, y, wcswidth(&ctx->line[ctx->start], mx_x));
185-
} else if (ctx->start) {
160+
else if (ctx->start)
186161
ctx->start = MAX(0, ctx->start - cur_len);
187-
} else {
188-
wmove(self->window, y, x - cur_len);
189-
}
190162
}
191163

192164
/* moves cursor/line position right in input field and buffer */
193-
static void input_mv_right(ToxWindow *self, int x, int y, int mx_x, int mx_y)
165+
static void input_mv_right(ToxWindow *self, int x, int mx_x)
194166
{
195167
ChatContext *ctx = self->chatwin;
196168

197-
if (ctx->pos >= ctx->len) {
198-
beep();
169+
if (ctx->pos >= ctx->len)
199170
return;
200-
}
201171

202172
++ctx->pos;
203173

204-
int cur_len = MAX(1, wcwidth(ctx->line[ctx->pos - 1]));
174+
int cur_len = wcwidth(ctx->line[ctx->pos - 1]);
205175

206176
if (x + cur_len >= mx_x) {
207177
int s_len = wcwidth(ctx->line[ctx->start]);
208-
int cdiff = cur_len - s_len;
209-
ctx->start += 1 + MAX(0, cdiff);
210-
wmove(self->window, y, wcswidth(&ctx->line[ctx->start], mx_x));
211-
} else {
212-
wmove(self->window, y, x + cur_len);
178+
ctx->start += 1 + MAX(0, cur_len - s_len);
213179
}
214180
}
215181

216182
/* puts a line history item in input field and buffer */
217-
static void input_history(ToxWindow *self, wint_t key, int x, int y, int mx_x, int mx_y)
183+
static void input_history(ToxWindow *self, wint_t key, int mx_x)
218184
{
219185
ChatContext *ctx = self->chatwin;
220186

221187
fetch_hist_item(ctx, key);
222188
ctx->start = mx_x * (ctx->len / mx_x);
223-
input_mv_end(self, x, y, mx_x, mx_y);
224189
}
225190

226191
/* Handles non-printable input keys that behave the same for all types of chat windows.
@@ -232,42 +197,46 @@ bool input_handle(ToxWindow *self, wint_t key, int x, int y, int mx_x, int mx_y)
232197
switch (key) {
233198
case 0x7f:
234199
case KEY_BACKSPACE:
235-
input_backspace(self, x, y, mx_x, mx_y);
200+
input_backspace(self, x, mx_x);
236201
break;
237202

238203
case KEY_DC:
239204
input_delete(self);
240205
break;
241206

242207
case T_KEY_DISCARD:
243-
input_discard(self, mx_y);
208+
input_discard(self);
244209
break;
245210

246211
case T_KEY_KILL:
247212
input_kill(self->chatwin);
248213
break;
249214

215+
case T_KEY_C_Y:
216+
input_yank(self, x, mx_x);
217+
break;
218+
250219
case KEY_HOME:
251220
case T_KEY_C_A:
252-
input_mv_home(self, mx_y);
221+
input_mv_home(self);
253222
break;
254223

255224
case KEY_END:
256225
case T_KEY_C_E:
257-
input_mv_end(self, x, y, mx_x, mx_y);
226+
input_mv_end(self, y, mx_x);
258227
break;
259228

260229
case KEY_LEFT:
261-
input_mv_left(self, x, y, mx_x, mx_y);
230+
input_mv_left(self, x, mx_x);
262231
break;
263232

264233
case KEY_RIGHT:
265-
input_mv_right(self, x, y, mx_x, mx_y);
234+
input_mv_right(self, x, mx_x);
266235
break;
267236

268237
case KEY_UP:
269238
case KEY_DOWN:
270-
input_history(self, key, x, y, mx_x, mx_y);
239+
input_history(self, key, mx_x);
271240
break;
272241

273242
default:

src/prompt.c

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,10 @@
2020
*
2121
*/
2222

23+
#ifndef _GNU_SOURCE
24+
#define _GNU_SOURCE /* needed for wcswidth() */
25+
#endif
26+
2327
#include <stdlib.h>
2428
#include <string.h>
2529
#include <wchar.h>
@@ -275,7 +279,7 @@ static void prompt_onDraw(ToxWindow *self, Tox *m)
275279
getyx(self->window, y, x);
276280
(void) x;
277281

278-
int new_x = ctx->start ? x2 - 1 : ctx->pos;
282+
int new_x = ctx->start ? x2 - 1 : wcswidth(ctx->line, ctx->pos);
279283
wmove(self->window, y + 1, new_x);
280284

281285
wrefresh(self->window);

src/toxic.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@
6262
#define T_KEY_C_V 0x16 /* ctrl-v */
6363
#define T_KEY_C_F 0x06 /* ctrl-f */
6464
#define T_KEY_C_H 0x08 /* ctrl-h */
65+
#define T_KEY_C_Y 0x19 /* ctrl-y */
6566

6667
typedef enum _FATAL_ERRS {
6768
FATALERR_MEMORY = -1, /* malloc() or calloc() failed */

0 commit comments

Comments
 (0)