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

📄 complete.c

📁 ReactOS是一些高手根据Windows XP的内核编写出的类XP。内核实现机理和API函数调用几乎相同。甚至可以兼容XP的程序。喜欢研究系统内核的人可以看一看。
💻 C
📖 第 1 页 / 共 3 页
字号:
                this_char = text[i];
                prev_char = text[i - 1];

                if ((this_char == '&' && (prev_char == '<' || prev_char == '>')) ||
	            (this_char == '|' && prev_char == '>'))
	            in_command_position = 0;
                else if (i > 0 && text [i-1] == '\\') /* Quoted */
	            in_command_position = 0;
	    }
	}
    }

    if (flags & INPUT_COMPLETE_COMMANDS)
    	p = strrchr (word, '`');
    if (flags & (INPUT_COMPLETE_COMMANDS | INPUT_COMPLETE_VARIABLES))
        q = strrchr (word, '$');
    if (flags & INPUT_COMPLETE_HOSTNAMES)
        r = strrchr (word, '@');
    if (q && q [1] == '(' && INPUT_COMPLETE_COMMANDS){
    	if (q > p)
    	    p = q + 1;
    	q = NULL;
    }

    /* Command substitution? */
    if (p > q && p > r){
        matches = completion_matches (p + 1, command_completion_function);
        if (matches)
            *start += p + 1 - word;
    }

    /* Variable name? */
    else if  (q > p && q > r){
        matches = completion_matches (q, variable_completion_function);
        if (matches)
            *start += q - word;
    }

    /* Starts with '@', then look through the known hostnames for
       completion first. */
    else if (r > p && r > q){
        matches = completion_matches (r, hostname_completion_function);
        if (matches)
            *start += r - word;
    }

    /* Starts with `~' and there is no slash in the word, then
       try completing this word as a username. */
    if (!matches && *word == '~' && (flags & INPUT_COMPLETE_USERNAMES) && !strchr (word, PATH_SEP))
        matches = completion_matches (word, username_completion_function);


    /* And finally if this word is in a command position, then
       complete over possible command names, including aliases, functions,
       and command names. */
    if (!matches && in_command_position)
        matches = completion_matches (word, command_completion_function);

    else if (!matches && (flags & INPUT_COMPLETE_FILENAMES)){
    	if (is_cd)
    	    ignore_filenames = 1;
    	matches = completion_matches (word, filename_completion_function);
    	ignore_filenames = 0;
    	if (!matches && is_cd && *word != PATH_SEP && *word != '~'){
    	    char *p, *q = text + *start;

    	    for (p = text; *p && p < q && (*p == ' ' || *p == '\t'); p++);
    	    if (!strncmp (p, "cd", 2))
    	        for (p += 2; *p && p < q && (*p == ' ' || *p == '\t'); p++);
    	    if (p == q){
		char *cdpath = getenv ("CDPATH");
		char c, *s, *r;

		if (cdpath == NULL)
		    c = 0;
		else
		    c = ':';
		while (!matches && c == ':'){
		    s = strchr (cdpath, ':');
		    if (s == NULL)
		        s = strchr (cdpath, 0);
		    c = *s;
		    *s = 0;
		    if (*cdpath){
			r = concat_dir_and_file (cdpath, word);
		        ignore_filenames = 1;
    	    		matches = completion_matches (r, filename_completion_function);
    	    		ignore_filenames = 0;
    	    		free (r);
		    }
		    *s = c;
		    cdpath = s + 1;
		}
    	    }
    	}
    }

    if (word)
    	free (word);

    return matches;
}

void free_completions (WInput *in)
{
    char **p;

    if (!in->completions)
    	return;
    for (p=in->completions; *p; p++)
    	free (*p);
    free (in->completions);
    in->completions = NULL;
}

static int query_height, query_width;
static WInput *input;
static int start, end, min_end;

