Esempio n. 1
0
size_t input_enqueue(String keys)
{
  char *ptr = keys.data;
  char *end = ptr + keys.size;

  while (rbuffer_space(input_buffer) >= 6 && ptr < end) {
    uint8_t buf[6] = { 0 };
    unsigned int new_size
        = trans_special((const uint8_t **)&ptr, (size_t)(end - ptr), buf, true,
                        true);

    if (new_size) {
      new_size = handle_mouse_event(&ptr, buf, new_size);
      rbuffer_write(input_buffer, (char *)buf, new_size);
      continue;
    }

    if (*ptr == '<') {
      char *old_ptr = ptr;
      // Invalid or incomplete key sequence, skip until the next '>' or *end.
      do {
        ptr++;
      } while (ptr < end && *ptr != '>');
      if (*ptr != '>') {
        // Incomplete key sequence, return without consuming.
        ptr = old_ptr;
        break;
      }
      ptr++;
      continue;
    }

    // copy the character, escaping CSI and K_SPECIAL
    if ((uint8_t)*ptr == CSI) {
      rbuffer_write(input_buffer, (char *)&(uint8_t){K_SPECIAL}, 1);
      rbuffer_write(input_buffer, (char *)&(uint8_t){KS_EXTRA}, 1);
      rbuffer_write(input_buffer, (char *)&(uint8_t){KE_CSI}, 1);
    } else if ((uint8_t)*ptr == K_SPECIAL) {
      rbuffer_write(input_buffer, (char *)&(uint8_t){K_SPECIAL}, 1);
      rbuffer_write(input_buffer, (char *)&(uint8_t){KS_SPECIAL}, 1);
      rbuffer_write(input_buffer, (char *)&(uint8_t){KE_FILLER}, 1);
    } else {
      rbuffer_write(input_buffer, ptr, 1);
    }
    ptr++;
  }

  size_t rv = (size_t)(ptr - keys.data);
  process_interrupts();
  return rv;
}
Esempio n. 2
0
static int replace_termcodes(char **to, char *from)
{
  int len = strlen(from);
  char buf[len];
  int i = 0;
  while (*from) {
    buf[i] = trans_special(&from);
    i++;
    from++;
  }
  *to = malloc((i)*sizeof(char*));
  strncpy(*to, buf, i);
  return i;
}
Esempio n. 3
0
// Replace any terminal code strings in from[] with the equivalent internal
// vim representation.	This is used for the "from" and "to" part of a
// mapping, and the "to" part of a menu command.
// Any strings like "<C-UP>" are also replaced, unless 'cpoptions' contains
// '<'.
// K_SPECIAL by itself is replaced by K_SPECIAL KS_SPECIAL KE_FILLER.
//
// The replacement is done in result[] and finally copied into allocated
// memory. If this all works well *bufp is set to the allocated memory and a
// pointer to it is returned. If something fails *bufp is set to NULL and from
// is returned.
//
// CTRL-V characters are removed.  When "from_part" is TRUE, a trailing CTRL-V
// is included, otherwise it is removed (for ":map xx ^V", maps xx to
// nothing).  When 'cpoptions' does not contain 'B', a backslash can be used
// instead of a CTRL-V.
char_u * replace_termcodes (
    char_u *from,
    char_u **bufp,
    int from_part,
    int do_lt,                     // also translate <lt>
    int special                    // always accept <key> notation
)
{
  ssize_t i;
  size_t slen;
  char_u key;
  size_t dlen = 0;
  char_u      *src;
  int do_backslash;             // backslash is a special character
  int do_special;               // recognize <> key codes
  char_u      *result;          // buffer for resulting string

  do_backslash = (vim_strchr(p_cpo, CPO_BSLASH) == NULL);
  do_special = (vim_strchr(p_cpo, CPO_SPECI) == NULL) || special;

  // Allocate space for the translation.  Worst case a single character is
  // replaced by 6 bytes (shifted special key), plus a NUL at the end.
  result = xmalloc(STRLEN(from) * 6 + 1);

  src = from;

  // Check for #n at start only: function key n
  if (from_part && src[0] == '#' && VIM_ISDIGIT(src[1])) {  // function key
    result[dlen++] = K_SPECIAL;
    result[dlen++] = 'k';
    if (src[1] == '0') {
      result[dlen++] = ';';     // #0 is F10 is "k;"
    } else {
      result[dlen++] = src[1];  // #3 is F3 is "k3"
    }
    src += 2;
  }

  // Copy each byte from *from to result[dlen]
  while (*src != NUL) {
    // If 'cpoptions' does not contain '<', check for special key codes,
    // like "<C-S-LeftMouse>"
    if (do_special && (do_lt || STRNCMP(src, "<lt>", 4) != 0)) {
      // Replace <SID> by K_SNR <script-nr> _.
      // (room: 5 * 6 = 30 bytes; needed: 3 + <nr> + 1 <= 14)
      if (STRNICMP(src, "<SID>", 5) == 0) {
        if (current_SID <= 0) {
          EMSG(_(e_usingsid));
        } else {
          src += 5;
          result[dlen++] = K_SPECIAL;
          result[dlen++] = (int)KS_EXTRA;
          result[dlen++] = (int)KE_SNR;
          sprintf((char *)result + dlen, "%" PRId64, (int64_t)current_SID);
          dlen += STRLEN(result + dlen);
          result[dlen++] = '_';
          continue;
        }
      }

      slen = trans_special(&src, result + dlen, TRUE);
      if (slen) {
        dlen += slen;
        continue;
      }
    }

    if (do_special) {
      char_u  *p, *s, len;

      // Replace <Leader> by the value of "mapleader".
      // Replace <LocalLeader> by the value of "maplocalleader".
      // If "mapleader" or "maplocalleader" isn't set use a backslash.
      if (STRNICMP(src, "<Leader>", 8) == 0) {
        len = 8;
        p = get_var_value((char_u *)"g:mapleader");
      } else if (STRNICMP(src, "<LocalLeader>", 13) == 0)   {
        len = 13;
        p = get_var_value((char_u *)"g:maplocalleader");
      } else {
        len = 0;
        p = NULL;
      }

      if (len != 0) {
        // Allow up to 8 * 6 characters for "mapleader".
        if (p == NULL || *p == NUL || STRLEN(p) > 8 * 6) {
          s = (char_u *)"\\";
        } else {
          s = p;
        }
        while (*s != NUL) {
          result[dlen++] = *s++;
        }
        src += len;
        continue;
      }
    }

    // Remove CTRL-V and ignore the next character.
    // For "from" side the CTRL-V at the end is included, for the "to"
    // part it is removed.
    // If 'cpoptions' does not contain 'B', also accept a backslash.
    key = *src;
    if (key == Ctrl_V || (do_backslash && key == '\\')) {
      ++src;  // skip CTRL-V or backslash
      if (*src == NUL) {
        if (from_part) {
          result[dlen++] = key;
        }
        break;
      }
    }

    // skip multibyte char correctly
    for (i = (*mb_ptr2len)(src); i > 0; --i) {
      // If the character is K_SPECIAL, replace it with K_SPECIAL
      // KS_SPECIAL KE_FILLER.
      // If compiled with the GUI replace CSI with K_CSI.
      if (*src == K_SPECIAL) {
        result[dlen++] = K_SPECIAL;
        result[dlen++] = KS_SPECIAL;
        result[dlen++] = KE_FILLER;
      } else {
        result[dlen++] = *src;
      }
      ++src;
    }
  }
  result[dlen] = NUL;

  *bufp = xrealloc(result, dlen + 1);

  return *bufp;
}