Example #1
0
static void remote_ui_raw_line(UI *ui, Integer grid, Integer row,
                               Integer startcol, Integer endcol,
                               Integer clearcol, Integer clearattr,
                               const schar_T *chunk, const sattr_T *attrs)
{
  UIData *data = ui->data;
  if (ui->ui_ext[kUINewgrid]) {
    Array args = ARRAY_DICT_INIT;
    ADD(args, INTEGER_OBJ(grid));
    ADD(args, INTEGER_OBJ(row));
    ADD(args, INTEGER_OBJ(startcol));
    Array cells = ARRAY_DICT_INIT;
    int repeat = 0;
    size_t ncells = (size_t)(endcol-startcol);
    int last_hl = -1;
    for (size_t i = 0; i < ncells; i++) {
      repeat++;
      if (i == ncells-1 || attrs[i] != attrs[i+1]
          || STRCMP(chunk[i], chunk[i+1])) {
        Array cell = ARRAY_DICT_INIT;
        ADD(cell, STRING_OBJ(cstr_to_string((const char *)chunk[i])));
        if (attrs[i] != last_hl || repeat > 1) {
          ADD(cell, INTEGER_OBJ(attrs[i]));
          last_hl = attrs[i];
        }
        if (repeat > 1) {
          ADD(cell, INTEGER_OBJ(repeat));
        }
        ADD(cells, ARRAY_OBJ(cell));
        repeat = 0;
      }
    }
    if (endcol < clearcol) {
      Array cell = ARRAY_DICT_INIT;
      ADD(cell, STRING_OBJ(cstr_to_string(" ")));
      ADD(cell, INTEGER_OBJ(clearattr));
      ADD(cell, INTEGER_OBJ(clearcol-endcol));
      ADD(cells, ARRAY_OBJ(cell));
    }
    ADD(args, ARRAY_OBJ(cells));

    push_call(ui, "grid_line", args);
  } else {
    for (int i = 0; i < endcol-startcol; i++) {
      remote_ui_cursor_goto(ui, row, startcol+i);
      remote_ui_highlight_set(ui, attrs[i]);
      remote_ui_put(ui, (const char *)chunk[i]);
      if (utf_ambiguous_width(utf_ptr2char(chunk[i]))) {
        data->client_col = -1;  // force cursor update
      }
    }
    if (endcol < clearcol) {
      remote_ui_cursor_goto(ui, row, endcol);
      remote_ui_highlight_set(ui, (int)clearattr);
      // legacy eol_clear was only ever used with cleared attributes
      // so be on the safe side
      if (clearattr == 0 && clearcol == Columns) {
        Array args = ARRAY_DICT_INIT;
        push_call(ui, "eol_clear", args);
      } else {
        for (Integer c = endcol; c < clearcol; c++) {
          remote_ui_put(ui, " ");
        }
      }
    }
  }
}
Example #2
0
/// Convert the string "str[orglen]" to do ignore-case comparing.  Uses the
/// current locale.
///
/// When "buf" is NULL returns an allocated string (NULL for out-of-memory).
/// Otherwise puts the result in "buf[buflen]".
///
/// @param str
/// @param orglen
/// @param buf
/// @param buflen
///
/// @return converted string.
char_u* str_foldcase(char_u *str, int orglen, char_u *buf, int buflen)
{
  garray_T ga;
  int i;
  int len = orglen;

#define GA_CHAR(i) ((char_u *)ga.ga_data)[i]
#define GA_PTR(i) ((char_u *)ga.ga_data + i)
#define STR_CHAR(i) (buf == NULL ? GA_CHAR(i) : buf[i])
#define STR_PTR(i) (buf == NULL ? GA_PTR(i) : buf + i)

  // Copy "str" into "buf" or allocated memory, unmodified.
  if (buf == NULL) {
    ga_init(&ga, 1, 10);

    ga_grow(&ga, len + 1);
    memmove(ga.ga_data, str, (size_t)len);
    ga.ga_len = len;
  } else {
    if (len >= buflen) {
      // Ugly!
      len = buflen - 1;
    }
    memmove(buf, str, (size_t)len);
  }

  if (buf == NULL) {
    GA_CHAR(len) = NUL;
  } else {
    buf[len] = NUL;
  }

  // Make each character lower case.
  i = 0;
  while (STR_CHAR(i) != NUL) {
    if (enc_utf8 || (has_mbyte && (MB_BYTE2LEN(STR_CHAR(i)) > 1))) {
      if (enc_utf8) {
        int c = utf_ptr2char(STR_PTR(i));
        int olen = utf_ptr2len(STR_PTR(i));
        int lc = utf_tolower(c);

        // Only replace the character when it is not an invalid
        // sequence (ASCII character or more than one byte) and
        // utf_tolower() doesn't return the original character.
        if (((c < 0x80) || (olen > 1)) && (c != lc)) {
          int nlen = utf_char2len(lc);

          // If the byte length changes need to shift the following
          // characters forward or backward.
          if (olen != nlen) {
            if (nlen > olen) {
              if (buf == NULL) {
                ga_grow(&ga, nlen - olen + 1);
              } else {
                if (len + nlen - olen >= buflen) {
                  // out of memory, keep old char
                  lc = c;
                  nlen = olen;
                }
              }
            }

            if (olen != nlen) {
              if (buf == NULL) {
                STRMOVE(GA_PTR(i) + nlen, GA_PTR(i) + olen);
                ga.ga_len += nlen - olen;
              } else {
                STRMOVE(buf + i + nlen, buf + i + olen);
                len += nlen - olen;
              }
            }
          }
          (void)utf_char2bytes(lc, STR_PTR(i));
        }
      }

      // skip to next multi-byte char
      i += (*mb_ptr2len)(STR_PTR(i));
    } else {
      if (buf == NULL) {
        GA_CHAR(i) = TOLOWER_LOC(GA_CHAR(i));
      } else {
        buf[i] = TOLOWER_LOC(buf[i]);
      }
      ++i;
    }
  }

  if (buf == NULL) {
    return (char_u *)ga.ga_data;
  }
  return buf;
}
Example #3
0
    static void
