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

📄 misc1.c

📁 VIM文本编辑器
💻 C
📖 第 1 页 / 共 5 页
字号:
 * return the 'y' or 'n'
 */
    int
ask_yesno(str, direct)
    char_u  *str;
    int	    direct;
{
    int	    r = ' ';
    char_u  buf[20];
    int	    len = 0;
    int	    idx = 0;
    int	    save_State = State;

    if (exiting)		/* put terminal in raw mode for this question */
	settmode(TMODE_RAW);
    ++no_wait_return;
#ifdef USE_GUI_WIN32
    dont_scroll = TRUE;		/* disallow scrolling here */
#endif
    State = CONFIRM;		/* mouse behaves like with :confirm */
#ifdef USE_MOUSE
    setmouse();			/* disables mouse for xterm */
#endif

    while (r != 'y' && r != 'n')
    {
	/* same highlighting as for wait_return */
	smsg_attr(hl_attr(HLF_R), (char_u *)"%s (y/n)?", str);
	if (direct)
	{
	    out_flush();
	    if (idx >= len)
	    {
		len = ui_inchar(buf, 20, -1L);
		idx = 0;
	    }
	    r = buf[idx++];
	}
	else
	    r = vgetc();
	if (r == Ctrl('C') || r == ESC)
	    r = 'n';
	msg_putchar(r);	    /* show what you typed */
	out_flush();
    }
    --no_wait_return;
    State = save_State;
#ifdef USE_MOUSE
    setmouse();
#endif
    return r;
}

/*
 * get a number from the user
 */
    int
get_number(colon)
    int	colon;			/* allow colon to abort */
{
    int	n = 0;
    int	c;

#ifdef USE_GUI_WIN32
    dont_scroll = TRUE;		/* disallow scrolling here */
#endif
    for (;;)
    {
	windgoto(msg_row, msg_col);
	c = vgetc();
	if (vim_isdigit(c))
	{
	    n = n * 10 + c - '0';
	    msg_putchar(c);
	}
	else if (c == K_DEL || c == K_BS || c == Ctrl('H'))
	{
	    n /= 10;
	    MSG_PUTS("\b \b");
	}
	else if (n == 0 && c == ':' && colon)
	{
	    stuffcharReadbuff(':');
	    if (!exmode_active)
		cmdline_row = msg_row;
	    skip_redraw = TRUE;	    /* skip redraw once */
	    do_redraw = FALSE;
	    break;
	}
	else if (c == CR || c == NL || c == Ctrl('C') || c == ESC)
	    break;
    }
    return n;
}

    void
msgmore(n)
    long n;
{
    long pn;

    if (global_busy ||	    /* no messages now, wait until global is finished */
	    keep_msg ||	    /* there is a message already, skip this one */
	    !messaging())   /* 'lazyredraw' set, don't do messages now */
	return;

    if (n > 0)
	pn = n;
    else
	pn = -n;

    if (pn > p_report)
    {
	sprintf((char *)msg_buf, "%ld %s line%s %s",
		pn, n > 0 ? "more" : "fewer", plural(pn),
		got_int ? "(Interrupted)" : "");
	if (msg(msg_buf))
	{
	    keep_msg = msg_buf;
	    keep_msg_attr = 0;
	}
    }
}

/*
 * flush map and typeahead buffers and give a warning for an error
 */
    void
beep_flush()
{
    flush_buffers(FALSE);
    vim_beep();
}

/*
 * give a warning for an error
 */
    void
vim_beep()
{
    if (p_vb)
    {
	out_str(T_VB);
    }
    else
    {
#ifdef MSDOS
	/*
	 * The number of beeps outputted is reduced to avoid having to wait
	 * for all the beeps to finish. This is only a problem on systems
	 * where the beeps don't overlap.
	 */
	if (beep_count == 0 || beep_count == 10)
	{
	    out_char('\007');
	    beep_count = 1;
	}
	else
	    ++beep_count;
#else
	out_char('\007');
#endif
    }
}

/*
 * To get the "real" home directory:
 * - get value of $HOME
 * For Unix:
 *  - go to that directory
 *  - do mch_dirname() to get the real name of that directory.
 *  This also works with mounts and links.
 *  Don't do this for MS-DOS, it will change the "current dir" for a drive.
 */
static char_u	*homedir = NULL;

    void
init_homedir()
{
    char_u  *var;

    var = mch_getenv((char_u *)"HOME");
#if defined(OS2) || defined(MSDOS) || defined(WIN32)
    /*
     * Default home dir is C:/
     * Best assumption we can make in such a situation.
     */
    if (var == NULL)
	var = "C:/";
#endif
    if (var != NULL)
    {
#ifdef UNIX
	if (mch_dirname(NameBuff, MAXPATHL) == OK)
	{
	    if (!mch_chdir((char *)var) && mch_dirname(IObuff, IOSIZE) == OK)
		var = IObuff;
	    mch_chdir((char *)NameBuff);
	}
#endif
	homedir = vim_strsave(var);
    }
}

