⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 message.c

📁 VIM文本编辑器
💻 C
📖 第 1 页 / 共 3 页
字号:
    {
	screen_fill(msg_row, msg_row + 1, msg_col, (int)Columns, ' ', ' ', 0);
	screen_fill(msg_row + 1, (int)Rows, 0, (int)Columns, ' ', ' ', 0);
    }
}

/*
 * Clear the command line.
 */
    void
msg_clr_cmdline()
{
    msg_row = cmdline_row;
    msg_col = 0;
    msg_clr_eos();
}

/*
 * end putting a message on the screen
 * call wait_return if the message does not fit in the available space
 * return TRUE if wait_return not called.
 */
    int
msg_end()
{
    /*
     * if the string is larger than the window,
     * or the ruler option is set and we run into it,
     * we have to redraw the window.
     * Do not do this if we are abandoning the file or editing the command line.
     */
    if (!exiting && msg_check() && State != CMDLINE)
    {
	wait_return(FALSE);
	return FALSE;
    }
    out_flush();
    return TRUE;
}

/*
 * If the written message has caused the screen to scroll up, or if we
 * run into the shown command or ruler, we have to redraw the window later.
 */
    int
msg_check()
{
    if (msg_scrolled || (msg_row == Rows - 1 && msg_col >= sc_col))
    {
	redraw_all_later(NOT_VALID);
	redraw_cmdline = TRUE;
	return TRUE;
    }
    return FALSE;
}

/*
 * May write a string to the redirection file.
 */
    static void
redir_write(s)
    char_u	*s;
{
    static int	    cur_col = 0;

    if (redir_fd != NULL && !redir_off)
    {
	/* If the string doesn't start with CR or NL, go to msg_col */
	if (*s != '\n' && *s != '\r')
	{
	    while (cur_col < msg_col)
	    {
		fputs(" ", redir_fd);
		++cur_col;
	    }
	}

	fputs((char *)s, redir_fd);

	/* Adjust the current column */
	while (*s)
	{
	    if (*s == '\r' || *s == '\n')
		cur_col = 0;
	    else if (*s == '\t')
		cur_col += (8 - cur_col % 8);
	    else
		++cur_col;
	    ++s;
	}
    }
}

/*
 * Give a warning message (for searching).
 * Use 'w' highlighting and may repeat the message after redrawing
 */
    void
give_warning(message, hl)
    char_u  *message;
    int	    hl;
{
    keep_msg = NULL;
    if (hl)
	keep_msg_attr = hl_attr(HLF_W);
    else
	keep_msg_attr = 0;
    if (msg_attr(message, keep_msg_attr) && !msg_scrolled)
	keep_msg = message;
    msg_didout = FALSE;	    /* overwrite this message */
    msg_nowait = TRUE;	    /* don't wait for this message */
    msg_col = 0;
}

/*
 * Advance msg cursor to column "col".
 */
    void
msg_advance(col)
    int	    col;
{
    if (col >= Columns)		/* not enough room */
	col = Columns - 1;
    while (msg_col < col)
	msg_putchar(' ');
}

#if defined(CON_DIALOG) || defined(PROTO)
/*
 * Used for "confirm()" function, and the :confirm command prefix.
 * Versions which haven't got flexible dialogs yet, and console
 * versions, get this generic handler which uses the command line.
 *
 * type  = one of:
 *	   VIM_QUESTION, VIM_INFO, VIM_WARNING, VIM_ERROR or VIM_GENERIC
 * title = title string (can be NULL for default)
 * (neither used in console dialogs at the moment)
 *
 * Format of the "buttons" string:
 * "Button1Name\nButton2Name\nButton3Name"
 * The first button should normally be the default/accept
 * The second button should be the 'Cancel' button
 * Other buttons- use your imagination!
 * A '&' in a button name becomes a shortcut, so each '&' should be before a
 * different letter.
 */
/* ARGSUSED */
    int
