To: vim-dev@vim.org Subject: Patch 7.2.201 Fcc: outbox From: Bram Moolenaar Mime-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ------------ Patch 7.2.201 Problem: Cannot copy/paste HTML to/from Firefox via the clipboard. Solution: Implement this for GTK. Add the "html" value to 'clipboard'. Files: runtime/doc/options.txt, src/globals.h, src/gui_gtk_x11.c, src/mbyte.c, src/proto/mbyte.pro, src/option.c *** ../vim-7.2.200/runtime/doc/options.txt 2009-02-21 20:27:00.000000000 +0100 --- runtime/doc/options.txt 2009-06-12 22:25:22.000000000 +0200 *************** *** 1443,1448 **** --- 1444,1457 ---- 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 *** ../vim-7.2.200/src/globals.h 2009-06-16 15:12:11.000000000 +0200 --- src/globals.h 2009-06-12 21:10:30.000000000 +0200 *************** *** 509,514 **** --- 509,515 ---- 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 *** ../vim-7.2.200/src/gui_gtk_x11.c 2009-06-16 15:12:11.000000000 +0200 --- src/gui_gtk_x11.c 2009-06-16 14:44:19.000000000 +0200 *************** *** 107,112 **** --- 107,113 ---- TARGET_UTF8_STRING, TARGET_STRING, TARGET_COMPOUND_TEXT, + TARGET_HTML, TARGET_TEXT, TARGET_TEXT_URI_LIST, TARGET_TEXT_PLAIN, *************** *** 123,128 **** --- 124,130 ---- {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,145 **** --- 142,148 ---- { {"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,183 **** --- 181,187 ---- * 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,1369 **** --- 1368,1391 ---- 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,1456 **** --- 1473,1479 ---- 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,1491 **** --- 1509,1548 ---- } #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,3469 **** --- 3521,3527 ---- /* 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,6670 **** --- 6723,6732 ---- 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); *** ../vim-7.2.200/src/mbyte.c 2009-06-16 15:12:11.000000000 +0200 --- src/mbyte.c 2009-06-16 15:01:30.000000000 +0200 *************** *** 3265,3271 **** # if defined(USE_ICONV) || defined(PROTO) ! static char_u *iconv_string __ARGS((vimconv_T *vcp, char_u *str, int slen, int *unconvlenp)); /* * Call iconv_open() with a check if iconv() works properly (there are broken --- 3265,3271 ---- # if defined(USE_ICONV) || defined(PROTO) ! 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,3338 **** * 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. */ static char_u * ! iconv_string(vcp, str, slen, unconvlenp) vimconv_T *vcp; char_u *str; int slen; int *unconvlenp; { const char *from; size_t fromlen; --- 3326,3340 ---- * 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, resultlenp) vimconv_T *vcp; char_u *str; int slen; int *unconvlenp; + int *resultlenp; { const char *from; size_t fromlen; *************** *** 3418,3423 **** --- 3420,3428 ---- /* Not enough room or skipping illegal sequence. */ done = to - (char *)result; } + + if (resultlenp != NULL) + *resultlenp = (int)(to - (char *)result); return result; } *************** *** 5837,5844 **** --- 5842,5866 ---- 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,5892 **** from_prop = enc_canon_props(from); to_prop = enc_canon_props(to); ! if ((from_prop & ENC_LATIN1) && (to_prop & ENC_UNICODE)) { /* 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)) { /* 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)) { /* Internal utf-8 -> latin1 conversion. */ vcp->vc_type = CONV_TO_LATIN1; } ! else if ((from_prop & ENC_UNICODE) && (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)) { 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); } #endif #ifdef MACOS_X --- 5878,5923 ---- from_prop = enc_canon_props(from); to_prop = enc_canon_props(to); ! 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_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_is_utf8 && (to_prop & ENC_LATIN1)) { /* Internal utf-8 -> latin1 conversion. */ vcp->vc_type = CONV_TO_LATIN1; } ! 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_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_is_utf8 ? 0 : encname2codepage(from); ! vcp->vc_cpto = to_is_utf8 ? 0 : encname2codepage(to); } #endif #ifdef MACOS_X *************** *** 5894,5900 **** { vcp->vc_type = CONV_MAC_LATIN1; } ! else if ((from_prop & ENC_MACROMAN) && (to_prop & ENC_UNICODE)) { vcp->vc_type = CONV_MAC_UTF8; vcp->vc_factor = 2; /* up to twice as long */ --- 5925,5931 ---- { vcp->vc_type = CONV_MAC_LATIN1; } ! 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,5909 **** { vcp->vc_type = CONV_LATIN1_MAC; } ! else if ((from_prop & ENC_UNICODE) && (to_prop & ENC_MACROMAN)) { vcp->vc_type = CONV_UTF8_MAC; } --- 5934,5940 ---- { vcp->vc_type = CONV_LATIN1_MAC; } ! else if (from_is_utf8 && (to_prop & ENC_MACROMAN)) { vcp->vc_type = CONV_UTF8_MAC; } *************** *** 5913,5920 **** { /* 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); if (vcp->vc_fd != (iconv_t)-1) { vcp->vc_type = CONV_ICONV; --- 5944,5951 ---- { /* Use iconv() for conversion. */ vcp->vc_fd = (iconv_t)my_iconv_open( ! 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,6178 **** # 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); break; # endif # ifdef WIN3264 --- 6201,6207 ---- # ifdef USE_ICONV case CONV_ICONV: /* conversion with output_conv.vc_fd */ ! retval = iconv_string(vcp, ptr, len, unconvlenp, lenp); break; # endif # ifdef WIN3264 *** ../vim-7.2.200/src/option.c 2009-05-17 13:30:58.000000000 +0200 --- src/option.c 2009-06-12 21:09:51.000000000 +0200 *************** *** 7024,7029 **** --- 7024,7030 ---- 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,7052 **** --- 7048,7058 ---- 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,7073 **** --- 7074,7080 ---- 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; } *** ../vim-7.2.200/src/version.c 2009-06-16 15:12:11.000000000 +0200 --- src/version.c 2009-06-16 15:14:02.000000000 +0200 *************** *** 678,679 **** --- 678,681 ---- { /* Add new patch number below this line */ + /**/ + 201, /**/ -- How To Keep A Healthy Level Of Insanity: 13. Go to a poetry recital and ask why the poems don't rhyme. /// Bram Moolenaar -- Bram@Moolenaar.net -- http://www.Moolenaar.net \\\ /// sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\ \\\ download, build and distribute -- http://www.A-A-P.org /// \\\ help me help AIDS victims -- http://ICCF-Holland.org ///