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

📄 buffer.c

📁 VIM文本编辑器
💻 C
📖 第 1 页 / 共 4 页
字号:
	    p = home_replace_save(NULL, name);
	    if (p != NULL && vim_regexec(prog, p, TRUE) != 0)
		match = name;
	    vim_free(p);
	}
    }
    return match;
}

/*
 * find file in buffer name list by number
 */
    BUF	*
buflist_findnr(nr)
    int		nr;
{
    BUF		*buf;

    if (nr == 0)
	nr = curwin->w_alt_fnum;
    for (buf = firstbuf; buf != NULL; buf = buf->b_next)
	if (buf->b_fnum == nr)
	    return (buf);
    return NULL;
}

/*
 * Get name of file 'n' in the buffer list.
 * home_replace() is used to shorten the file name (used for marks).
 * Returns a pointer to allocated memory, of NULL when failed.
 */
    char_u *
buflist_nr2name(n, fullname, helptail)
    int n;
    int fullname;
    int helptail;	    /* for help buffers return tail only */
{
    BUF	    *buf;

    buf = buflist_findnr(n);
    if (buf == NULL)
	return NULL;
    return home_replace_save(helptail ? buf : NULL,
				     fullname ? buf->b_ffname : buf->b_fname);
}

/*
 * set the lnum and col for the buffer 'buf' and the current window
 */
    static void
buflist_setfpos(buf, lnum, col)
    BUF		*buf;
    linenr_t	lnum;
    colnr_t	col;
{
    WINFPOS	*wlp;

    for (wlp = buf->b_winfpos; wlp != NULL; wlp = wlp->wl_next)
	if (wlp->wl_win == curwin)
	    break;
    if (wlp == NULL)		/* make new entry */
    {
	wlp = (WINFPOS *)alloc((unsigned)sizeof(WINFPOS));
	if (wlp == NULL)
	    return;
	wlp->wl_win = curwin;
    }
    else			/* remove entry from list */
    {
	if (wlp->wl_prev)
	    wlp->wl_prev->wl_next = wlp->wl_next;
	else
	    buf->b_winfpos = wlp->wl_next;
	if (wlp->wl_next)
	    wlp->wl_next->wl_prev = wlp->wl_prev;
    }
    wlp->wl_fpos.lnum = lnum;
    wlp->wl_fpos.col = col;

    /* insert entry in front of the list */
    wlp->wl_next = buf->b_winfpos;
    buf->b_winfpos = wlp;
    wlp->wl_prev = NULL;
    if (wlp->wl_next)
	wlp->wl_next->wl_prev = wlp;

    return;
}

/*
 * find the position (lnum and col) for the buffer 'buf' for the current window
 * returns a pointer to no_position if no position is found
 */
    static FPOS *
buflist_findfpos(buf)
    BUF		*buf;
{
    WINFPOS	*wlp;
    static	FPOS no_position = {1, 0};

    for (wlp = buf->b_winfpos; wlp != NULL; wlp = wlp->wl_next)
	if (wlp->wl_win == curwin)
	    break;

    if (wlp == NULL)	/* if no fpos for curwin, use the first in the list */
	wlp = buf->b_winfpos;

    if (wlp != NULL)
	return &(wlp->wl_fpos);
    else
	return &no_position;
}

/*
 * find the lnum for the buffer 'buf' for the current window
 */
    linenr_t
buflist_findlnum(buf)
    BUF	    *buf;
{
    return buflist_findfpos(buf)->lnum;
}

/*
 * list all know file names (for :files and :buffers command)
 */
    void
buflist_list()
{
    BUF		*buf;
    int		len;

    for (buf = firstbuf; buf != NULL && !got_int; buf = buf->b_next)
    {
	msg_putchar('\n');
	if (buf->b_fname == NULL)
	    STRCPY(NameBuff, "No File");
	else
	    home_replace(buf, buf->b_fname, NameBuff, MAXPATHL, TRUE);

	sprintf((char *)IObuff, "%3d %c%c%c \"",
		buf->b_fnum,
		buf == curbuf ? '%' :
			(curwin->w_alt_fnum == buf->b_fnum ? '#' : ' '),
		buf->b_ml.ml_mfp == NULL ? '-' :
			(buf->b_nwindows == 0 ? 'h' : ' '),
		buf_changed(buf) ? '+' : ' ');

	len = STRLEN(IObuff);
	STRNCPY(IObuff + len, NameBuff, IOSIZE - 20 - len);

	len = STRLEN(IObuff);
	IObuff[len++] = '"';
	/*
	 * try to put the "line" strings in column 40
	 */
	do
	{
	    IObuff[len++] = ' ';
	} while (len < 40 && len < IOSIZE - 18);
	sprintf((char *)IObuff + len, "line %ld",
		buf == curbuf ? curwin->w_cursor.lnum :
				(long)buflist_findlnum(buf));
	msg_outtrans(IObuff);
	out_flush();	    /* output one line at a time */
	ui_breakcheck();
    }
}

/*
 * Get file name and line number for file 'fnum'.
 * Used by DoOneCmd() for translating '%' and '#'.
 * Used by insert_reg() and cmdline_paste() for '#' register.
 * Return FAIL if not found, OK for success.
 */
    int
buflist_name_nr(fnum, fname, lnum)
    int		fnum;
    char_u	**fname;
    linenr_t	*lnum;
{
    BUF		*buf;

    buf = buflist_findnr(fnum);
    if (buf == NULL || buf->b_fname == NULL)
	return FAIL;

    *fname = buf->b_fname;
    *lnum = buflist_findlnum(buf);

    return OK;
}

/*
 * Set the current file name to 'ffname', short file name to 'sfname'.
 * The file name with the full path is also remembered, for when :cd is used.
 * Returns FAIL for failure (file name already in use by other buffer)
 *	OK otherwise.
 */
    int
setfname(ffname, sfname, message)
    char_u *ffname, *sfname;
    int	    message;
{
    BUF	    *buf;

    if (ffname == NULL || *ffname == NUL)
    {
	vim_free(curbuf->b_ffname);
	vim_free(curbuf->b_sfname);
	curbuf->b_ffname = NULL;
	curbuf->b_sfname = NULL;
    }
    else
    {
	fname_expand(&ffname, &sfname);	    /* will allocate ffname */
	if (ffname == NULL)		    /* out of memory */
	    return FAIL;

#ifdef USE_FNAME_CASE
# ifdef USE_LONG_FNAME
	if (USE_LONG_FNAME)
# endif
	    fname_case(sfname);	    /* set correct case for short file name */
#endif
	/*
	 * if the file name is already used in another buffer:
	 * - if the buffer is loaded, fail
	 * - if the buffer is not loaded, delete it from the list
	 */
	buf = buflist_findname(ffname);
	if (buf != NULL && buf != curbuf)
	{
	    if (buf->b_ml.ml_mfp != NULL)	/* it's loaded, fail */
	    {
		if (message)
		    EMSG("Buffer with this name already exists");
		vim_free(ffname);
		return FAIL;
	    }
	    close_buffer(NULL, buf, TRUE, TRUE);    /* delete from the list */
	}
	sfname = vim_strsave(sfname);
	if (ffname == NULL || sfname == NULL)
	{
	    vim_free(sfname);
	    vim_free(ffname);
	    return FAIL;
	}
	vim_free(curbuf->b_ffname);
	vim_free(curbuf->b_sfname);
	curbuf->b_ffname = ffname;
	curbuf->b_sfname = sfname;
    }
    curbuf->b_fname = curbuf->b_sfname;

#ifndef SHORT_FNAME
    curbuf->b_shortname = FALSE;
#endif
    /*
     * If the file name changed, also change the name of the swapfile
     */
    if (curbuf->b_ml.ml_mfp != NULL)
	ml_setname();

    check_arg_idx();		/* check file name for arg list */
    maketitle();		/* set window title */
    status_redraw_all();	/* status lines need to be redrawn */
    fmarks_check_names(curbuf);	/* check named file marks */
    ml_timestamp(curbuf);	/* reset timestamp */
    return OK;
}

/*
 * set alternate file name for current window
 *
 * Used by do_one_cmd(), do_write() and do_ecmd().
 */
    void
setaltfname(ffname, sfname, lnum)
    char_u	*ffname;
    char_u	*sfname;
    linenr_t	lnum;
{
    BUF	    *buf;

    buf = buflist_new(ffname, sfname, lnum, FALSE);
    if (buf != NULL)
	curwin->w_alt_fnum = buf->b_fnum;
}