do_dialog(type, title, message, buttons, dfltbutton)
    int		type;
    char_u	*title;
    char_u	*message;
    char_u	*buttons;
    int		dfltbutton;
{
    int		oldState;
    char_u	buf[20];	/* for getting keystrokes */
    int		retval = 0;
    char_u	*hotkeys;

#ifndef NO_CONSOLE
    /* Don't output anything in silent mode ("ex -s") */
    if (silent_mode)
	return dfltbutton;   /* return default option */
#endif

#ifdef GUI_DIALOG
    /* When GUI is running, use the GUI dialog */
    if (gui.in_use)
	return gui_mch_dialog(type, title, message, buttons, dfltbutton);
#endif

    oldState = State;
    State = CONFIRM;
#ifdef USE_MOUSE
    setmouse();
#endif

    /*
     * Since we wait for a keypress, don't make the
     * user press RETURN as well afterwards.
     */
    ++no_wait_return;
    hotkeys = msg_show_console_dialog(message, buttons, dfltbutton);

    if (hotkeys != NULL)
    {
	for (;;)
	{
	    /*
	     * Get a typed character directly from the user.
	     * Don't use vgetc(), it syncs undo and eats mapped
	     * characters.  Disadvantage: Special keys and mouse
	     * cannot be used here, typeahead is ignored.
	     */
	    cursor_on();
	    out_flush();
	    (void)ui_inchar(buf, 20, -1L);
	    switch (buf[0])
	    {
	    case CR:		/* User accepts default option */
	    case NL:
		retval = dfltbutton;
		break;
	    case Ctrl('C'):		/* User aborts/cancels */
	    case ESC:
		retval = 0;
		break;
	    default:		/* Could be a hotkey? */
#ifdef UNIX
		if (buf[0] == intr_char)
		{
		    retval = 0;	/* another way of cancelling */
		    break;
		}
#endif
		for (retval = 0; hotkeys[retval]; retval++)
		{
		    if (hotkeys[retval] == TO_LOWER(buf[0]))
			break;
		}
		if (hotkeys[retval])
		{
		    retval++;
		    break;
		}
		/* No hotkey match, so keep waiting */
		continue;
	    }
	    break;
	}

	vim_free(hotkeys);
    }

    State = oldState;
#ifdef USE_MOUSE
    setmouse();
#endif
    --no_wait_return;
    need_wait_return = FALSE;
    dont_wait_return = TRUE;	    /* don't wait again in main() */

    return retval;
}

char_u	*confirm_msg = NULL;	    /* ":confirm" message */

/*
 * Format the dialog string, and display it at the bottom of
 * the screen. Return a string of hotkey chars (if defined) for
 * each 'button'. If a button has no hotkey defined, the string
 * has the buttons first letter.
 *
 * Returns allocated array, or NULL for error.
 *
 */
    static char_u *
msg_show_console_dialog(message, buttons, dfltbutton)
    char_u	*message;
    char_u	*buttons;
    int		dfltbutton;
{
    int		len = 0;
    int		lenhotkey = 1;	/*first button*/
    char_u	*hotk;
    char_u	*p;
    char_u	*q;
    char_u	*r;

    /*
     * First compute how long a string we need to allocate for the message.
     */
    r = buttons;
    while (*r)
    {
	if (*r == DLG_BUTTON_SEP)
	{
	    len++;	    /* '\n' -> ', ' */
	    lenhotkey++;    /* each button needs a hotkey */
	}
	else if (*r == DLG_HOTKEY_CHAR)
	{
	    len++;	    /* '&a' -> '[a]' */
	}
	r++;
    }

    len += STRLEN(message)
	    + 2			/* for the NL's */
	    + STRLEN(buttons)
	    + 3;		/* for the ": " and NUL */

    lenhotkey++;		/* for the NUL */

    /*
     * Now allocate and load the strings
     */
    vim_free(confirm_msg);
    confirm_msg = alloc(len);
    if (confirm_msg == NULL)
	return NULL;
    *confirm_msg = NUL;
    hotk = alloc(lenhotkey);
    if (hotk == NULL)
	return NULL;

    *confirm_msg = '\n';
    STRCPY(confirm_msg + 1, message);

    p = confirm_msg + 1 + STRLEN(message);
    q = hotk;
    r = buttons;
    *q = (char_u)TO_LOWER(*r);	/* define lowercase hotkey */

    *p++ = '\n';

    while (*r)
    {
	if (*r == DLG_BUTTON_SEP)
	{
	    *p++ = ',';
	    *p++ = ' ';	    /* '\n' -> ', ' */
	    *(++q) = (char_u)TO_LOWER(*(r + 1)); /* next hotkey */
	    if (dfltbutton)
		--dfltbutton;
	}
	else if (*r == DLG_HOTKEY_CHAR)
	{
	    r++;
	    if (*r == DLG_HOTKEY_CHAR)		/* duplicate magic = literal */
		*p++ = *r;
	    else
	    {
		/* '&a' -> '[a]' */
		*p++ = (dfltbutton == 1) ? '[' : '(';
		*p++ = *r;
		*p++ = (dfltbutton == 1) ? ']' : ')';
		*q = (char_u)TO_LOWER(*r);	/* define lowercase hotkey */
	    }
	}
	else
	{
	    *p++ = *r;	    /* everything else copy literally */
	}
	r++;
    }
    *p++ = ':';
    *p++ = ' ';
    *p = NUL;
    *(++q) = NUL;

    display_confirm_msg();
    return hotk;
}

/*
 * Display the ":confirm" message.  Also called when screen resized.
 */
    void
display_confirm_msg()
{
    if (confirm_msg != NULL)
	msg_puts_attr(confirm_msg, hl_attr(HLF_M));
}

#endif /* CON_DIALOG */

#if defined(CON_DIALOG) || defined(GUI_DIALOG)

/*
 * Various stock dialogs used throughout Vim when :confirm is used.
 */
