mirror of
https://github.com/MidnightCommander/mc
synced 2024-12-23 04:46:55 +03:00
Merge branch '267_code_navigation_via_etags'
This commit is contained in:
commit
dc80d6821f
@ -10,6 +10,6 @@ libedit_a_SOURCES = \
|
|||||||
bookmark.c edit.c editcmd.c editwidget.c editdraw.c editkeys.c \
|
bookmark.c edit.c editcmd.c editwidget.c editdraw.c editkeys.c \
|
||||||
editmenu.c editoptions.c editcmddef.h edit.h edit-widget.h \
|
editmenu.c editoptions.c editcmddef.h edit.h edit-widget.h \
|
||||||
editlock.c editlock.h syntax.c usermap.h usermap.c wordproc.c \
|
editlock.c editlock.h syntax.c usermap.h usermap.c wordproc.c \
|
||||||
choosesyntax.c
|
choosesyntax.c etags.c etags.h
|
||||||
|
|
||||||
EXTRA_DIST = ChangeLog
|
EXTRA_DIST = ChangeLog
|
||||||
|
35
edit/edit.c
35
edit/edit.c
@ -646,6 +646,31 @@ edit_reload (WEdit *edit, const char *filename)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Load a new file into the editor and set line. If it fails, preserve the old file.
|
||||||
|
* To do it, allocate a new widget, initialize it and, if the new file
|
||||||
|
* was loaded, copy the data to the old widget.
|
||||||
|
* Return 1 on success, 0 on failure.
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
edit_reload_line (WEdit *edit, const char *filename, long line)
|
||||||
|
{
|
||||||
|
WEdit *e;
|
||||||
|
int lines = edit->num_widget_lines;
|
||||||
|
int columns = edit->num_widget_columns;
|
||||||
|
|
||||||
|
e = g_malloc0 (sizeof (WEdit));
|
||||||
|
e->widget = edit->widget;
|
||||||
|
if (!edit_init (e, lines, columns, filename, line)) {
|
||||||
|
g_free (e);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
edit_clean (edit);
|
||||||
|
memcpy (edit, e, sizeof (WEdit));
|
||||||
|
g_free (e);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Recording stack for undo:
|
Recording stack for undo:
|
||||||
@ -2480,6 +2505,13 @@ edit_execute_cmd (WEdit *edit, int command, int char_for_insertion)
|
|||||||
edit_insert_file_cmd (edit);
|
edit_insert_file_cmd (edit);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case CK_Load_Prev_File:
|
||||||
|
edit_load_back_cmd (edit);
|
||||||
|
break;
|
||||||
|
case CK_Load_Next_File:
|
||||||
|
edit_load_forward_cmd (edit);
|
||||||
|
break;
|
||||||
|
|
||||||
case CK_Toggle_Syntax:
|
case CK_Toggle_Syntax:
|
||||||
if ((option_syntax_highlighting ^= 1) == 1)
|
if ((option_syntax_highlighting ^= 1) == 1)
|
||||||
edit_load_syntax (edit, NULL, option_syntax_type);
|
edit_load_syntax (edit, NULL, option_syntax_type);
|
||||||
@ -2501,6 +2533,9 @@ edit_execute_cmd (WEdit *edit, int command, int char_for_insertion)
|
|||||||
case CK_Complete_Word:
|
case CK_Complete_Word:
|
||||||
edit_complete_word_cmd (edit);
|
edit_complete_word_cmd (edit);
|
||||||
break;
|
break;
|
||||||
|
case CK_Find_Definition:
|
||||||
|
edit_get_match_keyword_cmd (edit);
|
||||||
|
break;
|
||||||
|
|
||||||
case CK_Exit:
|
case CK_Exit:
|
||||||
dlg_stop (edit->widget.parent);
|
dlg_stop (edit->widget.parent);
|
||||||
|
10
edit/edit.h
10
edit/edit.h
@ -103,6 +103,14 @@
|
|||||||
#define TAB_SIZE option_tab_spacing
|
#define TAB_SIZE option_tab_spacing
|
||||||
#define HALF_TAB_SIZE ((int) option_tab_spacing / 2)
|
#define HALF_TAB_SIZE ((int) option_tab_spacing / 2)
|
||||||
|
|
||||||
|
/* max count stack files */
|
||||||
|
#define MAX_HISTORY_MOVETO 50
|
||||||
|
|
||||||
|
typedef struct edit_stack_type {
|
||||||
|
long line;
|
||||||
|
char *filename;
|
||||||
|
}edit_stack_type;
|
||||||
|
|
||||||
struct macro {
|
struct macro {
|
||||||
short command;
|
short command;
|
||||||
short ch;
|
short ch;
|
||||||
@ -175,6 +183,8 @@ int edit_save_block (WEdit * edit, const char *filename, long start, long finish
|
|||||||
int edit_save_block_cmd (WEdit * edit);
|
int edit_save_block_cmd (WEdit * edit);
|
||||||
int edit_insert_file_cmd (WEdit * edit);
|
int edit_insert_file_cmd (WEdit * edit);
|
||||||
int edit_insert_file (WEdit * edit, const char *filename);
|
int edit_insert_file (WEdit * edit, const char *filename);
|
||||||
|
int edit_load_back_cmd (WEdit * edit);
|
||||||
|
int edit_load_forward_cmd (WEdit * edit);
|
||||||
void edit_block_process_cmd (WEdit * edit, const char *shell_cmd, int block);
|
void edit_block_process_cmd (WEdit * edit, const char *shell_cmd, int block);
|
||||||
void freestrs (void);
|
void freestrs (void);
|
||||||
void edit_refresh_cmd (WEdit * edit);
|
void edit_refresh_cmd (WEdit * edit);
|
||||||
|
224
edit/editcmd.c
224
edit/editcmd.c
@ -1,4 +1,4 @@
|
|||||||
/* editor high level editing commands.
|
/* editor high level editing commands
|
||||||
|
|
||||||
Copyright (C) 1996, 1997, 1998, 2001, 2002, 2003, 2004, 2005, 2006,
|
Copyright (C) 1996, 1997, 1998, 2001, 2002, 2003, 2004, 2005, 2006,
|
||||||
2007 Free Software Foundation, Inc.
|
2007 Free Software Foundation, Inc.
|
||||||
@ -45,6 +45,8 @@
|
|||||||
#include "editlock.h"
|
#include "editlock.h"
|
||||||
#include "editcmddef.h"
|
#include "editcmddef.h"
|
||||||
#include "edit-widget.h"
|
#include "edit-widget.h"
|
||||||
|
#include "../edit/etags.h"
|
||||||
|
#include "../src/panel.h"
|
||||||
|
|
||||||
#include "../src/color.h" /* dialog_colors */
|
#include "../src/color.h" /* dialog_colors */
|
||||||
#include "../src/tty.h" /* LINES */
|
#include "../src/tty.h" /* LINES */
|
||||||
@ -2795,6 +2797,7 @@ static void
|
|||||||
edit_completion_dialog (WEdit * edit, int max_len, int word_len,
|
edit_completion_dialog (WEdit * edit, int max_len, int word_len,
|
||||||
struct selection *compl, int num_compl)
|
struct selection *compl, int num_compl)
|
||||||
{
|
{
|
||||||
|
|
||||||
int start_x, start_y, offset, i;
|
int start_x, start_y, offset, i;
|
||||||
char *curr = NULL;
|
char *curr = NULL;
|
||||||
Dlg_head *compl_dlg;
|
Dlg_head *compl_dlg;
|
||||||
@ -2883,8 +2886,8 @@ edit_complete_word_cmd (WEdit *edit)
|
|||||||
/* prepare match expression */
|
/* prepare match expression */
|
||||||
bufpos = &edit->buffers1[word_start >> S_EDIT_BUF_SIZE]
|
bufpos = &edit->buffers1[word_start >> S_EDIT_BUF_SIZE]
|
||||||
[word_start & M_EDIT_BUF_SIZE];
|
[word_start & M_EDIT_BUF_SIZE];
|
||||||
match_expr = g_strdup_printf ("%.*s[a-zA-Z_0-9]+", word_len, bufpos);
|
|
||||||
|
|
||||||
|
match_expr = g_strdup_printf ("%.*s[a-zA-Z_0-9]+", word_len, bufpos);
|
||||||
/* init search: backward, regexp, whole word, case sensitive */
|
/* init search: backward, regexp, whole word, case sensitive */
|
||||||
edit_set_search_parameters (0, 1, 1, 1, 1);
|
edit_set_search_parameters (0, 1, 1, 1, 1);
|
||||||
|
|
||||||
@ -2969,3 +2972,220 @@ edit_begin_end_macro_cmd(WEdit *edit)
|
|||||||
edit_execute_key_command (edit, command, -1);
|
edit_execute_key_command (edit, command, -1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
edit_load_forward_cmd (WEdit *edit)
|
||||||
|
{
|
||||||
|
if (edit->modified) {
|
||||||
|
if (edit_query_dialog2
|
||||||
|
(_("Warning"),
|
||||||
|
_(" Current text was modified without a file save. \n"
|
||||||
|
" Continue discards these changes. "), _("C&ontinue"),
|
||||||
|
_("&Cancel"))) {
|
||||||
|
edit->force |= REDRAW_COMPLETELY;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ( edit_stack_iterator + 1 < MAX_HISTORY_MOVETO ) {
|
||||||
|
if ( edit_history_moveto[edit_stack_iterator + 1].line < 1 ) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
edit_stack_iterator++;
|
||||||
|
if ( edit_history_moveto[edit_stack_iterator].filename ) {
|
||||||
|
edit_reload_line (edit, edit_history_moveto[edit_stack_iterator].filename,
|
||||||
|
edit_history_moveto[edit_stack_iterator].line);
|
||||||
|
return 0;
|
||||||
|
} else {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
edit_load_back_cmd (WEdit *edit)
|
||||||
|
{
|
||||||
|
if (edit->modified) {
|
||||||
|
if (edit_query_dialog2
|
||||||
|
(_("Warning"),
|
||||||
|
_(" Current text was modified without a file save. \n"
|
||||||
|
" Continue discards these changes. "), _("C&ontinue"),
|
||||||
|
_("&Cancel"))) {
|
||||||
|
edit->force |= REDRAW_COMPLETELY;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ( edit_stack_iterator > 0 ) {
|
||||||
|
edit_stack_iterator--;
|
||||||
|
if ( edit_history_moveto[edit_stack_iterator].filename ) {
|
||||||
|
edit_reload_line (edit, edit_history_moveto[edit_stack_iterator].filename,
|
||||||
|
edit_history_moveto[edit_stack_iterator].line);
|
||||||
|
return 0;
|
||||||
|
} else {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* let the user select where function definition */
|
||||||
|
static void
|
||||||
|
edit_select_definition_dialog (WEdit * edit, char *match_expr, int max_len, int word_len,
|
||||||
|
etags_hash_t *def_hash, int num_lines)
|
||||||
|
{
|
||||||
|
|
||||||
|
int start_x, start_y, offset, i;
|
||||||
|
char *curr = NULL;
|
||||||
|
etags_hash_t *curr_def;
|
||||||
|
Dlg_head *def_dlg;
|
||||||
|
WListbox *def_list;
|
||||||
|
int def_dlg_h; /* dialog height */
|
||||||
|
int def_dlg_w; /* dialog width */
|
||||||
|
|
||||||
|
/* calculate the dialog metrics */
|
||||||
|
def_dlg_h = num_lines + 2;
|
||||||
|
def_dlg_w = max_len + 4;
|
||||||
|
start_x = edit->curs_col + edit->start_col - (def_dlg_w / 2);
|
||||||
|
start_y = edit->curs_row + EDIT_TEXT_VERTICAL_OFFSET + 1;
|
||||||
|
|
||||||
|
if (start_x < 0)
|
||||||
|
start_x = 0;
|
||||||
|
if (def_dlg_w > COLS)
|
||||||
|
def_dlg_w = COLS;
|
||||||
|
if (def_dlg_h > LINES - 2)
|
||||||
|
def_dlg_h = LINES - 2;
|
||||||
|
|
||||||
|
offset = start_x + def_dlg_w - COLS;
|
||||||
|
if (offset > 0)
|
||||||
|
start_x -= offset;
|
||||||
|
offset = start_y + def_dlg_h - LINES;
|
||||||
|
if (offset > 0)
|
||||||
|
start_y -= (offset + 1);
|
||||||
|
|
||||||
|
/* create the dialog */
|
||||||
|
def_dlg = create_dlg (start_y, start_x, def_dlg_h, def_dlg_w,
|
||||||
|
dialog_colors, NULL, "[Definitions]", match_expr,
|
||||||
|
DLG_COMPACT);
|
||||||
|
|
||||||
|
/* create the listbox */
|
||||||
|
def_list = listbox_new (1, 1, def_dlg_w - 2, def_dlg_h - 2, NULL);
|
||||||
|
|
||||||
|
/* add the dialog */
|
||||||
|
add_widget (def_dlg, def_list);
|
||||||
|
|
||||||
|
char *label_def = NULL;
|
||||||
|
|
||||||
|
/* fill the listbox with the completions */
|
||||||
|
for (i = 0; i < num_lines; i++) {
|
||||||
|
label_def = g_strdup_printf ("%s -> %s:%ld", def_hash[i].short_define, def_hash[i].filename, def_hash[i].line);
|
||||||
|
listbox_add_item (def_list, LISTBOX_APPEND_AT_END, 0, label_def, &def_hash[i]);
|
||||||
|
g_free(label_def);
|
||||||
|
}
|
||||||
|
/* pop up the dialog */
|
||||||
|
run_dlg (def_dlg);
|
||||||
|
|
||||||
|
/* apply the choosen completion */
|
||||||
|
if ( def_dlg->ret_value == B_ENTER ) {
|
||||||
|
listbox_get_current (def_list, &curr, (etags_hash_t *) &curr_def);
|
||||||
|
int do_moveto = 0;
|
||||||
|
if ( edit->modified ) {
|
||||||
|
if ( !edit_query_dialog2
|
||||||
|
(_("Warning"),
|
||||||
|
_(" Current text was modified without a file save. \n"
|
||||||
|
" Continue discards these changes. "), _("C&ontinue"),
|
||||||
|
_("&Cancel"))) {
|
||||||
|
edit->force |= REDRAW_COMPLETELY;
|
||||||
|
do_moveto = 1;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
do_moveto = 1;
|
||||||
|
}
|
||||||
|
if ( curr && do_moveto) {
|
||||||
|
if ( edit_stack_iterator+1 < MAX_HISTORY_MOVETO ) {
|
||||||
|
g_free (edit_history_moveto[edit_stack_iterator].filename);
|
||||||
|
if ( edit->dir ) {
|
||||||
|
edit_history_moveto[edit_stack_iterator].filename = g_strdup_printf ("%s/%s", edit->dir, edit->filename);
|
||||||
|
} else {
|
||||||
|
edit_history_moveto[edit_stack_iterator].filename = g_strdup (edit->filename);
|
||||||
|
}
|
||||||
|
edit_history_moveto[edit_stack_iterator].line = edit->start_line +
|
||||||
|
edit->curs_row + 1;
|
||||||
|
edit_stack_iterator++;
|
||||||
|
g_free( edit_history_moveto[edit_stack_iterator].filename );
|
||||||
|
edit_history_moveto[edit_stack_iterator].filename = g_strdup(curr_def->fullpath);
|
||||||
|
edit_history_moveto[edit_stack_iterator].line = curr_def->line;
|
||||||
|
edit_reload_line (edit, edit_history_moveto[edit_stack_iterator].filename,
|
||||||
|
edit_history_moveto[edit_stack_iterator].line);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* clear definition hash */
|
||||||
|
for ( int i = 0; i < MAX_DEFINITIONS; i++) {
|
||||||
|
g_free(def_hash[i].filename);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* destroy dialog before return */
|
||||||
|
destroy_dlg (def_dlg);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
edit_get_match_keyword_cmd (WEdit *edit)
|
||||||
|
{
|
||||||
|
int word_len = 0;
|
||||||
|
int num_def = 0;
|
||||||
|
int max_len = 0;
|
||||||
|
long word_start = 0;
|
||||||
|
unsigned char *bufpos;
|
||||||
|
char *match_expr;
|
||||||
|
char *path = NULL;
|
||||||
|
char *ptr = NULL;
|
||||||
|
char *tagfile = NULL;
|
||||||
|
|
||||||
|
etags_hash_t def_hash[MAX_DEFINITIONS];
|
||||||
|
|
||||||
|
for ( int i = 0; i < MAX_DEFINITIONS; i++) {
|
||||||
|
def_hash[i].filename = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* search start of word to be completed */
|
||||||
|
if (!edit_find_word_start (edit, &word_start, &word_len))
|
||||||
|
return;
|
||||||
|
|
||||||
|
/* prepare match expression */
|
||||||
|
bufpos = &edit->buffers1[word_start >> S_EDIT_BUF_SIZE]
|
||||||
|
[word_start & M_EDIT_BUF_SIZE];
|
||||||
|
match_expr = g_strdup_printf ("%.*s", word_len, bufpos);
|
||||||
|
|
||||||
|
ptr = g_get_current_dir ();
|
||||||
|
path = g_strconcat (ptr, G_DIR_SEPARATOR_S, (char *) NULL);
|
||||||
|
g_free (ptr);
|
||||||
|
|
||||||
|
/* Recursive search file 'TAGS' in parent dirs */
|
||||||
|
do {
|
||||||
|
ptr = g_path_get_dirname (path);
|
||||||
|
g_free(path); path = ptr;
|
||||||
|
g_free (tagfile);
|
||||||
|
tagfile = g_build_filename (path, TAGS_NAME, (char *) NULL);
|
||||||
|
if ( exist_file (tagfile) )
|
||||||
|
break;
|
||||||
|
} while (strcmp( path, G_DIR_SEPARATOR_S) != 0);
|
||||||
|
|
||||||
|
if (tagfile){
|
||||||
|
num_def = etags_set_definition_hash(tagfile, path, match_expr, (etags_hash_t *) &def_hash);
|
||||||
|
g_free (tagfile);
|
||||||
|
}
|
||||||
|
g_free (path);
|
||||||
|
|
||||||
|
max_len = MAX_WIDTH_DEF_DIALOG;
|
||||||
|
word_len = 0;
|
||||||
|
if ( num_def > 0 ) {
|
||||||
|
edit_select_definition_dialog (edit, match_expr, max_len, word_len,
|
||||||
|
(etags_hash_t *) &def_hash,
|
||||||
|
num_def);
|
||||||
|
}
|
||||||
|
g_free (match_expr);
|
||||||
|
}
|
||||||
|
@ -42,6 +42,8 @@
|
|||||||
#define CK_Load 102
|
#define CK_Load 102
|
||||||
#define CK_New 103
|
#define CK_New 103
|
||||||
#define CK_Save_As 104
|
#define CK_Save_As 104
|
||||||
|
#define CK_Load_Prev_File 111
|
||||||
|
#define CK_Load_Next_File 112
|
||||||
|
|
||||||
/* block commands */
|
/* block commands */
|
||||||
#define CK_Mark 201
|
#define CK_Mark 201
|
||||||
@ -96,8 +98,9 @@
|
|||||||
#define CK_Terminal 422
|
#define CK_Terminal 422
|
||||||
#define CK_Terminal_App 423
|
#define CK_Terminal_App 423
|
||||||
#define CK_ExtCmd 424
|
#define CK_ExtCmd 424
|
||||||
|
|
||||||
#define CK_User_Menu 425
|
#define CK_User_Menu 425
|
||||||
|
#define CK_Find_Definition 426
|
||||||
|
|
||||||
/* application control */
|
/* application control */
|
||||||
#define CK_Save_Desktop 451
|
#define CK_Save_Desktop 451
|
||||||
#define CK_New_Window 452
|
#define CK_New_Window 452
|
||||||
|
@ -99,7 +99,7 @@ static const edit_key_map_type common_key_map[] = {
|
|||||||
{ KEY_RIGHT, CK_Right },
|
{ KEY_RIGHT, CK_Right },
|
||||||
{ KEY_UP, CK_Up },
|
{ KEY_UP, CK_Up },
|
||||||
|
|
||||||
{ ALT ('\n'), CK_Return },
|
{ ALT ('\n'), CK_Find_Definition },
|
||||||
{ ALT ('\t'), CK_Complete_Word },
|
{ ALT ('\t'), CK_Complete_Word },
|
||||||
{ ALT ('l'), CK_Goto },
|
{ ALT ('l'), CK_Goto },
|
||||||
{ ALT ('L'), CK_Goto },
|
{ ALT ('L'), CK_Goto },
|
||||||
@ -108,6 +108,8 @@ static const edit_key_map_type common_key_map[] = {
|
|||||||
{ ALT ('u'), CK_ExtCmd },
|
{ ALT ('u'), CK_ExtCmd },
|
||||||
{ ALT ('<'), CK_Beginning_Of_Text },
|
{ ALT ('<'), CK_Beginning_Of_Text },
|
||||||
{ ALT ('>'), CK_End_Of_Text },
|
{ ALT ('>'), CK_End_Of_Text },
|
||||||
|
{ ALT ('-'), CK_Load_Prev_File },
|
||||||
|
{ ALT ('='), CK_Load_Next_File },
|
||||||
{ ALT (KEY_BACKSPACE), CK_Delete_Word_Left },
|
{ ALT (KEY_BACKSPACE), CK_Delete_Word_Left },
|
||||||
|
|
||||||
{ XCTRL ('k'), CK_Delete_To_Line_End },
|
{ XCTRL ('k'), CK_Delete_To_Line_End },
|
||||||
|
185
edit/etags.c
Normal file
185
edit/etags.c
Normal file
@ -0,0 +1,185 @@
|
|||||||
|
/* editor C-code navigation via tags.
|
||||||
|
make TAGS file via command:
|
||||||
|
$ find . -type f -name "*.[ch]" | etags -l c --declarations -
|
||||||
|
|
||||||
|
or, if etags utility not installed:
|
||||||
|
$ find . -type f -name "*.[ch]" | ctags --c-kinds=+p --fields=+iaS --extra=+q -e -L-
|
||||||
|
|
||||||
|
Copyright (C) 2009 Free Software Foundation, Inc.
|
||||||
|
|
||||||
|
Authors:
|
||||||
|
Ilia Maslakov <il.smind@gmail.com>, 2009
|
||||||
|
Slava Zanko <slavazanko@gmail.com>, 2009
|
||||||
|
|
||||||
|
|
||||||
|
This file is part of the Midnight Commander.
|
||||||
|
|
||||||
|
The Midnight Commander is free software; you can redistribute it
|
||||||
|
and/or modify it under the terms of the GNU General Public License as
|
||||||
|
published by the Free Software Foundation; either version 2 of the
|
||||||
|
License, or (at your option) any later version.
|
||||||
|
|
||||||
|
The Midnight Commander is distributed in the hope that it will be
|
||||||
|
useful, but WITHOUT ANY WARRANTY; without even the implied warranty
|
||||||
|
of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
||||||
|
MA 02110-1301, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <config.h>
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <inttypes.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <ctype.h>
|
||||||
|
|
||||||
|
#include "../src/global.h"
|
||||||
|
#include "../src/util.h" /* canonicalize_pathname() */
|
||||||
|
#include "../edit/etags.h"
|
||||||
|
|
||||||
|
/*** file scope functions **********************************************/
|
||||||
|
|
||||||
|
static gboolean parse_define(char *buf, char **long_name, char **short_name, long *line)
|
||||||
|
{
|
||||||
|
enum {in_longname, in_shortname, in_line, finish} def_state = in_longname;
|
||||||
|
|
||||||
|
static char longdef[LONG_DEF_LEN];
|
||||||
|
static char shortdef[SHORT_DEF_LEN];
|
||||||
|
static char linedef[LINE_DEF_LEN];
|
||||||
|
int nlong = 0;
|
||||||
|
int nshort = 0;
|
||||||
|
int nline = 0;
|
||||||
|
char c = *buf;
|
||||||
|
|
||||||
|
while ( !(c =='\0' || c =='\n') ) {
|
||||||
|
switch ( def_state ) {
|
||||||
|
case in_longname:
|
||||||
|
if ( c == 0x01 ) {
|
||||||
|
def_state = in_line;
|
||||||
|
} else if ( c == 0x7F ) {
|
||||||
|
def_state = in_shortname;
|
||||||
|
} else {
|
||||||
|
if ( nlong < LONG_DEF_LEN - 1 ) {
|
||||||
|
longdef[nlong++] = c;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case in_shortname:
|
||||||
|
if ( isdigit(c) ) {
|
||||||
|
nshort = 0;
|
||||||
|
buf--;
|
||||||
|
def_state = in_line;
|
||||||
|
} else if ( c == 0x01 ) {
|
||||||
|
def_state = in_line;
|
||||||
|
} else {
|
||||||
|
if ( nshort < SHORT_DEF_LEN - 1 ) {
|
||||||
|
shortdef[nshort++] = c;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case in_line:
|
||||||
|
if ( c == ',' ) {
|
||||||
|
def_state = finish;
|
||||||
|
} else if ( isdigit(c) ) {
|
||||||
|
if ( nline < LINE_DEF_LEN - 1 ) {
|
||||||
|
linedef[nline++] = c;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case finish:
|
||||||
|
longdef[nlong] = '\0';
|
||||||
|
shortdef[nshort] = '\0';
|
||||||
|
linedef[nline] = '\0';
|
||||||
|
*long_name = g_strdup (longdef);
|
||||||
|
*short_name = g_strdup (shortdef);
|
||||||
|
*line = atol (linedef);
|
||||||
|
return TRUE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
buf++;
|
||||||
|
c = *buf;
|
||||||
|
}
|
||||||
|
*long_name = NULL;
|
||||||
|
*short_name = NULL;
|
||||||
|
*line = 0;
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*** public functions **************************************************/
|
||||||
|
|
||||||
|
int etags_set_definition_hash(const char *tagfile, const char *start_path,
|
||||||
|
const char *match_func,
|
||||||
|
etags_hash_t *def_hash)
|
||||||
|
{
|
||||||
|
FILE *f;
|
||||||
|
static char buf[BUF_LARGE];
|
||||||
|
|
||||||
|
char *longname = NULL;
|
||||||
|
char *shortname = NULL;
|
||||||
|
long line;
|
||||||
|
|
||||||
|
char *chekedstr = NULL;
|
||||||
|
|
||||||
|
int num = 0; /* returned value */
|
||||||
|
|
||||||
|
/* open file with positions */
|
||||||
|
f = fopen (tagfile, "r");
|
||||||
|
if (!f)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
int pos;
|
||||||
|
char *filename = NULL;
|
||||||
|
enum {start, in_filename, in_define} state = start;
|
||||||
|
|
||||||
|
while (fgets (buf, sizeof (buf), f)) {
|
||||||
|
|
||||||
|
switch ( state ) {
|
||||||
|
case start:
|
||||||
|
if ( buf[0] == 0x0C ) {
|
||||||
|
state = in_filename;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case in_filename:
|
||||||
|
pos = strcspn(buf, ",");
|
||||||
|
g_free(filename);
|
||||||
|
filename = g_malloc (pos + 2);
|
||||||
|
g_strlcpy(filename, (char *)buf, pos + 1);
|
||||||
|
state = in_define;
|
||||||
|
break;
|
||||||
|
case in_define:
|
||||||
|
if ( buf[0] == 0x0C ) {
|
||||||
|
state = in_filename;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
/* check if the filename matches the define pos */
|
||||||
|
chekedstr = strstr (buf, match_func);
|
||||||
|
if ( chekedstr ) {
|
||||||
|
parse_define (chekedstr, &longname, &shortname, &line);
|
||||||
|
if ( num < MAX_DEFINITIONS - 1 ) {
|
||||||
|
def_hash[num].filename_len = strlen (filename);
|
||||||
|
def_hash[num].fullpath = g_build_filename (start_path, filename, (char *) NULL);
|
||||||
|
canonicalize_pathname (def_hash[num].fullpath);
|
||||||
|
def_hash[num].filename = g_strdup (filename);
|
||||||
|
if ( shortname ) {
|
||||||
|
def_hash[num].short_define = g_strdup (shortname);
|
||||||
|
} else {
|
||||||
|
def_hash[num].short_define = g_strdup (longname);
|
||||||
|
}
|
||||||
|
def_hash[num].line = line;
|
||||||
|
g_free(shortname);
|
||||||
|
g_free(longname);
|
||||||
|
num++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
g_free(filename);
|
||||||
|
return num;
|
||||||
|
}
|
25
edit/etags.h
Normal file
25
edit/etags.h
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
#ifndef MC_EDIT_ETAGS_H
|
||||||
|
#define MC_EDIT_ETAGS_H 1
|
||||||
|
|
||||||
|
#include <sys/types.h> /* size_t */
|
||||||
|
#include "../src/global.h" /* include <glib.h> */
|
||||||
|
|
||||||
|
#define MAX_WIDTH_DEF_DIALOG 60 /* max width def dialog */
|
||||||
|
#define MAX_DEFINITIONS 60 /* count found entries show */
|
||||||
|
#define SHORT_DEF_LEN 30
|
||||||
|
#define LONG_DEF_LEN 40
|
||||||
|
#define LINE_DEF_LEN 16
|
||||||
|
#define TAGS_NAME "TAGS"
|
||||||
|
|
||||||
|
typedef struct etags_hash_struct {
|
||||||
|
size_t filename_len;
|
||||||
|
unsigned char *fullpath;
|
||||||
|
unsigned char *filename;
|
||||||
|
unsigned char *short_define;
|
||||||
|
long line;
|
||||||
|
} etags_hash_t;
|
||||||
|
|
||||||
|
int etags_set_definition_hash (const char *tagfile, const char *start_path,
|
||||||
|
const char *match_func, etags_hash_t *def_hash);
|
||||||
|
|
||||||
|
#endif /* MC_EDIT_ETAGS_H */
|
18
src/main.c
18
src/main.c
@ -279,6 +279,11 @@ char *mc_home = NULL;
|
|||||||
|
|
||||||
char cmd_buf[512];
|
char cmd_buf[512];
|
||||||
|
|
||||||
|
#ifdef USE_INTERNAL_EDIT
|
||||||
|
int edit_stack_iterator = 0;
|
||||||
|
struct edit_stack_type edit_history_moveto[MAX_HISTORY_MOVETO];
|
||||||
|
#endif
|
||||||
|
|
||||||
static void
|
static void
|
||||||
reload_panelized (WPanel *panel)
|
reload_panelized (WPanel *panel)
|
||||||
{
|
{
|
||||||
@ -2135,6 +2140,13 @@ main (int argc, char *argv[])
|
|||||||
|
|
||||||
vfs_init ();
|
vfs_init ();
|
||||||
|
|
||||||
|
#ifdef USE_INTERNAL_EDIT
|
||||||
|
for ( int i = 0; i < MAX_HISTORY_MOVETO; i++ ) {
|
||||||
|
edit_history_moveto[i].filename = NULL;
|
||||||
|
edit_history_moveto[i].line = -1;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef HAVE_SLANG
|
#ifdef HAVE_SLANG
|
||||||
SLtt_Ignore_Beep = 1;
|
SLtt_Ignore_Beep = 1;
|
||||||
#endif
|
#endif
|
||||||
@ -2255,5 +2267,11 @@ main (int argc, char *argv[])
|
|||||||
g_free (this_dir);
|
g_free (this_dir);
|
||||||
g_free (other_dir);
|
g_free (other_dir);
|
||||||
|
|
||||||
|
#ifdef USE_INTERNAL_EDIT
|
||||||
|
for ( int i = 0; i < MAX_HISTORY_MOVETO; i++ ) {
|
||||||
|
g_free(edit_history_moveto[i].filename);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -5,6 +5,10 @@
|
|||||||
#include "panel.h"
|
#include "panel.h"
|
||||||
#include "widget.h"
|
#include "widget.h"
|
||||||
|
|
||||||
|
#ifdef USE_INTERNAL_EDIT
|
||||||
|
#include "../edit/edit.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Toggling functions */
|
/* Toggling functions */
|
||||||
void toggle_fast_reload (void);
|
void toggle_fast_reload (void);
|
||||||
void toggle_mix_all_files (void);
|
void toggle_mix_all_files (void);
|
||||||
@ -38,6 +42,11 @@ extern int mou_auto_repeat;
|
|||||||
extern char *other_dir;
|
extern char *other_dir;
|
||||||
extern int mouse_move_pages;
|
extern int mouse_move_pages;
|
||||||
|
|
||||||
|
#ifdef USE_INTERNAL_EDIT
|
||||||
|
extern int edit_stack_iterator;
|
||||||
|
struct edit_stack_type edit_history_moveto[MAX_HISTORY_MOVETO];
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef HAVE_CHARSET
|
#ifdef HAVE_CHARSET
|
||||||
extern int source_codepage;
|
extern int source_codepage;
|
||||||
extern int display_codepage;
|
extern int display_codepage;
|
||||||
|
Loading…
Reference in New Issue
Block a user