write_string(garray_T *gap, char_u *str)
{
    char_u	*res = str;
    char_u	numbuf[NUMBUFLEN];

    if (res == NULL)
	ga_concat(gap, (char_u *)"null");
    else
    {
#if defined(FEAT_MBYTE) && defined(USE_ICONV)
	vimconv_T   conv;
	char_u	    *converted = NULL;

	if (!enc_utf8)
	{
	    /* Convert the text from 'encoding' to utf-8, the JSON string is
	     * always utf-8. */
	    conv.vc_type = CONV_NONE;
	    convert_setup(&conv, p_enc, (char_u*)"utf-8");
	    if (conv.vc_type != CONV_NONE)
		converted = res = string_convert(&conv, res, NULL);
	    convert_setup(&conv, NULL, NULL);
	}
#endif
	ga_append(gap, '"');
	while (*res != NUL)
	{
	    int c;
#ifdef FEAT_MBYTE
	    /* always use utf-8 encoding, ignore 'encoding' */
	    c = utf_ptr2char(res);
#else
	    c = *res;
#endif

	    switch (c)
	    {
		case 0x08:
		    ga_append(gap, '\\'); ga_append(gap, 'b'); break;
		case 0x09:
		    ga_append(gap, '\\'); ga_append(gap, 't'); break;
		case 0x0a:
		    ga_append(gap, '\\'); ga_append(gap, 'n'); break;
		case 0x0c:
		    ga_append(gap, '\\'); ga_append(gap, 'f'); break;
		case 0x0d:
		    ga_append(gap, '\\'); ga_append(gap, 'r'); break;
		case 0x22: /* " */
		case 0x5c: /* \ */
		    ga_append(gap, '\\');
		    ga_append(gap, c);
		    break;
		default:
		    if (c >= 0x20)
		    {
#ifdef FEAT_MBYTE
			numbuf[utf_char2bytes(c, numbuf)] = NUL;
#else
			numbuf[0] = c;
			numbuf[1] = NUL;
#endif
			ga_concat(gap, numbuf);
		    }
		    else
		    {
			vim_snprintf((char *)numbuf, NUMBUFLEN,
							 "\\u%04lx", (long)c);
			ga_concat(gap, numbuf);
		    }
	    }
#ifdef FEAT_MBYTE
	    res += utf_ptr2len(res);
#else
	    ++res;
#endif
	}
	ga_append(gap, '"');
#if defined(FEAT_MBYTE) && defined(USE_ICONV)
	vim_free(converted);
#endif
    }
}
Example #4
0
/*
 * Convert the string "str[orglen]" to do ignore-case comparing.  Uses the
 * current locale.
 * When "buf" is NULL returns an allocated string (NULL for out-of-memory).
 * Otherwise puts the result in "buf[buflen]".
 */
    char_u *
