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