mirror of
https://github.com/MidnightCommander/mc
synced 2025-03-22 07:42:54 +03:00
Added usage of search engine.
Signed-off-by: Slava Zanko <slavazanko@gmail.com>
This commit is contained in:
parent
e5dc79a441
commit
14fa0ea1e2
@ -446,6 +446,7 @@
|
||||
#define CK_DiffHelp 9034
|
||||
#define CK_DiffMergeCurrentHunk 9035
|
||||
#define CK_DiffSave 9036
|
||||
#define CK_DiffContinueSearch 9037
|
||||
|
||||
/*
|
||||
Process a block through a shell command: CK_Pipe_Block(i) executes shell_cmd[i].
|
||||
|
@ -1,8 +1,10 @@
|
||||
noinst_LTLIBRARIES = libdiffviewer.la
|
||||
|
||||
libdiffviewer_la_SOURCES = \
|
||||
ydiff.c \
|
||||
ydiff.h
|
||||
internal.h \
|
||||
search.c \
|
||||
ydiff.c ydiff.h
|
||||
|
||||
|
||||
libdiffviewer_la_CFLAGS = -I$(top_srcdir) \
|
||||
$(GLIB_CFLAGS) $(PCRE_CFLAGS) \
|
||||
|
147
src/diffviewer/internal.h
Normal file
147
src/diffviewer/internal.h
Normal file
@ -0,0 +1,147 @@
|
||||
#ifndef MC__DIFFVIEW_INTERNAL_H
|
||||
#define MC__DIFFVIEW_INTERNAL_H
|
||||
|
||||
#include "lib/global.h"
|
||||
#include "lib/mcconfig.h"
|
||||
#include "lib/search.h"
|
||||
#include "lib/tty/color.h"
|
||||
|
||||
#include "src/widget.h"
|
||||
|
||||
/*** typedefs(not structures) and defined constants **********************************************/
|
||||
|
||||
typedef int (*DFUNC) (void *ctx, int ch, int line, off_t off, size_t sz, const char *str);
|
||||
typedef int PAIR[2];
|
||||
|
||||
#define error_dialog(h, s) query_dialog(h, s, D_ERROR, 1, _("&Dismiss"))
|
||||
|
||||
/*** enums ***************************************************************************************/
|
||||
|
||||
typedef enum
|
||||
{
|
||||
DATA_SRC_MEM = 0,
|
||||
DATA_SRC_TMP = 1,
|
||||
DATA_SRC_ORG = 2
|
||||
} DSRC;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
DIFF_NONE = 0,
|
||||
DIFF_ADD = 1,
|
||||
DIFF_DEL = 2,
|
||||
DIFF_CHG = 3
|
||||
} DiffState;
|
||||
|
||||
/*** structures declarations (and typedefs of structures)*****************************************/
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int fd;
|
||||
int pos;
|
||||
int len;
|
||||
char *buf;
|
||||
int flags;
|
||||
void *data;
|
||||
} FBUF;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int a[2][2];
|
||||
int cmd;
|
||||
} DIFFCMD;
|
||||
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int off;
|
||||
int len;
|
||||
} BRACKET[2];
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int ch;
|
||||
int line;
|
||||
union
|
||||
{
|
||||
off_t off;
|
||||
size_t len;
|
||||
} u;
|
||||
void *p;
|
||||
} DIFFLN;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
FBUF *f;
|
||||
GArray *a;
|
||||
DSRC dsrc;
|
||||
} PRINTER_CTX;
|
||||
|
||||
typedef struct WDiff_struct
|
||||
{
|
||||
Widget widget;
|
||||
|
||||
const char *args; /* Args passed to diff */
|
||||
const char *file[2]; /* filenames */
|
||||
const char *label[2];
|
||||
FBUF *f[2];
|
||||
const char *backup_sufix;
|
||||
gboolean merged;
|
||||
GArray *a[2];
|
||||
GPtrArray *hdiff;
|
||||
int ndiff; /* number of hunks */
|
||||
DSRC dsrc; /* data source: memory or temporary file */
|
||||
|
||||
int view_quit:1; /* Quit flag */
|
||||
|
||||
int height;
|
||||
int half1;
|
||||
int half2;
|
||||
int width1;
|
||||
int width2;
|
||||
int bias;
|
||||
int new_frame;
|
||||
int skip_rows;
|
||||
int skip_cols;
|
||||
int display_symbols;
|
||||
int display_numbers;
|
||||
int show_cr;
|
||||
int tab_size;
|
||||
int ord;
|
||||
int full;
|
||||
gboolean utf8;
|
||||
/* converter for translation of text */
|
||||
GIConv converter;
|
||||
struct
|
||||
{
|
||||
int quality;
|
||||
gboolean strip_trailing_cr;
|
||||
gboolean ignore_tab_expansion;
|
||||
gboolean ignore_space_change;
|
||||
gboolean ignore_all_space;
|
||||
gboolean ignore_case;
|
||||
} opt;
|
||||
|
||||
/* Search variables */
|
||||
struct
|
||||
{
|
||||
mc_search_t *handle;
|
||||
gchar *last_string;
|
||||
|
||||
ssize_t last_found_line;
|
||||
size_t last_accessed_num_line;
|
||||
} search;
|
||||
|
||||
} WDiff;
|
||||
|
||||
/*** global variables defined in .c file *********************************************************/
|
||||
|
||||
/*** declarations of public functions ************************************************************/
|
||||
|
||||
/* search.c */
|
||||
void dview_search_cmd (WDiff * dview);
|
||||
void dview_continue_search_cmd (WDiff * dview);
|
||||
|
||||
/* ydiff.c */
|
||||
void dview_update (WDiff * dview);
|
||||
|
||||
#endif /* MC__DIFFVIEW_INTERNAL_H */
|
310
src/diffviewer/search.c
Normal file
310
src/diffviewer/search.c
Normal file
@ -0,0 +1,310 @@
|
||||
/*
|
||||
Search functions for diffviewer.
|
||||
|
||||
Copyright (C) 2010 The Free Software Foundation, Inc.
|
||||
|
||||
Written by:
|
||||
Slava Zanko <slavazanko@gmail.com>, 2010.
|
||||
|
||||
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 <stdio.h>
|
||||
|
||||
#include "lib/global.h"
|
||||
#include "lib/strutil.h"
|
||||
#include "lib/tty/key.h"
|
||||
|
||||
#include "src/dialog.h"
|
||||
#include "src/wtools.h"
|
||||
#include "src/history.h"
|
||||
#include "src/charsets.h"
|
||||
|
||||
#include "internal.h"
|
||||
|
||||
/*** global variables ****************************************************************************/
|
||||
|
||||
/*** file scope macro definitions ****************************************************************/
|
||||
|
||||
#define SEARCH_DLG_WIDTH 58
|
||||
#define SEARCH_DLG_HEIGHT 13
|
||||
|
||||
/*** file scope type declarations ****************************************************************/
|
||||
|
||||
typedef struct mcdiffview_search_options_struct
|
||||
{
|
||||
mc_search_type_t type;
|
||||
gboolean case_sens;
|
||||
gboolean backwards;
|
||||
gboolean whole_words;
|
||||
gboolean all_codepages;
|
||||
} mcdiffview_search_options_t;
|
||||
|
||||
/*** file scope variables ************************************************************************/
|
||||
|
||||
static mcdiffview_search_options_t mcdiffview_search_options = {
|
||||
.type = MC_SEARCH_T_NORMAL,
|
||||
.case_sens = FALSE,
|
||||
.backwards = FALSE,
|
||||
.whole_words = FALSE,
|
||||
.all_codepages = FALSE,
|
||||
};
|
||||
|
||||
/*** file scope functions ************************************************************************/
|
||||
/* --------------------------------------------------------------------------------------------- */
|
||||
|
||||
#define DLG_BTN1_text N_("&Cancel")
|
||||
#define DLG_BTN2_text N_("&OK")
|
||||
|
||||
static void
|
||||
mcdiffview_dialog_fix_buttons_positions (QuickDialog * dlg)
|
||||
{
|
||||
size_t str_cancel_len, str_ok_len;
|
||||
size_t first_start_position;
|
||||
|
||||
str_cancel_len = str_term_width1 (_(DLG_BTN1_text)) + 4;
|
||||
str_ok_len = str_term_width1 (_(DLG_BTN2_text)) + 6;
|
||||
|
||||
first_start_position = (SEARCH_DLG_WIDTH - str_cancel_len - str_ok_len - 1) / 2;
|
||||
dlg->widgets[1].relative_x = first_start_position;
|
||||
dlg->widgets[0].relative_x = first_start_position + str_ok_len + 1;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------- */
|
||||
|
||||
static gboolean
|
||||
mcdiffview_dialog_search (WDiff * dview)
|
||||
{
|
||||
char *exp = NULL;
|
||||
|
||||
int qd_result;
|
||||
|
||||
size_t num_of_types;
|
||||
gchar **list_of_types = mc_search_get_types_strings_array (&num_of_types);
|
||||
|
||||
QuickWidget search_widgets[] = {
|
||||
/* 0 */
|
||||
QUICK_BUTTON (3, SEARCH_DLG_WIDTH, SEARCH_DLG_HEIGHT - 3, SEARCH_DLG_HEIGHT, DLG_BTN1_text,
|
||||
B_CANCEL, NULL),
|
||||
/* 1 */
|
||||
QUICK_BUTTON (3, SEARCH_DLG_WIDTH, SEARCH_DLG_HEIGHT - 3, SEARCH_DLG_HEIGHT, DLG_BTN2_text,
|
||||
B_ENTER, NULL),
|
||||
/* 2 */
|
||||
#ifdef HAVE_CHARSET
|
||||
QUICK_CHECKBOX (33, SEARCH_DLG_WIDTH, 8, SEARCH_DLG_HEIGHT, N_("All charsets"),
|
||||
&mcdiffview_search_options.all_codepages),
|
||||
#endif
|
||||
|
||||
QUICK_CHECKBOX (33, SEARCH_DLG_WIDTH, 7, SEARCH_DLG_HEIGHT, N_("&Whole words"),
|
||||
&mcdiffview_search_options.whole_words),
|
||||
/* 3 */
|
||||
QUICK_CHECKBOX (33, SEARCH_DLG_WIDTH, 6, SEARCH_DLG_HEIGHT, N_("&Backwards"),
|
||||
&mcdiffview_search_options.backwards),
|
||||
/* 4 */
|
||||
QUICK_CHECKBOX (33, SEARCH_DLG_WIDTH, 5, SEARCH_DLG_HEIGHT, N_("case &Sensitive"),
|
||||
&mcdiffview_search_options.case_sens),
|
||||
/* 5 */
|
||||
QUICK_RADIO (3, SEARCH_DLG_WIDTH, 5, SEARCH_DLG_HEIGHT,
|
||||
num_of_types, (const char **) list_of_types,
|
||||
(int *) &mcdiffview_search_options.type),
|
||||
/* 6 */
|
||||
QUICK_INPUT (3, SEARCH_DLG_WIDTH, 3, SEARCH_DLG_HEIGHT,
|
||||
INPUT_LAST_TEXT, SEARCH_DLG_WIDTH - 6, 0,
|
||||
MC_HISTORY_SHARED_SEARCH,
|
||||
&exp),
|
||||
/* 7 */
|
||||
QUICK_LABEL (2, SEARCH_DLG_WIDTH, 2, SEARCH_DLG_HEIGHT, N_(" Enter search string:")),
|
||||
QUICK_END
|
||||
};
|
||||
|
||||
QuickDialog search_input = {
|
||||
SEARCH_DLG_WIDTH, SEARCH_DLG_HEIGHT, -1, 0,
|
||||
N_("Search"), "[Input Line Keys]",
|
||||
search_widgets, 0
|
||||
};
|
||||
|
||||
mcdiffview_dialog_fix_buttons_positions (&search_input);
|
||||
|
||||
qd_result = quick_dialog (&search_input);
|
||||
g_strfreev (list_of_types);
|
||||
|
||||
|
||||
if ((qd_result == B_CANCEL) || (exp == NULL) || (exp[0] == '\0'))
|
||||
{
|
||||
g_free (exp);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
#ifdef HAVE_CHARSET
|
||||
{
|
||||
GString *tmp = str_convert_to_input (exp);
|
||||
|
||||
if (tmp)
|
||||
{
|
||||
g_free (exp);
|
||||
exp = g_string_free (tmp, FALSE);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
g_free (dview->search.last_string);
|
||||
dview->search.last_string = exp;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------- */
|
||||
|
||||
static gboolean
|
||||
mcdiffview_do_search_backward (WDiff * dview)
|
||||
{
|
||||
size_t ind;
|
||||
DIFFLN *p;
|
||||
|
||||
dview->search.last_accessed_num_line--;
|
||||
|
||||
if (dview->search.last_accessed_num_line < 0)
|
||||
return FALSE;
|
||||
|
||||
for (ind = dview->search.last_accessed_num_line; ind > 0; ind--)
|
||||
{
|
||||
p = (DIFFLN *) & g_array_index (dview->a[dview->ord], DIFFLN, ind);
|
||||
if (p->u.len == 0)
|
||||
continue;
|
||||
|
||||
if (mc_search_run (dview->search.handle, p->p, 0, p->u.len, NULL))
|
||||
{
|
||||
dview->skip_rows = dview->search.last_found_line =
|
||||
dview->search.last_accessed_num_line = ind;
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------- */
|
||||
|
||||
|
||||
static gboolean
|
||||
mcdiffview_do_search_forward (WDiff * dview)
|
||||
{
|
||||
size_t ind;
|
||||
DIFFLN *p;
|
||||
|
||||
dview->search.last_accessed_num_line++;
|
||||
|
||||
if (dview->search.last_accessed_num_line > dview->a[dview->ord]->len)
|
||||
return FALSE;
|
||||
|
||||
for (ind = dview->search.last_accessed_num_line; ind < dview->a[dview->ord]->len; ind++)
|
||||
{
|
||||
p = (DIFFLN *) & g_array_index (dview->a[dview->ord], DIFFLN, ind);
|
||||
if (p->u.len == 0)
|
||||
continue;
|
||||
|
||||
if (mc_search_run (dview->search.handle, p->p, 0, p->u.len, NULL))
|
||||
{
|
||||
dview->skip_rows = dview->search.last_found_line =
|
||||
dview->search.last_accessed_num_line = ind;
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------- */
|
||||
|
||||
static void
|
||||
mcdiffview_do_search (WDiff * dview)
|
||||
{
|
||||
gboolean present_result = FALSE;
|
||||
|
||||
|
||||
tty_enable_interrupt_key ();
|
||||
|
||||
if (mcdiffview_search_options.backwards)
|
||||
{
|
||||
present_result = mcdiffview_do_search_backward (dview);
|
||||
}
|
||||
else
|
||||
{
|
||||
present_result = mcdiffview_do_search_forward (dview);
|
||||
}
|
||||
|
||||
tty_disable_interrupt_key ();
|
||||
|
||||
if (!present_result)
|
||||
{
|
||||
dview->search.last_found_line = -1;
|
||||
error_dialog (_("Search"), _(" Search string not found "));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------- */
|
||||
/*** public functions ****************************************************************************/
|
||||
/* --------------------------------------------------------------------------------------------- */
|
||||
|
||||
void
|
||||
dview_search_cmd (WDiff * dview)
|
||||
{
|
||||
if (dview->dsrc != DATA_SRC_MEM)
|
||||
{
|
||||
error_dialog (_("Search"), _(" Search is disabled "));
|
||||
return;
|
||||
}
|
||||
|
||||
if (!mcdiffview_dialog_search (dview))
|
||||
return;
|
||||
|
||||
mc_search_free (dview->search.handle);
|
||||
dview->search.handle = mc_search_new (dview->search.last_string, -1);
|
||||
|
||||
if (dview->search.handle == NULL)
|
||||
return;
|
||||
|
||||
dview->search.handle->search_type = mcdiffview_search_options.type;
|
||||
dview->search.handle->is_all_charsets = mcdiffview_search_options.all_codepages;
|
||||
dview->search.handle->is_case_sentitive = mcdiffview_search_options.case_sens;
|
||||
dview->search.handle->whole_words = mcdiffview_search_options.whole_words;
|
||||
|
||||
mcdiffview_do_search (dview);
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------- */
|
||||
|
||||
void
|
||||
dview_continue_search_cmd (WDiff * dview)
|
||||
{
|
||||
if (dview->dsrc != DATA_SRC_MEM)
|
||||
{
|
||||
error_dialog (_("Search"), _(" Search is disabled "));
|
||||
return;
|
||||
}
|
||||
if (dview->search.handle == NULL)
|
||||
{
|
||||
dview_search_cmd (dview);
|
||||
return;
|
||||
}
|
||||
mcdiffview_do_search (dview);
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------- */
|
@ -43,7 +43,6 @@
|
||||
#include "src/keybind.h"
|
||||
#include "src/cmd.h"
|
||||
#include "src/dialog.h"
|
||||
#include "src/widget.h"
|
||||
#include "src/help.h"
|
||||
#include "src/wtools.h"
|
||||
#include "src/charsets.h"
|
||||
@ -55,6 +54,7 @@
|
||||
#include "src/selcodepage.h"
|
||||
|
||||
#include "ydiff.h"
|
||||
#include "internal.h"
|
||||
|
||||
/*** global variables ****************************************************************************/
|
||||
|
||||
@ -79,9 +79,6 @@ do { \
|
||||
#define OPTX 50
|
||||
#define OPTY 16
|
||||
|
||||
#define SEARCH_DLG_WIDTH 58
|
||||
#define SEARCH_DLG_HEIGHT 14
|
||||
|
||||
#define ADD_CH '+'
|
||||
#define DEL_CH '-'
|
||||
#define CHG_CH '*'
|
||||
@ -93,26 +90,16 @@ do { \
|
||||
|
||||
#define TAB_SKIP(ts, pos) ((ts) - (pos) % (ts))
|
||||
|
||||
#define error_dialog(h, s) query_dialog(h, s, D_ERROR, 1, _("&Dismiss"))
|
||||
|
||||
#define FILE_DIRTY(fs) \
|
||||
do { \
|
||||
(fs)->pos = 0; \
|
||||
(fs)->len = 0; \
|
||||
} while (0)
|
||||
|
||||
#define IS_WHOLE_OR_DONT_CARE() \
|
||||
(!whole || ( \
|
||||
(i == 0 || strchr(wholechars, haystack[i - 1]) == NULL) && \
|
||||
(i + nlen == hlen || strchr(wholechars, haystack[i + nlen]) == NULL) \
|
||||
))
|
||||
|
||||
/*** file scope type declarations ****************************************************************/
|
||||
|
||||
/*** file scope variables ************************************************************************/
|
||||
|
||||
static const char *wholechars = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz_";
|
||||
|
||||
/*** file scope functions ************************************************************************/
|
||||
|
||||
/* --------------------------------------------------------------------------------------------- */
|
||||
@ -1909,6 +1896,11 @@ destroy_hdiff (WDiff * dview)
|
||||
g_ptr_array_free (dview->hdiff, TRUE);
|
||||
dview->hdiff = NULL;
|
||||
}
|
||||
|
||||
mc_search_free (dview->search.handle);
|
||||
dview->search.handle = NULL;
|
||||
g_free (dview->search.last_string);
|
||||
dview->search.last_string = NULL;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------- */
|
||||
@ -2347,7 +2339,12 @@ dview_init (WDiff * dview, const char *args, const char *file1, const char *file
|
||||
dview->tab_size = 8;
|
||||
dview->ord = 0;
|
||||
dview->full = 0;
|
||||
dview->last_found = -1;
|
||||
|
||||
dview->search.handle=NULL;
|
||||
dview->search.last_string=NULL;
|
||||
dview->search.last_found_line = -1;
|
||||
dview->search.last_accessed_num_line = 0;
|
||||
|
||||
|
||||
dview->opt.quality = 0;
|
||||
dview->opt.strip_trailing_cr = 0;
|
||||
@ -2532,7 +2529,7 @@ dview_display_file (const WDiff * dview, int ord, int r, int c, int height, int
|
||||
}
|
||||
if (f == NULL)
|
||||
{
|
||||
if (i == (size_t) dview->last_found)
|
||||
if (i == (size_t) dview->search.last_found_line)
|
||||
{
|
||||
tty_setcolor (MARKED_SELECTED_COLOR);
|
||||
}
|
||||
@ -2719,92 +2716,6 @@ dview_status (const WDiff * dview, int ord, int width, int c)
|
||||
|
||||
/* --------------------------------------------------------------------------------------------- */
|
||||
|
||||
static void
|
||||
dview_update (WDiff * dview)
|
||||
{
|
||||
int height = dview->height;
|
||||
int width1;
|
||||
int width2;
|
||||
|
||||
int last = dview->a[0]->len - 1;
|
||||
|
||||
if (dview->skip_rows > last)
|
||||
{
|
||||
dview->skip_rows = last;
|
||||
}
|
||||
if (dview->skip_rows < 0)
|
||||
{
|
||||
dview->skip_rows = 0;
|
||||
}
|
||||
if (dview->skip_cols < 0)
|
||||
{
|
||||
dview->skip_cols = 0;
|
||||
}
|
||||
|
||||
if (height < 2)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
width1 = dview->half1 + dview->bias;
|
||||
width2 = dview->half2 - dview->bias;
|
||||
if (dview->full)
|
||||
{
|
||||
width1 = COLS;
|
||||
width2 = 0;
|
||||
}
|
||||
|
||||
if (dview->new_frame)
|
||||
{
|
||||
int xwidth = dview->display_symbols + dview->display_numbers;
|
||||
|
||||
tty_setcolor (NORMAL_COLOR);
|
||||
if (width1 > 1)
|
||||
{
|
||||
tty_draw_box (1, 0, height, width1, FALSE);
|
||||
}
|
||||
if (width2 > 1)
|
||||
{
|
||||
tty_draw_box (1, width1, height, width2, FALSE);
|
||||
}
|
||||
|
||||
if (xwidth)
|
||||
{
|
||||
xwidth++;
|
||||
if (xwidth < width1 - 1)
|
||||
{
|
||||
tty_gotoyx (1, xwidth);
|
||||
tty_print_alt_char (mc_tty_frm[MC_TTY_FRM_DTOPMIDDLE], FALSE);
|
||||
tty_gotoyx (height, xwidth);
|
||||
tty_print_alt_char (mc_tty_frm[MC_TTY_FRM_DBOTTOMMIDDLE], FALSE);
|
||||
tty_draw_vline (2, xwidth, mc_tty_frm[MC_TTY_FRM_VERT], height - 2);
|
||||
}
|
||||
if (xwidth < width2 - 1)
|
||||
{
|
||||
tty_gotoyx (1, width1 + xwidth);
|
||||
tty_print_alt_char (mc_tty_frm[MC_TTY_FRM_DTOPMIDDLE], FALSE);
|
||||
tty_gotoyx (height, width1 + xwidth);
|
||||
tty_print_alt_char (mc_tty_frm[MC_TTY_FRM_DBOTTOMMIDDLE], FALSE);
|
||||
tty_draw_vline (2, width1 + xwidth, mc_tty_frm[MC_TTY_FRM_VERT], height - 2);
|
||||
}
|
||||
}
|
||||
dview->new_frame = 0;
|
||||
}
|
||||
|
||||
if (width1 > 2)
|
||||
{
|
||||
dview_status (dview, dview->ord, width1, 0);
|
||||
dview_display_file (dview, dview->ord, 2, 1, height - 2, width1 - 2);
|
||||
}
|
||||
if (width2 > 2)
|
||||
{
|
||||
dview_status (dview, dview->ord ^ 1, width2, width1);
|
||||
dview_display_file (dview, dview->ord ^ 1, 2, width1 + 1, height - 2, width2 - 2);
|
||||
}
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------- */
|
||||
|
||||
static void
|
||||
dview_redo (WDiff * dview)
|
||||
{
|
||||
@ -2819,265 +2730,6 @@ dview_redo (WDiff * dview)
|
||||
|
||||
/* --------------------------------------------------------------------------------------------- */
|
||||
|
||||
static const unsigned char *
|
||||
memmem_dummy (const unsigned char *haystack, size_t i, size_t hlen, const unsigned char *needle,
|
||||
size_t nlen, int whole)
|
||||
{
|
||||
for (; i + nlen <= hlen; i++)
|
||||
{
|
||||
if (haystack[i] == needle[0])
|
||||
{
|
||||
size_t j;
|
||||
for (j = 1; j < nlen; j++)
|
||||
{
|
||||
if (haystack[i + j] != needle[j])
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (j == nlen && IS_WHOLE_OR_DONT_CARE ())
|
||||
{
|
||||
return haystack + i;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------- */
|
||||
|
||||
static const unsigned char *
|
||||
memmem_dummy_nocase (const unsigned char *haystack, size_t i, size_t hlen,
|
||||
const unsigned char *needle, size_t nlen, int whole)
|
||||
{
|
||||
for (; i + nlen <= hlen; i++)
|
||||
{
|
||||
if (toupper (haystack[i]) == toupper (needle[0]))
|
||||
{
|
||||
size_t j;
|
||||
for (j = 1; j < nlen; j++)
|
||||
{
|
||||
if (toupper (haystack[i + j]) != toupper (needle[j]))
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (j == nlen && IS_WHOLE_OR_DONT_CARE ())
|
||||
{
|
||||
return haystack + i;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------- */
|
||||
|
||||
static const unsigned char *
|
||||
search_string (const DIFFLN * p, size_t xpos, const void *needle, size_t nlen, int whole, int ccase)
|
||||
{
|
||||
const unsigned char *haystack = p->p;
|
||||
size_t hlen = p->u.len;
|
||||
|
||||
if (xpos > hlen || nlen <= 0 || haystack == NULL || needle == NULL)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* XXX I should use Boyer-Moore */
|
||||
if (ccase)
|
||||
{
|
||||
return memmem_dummy (haystack, xpos, hlen, needle, nlen, whole);
|
||||
}
|
||||
else
|
||||
{
|
||||
return memmem_dummy_nocase (haystack, xpos, hlen, needle, nlen, whole);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* --------------------------------------------------------------------------------------------- */
|
||||
|
||||
static int
|
||||
dview_search_string (WDiff * dview, const char *needle, int ccase, int back, int whole)
|
||||
{
|
||||
size_t nlen = strlen (needle);
|
||||
size_t xpos = 0;
|
||||
|
||||
int ord = dview->ord;
|
||||
const DIFFLN *p;
|
||||
|
||||
size_t i = (size_t) dview->last_found;
|
||||
|
||||
if (back)
|
||||
{
|
||||
if (i == (size_t) - 1)
|
||||
{
|
||||
i = dview->skip_rows;
|
||||
}
|
||||
for (--i; i >= 0; i--)
|
||||
{
|
||||
const unsigned char *q;
|
||||
|
||||
p = (DIFFLN *) & g_array_index (dview->a[ord], DIFFLN, i);
|
||||
q = search_string (p, xpos, needle, nlen, whole, ccase);
|
||||
if (q != NULL)
|
||||
{
|
||||
return i;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (i == (size_t) - 1)
|
||||
{
|
||||
i = dview->skip_rows - 1;
|
||||
}
|
||||
for (++i; i < dview->a[ord]->len; i++)
|
||||
{
|
||||
const unsigned char *q;
|
||||
|
||||
p = (DIFFLN *) & g_array_index (dview->a[ord], DIFFLN, i);
|
||||
q = search_string (p, xpos, needle, nlen, whole, ccase);
|
||||
if (q != NULL)
|
||||
{
|
||||
return i;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------- */
|
||||
|
||||
static void
|
||||
dview_search (WDiff * dview, int again)
|
||||
{
|
||||
/* XXX some statics here, to be remembered between runs */
|
||||
static char *searchopt_text = NULL;
|
||||
static int searchopt_type;
|
||||
static int searchopt_case;
|
||||
static int searchopt_backwards;
|
||||
static int searchopt_whole;
|
||||
|
||||
static int compiled = 0;
|
||||
|
||||
if (again < 0)
|
||||
{
|
||||
g_free (searchopt_text);
|
||||
searchopt_text = NULL;
|
||||
if (compiled)
|
||||
{
|
||||
compiled = 0;
|
||||
/*XXX free search exp */
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (dview->dsrc != DATA_SRC_MEM)
|
||||
{
|
||||
error_dialog (_("Search"), _(" Search is disabled "));
|
||||
return;
|
||||
}
|
||||
|
||||
if (!again || searchopt_text == NULL)
|
||||
{
|
||||
char *tsearchopt_text = NULL;
|
||||
int tsearchopt_type = searchopt_type;
|
||||
int tsearchopt_case = searchopt_case;
|
||||
int tsearchopt_backwards = searchopt_backwards;
|
||||
int tsearchopt_whole = searchopt_whole;
|
||||
|
||||
const char *search_str[] = {
|
||||
N_("&Normal")
|
||||
};
|
||||
|
||||
QuickWidget search_widgets[] = {
|
||||
/* 0 */
|
||||
QUICK_BUTTON (6, 10, 11, SEARCH_DLG_HEIGHT, N_("&Cancel"), B_CANCEL, NULL),
|
||||
/* 1 */
|
||||
QUICK_BUTTON (4, 10, 11, SEARCH_DLG_HEIGHT, N_("&Find all"), B_USER, NULL),
|
||||
/* 2 */
|
||||
QUICK_BUTTON (2, 10, 11, SEARCH_DLG_HEIGHT, N_("&OK"), B_ENTER, NULL),
|
||||
/* 3 */
|
||||
QUICK_CHECKBOX (33, SEARCH_DLG_WIDTH, 8, SEARCH_DLG_HEIGHT, N_("&Whole words"),
|
||||
&tsearchopt_whole),
|
||||
/* 4 */
|
||||
QUICK_CHECKBOX (33, SEARCH_DLG_WIDTH, 6, SEARCH_DLG_HEIGHT, N_("&Backwards"),
|
||||
&tsearchopt_backwards),
|
||||
/* 5 */
|
||||
QUICK_CHECKBOX (33, SEARCH_DLG_WIDTH, 5, SEARCH_DLG_HEIGHT, N_("case &Sensitive"),
|
||||
&tsearchopt_case),
|
||||
/* 6 */
|
||||
QUICK_RADIO (3, SEARCH_DLG_WIDTH, 5, SEARCH_DLG_HEIGHT,
|
||||
1, (const char **) search_str, (int *) &tsearchopt_type),
|
||||
/* 7 */
|
||||
QUICK_INPUT (3, SEARCH_DLG_WIDTH, 3, SEARCH_DLG_HEIGHT,
|
||||
tsearchopt_text, SEARCH_DLG_WIDTH - 6, 0, MC_HISTORY_SHARED_SEARCH,
|
||||
&tsearchopt_text),
|
||||
/* 8 */
|
||||
QUICK_LABEL (2, SEARCH_DLG_WIDTH, 2, SEARCH_DLG_HEIGHT, N_(" Enter search string:")),
|
||||
QUICK_END
|
||||
};
|
||||
|
||||
QuickDialog search_input = {
|
||||
SEARCH_DLG_WIDTH, SEARCH_DLG_HEIGHT, -1, 0,
|
||||
N_("Search"), "[Input Line Keys]",
|
||||
search_widgets, 0
|
||||
};
|
||||
|
||||
if (quick_dialog (&search_input) == B_CANCEL)
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (tsearchopt_text == NULL || !*tsearchopt_text)
|
||||
{
|
||||
g_free (tsearchopt_text);
|
||||
return;
|
||||
}
|
||||
g_free (searchopt_text);
|
||||
|
||||
searchopt_text = tsearchopt_text;
|
||||
searchopt_type = tsearchopt_type;
|
||||
searchopt_case = tsearchopt_case;
|
||||
searchopt_backwards = tsearchopt_backwards;
|
||||
searchopt_whole = tsearchopt_whole;
|
||||
}
|
||||
|
||||
if (compiled)
|
||||
{
|
||||
compiled = 0;
|
||||
/*XXX free search exp */
|
||||
}
|
||||
if (0 /*XXX new search exp */ )
|
||||
{
|
||||
error_dialog (_("Error"), _(" Cannot search "));
|
||||
return;
|
||||
}
|
||||
compiled = 1;
|
||||
if (searchopt_type == 0)
|
||||
{
|
||||
dview->last_found =
|
||||
dview_search_string (dview, searchopt_text, searchopt_case, searchopt_backwards,
|
||||
searchopt_whole);
|
||||
}
|
||||
|
||||
if (dview->last_found == -1)
|
||||
{
|
||||
error_dialog (_("Search"), _(" Search string not found "));
|
||||
}
|
||||
else
|
||||
{
|
||||
dview->skip_rows = dview->last_found;
|
||||
dview_update (dview);
|
||||
}
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------- */
|
||||
|
||||
static void
|
||||
dview_edit (WDiff * dview, int ord)
|
||||
{
|
||||
@ -3126,7 +2778,7 @@ dview_goto_cmd (WDiff * dview, int ord)
|
||||
}
|
||||
}
|
||||
}
|
||||
dview->skip_rows = i;
|
||||
dview->skip_rows = dview->search.last_accessed_num_line = i;
|
||||
snprintf (prev, sizeof (prev), "%d", newline);
|
||||
}
|
||||
g_free (input);
|
||||
@ -3168,12 +2820,14 @@ dview_event (Gpm_Event * event, void *x)
|
||||
if ((event->buttons & GPM_B_UP) && (event->type & GPM_DOWN))
|
||||
{
|
||||
dview->skip_rows -= 2;
|
||||
dview->search.last_accessed_num_line = dview->skip_rows;
|
||||
dview_update (dview);
|
||||
return result;
|
||||
}
|
||||
if ((event->buttons & GPM_B_DOWN) && (event->type & GPM_DOWN))
|
||||
{
|
||||
dview->skip_rows += 2;
|
||||
dview->search.last_accessed_num_line = dview->skip_rows;
|
||||
dview_update (dview);
|
||||
return result;
|
||||
}
|
||||
@ -3294,17 +2948,17 @@ dview_execute_cmd (WDiff * dview, unsigned long command)
|
||||
dview_redo (dview);
|
||||
break;
|
||||
case CK_DiffNextHunk:
|
||||
dview->skip_rows = find_next_hunk (dview->a[0], dview->skip_rows);
|
||||
dview->skip_rows = dview->search.last_accessed_num_line = find_next_hunk (dview->a[0], dview->skip_rows);
|
||||
break;
|
||||
case CK_DiffPrevHunk:
|
||||
dview->skip_rows = find_prev_hunk (dview->a[0], dview->skip_rows);
|
||||
dview->skip_rows = dview->search.last_accessed_num_line = find_prev_hunk (dview->a[0], dview->skip_rows);
|
||||
break;
|
||||
case CK_DiffGoto:
|
||||
dview_goto_cmd (dview, TRUE);
|
||||
break;
|
||||
/* what this?
|
||||
case KEY_BACKSPACE:
|
||||
dview->last_found = -1;
|
||||
dview->search.last_found_line = -1;
|
||||
break;
|
||||
*/
|
||||
case CK_DiffEditCurrent:
|
||||
@ -3318,25 +2972,32 @@ dview_execute_cmd (WDiff * dview, unsigned long command)
|
||||
dview_edit (dview, dview->ord ^ 1);
|
||||
break;
|
||||
case CK_DiffSearch:
|
||||
dview_search (dview, 1);
|
||||
dview_search_cmd (dview);
|
||||
break;
|
||||
case CK_DiffContinueSearch:
|
||||
dview_continue_search_cmd (dview);
|
||||
break;
|
||||
case CK_DiffBOF:
|
||||
dview->skip_rows = 0;
|
||||
dview->skip_rows = dview->search.last_accessed_num_line = 0;
|
||||
break;
|
||||
case CK_DiffEOF:
|
||||
dview->skip_rows = dview->a[0]->len - 1;
|
||||
dview->skip_rows = dview->search.last_accessed_num_line = dview->a[0]->len - 1;
|
||||
break;
|
||||
case CK_DiffUp:
|
||||
dview->skip_rows--;
|
||||
dview->search.last_accessed_num_line = dview->skip_rows;
|
||||
break;
|
||||
case CK_DiffDown:
|
||||
dview->skip_rows++;
|
||||
dview->search.last_accessed_num_line = dview->skip_rows;
|
||||
break;
|
||||
case CK_DiffPageDown:
|
||||
dview->skip_rows += dview->height - 2;
|
||||
dview->search.last_accessed_num_line = dview->skip_rows;
|
||||
break;
|
||||
case CK_DiffPageUp:
|
||||
dview->skip_rows -= dview->height - 2;
|
||||
dview->search.last_accessed_num_line = dview->skip_rows;
|
||||
break;
|
||||
case CK_DiffLeft:
|
||||
dview->skip_cols--;
|
||||
@ -3512,7 +3173,6 @@ diff_view (const char *file1, const char *file2, const char *label1, const char
|
||||
if (!error)
|
||||
{
|
||||
run_dlg (dview_dlg);
|
||||
dview_search (dview, -1);
|
||||
dview_fini (dview);
|
||||
}
|
||||
destroy_dlg (dview_dlg);
|
||||
@ -3603,3 +3263,91 @@ dview_diff_cmd (WDiff *dview)
|
||||
message (1, MSG_ERROR, _("Need two files to compare"));
|
||||
}
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------- */
|
||||
|
||||
void
|
||||
dview_update (WDiff * dview)
|
||||
{
|
||||
int height = dview->height;
|
||||
int width1;
|
||||
int width2;
|
||||
|
||||
int last = dview->a[0]->len - 1;
|
||||
|
||||
if (dview->skip_rows > last)
|
||||
{
|
||||
dview->skip_rows = dview->search.last_accessed_num_line = last;
|
||||
}
|
||||
if (dview->skip_rows < 0)
|
||||
{
|
||||
dview->skip_rows = dview->search.last_accessed_num_line = 0;
|
||||
}
|
||||
if (dview->skip_cols < 0)
|
||||
{
|
||||
dview->skip_cols = 0;
|
||||
}
|
||||
|
||||
if (height < 2)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
width1 = dview->half1 + dview->bias;
|
||||
width2 = dview->half2 - dview->bias;
|
||||
if (dview->full)
|
||||
{
|
||||
width1 = COLS;
|
||||
width2 = 0;
|
||||
}
|
||||
|
||||
if (dview->new_frame)
|
||||
{
|
||||
int xwidth = dview->display_symbols + dview->display_numbers;
|
||||
|
||||
tty_setcolor (NORMAL_COLOR);
|
||||
if (width1 > 1)
|
||||
{
|
||||
tty_draw_box (1, 0, height, width1, FALSE);
|
||||
}
|
||||
if (width2 > 1)
|
||||
{
|
||||
tty_draw_box (1, width1, height, width2, FALSE);
|
||||
}
|
||||
|
||||
if (xwidth)
|
||||
{
|
||||
xwidth++;
|
||||
if (xwidth < width1 - 1)
|
||||
{
|
||||
tty_gotoyx (1, xwidth);
|
||||
tty_print_alt_char (mc_tty_frm[MC_TTY_FRM_DTOPMIDDLE], FALSE);
|
||||
tty_gotoyx (height, xwidth);
|
||||
tty_print_alt_char (mc_tty_frm[MC_TTY_FRM_DBOTTOMMIDDLE], FALSE);
|
||||
tty_draw_vline (2, xwidth, mc_tty_frm[MC_TTY_FRM_VERT], height - 2);
|
||||
}
|
||||
if (xwidth < width2 - 1)
|
||||
{
|
||||
tty_gotoyx (1, width1 + xwidth);
|
||||
tty_print_alt_char (mc_tty_frm[MC_TTY_FRM_DTOPMIDDLE], FALSE);
|
||||
tty_gotoyx (height, width1 + xwidth);
|
||||
tty_print_alt_char (mc_tty_frm[MC_TTY_FRM_DBOTTOMMIDDLE], FALSE);
|
||||
tty_draw_vline (2, width1 + xwidth, mc_tty_frm[MC_TTY_FRM_VERT], height - 2);
|
||||
}
|
||||
}
|
||||
dview->new_frame = 0;
|
||||
}
|
||||
|
||||
if (width1 > 2)
|
||||
{
|
||||
dview_status (dview, dview->ord, width1, 0);
|
||||
dview_display_file (dview, dview->ord, 2, 1, height - 2, width1 - 2);
|
||||
}
|
||||
if (width2 > 2)
|
||||
{
|
||||
dview_status (dview, dview->ord ^ 1, width2, width1);
|
||||
dview_display_file (dview, dview->ord ^ 1, 2, width1 + 1, height - 2, width2 - 2);
|
||||
}
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------- */
|
||||
|
@ -1,114 +1,18 @@
|
||||
#ifndef MC_YDIFF_H
|
||||
#define MC_YDIFF_H
|
||||
#ifndef MC__DIFFVIEW_YDIFF_H
|
||||
#define MC__DIFFVIEW_YDIFF_H
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int fd;
|
||||
int pos;
|
||||
int len;
|
||||
char *buf;
|
||||
int flags;
|
||||
void *data;
|
||||
} FBUF;
|
||||
/*** typedefs(not structures) and defined constants **********************************************/
|
||||
struct WDiff_struct;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int a[2][2];
|
||||
int cmd;
|
||||
} DIFFCMD;
|
||||
/*** enums ***************************************************************************************/
|
||||
|
||||
typedef int (*DFUNC) (void *ctx, int ch, int line, off_t off, size_t sz, const char *str);
|
||||
/*** structures declarations (and typedefs of structures)*****************************************/
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int off;
|
||||
int len;
|
||||
} BRACKET[2];
|
||||
/*** global variables defined in .c file *********************************************************/
|
||||
|
||||
typedef int PAIR[2];
|
||||
/*** declarations of public functions ************************************************************/
|
||||
|
||||
typedef enum
|
||||
{
|
||||
DATA_SRC_MEM = 0,
|
||||
DATA_SRC_TMP = 1,
|
||||
DATA_SRC_ORG = 2
|
||||
} DSRC;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int ch;
|
||||
int line;
|
||||
union
|
||||
{
|
||||
off_t off;
|
||||
size_t len;
|
||||
} u;
|
||||
void *p;
|
||||
} DIFFLN;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
FBUF *f;
|
||||
GArray *a;
|
||||
DSRC dsrc;
|
||||
} PRINTER_CTX;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
Widget widget;
|
||||
|
||||
const char *args; /* Args passed to diff */
|
||||
const char *file[2]; /* filenames */
|
||||
const char *label[2];
|
||||
FBUF *f[2];
|
||||
const char *backup_sufix;
|
||||
gboolean merged;
|
||||
GArray *a[2];
|
||||
GPtrArray *hdiff;
|
||||
int ndiff; /* number of hunks */
|
||||
DSRC dsrc; /* data source: memory or temporary file */
|
||||
|
||||
int view_quit:1; /* Quit flag */
|
||||
|
||||
int height;
|
||||
int half1;
|
||||
int half2;
|
||||
int width1;
|
||||
int width2;
|
||||
int bias;
|
||||
int new_frame;
|
||||
int skip_rows;
|
||||
int skip_cols;
|
||||
int display_symbols;
|
||||
int display_numbers;
|
||||
int show_cr;
|
||||
int tab_size;
|
||||
int ord;
|
||||
int full;
|
||||
ssize_t last_found;
|
||||
gboolean utf8;
|
||||
/* converter for translation of text */
|
||||
GIConv converter;
|
||||
struct
|
||||
{
|
||||
int quality;
|
||||
gboolean strip_trailing_cr;
|
||||
gboolean ignore_tab_expansion;
|
||||
gboolean ignore_space_change;
|
||||
gboolean ignore_all_space;
|
||||
gboolean ignore_case;
|
||||
} opt;
|
||||
} WDiff;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
DIFF_NONE = 0,
|
||||
DIFF_ADD = 1,
|
||||
DIFF_DEL = 2,
|
||||
DIFF_CHG = 3
|
||||
} DiffState;
|
||||
|
||||
void dview_diff_cmd (WDiff * dview);
|
||||
void dview_diff_cmd (struct WDiff_struct * dview);
|
||||
int diff_view (const char *file1, const char *file2, const char *label1, const char *label2);
|
||||
|
||||
#endif
|
||||
#endif /* MC__DIFFVIEW_YDIFF_H */
|
||||
|
@ -468,6 +468,7 @@ static name_keymap_t command_names[] = {
|
||||
{ "DiffEditCurrent", CK_DiffEditCurrent},
|
||||
{ "DiffEditOther", CK_DiffEditOther},
|
||||
{ "DiffSearch", CK_DiffSearch},
|
||||
{ "DiffContinueSearch", CK_DiffContinueSearch},
|
||||
{ "DiffEOF", CK_DiffEOF},
|
||||
{ "DiffBOF", CK_DiffBOF},
|
||||
{ "DiffDown", CK_DiffDown},
|
||||
@ -990,6 +991,7 @@ const global_keymap_t default_diff_keymap[] = {
|
||||
{ KEY_F (4), CK_DiffEditCurrent, "F4" },
|
||||
{ KEY_F (5), CK_DiffMergeCurrentHunk, "F5" },
|
||||
{ KEY_F (7), CK_DiffSearch, "F7" },
|
||||
{ KEY_F (17), CK_DiffContinueSearch, "S-F7" },
|
||||
{ KEY_F (10), CK_DiffQuit, "F10" },
|
||||
{ KEY_F (14), CK_DiffEditOther, "S-F4" },
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user