#if 0	/* not used yet */
    void
vim_dialog_ok(type, title, message)
    int		type;
    char_u	*title;
    char_u	*message;
{
    (void)do_dialog(type,
			  title == NULL ? (char_u *)"Information" : title,
			  message,
			  (char_u *)"&OK", 1);
}
#endif

#if 0	/* not used yet */
    int
vim_dialog_okcancel(type, title, message, dflt)
    int		type;
    char_u	*title;
    char_u	*message;
    int		dflt;
{
    if (do_dialog(type,
		title == NULL ? (char_u *)"Confirmation" : title,
		message,
		(char_u *)"&OK\n&Cancel", dflt) == 1)
	return VIM_OK;
    return VIM_CANCEL;
}
#endif

    int
vim_dialog_yesno(type, title, message, dflt)
    int		type;
    char_u	*title;
    char_u	*message;
    int		dflt;
{
    if (do_dialog(type,
		title == NULL ? (char_u *)"Question" : title,
		message,
		(char_u *)"&Yes\n&No", dflt) == 1)
	return VIM_YES;
    return VIM_NO;
}

    int
vim_dialog_yesnocancel(type, title, message, dflt)
    int		type;
    char_u	*title;
    char_u	*message;
    int		dflt;
{
    switch (do_dialog(type,
		title == NULL ? (char_u *)"Question" : title,
		message,
		(char_u *)"&Yes\n&No\n&Cancel", dflt))
    {
	case 1: return VIM_YES;
	case 2: return VIM_NO;
    }
    return VIM_CANCEL;
}

    int
vim_dialog_yesnoallcancel(type, title, message, dflt)
    int		type;
    char_u	*title;
    char_u	*message;
    int		dflt;
{
    switch (do_dialog(type,
		title == NULL ? (char_u *)"Question" : title,
		message,
		(char_u *)"&Yes\n&No\nSave &All\n&Discard All\n&Cancel", dflt))
    {
	case 1: return VIM_YES;
	case 2: return VIM_NO;
	case 3: return VIM_ALL;
	case 4: return VIM_DISCARDALL;
    }
    return VIM_CANCEL;
}

#endif /* GUI_DIALOG || CON_DIALOG */

#if defined(USE_BROWSE) || defined(PROTO)
/*
 * Generic browse function.  Calls gui_mch_browse() when possible.
 * Later this may pop-up a non-GUI file selector (external command?).
 */
    char_u *
do_browse(saving, title, dflt, ext, initdir, filter, buf)
    int		saving;		/* write action */
    char_u	*title;		/* title for the window */
    char_u	*dflt;		/* default file name */
    char_u	*ext;		/* extension added */
    char_u	*initdir;	/* initial directory, NULL for current dir */
    char_u	*filter;	/* file name filter */
    BUF		*buf;		/* buffer to read/write for */
{
    char_u		*fname;
    static char_u	*last_dir = NULL;    /* last used directory */
    char_u		*tofree = NULL;


    /* Must turn off browse straight away, or :so autocommands will get the
     * flag too!  */
    browse = FALSE;

    if (title == NULL)
    {
	if (saving)
	    title = (char_u *)"Save File dialog";
	else
	    title = (char_u *)"Open File dialog";
    }

    /* When no directory specified, use buffer dir, last dir or current dir */
    if (initdir == NULL || *initdir == NUL)
    {
	/* When saving or 'browsedir' is "buffer", use buffer fname */
	if ((saving || *p_bsdir == 'b') && buf != NULL && buf->b_ffname != NULL)
	{
	    dflt = gettail(curbuf->b_ffname);
	    tofree = vim_strsave(curbuf->b_ffname);
	    if (tofree != NULL)
	    {
		initdir = tofree;
		*gettail(initdir) = NUL;
	    }
	}
	/* When 'browsedir' is "last", use dir from last browse */
	else if (*p_bsdir == 'l')
	    initdir = last_dir;
	/* When 'browsedir is "current", use current directory.  This is the
	 * default already, leave initdir empty. */
    }

# ifdef USE_GUI
    if (gui.in_use)		/* when this changes, also adjust f_has()! */
    {
	fname = gui_mch_browse(saving, title, dflt, ext, initdir, filter);
    }
    else
# endif
    {
	/* TODO: non-GUI file selector here */
	fname = NULL;
    }

    /* keep the directory for next time */
    if (fname != NULL)
    {
	vim_free(last_dir);
	last_dir = vim_strsave(fname);
	if (last_dir != NULL)
	{
	    *gettail(last_dir) = NUL;
	    if (*last_dir == NUL)
	    {
		/* filename only returned, must be in current dir*/
		vim_free(last_dir);
		last_dir = alloc(MAXPATHL);
		if (last_dir != NULL)
		    mch_dirname(last_dir, MAXPATHL);
	    }
	}
    }

    vim_free(tofree);

    return fname;
}
#endif

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -