Annotation of src/usr.bin/vim/message.c, Revision 1.3
1.3 ! downsj 1: /* $OpenBSD: message.c,v 1.2 1996/09/21 06:23:09 downsj Exp $ */
1.1 downsj 2: /* vi:set ts=4 sw=4:
3: *
4: * VIM - Vi IMproved by Bram Moolenaar
5: *
6: * Do ":help uganda" in Vim to read copying and usage conditions.
7: * Do ":help credits" in Vim to see a list of people who contributed.
8: */
9:
10: /*
11: * message.c: functions for displaying messages on the command line
12: */
13:
14: #include "vim.h"
15: #include "globals.h"
16: #define MESSAGE /* don't include prototype for smsg() */
17: #include "proto.h"
18: #include "option.h"
1.2 downsj 19: #ifdef __QNX__
20: # include <stdarg.h>
21: #endif
1.1 downsj 22:
23: static void msg_screen_outchar __ARGS((int c));
24: static int msg_check_screen __ARGS((void));
25:
1.3 ! downsj 26: /* lines_left moved to globals so do_exmode could see it */
1.1 downsj 27:
28: /*
29: * msg(s) - displays the string 's' on the status line
30: * When terminal not initialized (yet) fprintf(stderr,..) is used.
31: * return TRUE if wait_return not called
32: */
33: int
34: msg(s)
35: char_u *s;
36: {
37: msg_start();
38: if (msg_highlight)
39: start_highlight();
40: msg_outtrans(s);
41: if (msg_highlight)
42: {
43: stop_highlight();
44: msg_highlight = FALSE; /* clear for next call */
45: }
46: msg_clr_eos();
47: return msg_end();
48: }
49:
50: /*
51: * automatic prototype generation does not understand this function
52: */
53: #ifndef PROTO
1.2 downsj 54: #ifndef __QNX__
1.1 downsj 55: int smsg __ARGS((char_u *, long, long, long,
56: long, long, long, long, long, long, long));
57:
58: /* VARARGS */
59: int
60: smsg(s, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10)
61: char_u *s;
62: long a1, a2, a3, a4, a5, a6, a7, a8, a9, a10;
63: {
64: sprintf((char *)IObuff, (char *)s, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10);
65: return msg(IObuff);
66: }
1.2 downsj 67: #else /* __QNX__ */
68: void smsg(char_u *s, ...)
69: {
70: va_list arglist;
71: va_start(arglist, s);
72: vsprintf((char *)IObuff, (char *)s, arglist);
73: va_end(arglist);
74: msg(IObuff);
75: }
76: #endif /* __QNX__ */
1.1 downsj 77: #endif
78:
79: /*
80: * emsg() - display an error message
81: *
82: * Rings the bell, if appropriate, and calls message() to do the real work
83: * When terminal not initialized (yet) fprintf(stderr,..) is used.
84: *
85: * return TRUE if wait_return not called
86: */
87: int
88: emsg(s)
89: char_u *s;
90: {
91: char_u *Buf;
92: #ifdef SLEEP_IN_EMSG
93: int retval;
94: #endif
95: static int last_lnum = 0;
96: static char_u *last_sourcing_name = NULL;
97:
98: if (emsg_off) /* no error messages at the moment */
99: return TRUE;
100:
101: if (global_busy) /* break :global command */
102: ++global_busy;
103:
104: if (p_eb)
105: beep_flush(); /* also includes flush_buffers() */
106: else
107: flush_buffers(FALSE); /* flush internal buffers */
108: did_emsg = TRUE; /* flag for DoOneCmd() */
109: ++msg_scroll; /* don't overwrite a previous message */
110: (void)set_highlight('e'); /* set highlight mode for error messages */
111: msg_highlight = TRUE;
112: if (msg_scrolled)
113: need_wait_return = TRUE; /* needed in case emsg() is called after
114: * wait_return has reset need_wait_return
115: * and a redraw is expected because
116: * msg_scrolled is non-zero */
117:
118: /*
119: * First output name and line number of source of error message
120: */
121: if (sourcing_name != NULL &&
122: (sourcing_name != last_sourcing_name || sourcing_lnum != last_lnum)
123: && (Buf = alloc(MAXPATHL + 30)) != NULL)
124: {
125: ++no_wait_return;
126: if (sourcing_name != last_sourcing_name)
127: {
128: sprintf((char *)Buf, "Error detected while processing %s:",
129: sourcing_name);
130: msg(Buf);
131: msg_highlight = TRUE;
132: }
133: /* lnum is 0 when executing a command from the command line
134: * argument, we don't want a line number then */
135: if (sourcing_lnum != 0)
136: {
137: (void)set_highlight('n'); /* highlight mode for line numbers */
138: sprintf((char *)Buf, "line %4ld:", sourcing_lnum);
139: msg(Buf);
140: (void)set_highlight('e'); /* highlight mode for error messages */
141: msg_highlight = TRUE;
142: }
143: --no_wait_return;
144: last_lnum = sourcing_lnum; /* only once for each line */
145: vim_free(Buf);
146: }
147: last_sourcing_name = sourcing_name; /* do this also when it is NULL */
148:
149: #ifdef SLEEP_IN_EMSG
150: /*
151: * Msg returns TRUE if wait_return() was not called.
152: * In that case may call sleep() to give the user a chance to read the message.
153: * Don't call sleep() if dont_sleep is set.
154: */
155: retval = msg(s);
156: if (retval)
157: {
158: if (dont_sleep || need_wait_return)
159: need_sleep = TRUE; /* sleep before removing the message */
160: else
161: mch_delay(1000L, TRUE); /* give user chance to read message */
162: }
163: /* --msg_scroll; don't overwrite this message */
164: return retval;
165: #else
166: emsg_on_display = TRUE; /* remember there is an error message */
167: return msg(s);
168: #endif
169: }
170:
171: int
172: emsg2(s, a1)
173: char_u *s, *a1;
174: {
175: /* Check for NULL strings (just in case) */
176: if (a1 == NULL)
177: a1 = (char_u *)"[NULL]";
178: /* Check for very long strings (can happen with ":help ^A<CR>") */
1.2 downsj 179: if (STRLEN(s) + STRLEN(a1) >= (size_t)IOSIZE)
1.1 downsj 180: a1 = (char_u *)"[string too long]";
181: sprintf((char *)IObuff, (char *)s, (char *)a1);
182: return emsg(IObuff);
183: }
184:
185: int
186: emsgn(s, n)
187: char_u *s;
188: long n;
189: {
190: sprintf((char *)IObuff, (char *)s, n);
191: return emsg(IObuff);
192: }
193:
194: /*
195: * Like msg(), but truncate to a single line if p_shm contains 't'.
196: * Careful: The string may be changed!
197: */
198: int
199: msg_trunc(s)
200: char_u *s;
201: {
202: int n;
203:
204: if (shortmess(SHM_TRUNC) && (n = (int)STRLEN(s) -
205: (int)(Rows - cmdline_row - 1) * Columns - sc_col + 1) > 0)
206: {
207: s[n] = '<';
208: return msg(s + n);
209: }
210: else
211: return msg(s);
212: }
213:
214: /*
215: * wait for the user to hit a key (normally a return)
216: * if 'redraw' is TRUE, clear and redraw the screen
217: * if 'redraw' is FALSE, just redraw the screen
218: * if 'redraw' is -1, don't redraw at all
219: */
220: void
221: wait_return(redraw)
222: int redraw;
223: {
224: int c;
225: int oldState;
226: int tmpState;
227:
228: if (redraw == TRUE)
229: must_redraw = CLEAR;
230:
231: /*
232: * With the global command (and some others) we only need one return at the
233: * end. Adjust cmdline_row to avoid the next message overwriting the last one.
234: */
235: if (no_wait_return)
236: {
237: need_wait_return = TRUE;
238: cmdline_row = msg_row;
239: return;
240: }
241: oldState = State;
242: if (quit_more)
243: {
244: c = CR; /* just pretend CR was hit */
245: quit_more = FALSE;
246: got_int = FALSE;
247: }
1.3 ! downsj 248: else if (exmode_active)
! 249: {
! 250: MSG_OUTSTR(" "); /* make sure the cursor is on the right line */
! 251: c = CR; /* no need for a return in ex mode */
! 252: got_int = FALSE;
! 253: }
1.1 downsj 254: else
255: {
256: State = HITRETURN;
257: #ifdef USE_MOUSE
258: setmouse();
259: #endif
260: if (msg_didout) /* start on a new line */
261: msg_outchar('\n');
262: if (got_int)
263: MSG_OUTSTR("Interrupt: ");
264:
265: (void)set_highlight('r');
266: start_highlight();
267: #ifdef ORG_HITRETURN
268: MSG_OUTSTR("Press RETURN to continue");
269: stop_highlight();
270: do {
271: c = vgetc();
272: } while (vim_strchr((char_u *)"\r\n: ", c) == NULL);
273: if (c == ':') /* this can vi too (but not always!) */
274: stuffcharReadbuff(c);
275: #else
276: MSG_OUTSTR("Press RETURN or enter command to continue");
277: stop_highlight();
278: do
279: {
280: c = vgetc();
281: got_int = FALSE;
282: } while (c == Ctrl('C')
283: #ifdef USE_GUI
284: || c == K_SCROLLBAR || c == K_HORIZ_SCROLLBAR
285: #endif
286: #ifdef USE_MOUSE
287: || c == K_LEFTDRAG || c == K_LEFTRELEASE
288: || c == K_MIDDLEDRAG || c == K_MIDDLERELEASE
289: || c == K_RIGHTDRAG || c == K_RIGHTRELEASE
290: || c == K_IGNORE ||
291: (!mouse_has(MOUSE_RETURN) &&
292: (c == K_LEFTMOUSE ||
293: c == K_MIDDLEMOUSE ||
294: c == K_RIGHTMOUSE))
295: #endif
296: );
297: mch_breakcheck();
298: #ifdef USE_MOUSE
299: /*
300: * Avoid that the mouse-up event causes visual mode to start.
301: */
302: if (c == K_LEFTMOUSE || c == K_MIDDLEMOUSE || c == K_RIGHTMOUSE)
303: jump_to_mouse(MOUSE_SETPOS);
304: else
305: #endif
306: if (vim_strchr((char_u *)"\r\n ", c) == NULL)
307: {
308: stuffcharReadbuff(c);
309: do_redraw = TRUE; /* need a redraw even though there is
310: something in the stuff buffer */
311: }
312: #endif
313: }
314:
315: /*
316: * If the user hits ':', '?' or '/' we get a command line from the next
317: * line.
318: */
319: if (c == ':' || c == '?' || c == '/')
320: {
321: cmdline_row = msg_row;
322: skip_redraw = TRUE; /* skip redraw once */
323: do_redraw = FALSE;
324: }
325:
326: /*
327: * If the window size changed set_winsize() will redraw the screen.
328: * Otherwise the screen is only redrawn if 'redraw' is set and no ':' typed.
329: */
330: tmpState = State;
331: State = oldState; /* restore State before set_winsize */
332: #ifdef USE_MOUSE
333: setmouse();
334: #endif
335: msg_check();
336:
337: need_wait_return = FALSE;
338: emsg_on_display = FALSE; /* can delete error message now */
339: #ifdef SLEEP_IN_EMSG
340: need_sleep = FALSE; /* no need to call sleep() anymore */
341: #endif
342: msg_didany = FALSE; /* reset lines_left at next msg_start() */
343: lines_left = -1;
344: if (keep_msg != NULL && linetabsize(keep_msg) >=
345: (Rows - cmdline_row - 1) * Columns + sc_col)
346: keep_msg = NULL; /* don't redisplay message, it's too long */
347:
348: if (tmpState == SETWSIZE) /* got resize event while in vgetc() */
349: {
350: starttermcap(); /* start termcap before redrawing */
351: set_winsize(0, 0, FALSE);
352: }
353: else if (!skip_redraw && (redraw == TRUE || (msg_scrolled && redraw != -1)))
354: {
355: starttermcap(); /* start termcap before redrawing */
356: updateScreen(VALID);
357: }
358:
359: dont_wait_return = TRUE; /* don't wait again in main() */
360: }
361:
362: /*
363: * Prepare for outputting characters in the command line.
364: */
365: void
366: msg_start()
367: {
368: keep_msg = NULL; /* don't display old message now */
369: keep_msg_highlight = 0;
370: if (!msg_scroll && full_screen) /* overwrite last message */
371: msg_pos(cmdline_row, 0);
372: else if (msg_didout) /* start message on next line */
373: {
374: msg_outchar('\n');
375: cmdline_row = msg_row;
376: }
377: if (!msg_didany)
378: lines_left = cmdline_row;
379: msg_didout = FALSE; /* no output on current line yet */
380: cursor_off();
381: }
382:
383: /*
384: * Move message position. This should always be used after moving the cursor.
385: * Use negative value if row or col does not have to be changed.
386: */
387: void
388: msg_pos(row, col)
389: int row, col;
390: {
391: if (row >= 0)
392: msg_row = row;
393: if (col >= 0)
394: msg_col = col;
395: }
396:
397: void
398: msg_outchar(c)
399: int c;
400: {
401: char_u buf[4];
402:
403: if (IS_SPECIAL(c))
404: {
405: buf[0] = K_SPECIAL;
406: buf[1] = K_SECOND(c);
407: buf[2] = K_THIRD(c);
408: buf[3] = NUL;
409: }
410: else
411: {
412: buf[0] = c;
413: buf[1] = NUL;
414: }
415: msg_outstr(buf);
416: }
417:
418: void
419: msg_outnum(n)
420: long n;
421: {
422: char_u buf[20];
423:
424: sprintf((char *)buf, "%ld", n);
425: msg_outstr(buf);
426: }
427:
428: void
429: msg_home_replace(fname)
430: char_u *fname;
431: {
432: char_u *name;
433:
434: name = home_replace_save(NULL, fname);
435: if (name != NULL)
436: msg_outtrans(name);
437: vim_free(name);
438: }
439:
440: /*
441: * output 'len' characters in 'str' (including NULs) with translation
442: * if 'len' is -1, output upto a NUL character
443: * return the number of characters it takes on the screen
444: */
445: int
446: msg_outtrans(str)
447: register char_u *str;
448: {
449: return msg_outtrans_len(str, (int)STRLEN(str));
450: }
451:
452: int
453: msg_outtrans_len(str, len)
454: register char_u *str;
455: register int len;
456: {
457: int retval = 0;
458:
459: while (--len >= 0)
460: {
461: msg_outstr(transchar(*str));
462: retval += charsize(*str);
463: ++str;
464: }
465: return retval;
466: }
467:
468: /*
469: * Output the string 'str' upto a NUL character.
470: * Return the number of characters it takes on the screen.
471: *
472: * If K_SPECIAL is encountered, then it is taken in conjunction with the
473: * following character and shown as <F1>, <S-Up> etc. In addition, if 'all'
474: * is TRUE, then any other character which has its 8th bit set is shown as
475: * <M-x>, where x is the equivalent character without its 8th bit set. If a
476: * character is displayed in one of these special ways, is also highlighted
477: * (its highlight name is '8' in the p_hl variable).
478: * This function is used to show mappings, where we want to see how to type
479: * the character/string -- webb
480: */
481: int
482: msg_outtrans_special(str, all)
483: register char_u *str;
484: register int all; /* <M-a> etc as well as <F1> etc */
485: {
486: int retval = 0;
487: char_u *string;
488: int c;
489: int modifiers;
490:
491: set_highlight('8');
492: for (; *str; ++str)
493: {
494: c = *str;
495: if (c == K_SPECIAL && str[1] != NUL && str[2] != NUL)
496: {
497: modifiers = 0x0;
498: if (str[1] == KS_MODIFIER)
499: {
500: modifiers = str[2];
501: str += 3;
502: c = *str;
503: }
504: if (c == K_SPECIAL)
505: {
506: c = TO_SPECIAL(str[1], str[2]);
507: str += 2;
508: if (c == K_ZERO) /* display <Nul> as ^@ */
509: c = NUL;
510: }
511: if (IS_SPECIAL(c) || modifiers) /* special key */
512: {
513: string = get_special_key_name(c, modifiers);
514: start_highlight();
515: msg_outstr(string);
516: retval += STRLEN(string);
517: stop_highlight();
518: flushbuf(); /* Otherwise gets overwritten by spaces */
519: continue;
520: }
521: }
522: if ((c & 0x80) && all)
523: {
524: start_highlight();
525: MSG_OUTSTR("<M-");
526: msg_outstr(transchar(c & 0x7f));
527: retval += 2 + charsize(c & 0x7f);
528: MSG_OUTSTR(">");
529: stop_highlight();
530: }
531: else
532: {
533: msg_outstr(transchar(c));
534: retval += charsize(c);
535: }
536: }
537: return retval;
538: }
539:
540: /*
541: * print line for :p command
542: */
543: void
544: msg_prt_line(s)
545: char_u *s;
546: {
547: register int si = 0;
548: register int c;
549: register int col = 0;
550:
551: int n_extra = 0;
552: int n_spaces = 0;
553: char_u *p = NULL; /* init to make SASC shut up */
554: int n;
1.3 ! downsj 555:
! 556: /*
! 557: * if it's a blank line, echo a space, because otherwise if we're
! 558: * in ex mode, the : for the next command will end up on the wrong
! 559: * line. I don't know why -- hooray for cargo cult programming!
! 560: */
! 561:
! 562: if (*s == 0) {
! 563: msg_outchar(' ');
! 564: }
1.1 downsj 565:
566: for (;;)
567: {
568: if (n_extra)
569: {
570: --n_extra;
571: c = *p++;
572: }
573: else if (n_spaces)
574: {
575: --n_spaces;
576: c = ' ';
577: }
578: else
579: {
580: c = s[si++];
581: if (c == TAB && !curwin->w_p_list)
582: {
583: /* tab amount depends on current column */
584: n_spaces = curbuf->b_p_ts - col % curbuf->b_p_ts - 1;
585: c = ' ';
586: }
587: else if (c == NUL && curwin->w_p_list)
588: {
589: p = (char_u *)"";
590: n_extra = 1;
591: c = '$';
592: }
593: else if (c != NUL && (n = charsize(c)) > 1)
594: {
595: n_extra = n - 1;
596: p = transchar(c);
597: c = *p++;
598: }
599: }
600:
601: if (c == NUL)
602: break;
603:
604: msg_outchar(c);
605: col++;
606: }
607: }
608:
609: /*
610: * output a string to the screen at position msg_row, msg_col
611: * Update msg_row and msg_col for the next message.
612: */
613: void
614: msg_outstr(s)
615: char_u *s;
616: {
617: int oldState;
618: char_u buf[20];
619:
620: /*
621: * If there is no valid screen, use fprintf so we can see error messages.
622: * If termcap is not active, we may be writing in an alternate console
623: * window, cursor positioning may not work correctly (window size may be
624: * different, e.g. for WIN32 console).
625: */
626: if (!msg_check_screen()
627: #ifdef WIN32
628: || !termcap_active
629: #endif
630: )
631: {
632: #ifdef WIN32
633: mch_settmode(0); /* cook so that \r and \n are handled correctly */
634: #endif
635: fprintf(stderr, (char *)s);
636: msg_didout = TRUE; /* assume that line is not empty */
637: #ifdef WIN32
638: mch_settmode(1);
639: #endif
640: return;
641: }
642:
643: msg_didany = TRUE; /* remember that something was outputted */
644: while (*s)
645: {
646: /*
647: * The screen is scrolled up when:
648: * - When outputting a newline in the last row
649: * - when outputting a character in the last column of the last row
650: * (some terminals scroll automatically, some don't. To avoid
651: * problems we scroll ourselves)
652: */
653: if (msg_row >= Rows - 1 && (*s == '\n' || msg_col >= Columns - 1 ||
654: (*s == TAB && msg_col >= ((Columns - 1) & ~7))))
655: {
656: screen_del_lines(0, 0, 1, (int)Rows, TRUE); /* always works */
657: msg_row = Rows - 2;
658: if (msg_col >= Columns) /* can happen after screen resize */
659: msg_col = Columns - 1;
660: ++msg_scrolled;
661: need_wait_return = TRUE; /* may need wait_return in main() */
662: if (cmdline_row > 0)
663: --cmdline_row;
664: /*
665: * if screen is completely filled wait for a character
666: */
667: if (p_more && --lines_left == 0 && State != HITRETURN)
668: {
669: oldState = State;
670: State = ASKMORE;
671: #ifdef USE_MOUSE
672: setmouse();
673: #endif
674: msg_moremsg(FALSE);
675: for (;;)
676: {
677: /*
678: * Get a typed character directly from the user.
679: * Don't use vgetc(), it syncs undo and eats mapped
680: * characters. Disadvantage: Special keys and mouse
681: * cannot be used here, typeahead is ignored.
682: */
683: flushbuf();
684: (void)mch_inchar(buf, 20, -1L);
685: switch (buf[0])
686: {
687: case CR: /* one extra line */
688: case NL:
689: lines_left = 1;
690: break;
691: case ':': /* start new command line */
692: stuffcharReadbuff(':');
693: cmdline_row = Rows - 1; /* put ':' on this line */
694: skip_redraw = TRUE; /* skip redraw once */
695: dont_wait_return = TRUE; /* don't wait in main() */
696: /*FALLTHROUGH*/
697: case 'q': /* quit */
698: case Ctrl('C'):
699: got_int = TRUE;
700: quit_more = TRUE;
701: break;
702: case 'd': /* Down half a page */
703: lines_left = Rows / 2;
704: break;
705: case ' ': /* one extra page */
706: lines_left = Rows - 1;
707: break;
708: default: /* no valid response */
709: msg_moremsg(TRUE);
710: continue;
711: }
712: break;
713: }
714: /* clear the --more-- message */
715: screen_fill((int)Rows - 1, (int)Rows,
716: 0, (int)Columns, ' ', ' ');
717: State = oldState;
718: #ifdef USE_MOUSE
719: setmouse();
720: #endif
721: if (quit_more)
722: {
723: msg_row = Rows - 1;
724: msg_col = 0;
725: return; /* the string is not displayed! */
726: }
727: }
728: }
729: if (*s == '\n') /* go to next line */
730: {
731: msg_didout = FALSE; /* remember that line is empty */
732: msg_col = 0;
733: if (++msg_row >= Rows) /* safety check */
734: msg_row = Rows - 1;
735: }
736: else if (*s == '\r') /* go to column 0 */
737: {
738: msg_col = 0;
739: }
740: else if (*s == '\b') /* go to previous char */
741: {
742: if (msg_col)
743: --msg_col;
744: }
745: else if (*s == TAB) /* translate into spaces */
746: {
747: do
748: msg_screen_outchar(' ');
749: while (msg_col & 7);
750: }
751: else
752: msg_screen_outchar(*s);
753: ++s;
754: }
755: }
756:
757: static void
758: msg_screen_outchar(c)
759: int c;
760: {
761: msg_didout = TRUE; /* remember that line is not empty */
762: screen_outchar(c, msg_row, msg_col);
763: if (++msg_col >= Columns)
764: {
765: msg_col = 0;
766: ++msg_row;
767: }
768: }
769:
770: void
771: msg_moremsg(full)
772: int full;
773: {
774: /*
775: * Need to restore old highlighting when we've finished with it
776: * because the output that's paging may be relying on it not
777: * changing -- webb
778: */
779: remember_highlight();
780: set_highlight('m');
781: start_highlight();
782: screen_msg((char_u *)"-- More --", (int)Rows - 1, 0);
783: if (full)
784: screen_msg((char_u *)" (RET: line, SPACE: page, d: half page, q: quit)",
785: (int)Rows - 1, 10);
786: stop_highlight();
787: recover_old_highlight();
788: }
789:
790: /*
791: * msg_check_screen - check if the screen is initialized.
792: * Also check msg_row and msg_col, if they are too big it may cause a crash.
793: */
794: static int
795: msg_check_screen()
796: {
797: if (!full_screen || !screen_valid(FALSE))
798: return FALSE;
799:
800: if (msg_row >= Rows)
801: msg_row = Rows - 1;
802: if (msg_col >= Columns)
803: msg_col = Columns - 1;
804: return TRUE;
805: }
806:
807: /*
808: * clear from current message position to end of screen
809: * Note: msg_col is not updated, so we remember the end of the message
810: * for msg_check().
811: */
812: void
813: msg_clr_eos()
814: {
815: if (!msg_check_screen()
816: #ifdef WIN32
817: || !termcap_active
818: #endif
819: )
820: return;
821: screen_fill(msg_row, msg_row + 1, msg_col, (int)Columns, ' ', ' ');
822: screen_fill(msg_row + 1, (int)Rows, 0, (int)Columns, ' ', ' ');
823: }
824:
825: /*
826: * end putting a message on the screen
827: * call wait_return if the message does not fit in the available space
828: * return TRUE if wait_return not called.
829: */
830: int
831: msg_end()
832: {
833: /*
834: * if the string is larger than the window,
835: * or the ruler option is set and we run into it,
836: * we have to redraw the window.
837: * Do not do this if we are abandoning the file or editing the command line.
838: */
839: if (!exiting && msg_check() && State != CMDLINE)
840: {
841: wait_return(FALSE);
842: return FALSE;
843: }
844: flushbuf();
845: return TRUE;
846: }
847:
848: /*
849: * If the written message has caused the screen to scroll up, or if we
850: * run into the shown command or ruler, we have to redraw the window later.
851: */
852: int
853: msg_check()
854: {
855: if (msg_scrolled || (msg_row == Rows - 1 && msg_col >= sc_col))
856: {
857: redraw_later(NOT_VALID);
858: redraw_cmdline = TRUE;
859: return TRUE;
860: }
861: return FALSE;
862: }