summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAlexander Færøy <ahf@irssi.org>2010-02-27 14:57:16 +0000
committerahf <ahf@dbcabf3a-b0e7-0310-adc4-f8d773084564>2010-02-27 14:57:16 +0000
commit3eea03ccb81578fac0cb677d419c8176c5e30078 (patch)
tree3f828d29c49795dc2ff2ffae61e763548c938634 /src
parent59142d845df4551530561b8dfe78c3f468764679 (diff)
downloadirssi-3eea03ccb81578fac0cb677d419c8176c5e30078.zip
Irssi now detects a paste if it reads at least three bytes in a single read;
subsequent reads are associated to the same paste if they happen before 'paste_detect_time' time since the last read. If no read occurs after 'paste_detect_time' time the paste buffer is flushed; if there is at least one complete line its content is sent as a paste, otherwise it is processed normally. Thanks to Emanuele Giaquinta. git-svn-id: file:///var/www/svn.irssi.org/SVN/irssi/trunk@5121 dbcabf3a-b0e7-0310-adc4-f8d773084564
Diffstat (limited to 'src')
-rw-r--r--src/fe-text/gui-readline.c181
-rw-r--r--src/fe-text/term-curses.c6
-rw-r--r--src/fe-text/term-terminfo.c6
-rw-r--r--src/fe-text/term.h2
4 files changed, 66 insertions, 129 deletions
diff --git a/src/fe-text/gui-readline.c b/src/fe-text/gui-readline.c
index 298a15d6..476a798b 100644
--- a/src/fe-text/gui-readline.c
+++ b/src/fe-text/gui-readline.c
@@ -56,8 +56,7 @@ static int readtag;
static unichar prev_key;
static GTimeVal last_keypress;
-static int paste_detect_time, paste_detect_keycount, paste_verify_line_count;
-static int paste_state, paste_keycount;
+static int paste_detect_time, paste_verify_line_count;
static char *paste_entry;
static int paste_entry_pos;
static GArray *paste_buffer;
@@ -65,6 +64,7 @@ static GArray *paste_buffer;
static char *paste_old_prompt;
static int paste_prompt, paste_line_count;
static int paste_join_multiline;
+static int paste_timeout_id;
static void sig_input(void);
@@ -312,8 +312,11 @@ static void paste_send(void)
static void paste_flush(int send)
{
- gui_entry_set_text(active_entry, paste_entry);
- gui_entry_set_pos(active_entry, paste_entry_pos);
+ if (paste_prompt) {
+ gui_entry_set_text(active_entry, paste_entry);
+ gui_entry_set_pos(active_entry, paste_entry_pos);
+ g_free_and_null(paste_entry);
+ }
if (send)
paste_send();
@@ -325,7 +328,6 @@ static void paste_flush(int send)
paste_prompt = FALSE;
paste_line_count = 0;
- paste_state = 0;
gui_entry_redraw(active_entry);
}
@@ -345,113 +347,18 @@ static void insert_paste_prompt(void)
str = format_get_text(MODULE_NAME, active_win, NULL, NULL,
TXT_PASTE_PROMPT, 0, 0);
gui_entry_set_prompt(active_entry, str);
+ paste_entry = gui_entry_get_text(active_entry);
+ paste_entry_pos = gui_entry_get_pos(active_entry);
gui_entry_set_text(active_entry, "");
g_free(str);
}
-static gboolean paste_timeout(gpointer data)
-{
- GTimeVal now;
- int diff;
-
- if (paste_state == 0) {
- /* gone already */
- return FALSE;
- }
-
- g_get_current_time(&now);
- diff = (now.tv_sec - last_keypress.tv_sec) * 1000 +
- (now.tv_usec - last_keypress.tv_usec)/1000;
-
- if (diff < paste_detect_time) {
- /* still pasting */
- return TRUE;
- }
-
- if (paste_line_count < paste_verify_line_count ||
- active_win->active == NULL) {
- /* paste without asking */
- paste_flush(TRUE);
- } else if (!paste_prompt) {
- insert_paste_prompt();
- }
- return TRUE;
-}
-
-static int check_pasting(unichar key, int diff)
-{
- if (paste_state < 0)
- return FALSE;
-
- if (paste_state == 0) {
- /* two keys hit together quick. possibly pasting */
- if (diff > paste_detect_time)
- return FALSE;
-
- g_free(paste_entry);
- paste_entry = gui_entry_get_text(active_entry);
- paste_entry_pos = gui_entry_get_pos(active_entry);
-
- paste_state++;
- paste_line_count = 0;
- paste_keycount = 0;
- g_array_set_size(paste_buffer, 0);
- if (prev_key != '\r' && prev_key != '\n') {
- paste_keycount++;
- }
- } else if (paste_state > 0 && diff > paste_detect_time &&
- paste_line_count == 0) {
- /* reset paste state */
- paste_state = 0;
- return FALSE;
- }
-
- /* continuing quick hits */
- if (paste_prompt) {
- if (key == 11 || key == 3)
- paste_flush(key == 11);
- return TRUE;
- }
-
- g_array_append_val(paste_buffer, key);
- if ((key == '\r' || key == '\n') &&
- (prev_key != '\r' && prev_key != '\n')) {
- if (paste_state == 1) {
- if (paste_keycount < paste_detect_keycount) {
- /* not enough keypresses to determine if this is
- pasting or not. don't reset paste_keycount, but
- send this line as non-pasted */
- g_array_set_size(paste_buffer, 0);
- *paste_entry = '\0';
- return FALSE;
- }
-
- /* newline - assume this line was pasted */
- paste_state = 2;
- gui_entry_set_text(active_entry, paste_entry);
- gui_entry_set_pos(active_entry, paste_entry_pos);
- if (paste_verify_line_count > 0)
- g_timeout_add(100, paste_timeout, NULL);
- }
-
- if (paste_verify_line_count <= 0) {
- /* paste previous line */
- paste_send();
- g_array_set_size(paste_buffer, 0);
- } else {
- paste_line_count++;
- }
- }
-
- return paste_state == 2;
-}
-
static void sig_gui_key_pressed(gpointer keyp)
{
GTimeVal now;
unichar key;
char str[20];
- int ret, diff;
+ int ret;
key = GPOINTER_TO_INT(keyp);
@@ -461,14 +368,6 @@ static void sig_gui_key_pressed(gpointer keyp)
}
g_get_current_time(&now);
- diff = (now.tv_sec - last_keypress.tv_sec) * 1000 +
- (now.tv_usec - last_keypress.tv_usec)/1000;
-
- if (check_pasting(key, diff)) {
- last_keypress = now;
- prev_key = key;
- return;
- }
if (key < 32) {
/* control key */
@@ -519,7 +418,6 @@ static void sig_gui_key_pressed(gpointer keyp)
you're holding some key down */
if (ret != 0 && key != prev_key) {
last_keypress = now;
- paste_keycount++;
}
prev_key = key;
}
@@ -716,6 +614,26 @@ static void key_delete_to_next_space(void)
gui_entry_erase_next_word(active_entry, TRUE);
}
+static gboolean paste_timeout(gpointer data)
+{
+ if (paste_line_count == 0) {
+ int i;
+
+ for (i = 0; i < paste_buffer->len; i++) {
+ unichar key = g_array_index(paste_buffer, unichar, i);
+ signal_emit("gui key pressed", 1, GINT_TO_POINTER(key));
+ }
+ g_array_set_size(paste_buffer, 0);
+ } else if (paste_verify_line_count > 0 &&
+ paste_line_count >= paste_verify_line_count &&
+ active_win->active != NULL)
+ insert_paste_prompt();
+ else
+ paste_flush(TRUE);
+ paste_timeout_id = -1;
+ return FALSE;
+}
+
static void sig_input(void)
{
if (!active_entry) {
@@ -723,7 +641,32 @@ static void sig_input(void)
return;
}
- term_gets();
+ if (paste_prompt) {
+ GArray *buffer = g_array_new(FALSE, FALSE, sizeof(unichar));
+ int line_count = 0;
+ unichar key;
+ term_gets(buffer, &line_count);
+ key = g_array_index(buffer, unichar, 0);
+ if (key == 11 || key == 3)
+ paste_flush(key == 11);
+ g_array_free(buffer, TRUE);
+ } else {
+ term_gets(paste_buffer, &paste_line_count);
+ if (paste_detect_time > 0 && paste_buffer->len >= 3) {
+ if (paste_timeout_id != -1)
+ g_source_remove(paste_timeout_id);
+ paste_timeout_id = g_timeout_add(paste_detect_time, paste_timeout, NULL);
+ } else {
+ int i;
+
+ for (i = 0; i < paste_buffer->len; i++) {
+ unichar key = g_array_index(paste_buffer, unichar, i);
+ signal_emit("gui key pressed", 1, GINT_TO_POINTER(key));
+ }
+ g_array_set_size(paste_buffer, 0);
+ paste_line_count = 0;
+ }
+ }
}
time_t get_idle_time(void)
@@ -984,14 +927,6 @@ static void sig_gui_entry_redirect(SIGNAL_FUNC func, const char *entry,
static void setup_changed(void)
{
paste_detect_time = settings_get_time("paste_detect_time");
- if (paste_detect_time == 0)
- paste_state = -1;
- else if (paste_state == -1)
- paste_state = 0;
-
- paste_detect_keycount = settings_get_int("paste_detect_keycount");
- if (paste_detect_keycount < 2)
- paste_state = -1;
paste_verify_line_count = settings_get_int("paste_verify_line_count");
paste_join_multiline = settings_get_bool("paste_join_multiline");
@@ -1005,18 +940,16 @@ void gui_readline_init(void)
escape_next_key = FALSE;
redir = NULL;
- paste_state = 0;
- paste_keycount = 0;
paste_entry = NULL;
paste_entry_pos = 0;
paste_buffer = g_array_new(FALSE, FALSE, sizeof(unichar));
paste_old_prompt = NULL;
+ paste_timeout_id = -1;
g_get_current_time(&last_keypress);
input_listen_init(STDIN_FILENO);
settings_add_str("history", "scroll_page_count", "/2");
settings_add_time("misc", "paste_detect_time", "5msecs");
- settings_add_int("misc", "paste_detect_keycount", 5);
/* NOTE: function keys can generate at least 5 characters long
keycodes. this must be larger to allow them to work. */
settings_add_int("misc", "paste_verify_line_count", 5);
diff --git a/src/fe-text/term-curses.c b/src/fe-text/term-curses.c
index 749336b7..fc674fd3 100644
--- a/src/fe-text/term-curses.c
+++ b/src/fe-text/term-curses.c
@@ -381,7 +381,7 @@ void term_set_input_type(int type)
{
}
-void term_gets(void)
+void term_gets(GArray *buffer, int *line_count)
{
#ifdef WIDEC_CURSES
wint_t key;
@@ -401,6 +401,8 @@ void term_gets(void)
continue;
#endif
- signal_emit("gui key pressed", 1, GINT_TO_POINTER(key));
+ g_array_append_val(buffer, key);
+ if (key == '\r' || key == '\n')
+ (*line_count)++;
}
}
diff --git a/src/fe-text/term-terminfo.c b/src/fe-text/term-terminfo.c
index 8232bf19..9dfc0db4 100644
--- a/src/fe-text/term-terminfo.c
+++ b/src/fe-text/term-terminfo.c
@@ -575,7 +575,7 @@ void term_set_input_type(int type)
}
}
-void term_gets(void)
+void term_gets(GArray *buffer, int *line_count)
{
int ret, i, char_len;
@@ -600,7 +600,9 @@ void term_gets(void)
&key);
if (char_len < 0)
break;
- signal_emit("gui key pressed", 1, GINT_TO_POINTER(key));
+ g_array_append_val(buffer, key);
+ if (key == '\r' || key == '\n')
+ (*line_count)++;
i += char_len;
}
diff --git a/src/fe-text/term.h b/src/fe-text/term.h
index d0cc637f..27174c83 100644
--- a/src/fe-text/term.h
+++ b/src/fe-text/term.h
@@ -81,7 +81,7 @@ void term_stop(void);
/* keyboard input handling */
void term_set_input_type(int type);
-void term_gets(void);
+void term_gets(GArray *buffer, int *line_count);
/* internal */
void term_common_init(void);