/*
 * Get alternate file name for current window.
 * Return NULL if there isn't any, and give error message if requested.
 */
    char_u  *
getaltfname(errmsg)
    int		errmsg;		/* give error message */
{
    char_u	*fname;
    linenr_t	dummy;

    if (buflist_name_nr(0, &fname, &dummy) == FAIL)
    {
	if (errmsg)
	    emsg(e_noalt);
	return NULL;
    }
    return fname;
}

/*
 * add a file name to the buflist and return its number
 *
 * used by qf_init(), main() and doarglist()
 */
    int
buflist_add(fname)
    char_u	*fname;
{
    BUF	    *buf;

    buf = buflist_new(fname, NULL, (linenr_t)0, FALSE);
    if (buf != NULL)
	return buf->b_fnum;
    return 0;
}

/*
 * set alternate cursor position for current window
 */
    void
buflist_altfpos()
{
    buflist_setfpos(curbuf, curwin->w_cursor.lnum, curwin->w_cursor.col);
}

/*
 * Return TRUE if 'fname' is not the same file as current file.
 * Fname must have a full path (expanded by mch_FullName).
 */
    int
otherfile(fname)
    char_u  *fname;
{				    /* no name is different */
    if (fname == NULL || *fname == NUL || curbuf->b_ffname == NULL)
	return TRUE;
    if (fnamecmp(fname, curbuf->b_ffname) == 0)
	return FALSE;
#ifdef UNIX
    {
	struct stat	st1, st2;

	/* Use stat() to check if the files are the same, even when the names
	 * are different (possible with links) */
	if (	   stat((char *)fname, &st1) >= 0
		&& stat((char *)curbuf->b_ffname, &st2) >= 0
		&& st1.st_dev == st2.st_dev
		&& st1.st_ino == st2.st_ino)
	    return FALSE;
    }
#endif
    return TRUE;
}

    void
fileinfo(fullname, shorthelp, dont_truncate)
    int fullname;
    int shorthelp;
    int	dont_truncate;
{
    char_u	*name;
    int		n;
    char_u	*p;
    char_u	*buffer;

    buffer = alloc(IOSIZE);
    if (buffer == NULL)
	return;

    if (fullname > 1)	    /* 2 CTRL-G: include buffer number */
    {
	sprintf((char *)buffer, "buf %d: ", curbuf->b_fnum);
	p = buffer + STRLEN(buffer);
    }
    else
	p = buffer;

    *p++ = '"';
    if (curbuf->b_ffname == NULL)
	STRCPY(p, "No File");
    else
    {
	if (!fullname && curbuf->b_fname != NULL)
	    name = curbuf->b_fname;
	else
	    name = curbuf->b_ffname;
	home_replace(shorthelp ? curbuf : NULL, name, p,
					  (int)(IOSIZE - (p - buffer)), TRUE);
    }

    sprintf((char *)buffer + STRLEN(buffer),
	    "\"%s%s%s%s",
	    curbuf_changed() ? (shortmess(SHM_MOD) ?
						" [+]" : " [Modified]") : " ",
	    curbuf->b_notedited ? "[Not edited]" : "",
	    curbuf->b_p_ro ? (shortmess(SHM_RO) ? "[RO]" : "[readonly]") : "",
	    (curbuf_changed() || curbuf->b_notedited || curbuf->b_p_ro) ?
								    " " : "");
    n = (int)(((long)curwin->w_cursor.lnum * 100L) /
					    (long)curbuf->b_ml.ml_line_count);
    if (curbuf->b_ml.ml_flags & ML_EMPTY)
    {
	STRCPY(buffer + STRLEN(buffer), no_lines_msg);
    }
    else if (p_ru)
    {
	/* Current line and column are already on the screen -- webb */
	sprintf((char *)buffer + STRLEN(buffer),
	    "%ld line%s --%d%%--",
	    (long)curbuf->b_ml.ml_line_count,
	    plural((long)curbuf->b_ml.ml_line_count),
	    n);
    }
    else
    {
	sprintf((char *)buffer + STRLEN(buffer),
	    "line %ld of %ld --%d%%-- col ",
	    (long)curwin->w_cursor.lnum,
	    (long)curbuf->b_ml.ml_line_count,
	    n);
	validate_virtcol();
	col_print(buffer + STRLEN(buffer),
		   (int)curwin->w_cursor.col + 1, (int)curwin->w_virtcol + 1);
    }

    (void)append_arg_number(buffer, !shortmess(SHM_FILE), IOSIZE);

    if (dont_truncate)
	msg(buffer);
    else
	msg_trunc_attr(buffer, FALSE, 0);

    vim_free(buffer);
}