/*
 * Expand environment variable with path name.
 * "~/" is also expanded, using $HOME.	For Unix "~user/" is expanded.
 * If anything fails no expansion is done and dst equals src.
 */
    void
expand_env(src, dst, dstlen)
    char_u  *src;	    /* input string e.g. "$HOME/vim.hlp" */
    char_u  *dst;	    /* where to put the result */
    int	    dstlen;	    /* maximum length of the result */
{
    char_u  *tail;
    int	    c;
    char_u  *var;
    int	    copy_char;
    int	    mustfree;	    /* var was allocated, need to free it later */
    char_u  *p;
    int	    at_start = TRUE;

    src = skipwhite(src);
    --dstlen;		    /* leave one char space for "\," */
    while (*src && dstlen > 0)
    {
	copy_char = TRUE;
	if (*src == '$' || (*src == '~' && at_start))
	{
	    mustfree = FALSE;

	    /*
	     * The variable name is copied into dst temporarily, because it may
	     * be a string in read-only memory and a NUL needs to be inserted.
	     */
	    if (*src == '$')				/* environment var */
	    {
		tail = src + 1;
		var = dst;
		c = dstlen - 1;

#ifdef UNIX
		/* Unix has ${var-name} type environment vars */
		if (*tail == '{' && !vim_isIDc('{'))
		{
		    tail++;	/* ignore '{' */
		    while (c-- > 0 && *tail && *tail != '}')
			*var++ = *tail++;
		    tail++;	/* ignore '}' */
		}
		else
#endif
		{
		    while (c-- > 0 && *tail && vim_isIDc(*tail))
		    {
#ifdef OS2		/* env vars only in uppercase */
			*var++ = TO_UPPER(*tail);
			tail++;	    /* toupper() may be a macro! */
#else
			*var++ = *tail++;
#endif
		    }
		}

		*var = NUL;
#if defined(OS2) || defined(MSDOS) || defined(WIN32)
		/* use "C:/" when $HOME is not set */
		if (STRCMP(dst, "HOME") == 0)
		    var = homedir;
		else
#endif
		{
		    var = mch_getenv(dst);
		    /*
		     * When expanding $VIM fails, try using the directory name
		     * from 'helpfile'.
		     */
		    if (var == NULL && STRCMP(dst, "VIM") == 0)
		    {
			p = NULL;
			if (vim_strchr(p_hf, '$') == NULL)
			    p = p_hf;
#ifdef USE_EXE_NAME
			/*
			 * Use the name of the executable, obtained from
			 * argv[0].
			 */
			else
			{
			    p = exe_name;
# ifdef MSDOS
			    /*
			     * Try the DOS search path.  The executable may in
			     * fact be called differently, so try this last.
			     */
			    if (p == NULL || *p == NUL)
				p = searchpath("vim.exe");
# endif
			}
#endif
			if (p != NULL)
			{
			    char_u	*pend;

			    /* remove the file name */
			    pend = gettail(p);
			    /* remove "doc/" from 'helpfile', if present */
			    if (p == p_hf && pend - 4 >= p
					&& fnamencmp(pend - 4, "doc", 3) == 0
					&& (pend - 4 == p
						|| vim_ispathsep(pend[-5])))
				pend -= 4;
#ifdef USE_EXE_NAME
			    /* remove "src/" from exe_name, if present */
			    if (p == exe_name)
			    {
				if (pend - 4 >= p
					&& fnamencmp(pend - 4, "src", 3) == 0
					&& (pend - 4 == p
						|| vim_ispathsep(pend[-5])))
				    pend -= 4;
			    }
#endif
#ifndef macintosh
			    /* remove trailing path separator */
			    if (pend > p && vim_ispathsep(pend[-1]))
				--pend;
#endif
			    var = vim_strnsave(p, (int)(pend - p));
			    mustfree = TRUE;
			    if (!mch_isdir(var))
			    {
				vim_free(var);
				var = NULL;
			    }
			}
#ifdef HAVE_PATHDEF
			/* for Unix we can use default_vim_dir */
			if (var == NULL)
			{
			    var = default_vim_dir;
			    mustfree = FALSE;
			}
#endif
		    }
		}
	    }
							/* home directory */
	    else if (  src[1] == NUL
		    || vim_ispathsep(src[1])
		    || vim_strchr((char_u *)" ,\t\n", src[1]) != NULL)
	    {
		var = homedir;
		tail = src + 1;
	    }
	    else					/* user directory */
	    {
#ifndef UNIX
		/* cannot expand user's home directory, so don't try */
		var = NULL;
		tail = (char_u *)"";	/* for gcc */
#else
		/*
		 * Copy ~user to dst[], so we can put a NUL after it.
		 */
		tail = src;
		var = dst;
		c = dstlen - 1;
		while (	   c-- > 0
			&& *tail
			&& vim_isfilec(*tail)
			&& !vim_ispathsep(*tail))
		    *var++ = *tail++;
		*var = NUL;

		/*
		 * If the system supports getpwnam(), use it.
		 * Otherwise, or if getpwnam() fails, the shell is used to
		 * expand ~user.  This is slower and may fail if the shell
		 * does not support ~user (old versions of /bin/sh).
		 */
# if defined(HAVE_GETPWNAM) && defined(HAVE_PWD_H)
		{
		    struct passwd *pw;

		    pw = getpwnam((char *)dst + 1);
		    if (pw != NULL)
			var = (char_u *)pw->pw_dir;
		    else
			var = NULL;
		}
		if (var == NULL)
# endif
		{
		    var = ExpandOne(dst, NULL, 0, WILD_EXPAND_FREE);
		    mustfree = TRUE;
		}
#endif /* UNIX */
	    }

	    if (var != NULL && *var != NUL &&
			  (STRLEN(var) + STRLEN(tail) + 1 < (unsigned)dstlen))
	    {
		STRCPY(dst, var);
		dstlen -= STRLEN(var);
		dst += STRLEN(var);
		    /* if var[] ends in a path separator and tail[] starts
		     * with it, skip a character */
		if (*var && vim_ispathsep(*(dst-1)) && vim_ispathsep(*tail))
		    ++tail;
		src = tail;
		copy_char = FALSE;
	    }
	    if (mustfree)
		vim_free(var);
	}

	if (copy_char)	    /* copy at least one char */
	{
	    /*
	     * Recogize the start of a new name, for '~'.
	     */
	    at_start = FALSE;
	    if (src[0] == '\\')
	    {
		*dst++ = *src++;
		--dstlen;
	    }
	    else if (src[0] == ' ' || src[0] == ',')
		at_start = TRUE;
	    *dst++ = *src++;
	    --dstlen;
	}
    }
    *dst = NUL;
}