static int insert_text (WInput *in, char *text, int len)
{
    len = min (len, strlen (text)) + start - end;
    if (strlen (in->buffer) + len >= in->current_max_len){
    /* Expand the buffer */
    	char *narea = realloc(in->buffer, in->current_max_len + len + in->field_len);
	if (narea){
	    in->buffer = narea;
	    in->current_max_len += len + in->field_len;
	}
    }
    if (strlen (in->buffer)+1 < in->current_max_len){
    	if (len > 0){
	    int i, l = strlen (&in->buffer [end]);
	    for (i = l + 1; i >= 0; i--)
	        in->buffer [end + len + i] = in->buffer [end + i];
	} else if (len < 0){
	    char *p = in->buffer + end + len, *q = in->buffer + end;
	    while (*q)
	    	*(p++) = *(q++);
	    *p = 0;
	}
	strncpy (in->buffer + start, text, len - start + end);
	in->point += len;
	update_input (in, 1);
	end += len;
    }
    return len != 0;
}

static int query_callback (Dlg_head * h, int Par, int Msg)
{
    switch (Msg) {
    	case DLG_DRAW:
    	    attrset (COLOR_NORMAL);
	    dlg_erase (h);
    	    draw_box (h, 0, 0, query_height, query_width);
    	    break;

    	case DLG_KEY:
	    switch (Par) {
		case KEY_LEFT:
		case KEY_RIGHT:
	    	    h->ret_value = 0;
		    dlg_stop (h);
	    	    return 1;

	    	case 0177:
	    	case KEY_BACKSPACE:
	    	case XCTRL('h'):
	    	    if (end == min_end){
	    	    	h->ret_value = 0;
			dlg_stop (h);
	    	    	return 1;
	    	    } else {
	    	    	WLEntry *e, *e1;

	    	    	e1 = e = ((WListbox *)(h->current->widget))->list;
	    	    	do {
	    	    	    if (!strncmp (input->buffer + start, e1->text, end - start - 1)){
	    	    	    	listbox_select_entry((WListbox *)(h->current->widget), e1);
	    	    	    	handle_char (input, Par);
	    	    	    	end--;
				send_message (h, h->current->widget,
				    WIDGET_DRAW, 0);
	    	    	    	break;
	    	    	    }
	    	    	    e1 = e1->next;
	    	    	} while (e != e1);
	    	    }
	    	    return 1;

                default:
	    	    if (Par > 0xff || !is_printable (Par)){
	    	    	if (is_in_input_map (input, Par) == 2){
	    	    	    if (end == min_end)
	    	    	        return 1;
	    	    	    h->ret_value = B_USER; /* This means we want to refill the
	    	    	         	              list box and start again */
			    dlg_stop (h);
	    	    	    return 1;
	    	    	} else
	    	    	    return 0;
	    	    } else {
	    	    	WLEntry *e, *e1;
	    	    	int need_redraw = 0;
	    	    	int low = 4096;
	    	    	char *last_text = NULL;

	    	    	e1 = e = ((WListbox *)(h->current->widget))->list;
	    	    	do {
	    	    	    if (!strncmp (input->buffer + start, e1->text, end - start)){
	    	    	        if (e1->text [end - start] == Par){
	    	    	            if (need_redraw){
	    	    	            	register int c1, c2, si;

					for (si = end - start + 1;
					     (c1 = last_text [si]) &&
					     (c2 = e1->text [si]); si++)
		    			    if (c1 != c2)
		    			    	break;
	        			if (low > si)
	        			    low = si;
					last_text = e1->text;
					need_redraw = 2;
	    	    	            } else {
	    	    	            	need_redraw = 1;
	    	    	    	    	listbox_select_entry((WListbox *)(h->current->widget), e1);
	    	    	    	    	last_text = e1->text;
	    	    	    	    }
	    	    	        }
	    	    	    }
	    	    	    e1 = e1->next;
	    	    	} while (e != e1);
	    	    	if (need_redraw == 2){
	    	    	    insert_text (input, last_text, low);
	    	    	    send_message (h, h->current->widget,WIDGET_DRAW,0);
	    	    	} else if (need_redraw == 1){
	    	    	    h->ret_value = B_ENTER;
			    dlg_stop (h);
	    	    	}
	    	    }
	    	    return 1;
	    }
	    break;
    }
    return 0;
}

