.B Command Mode
Execute vimp commands from the builtin inputbox (commandline).
.TP
+.B Search Mode
+Search for strings within the current displayed page.
+.TP
.B Insert Mode
Used for editing text elements in a webpage.
.SH COMMANDS
Scroll the page N times the "scrollstep" to the end.
.SS Keybinding
To bind a command to a key sequence use the {n,i,c,h}map command. To map a
-keysequence to a command, use this format "nmap {[modkey]key}={command}".
+keysequence to a command, use this format "nmap {[modkey]key}={command}[ params]".
The modkey is a single simple char like "g". The key can also contain
special keys and modifiers and is given in format like "<ctrl-o>", "<tab>",
Example:
.br
-To add a keybinding to focus the next hint in hinting mode use
-"hmap <shift-tab>=hint-focus-prev"
+"hmap <shift-tab>=hint-focus-prev" to add focus next in in Hinting Mode.
+.br
+"nmap <shift-?>=input :foo" to write :foo into input box and switch to Command Mode.
.br
-To remove this keybinding use "hunmap <shift-tab>".
+"hunmap <shift-tab>" To remove this keybinding use.
.TP
.B nmap
Add a keybinding used in Normal Mode.
.B hmap
Add a keybinding used in Hint Mode.
.TP
+.B smap
+Add keybinding used in Search Mode.
+.TP
.B nunmap
Remove a Normal Mode keybinding.
.TP
.TP
.B hunmap
Remove a Hint Mode keybinding.
+.TP
+.B sunmap
+Remove a Search Mode keybinding.
.SS Complete
.TP
.B complete
.B set
Set configuration values.
.TP
+.B search-{forward, backward}
+Search in current page forward or backward.
+.TP
.B inspect
Toggles the webinspector for current page. This is only available if the config
"webinspector" is enabled.
{"imap", command_map, {VP_MODE_INSERT}, VP_MODE_NORMAL},
{"cmap", command_map, {VP_MODE_COMMAND}, VP_MODE_NORMAL},
{"hmap", command_map, {VP_MODE_HINTING}, VP_MODE_NORMAL},
+ {"smap", command_map, {VP_MODE_SEARCH}, VP_MODE_NORMAL},
{"nunmap", command_unmap, {VP_MODE_NORMAL}, VP_MODE_NORMAL},
{"iunmap", command_unmap, {VP_MODE_INSERT}, VP_MODE_NORMAL},
{"cunmap", command_unmap, {VP_MODE_COMMAND}, VP_MODE_NORMAL},
{"hunmap", command_unmap, {VP_MODE_HINTING}, VP_MODE_NORMAL},
+ {"sunmap", command_map, {VP_MODE_SEARCH}, VP_MODE_NORMAL},
{"set", command_set, {0}, VP_MODE_NORMAL},
{"complete", command_complete, {0}, VP_MODE_COMMAND | VP_MODE_COMPLETE},
{"complete-back", command_complete, {1}, VP_MODE_COMMAND | VP_MODE_COMPLETE},
{"hint-focus-prev", command_hints_focus, {1}, VP_MODE_HINTING},
{"yank-uri", command_yank, {COMMAND_YANK_PRIMARY | COMMAND_YANK_SECONDARY | COMMAND_YANK_URI}, VP_MODE_NORMAL},
{"yank-selection", command_yank, {COMMAND_YANK_PRIMARY | COMMAND_YANK_SECONDARY | COMMAND_YANK_SELECTION}, VP_MODE_NORMAL},
+ {"search-forward", command_search, {VP_SEARCH_FORWARD}, VP_MODE_SEARCH},
+ {"search-backward", command_search, {VP_SEARCH_BACKWARD}, VP_MODE_SEARCH},
};
static void command_write_input(const gchar* str);
return FALSE;
}
+gboolean command_search(const Arg* arg)
+{
+ State* state = &vp.state;
+ gboolean forward = !(arg->i ^ state->search_dir);
+
+ if (arg->i == VP_SEARCH_OFF && state->search_query) {
+ OVERWRITE_STRING(state->search_query, NULL);
+ webkit_web_view_unmark_text_matches(vp.gui.webview);
+
+ return TRUE;
+ }
+
+ /* copy search query for later use */
+ if (arg->s) {
+ OVERWRITE_STRING(state->search_query, arg->s);
+ /* set dearch dir only when the searching is started */
+ vp.state.search_dir = arg->i;
+
+ vp_set_mode(VP_MODE_SEARCH, FALSE);
+ }
+
+ if (state->search_query) {
+ webkit_web_view_mark_text_matches(vp.gui.webview, state->search_query, FALSE, 0);
+ webkit_web_view_set_highlight_text_matches(vp.gui.webview, TRUE);
+
+ webkit_web_view_search_text(vp.gui.webview, state->search_query, FALSE, forward, TRUE);
+ }
+
+ return TRUE;
+}
+
static void command_write_input(const gchar* str)
{
gint pos = 0;
gboolean command_hints(const Arg* arg);
gboolean command_hints_focus(const Arg* arg);
gboolean command_yank(const Arg* arg);
+gboolean command_search(const Arg* arg);
#endif /* end of include guard: COMMAND_H */
{"nmap gf=source"},
{"nmap gF=inspect"},
{"nmap <shift-:>=input"},
+ {"nmap <shift-/>=input /"},
+ {"nmap <shift-?>=input ?"},
+ {"smap n=search-forward"},
+ {"smap N=search-backward"},
{"nmap o=inputopen"},
{"nmap t=inputtabopen"},
{"nmap O=inputopencurrent"},
char **string = g_strsplit(line, "=", 2);
guint len = g_strv_length(string);
- if (len == 2 && command_exists(string[1])) {
+ if (len == 2) {
+ /* split the input string into command and parameter part */
+ gchar** token = g_strsplit(string[1], " ", 2);
+ if (!token[0] || !command_exists(token[0])) {
+ g_strfreev(token);
+ return FALSE;
+ }
+
Keybind* keybind = g_new0(Keybind, 1);
keybind->mode = mode;
- keybind->command = g_strdup(string[1]);
+ keybind->command = g_strdup(token[0]);
+ keybind->param = g_strdup(token[1]);
+ g_strfreev(token);
keybind_str_to_keybind(string[0], keybind);
if (link) {
Keybind* keybind = (Keybind*)link->data;
- command_run(keybind->command, NULL);
+ command_run(keybind->command, keybind->param);
return TRUE;
}
guint modmask; /* modemask for the kayval */
guint keyval;
gchar* command; /* command to run */
+ gchar* param;
} Keybind;
void keybind_init(void);
gtk_widget_grab_focus(GTK_WIDGET(gui->webview));
+ if (length <= 1) {
+ return;
+ }
+
/* do not free or modify text */
text = gtk_entry_get_text(entry);
- if (1 < length && ':' == text[0]) {
- completion_clean();
- success = vp_process_input((text + 1));
- if (!success) {
- /* switch to normal mode after running command without success the
- * mode after success is set by command_run to the value defined
- * for the command */
- vp_set_mode(VP_MODE_NORMAL , FALSE);
- }
+ switch (text[0]) {
+ case '/':
+ case '?':
+ {
+ Arg a = {text[0] == '/' ? VP_SEARCH_FORWARD : VP_SEARCH_BACKWARD, g_strdup(text + 1)};
+ command_search(&a);
+ g_free(a.s);
+ }
+ break;
+
+ case ':':
+ completion_clean();
+ success = vp_process_input((text + 1));
+ if (!success) {
+ /* switch to normal mode after running command without success the
+ * mode after success is set by command_run to the value defined
+ * for the command */
+ vp_set_mode(VP_MODE_NORMAL, FALSE);
+ }
+ break;
}
}
}
switch (CLEAN_MODE(mode)) {
case VP_MODE_NORMAL:
- /* if previous mode was hinting clear the hints */
if (GET_CLEAN_MODE() == VP_MODE_HINTING) {
+ /* if previous mode was hinting clear the hints */
hints_clear();
- }
- /* clean the input if current mode is insert to remove -- INPUT -- */
- if (GET_CLEAN_MODE() == VP_MODE_INSERT) {
+ } else if (GET_CLEAN_MODE() == VP_MODE_INSERT) {
+ /* clean the input if current mode is insert to remove -- INPUT -- */
clean = TRUE;
+ } else if (GET_CLEAN_MODE() == VP_MODE_SEARCH) {
+ /* cleaup previous search */
+ command_search(&((Arg){VP_SEARCH_OFF}));
}
gtk_widget_grab_focus(GTK_WIDGET(vp.gui.webview));
break;
+ case VP_MODE_SEARCH:
+ break;
+
case VP_MODE_COMMAND:
case VP_MODE_HINTING:
gtk_widget_grab_focus(GTK_WIDGET(vp.gui.inputbox));
VP_SCROLL_UNIT_HALFPAGE = (1 << 4)
};
+typedef enum {
+ VP_SEARCH_FORWARD,
+ VP_SEARCH_BACKWARD,
+ VP_SEARCH_OFF,
+} SearchDirection;
+
typedef enum {
VP_MSG_NORMAL,
VP_MSG_ERROR,
guint progress;
StatusType status;
gboolean is_inspecting;
+ SearchDirection search_dir;
+ gchar* search_query;
} State;
/* behaviour */