/*
 * Call expand_env() and store the result in an allocated string.
 * This is not very memory efficient, this expects the result to be freed
 * again soon.
 */
    char_u *
expand_env_save(src)
    char_u	*src;
{
    char_u	*p;

    p = alloc(MAXPATHL);
    if (p != NULL)
	expand_env(src, p, MAXPATHL);
    return p;
}

/*
 * Replace home directory by "~" in each space or comma separated file name in
 * 'src'.
 * if "one" is TRUE, only replace one file name, include spaces and commas in
 * the file name.
 * If anything fails (except when out of space) dst equals src.
 */
    void
home_replace(buf, src, dst, dstlen, one)
    BUF	    *buf;	    /* when not NULL, check for help files */
    char_u  *src;	    /* input file name */
    char_u  *dst;	    /* where to put the result */
    int	    dstlen;	    /* maximum length of the result */
    int	    one;
{
    size_t  dirlen = 0, envlen = 0;
    size_t  len;
    char_u  *homedir_env;
    char_u  *p;

    if (src == NULL)
    {
	*dst = NUL;
	return;
    }

    /*
     * If the file is a help file, remove the path completely.
     */
    if (buf != NULL && buf->b_help)
    {
	STRCPY(dst, gettail(src));
	return;
    }

    /*
     * We check both the value of the $HOME environment variable and the
     * "real" home directory.
     */
    if (homedir != NULL)
	dirlen = STRLEN(homedir);
    homedir_env = mch_getenv((char_u *)"HOME");
    if (homedir_env != NULL)
	envlen = STRLEN(homedir_env);

    if (!one)
	src = skipwhite(src);
    while (*src && dstlen > 0)
    {
	/*
	 * Here we are at the beginning of a file name.
	 * First, check to see if the beginning of the file name matches
	 * $HOME or the "real" home directory. Check that there is a '/'
	 * after the match (so that if e.g. the file is "/home/pieter/bla",
	 * and the home directory is "/home/piet", the file does not end up
	 * as "~er/bla" (which would seem to indicate the file "bla" in user
	 * er's home directory)).
	 */
	p = homedir;
	len = dirlen;
	for (;;)
	{
	    if (   len
		&& fnamencmp(src, p, len) == 0
		&& (vim_ispathsep(src[len])
		    || (!one && (src[len] == ',' || src[len] == ' '))
		    || src[len] == NUL))
	    {
		src += len;
		if (--dstlen > 0)
		    *dst++ = '~';

		/*
		 * If it's just the home directory, add  "/".
		 */
		if (!vim_ispathsep(src[0]) && --dstlen > 0)
		    *dst++ = '/';
	    }
	    if (p == homedir_env)
		break;
	    p = homedir_env;
	    len = envlen;
	}

	/* if (!one) skip to separator: space or comma */

⌨️ 快捷键说明

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