/*
 * Give some info about the position of the cursor (for "g CTRL-G").
 */
    void
cursor_pos_info()
{
    char_u	*p;
    char_u	buf1[20];
    char_u	buf2[20];
    linenr_t	lnum;
    long	char_count = 0;
    long	char_count_cursor = 0;
    int	    eol_size;

    /*
     * Compute the length of the file in characters.
     */
    if (curbuf->b_ml.ml_flags & ML_EMPTY)
    {
	MSG(no_lines_msg);
    }
    else
    {
	if (get_fileformat(curbuf) == EOL_DOS)
	    eol_size = 2;
	else
	    eol_size = 1;
	for (lnum = 1; lnum <= curbuf->b_ml.ml_line_count; ++lnum)
	{
	    if (lnum == curwin->w_cursor.lnum)
		char_count_cursor = char_count + curwin->w_cursor.col + 1;
	    char_count += STRLEN(ml_get(lnum)) + eol_size;
	}
	if (!curbuf->b_p_eol && curbuf->b_p_bin)
	    char_count -= eol_size;

	p = ml_get_curline();
	validate_virtcol();
	col_print(buf1, (int)curwin->w_cursor.col + 1,
						  (int)curwin->w_virtcol + 1);
	col_print(buf2, (int)STRLEN(p), linetabsize(p));

	sprintf((char *)IObuff, "Col %s of %s; Line %ld of %ld; Char %ld of %ld",
		(char *)buf1, (char *)buf2,
		(long)curwin->w_cursor.lnum, (long)curbuf->b_ml.ml_line_count,
		char_count_cursor, char_count);
	msg(IObuff);
    }
}

    void
col_print(buf, col, vcol)
    char_u  *buf;
    int	    col;
    int	    vcol;
{
    if (col == vcol)
	sprintf((char *)buf, "%d", col);
    else
	sprintf((char *)buf, "%d-%d", col, vcol);
}

/*
 * put file name in title bar of window and in icon title
 */

static char_u *lasttitle = NULL;
static char_u *lasticon = NULL;

    void
maketitle()
{
    char_u	*t_name;
    char_u	*i_name;
    int		maxlen;
    int		len;
    char_u	*buf = NULL;

    if (curbuf->b_ffname == NULL)
    {
	t_name = (char_u *)"VIM -";
	i_name = (char_u *)"No File";
    }
    else
    {
	buf = alloc(IOSIZE);
	if (buf == NULL)
	    return;
	STRCPY(buf, "VIM - ");
	home_replace(curbuf, curbuf->b_ffname, buf + 6, IOSIZE - 6, TRUE);
	append_arg_number(buf, FALSE, IOSIZE);
	if (p_titlelen > 0)
	{
	    maxlen = p_titlelen * Columns / 100;
	    if (maxlen < 10)
		maxlen = 10;
	    len = STRLEN(buf);
	    if (len > maxlen)
	    {
		mch_memmove(buf + 6, buf + 6 + len - maxlen,
							  (size_t)maxlen - 5);
		buf[5] = '<';
	    }
	}
	t_name = buf;
	i_name = gettail(curbuf->b_ffname); /* use file name only for icon */
    }

    vim_free(lasttitle);
    lasttitle = NULL;
    if (p_title)
    {
	if (*p_titlestring)
	    lasttitle = vim_strsave(p_titlestring);
	else if ((lasttitle = alloc((unsigned)(vim_strsize(t_name) + 1)))
								      != NULL)
	{
	    *lasttitle = NUL;
	    while (*t_name)
		STRCAT(lasttitle, transchar(*t_name++));
	}
    }
    vim_free(buf);

    vim_free(lasticon);
    lasticon = NULL;
    if (p_icon)
    {
	if (*p_iconstring)
	    lasticon = vim_strsave(p_iconstring);
	else if ((lasticon = alloc((unsigned)(vim_strsize(i_name) + 1)))
								      != NULL)
	{
	    *lasticon = NUL;
	    while (*i_name)
		STRCAT(lasticon, transchar(*i_name++));
	}

⌨️ 快捷键说明

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