今日の関数 do_search その1 (https://github.com/vim/vim)

vimで検索されると呼ばれる関数です。 検索の実行はsearchitでされますがその前後にoffsetや複数回の検索の調整をこの関数では 行います。

search.c

    int
do_search(
    oparg_T	    *oap,	/* can be NULL */
    int		    dirc,	/* '/' or '?' */
    char_u	    *pat,
    long	    count,
    int		    options,
    proftime_T	    *tm)	/* timeout limit or NULL */
{
    pos_T	    pos;	/* position of the last match */
    char_u	    *searchstr;
    struct soffset  old_off;
    int		    retval;	/* Return value */
    char_u	    *p;
    long	    c;
    char_u	    *dircp;
    char_u	    *strcopy = NULL;
    char_u	    *ps;

変数を初期化します。

 /*
 * A line offset is not remembered, this is vi compatible.
 */
if (spats[0].off.line && vim_strchr(p_cpo, CPO_LINEOFF) != NULL)
{
	spats[0].off.line = FALSE;
	spats[0].off.off = 0;
}

spats[0]の中にある変数を初期化します。vi compatible のためのようです。

/*
 * Save the values for when (options & SEARCH_KEEP) is used.
 * (there is no "if ()" around this because gcc wants them initialized)
 */
old_off = spats[0].off;

pos = curwin->w_cursor;	/* start searching at the cursor position */

SEARCH_KEEPのオプションをつければ前回のoffsetをそのまま使います。 ここでposを今のカーソルの位置にセットしておきます。これでカーソル位置から 検索がされるようになります。

if (dirc == 0)
	dirc = spats[0].off.dir;
	else
{
	spats[0].off.dir = dirc;
#if defined(FEAT_EVAL)
	set_vv_searchforward();
#endif
}

dircは'/'か'?'を指しています。もし何も指していない場合前回と同じdirが使われます。

if (options & SEARCH_REV)
{
#ifdef WIN32
	/* There is a bug in the Visual C++ 2.2 compiler which means that
	 * dirc always ends up being '/' */
	dirc = (dirc == '/')  ?  '?'  :  '/';
#else
	if (dirc == '/')
		dirc = '?';
	else
		dirc = '/';
#endif
}

SEARCH_REVのオプションが有効なら'/'と'?'を反転します。

#ifdef FEAT_FOLDING
/* If the cursor is in a closed fold, don't find another match in the same
 * fold. */
if (dirc == '/')
{
	if (hasFolding(pos.lnum, NULL, &pos.lnum))
		pos.col = MAXCOL - 2;	/* avoid overflow when adding 1 */
}
else
{
	if (hasFolding(pos.lnum, &pos.lnum, NULL))
		pos.col = 0;
}
#endif

カーソルが閉じているfoldにいたらその中の検索はしないために もし'/'前進検索ならカーソルのcolの位置をmaxの位置に持っていき '?'後進検索ならカーソルの位置を行の最初に移動します。 こうすることでもうこの行では検索がマッチしません。

#ifdef FEAT_SEARCH_EXTRA
/*
 * Turn 'hlsearch' highlighting back on.
 */
if (no_hlsearch && !(options & SEARCH_KEEP))
{
	redraw_all_later(SOME_VALID);
	SET_NO_HLSEARCH(FALSE);
}
#endif

FEAT_SEARCH_EXTRAが定義されているならhlsearchをセットします。 hlsearchをセットすると検索で見つかったすべての文字がハイライトされます。