str_foldcase(
    char_u	*str,
    int		orglen,
    char_u	*buf,
    int		buflen)
{
    garray_T	ga;
    int		i;
    int		len = orglen;

#define GA_CHAR(i)  ((char_u *)ga.ga_data)[i]
#define GA_PTR(i)   ((char_u *)ga.ga_data + i)
#define STR_CHAR(i)  (buf == NULL ? GA_CHAR(i) : buf[i])
#define STR_PTR(i)   (buf == NULL ? GA_PTR(i) : buf + i)

    /* Copy "str" into "buf" or allocated memory, unmodified. */
    if (buf == NULL)
    {
	ga_init2(&ga, 1, 10);
	if (ga_grow(&ga, len + 1) == FAIL)
	    return NULL;
	mch_memmove(ga.ga_data, str, (size_t)len);
	ga.ga_len = len;
    }
    else
    {
	if (len >= buflen)	    /* Ugly! */
	    len = buflen - 1;
	mch_memmove(buf, str, (size_t)len);
    }
    if (buf == NULL)
	GA_CHAR(len) = NUL;
    else
	buf[len] = NUL;

    /* Make each character lower case. */
    i = 0;
    while (STR_CHAR(i) != NUL)
    {
#ifdef FEAT_MBYTE
	if (enc_utf8 || (has_mbyte && MB_BYTE2LEN(STR_CHAR(i)) > 1))
	{
	    if (enc_utf8)
	    {
		int	c = utf_ptr2char(STR_PTR(i));
		int	olen = utf_ptr2len(STR_PTR(i));
		int	lc = utf_tolower(c);

		/* Only replace the character when it is not an invalid
		 * sequence (ASCII character or more than one byte) and
		 * utf_tolower() doesn't return the original character. */
		if ((c < 0x80 || olen > 1) && c != lc)
		{
		    int	    nlen = utf_char2len(lc);

		    /* If the byte length changes need to shift the following
		     * characters forward or backward. */
		    if (olen != nlen)
		    {
			if (nlen > olen)
			{
			    if (buf == NULL
				    ? ga_grow(&ga, nlen - olen + 1) == FAIL
				    : len + nlen - olen >= buflen)
			    {
				/* out of memory, keep old char */
				lc = c;
				nlen = olen;
			    }
			}
			if (olen != nlen)
			{
			    if (buf == NULL)
			    {
				STRMOVE(GA_PTR(i) + nlen, GA_PTR(i) + olen);
				ga.ga_len += nlen - olen;
			    }
			    else
			    {
				STRMOVE(buf + i + nlen, buf + i + olen);
				len += nlen - olen;
			    }
			}
		    }
		    (void)utf_char2bytes(lc, STR_PTR(i));
		}
	    }
	    /* skip to next multi-byte char */
	    i += (*mb_ptr2len)(STR_PTR(i));
	}
	else
#endif
	{
	    if (buf == NULL)
		GA_CHAR(i) = TOLOWER_LOC(GA_CHAR(i));
	    else
		buf[i] = TOLOWER_LOC(buf[i]);
	    ++i;
	}
    }

    if (buf == NULL)
	return (char_u *)ga.ga_data;
    return buf;
}