Here is an updated version of the patch. In previous version the jumpkey numbers were displayed even for empty entries. This was most noticeable in the hotlist. I think it was quite confusing. Now the numbers are displayed only for non-empty entries.
The new version of the patch is attached to this message. The only difference between the two versions: diff -purN mc-4.6.0-pre1/src/widget.c mc-4.6.0-pre1.new/src/widget.c --- mc-4.6.0-pre1/src/widget.c Wed Dec 18 04:04:33 2002 +++ mc-4.6.0-pre1.new/src/widget.c Wed Dec 18 04:04:17 2002 @@ -1729,7 +1729,7 @@ listbox_draw (WListbox *l, Dlg_head *h, text = e->text; e = e->next; } - if (l->use_jumpkeys) + if (l->use_jumpkeys && *text) printw (" %3d | %-*s ", i + 1, l->width-7, name_trunc (text, l->width-7)); else printw (" %-*s ", l->width-2, name_trunc (text, l->width-2)); -- Tomas Styblo <[EMAIL PROTECTED]> PGP: http://pgp.mit.edu:11371/pks/lookup?op=get&search=0xC97EA4B6
diff -purN mc-4.6.0-pre1/doc/mc.1.in mc-4.6.0-pre1.new/doc/mc.1.in --- mc-4.6.0-pre1/doc/mc.1.in Wed Aug 21 03:08:46 2002 +++ mc-4.6.0-pre1.new/doc/mc.1.in Wed Dec 18 03:23:49 2002 @@ -337,6 +337,12 @@ suspended by using this trick, you won't programs from the Midnight Commander until you terminate the suspended application. .PP +.B number keys, +When the "lynx-like jumpkeys" configuration option is enabled, then you +can use number keys to select numbered entries in the panels, the +history and the hotlist. More information about this feature is in +the "Configuration: Panel Options" section. +.PP .SH " Directory Panels" This section lists the keys which operate on the directory panels. If you want to know how to change the appearance of the panels take a @@ -585,6 +591,11 @@ completion .\"Completion" for you. .PP +When the configuration option "lynx-like jumpkeys" is enabled and the +command line is empty, then the number keys are intercepted by the +panels. To execute a command which begins with a number, the command +must be prefixed with a space. +.PP .SH "" .SH "Menu Bar" The menu bar pops up when you press F9 or click the mouse on the top @@ -732,6 +743,9 @@ the group of the file. .B inode, the inode of the file. .PP +.B jumpkey, +number of the entry, used by the "lynx-like jumpkeys" feature. +.PP Also you may use these field names for arranging the display: .PP .B space, @@ -1569,6 +1583,14 @@ mode or owner changes, etc) the display if you have the option on, you have to rescan the directory manually (with C-r). .PP +.I Lynx-like jumpkeys. +This option enables a lynx-like navigation using numbered entries in +the panels and other widgets. Each displayed entry is numbered and +may be selected by one or two keystrokes. +To select for example a file or a hotlist entry numbered "23", +just press the keys "2" and "3" in quick succession. +The selection cursor will immediately move to that entry. +.PP .B Pause after run .PP After executing your commands, the Midnight Commander can pause, so diff -purN mc-4.6.0-pre1/src/complete.c mc-4.6.0-pre1.new/src/complete.c --- mc-4.6.0-pre1/src/complete.c Tue Mar 26 03:09:39 2002 +++ mc-4.6.0-pre1.new/src/complete.c Wed Dec 18 03:23:49 2002 @@ -990,6 +990,7 @@ complete_engine (WInput *in, int what_to dialog_colors, query_callback, "[Completion]", "complete", DLG_NONE); query_list = listbox_new (1, 1, w - 2, h - 2, 0, querylist_callback, NULL); + query_list->use_jumpkeys = 0; /* never use jumpkeys in completion menu */ add_widget (query_dlg, query_list); for (p = in->completions + 1; *p; p++) listbox_add_item (query_list, 0, 0, *p, NULL); diff -purN mc-4.6.0-pre1/src/dir.h mc-4.6.0-pre1.new/src/dir.h --- mc-4.6.0-pre1/src/dir.h Fri Dec 28 02:11:52 2001 +++ mc-4.6.0-pre1.new/src/dir.h Wed Dec 18 03:23:49 2002 @@ -10,6 +10,7 @@ typedef struct { /* File attributes */ int fnamelen; + int jumpkey_num; char *fname; struct stat buf; diff -purN mc-4.6.0-pre1/src/main.c mc-4.6.0-pre1.new/src/main.c --- mc-4.6.0-pre1/src/main.c Wed Aug 21 03:08:49 2002 +++ mc-4.6.0-pre1.new/src/main.c Wed Dec 18 03:23:49 2002 @@ -286,6 +286,10 @@ static int edit_one_file_start_line = 1; shut down */ int midnight_shutdown = 0; +/* Grab number keys in panels and listbox widgets and use them + * as lynx-like jumpkeys */ +int use_jumpkeys = 0; + /* to show nice prompts */ static int last_paused = 0; @@ -1176,6 +1180,20 @@ toggle_show_hidden (void) update_panels (UP_RELOAD, UP_KEEPSEL); } +void +toggle_use_jumpkeys (void) +{ + int i; + WPanel *p; + + use_jumpkeys = !use_jumpkeys; + for (i = 0; i <= 1; i++) { + p = (i == 0 ? left_panel : right_panel); + if (p) set_panel_formats (p); + } + update_panels (UP_RELOAD, UP_KEEPSEL); +} + /* * Just a hack for allowing url-like pathnames to be accepted from the * command line. diff -purN mc-4.6.0-pre1/src/main.h mc-4.6.0-pre1.new/src/main.h --- mc-4.6.0-pre1/src/main.h Mon Aug 19 06:16:47 2002 +++ mc-4.6.0-pre1.new/src/main.h Wed Dec 18 03:23:49 2002 @@ -5,6 +5,7 @@ void toggle_fast_reload (void); void toggle_mix_all_files (void); void toggle_show_backup (void); void toggle_show_hidden (void); +void toggle_use_jumpkeys (void); enum { RP_NOCLEAR, @@ -84,6 +85,7 @@ extern int only_leading_plus_minus; extern int ftpfs_directory_timeout; extern int output_starts_shell; extern int midnight_shutdown; +extern int use_jumpkeys; extern char search_buffer [256]; extern char cmd_buf [512]; extern char *cmdline_geometry; diff -purN mc-4.6.0-pre1/src/option.c mc-4.6.0-pre1.new/src/option.c --- mc-4.6.0-pre1/src/option.c Tue Aug 20 04:57:25 2002 +++ mc-4.6.0-pre1.new/src/option.c Wed Dec 18 03:23:49 2002 @@ -82,6 +82,7 @@ static struct { {N_("shell &Patterns"), &easy_patterns, TOGGLE_VARIABLE, 0, "shell-patt" }, {N_("Compute &Totals"), &file_op_compute_totals, TOGGLE_VARIABLE, 0, "compute-totals" }, {N_("&Verbose operation"), &verbose, TOGGLE_VARIABLE, 0, "verbose" }, + {N_("&lynx-like jumpkeys"), &use_jumpkeys, toggle_use_jumpkeys, 0, +"jumpkeys" }, {N_("&Fast dir reload"), &fast_reload, toggle_fast_reload, 0, "fast-reload" }, {N_("mi&X all files"), &mix_all_files, toggle_mix_all_files, 0, "mix-files" }, {N_("&Drop down menus"), &drop_menus, TOGGLE_VARIABLE, 0, "drop-menus" }, @@ -105,7 +106,7 @@ static int configure_callback (struct Dl attrset (COLOR_NORMAL); dlg_erase (h); draw_box (h, 1, 2, h->lines - 2, h->cols - 4); - draw_box (h, PY, PX, 8, first_width); + draw_box (h, PY, PX, 9, first_width); draw_box (h, RY, RX, 5, first_width); draw_box (h, OY, OX, 15, second_width); @@ -221,8 +222,8 @@ static void init_configure (void) pause_radio = radio_new (RY+1, RX+2, 3, pause_options, 1, "pause-radio"); pause_radio->sel = pause_after_run; add_widget (conf_dlg, pause_radio); - for (i = 0; i < 6; i++){ - check_options [i+13].widget = check_new (PY + (6-i), PX+2, + for (i = 0; i < 7; i++){ + check_options [i+13].widget = check_new (PY + (7-i), PX+2, XTRACT(i+13)); add_widget (conf_dlg, check_options [i+13].widget); } diff -purN mc-4.6.0-pre1/src/screen.c mc-4.6.0-pre1.new/src/screen.c --- mc-4.6.0-pre1/src/screen.c Mon Aug 19 00:07:09 2002 +++ mc-4.6.0-pre1.new/src/screen.c Wed Dec 18 03:23:49 2002 @@ -44,6 +44,7 @@ #include "user.h" #include "profile.h" #include "widget.h" +#include "command.h" #include "../vfs/vfs.h" #ifdef _OS_NT @@ -371,6 +372,14 @@ string_dot (file_entry *fe, int len) return "."; } +static const char * +string_jumpkey (file_entry *fe, int len) +{ + static char jumpkey[4]; + snprintf(jumpkey, sizeof(jumpkey), "%3d", fe->jumpkey_num); + return (jumpkey); +} + #define GT 1 static struct { @@ -402,6 +411,7 @@ static struct { { "|", 1, 0, J_RIGHT, " ", 0, NULL, NULL }, { "space", 1, 0, J_RIGHT, " ", 0, string_space, NULL }, { "dot", 1, 0, J_RIGHT, " ", 0, string_dot, NULL }, +{ "jumpkey", 3, 0, J_RIGHT, " ", 0, string_jumpkey, +NULL }, }; static char * @@ -679,6 +689,7 @@ paint_dir (WPanel *panel) color = 2 * (panel->dir.list [i+panel->top_file].f.marked); color += (panel->selected==i+panel->top_file && panel->active); } + panel->dir.list[i+panel->top_file].jumpkey_num = i + 1; repaint_file (panel, i+panel->top_file, 1, color, 0); } standend (); @@ -1399,17 +1410,26 @@ panel_format (WPanel *panel) switch (panel->list_type){ case list_long: - return "full perm,space,nlink,space,owner,space,group,space,size,space,mtime,space,name"; + if (use_jumpkeys) + return "full +jumpkey,|,perm,space,nlink,space,owner,space,group,space,size,space,mtime,space,name"; + else + return "full +perm,space,nlink,space,owner,space,group,space,size,space,mtime,space,name"; case list_brief: - return "half 2,type,name"; + if (use_jumpkeys) + return "half 2,jumpkey,|,type,name"; + else + return "half 2,type,name"; case list_user: return panel->user_format; default: case list_full: - return "half type,name,|,size,|,mtime"; + if (use_jumpkeys) + return "half jumpkey,|,type,name,|,size,|,mtime"; + else + return "half type,name,|,size,|,mtime"; } } @@ -2137,7 +2157,10 @@ static inline int panel_key (WPanel *panel, int key) { int i; - + static int jumpkey_num = 0; /* number of entry the user wants to select */ + static struct timeval jumpkey_time; /* time of last jumpkey keystroke */ + int items = llines (panel) * (panel->split ? 2 : 1); + for (i = 0; panel_keymap [i].key_code; i++){ if (key == panel_keymap [i].key_code){ if (panel_keymap [i].fn != start_search) @@ -2165,6 +2188,40 @@ panel_key (WPanel *panel, int key) return 1; } + switch (key) { + case '0': case '1': case '2': case '3': case '4': + case '5': case '6': case '7': case '8': case '9': + if (! use_jumpkeys) + break; + + /* process jumpkeys only if command line is empty */ + if (input_w(cmdline)->point > 0) + break; + + if (jumpkey_num > 0 && + gettimeofday_diff_ms(&jumpkey_time, NULL) <= JUMPKEY_MAXDELAY) { + if ((jumpkey_num * 10) + char_to_int(key) > items) { + jumpkey_num = char_to_int(key); + } + else + jumpkey_num = (jumpkey_num * 10) + char_to_int(key); + } + else { + jumpkey_num = char_to_int(key); + } + gettimeofday(&jumpkey_time, NULL); + + if (jumpkey_num == 0 || jumpkey_num > items) + return 0; + + unselect_item(panel); + panel->selected = (panel->top_file + jumpkey_num) - 1; + select_item(panel); + paint_panel(panel); + return 1; + break; + } + /* Do not eat characters not meant for the panel below ' ' (e.g. C-l). */ if ((key >= ' '&& key <= 255) || key == 8 || key == KEY_BACKSPACE) { if (panel->searching){ diff -purN mc-4.6.0-pre1/src/setup.c mc-4.6.0-pre1.new/src/setup.c --- mc-4.6.0-pre1/src/setup.c Mon Aug 19 06:16:47 2002 +++ mc-4.6.0-pre1.new/src/setup.c Wed Dec 18 03:23:49 2002 @@ -193,6 +193,7 @@ static const struct { { "xtree_mode", &xtree_mode }, { "num_history_items_recorded", &num_history_items_recorded }, { "file_op_compute_totals", &file_op_compute_totals }, + { "use_jumpkeys", &use_jumpkeys }, #ifdef SAVE_CHANGES_OUTSIDE_OPTIONS_MENU { "dive_into_subdirs", &dive_into_subdirs }, { "preserve_uidgid", &preserve_uidgid }, diff -purN mc-4.6.0-pre1/src/util.h mc-4.6.0-pre1.new/src/util.h --- mc-4.6.0-pre1/src/util.h Tue Aug 20 04:57:25 2002 +++ mc-4.6.0-pre1.new/src/util.h Wed Dec 18 03:23:49 2002 @@ -31,6 +31,7 @@ char *reverse_string (char *string); char *diff_two_paths (char *first, char *second); char *x_basename (char *s); +#define char_to_int(CH) (CH - '0') /* Profile managing functions */ int set_int (char *, char *, int); @@ -90,6 +91,7 @@ char *canonicalize_pathname (char *); char *get_current_wd (char *buffer, int size); int my_mkdir (char *s, mode_t mode); int my_rmdir (char *s); +long gettimeofday_diff_ms (struct timeval *from, struct timeval *to); /* Rotating dash routines */ void use_dash (int flag); /* Disable/Enable rotate_dash routines */ diff -purN mc-4.6.0-pre1/src/utilunix.c mc-4.6.0-pre1.new/src/utilunix.c --- mc-4.6.0-pre1/src/utilunix.c Tue Aug 20 04:57:25 2002 +++ mc-4.6.0-pre1.new/src/utilunix.c Wed Dec 18 03:23:49 2002 @@ -640,6 +640,34 @@ int gettimeofday (struct timeval *tp, vo } #endif /* HAVE_GET_PROCESS_STATS */ +/* Return the difference between two timeval timestamps in + * miliseconds. + * The seconds timestamp must be larger or equal to the first. + * The first timestamp is mandatory. + * If the second timestamp is NULL then the first timestamp is + * compared to the current time. + * The return value is "long", therefore it may overflow if the + * difference is too big. */ +long gettimeofday_diff_ms (struct timeval *from, struct timeval *to) +{ + struct timeval now; + long diff; + + if (from == NULL) + return (-1); + + if (to == NULL) { + gettimeofday(&now, NULL); + to = &now; + } + + diff = ((to->tv_sec == from->tv_sec ? + to->tv_usec - from->tv_usec : + to->tv_usec + (1e6 - from->tv_usec) + + (((to->tv_sec - from->tv_sec) - 1) * 1e6)) / 1000); + return (diff); +} + #ifndef HAVE_PUTENV /* The following piece of code was copied from the GNU C Library */ diff -purN mc-4.6.0-pre1/src/widget.c mc-4.6.0-pre1.new/src/widget.c --- mc-4.6.0-pre1/src/widget.c Sat Jul 20 04:54:52 2002 +++ mc-4.6.0-pre1.new/src/widget.c Wed Dec 18 03:17:50 2002 @@ -42,6 +42,7 @@ #include "complete.h" #include "key.h" /* XCTRL and ALT macros */ #include "profile.h" /* for history loading and saving */ +#include "main.h" static int button_event (Gpm_Event *event, WButton *b); @@ -1728,7 +1729,10 @@ listbox_draw (WListbox *l, Dlg_head *h, text = e->text; e = e->next; } - printw (" %-*s ", l->width-2, name_trunc (text, l->width-2)); + if (l->use_jumpkeys && *text) + printw (" %3d | %-*s ", i + 1, l->width-7, name_trunc (text, l->width-7)); + else + printw (" %-*s ", l->width-2, name_trunc (text, l->width-2)); } l->cursor_y = sel_line; if (!l->scrollbar) @@ -1919,7 +1923,9 @@ listbox_key (WListbox *l, int key) { int i; int j = 0; - + static int jumpkey_num = 0; /* number of entry the user wants to select */ + static struct timeval jumpkey_time; /* time of last jumpkey keystroke */ + WLEntry *e = NULL; if (!l->list) return 0; @@ -1959,6 +1965,39 @@ listbox_key (WListbox *l, int key) for (i = 0; i < l->height-1; i++) j |= listbox_back (l); return j > 0; + + case '0': case '1': case '2': case '3': case '4': + case '5': case '6': case '7': case '8': case '9': + if (! l->use_jumpkeys) + break; + + if (jumpkey_num > 0 && + gettimeofday_diff_ms(&jumpkey_time, NULL) <= JUMPKEY_MAXDELAY) { + if ((jumpkey_num * 10) + char_to_int(key) > + (l->height > l->count ? l->count : l->height)) { + jumpkey_num = char_to_int(key); + } + else + jumpkey_num = (jumpkey_num * 10) + char_to_int(key); + } + else { + jumpkey_num = char_to_int(key); + } + gettimeofday(&jumpkey_time, NULL); + + if (jumpkey_num == 0 || jumpkey_num > + (l->height > l->count ? l->count : l->height)) + return 0; + if (! (e = l->top)) + return 0; + for (i = 1; i < jumpkey_num; i++) { + if (e->next) + e = e->next; + } + if (e != l->current) { + listbox_select_entry(l, e); + return 1; + } } return 0; } @@ -2108,6 +2147,7 @@ listbox_new (int y, int x, int width, in l->cback = callback; l->action = action; l->allow_duplicates = 1; + l->use_jumpkeys = use_jumpkeys; l->scrollbar = slow_terminal ? 0 : 1; widget_want_hotkey (l->widget, 1); diff -purN mc-4.6.0-pre1/src/widget.h mc-4.6.0-pre1.new/src/widget.h --- mc-4.6.0-pre1/src/widget.h Mon Oct 1 15:30:24 2001 +++ mc-4.6.0-pre1.new/src/widget.h Wed Dec 18 03:23:49 2002 @@ -96,6 +96,7 @@ typedef struct { int transparent; /* Paint in the default color fg/bg */ } WLabel; +#define JUMPKEY_MAXDELAY 1500 typedef struct WLEntry { char *text; /* Text to display */ int hotkey; @@ -128,6 +129,7 @@ typedef struct { int height; /* Size of the widget */ int action; /* Action type */ int allow_duplicates; /* Do we allow duplicates on the list? */ + int use_jumpkeys; int scrollbar; /* Draw a scrollbar? */ lcback cback; /* The callback function */ int cursor_x, cursor_y; /* Cache the values */