# HG changeset patch # User vimboss # Date 1245158586 0 # Node ID 062104a823df0f5a225b327b00a3766e41e4610f # Parent 4c02214d1465ac2b014a9a1096927ad04eb710e8 updated for version 7.2-201 diff --git a/runtime/doc/options.txt b/runtime/doc/options.txt --- a/runtime/doc/options.txt +++ b/runtime/doc/options.txt @@ -1443,6 +1443,14 @@ A jump table for the options with a shor autoselectml Like "autoselect", but for the modeless selection only. Compare to the 'A' flag in 'guioptions'. + html When the clipboard contains HTML, use this when + pasting. When putting text on the clipboard, mark it + as HTML. This works to copy rendered HTML from + Firefox, paste it as raw HTML in Vim, select the HTML + in Vim and paste it in a rich edit box in Firefox. + Only supported for GTK version 2 and later. + Only available with the |+multi_byte| feature. + exclude:{pattern} Defines a pattern that is matched against the name of the terminal 'term'. If there is a match, no diff --git a/src/globals.h b/src/globals.h --- a/src/globals.h +++ b/src/globals.h @@ -509,6 +509,7 @@ EXTERN VimClipboard clip_plus; /* CLIPBO EXTERN int clip_unnamed INIT(= FALSE); EXTERN int clip_autoselect INIT(= FALSE); EXTERN int clip_autoselectml INIT(= FALSE); +EXTERN int clip_html INIT(= FALSE); EXTERN regprog_T *clip_exclude_prog INIT(= NULL); #endif diff --git a/src/gui_gtk_x11.c b/src/gui_gtk_x11.c --- a/src/gui_gtk_x11.c +++ b/src/gui_gtk_x11.c @@ -107,6 +107,7 @@ enum TARGET_UTF8_STRING, TARGET_STRING, TARGET_COMPOUND_TEXT, + TARGET_HTML, TARGET_TEXT, TARGET_TEXT_URI_LIST, TARGET_TEXT_PLAIN, @@ -123,6 +124,7 @@ static const GtkTargetEntry selection_ta {VIMENC_ATOM_NAME, 0, TARGET_VIMENC}, {VIM_ATOM_NAME, 0, TARGET_VIM}, #ifdef FEAT_MBYTE + {"text/html", 0, TARGET_HTML}, {"UTF8_STRING", 0, TARGET_UTF8_STRING}, #endif {"COMPOUND_TEXT", 0, TARGET_COMPOUND_TEXT}, @@ -140,6 +142,7 @@ static const GtkTargetEntry dnd_targets[ { {"text/uri-list", 0, TARGET_TEXT_URI_LIST}, # ifdef FEAT_MBYTE + {"text/html", 0, TARGET_HTML}, {"UTF8_STRING", 0, TARGET_UTF8_STRING}, # endif {"STRING", 0, TARGET_STRING}, @@ -178,6 +181,7 @@ static GdkAtom save_yourself_atom = GDK_ * Atoms used to control/reference X11 selections. */ #ifdef FEAT_MBYTE +static GdkAtom html_atom = GDK_NONE; static GdkAtom utf8_string_atom = GDK_NONE; #endif #ifndef HAVE_GTK2 @@ -1364,6 +1368,24 @@ selection_received_cb(GtkWidget *widget else text = tmpbuf_utf8; } + else if (len >= 2 && text[0] == 0xff && text[1] == 0xfe) + { + vimconv_T conv; + + /* UTF-16, we get this for HTML */ + conv.vc_type = CONV_NONE; + convert_setup_ext(&conv, (char_u *)"utf-16le", FALSE, p_enc, TRUE); + + if (conv.vc_type != CONV_NONE) + { + text += 2; + len -= 2; + tmpbuf = string_convert(&conv, text, &len); + convert_setup(&conv, NULL, NULL); + } + if (tmpbuf != NULL) + text = tmpbuf; + } } #else /* !HAVE_GTK2 */ # ifdef FEAT_MBYTE @@ -1451,6 +1473,7 @@ selection_get_cb(GtkWidget *widget U if (info != (guint)TARGET_STRING #ifdef FEAT_MBYTE + && (!clip_html || info != (guint)TARGET_HTML) && info != (guint)TARGET_UTF8_STRING && info != (guint)TARGET_VIMENC #endif @@ -1486,6 +1509,40 @@ selection_get_cb(GtkWidget *widget U } #ifdef FEAT_MBYTE + else if (info == (guint)TARGET_HTML) + { + vimconv_T conv; + + /* Since we get utf-16, we probably should set it as well. */ + conv.vc_type = CONV_NONE; + convert_setup_ext(&conv, p_enc, TRUE, (char_u *)"utf-16le", FALSE); + if (conv.vc_type != CONV_NONE) + { + tmpbuf = string_convert(&conv, string, &length); + convert_setup(&conv, NULL, NULL); + vim_free(string); + string = tmpbuf; + } + + /* Prepend the BOM: "fffe" */ + if (string != NULL) + { + tmpbuf = alloc(length + 2); + tmpbuf[0] = 0xff; + tmpbuf[1] = 0xfe; + mch_memmove(tmpbuf + 2, string, (size_t)length); + vim_free(string); + string = tmpbuf; + length += 2; + + selection_data->type = selection_data->target; + selection_data->format = 16; /* 16 bits per char */ + gtk_selection_data_set(selection_data, html_atom, 16, + string, length); + vim_free(string); + } + return; + } else if (info == (guint)TARGET_VIMENC) { int l = STRLEN(p_enc); @@ -3464,6 +3521,7 @@ gui_mch_init(void) /* Initialise atoms */ #ifdef FEAT_MBYTE + html_atom = gdk_atom_intern("text/html", FALSE); utf8_string_atom = gdk_atom_intern("UTF8_STRING", FALSE); #endif #ifndef HAVE_GTK2 @@ -6665,6 +6723,10 @@ clip_mch_request_selection(VimClipboard for (i = 0; i < N_SELECTION_TARGETS; ++i) { +#ifdef FEAT_MBYTE + if (!clip_html && selection_targets[i].info == TARGET_HTML) + continue; +#endif received_selection = RS_NONE; target = gdk_atom_intern(selection_targets[i].target, FALSE); diff --git a/src/mbyte.c b/src/mbyte.c --- a/src/mbyte.c +++ b/src/mbyte.c @@ -3265,7 +3265,7 @@ encname2codepage(name) # if defined(USE_ICONV) || defined(PROTO) -static char_u *iconv_string __ARGS((vimconv_T *vcp, char_u *str, int slen, int *unconvlenp)); +static char_u *iconv_string __ARGS((vimconv_T *vcp, char_u *str, int slen, int *unconvlenp, int *resultlenp)); /* * Call iconv_open() with a check if iconv() works properly (there are broken @@ -3326,13 +3326,15 @@ my_iconv_open(to, from) * If "unconvlenp" is not NULL handle the string ending in an incomplete * sequence and set "*unconvlenp" to the length of it. * Returns the converted string in allocated memory. NULL for an error. + * If resultlenp is not NULL, sets it to the result length in bytes. */ static char_u * -iconv_string(vcp, str, slen, unconvlenp) +iconv_string(vcp, str, slen, unconvlenp, resultlenp) vimconv_T *vcp; char_u *str; int slen; int *unconvlenp; + int *resultlenp; { const char *from; size_t fromlen; @@ -3418,6 +3420,9 @@ iconv_string(vcp, str, slen, unconvlenp) /* Not enough room or skipping illegal sequence. */ done = to - (char *)result; } + + if (resultlenp != NULL) + *resultlenp = (int)(to - (char *)result); return result; } @@ -5837,8 +5842,25 @@ convert_setup(vcp, from, to) char_u *from; char_u *to; { + return convert_setup_ext(vcp, from, TRUE, to, TRUE); +} + +/* + * As convert_setup(), but only when from_unicode_is_utf8 is TRUE will all + * "from" unicode charsets be considered utf-8. Same for "to". + */ + int +convert_setup_ext(vcp, from, from_unicode_is_utf8, to, to_unicode_is_utf8) + vimconv_T *vcp; + char_u *from; + int from_unicode_is_utf8; + char_u *to; + int to_unicode_is_utf8; +{ int from_prop; int to_prop; + int from_is_utf8; + int to_is_utf8; /* Reset to no conversion. */ # ifdef USE_ICONV @@ -5856,37 +5878,46 @@ convert_setup(vcp, from, to) from_prop = enc_canon_props(from); to_prop = enc_canon_props(to); - if ((from_prop & ENC_LATIN1) && (to_prop & ENC_UNICODE)) + if (from_unicode_is_utf8) + from_is_utf8 = from_prop & ENC_UNICODE; + else + from_is_utf8 = from_prop == ENC_UNICODE; + if (to_unicode_is_utf8) + to_is_utf8 = to_prop & ENC_UNICODE; + else + to_is_utf8 = to_prop == ENC_UNICODE; + + if ((from_prop & ENC_LATIN1) && to_is_utf8) { /* Internal latin1 -> utf-8 conversion. */ vcp->vc_type = CONV_TO_UTF8; vcp->vc_factor = 2; /* up to twice as long */ } - else if ((from_prop & ENC_LATIN9) && (to_prop & ENC_UNICODE)) + else if ((from_prop & ENC_LATIN9) && to_is_utf8) { /* Internal latin9 -> utf-8 conversion. */ vcp->vc_type = CONV_9_TO_UTF8; vcp->vc_factor = 3; /* up to three as long (euro sign) */ } - else if ((from_prop & ENC_UNICODE) && (to_prop & ENC_LATIN1)) + else if (from_is_utf8 && (to_prop & ENC_LATIN1)) { /* Internal utf-8 -> latin1 conversion. */ vcp->vc_type = CONV_TO_LATIN1; } - else if ((from_prop & ENC_UNICODE) && (to_prop & ENC_LATIN9)) + else if (from_is_utf8 && (to_prop & ENC_LATIN9)) { /* Internal utf-8 -> latin9 conversion. */ vcp->vc_type = CONV_TO_LATIN9; } #ifdef WIN3264 /* Win32-specific codepage <-> codepage conversion without iconv. */ - else if (((from_prop & ENC_UNICODE) || encname2codepage(from) > 0) - && ((to_prop & ENC_UNICODE) || encname2codepage(to) > 0)) + else if ((from_is_utf8 || encname2codepage(from) > 0) + && (to_is_utf8 || encname2codepage(to) > 0)) { vcp->vc_type = CONV_CODEPAGE; vcp->vc_factor = 2; /* up to twice as long */ - vcp->vc_cpfrom = (from_prop & ENC_UNICODE) ? 0 : encname2codepage(from); - vcp->vc_cpto = (to_prop & ENC_UNICODE) ? 0 : encname2codepage(to); + vcp->vc_cpfrom = from_is_utf8 ? 0 : encname2codepage(from); + vcp->vc_cpto = to_is_utf8 ? 0 : encname2codepage(to); } #endif #ifdef MACOS_X @@ -5894,7 +5925,7 @@ convert_setup(vcp, from, to) { vcp->vc_type = CONV_MAC_LATIN1; } - else if ((from_prop & ENC_MACROMAN) && (to_prop & ENC_UNICODE)) + else if ((from_prop & ENC_MACROMAN) && to_is_utf8) { vcp->vc_type = CONV_MAC_UTF8; vcp->vc_factor = 2; /* up to twice as long */ @@ -5903,7 +5934,7 @@ convert_setup(vcp, from, to) { vcp->vc_type = CONV_LATIN1_MAC; } - else if ((from_prop & ENC_UNICODE) && (to_prop & ENC_MACROMAN)) + else if (from_is_utf8 && (to_prop & ENC_MACROMAN)) { vcp->vc_type = CONV_UTF8_MAC; } @@ -5913,8 +5944,8 @@ convert_setup(vcp, from, to) { /* Use iconv() for conversion. */ vcp->vc_fd = (iconv_t)my_iconv_open( - (to_prop & ENC_UNICODE) ? (char_u *)"utf-8" : to, - (from_prop & ENC_UNICODE) ? (char_u *)"utf-8" : from); + to_is_utf8 ? (char_u *)"utf-8" : to, + from_is_utf8 ? (char_u *)"utf-8" : from); if (vcp->vc_fd != (iconv_t)-1) { vcp->vc_type = CONV_ICONV; @@ -6170,9 +6201,7 @@ string_convert_ext(vcp, ptr, lenp, uncon # ifdef USE_ICONV case CONV_ICONV: /* conversion with output_conv.vc_fd */ - retval = iconv_string(vcp, ptr, len, unconvlenp); - if (retval != NULL && lenp != NULL) - *lenp = (int)STRLEN(retval); + retval = iconv_string(vcp, ptr, len, unconvlenp, lenp); break; # endif # ifdef WIN3264 diff --git a/src/option.c b/src/option.c --- a/src/option.c +++ b/src/option.c @@ -7024,6 +7024,7 @@ check_clipboard_option() int new_unnamed = FALSE; int new_autoselect = FALSE; int new_autoselectml = FALSE; + int new_html = FALSE; regprog_T *new_exclude_prog = NULL; char_u *errmsg = NULL; char_u *p; @@ -7047,6 +7048,11 @@ check_clipboard_option() new_autoselectml = TRUE; p += 12; } + else if (STRNCMP(p, "html", 4) == 0 && (p[4] == ',' || p[4] == NUL)) + { + new_html = TRUE; + p += 4; + } else if (STRNCMP(p, "exclude:", 8) == 0 && new_exclude_prog == NULL) { p += 8; @@ -7068,6 +7074,7 @@ check_clipboard_option() clip_unnamed = new_unnamed; clip_autoselect = new_autoselect; clip_autoselectml = new_autoselectml; + clip_html = new_html; vim_free(clip_exclude_prog); clip_exclude_prog = new_exclude_prog; } diff --git a/src/version.c b/src/version.c --- a/src/version.c +++ b/src/version.c @@ -677,6 +677,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ /**/ + 201, +/**/ 200, /**/ 199,