/
glue.c
195 lines (167 loc) · 3.88 KB
/
glue.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
/* Miscellaneous functions
Copyright (c) 2008 Free Software Foundation, Inc.
Copyright (c) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004 Sandro Sigala.
This file is part of GNU Zile.
GNU Zile is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3, or (at your option)
any later version.
GNU Zile is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU Zile; see the file COPYING. If not, write to the
Free Software Foundation, Fifth Floor, 51 Franklin Street, Boston,
MA 02111-1301, USA. */
#include "config.h"
#include <assert.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "zile.h"
#include "extern.h"
/*
* Ring the bell if ring-bell is set.
*/
void
ding (void)
{
if (thisflag & FLAG_DEFINING_MACRO)
cancel_kbd_macro ();
if (get_variable_bool ("ring-bell"))
term_beep ();
}
#define MAX_KEY_BUF 16
static int key_buf[MAX_KEY_BUF];
static int *keyp = key_buf;
static size_t _last_key;
/* Return last key pressed */
size_t
lastkey (void)
{
return _last_key;
}
/*
* Get a keystroke, waiting for up to timeout 10ths of a second if
* mode contains GETKEY_DELAYED, and translating it into a
* keycode unless mode contains GETKEY_UNFILTERED.
*/
size_t
xgetkey (int mode, size_t timeout)
{
if (keyp > key_buf)
_last_key = *--keyp;
else
_last_key = term_xgetkey (mode, timeout);
if (thisflag & FLAG_DEFINING_MACRO)
add_key_to_cmd (_last_key);
return _last_key;
}
/*
* Wait for a keystroke indefinitely, and return the
* corresponding keycode.
*/
size_t
getkey (void)
{
return xgetkey (0, 0);
}
/*
* Wait for timeout 10ths if a second or until a key is pressed.
* The key is then available with [x]getkey().
*/
void
waitkey (size_t timeout)
{
ungetkey (xgetkey (GETKEY_DELAYED, timeout));
}
void
ungetkey (size_t key)
{
if (keyp < key_buf + MAX_KEY_BUF && key != KBD_NOKEY)
*keyp++ = key;
}
/*
* Copy a region of text into an allocated buffer.
*/
char *
copy_text_block (size_t startn, size_t starto, size_t size)
{
char *buf, *dp;
size_t max_size, n, i;
Line *lp;
max_size = 10;
dp = buf = (char *) xzalloc (max_size);
lp = cur_bp->pt.p;
n = cur_bp->pt.n;
if (n > startn)
do
lp = lp->prev;
while (--n > startn);
else if (n < startn)
do
lp = lp->next;
while (++n < startn);
for (i = starto; dp - buf < (int) size;)
{
if (dp >= buf + max_size)
{
int save_off = dp - buf;
max_size += 10;
buf = (char *) xrealloc (buf, max_size);
dp = buf + save_off;
}
if (i < astr_len (lp->text))
*dp++ = *astr_char (lp->text, (ptrdiff_t) (i++));
else
{
*dp++ = '\n';
lp = lp->next;
i = 0;
}
}
return buf;
}
/*
* Return a string of maximum length `maxlen' beginning with a `...'
* sequence if a cut is need.
*/
astr
shorten_string (char *s, int maxlen)
{
astr as = astr_new ();
int len = strlen (s);
if (len <= maxlen)
astr_cpy_cstr (as, s);
else
{
astr_cpy_cstr (as, "...");
astr_cat_cstr (as, s + len - maxlen + 3);
}
return as;
}
/*
* Jump to the specified line number and offset.
*/
void
goto_point (Point pt)
{
if (cur_bp->pt.n > pt.n)
do
FUNCALL (previous_line);
while (cur_bp->pt.n > pt.n);
else if (cur_bp->pt.n < pt.n)
do
FUNCALL (next_line);
while (cur_bp->pt.n < pt.n);
if (cur_bp->pt.o > pt.o)
do
FUNCALL (backward_char);
while (cur_bp->pt.o > pt.o);
else if (cur_bp->pt.o < pt.o)
do
FUNCALL (forward_char);
while (cur_bp->pt.o < pt.o);
}