blob: d29c26dab3e63b7aac7652e2f795b1d640d925bd [file] [log] [blame]
Bram Moolenaaredf3f972016-08-29 22:49:24 +02001/* vi:set ts=8 sts=4 sw=4 noet:
Bram Moolenaar071d4272004-06-13 20:20:40 +00002 *
3 * VIM - Vi IMproved by Bram Moolenaar
4 *
5 * Do ":help uganda" in Vim to read copying and usage conditions.
6 * Do ":help credits" in Vim to see a list of people who contributed.
7 * See README.txt for an overview of the Vim source code.
8 */
9
10/*
11 * ui.c: functions that handle the user interface.
12 * 1. Keyboard input stuff, and a bit of windowing stuff. These are called
13 * before the machine specific stuff (mch_*) so that we can call the GUI
14 * stuff instead if the GUI is running.
Bram Moolenaar45fffdf2020-03-24 21:42:01 +010015 * 2. Input buffer stuff.
Bram Moolenaar071d4272004-06-13 20:20:40 +000016 */
17
18#include "vim.h"
19
20 void
Bram Moolenaar764b23c2016-01-30 21:10:09 +010021ui_write(char_u *s, int len)
Bram Moolenaar071d4272004-06-13 20:20:40 +000022{
23#ifdef FEAT_GUI
24 if (gui.in_use && !gui.dying && !gui.starting)
25 {
26 gui_write(s, len);
27 if (p_wd)
Bram Moolenaarc9e649a2017-12-18 18:14:47 +010028 gui_wait_for_chars(p_wd, typebuf.tb_change_cnt);
Bram Moolenaar071d4272004-06-13 20:20:40 +000029 return;
30 }
31#endif
32#ifndef NO_CONSOLE
Bram Moolenaare38eab22019-12-05 21:50:01 +010033 // Don't output anything in silent mode ("ex -s") unless 'verbose' set
Bram Moolenaar071d4272004-06-13 20:20:40 +000034 if (!(silent_mode && p_verbose == 0))
35 {
Bram Moolenaar4f974752019-02-17 17:44:42 +010036#if !defined(MSWIN)
Bram Moolenaar071d4272004-06-13 20:20:40 +000037 char_u *tofree = NULL;
38
39 if (output_conv.vc_type != CONV_NONE)
40 {
Bram Moolenaare38eab22019-12-05 21:50:01 +010041 // Convert characters from 'encoding' to 'termencoding'.
Bram Moolenaar071d4272004-06-13 20:20:40 +000042 tofree = string_convert(&output_conv, s, &len);
43 if (tofree != NULL)
44 s = tofree;
45 }
46#endif
47
48 mch_write(s, len);
49
Bram Moolenaar4f974752019-02-17 17:44:42 +010050# if !defined(MSWIN)
Bram Moolenaar071d4272004-06-13 20:20:40 +000051 if (output_conv.vc_type != CONV_NONE)
52 vim_free(tofree);
Bram Moolenaar264b74f2019-01-24 17:18:42 +010053# endif
Bram Moolenaar071d4272004-06-13 20:20:40 +000054 }
55#endif
56}
57
Bram Moolenaar4f974752019-02-17 17:44:42 +010058#if defined(UNIX) || defined(VMS) || defined(PROTO) || defined(MSWIN)
Bram Moolenaar071d4272004-06-13 20:20:40 +000059/*
60 * When executing an external program, there may be some typed characters that
61 * are not consumed by it. Give them back to ui_inchar() and they are stored
62 * here for the next call.
63 */
64static char_u *ta_str = NULL;
Bram Moolenaare38eab22019-12-05 21:50:01 +010065static int ta_off; // offset for next char to use when ta_str != NULL
66static int ta_len; // length of ta_str when it's not NULL
Bram Moolenaar071d4272004-06-13 20:20:40 +000067
68 void
Bram Moolenaar764b23c2016-01-30 21:10:09 +010069ui_inchar_undo(char_u *s, int len)
Bram Moolenaar071d4272004-06-13 20:20:40 +000070{
71 char_u *new;
72 int newlen;
73
74 newlen = len;
75 if (ta_str != NULL)
76 newlen += ta_len - ta_off;
77 new = alloc(newlen);
78 if (new != NULL)
79 {
80 if (ta_str != NULL)
81 {
82 mch_memmove(new, ta_str + ta_off, (size_t)(ta_len - ta_off));
83 mch_memmove(new + ta_len - ta_off, s, (size_t)len);
84 vim_free(ta_str);
85 }
86 else
87 mch_memmove(new, s, (size_t)len);
88 ta_str = new;
89 ta_len = newlen;
90 ta_off = 0;
91 }
92}
93#endif
94
95/*
Bram Moolenaarb6101cf2012-10-21 00:58:39 +020096 * ui_inchar(): low level input function.
Bram Moolenaar071d4272004-06-13 20:20:40 +000097 * Get characters from the keyboard.
98 * Return the number of characters that are available.
99 * If "wtime" == 0 do not wait for characters.
100 * If "wtime" == -1 wait forever for characters.
101 * If "wtime" > 0 wait "wtime" milliseconds for a character.
102 *
103 * "tb_change_cnt" is the value of typebuf.tb_change_cnt if "buf" points into
104 * it. When typebuf.tb_change_cnt changes (e.g., when a message is received
105 * from a remote client) "buf" can no longer be used. "tb_change_cnt" is NULL
106 * otherwise.
107 */
108 int
Bram Moolenaar764b23c2016-01-30 21:10:09 +0100109ui_inchar(
110 char_u *buf,
111 int maxlen,
Bram Moolenaare38eab22019-12-05 21:50:01 +0100112 long wtime, // don't use "time", MIPS cannot handle it
Bram Moolenaar764b23c2016-01-30 21:10:09 +0100113 int tb_change_cnt)
Bram Moolenaar071d4272004-06-13 20:20:40 +0000114{
115 int retval = 0;
116
117#if defined(FEAT_GUI) && (defined(UNIX) || defined(VMS))
118 /*
119 * Use the typeahead if there is any.
120 */
121 if (ta_str != NULL)
122 {
123 if (maxlen >= ta_len - ta_off)
124 {
125 mch_memmove(buf, ta_str + ta_off, (size_t)ta_len);
Bram Moolenaard23a8232018-02-10 18:45:26 +0100126 VIM_CLEAR(ta_str);
Bram Moolenaar071d4272004-06-13 20:20:40 +0000127 return ta_len;
128 }
129 mch_memmove(buf, ta_str + ta_off, (size_t)maxlen);
130 ta_off += maxlen;
131 return maxlen;
132 }
133#endif
134
Bram Moolenaar05159a02005-02-26 23:04:13 +0000135#ifdef FEAT_PROFILE
Bram Moolenaarb3656ed2006-03-20 21:59:49 +0000136 if (do_profiling == PROF_YES && wtime != 0)
Bram Moolenaar05159a02005-02-26 23:04:13 +0000137 prof_inchar_enter();
138#endif
139
Bram Moolenaar071d4272004-06-13 20:20:40 +0000140#ifdef NO_CONSOLE_INPUT
Bram Moolenaare38eab22019-12-05 21:50:01 +0100141 // Don't wait for character input when the window hasn't been opened yet.
142 // Do try reading, this works when redirecting stdin from a file.
143 // Must return something, otherwise we'll loop forever. If we run into
144 // this very often we probably got stuck, exit Vim.
Bram Moolenaar071d4272004-06-13 20:20:40 +0000145 if (no_console_input())
146 {
147 static int count = 0;
148
149# ifndef NO_CONSOLE
Bram Moolenaar13410242018-11-26 21:19:11 +0100150 retval = mch_inchar(buf, maxlen, wtime, tb_change_cnt);
Bram Moolenaar43b604c2005-03-22 23:06:55 +0000151 if (retval > 0 || typebuf_changed(tb_change_cnt) || wtime >= 0)
Bram Moolenaar05159a02005-02-26 23:04:13 +0000152 goto theend;
Bram Moolenaar071d4272004-06-13 20:20:40 +0000153# endif
154 if (wtime == -1 && ++count == 1000)
155 read_error_exit();
156 buf[0] = CAR;
Bram Moolenaar05159a02005-02-26 23:04:13 +0000157 retval = 1;
158 goto theend;
Bram Moolenaar071d4272004-06-13 20:20:40 +0000159 }
160#endif
161
Bram Moolenaare38eab22019-12-05 21:50:01 +0100162 // If we are going to wait for some time or block...
Bram Moolenaarc8da3112007-03-08 12:36:46 +0000163 if (wtime == -1 || wtime > 100L)
164 {
Bram Moolenaare38eab22019-12-05 21:50:01 +0100165 // ... allow signals to kill us.
Bram Moolenaarc8da3112007-03-08 12:36:46 +0000166 (void)vim_handle_signal(SIGNAL_UNBLOCK);
167
Bram Moolenaare38eab22019-12-05 21:50:01 +0100168 // ... there is no need for CTRL-C to interrupt something, don't let
169 // it set got_int when it was mapped.
Bram Moolenaar50008692015-01-14 16:08:32 +0100170 if ((mapped_ctrl_c | curbuf->b_mapped_ctrl_c) & get_real_state())
Bram Moolenaarc8da3112007-03-08 12:36:46 +0000171 ctrl_c_interrupts = FALSE;
172 }
Bram Moolenaar071d4272004-06-13 20:20:40 +0000173
Bram Moolenaare40b9d42019-01-27 16:55:47 +0100174 /*
175 * Here we call gui_inchar() or mch_inchar(), the GUI or machine-dependent
176 * input function. The functionality they implement is like this:
177 *
178 * while (not timed out)
179 * {
180 * handle-resize;
181 * parse-queued-messages;
182 * if (waited for 'updatetime')
183 * trigger-cursorhold;
184 * ui_wait_for_chars_or_timer()
185 * if (character available)
186 * break;
187 * }
188 *
189 * ui_wait_for_chars_or_timer() does:
190 *
191 * while (not timed out)
192 * {
193 * if (any-timer-triggered)
194 * invoke-timer-callback;
195 * wait-for-character();
196 * if (character available)
197 * break;
198 * }
199 *
200 * wait-for-character() does:
201 * while (not timed out)
202 * {
203 * Wait for event;
204 * if (something on channel)
205 * read/write channel;
206 * else if (resized)
207 * handle_resize();
208 * else if (system event)
209 * deal-with-system-event;
210 * else if (character available)
211 * break;
212 * }
213 *
214 */
215
Bram Moolenaar071d4272004-06-13 20:20:40 +0000216#ifdef FEAT_GUI
217 if (gui.in_use)
Bram Moolenaarc9e649a2017-12-18 18:14:47 +0100218 retval = gui_inchar(buf, maxlen, wtime, tb_change_cnt);
Bram Moolenaar071d4272004-06-13 20:20:40 +0000219#endif
220#ifndef NO_CONSOLE
221# ifdef FEAT_GUI
222 else
223# endif
224 retval = mch_inchar(buf, maxlen, wtime, tb_change_cnt);
225#endif
226
Bram Moolenaarc8da3112007-03-08 12:36:46 +0000227 if (wtime == -1 || wtime > 100L)
Bram Moolenaare38eab22019-12-05 21:50:01 +0100228 // block SIGHUP et al.
Bram Moolenaarc8da3112007-03-08 12:36:46 +0000229 (void)vim_handle_signal(SIGNAL_BLOCK);
230
Bram Moolenaar071d4272004-06-13 20:20:40 +0000231 ctrl_c_interrupts = TRUE;
232
Bram Moolenaar05159a02005-02-26 23:04:13 +0000233#ifdef NO_CONSOLE_INPUT
234theend:
235#endif
236#ifdef FEAT_PROFILE
Bram Moolenaarb3656ed2006-03-20 21:59:49 +0000237 if (do_profiling == PROF_YES && wtime != 0)
Bram Moolenaar05159a02005-02-26 23:04:13 +0000238 prof_inchar_exit();
239#endif
Bram Moolenaar071d4272004-06-13 20:20:40 +0000240 return retval;
241}
242
Bram Moolenaar95f0b6e2019-12-15 12:54:18 +0100243#if defined(UNIX) || defined(VMS) || defined(FEAT_GUI) || defined(PROTO)
Bram Moolenaare40b9d42019-01-27 16:55:47 +0100244/*
245 * Common code for mch_inchar() and gui_inchar(): Wait for a while or
246 * indefinitely until characters are available, dealing with timers and
247 * messages on channels.
248 *
249 * "buf" may be NULL if the available characters are not to be returned, only
250 * check if they are available.
251 *
252 * Return the number of characters that are available.
253 * If "wtime" == 0 do not wait for characters.
254 * If "wtime" == n wait a short time for characters.
255 * If "wtime" == -1 wait forever for characters.
256 */
257 int
258inchar_loop(
259 char_u *buf,
260 int maxlen,
261 long wtime, // don't use "time", MIPS cannot handle it
262 int tb_change_cnt,
263 int (*wait_func)(long wtime, int *interrupted, int ignore_input),
264 int (*resize_func)(int check_only))
265{
266 int len;
267 int interrupted = FALSE;
Bram Moolenaar12dfc9e2019-01-28 22:32:58 +0100268 int did_call_wait_func = FALSE;
Bram Moolenaare40b9d42019-01-27 16:55:47 +0100269 int did_start_blocking = FALSE;
270 long wait_time;
271 long elapsed_time = 0;
272#ifdef ELAPSED_FUNC
273 elapsed_T start_tv;
274
275 ELAPSED_INIT(start_tv);
276#endif
277
Bram Moolenaare38eab22019-12-05 21:50:01 +0100278 // repeat until we got a character or waited long enough
Bram Moolenaare40b9d42019-01-27 16:55:47 +0100279 for (;;)
280 {
Bram Moolenaare38eab22019-12-05 21:50:01 +0100281 // Check if window changed size while we were busy, perhaps the ":set
282 // columns=99" command was used.
Bram Moolenaare40b9d42019-01-27 16:55:47 +0100283 if (resize_func != NULL)
284 resize_func(FALSE);
285
286#ifdef MESSAGE_QUEUE
287 // Only process messages when waiting.
288 if (wtime != 0)
289 {
290 parse_queued_messages();
291 // If input was put directly in typeahead buffer bail out here.
292 if (typebuf_changed(tb_change_cnt))
293 return 0;
294 }
295#endif
296 if (wtime < 0 && did_start_blocking)
297 // blocking and already waited for p_ut
298 wait_time = -1;
299 else
300 {
301 if (wtime >= 0)
302 wait_time = wtime;
303 else
304 // going to block after p_ut
305 wait_time = p_ut;
306#ifdef ELAPSED_FUNC
307 elapsed_time = ELAPSED_FUNC(start_tv);
308#endif
309 wait_time -= elapsed_time;
Bram Moolenaar12dfc9e2019-01-28 22:32:58 +0100310
311 // If the waiting time is now zero or less, we timed out. However,
312 // loop at least once to check for characters and events. Matters
313 // when "wtime" is zero.
314 if (wait_time <= 0 && did_call_wait_func)
Bram Moolenaare40b9d42019-01-27 16:55:47 +0100315 {
316 if (wtime >= 0)
317 // no character available within "wtime"
318 return 0;
319
320 // No character available within 'updatetime'.
321 did_start_blocking = TRUE;
322 if (trigger_cursorhold() && maxlen >= 3
323 && !typebuf_changed(tb_change_cnt))
324 {
325 // Put K_CURSORHOLD in the input buffer or return it.
326 if (buf == NULL)
327 {
328 char_u ibuf[3];
329
330 ibuf[0] = CSI;
331 ibuf[1] = KS_EXTRA;
332 ibuf[2] = (int)KE_CURSORHOLD;
333 add_to_input_buf(ibuf, 3);
334 }
335 else
336 {
337 buf[0] = K_SPECIAL;
338 buf[1] = KS_EXTRA;
339 buf[2] = (int)KE_CURSORHOLD;
340 }
341 return 3;
342 }
343
344 // There is no character available within 'updatetime' seconds:
345 // flush all the swap files to disk. Also done when
346 // interrupted by SIGWINCH.
347 before_blocking();
348 continue;
349 }
350 }
351
352#ifdef FEAT_JOB_CHANNEL
353 if (wait_time < 0 || wait_time > 100L)
354 {
355 // Checking if a job ended requires polling. Do this at least
356 // every 100 msec.
357 if (has_pending_job())
358 wait_time = 100L;
359
360 // If there is readahead then parse_queued_messages() timed out and
361 // we should call it again soon.
362 if (channel_any_readahead())
363 wait_time = 10L;
364 }
365#endif
366#ifdef FEAT_BEVAL_GUI
367 if (p_beval && wait_time > 100L)
368 // The 'balloonexpr' may indirectly invoke a callback while waiting
369 // for a character, need to check often.
370 wait_time = 100L;
371#endif
372
373 // Wait for a character to be typed or another event, such as the winch
374 // signal or an event on the monitored file descriptors.
Bram Moolenaar12dfc9e2019-01-28 22:32:58 +0100375 did_call_wait_func = TRUE;
Bram Moolenaare40b9d42019-01-27 16:55:47 +0100376 if (wait_func(wait_time, &interrupted, FALSE))
377 {
378 // If input was put directly in typeahead buffer bail out here.
379 if (typebuf_changed(tb_change_cnt))
380 return 0;
381
382 // We might have something to return now.
383 if (buf == NULL)
384 // "buf" is NULL, we were just waiting, not actually getting
385 // input.
386 return input_available();
387
388 len = read_from_input_buf(buf, (long)maxlen);
389 if (len > 0)
390 return len;
391 continue;
392 }
393 // Timed out or interrupted with no character available.
394
395#ifndef ELAPSED_FUNC
396 // estimate the elapsed time
397 elapsed_time += wait_time;
398#endif
399
400 if ((resize_func != NULL && resize_func(TRUE))
Bram Moolenaar3e9d4d82019-01-27 17:08:40 +0100401#if defined(FEAT_CLIENTSERVER) && defined(UNIX)
Bram Moolenaare40b9d42019-01-27 16:55:47 +0100402 || server_waiting()
403#endif
404#ifdef MESSAGE_QUEUE
405 || interrupted
406#endif
407 || wait_time > 0
408 || (wtime < 0 && !did_start_blocking))
409 // no character available, but something to be done, keep going
410 continue;
411
412 // no character available or interrupted, return zero
413 break;
414 }
415 return 0;
416}
417#endif
418
Bram Moolenaarc46af532019-01-09 22:24:49 +0100419#if defined(FEAT_TIMERS) || defined(PROTO)
Bram Moolenaarc9e649a2017-12-18 18:14:47 +0100420/*
421 * Wait for a timer to fire or "wait_func" to return non-zero.
422 * Returns OK when something was read.
423 * Returns FAIL when it timed out or was interrupted.
424 */
425 int
426ui_wait_for_chars_or_timer(
427 long wtime,
428 int (*wait_func)(long wtime, int *interrupted, int ignore_input),
429 int *interrupted,
430 int ignore_input)
431{
432 int due_time;
433 long remaining = wtime;
434 int tb_change_cnt = typebuf.tb_change_cnt;
Bram Moolenaarc46af532019-01-09 22:24:49 +0100435# ifdef FEAT_JOB_CHANNEL
Bram Moolenaare299bbd2019-01-17 14:12:02 +0100436 int brief_wait = FALSE;
Bram Moolenaarc46af532019-01-09 22:24:49 +0100437# endif
Bram Moolenaarc9e649a2017-12-18 18:14:47 +0100438
Bram Moolenaarc46af532019-01-09 22:24:49 +0100439 // When waiting very briefly don't trigger timers.
Bram Moolenaarc9e649a2017-12-18 18:14:47 +0100440 if (wtime >= 0 && wtime < 10L)
441 return wait_func(wtime, NULL, ignore_input);
442
443 while (wtime < 0 || remaining > 0)
444 {
Bram Moolenaarc46af532019-01-09 22:24:49 +0100445 // Trigger timers and then get the time in wtime until the next one is
446 // due. Wait up to that time.
Bram Moolenaarc9e649a2017-12-18 18:14:47 +0100447 due_time = check_due_timer();
448 if (typebuf.tb_change_cnt != tb_change_cnt)
449 {
Bram Moolenaare38eab22019-12-05 21:50:01 +0100450 // timer may have used feedkeys()
Bram Moolenaarc9e649a2017-12-18 18:14:47 +0100451 return FAIL;
452 }
453 if (due_time <= 0 || (wtime > 0 && due_time > remaining))
454 due_time = remaining;
Bram Moolenaar28e67e02019-08-15 23:05:49 +0200455# if defined(FEAT_JOB_CHANNEL) || defined(FEAT_SOUND_CANBERRA)
456 if ((due_time < 0 || due_time > 10L) && (
457# if defined(FEAT_JOB_CHANNEL)
458 (
459# if defined(FEAT_GUI)
460 !gui.in_use &&
461# endif
462 (has_pending_job() || channel_any_readahead()))
463# ifdef FEAT_SOUND_CANBERRA
464 ||
465# endif
Bram Moolenaarc46af532019-01-09 22:24:49 +0100466# endif
Bram Moolenaar28e67e02019-08-15 23:05:49 +0200467# ifdef FEAT_SOUND_CANBERRA
468 has_any_sound_callback()
469# endif
470 ))
Bram Moolenaarc46af532019-01-09 22:24:49 +0100471 {
472 // There is a pending job or channel, should return soon in order
473 // to handle them ASAP. Do check for input briefly.
474 due_time = 10L;
Bram Moolenaar6cdce2a2019-09-07 23:25:09 +0200475# ifdef FEAT_JOB_CHANNEL
Bram Moolenaarc46af532019-01-09 22:24:49 +0100476 brief_wait = TRUE;
Bram Moolenaar6cdce2a2019-09-07 23:25:09 +0200477# endif
Bram Moolenaarc46af532019-01-09 22:24:49 +0100478 }
479# endif
Bram Moolenaarc9e649a2017-12-18 18:14:47 +0100480 if (wait_func(due_time, interrupted, ignore_input))
481 return OK;
Bram Moolenaarc46af532019-01-09 22:24:49 +0100482 if ((interrupted != NULL && *interrupted)
483# ifdef FEAT_JOB_CHANNEL
484 || brief_wait
485# endif
486 )
487 // Nothing available, but need to return so that side effects get
488 // handled, such as handling a message on a channel.
Bram Moolenaara338adc2018-01-31 20:51:47 +0100489 return FAIL;
Bram Moolenaarc9e649a2017-12-18 18:14:47 +0100490 if (wtime > 0)
491 remaining -= due_time;
492 }
493 return FAIL;
494}
495#endif
496
Bram Moolenaar071d4272004-06-13 20:20:40 +0000497/*
Bram Moolenaarc46af532019-01-09 22:24:49 +0100498 * Return non-zero if a character is available.
Bram Moolenaar071d4272004-06-13 20:20:40 +0000499 */
500 int
Bram Moolenaar764b23c2016-01-30 21:10:09 +0100501ui_char_avail(void)
Bram Moolenaar071d4272004-06-13 20:20:40 +0000502{
503#ifdef FEAT_GUI
504 if (gui.in_use)
505 {
506 gui_mch_update();
507 return input_available();
508 }
509#endif
510#ifndef NO_CONSOLE
511# ifdef NO_CONSOLE_INPUT
512 if (no_console_input())
513 return 0;
514# endif
515 return mch_char_avail();
516#else
517 return 0;
518#endif
519}
520
521/*
522 * Delay for the given number of milliseconds. If ignoreinput is FALSE then we
523 * cancel the delay if a key is hit.
524 */
525 void
Bram Moolenaarb340bae2020-06-15 19:51:56 +0200526ui_delay(long msec_arg, int ignoreinput)
Bram Moolenaar071d4272004-06-13 20:20:40 +0000527{
Bram Moolenaarb340bae2020-06-15 19:51:56 +0200528 long msec = msec_arg;
529
530#ifdef FEAT_EVAL
531 if (ui_delay_for_testing > 0)
532 msec = ui_delay_for_testing;
533#endif
Bram Moolenaareda1da02019-11-17 17:06:33 +0100534#ifdef FEAT_JOB_CHANNEL
535 ch_log(NULL, "ui_delay(%ld)", msec);
536#endif
Bram Moolenaar071d4272004-06-13 20:20:40 +0000537#ifdef FEAT_GUI
538 if (gui.in_use && !ignoreinput)
Bram Moolenaarc9e649a2017-12-18 18:14:47 +0100539 gui_wait_for_chars(msec, typebuf.tb_change_cnt);
Bram Moolenaar071d4272004-06-13 20:20:40 +0000540 else
541#endif
Bram Moolenaar0981c872020-08-23 14:28:37 +0200542 mch_delay(msec, ignoreinput ? MCH_DELAY_IGNOREINPUT : 0);
Bram Moolenaar071d4272004-06-13 20:20:40 +0000543}
544
545/*
546 * If the machine has job control, use it to suspend the program,
547 * otherwise fake it by starting a new shell.
548 * When running the GUI iconify the window.
549 */
550 void
Bram Moolenaar764b23c2016-01-30 21:10:09 +0100551ui_suspend(void)
Bram Moolenaar071d4272004-06-13 20:20:40 +0000552{
553#ifdef FEAT_GUI
554 if (gui.in_use)
555 {
556 gui_mch_iconify();
557 return;
558 }
559#endif
560 mch_suspend();
561}
562
Bram Moolenaar041c7102020-05-30 18:14:57 +0200563#if !defined(UNIX) || !defined(SIGTSTP) || defined(PROTO)
Bram Moolenaar071d4272004-06-13 20:20:40 +0000564/*
565 * When the OS can't really suspend, call this function to start a shell.
566 * This is never called in the GUI.
567 */
568 void
Bram Moolenaar764b23c2016-01-30 21:10:09 +0100569suspend_shell(void)
Bram Moolenaar071d4272004-06-13 20:20:40 +0000570{
571 if (*p_sh == NUL)
Bram Moolenaarf9e3e092019-01-13 23:38:42 +0100572 emsg(_(e_shellempty));
Bram Moolenaar071d4272004-06-13 20:20:40 +0000573 else
574 {
Bram Moolenaar32526b32019-01-19 17:43:09 +0100575 msg_puts(_("new shell started\n"));
Bram Moolenaar071d4272004-06-13 20:20:40 +0000576 do_shell(NULL, 0);
577 }
578}
579#endif
580
581/*
582 * Try to get the current Vim shell size. Put the result in Rows and Columns.
583 * Use the new sizes as defaults for 'columns' and 'lines'.
584 * Return OK when size could be determined, FAIL otherwise.
585 */
586 int
Bram Moolenaar764b23c2016-01-30 21:10:09 +0100587ui_get_shellsize(void)
Bram Moolenaar071d4272004-06-13 20:20:40 +0000588{
589 int retval;
590
591#ifdef FEAT_GUI
592 if (gui.in_use)
593 retval = gui_get_shellsize();
594 else
595#endif
596 retval = mch_get_shellsize();
597
598 check_shellsize();
599
Bram Moolenaare38eab22019-12-05 21:50:01 +0100600 // adjust the default for 'lines' and 'columns'
Bram Moolenaar071d4272004-06-13 20:20:40 +0000601 if (retval == OK)
602 {
603 set_number_default("lines", Rows);
604 set_number_default("columns", Columns);
605 }
606 return retval;
607}
608
609/*
610 * Set the size of the Vim shell according to Rows and Columns, if possible.
611 * The gui_set_shellsize() or mch_set_shellsize() function will try to set the
612 * new size. If this is not possible, it will adjust Rows and Columns.
613 */
Bram Moolenaar071d4272004-06-13 20:20:40 +0000614 void
Bram Moolenaar764b23c2016-01-30 21:10:09 +0100615ui_set_shellsize(
Bram Moolenaare38eab22019-12-05 21:50:01 +0100616 int mustset UNUSED) // set by the user
Bram Moolenaar071d4272004-06-13 20:20:40 +0000617{
618#ifdef FEAT_GUI
619 if (gui.in_use)
Bram Moolenaar8968a312013-07-03 16:58:44 +0200620 gui_set_shellsize(mustset, TRUE, RESIZE_BOTH);
Bram Moolenaar071d4272004-06-13 20:20:40 +0000621 else
622#endif
623 mch_set_shellsize();
624}
625
626/*
627 * Called when Rows and/or Columns changed. Adjust scroll region and mouse
628 * region.
629 */
630 void
Bram Moolenaar764b23c2016-01-30 21:10:09 +0100631ui_new_shellsize(void)
Bram Moolenaar071d4272004-06-13 20:20:40 +0000632{
633 if (full_screen && !exiting)
634 {
635#ifdef FEAT_GUI
636 if (gui.in_use)
637 gui_new_shellsize();
638 else
639#endif
640 mch_new_shellsize();
641 }
642}
643
Bram Moolenaar6bc93052019-04-06 20:00:19 +0200644#if ((defined(FEAT_EVAL) || defined(FEAT_TERMINAL)) \
Bram Moolenaar3d3f2172019-04-06 17:56:05 +0200645 && (defined(FEAT_GUI) \
Bram Moolenaar16c34c32019-04-06 22:01:24 +0200646 || defined(MSWIN) \
Bram Moolenaar3d3f2172019-04-06 17:56:05 +0200647 || (defined(HAVE_TGETENT) && defined(FEAT_TERMRESPONSE)))) \
Bram Moolenaarfa1e90c2019-04-06 17:47:40 +0200648 || defined(PROTO)
649/*
650 * Get the window position in pixels, if possible.
651 * Return FAIL when not possible.
652 */
653 int
Bram Moolenaarbd67aac2019-09-21 23:09:04 +0200654ui_get_winpos(int *x, int *y, varnumber_T timeout UNUSED)
Bram Moolenaarfa1e90c2019-04-06 17:47:40 +0200655{
656# ifdef FEAT_GUI
657 if (gui.in_use)
658 return gui_mch_get_winpos(x, y);
659# endif
Bram Moolenaarafde13b2019-04-28 19:46:49 +0200660# if defined(MSWIN) && (!defined(FEAT_GUI) || defined(VIMDLL))
Bram Moolenaar16c34c32019-04-06 22:01:24 +0200661 return mch_get_winpos(x, y);
Bram Moolenaar6bc93052019-04-06 20:00:19 +0200662# else
Bram Moolenaar16c34c32019-04-06 22:01:24 +0200663# if defined(HAVE_TGETENT) && defined(FEAT_TERMRESPONSE)
664 return term_get_winpos(x, y, timeout);
665# else
Bram Moolenaar6bc93052019-04-06 20:00:19 +0200666 return FAIL;
Bram Moolenaar16c34c32019-04-06 22:01:24 +0200667# endif
Bram Moolenaarfa1e90c2019-04-06 17:47:40 +0200668# endif
669}
670#endif
671
Bram Moolenaar071d4272004-06-13 20:20:40 +0000672 void
Bram Moolenaar764b23c2016-01-30 21:10:09 +0100673ui_breakcheck(void)
Bram Moolenaar071d4272004-06-13 20:20:40 +0000674{
Bram Moolenaarb9c31e72016-09-29 15:18:57 +0200675 ui_breakcheck_force(FALSE);
676}
677
678/*
679 * When "force" is true also check when the terminal is not in raw mode.
680 * This is useful to read input on channels.
681 */
682 void
683ui_breakcheck_force(int force)
684{
Bram Moolenaar48d23bb2018-11-20 02:42:43 +0100685 static int recursive = FALSE;
686 int save_updating_screen = updating_screen;
Bram Moolenaare3caa112017-01-31 22:07:42 +0100687
Bram Moolenaar48d23bb2018-11-20 02:42:43 +0100688 // We could be called recursively if stderr is redirected, calling
689 // fill_input_buf() calls settmode() when stdin isn't a tty. settmode()
690 // calls vgetorpeek() which calls ui_breakcheck() again.
691 if (recursive)
692 return;
693 recursive = TRUE;
694
695 // We do not want gui_resize_shell() to redraw the screen here.
Bram Moolenaare3caa112017-01-31 22:07:42 +0100696 ++updating_screen;
697
Bram Moolenaar071d4272004-06-13 20:20:40 +0000698#ifdef FEAT_GUI
699 if (gui.in_use)
700 gui_mch_update();
701 else
702#endif
Bram Moolenaarb9c31e72016-09-29 15:18:57 +0200703 mch_breakcheck(force);
Bram Moolenaare3caa112017-01-31 22:07:42 +0100704
Bram Moolenaar42335f52018-09-13 15:33:43 +0200705 if (save_updating_screen)
706 updating_screen = TRUE;
Bram Moolenaar0cb8ac72018-05-11 22:01:51 +0200707 else
Bram Moolenaar68a4b042019-05-29 22:28:29 +0200708 after_updating_screen(FALSE);
Bram Moolenaar48d23bb2018-11-20 02:42:43 +0100709
710 recursive = FALSE;
Bram Moolenaar071d4272004-06-13 20:20:40 +0000711}
712
Bram Moolenaare38eab22019-12-05 21:50:01 +0100713//////////////////////////////////////////////////////////////////////////////
Bram Moolenaare38eab22019-12-05 21:50:01 +0100714// Functions that handle the input buffer.
715// This is used for any GUI version, and the unix terminal version.
716//
717// For Unix, the input characters are buffered to be able to check for a
718// CTRL-C. This should be done with signals, but I don't know how to do that
719// in a portable way for a tty in RAW mode.
720//
721// For the client-server code in the console the received keys are put in the
722// input buffer.
Bram Moolenaar071d4272004-06-13 20:20:40 +0000723
724#if defined(USE_INPUT_BUF) || defined(PROTO)
725
726/*
727 * Internal typeahead buffer. Includes extra space for long key code
728 * descriptions which would otherwise overflow. The buffer is considered full
729 * when only this extra space (or part of it) remains.
730 */
Bram Moolenaarbb1969b2019-01-17 15:45:25 +0100731#if defined(FEAT_JOB_CHANNEL) || defined(FEAT_CLIENTSERVER)
Bram Moolenaar071d4272004-06-13 20:20:40 +0000732 /*
Bram Moolenaarbb1969b2019-01-17 15:45:25 +0100733 * NetBeans stuffs debugger commands into the input buffer.
Bram Moolenaar071d4272004-06-13 20:20:40 +0000734 * This requires a larger buffer...
735 * (Madsen) Go with this for remote input as well ...
736 */
737# define INBUFLEN 4096
738#else
739# define INBUFLEN 250
740#endif
741
742static char_u inbuf[INBUFLEN + MAX_KEY_CODE_LEN];
Bram Moolenaare38eab22019-12-05 21:50:01 +0100743static int inbufcount = 0; // number of chars in inbuf[]
Bram Moolenaar071d4272004-06-13 20:20:40 +0000744
745/*
746 * vim_is_input_buf_full(), vim_is_input_buf_empty(), add_to_input_buf(), and
747 * trash_input_buf() are functions for manipulating the input buffer. These
748 * are used by the gui_* calls when a GUI is used to handle keyboard input.
749 */
750
751 int
Bram Moolenaar764b23c2016-01-30 21:10:09 +0100752vim_is_input_buf_full(void)
Bram Moolenaar071d4272004-06-13 20:20:40 +0000753{
754 return (inbufcount >= INBUFLEN);
755}
756
757 int
Bram Moolenaar764b23c2016-01-30 21:10:09 +0100758vim_is_input_buf_empty(void)
Bram Moolenaar071d4272004-06-13 20:20:40 +0000759{
760 return (inbufcount == 0);
761}
762
763#if defined(FEAT_OLE) || defined(PROTO)
764 int
Bram Moolenaar764b23c2016-01-30 21:10:09 +0100765vim_free_in_input_buf(void)
Bram Moolenaar071d4272004-06-13 20:20:40 +0000766{
767 return (INBUFLEN - inbufcount);
768}
769#endif
770
Bram Moolenaar241a8aa2005-12-06 20:04:44 +0000771#if defined(FEAT_GUI_GTK) || defined(PROTO)
Bram Moolenaar071d4272004-06-13 20:20:40 +0000772 int
Bram Moolenaar764b23c2016-01-30 21:10:09 +0100773vim_used_in_input_buf(void)
Bram Moolenaar071d4272004-06-13 20:20:40 +0000774{
775 return inbufcount;
776}
777#endif
778
Bram Moolenaar071d4272004-06-13 20:20:40 +0000779/*
780 * Return the current contents of the input buffer and make it empty.
781 * The returned pointer must be passed to set_input_buf() later.
782 */
783 char_u *
Bram Moolenaar764b23c2016-01-30 21:10:09 +0100784get_input_buf(void)
Bram Moolenaar071d4272004-06-13 20:20:40 +0000785{
786 garray_T *gap;
787
Bram Moolenaare38eab22019-12-05 21:50:01 +0100788 // We use a growarray to store the data pointer and the length.
Bram Moolenaarc799fe22019-05-28 23:08:19 +0200789 gap = ALLOC_ONE(garray_T);
Bram Moolenaar071d4272004-06-13 20:20:40 +0000790 if (gap != NULL)
791 {
Bram Moolenaare38eab22019-12-05 21:50:01 +0100792 // Add one to avoid a zero size.
Bram Moolenaar18a4ba22019-05-24 19:39:03 +0200793 gap->ga_data = alloc(inbufcount + 1);
Bram Moolenaar071d4272004-06-13 20:20:40 +0000794 if (gap->ga_data != NULL)
795 mch_memmove(gap->ga_data, inbuf, (size_t)inbufcount);
796 gap->ga_len = inbufcount;
797 }
798 trash_input_buf();
799 return (char_u *)gap;
800}
801
802/*
803 * Restore the input buffer with a pointer returned from get_input_buf().
804 * The allocated memory is freed, this only works once!
805 */
806 void
Bram Moolenaar764b23c2016-01-30 21:10:09 +0100807set_input_buf(char_u *p)
Bram Moolenaar071d4272004-06-13 20:20:40 +0000808{
809 garray_T *gap = (garray_T *)p;
810
811 if (gap != NULL)
812 {
813 if (gap->ga_data != NULL)
814 {
815 mch_memmove(inbuf, gap->ga_data, gap->ga_len);
816 inbufcount = gap->ga_len;
817 vim_free(gap->ga_data);
818 }
819 vim_free(gap);
820 }
821}
Bram Moolenaar071d4272004-06-13 20:20:40 +0000822
Bram Moolenaar071d4272004-06-13 20:20:40 +0000823/*
824 * Add the given bytes to the input buffer
825 * Special keys start with CSI. A real CSI must have been translated to
826 * CSI KS_EXTRA KE_CSI. K_SPECIAL doesn't require translation.
827 */
828 void
Bram Moolenaar764b23c2016-01-30 21:10:09 +0100829add_to_input_buf(char_u *s, int len)
Bram Moolenaar071d4272004-06-13 20:20:40 +0000830{
831 if (inbufcount + len > INBUFLEN + MAX_KEY_CODE_LEN)
Bram Moolenaare38eab22019-12-05 21:50:01 +0100832 return; // Shouldn't ever happen!
Bram Moolenaar071d4272004-06-13 20:20:40 +0000833
Bram Moolenaar071d4272004-06-13 20:20:40 +0000834 while (len--)
835 inbuf[inbufcount++] = *s++;
836}
Bram Moolenaar071d4272004-06-13 20:20:40 +0000837
Bram Moolenaar071d4272004-06-13 20:20:40 +0000838/*
839 * Add "str[len]" to the input buffer while escaping CSI bytes.
840 */
841 void
842add_to_input_buf_csi(char_u *str, int len)
843{
844 int i;
845 char_u buf[2];
846
847 for (i = 0; i < len; ++i)
848 {
849 add_to_input_buf(str + i, 1);
850 if (str[i] == CSI)
851 {
Bram Moolenaare38eab22019-12-05 21:50:01 +0100852 // Turn CSI into K_CSI.
Bram Moolenaar071d4272004-06-13 20:20:40 +0000853 buf[0] = KS_EXTRA;
854 buf[1] = (int)KE_CSI;
855 add_to_input_buf(buf, 2);
856 }
857 }
858}
Bram Moolenaar071d4272004-06-13 20:20:40 +0000859
Bram Moolenaare38eab22019-12-05 21:50:01 +0100860/*
861 * Remove everything from the input buffer. Called when ^C is found.
862 */
Bram Moolenaar071d4272004-06-13 20:20:40 +0000863 void
Bram Moolenaar764b23c2016-01-30 21:10:09 +0100864trash_input_buf(void)
Bram Moolenaar071d4272004-06-13 20:20:40 +0000865{
866 inbufcount = 0;
867}
Bram Moolenaar071d4272004-06-13 20:20:40 +0000868
869/*
870 * Read as much data from the input buffer as possible up to maxlen, and store
871 * it in buf.
Bram Moolenaar071d4272004-06-13 20:20:40 +0000872 */
873 int
Bram Moolenaar764b23c2016-01-30 21:10:09 +0100874read_from_input_buf(char_u *buf, long maxlen)
Bram Moolenaar071d4272004-06-13 20:20:40 +0000875{
Bram Moolenaare38eab22019-12-05 21:50:01 +0100876 if (inbufcount == 0) // if the buffer is empty, fill it
Bram Moolenaar071d4272004-06-13 20:20:40 +0000877 fill_input_buf(TRUE);
878 if (maxlen > inbufcount)
879 maxlen = inbufcount;
880 mch_memmove(buf, inbuf, (size_t)maxlen);
881 inbufcount -= maxlen;
882 if (inbufcount)
883 mch_memmove(inbuf, inbuf + maxlen, (size_t)inbufcount);
884 return (int)maxlen;
885}
886
887 void
Bram Moolenaar764b23c2016-01-30 21:10:09 +0100888fill_input_buf(int exit_on_error UNUSED)
Bram Moolenaar071d4272004-06-13 20:20:40 +0000889{
Bram Moolenaard0573012017-10-28 21:11:06 +0200890#if defined(UNIX) || defined(VMS) || defined(MACOS_X)
Bram Moolenaar071d4272004-06-13 20:20:40 +0000891 int len;
892 int try;
893 static int did_read_something = FALSE;
Bram Moolenaare38eab22019-12-05 21:50:01 +0100894 static char_u *rest = NULL; // unconverted rest of previous read
Bram Moolenaar071d4272004-06-13 20:20:40 +0000895 static int restlen = 0;
896 int unconverted;
Bram Moolenaar071d4272004-06-13 20:20:40 +0000897#endif
898
899#ifdef FEAT_GUI
Bram Moolenaar54ee7752005-05-31 22:22:17 +0000900 if (gui.in_use
901# ifdef NO_CONSOLE_INPUT
Bram Moolenaare38eab22019-12-05 21:50:01 +0100902 // Don't use the GUI input when the window hasn't been opened yet.
903 // We get here from ui_inchar() when we should try reading from stdin.
Bram Moolenaar54ee7752005-05-31 22:22:17 +0000904 && !no_console_input()
905# endif
906 )
Bram Moolenaar071d4272004-06-13 20:20:40 +0000907 {
908 gui_mch_update();
909 return;
910 }
911#endif
Bram Moolenaard0573012017-10-28 21:11:06 +0200912#if defined(UNIX) || defined(VMS) || defined(MACOS_X)
Bram Moolenaar071d4272004-06-13 20:20:40 +0000913 if (vim_is_input_buf_full())
914 return;
915 /*
916 * Fill_input_buf() is only called when we really need a character.
917 * If we can't get any, but there is some in the buffer, just return.
918 * If we can't get any, and there isn't any in the buffer, we give up and
919 * exit Vim.
920 */
Bram Moolenaar071d4272004-06-13 20:20:40 +0000921 if (rest != NULL)
922 {
Bram Moolenaare38eab22019-12-05 21:50:01 +0100923 // Use remainder of previous call, starts with an invalid character
924 // that may become valid when reading more.
Bram Moolenaar071d4272004-06-13 20:20:40 +0000925 if (restlen > INBUFLEN - inbufcount)
926 unconverted = INBUFLEN - inbufcount;
927 else
928 unconverted = restlen;
929 mch_memmove(inbuf + inbufcount, rest, unconverted);
930 if (unconverted == restlen)
Bram Moolenaard23a8232018-02-10 18:45:26 +0100931 VIM_CLEAR(rest);
Bram Moolenaar071d4272004-06-13 20:20:40 +0000932 else
933 {
934 restlen -= unconverted;
935 mch_memmove(rest, rest + unconverted, restlen);
936 }
937 inbufcount += unconverted;
938 }
939 else
940 unconverted = 0;
Bram Moolenaar071d4272004-06-13 20:20:40 +0000941
Bram Moolenaare38eab22019-12-05 21:50:01 +0100942 len = 0; // to avoid gcc warning
Bram Moolenaar071d4272004-06-13 20:20:40 +0000943 for (try = 0; try < 100; ++try)
944 {
Bram Moolenaar4e601e32018-04-24 13:29:51 +0200945 size_t readlen = (size_t)((INBUFLEN - inbufcount)
Bram Moolenaar9645e2d2020-03-20 20:48:49 +0100946 / input_conv.vc_factor);
Bram Moolenaar4e601e32018-04-24 13:29:51 +0200947# ifdef VMS
Bram Moolenaar49943732018-04-24 20:27:26 +0200948 len = vms_read((char *)inbuf + inbufcount, readlen);
Bram Moolenaar4e601e32018-04-24 13:29:51 +0200949# else
950 len = read(read_cmd_fd, (char *)inbuf + inbufcount, readlen);
Bram Moolenaar071d4272004-06-13 20:20:40 +0000951# endif
Bram Moolenaar7ca86fe2020-09-03 19:25:11 +0200952# ifdef FEAT_JOB_CHANNEL
953 if (len > 0)
954 {
955 inbuf[inbufcount + len] = NUL;
956 ch_log(NULL, "raw key input: \"%s\"", inbuf + inbufcount);
957 }
958# endif
Bram Moolenaar5313dcb2005-02-22 08:56:13 +0000959
Bram Moolenaar071d4272004-06-13 20:20:40 +0000960 if (len > 0 || got_int)
961 break;
962 /*
963 * If reading stdin results in an error, continue reading stderr.
964 * This helps when using "foo | xargs vim".
965 */
966 if (!did_read_something && !isatty(read_cmd_fd) && read_cmd_fd == 0)
967 {
968 int m = cur_tmode;
969
Bram Moolenaare38eab22019-12-05 21:50:01 +0100970 // We probably set the wrong file descriptor to raw mode. Switch
971 // back to cooked mode, use another descriptor and set the mode to
972 // what it was.
Bram Moolenaar071d4272004-06-13 20:20:40 +0000973 settmode(TMODE_COOK);
974#ifdef HAVE_DUP
Bram Moolenaare38eab22019-12-05 21:50:01 +0100975 // Use stderr for stdin, also works for shell commands.
Bram Moolenaar071d4272004-06-13 20:20:40 +0000976 close(0);
Bram Moolenaar42335f52018-09-13 15:33:43 +0200977 vim_ignored = dup(2);
Bram Moolenaar071d4272004-06-13 20:20:40 +0000978#else
Bram Moolenaare38eab22019-12-05 21:50:01 +0100979 read_cmd_fd = 2; // read from stderr instead of stdin
Bram Moolenaar071d4272004-06-13 20:20:40 +0000980#endif
981 settmode(m);
982 }
983 if (!exit_on_error)
984 return;
985 }
Bram Moolenaar071d4272004-06-13 20:20:40 +0000986 if (len <= 0 && !got_int)
987 read_error_exit();
988 if (len > 0)
989 did_read_something = TRUE;
990 if (got_int)
991 {
Bram Moolenaare38eab22019-12-05 21:50:01 +0100992 // Interrupted, pretend a CTRL-C was typed.
Bram Moolenaar071d4272004-06-13 20:20:40 +0000993 inbuf[0] = 3;
994 inbufcount = 1;
995 }
996 else
997 {
Bram Moolenaar071d4272004-06-13 20:20:40 +0000998 /*
999 * May perform conversion on the input characters.
1000 * Include the unconverted rest of the previous call.
1001 * If there is an incomplete char at the end it is kept for the next
1002 * time, reading more bytes should make conversion possible.
1003 * Don't do this in the unlikely event that the input buffer is too
1004 * small ("rest" still contains more bytes).
1005 */
1006 if (input_conv.vc_type != CONV_NONE)
1007 {
1008 inbufcount -= unconverted;
1009 len = convert_input_safe(inbuf + inbufcount,
1010 len + unconverted, INBUFLEN - inbufcount,
1011 rest == NULL ? &rest : NULL, &restlen);
1012 }
Bram Moolenaar071d4272004-06-13 20:20:40 +00001013 while (len-- > 0)
1014 {
1015 /*
Bram Moolenaar9645e2d2020-03-20 20:48:49 +01001016 * If a CTRL-C was typed, remove it from the buffer and set
Bram Moolenaar02faa942021-01-02 16:17:18 +01001017 * got_int. Also recognize CTRL-C with modifyOtherKeys set, in two
1018 * forms.
Bram Moolenaar071d4272004-06-13 20:20:40 +00001019 */
Bram Moolenaar9645e2d2020-03-20 20:48:49 +01001020 if (ctrl_c_interrupts && (inbuf[inbufcount] == 3
1021 || (len >= 9 && STRNCMP(inbuf + inbufcount,
Bram Moolenaar02faa942021-01-02 16:17:18 +01001022 "\033[27;5;99~", 10) == 0)
1023 || (len >= 7 && STRNCMP(inbuf + inbufcount,
1024 "\033[99;5u", 7) == 0)))
Bram Moolenaar071d4272004-06-13 20:20:40 +00001025 {
Bram Moolenaare38eab22019-12-05 21:50:01 +01001026 // remove everything typed before the CTRL-C
Bram Moolenaar071d4272004-06-13 20:20:40 +00001027 mch_memmove(inbuf, inbuf + inbufcount, (size_t)(len + 1));
1028 inbufcount = 0;
1029 got_int = TRUE;
1030 }
1031 ++inbufcount;
1032 }
1033 }
Bram Moolenaar74ee5e22019-12-13 18:13:22 +01001034#endif // UNIX || VMS || MACOS_X
Bram Moolenaar071d4272004-06-13 20:20:40 +00001035}
Bram Moolenaar74ee5e22019-12-13 18:13:22 +01001036#endif // USE_INPUT_BUF
Bram Moolenaar071d4272004-06-13 20:20:40 +00001037
1038/*
1039 * Exit because of an input read error.
1040 */
1041 void
Bram Moolenaar764b23c2016-01-30 21:10:09 +01001042read_error_exit(void)
Bram Moolenaar071d4272004-06-13 20:20:40 +00001043{
Bram Moolenaare38eab22019-12-05 21:50:01 +01001044 if (silent_mode) // Normal way to exit for "ex -s"
Bram Moolenaar071d4272004-06-13 20:20:40 +00001045 getout(0);
1046 STRCPY(IObuff, _("Vim: Error reading input, exiting...\n"));
1047 preserve_exit();
1048}
1049
1050#if defined(CURSOR_SHAPE) || defined(PROTO)
1051/*
1052 * May update the shape of the cursor.
1053 */
1054 void
Bram Moolenaar3cd43cc2017-08-12 19:51:41 +02001055ui_cursor_shape_forced(int forced)
Bram Moolenaar071d4272004-06-13 20:20:40 +00001056{
1057# ifdef FEAT_GUI
1058 if (gui.in_use)
1059 gui_update_cursor_later();
Bram Moolenaar293ee4d2004-12-09 21:34:53 +00001060 else
Bram Moolenaar071d4272004-06-13 20:20:40 +00001061# endif
Bram Moolenaar3cd43cc2017-08-12 19:51:41 +02001062 term_cursor_mode(forced);
Bram Moolenaar293ee4d2004-12-09 21:34:53 +00001063
Bram Moolenaar071d4272004-06-13 20:20:40 +00001064# ifdef MCH_CURSOR_SHAPE
1065 mch_update_cursor();
1066# endif
Bram Moolenaarf5963f72010-07-23 22:10:27 +02001067
1068# ifdef FEAT_CONCEAL
Bram Moolenaarb9464822018-05-10 15:09:49 +02001069 conceal_check_cursor_line();
Bram Moolenaarf5963f72010-07-23 22:10:27 +02001070# endif
Bram Moolenaar071d4272004-06-13 20:20:40 +00001071}
Bram Moolenaar3cd43cc2017-08-12 19:51:41 +02001072
1073 void
1074ui_cursor_shape(void)
1075{
1076 ui_cursor_shape_forced(FALSE);
1077}
Bram Moolenaar071d4272004-06-13 20:20:40 +00001078#endif
1079
Bram Moolenaar071d4272004-06-13 20:20:40 +00001080/*
1081 * Check bounds for column number
1082 */
1083 int
Bram Moolenaar764b23c2016-01-30 21:10:09 +01001084check_col(int col)
Bram Moolenaar071d4272004-06-13 20:20:40 +00001085{
1086 if (col < 0)
1087 return 0;
1088 if (col >= (int)screen_Columns)
1089 return (int)screen_Columns - 1;
1090 return col;
1091}
1092
1093/*
1094 * Check bounds for row number
1095 */
1096 int
Bram Moolenaar764b23c2016-01-30 21:10:09 +01001097check_row(int row)
Bram Moolenaar071d4272004-06-13 20:20:40 +00001098{
1099 if (row < 0)
1100 return 0;
1101 if (row >= (int)screen_Rows)
1102 return (int)screen_Rows - 1;
1103 return row;
1104}
Bram Moolenaar071d4272004-06-13 20:20:40 +00001105
Bram Moolenaar4f974752019-02-17 17:44:42 +01001106#if defined(FEAT_GUI) || defined(MSWIN) || defined(PROTO)
Bram Moolenaar071d4272004-06-13 20:20:40 +00001107/*
1108 * Called when focus changed. Used for the GUI or for systems where this can
1109 * be done in the console (Win32).
1110 */
1111 void
Bram Moolenaar764b23c2016-01-30 21:10:09 +01001112ui_focus_change(
Bram Moolenaare38eab22019-12-05 21:50:01 +01001113 int in_focus) // TRUE if focus gained.
Bram Moolenaar071d4272004-06-13 20:20:40 +00001114{
1115 static time_t last_time = (time_t)0;
1116 int need_redraw = FALSE;
1117
Bram Moolenaare38eab22019-12-05 21:50:01 +01001118 // When activated: Check if any file was modified outside of Vim.
1119 // Only do this when not done within the last two seconds (could get
1120 // several events in a row).
Bram Moolenaar071d4272004-06-13 20:20:40 +00001121 if (in_focus && last_time + 2 < time(NULL))
1122 {
1123 need_redraw = check_timestamps(
1124# ifdef FEAT_GUI
1125 gui.in_use
1126# else
1127 FALSE
1128# endif
1129 );
1130 last_time = time(NULL);
1131 }
1132
Bram Moolenaar071d4272004-06-13 20:20:40 +00001133 /*
1134 * Fire the focus gained/lost autocommand.
1135 */
1136 need_redraw |= apply_autocmds(in_focus ? EVENT_FOCUSGAINED
1137 : EVENT_FOCUSLOST, NULL, NULL, FALSE, curbuf);
Bram Moolenaar071d4272004-06-13 20:20:40 +00001138
1139 if (need_redraw)
1140 {
Bram Moolenaare38eab22019-12-05 21:50:01 +01001141 // Something was executed, make sure the cursor is put back where it
1142 // belongs.
Bram Moolenaar071d4272004-06-13 20:20:40 +00001143 need_wait_return = FALSE;
1144
1145 if (State & CMDLINE)
1146 redrawcmdline();
1147 else if (State == HITRETURN || State == SETWSIZE || State == ASKMORE
1148 || State == EXTERNCMD || State == CONFIRM || exmode_active)
1149 repeat_message();
1150 else if ((State & NORMAL) || (State & INSERT))
1151 {
1152 if (must_redraw != 0)
1153 update_screen(0);
1154 setcursor();
1155 }
Bram Moolenaare38eab22019-12-05 21:50:01 +01001156 cursor_on(); // redrawing may have switched it off
Bram Moolenaara338adc2018-01-31 20:51:47 +01001157 out_flush_cursor(FALSE, TRUE);
Bram Moolenaar071d4272004-06-13 20:20:40 +00001158# ifdef FEAT_GUI
1159 if (gui.in_use)
Bram Moolenaar071d4272004-06-13 20:20:40 +00001160 gui_update_scrollbars(FALSE);
Bram Moolenaar071d4272004-06-13 20:20:40 +00001161# endif
1162 }
1163#ifdef FEAT_TITLE
Bram Moolenaare38eab22019-12-05 21:50:01 +01001164 // File may have been changed from 'readonly' to 'noreadonly'
Bram Moolenaar071d4272004-06-13 20:20:40 +00001165 if (need_maketitle)
1166 maketitle();
1167#endif
1168}
1169#endif
1170
Bram Moolenaarf2bd8ef2018-03-04 18:08:14 +01001171#if defined(HAVE_INPUT_METHOD) || defined(PROTO)
Bram Moolenaar071d4272004-06-13 20:20:40 +00001172/*
1173 * Save current Input Method status to specified place.
1174 */
1175 void
Bram Moolenaar764b23c2016-01-30 21:10:09 +01001176im_save_status(long *psave)
Bram Moolenaar071d4272004-06-13 20:20:40 +00001177{
Bram Moolenaare38eab22019-12-05 21:50:01 +01001178 // Don't save when 'imdisable' is set or "xic" is NULL, IM is always
1179 // disabled then (but might start later).
1180 // Also don't save when inside a mapping, vgetc_im_active has not been set
1181 // then.
1182 // And don't save when the keys were stuffed (e.g., for a "." command).
1183 // And don't save when the GUI is running but our window doesn't have
1184 // input focus (e.g., when a find dialog is open).
Bram Moolenaar071d4272004-06-13 20:20:40 +00001185 if (!p_imdisable && KeyTyped && !KeyStuffed
1186# ifdef FEAT_XIM
1187 && xic != NULL
1188# endif
1189# ifdef FEAT_GUI
1190 && (!gui.in_use || gui.in_focus)
1191# endif
1192 )
1193 {
Bram Moolenaare38eab22019-12-05 21:50:01 +01001194 // Do save when IM is on, or IM is off and saved status is on.
Bram Moolenaar071d4272004-06-13 20:20:40 +00001195 if (vgetc_im_active)
1196 *psave = B_IMODE_IM;
1197 else if (*psave == B_IMODE_IM)
1198 *psave = B_IMODE_NONE;
1199 }
1200}
1201#endif