static char * extract_arg (char *p, char *arg, int size) { char *np; while (*p && (*p == ' ' || *p == '\t' || *p == '\n')) p++; /* support quote space .mnu */ while (*p && (*p != ' ' || *(p - 1) == '\\') && *p != '\t' && *p != '\n') { np = str_get_next_char (p); if (np - p >= size) break; memcpy (arg, p, np - p); arg += np - p; size -= np - p; p = np; } *arg = 0; if (!*p || *p == '\n') str_prev_char (&p); return p; }
static int complete_engine (WInput * in, int what_to_do) { if (in->completions != NULL && str_offset_to_pos (in->buffer, in->point) != end) input_free_completions (in); if (in->completions == NULL) { char *s; end = str_offset_to_pos (in->buffer, in->point); s = in->buffer; if (in->point != 0) { /* get symbol before in->point */ size_t i; for (i = in->point - 1; i > 0; i--) str_next_char (&s); } for (; s >= in->buffer; str_prev_char (&s)) { start = s - in->buffer; if (strchr (" \t;|<>", *s) != NULL) break; } if (start < end) { str_next_char (&s); start = s - in->buffer; } in->completions = try_complete (in->buffer, &start, &end, in->completion_flags); } if (in->completions != NULL) { if (what_to_do & DO_INSERTION || ((what_to_do & DO_QUERY) && !in->completions[1])) { char *lc_complete = in->completions[0]; if (insert_text (in, lc_complete, strlen (lc_complete))) { if (in->completions[1]) tty_beep (); else input_free_completions (in); } else tty_beep (); } if ((what_to_do & DO_QUERY) && in->completions && 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 != NULL; count++, p++) { i = str_term_width1 (*p); if (i > 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->term_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 (TRUE, y, x, query_height, query_width, dialog_colors, query_callback, NULL, "[Completion]", NULL, DLG_COMPACT); query_list = listbox_new (1, 1, h - 2, w - 2, FALSE, NULL); add_widget (query_dlg, query_list); for (p = in->completions + 1; *p; p++) listbox_add_item (query_list, LISTBOX_APPEND_AT_END, 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) input_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 tty_beep (); return 0; }
static char * test_line (WEdit * edit_widget, char *p, int *result) { int condition; char operator; /* Repeat till end of line */ while (*p && *p != '\n') { char *debug_start, *debug_end; /* support quote space .mnu */ while ((*p == ' ' && *(p - 1) != '\\') || *p == '\t') p++; if (!*p || *p == '\n') break; operator = *p++; if (*p == '?') { debug_flag = 1; p++; } /* support quote space .mnu */ while ((*p == ' ' && *(p - 1) != '\\') || *p == '\t') p++; if (!*p || *p == '\n') break; condition = 1; /* True by default */ debug_start = p; p = test_condition (edit_widget, p, &condition); debug_end = p; /* Add one debug statement */ debug_out (debug_start, debug_end, condition); switch (operator) { case '+': case '=': /* Assignment */ *result = condition; break; case '&': /* Logical and */ *result &= condition; break; case '|': /* Logical or */ *result |= condition; break; default: debug_error = 1; break; } /* switch */ /* Add one debug statement */ debug_out (&operator, NULL, *result); } /* while (*p != '\n') */ /* Report debug message */ debug_out (NULL, NULL, 1); if (!*p || *p == '\n') str_prev_char (&p); return p; }
static char * test_condition (WEdit * edit_widget, char *p, int *condition) { char arg[256]; const mc_search_type_t search_type = easy_patterns ? MC_SEARCH_T_GLOB : MC_SEARCH_T_REGEX; /* Handle one condition */ for (; *p != '\n' && *p != '&' && *p != '|'; p++) { WPanel *panel = NULL; /* support quote space .mnu */ if ((*p == ' ' && *(p - 1) != '\\') || *p == '\t') continue; if (*p >= 'a') panel = current_panel; else if (get_other_type () == view_listing) panel = other_panel; *p |= 0x20; switch (*p++) { case '!': p = test_condition (edit_widget, p, condition); *condition = !*condition; str_prev_char (&p); break; case 'f': /* file name pattern */ p = extract_arg (p, arg, sizeof (arg)); #ifdef USE_INTERNAL_EDIT if (edit_widget != NULL) { char *edit_filename; edit_filename = edit_get_file_name (edit_widget); *condition = mc_search (arg, DEFAULT_CHARSET, edit_filename, search_type) ? 1 : 0; g_free (edit_filename); } else #endif *condition = panel != NULL && mc_search (arg, DEFAULT_CHARSET, panel->dir.list[panel->selected].fname, search_type) ? 1 : 0; break; case 'y': /* syntax pattern */ #ifdef USE_INTERNAL_EDIT if (edit_widget != NULL) { const char *syntax_type = edit_get_syntax_type (edit_widget); if (syntax_type != NULL) { p = extract_arg (p, arg, sizeof (arg)); *condition = mc_search (arg, DEFAULT_CHARSET, syntax_type, MC_SEARCH_T_NORMAL) ? 1 : 0; } } #endif break; case 'd': p = extract_arg (p, arg, sizeof (arg)); *condition = panel != NULL && mc_search (arg, DEFAULT_CHARSET, vfs_path_as_str (panel->cwd_vpath), search_type) ? 1 : 0; break; case 't': p = extract_arg (p, arg, sizeof (arg)); *condition = panel != NULL && test_type (panel, arg) ? 1 : 0; break; case 'x': /* executable */ { struct stat status; p = extract_arg (p, arg, sizeof (arg)); if (stat (arg, &status) == 0) *condition = is_exe (status.st_mode) ? 1 : 0; else *condition = 0; break; } default: debug_error = 1; break; } /* switch */ } /* while */ return p; }