static int querylist_callback (void *data)
{
    return 1;
}

#define DO_INSERTION 1
#define DO_QUERY     2
/* Returns 1 if the user would like to see us again */
int complete_engine (WInput *in, int what_to_do)
{
    if (in->completions && in->point != end)
    	free_completions (in);
    if (!in->completions){
    	end = in->point;
        for (start = end ? end - 1 : 0; start > -1; start--)
    	    if (strchr (" \t;|<>", in->buffer [start]))
    	        break;
    	if (start < end)
    	    start++;
    	in->completions = try_complete (in->buffer, &start, &end, in->completion_flags);
    }
    if (in->completions){
    	if (what_to_do & DO_INSERTION) {
    	    if (insert_text (in, in->completions [0], strlen (in->completions [0]))){
    	        if (in->completions [1])
    	    	    beep ();
	    } else
	        beep ();
        }
    	if ((what_to_do & DO_QUERY) && in->completions [1]) {
    	    int maxlen = 0, i, count = 0;
    	    int x, y, w, h;
    	    int start_x, start_y;
    	    char **p, *q;
    	    Dlg_head *query_dlg;
    	    WListbox *query_list;

    	    for (p=in->completions + 1; *p; count++, p++)
    	    	if ((i = strlen (*p)) > maxlen)
    	    	    maxlen = i;
    	    start_x = in->widget.x;
    	    start_y = in->widget.y;
    	    if (start_y - 2 >= count) {
    	    	y = start_y - 2 - count;
    	    	h = 2 + count;
    	    } else {
    	    	if (start_y >= LINES - start_y - 1) {
    	    	    y = 0;
    	    	    h = start_y;
    	    	} else {
    	    	    y = start_y + 1;
    	    	    h = LINES - start_y - 1;
    	    	}
    	    }
    	    x = start - in->first_shown - 2 + start_x;
    	    w = maxlen + 4;
    	    if (x + w > COLS)
    	    	x = COLS - w;
    	    if (x < 0)
    	    	x = 0;
    	    if (x + w > COLS)
    	    	w = COLS;
    	    input = in;
    	    min_end = end;
	    query_height = h;
	    query_width  = w;
    	    query_dlg = create_dlg (y, x, query_height, query_width,
				    dialog_colors, query_callback,
				    "[Completion-query]", "complete", DLG_NONE);
    	    query_list = listbox_new (1, 1, w - 2, h - 2, 0, querylist_callback, NULL);
    	    add_widget (query_dlg, query_list);
    	    for (p = in->completions + 1; *p; p++)
    	    	listbox_add_item (query_list, 0, 0, *p, NULL);
    	    run_dlg (query_dlg);
    	    q = NULL;
    	    if (query_dlg->ret_value == B_ENTER){
    	    	listbox_get_current (query_list, &q, NULL);
    	    	if (q)
    	    	    insert_text (in, q, strlen (q));
    	    }
    	    if (q || end != min_end)
    	    	free_completions (in);
    	    i = query_dlg->ret_value; /* B_USER if user wants to start over again */
    	    destroy_dlg (query_dlg);
    	    if (i == B_USER)
    	    	return 1;
    	}
    } else
    	beep ();
    return 0;
}

void complete (WInput *in)
{
    if (in->completions)
    	while (complete_engine (in, DO_QUERY));
    else if (show_all_if_ambiguous){
    	complete_engine (in, DO_INSERTION);
    	while (complete_engine (in, DO_QUERY));
    } else
    	complete_engine (in, DO_INSERTION);
}

⌨️ 快捷键说明

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