Ticket #4169: 0001-Selectable-listing-of-various-object-types-from-TAGS.patch
File 0001-Selectable-listing-of-various-object-types-from-TAGS.patch, 33.9 KB (added by psprint, 3 years ago) |
---|
-
lib/keybind.c
From 41b925152221c864d37f425b7a73ea354cbe197e Mon Sep 17 00:00:00 2001 From: Sebastian Gniazdowski <sgniazdowski@gmail.com> Date: Sun, 10 Jan 2021 10:41:55 -0600 Subject: [PATCH] Selectable listing of various object types from TAGS file. --- lib/keybind.c | 5 + lib/keybind.h | 5 + lib/strutil.h | 2 + lib/strutil/strutil.c | 32 ++++++ misc/mc.default.keymap | 5 + src/editor/edit-impl.h | 3 +- src/editor/edit.c | 17 ++- src/editor/editcmd.c | 183 ++++++++++++++++++++++++-------- src/editor/editcmd_dialogs.c | 122 +++++++++------------- src/editor/editcmd_dialogs.h | 6 +- src/editor/etags.c | 197 +++++++++++++++++++++++++++++++++++ src/editor/etags.h | 36 ++++++- src/keybind-defaults.c | 5 + 13 files changed, 491 insertions(+), 127 deletions(-) diff --git a/lib/keybind.c b/lib/keybind.c index abd44d3e2..41a39579b 100644
a b static name_keymap_t command_names[] = { 152 152 ADD_KEYMAP_NAME (ViewRaw), 153 153 ADD_KEYMAP_NAME (ViewFile), 154 154 ADD_KEYMAP_NAME (ViewFiltered), 155 ADD_KEYMAP_NAME (SelectFunction), 156 ADD_KEYMAP_NAME (SelectVariable), 157 ADD_KEYMAP_NAME (SelectType), 158 ADD_KEYMAP_NAME (SelectOther), 159 ADD_KEYMAP_NAME (SelectAllKinds), 155 160 ADD_KEYMAP_NAME (Find), 156 161 ADD_KEYMAP_NAME (DirSize), 157 162 ADD_KEYMAP_NAME (CompareDirs), -
lib/keybind.h
diff --git a/lib/keybind.h b/lib/keybind.h index 9638bd651..92f496479 100644
a b enum 139 139 CK_ViewRaw, 140 140 CK_ViewFile, 141 141 CK_ViewFiltered, 142 CK_SelectFunction, 143 CK_SelectVariable, 144 CK_SelectType, 145 CK_SelectOther, 146 CK_SelectAllKinds, 142 147 CK_Find, 143 148 CK_DirSize, 144 149 CK_HotListAdd, -
lib/strutil.h
diff --git a/lib/strutil.h b/lib/strutil.h index a091c25aa..abfe4014d 100644
a b strtol_error_t xstrtoumax (const char *s, char **ptr, int base, uintmax_t * val, 582 582 const char *valid_suffixes); 583 583 uintmax_t parse_integer (const char *str, gboolean * invalid); 584 584 585 char *str_collapse_whitespace(char *s, char overwrite_char); 586 585 587 /* --------------------------------------------------------------------------------------------- */ 586 588 /*** inline functions ****************************************************************************/ 587 589 /* --------------------------------------------------------------------------------------------- */ -
lib/strutil/strutil.c
diff --git a/lib/strutil/strutil.c b/lib/strutil/strutil.c index cf11d00d8..adc29c406 100644
a b 29 29 #include <langinfo.h> 30 30 #include <string.h> 31 31 #include <errno.h> 32 #include <ctype.h> 32 33 33 34 #include "lib/global.h" 34 35 #include "lib/util.h" /* MC_PTR_FREE */ … … parse_integer (const char *str, gboolean * invalid) 1021 1022 } 1022 1023 1023 1024 /* --------------------------------------------------------------------------------------------- */ 1025 1026 char *str_collapse_whitespace(char *s, char overwrite_char) 1027 { 1028 int i, wi=0, size, span=0; 1029 size=strlen(s); 1030 1031 /* Skip leading whitespace. */ 1032 for (i=0; i<size; i++) { 1033 if (!isspace(s[i])) 1034 break; 1035 } 1036 1037 /* Collapse remaining whitespace. */ 1038 for (; i<size; i++) { 1039 if (isspace(s[i])) // == ' ') 1040 span=1; 1041 else { 1042 if(span) 1043 s[wi++] = overwrite_space; 1044 1045 s[wi++] = s[i]; 1046 span = 0; 1047 } 1048 } 1049 1050 s[wi]='\0'; 1051 1052 return s; 1053 } 1054 1055 /* --------------------------------------------------------------------------------------------- */ -
misc/mc.default.keymap
diff --git a/misc/mc.default.keymap b/misc/mc.default.keymap index 1bf68b2df..721e85022 100644
a b SpellCheckCurrentWord = ctrl-p 387 387 # WindowNext = 388 388 # WindowPrev = 389 389 # ExtendedKeyMap = 390 SelectFunction = alt-shift-f 391 SelectVariable = alt-shift-v 392 SelectType = alt-shift-t 393 SelectOther = alt-shift-o 394 SelectAllKinds = alt-shift-a 390 395 391 396 [viewer] 392 397 Help = f1 -
src/editor/edit-impl.h
diff --git a/src/editor/edit-impl.h b/src/editor/edit-impl.h index 3ad04dbea..dd996face 100644
a b 18 18 #include "lib/vfs/vfs.h" /* vfs_path_t */ 19 19 20 20 #include "edit.h" 21 #include "etags.h" 21 22 22 23 /*** typedefs(not structures) and defined constants **********************************************/ 23 24 … … mc_search_cbret_t edit_search_cmd_callback (const void *user_data, gsize char_of 202 203 mc_search_cbret_t edit_search_update_callback (const void *user_data, gsize char_offset); 203 204 204 205 void edit_complete_word_cmd (WEdit * edit); 205 void edit_ get_match_keyword_cmd (WEdit * edit);206 void edit_select_object_from_tags(WEdit * edit, etags_jump_type_t type); 206 207 207 208 #ifdef HAVE_ASPELL 208 209 int edit_suggest_current_word (WEdit * edit); -
src/editor/edit.c
diff --git a/src/editor/edit.c b/src/editor/edit.c index e13be389a..0e7e75867 100644
a b edit_execute_cmd (WEdit * edit, long command, int char_for_insertion) 3860 3860 else 3861 3861 edit_complete_word_cmd (edit); 3862 3862 break; 3863 case CK_SelectFunction: 3864 edit_select_object_from_tags(edit, TAG_JUMP_KIND_FUNCTION_LIST); 3865 break; 3866 case CK_SelectVariable: 3867 edit_select_object_from_tags(edit, TAG_JUMP_KIND_VAR_LIST); 3868 break; 3869 case CK_SelectType: 3870 edit_select_object_from_tags(edit, TAG_JUMP_KIND_TYPE_LIST); 3871 break; 3872 case CK_SelectOther: 3873 edit_select_object_from_tags(edit, TAG_JUMP_KIND_OTHER_LIST); 3874 break; 3875 case CK_SelectAllKinds: 3876 edit_select_object_from_tags(edit, TAG_JUMP_KIND_ANY_LIST); 3877 break; 3863 3878 case CK_Find: 3864 edit_ get_match_keyword_cmd (edit);3879 edit_select_object_from_tags(edit, TAG_JUMP_KIND_MATCH_WORD); 3865 3880 break; 3866 3881 3867 3882 #ifdef HAVE_ASPELL -
src/editor/editcmd.c
diff --git a/src/editor/editcmd.c b/src/editor/editcmd.c index e2b904604..4265cd8fc 100644
a b edit_find_word_start (const edit_buffer_t * buf, off_t * word_start, gsize * wor 1140 1140 return FALSE; 1141 1141 1142 1142 c = edit_buffer_get_previous_byte (buf); 1143 /* return if not at end or in word*/1143 /* return if the word is empty */ 1144 1144 if (is_break_char (c)) 1145 1145 return FALSE; 1146 1146 … … edit_find_word_start (const edit_buffer_t * buf, off_t * word_start, gsize * wor 1169 1169 return TRUE; 1170 1170 } 1171 1171 1172 /* Gets the word on the left of the cursor. 1173 * 1174 * @param buf The edit buffer. 1175 * @param initial Initial contents of the result. 1176 * @param release_on_empty Should the initial g_string be released when returning NULL. 1177 * @return g_string with the word or NULL if the word is empty. 1178 */ 1179 static GString * 1180 edit_get_left_whole_word(const edit_buffer_t * buf, GString *initial, gboolean release_on_empty) 1181 { 1182 GString *ret = initial; 1183 gsize i, word_len = 0; 1184 off_t word_start = 0; 1185 1186 /* Search start of word left of cursor. */ 1187 if (!edit_find_word_start (buf, &word_start, &word_len)) { 1188 if (initial && release_on_empty) 1189 g_string_free(initial, TRUE); 1190 return NULL; 1191 } 1192 1193 /* ret = g_strdup_printf ("\\b%.*s[a-zA-Z_0-9]+", word_len, bufpos); */ 1194 if (!ret) 1195 ret = g_string_sized_new (SHORT_DEF_LEN); 1196 1197 for (i = 0; i < word_len; i++) 1198 g_string_append_c (ret, edit_buffer_get_byte (buf, word_start + i)); 1199 1200 return ret; 1201 } 1202 1172 1203 /* --------------------------------------------------------------------------------------------- */ 1173 1204 /** 1174 1205 * Get current word under cursor … … edit_load_back_cmd (WEdit * edit) 3501 3532 /* --------------------------------------------------------------------------------------------- */ 3502 3533 3503 3534 void 3504 edit_ get_match_keyword_cmd (WEdit * edit)3535 edit_select_object_from_tags(WEdit * edit, etags_jump_type_t type) 3505 3536 { 3506 gsize word_len = 0, max_len = 0; 3507 int num_def = 0; 3508 gsize i; 3509 off_t word_start = 0; 3510 GString *match_expr; 3511 char *path = NULL; 3512 char *ptr = NULL; 3513 char *tagfile = NULL; 3537 int i, num_obj, max_len; 3514 3538 3515 etags_hash_t def_hash[MAX_DEFINITIONS]; 3539 /* Group 0-initialized pointers into a struct for easy initialization. */ 3540 struct { 3541 const char *fname0; char *fname, *tagfile, *path, *ptr; 3542 GString *match_expr; 3543 etags_hash_t found_func[MAX_TAG_OBJECTS], *selected_object; 3544 } var = {0}; 3516 3545 3517 for (i = 0; i < MAX_DEFINITIONS; i++) 3518 def_hash[i].filename = NULL; 3519 3520 /* search start of word to be completed */ 3521 if (!edit_find_word_start (&edit->buffer, &word_start, &word_len)) 3546 /* No file means no entries in tags file → exit. */ 3547 if (edit->filename_vpath == NULL) 3522 3548 return; 3523 3549 3524 /* prepare match expression*/3525 match_expr = g_string_sized_new (word_len);3526 for (i = 0; i < word_len; i++)3527 g_string_append_c (match_expr, edit_buffer_get_byte (&edit->buffer, word_start + i));3550 /* Set up current directory variable. */ 3551 var.ptr = g_get_current_dir (); 3552 var.path = g_strconcat (var.ptr, PATH_SEP_STR, (char *) NULL); 3553 g_free (var.ptr); 3528 3554 3529 ptr = g_get_current_dir (); 3530 path = g_strconcat (ptr, PATH_SEP_STR, (char *) NULL); 3531 g_free (ptr); 3555 /* Locate the tags file and its directory. */ 3556 etags_locate_tags_file(&var.tagfile, &var.path); 3532 3557 3533 /* Recursive search file 'TAGS' in parent dirs */ 3534 do 3535 { 3536 ptr = g_path_get_dirname (path); 3537 g_free (path); 3538 path = ptr; 3539 g_free (tagfile); 3540 tagfile = mc_build_filename (path, TAGS_NAME, (char *) NULL); 3541 if (exist_file (tagfile)) 3542 break; 3558 if (!var.tagfile) 3559 goto exit_jump_tag_obj; 3560 3561 if (type >= TAG_JUMP_KIND_FUNCTION_LIST && type <= TAG_JUMP_KIND_ANY_LIST) { 3562 /* Establish the base relative filename of current buffer. */ 3563 var.fname0 = vfs_path_as_str (edit->filename_vpath); 3564 if (g_str_has_prefix(var.fname0, var.path)) { 3565 var.fname0 = var.fname0 + strlen(var.path) + 1; 3566 var.fname = g_strdup(var.fname0); 3567 } else 3568 /* A fallback that shouldn't be needed and is unreliable. */ 3569 var.fname = g_path_get_basename(var.fname0); 3570 var.match_expr = g_string_new(var.fname); 3571 } else if (type == TAG_JUMP_KIND_MATCH_WORD) { 3572 // The function releases the string on empty word result. 3573 var.match_expr = edit_get_left_whole_word(&edit->buffer, NULL, FALSE); 3574 3575 if(!var.match_expr) 3576 goto exit_jump_tag_obj; 3577 3578 } else 3579 goto exit_jump_tag_obj; 3580 3581 if (type >= TAG_JUMP_KIND_FUNCTION_LIST && type <= TAG_JUMP_KIND_ANY_LIST) { 3582 num_obj = etags_get_objects_for_file(type, var.tagfile, var.path, var.fname, (etags_hash_t *) 3583 &var.found_func, &max_len, MAX_TAG_OBJECTS); 3584 } else { 3585 max_len = MAX_WIDTH_DEF_DIALOG; 3586 num_obj = etags_set_definition_hash (var.tagfile, var.path, var.match_expr->str, (etags_hash_t *) 3587 &var.found_func); 3543 3588 } 3544 while (strcmp (path, PATH_SEP_STR) != 0);3545 3589 3546 if (tagfile != NULL) 3547 { 3548 num_def = 3549 etags_set_definition_hash (tagfile, path, match_expr->str, (etags_hash_t *) & def_hash); 3550 g_free (tagfile); 3590 /* Show the list. */ 3591 if (num_obj > 0) 3592 var.selected_object = editcmd_dialog_select_tags_object_show (edit, var.fname, max_len, 3593 (etags_hash_t *) & var.found_func, type, num_obj); 3594 3595 if (var.selected_object) { 3596 int line = var.selected_object->line; 3597 3598 /* Move the display to the function line. */ 3599 if (type >= TAG_JUMP_KIND_FUNCTION_LIST && type <= TAG_JUMP_KIND_ANY_LIST) { 3600 edit_move_display (edit, line - WIDGET (edit)->lines / 2 - 1); 3601 edit_move_to_line (edit, line - 1); 3602 edit->force |= REDRAW_COMPLETELY; 3603 } else { 3604 char *fullpath = var.selected_object->fullpath; 3605 gboolean do_moveto = FALSE; 3606 if (!edit->modified) 3607 do_moveto = TRUE; 3608 else if (!edit_query_dialog2 3609 (_("Warning"), 3610 _("Current text was modified without a file save.\n" 3611 "Continue discards these changes."), _("C&ontinue"), _("&Cancel"))) 3612 { 3613 edit->force |= REDRAW_COMPLETELY; 3614 do_moveto = TRUE; 3615 } 3616 3617 if (do_moveto) { 3618 /* Replace the file in current editor (no new file is opened). */ 3619 vfs_path_free (edit_history_moveto[edit_stack_iterator].filename_vpath); 3620 3621 if (edit->dir_vpath != NULL) 3622 edit_history_moveto[edit_stack_iterator].filename_vpath = 3623 vfs_path_append_vpath_new (edit->dir_vpath, edit->filename_vpath, NULL); 3624 else 3625 edit_history_moveto[edit_stack_iterator].filename_vpath = 3626 vfs_path_clone (edit->filename_vpath); 3627 3628 edit_history_moveto[edit_stack_iterator].line = edit->start_line + edit->curs_row + 1; 3629 edit_stack_iterator++; 3630 vfs_path_free (edit_history_moveto[edit_stack_iterator].filename_vpath); 3631 edit_history_moveto[edit_stack_iterator].filename_vpath = 3632 vfs_path_from_str ((char *) fullpath); 3633 edit_history_moveto[edit_stack_iterator].line = line; 3634 edit_reload_line (edit, edit_history_moveto[edit_stack_iterator].filename_vpath, 3635 edit_history_moveto[edit_stack_iterator].line); 3636 } 3637 } 3551 3638 } 3552 g_free (path); 3639 exit_jump_tag_obj: 3640 /* Clear results hash */ 3641 for (i = 0; i < num_obj; i++) 3642 g_free (var.found_func[i].filename); 3553 3643 3554 max_len = MAX_WIDTH_DEF_DIALOG; 3555 word_len = 0; 3556 if (num_def > 0) 3557 editcmd_dialog_select_definition_show (edit, match_expr->str, max_len, word_len, 3558 (etags_hash_t *) & def_hash, num_def); 3559 g_string_free (match_expr, TRUE); 3644 /* Release other variables. */ 3645 g_free(var.fname); 3646 g_free(var.tagfile); 3647 g_free(var.path); 3648 3649 if (var.match_expr) 3650 g_string_free(var.match_expr, TRUE); 3560 3651 } 3561 3652 3562 3653 /* --------------------------------------------------------------------------------------------- */ -
src/editor/editcmd_dialogs.c
diff --git a/src/editor/editcmd_dialogs.c b/src/editor/editcmd_dialogs.c index 8b3634f23..07f81b156 100644
a b editcmd_dialog_completion_show (const WEdit * edit, int max_len, GString ** comp 408 408 } 409 409 410 410 /* --------------------------------------------------------------------------------------------- */ 411 /* let the user select where function definition*/411 /* function and data structure selection dialog */ 412 412 413 void 414 editcmd_dialog_select_definition_show (WEdit * edit, char *match_expr, int max_len, int word_len, 415 etags_hash_t * def_hash, int num_lines) 413 etags_hash_t * 414 editcmd_dialog_select_tags_object_show (WEdit * edit, char *match_expr, int max_len, 415 etags_hash_t * all_found, etags_jump_type_t type, 416 int num_lines) 416 417 { 417 int start_x, start_y, offset, i; 418 int start_x, start_y, offset, i, selected_on_start = 0; 419 gboolean found_current = FALSE; 418 420 char *curr = NULL; 419 WDialog *def_dlg; 420 WListbox *def_list; 421 int def_dlg_h; /* dialog height */ 422 int def_dlg_w; /* dialog width */ 421 WDialog *func_dlg; 422 WListbox *func_list; 423 int func_dlg_h; /* dialog height */ 424 int func_dlg_w; /* dialog width */ 425 etags_hash_t *selection_data = NULL; 423 426 424 (void) word_len;425 427 /* calculate the dialog metrics */ 426 def_dlg_h = num_lines + 2;427 def_dlg_w = max_len+ 4;428 start_x = edit->curs_col + edit->start_col - ( def_dlg_w / 2) +428 func_dlg_h = num_lines + 2; 429 func_dlg_w = max_len >= MAX_WIDTH_DEF_DIALOG/2 ? max_len + 4 : MAX_WIDTH_DEF_DIALOG/2 + 4; 430 start_x = edit->curs_col + edit->start_col - (func_dlg_w / 2) + 429 431 EDIT_TEXT_HORIZONTAL_OFFSET + (edit->fullscreen ? 0 : 1) + option_line_state_width; 430 432 start_y = edit->curs_row + EDIT_TEXT_VERTICAL_OFFSET + (edit->fullscreen ? 0 : 1) + 1; 431 433 432 434 if (start_x < 0) 433 435 start_x = 0; 434 if ( def_dlg_w > COLS)435 def_dlg_w = COLS;436 if ( def_dlg_h > LINES - 2)437 def_dlg_h = LINES - 2;436 if (func_dlg_w > COLS) 437 func_dlg_w = COLS; 438 if (func_dlg_h > LINES - 2) 439 func_dlg_h = LINES - 2; 438 440 439 offset = start_x + def_dlg_w - COLS;441 offset = start_x + func_dlg_w - COLS; 440 442 if (offset > 0) 441 443 start_x -= offset; 442 offset = start_y + def_dlg_h - LINES;444 offset = start_y + func_dlg_h - LINES; 443 445 if (offset > 0) 444 446 start_y -= (offset + 1); 445 447 446 def_dlg = dlg_create (TRUE, start_y, start_x, def_dlg_h, def_dlg_w, WPOS_KEEP_DEFAULT, TRUE,448 func_dlg = dlg_create (TRUE, start_y, start_x, func_dlg_h, func_dlg_w, WPOS_KEEP_DEFAULT, TRUE, 447 449 dialog_colors, NULL, NULL, "[Definitions]", match_expr); 448 def_list = listbox_new (1, 1, def_dlg_h - 2, def_dlg_w - 2, FALSE, NULL);449 group_add_widget (GROUP ( def_dlg), def_list);450 func_list = listbox_new (1, 1, func_dlg_h - 2, func_dlg_w - 2, FALSE, NULL); 451 group_add_widget (GROUP (func_dlg), func_list); 450 452 451 453 /* fill the listbox with the completions */ 452 454 for (i = 0; i < num_lines; i++) 453 455 { 454 char *label _def;456 char *label = NULL; 455 457 456 label_def = 457 g_strdup_printf ("%s -> %s:%ld", def_hash[i].short_define, def_hash[i].filename, 458 def_hash[i].line); 459 listbox_add_item (def_list, LISTBOX_APPEND_AT_END, 0, label_def, &def_hash[i], FALSE); 460 g_free (label_def); 458 if (type >= TAG_JUMP_KIND_FUNCTION_LIST && type <= TAG_JUMP_KIND_ANY_LIST) 459 label = all_found[i].short_define; 460 else if (type == TAG_JUMP_KIND_MATCH_WORD) 461 label = 462 g_strdup_printf ("%s -> %s:%ld", all_found[i].short_define, all_found[i].filename, 463 all_found[i].line); 464 else 465 label = g_strdup("error"); 466 listbox_add_item (func_list, LISTBOX_APPEND_AT_END, 0, label, &all_found[i], FALSE); 467 g_free (label); 468 469 /* Detect currently active code segment. */ 470 if ((all_found[i].line - 1) <= edit->buffer.curs_line) { 471 found_current = TRUE; 472 selected_on_start = i; 473 } 461 474 } 475 if (found_current) 476 listbox_select_entry(func_list, selected_on_start); 477 /* Option to enable Multi Search from the start. */ 478 listbox_conditionally_enable_multi_search(func_list); 462 479 463 480 /* pop up the dialog and apply the chosen completion */ 464 if (dlg_run (def_dlg) == B_ENTER) 465 { 466 etags_hash_t *curr_def = NULL; 467 gboolean do_moveto = FALSE; 468 469 listbox_get_current (def_list, &curr, (void **) &curr_def); 470 471 if (!edit->modified) 472 do_moveto = TRUE; 473 else if (!edit_query_dialog2 474 (_("Warning"), 475 _("Current text was modified without a file save.\n" 476 "Continue discards these changes."), _("C&ontinue"), _("&Cancel"))) 477 { 478 edit->force |= REDRAW_COMPLETELY; 479 do_moveto = TRUE; 480 } 481 482 if (curr != NULL && do_moveto && edit_stack_iterator + 1 < MAX_HISTORY_MOVETO) 483 { 484 vfs_path_free (edit_history_moveto[edit_stack_iterator].filename_vpath); 485 486 if (edit->dir_vpath != NULL) 487 edit_history_moveto[edit_stack_iterator].filename_vpath = 488 vfs_path_append_vpath_new (edit->dir_vpath, edit->filename_vpath, NULL); 489 else 490 edit_history_moveto[edit_stack_iterator].filename_vpath = 491 vfs_path_clone (edit->filename_vpath); 492 493 edit_history_moveto[edit_stack_iterator].line = edit->start_line + edit->curs_row + 1; 494 edit_stack_iterator++; 495 vfs_path_free (edit_history_moveto[edit_stack_iterator].filename_vpath); 496 edit_history_moveto[edit_stack_iterator].filename_vpath = 497 vfs_path_from_str ((char *) curr_def->fullpath); 498 edit_history_moveto[edit_stack_iterator].line = curr_def->line; 499 edit_reload_line (edit, edit_history_moveto[edit_stack_iterator].filename_vpath, 500 edit_history_moveto[edit_stack_iterator].line); 501 } 502 } 503 504 /* clear definition hash */ 505 for (i = 0; i < MAX_DEFINITIONS; i++) 506 g_free (def_hash[i].filename); 481 if (dlg_run (func_dlg) == B_ENTER) 482 listbox_get_current (func_list, &curr, (void **) &selection_data); 507 483 508 484 /* destroy dialog before return */ 509 dlg_destroy (def_dlg); 485 dlg_destroy (func_dlg); 486 487 return selection_data; 510 488 } 511 489 512 490 /* --------------------------------------------------------------------------------------------- */ -
src/editor/editcmd_dialogs.h
diff --git a/src/editor/editcmd_dialogs.h b/src/editor/editcmd_dialogs.h index f691c857e..8d6a7933a 100644
a b 5 5 6 6 /*** typedefs(not structures) and defined constants **********************************************/ 7 7 8 struct etags_hash_struct;8 typedef struct etags_hash_struct etags_hash_t; 9 9 10 10 #define B_REPLACE_ALL (B_USER+1) 11 11 #define B_REPLACE_ONE (B_USER+2) … … int editcmd_dialog_raw_key_query (const char *heading, const char *query, gboole 28 28 char *editcmd_dialog_completion_show (const WEdit * edit, int max_len, GString ** compl, 29 29 int num_compl); 30 30 31 void editcmd_dialog_select_definition_show (WEdit *, char *, int, int, struct etags_hash_struct *,32 int);31 etags_hash_t *editcmd_dialog_select_tags_object_show (WEdit *, char *, int, etags_hash_t *, 32 etags_jump_type_t, int); 33 33 34 34 int editcmd_dialog_replace_prompt_show (WEdit *, char *, char *, int, int); 35 35 /*** inline functions ****************************************************************************/ -
src/editor/etags.c
diff --git a/src/editor/etags.c b/src/editor/etags.c index 35c7a2f04..952df9b99 100644
a b 39 39 40 40 #include "lib/global.h" 41 41 #include "lib/util.h" /* canonicalize_pathname() */ 42 #include "lib/fileloc.h" 43 #include "lib/strutil.h" 42 44 43 45 #include "etags.h" 44 46 … … 53 55 /*** file scope functions ************************************************************************/ 54 56 /* --------------------------------------------------------------------------------------------- */ 55 57 58 int 59 etags_locate_tags_file(char **tagfile_return, char **path_return) { 60 char *tagfile = *tagfile_return, *path = *path_return, *ptr = NULL; 61 int search_result = 0; 62 63 /* Recursive search file 'TAGS' in parent dirs */ 64 do 65 { 66 ptr = g_path_get_dirname (path); 67 g_free (path); 68 path = ptr; 69 g_free (tagfile); 70 tagfile = mc_build_filename (path, TAGS_NAME, (char *) NULL); 71 if (exist_file (tagfile)) { 72 search_result = 1; 73 break; 74 } 75 } 76 while (strcmp (path, PATH_SEP_STR) != 0); 77 78 *tagfile_return = tagfile; 79 *path_return = path; 80 81 return search_result; 82 } 83 56 84 static gboolean 57 85 parse_define (const char *buf, char **long_name, char **short_name, long *line) 58 86 { … … parse_define (const char *buf, char **long_name, char **short_name, long *line) 169 197 /*** public functions ****************************************************************************/ 170 198 /* --------------------------------------------------------------------------------------------- */ 171 199 200 /* Fills the etags info array with ·all· objects of given ·type· (functions, etc.) */ 201 int etags_get_objects_for_file (etags_rank_t type, const char *tagfile, 202 const char *start_path, const char *match_filename, 203 etags_hash_t * functions_hash, 204 int *max_len_return, int size_limit) 205 { 206 /* *INDENT-OFF* */ 207 enum 208 { 209 start, 210 in_filename, 211 in_define 212 } state = start; 213 /* *INDENT-ON* */ 214 215 FILE *f; 216 char buf[BUF_LARGE]; 217 218 int num = 0; /* returned value */ 219 char *filename = NULL; 220 221 if (!match_filename || !tagfile) 222 return 0; 223 224 *max_len_return = 0; 225 226 /* open file with positions */ 227 f = fopen (tagfile, "r"); 228 if (f == NULL) 229 return 0; 230 231 while (fgets (buf, sizeof (buf), f)) 232 { 233 switch (state) 234 { 235 case start: 236 if (buf[0] == 0x0C) 237 { 238 state = in_filename; 239 } 240 break; 241 case in_filename: 242 { 243 size_t pos; 244 245 pos = strcspn (buf, ","); 246 g_free (filename); 247 filename = g_strndup (buf, pos); 248 state = in_define; 249 break; 250 } 251 case in_define: 252 if (buf[0] == 0x0C) 253 { 254 state = in_filename; 255 break; 256 } 257 /* check if the filename matches the requested one */ 258 if (strcmp (filename, match_filename) == 0) 259 { 260 char *longname = NULL; 261 char *shortname = NULL; 262 long line = 0; 263 264 parse_define (buf, &longname, &shortname, &line); 265 if (num < size_limit - 1) 266 { 267 gboolean can_be_func, can_be_var, can_be_type, is_other; 268 269 /* Prepare the work variable. */ 270 char *longname_wr; 271 longname_wr = g_strdup(longname); 272 273 /* Function – if there's '(' in the declaration. */ 274 can_be_func = strstr(longname,"(") != NULL; 275 /* Variable – if there's no parens and no # in the declaration. */ 276 can_be_var = strstr(g_strdelimit(longname_wr,"}{()#",''),"") == NULL; 277 /* Type – if there's a 'struct', 'typedef', 'enum' or '}' in the declaration. */ 278 can_be_type=(strstr(longname,"struct ") || 279 strstr(longname,"typedef ") || 280 strstr(longname,"enum ")) || 281 (strstr(longname, "}") && 282 (g_str_has_suffix(shortname,"_t") || 283 g_str_has_suffix(shortname,"_type"))); 284 /* Other kind – nor any of the above. */ 285 is_other = !can_be_func && !can_be_var && !can_be_type; 286 287 /* Renew the work variable. */ 288 g_free(longname_wr); 289 longname_wr = g_strdup(longname); 290 291 /* A closer examination of type tags. */ 292 if (type == TAG_RANK_TYPES && can_be_type && !can_be_func) { 293 /* 294 * Verify if it's not a struct variable or an enum. 295 * It filters out occurrences such as: 296 * – struct type SHORTNAME … – i.e.: the shortname at 3rd position, because 297 * this means that a struct variable, not a struct type is being defined. 298 */ 299 gchar **words = g_strsplit(str_collapse_whitespace(longname_wr, ' ')," ", -1); 300 if (words[2] && strcmp(words[2], shortname) == 0) 301 can_be_type = FALSE; 302 g_strfreev(words); 303 } 304 305 /* A closer examination of variable tags. */ 306 if (type == TAG_RANK_VARIABLES && can_be_var) { 307 /* Verify if it's not a struct typedef or an enum. */ 308 gchar **words = g_strsplit(str_collapse_whitespace(longname_wr, ' ')," ", -1); 309 if (strcmp(words[0], "typedef") == 0 || !words[0] || !words[1]) 310 can_be_var = FALSE; 311 /* Most probably an enum ENUM = 0|1|… assignment. */ 312 if (!words[0] || strstr(words[0], "=") || (words[1] && words[1][0] == '=')) 313 can_be_var = FALSE; 314 g_strfreev(words); 315 } 316 317 /* Free the work variable. */ 318 g_free(longname_wr); 319 320 /* Is the object of the requested type? */ 321 if (type == TAG_RANK_ANY || 322 ((type == TAG_RANK_FUNCTIONS && can_be_func) || 323 (type == TAG_RANK_VARIABLES && can_be_var) || 324 (type == TAG_RANK_TYPES && can_be_type) || 325 (type == TAG_RANK_OTHER && is_other))) 326 { 327 /* Update the max. length return variable */ 328 int max_len_candidate; 329 max_len_candidate = strlen(shortname); 330 if (*max_len_return < max_len_candidate) 331 *max_len_return = max_len_candidate; 332 333 /* Save the filename. */ 334 functions_hash[num].filename = g_strdup (filename); 335 functions_hash[num].filename_len = strlen (filename); 336 337 /* Save and canonicalize the path to the file. */ 338 functions_hash[num].fullpath = 339 mc_build_filename (start_path, filename, (char *) NULL); 340 canonicalize_pathname (functions_hash[num].fullpath); 341 342 /* Save the short define. */ 343 if (shortname) 344 functions_hash[num].short_define = g_strdup (shortname); 345 else 346 functions_hash[num].short_define = g_strdup (longname); 347 348 /* Save the line number. */ 349 functions_hash[num].line = line; 350 351 /* Increase the count of the matched objects. */ 352 num++; 353 } 354 } 355 } 356 break; 357 default: 358 break; 359 } 360 } 361 362 g_free (filename); 363 fclose (f); 364 return num; 365 } 366 367 /* --------------------------------------------------------------------------------------------- */ 368 172 369 int 173 370 etags_set_definition_hash (const char *tagfile, const char *start_path, 174 371 const char *match_func, etags_hash_t * def_hash) -
src/editor/etags.h
diff --git a/src/editor/etags.h b/src/editor/etags.h index be71b3a27..a0eb77710 100644
a b 6 6 7 7 /*** typedefs(not structures) and defined constants **********************************************/ 8 8 9 #define MAX_WIDTH_DEF_DIALOG 60 /* max width defdialog */10 #define MAX_ DEFINITIONS 60 /* count found entries show */11 #define SHORT_DEF_LEN 3012 #define LONG_DEF_LEN 409 #define MAX_WIDTH_DEF_DIALOG 60 /* max width of the dialog */ 10 #define MAX_TAG_OBJECTS 350 11 #define SHORT_DEF_LEN 70 12 #define LONG_DEF_LEN 70 13 13 #define LINE_DEF_LEN 16 14 14 15 15 /*** enums ***************************************************************************************/ … … typedef struct etags_hash_struct 25 25 long line; 26 26 } etags_hash_t; 27 27 28 29 typedef enum 30 { 31 TAG_JUMP_KIND_FUNCTION_LIST, /* List of functions in current file. */ 32 TAG_JUMP_KIND_TYPE_LIST, /* List of type definitions in current file. */ 33 TAG_JUMP_KIND_VAR_LIST, /* List of variables in current file. */ 34 TAG_JUMP_KIND_OTHER_LIST, /* List of other tag object types for the current file. */ 35 TAG_JUMP_KIND_ANY_LIST, /* List of all tags for current file. */ 36 TAG_JUMP_KIND_MATCH_WORD, /* A list of tag objects matching left word. */ 37 TAG_JUMP_KIND_QUICK_WHOLE_WORD /* Future – instantly jump to the id under cursor, same file */ 38 } etags_jump_type_t; 39 40 typedef enum 41 { 42 TAG_RANK_FUNCTIONS, /* Function definitions */ 43 TAG_RANK_TYPES, /* Types (structs, typedefs, etc.) */ 44 TAG_RANK_VARIABLES, /* Variables */ 45 TAG_RANK_OTHER, /* Other kind (not of the above) */ 46 TAG_RANK_ANY /* All kinds */ 47 } etags_rank_t; 48 28 49 /*** global variables defined in .c file *********************************************************/ 29 50 30 51 /*** declarations of public functions ************************************************************/ … … typedef struct etags_hash_struct 33 54 int etags_set_definition_hash (const char *tagfile, const char *start_path, 34 55 const char *match_func, etags_hash_t * def_hash); 35 56 57 int etags_get_objects_for_file (etags_rank_t type, const char *tagfile, 58 const char *start_path, const char *match_filename, 59 etags_hash_t * functions_hash, 60 int *max_len_return, int size_limit); 61 62 int etags_locate_tags_file(char **tagfile_return, char **path_return); 63 36 64 /*** inline functions ****************************************************************************/ 37 65 #endif /* MC__EDIT_ETAGS_H */ -
src/keybind-defaults.c
diff --git a/src/keybind-defaults.c b/src/keybind-defaults.c index c423e6be4..e16df0ea5 100644
a b static const global_keymap_ini_t default_editor_keymap[] = { 465 465 {"ShowNumbers", "alt-n"}, 466 466 {"ShowTabTws", "alt-underline"}, 467 467 {"SyntaxOnOff", "ctrl-s"}, 468 {"SelectFunction","alt-shift-f"}, 469 {"SelectVariable","alt-shift-v"}, 470 {"SelectType","alt-shift-t"}, 471 {"SelectOther","alt-shift-o"}, 472 {"SelectAllKinds","alt-shift-a"}, 468 473 {"Find", "alt-enter"}, 469 474 {"FilePrev", "alt-minus"}, 470 475 {"FileNext", "alt-plus"},