| To: vim-dev@vim.org |
| Subject: Patch 7.2.201 |
| Fcc: outbox |
| From: Bram Moolenaar <Bram@moolenaar.net> |
| 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 |
| |
| |
| |
| |
| |
| *** 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 |
| |
| |
| |
| *** 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 |
| |
| |
| |
| |
| *** 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); |
| |
| |
| |
| |
| *** 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 |
| |
| |
| |
| *** 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; |
| } |
| |
| |
| |
| *** 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 /// |