Allow to yank, and paste from different registers.
Open the oldest entry from read it later queue in current browser window, if
vimb has been compiled with QUEUE feature.
.TP
-.B p
-Open the URI out of the clipboard.
+.BI [ \[char34]x ]p
+Open the URI out of the register \fIx\fP or if not given from clipboard.
.TP
-.B P
-Open the URI out of the clipboard into new window.
+.BI [ \[char34]x ]P
+Open the URI out of the register \fIx\fP or if not given from clipboard into
+new window.
.TP
.BI [ N ]CTRL\-O
Go back \fIN\fP steps in the browser history.
Reset Zoom.
.SS Yank
.TP
-.B y
-Yank the URI or current page into clipboard.
+.BI [ \[char34]x ]y
+Yank the URI or current page into register \fIx\fP and clipboard.
.TP
-.B Y
-Yank the current selection into clipboard.
+.BI [ \[char34]x ]Y
+Yank the current selection into register \fIx\fP and clipboard.
.SH COMMAND MODE
.SS Command Line Editing
.TP
.TP
.B CTRL\-V
Pass the next key press directly to gtk.
+.TP
+.B CTRL\-R {0-9a-z}
+Insert the content of given buffer at cursor position.
.SS Command Line History
.TP
.B <Tab>
return true;
}
-gboolean command_yank(const Arg *arg)
+gboolean command_yank(const Arg *arg, char buf)
{
static char *tmpl = "Yanked: %s";
text = gtk_clipboard_wait_for_text(SECONDARY_CLIPBOARD());
}
if (text) {
+ /* put the text into the yank buffer */
+ vb_register_add(buf, text);
vb_echo(VB_MSG_NORMAL, false, tmpl, text);
g_free(text);
a.s = arg->s;
}
if (a.s) {
+ /* put the text into the yank buffer */
vb_set_clipboard(&a);
+ vb_register_add(buf, a.s);
vb_echo(VB_MSG_NORMAL, false, tmpl, a.s);
return true;
#endif
gboolean command_search(const Arg *arg);
-gboolean command_yank(const Arg *arg);
+gboolean command_yank(const Arg *arg, char buf);
gboolean command_save(const Arg *arg);
#ifdef FEATURE_QUEUE
gboolean command_queue(const Arg *arg);
#include "handlers.h"
#include "map.h"
#include "js.h"
+#include "normal.h"
typedef enum {
EX_BMA,
EX_TABOPEN,
} ExCode;
+typedef enum {
+ PHASE_START,
+ PHASE_CUTBUF,
+} Phase;
+
typedef struct {
int count; /* commands count */
int idx; /* index in commands array */
int flags;
} ExInfo;
+static struct {
+ char cutbuf; /* char for the cut buffer */
+ Phase phase; /* current parsing phase */
+} info = {'\0', PHASE_START};
+
static void input_activate(void);
static gboolean parse(const char **input, ExArg *arg);
static gboolean parse_count(const char **input, ExArg *arg);
GtkTextIter start, end;
GtkTextBuffer *buffer = vb.gui.buffer;
GtkTextMark *mark;
+ VbResult res;
+ const char *text;
/* delegate call to the submode */
if (RESULT_COMPLETE == hints_keypress(key)) {
return RESULT_COMPLETE;
}
- switch (key) {
- case KEY_TAB:
- complete(1);
- break;
+ /* process the custbuffer */
+ if (info.phase == PHASE_CUTBUF) {
+ info.cutbuf = (char)key;
+ info.phase = PHASE_CUTBUF;
- case KEY_SHIFT_TAB:
- complete(-1);
- break;
+ /* insert the cutbuffer text at cursor position */
+ text = vb_register_get((char)key);
+ if (text) {
+ gtk_text_buffer_insert_at_cursor(buffer, text, strlen(text));
+ }
- case CTRL('['):
- case CTRL('C'):
- mode_enter('n');
- vb_set_input_text("");
- break;
+ res = RESULT_COMPLETE;
+ } else {
+ res = RESULT_COMPLETE;
+ switch (key) {
+ case KEY_TAB:
+ complete(1);
+ break;
- case KEY_CR:
- input_activate();
- break;
+ case KEY_SHIFT_TAB:
+ complete(-1);
+ break;
- case KEY_UP:
- history(true);
- break;
+ case CTRL('['):
+ case CTRL('C'):
+ mode_enter('n');
+ vb_set_input_text("");
+ break;
- case KEY_DOWN:
- history(false);
- break;
+ case KEY_CR:
+ input_activate();
+ break;
- /* basic command line editing */
- case CTRL('H'):
- /* delete the last char before the cursor */
- mark = gtk_text_buffer_get_insert(buffer);
- gtk_text_buffer_get_iter_at_mark(buffer, &start, mark);
- gtk_text_buffer_backspace(buffer, &start, true, true);
- break;
+ case KEY_UP:
+ history(true);
+ break;
- case CTRL('W'):
- /* delete word backward from cursor */
- mark = gtk_text_buffer_get_insert(buffer);
- gtk_text_buffer_get_iter_at_mark(buffer, &end, mark);
+ case KEY_DOWN:
+ history(false);
+ break;
- /* copy the iter to build start and end point for deletion */
- start = end;
+ /* basic command line editing */
+ case CTRL('H'):
+ /* delete the last char before the cursor */
+ mark = gtk_text_buffer_get_insert(buffer);
+ gtk_text_buffer_get_iter_at_mark(buffer, &start, mark);
+ gtk_text_buffer_backspace(buffer, &start, true, true);
+ break;
- /* move the iterator to the beginning of previous word */
- if (gtk_text_iter_backward_word_start(&start)) {
- gtk_text_buffer_delete(buffer, &start, &end);
- }
- break;
+ case CTRL('W'):
+ /* delete word backward from cursor */
+ mark = gtk_text_buffer_get_insert(buffer);
+ gtk_text_buffer_get_iter_at_mark(buffer, &end, mark);
- case CTRL('B'):
- /* move the cursor direct behind the prompt */
- gtk_text_buffer_get_iter_at_offset(buffer, &start, strlen(vb.state.prompt));
- gtk_text_buffer_place_cursor(buffer, &start);
- break;
+ /* copy the iter to build start and end point for deletion */
+ start = end;
- case CTRL('E'):
- /* move the cursor to the end of line */
- gtk_text_buffer_get_end_iter(buffer, &start);
- gtk_text_buffer_place_cursor(buffer, &start);
- break;
+ /* move the iterator to the beginning of previous word */
+ if (gtk_text_iter_backward_word_start(&start)) {
+ gtk_text_buffer_delete(buffer, &start, &end);
+ }
+ break;
- case CTRL('U'):
- /* remove everythings between cursor and prompt */
- mark = gtk_text_buffer_get_insert(buffer);
- gtk_text_buffer_get_iter_at_mark(buffer, &end, mark);
- gtk_text_buffer_get_iter_at_offset(buffer, &start, strlen(vb.state.prompt));
- gtk_text_buffer_delete(buffer, &start, &end);
- break;
+ case CTRL('B'):
+ /* move the cursor direct behind the prompt */
+ gtk_text_buffer_get_iter_at_offset(buffer, &start, strlen(vb.state.prompt));
+ gtk_text_buffer_place_cursor(buffer, &start);
+ break;
- default:
- /* if is printable ascii char, than write it at the cursor
- * position into input box */
- if (key >= 0x20 && key <= 0x7e) {
- gtk_text_buffer_insert_at_cursor(buffer, (char[2]){key, 0}, 1);
- } else {
- vb.state.processed_key = false;
- }
+ case CTRL('E'):
+ /* move the cursor to the end of line */
+ gtk_text_buffer_get_end_iter(buffer, &start);
+ gtk_text_buffer_place_cursor(buffer, &start);
+ break;
+
+ case CTRL('U'):
+ /* remove everythings between cursor and prompt */
+ mark = gtk_text_buffer_get_insert(buffer);
+ gtk_text_buffer_get_iter_at_mark(buffer, &end, mark);
+ gtk_text_buffer_get_iter_at_offset(buffer, &start, strlen(vb.state.prompt));
+ gtk_text_buffer_delete(buffer, &start, &end);
+ break;
+
+ case CTRL('R'):
+ info.cutbuf = (char)key;
+ info.phase = PHASE_CUTBUF;
+ vb.mode->flags |= FLAG_NOMAP;
+ res = RESULT_MORE;
+ break;
+
+ default:
+ /* if is printable ascii char, than write it at the cursor
+ * position into input box */
+ if (key >= 0x20 && key <= 0x7e) {
+ gtk_text_buffer_insert_at_cursor(buffer, (char[2]){key, 0}, 1);
+ } else {
+ vb.state.processed_key = false;
+ }
+ }
+ }
+
+ if (res == RESULT_COMPLETE) {
+ info.cutbuf = 0;
+ info.phase = PHASE_START;
+ } else {
+ /* if the key sequence is not complete show the already typed keys in
+ * status bar */
+ normal_showcmd(key);
}
- return RESULT_COMPLETE;
+ return res;
}
/**
case 'Y':
a.i = COMMAND_YANK_ARG;
a.s = v;
- command_yank(&a);
+ command_yank(&a, '\0');
break;
#ifdef FEATURE_QUEUE
static void init_files(void);
static void session_init(void);
static void session_cleanup(void);
+static void register_init(void);
+static void register_cleanup(void);
static gboolean hide_message();
static void set_status(const StatusType status);
static void input_print(gboolean force, const MessageType type, gboolean hide, const char *message);
setting_cleanup();
history_cleanup();
session_cleanup();
+ register_cleanup();
for (int i = 0; i < FILES_LAST; i++) {
g_free(vb.files[i]);
init_files();
session_init();
setting_init();
+ register_init();
read_config();
/* initially apply input style */
#endif
}
+static void register_init(void)
+{
+ memset(vb.state.reg, 0, sizeof(char*));
+}
+
+void vb_register_add(char buf, const char *value)
+{
+ char *mark;
+ int idx;
+
+ /* make sure the mark is a valid mark char */
+ if ((mark = strchr(VB_REG_CHARS, buf))) {
+ /* get the index of the mark char */
+ idx = mark - VB_REG_CHARS;
+
+ OVERWRITE_STRING(vb.state.reg[idx], value);
+ }
+}
+
+const char *vb_register_get(char buf)
+{
+ char *mark;
+ int idx;
+
+ /* make sure the mark is a valid mark char */
+ if ((mark = strchr(VB_REG_CHARS, buf))) {
+ /* get the index of the mark char */
+ idx = mark - VB_REG_CHARS;
+
+ return vb.state.reg[idx];
+ }
+
+ return NULL;
+}
+
+static void register_cleanup(void)
+{
+ int i;
+ for (i = 0; i < VB_REG_SIZE; i++) {
+ if (vb.state.reg[i]) {
+ g_free(vb.state.reg[i]);
+ }
+ }
+}
+
static gboolean button_relase_cb(WebKitWebView *webview, GdkEventButton *event)
{
gboolean propagate = false;
#define VB_MARK_TICK 0
#define VB_MARK_SIZE (sizeof(VB_MARK_CHARS) - 1)
+#define VB_REG_CHARS "0123456789abcdefghijklmnopqrstuvwxyz"
+#define VB_REG_SIZE (sizeof(VB_REG_CHARS) - 1)
+
/* enums */
typedef enum {
RESULT_COMPLETE,
char prompt[PROMPT_SIZE]; /* current prompt ':', 'g;t', '/' including nul */
gdouble marks[VB_MARK_SIZE]; /* holds marks set to page with 'm{markchar}' */
char *linkhover; /* the uri of the curret hovered link */
+ GHashTable *buffer; /* holds the yank buffer */
+ char *reg[VB_REG_SIZE]; /* holds the yank buffer */
} State;
typedef struct {
void vb_update_status_style(void);
void vb_update_input_style(void);
void vb_update_urlbar(const char *uri);
+void vb_register_add(char buf, const char *value);
+const char *vb_register_get(char buf);
gboolean vb_download(WebKitWebView *view, WebKitDownload *download, const char *path);
void vb_quit(void);
PHASE_KEY2,
PHASE_KEY3,
PHASE_COMPLETE,
+ PHASE_CUTBUF,
} Phase;
-struct NormalCmdInfo_s {
+typedef struct NormalCmdInfo_s {
int count; /* count used for the command */
char key; /* command key */
char key2; /* second command key (optional) */
char key3; /* third command key only for hinting */
+ char cutbuf; /* char for the cut buffer */
Phase phase; /* current parsing phase */
-} info = {0, '\0', '\0', PHASE_START};
+} NormalCmdInfo;
+
+static NormalCmdInfo info = {0, '\0', '\0', PHASE_START};
typedef VbResult (*NormalCommand)(const NormalCmdInfo *info);
info.phase = PHASE_KEY2;
info.key = key;
vb.mode->flags |= FLAG_NOMAP;
+ } else if ((char)key == '"') {
+ info.phase = PHASE_CUTBUF;
+ vb.mode->flags |= FLAG_NOMAP;
+ } else if (info.phase == PHASE_CUTBUF) {
+ info.cutbuf = (char)key;
+ info.phase = PHASE_START;
} else {
info.key = key;
info.phase = PHASE_COMPLETE;
if (res == RESULT_COMPLETE) {
/* unset the info */
- info.key = info.key2 = info.key3 = info.count = 0;
+ info.key = info.key2 = info.key3 = info.count = info.cutbuf = 0;
info.phase = PHASE_START;
} else if (res == RESULT_MORE) {
normal_showcmd(key);
{
Arg a = {info->key == 'P' ? VB_TARGET_NEW : VB_TARGET_CURRENT};
- a.s = gtk_clipboard_wait_for_text(PRIMARY_CLIPBOARD());
- if (!a.s) {
- a.s = gtk_clipboard_wait_for_text(SECONDARY_CLIPBOARD());
+ /* if cutbuffer is not the default - read out of the internal cutbuffer */
+ if (info->cutbuf) {
+ a.s = g_strdup(vb_register_get(info->cutbuf));
+ } else {
+ /* if no cutbuffer is given use the system clipboard */
+ a.s = gtk_clipboard_wait_for_text(PRIMARY_CLIPBOARD());
+ if (!a.s) {
+ a.s = gtk_clipboard_wait_for_text(SECONDARY_CLIPBOARD());
+ }
}
if (a.s) {
{
Arg a = {info->key == 'Y' ? COMMAND_YANK_SELECTION : COMMAND_YANK_URI};
- return command_yank(&a) ? RESULT_COMPLETE : RESULT_ERROR;
+ return command_yank(&a, info->cutbuf) ? RESULT_COMPLETE : RESULT_ERROR;
}
static VbResult normal_zoom(const NormalCmdInfo *info)
#include "config.h"
#include "main.h"
-typedef struct NormalCmdInfo_s NormalCmdInfo;
-
void normal_enter(void);
void normal_leave(void);
VbResult normal_keypress(int key);