static dbus_bool_t
ascii_isxdigit (char c)
{
  return (ascii_isdigit (c) ||
	  (c >= 'a' && c <= 'f') ||
	  (c >= 'A' && c <= 'F'));
}
Esempio n. 2
0
/// Add the digraphs in the argument to the digraph table.
/// format: {c1}{c2} char {c1}{c2} char ...
///
/// @param str
void putdigraph(char_u *str)
{
  char_u char1, char2;
  digr_T *dp;

  while (*str != NUL) {
    str = skipwhite(str);

    if (*str == NUL) {
      return;
    }
    char1 = *str++;
    char2 = *str++;

    if (char2 == 0) {
      EMSG(_(e_invarg));
      return;
    }

    if ((char1 == ESC) || (char2 == ESC)) {
      EMSG(_("E104: Escape not allowed in digraph"));
      return;
    }
    str = skipwhite(str);

    if (!ascii_isdigit(*str)) {
      EMSG(_(e_number_exp));
      return;
    }
    int n = getdigits_int(&str);

    // If the digraph already exists, replace the result.
    dp = (digr_T *)user_digraphs.ga_data;

    int i;
    for (i = 0; i < user_digraphs.ga_len; ++i) {
      if (((int)dp->char1 == char1) && ((int)dp->char2 == char2)) {
        dp->result = n;
        break;
      }
      ++dp;
    }

    // Add a new digraph to the table.
    if (i == user_digraphs.ga_len) {
      dp = GA_APPEND_VIA_PTR(digr_T, &user_digraphs);
      dp->char1 = char1;
      dp->char2 = char2;
      dp->result = n;
    }
  }
}
Esempio n. 3
0
int find_special_key(const char_u **srcp, const size_t src_len, int *const modp,
                     const bool keycode, const bool keep_x_key,
                     const bool in_string)
{
  const char_u *last_dash;
  const char_u *end_of_name;
  const char_u *src;
  const char_u *bp;
  const char_u *const end = *srcp + src_len - 1;
  int modifiers;
  int bit;
  int key;
  uvarnumber_T n;
  int l;

  if (src_len == 0) {
    return 0;
  }

  src = *srcp;
  if (src[0] != '<') {
    return 0;
  }

  // Find end of modifier list
  last_dash = src;
  for (bp = src + 1; bp <= end && (*bp == '-' || ascii_isident(*bp)); bp++) {
    if (*bp == '-') {
      last_dash = bp;
      if (bp + 1 <= end) {
        l = utfc_ptr2len_len(bp + 1, (int)(end - bp) + 1);
        // Anything accepted, like <C-?>.
        // <C-"> or <M-"> are not special in strings as " is
        // the string delimiter. With a backslash it works: <M-\">
        if (end - bp > l && !(in_string && bp[1] == '"') && bp[2] == '>') {
          bp += l;
        } else if (end - bp > 2 && in_string && bp[1] == '\\'
                   && bp[2] == '"' && bp[3] == '>') {
          bp += 2;
        }
      }
    }
    if (end - bp > 3 && bp[0] == 't' && bp[1] == '_') {
      bp += 3;  // skip t_xx, xx may be '-' or '>'
    } else if (end - bp > 4 && STRNICMP(bp, "char-", 5) == 0) {
      vim_str2nr(bp + 5, NULL, &l, STR2NR_ALL, NULL, NULL, 0);
      bp += l + 5;
      break;
    }
  }

  if (bp <= end && *bp == '>') {  // found matching '>'
    end_of_name = bp + 1;

    /* Which modifiers are given? */
    modifiers = 0x0;
    for (bp = src + 1; bp < last_dash; bp++) {
      if (*bp != '-') {
        bit = name_to_mod_mask(*bp);
        if (bit == 0x0) {
          break;                // Illegal modifier name
        }
        modifiers |= bit;
      }
    }

    // Legal modifier name.
    if (bp >= last_dash) {
      if (STRNICMP(last_dash + 1, "char-", 5) == 0
          && ascii_isdigit(last_dash[6])) {
        // <Char-123> or <Char-033> or <Char-0x33>
        vim_str2nr(last_dash + 6, NULL, NULL, STR2NR_ALL, NULL, &n, 0);
        key = (int)n;
      } else {
        int off = 1;

        // Modifier with single letter, or special key name.
        if (in_string && last_dash[1] == '\\' && last_dash[2] == '"') {
          off = 2;
        }
        l = mb_ptr2len(last_dash + 1);
        if (modifiers != 0 && last_dash[l + 1] == '>') {
          key = PTR2CHAR(last_dash + off);
        } else {
          key = get_special_key_code(last_dash + off);
          if (!keep_x_key) {
            key = handle_x_keys(key);
          }
        }
      }

      // get_special_key_code() may return NUL for invalid
      // special key name.
      if (key != NUL) {
        // Only use a modifier when there is no special key code that
        // includes the modifier.
        key = simplify_key(key, &modifiers);

        if (!keycode) {
          // don't want keycode, use single byte code
          if (key == K_BS) {
            key = BS;
          } else if (key == K_DEL || key == K_KDEL) {
            key = DEL;
          }
        }

        // Normal Key with modifier:
        // Try to make a single byte code (except for Alt/Meta modifiers).
        if (!IS_SPECIAL(key)) {
          key = extract_modifiers(key, &modifiers);
        }

        *modp = modifiers;
        *srcp = end_of_name;
        return key;
      }
    }
  }
  return 0;
}
Esempio n. 4
0
/// Helper for init_chartab
///
/// @param global false: only set buf->b_chartab[]
///
/// @return FAIL if 'iskeyword', 'isident', 'isfname' or 'isprint' option has
/// an error, OK otherwise.
int buf_init_chartab(buf_T *buf, int global)
{
  int c;
  int c2;
  int i;
  bool tilde;
  bool do_isalpha;

  if (global) {
    // Set the default size for printable characters:
    // From <Space> to '~' is 1 (printable), others are 2 (not printable).
    // This also inits all 'isident' and 'isfname' flags to false.
    c = 0;

    while (c < ' ') {
      g_chartab[c++] = (dy_flags & DY_UHEX) ? 4 : 2;
    }

    while (c <= '~') {
      g_chartab[c++] = 1 + CT_PRINT_CHAR;
    }

    if (p_altkeymap) {
      while (c < YE) {
        g_chartab[c++] = 1 + CT_PRINT_CHAR;
      }
    }

    while (c < 256) {
      if (c >= 0xa0) {
        // UTF-8: bytes 0xa0 - 0xff are printable (latin1)
        g_chartab[c++] = CT_PRINT_CHAR + 1;
      } else {
        // the rest is unprintable by default
        g_chartab[c++] = (dy_flags & DY_UHEX) ? 4 : 2;
      }
    }

    // Assume that every multi-byte char is a filename character.
    for (c = 1; c < 256; c++) {
      if (c >= 0xa0) {
        g_chartab[c] |= CT_FNAME_CHAR;
      }
    }
  }

  // Init word char flags all to false
  memset(buf->b_chartab, 0, (size_t)32);

  // In lisp mode the '-' character is included in keywords.
  if (buf->b_p_lisp) {
    SET_CHARTAB(buf, '-');
  }

  // Walk through the 'isident', 'iskeyword', 'isfname' and 'isprint'
  // options Each option is a list of characters, character numbers or
  // ranges, separated by commas, e.g.: "200-210,x,#-178,-"
  for (i = global ? 0 : 3; i <= 3; i++) {
    const char_u *p;
    if (i == 0) {
      // first round: 'isident'
      p = p_isi;
    } else if (i == 1) {
      // second round: 'isprint'
      p = p_isp;
    } else if (i == 2) {
      // third round: 'isfname'
      p = p_isf;
    } else {  // i == 3
      // fourth round: 'iskeyword'
      p = buf->b_p_isk;
    }

    while (*p) {
      tilde = false;
      do_isalpha = false;

      if ((*p == '^') && (p[1] != NUL)) {
        tilde = true;
        ++p;
      }

      if (ascii_isdigit(*p)) {
        c = getdigits_int((char_u **)&p);
      } else {
        c = mb_ptr2char_adv(&p);
      }
      c2 = -1;

      if ((*p == '-') && (p[1] != NUL)) {
        ++p;

        if (ascii_isdigit(*p)) {
          c2 = getdigits_int((char_u **)&p);
        } else {
          c2 = mb_ptr2char_adv(&p);
        }
      }

      if ((c <= 0)
          || (c >= 256)
          || ((c2 < c) && (c2 != -1))
          || (c2 >= 256)
          || !((*p == NUL) || (*p == ','))) {
        return FAIL;
      }

      if (c2 == -1) {  // not a range
        // A single '@' (not "@-@"):
        // Decide on letters being ID/printable/keyword chars with
        // standard function isalpha(). This takes care of locale for
        // single-byte characters).
        if (c == '@') {
          do_isalpha = true;
          c = 1;
          c2 = 255;
        } else {
          c2 = c;
        }
      }

      while (c <= c2) {
        // Use the MB_ functions here, because isalpha() doesn't
        // work properly when 'encoding' is "latin1" and the locale is
        // "C".
        if (!do_isalpha
            || mb_islower(c)
            || mb_isupper(c)
            || (p_altkeymap && (F_isalpha(c) || F_isdigit(c)))) {
          if (i == 0) {
            // (re)set ID flag
            if (tilde) {
              g_chartab[c] &= (uint8_t)~CT_ID_CHAR;
            } else {
              g_chartab[c] |= CT_ID_CHAR;
            }
          } else if (i == 1) {
            // (re)set printable
            // For double-byte we keep the cell width, so
            // that we can detect it from the first byte.
            if (((c < ' ')
                 || (c > '~')
                 || (p_altkeymap && (F_isalpha(c) || F_isdigit(c))))) {
              if (tilde) {
                g_chartab[c] = (uint8_t)((g_chartab[c] & ~CT_CELL_MASK)
                                         + ((dy_flags & DY_UHEX) ? 4 : 2));
                g_chartab[c] &= (uint8_t)~CT_PRINT_CHAR;
              } else {
                g_chartab[c] = (uint8_t)((g_chartab[c] & ~CT_CELL_MASK) + 1);
                g_chartab[c] |= CT_PRINT_CHAR;
              }
            }
          } else if (i == 2) {
            // (re)set fname flag
            if (tilde) {
              g_chartab[c] &= (uint8_t)~CT_FNAME_CHAR;
            } else {
              g_chartab[c] |= CT_FNAME_CHAR;
            }
          } else {  // i == 3
            // (re)set keyword flag
            if (tilde) {
              RESET_CHARTAB(buf, c);
            } else {
              SET_CHARTAB(buf, c);
            }
          }
        }
        ++c;
      }

      c = *p;
      p = skip_to_option_part(p);

      if ((c == ',') && (*p == NUL)) {
        // Trailing comma is not allowed.
        return FAIL;
      }
    }
  }
  chartab_initialized = true;
  return OK;
}
Esempio n. 5
0
/// Map Farsi keyboard when in fkmap mode.
int fkmap(int c)
{
  int tempc;
  static int revins;

  if (IS_SPECIAL(c)) {
    return c;
  }

  if (ascii_isdigit(c)
      || ((c == '.'
           || c == '+'
           || c == '-'
           || c == '^'
           || c == '%'
           || c == '#'
           || c == '=')
          && revins)) {
    if (!revins) {
      if (curwin->w_cursor.col) {
        if (!p_ri) {
          dec_cursor();
        }

        chg_c_toX_orX();
        chg_l_toXor_X();
        if (!p_ri) {
          inc_cursor();
        }
      }
    }

    arrow_used = TRUE;
    (void)stop_arrow();

    if (!curwin->w_p_rl && revins) {
      inc_cursor();
    }

    revins++;
    p_ri = 1;
  } else {
    if (revins) {
      arrow_used = TRUE;
      (void)stop_arrow();

      revins = 0;
      if (curwin->w_p_rl) {
        while ((F_isdigit(gchar_cursor())
                || (gchar_cursor() == F_PERIOD
                    || gchar_cursor() == F_PLUS
                    || gchar_cursor() == F_MINUS
                    || gchar_cursor() == F_MUL
                    || gchar_cursor() == F_DIVIDE
                    || gchar_cursor() == F_PERCENT
                    || gchar_cursor() == F_EQUALS))
                && gchar_cursor() != NUL) {
          curwin->w_cursor.col++;
        }
      } else {
        if (curwin->w_cursor.col) {
          while ((F_isdigit(gchar_cursor())
                 || (gchar_cursor() == F_PERIOD
                     || gchar_cursor() == F_PLUS
                     || gchar_cursor() == F_MINUS
                     || gchar_cursor() == F_MUL
                     || gchar_cursor() == F_DIVIDE
                     || gchar_cursor() == F_PERCENT
                     || gchar_cursor() == F_EQUALS))
                 && --curwin->w_cursor.col) {
          }
        }

        if (!F_isdigit(gchar_cursor())) {
          ++curwin->w_cursor.col;
        }
      }
    }
  }

  if (!revins) {
    if (curwin->w_p_rl) {
      p_ri = 0;
    }

    if (!curwin->w_p_rl) {
      p_ri = 1;
    }
  }

  if ((c < 0x100)
      && (isalpha(c)
          || (c == '&')
          || (c == '^')
          || (c == ';')
          || (c == '\'')
          || (c == ',')
          || (c == '[')
          || (c == ']')
          || (c == '{')
          || (c == '}'))) {
    chg_r_to_Xor_X_();
  }

  tempc = 0;
  switch (c) {
    case '`':
    case ' ':
    case '.':
    case '!':
    case '"':
    case '$':
    case '%':
    case '^':
    case '&':
    case '/':
    case '(':
    case ')':
    case '=':
    case '\\':
    case '?':
    case '+':
    case '-':
    case '_':
    case '*':
    case ':':
    case '#':
    case '~':
    case '@':
    case '<':
    case '>':
    case '{':
    case '}':
    case '|':
    case '0':
    case '1':
    case '2':
    case '3':
    case '4':
    case '5':
    case '6':
    case '7':
    case '8':
    case '9':
    case 'B':
    case 'E':
    case 'F':
    case 'H':
    case 'I':
    case 'K':
    case 'L':
    case 'M':
    case 'O':
    case 'P':
    case 'Q':
    case 'R':
    case 'T':
    case 'U':
    case 'W':
    case 'Y':
    case  NL:
    case  TAB:
      if (p_ri && (c == NL) && curwin->w_cursor.col) {
        // If the char before the cursor is _X_ or X_ do not change
        // the one under the cursor with X type.

        dec_cursor();
        if (F_isalpha(gchar_cursor())) {
          inc_cursor();
          return NL;
        }
        inc_cursor();
      }

      if (!p_ri) {
        if (!curwin->w_cursor.col) {
          switch (c) {
            case '0'  : return FARSI_0     ;
            case '1'  : return FARSI_1     ;
            case '2'  : return FARSI_2     ;
            case '3'  : return FARSI_3     ;
            case '4'  : return FARSI_4     ;
            case '5'  : return FARSI_5     ;
            case '6'  : return FARSI_6     ;
            case '7'  : return FARSI_7     ;
            case '8'  : return FARSI_8     ;
            case '9'  : return FARSI_9     ;
            case 'B'  : return F_PSP       ;
            case 'E'  : return JAZR_N      ;
            case 'F'  : return ALEF_D_H    ;
            case 'H'  : return ALEF_A      ;
            case 'I'  : return TASH        ;
            case 'K'  : return F_LQUOT     ;
            case 'L'  : return F_RQUOT     ;
            case 'M'  : return HAMZE       ;
            case 'O'  : return '['         ;
            case 'P'  : return ']'         ;
            case 'Q'  : return OO          ;
            case 'R'  : return MAD_N       ;
            case 'T'  : return OW          ;
            case 'U'  : return MAD         ;
            case 'W'  : return OW_OW       ;
            case 'Y'  : return JAZR        ;
            case '`'  : return F_PCN       ;
            case '!'  : return F_EXCL      ;
            case '@'  : return F_COMMA     ;
            case '#'  : return F_DIVIDE    ;
            case '$'  : return F_CURRENCY  ;
            case '%'  : return F_PERCENT   ;
            case '^'  : return F_MUL       ;
            case '&'  : return F_BCOMMA    ;
            case '*'  : return F_STAR      ;
            case '('  : return F_LPARENT   ;
            case ')'  : return F_RPARENT   ;
            case '-'  : return F_MINUS     ;
            case '_'  : return F_UNDERLINE ;
            case '='  : return F_EQUALS    ;
            case '+'  : return F_PLUS      ;
            case '\\' : return F_BSLASH    ;
            case '|'  : return F_PIPE      ;
            case ':'  : return F_DCOLON    ;
            case '"'  : return F_SEMICOLON ;
            case '.'  : return F_PERIOD    ;
            case '/'  : return F_SLASH     ;
            case '<'  : return F_LESS      ;
            case '>'  : return F_GREATER   ;
            case '?'  : return F_QUESTION  ;
            case ' '  : return F_BLANK     ;
          }
          break;
        }
      }

      if (!p_ri) {
        dec_cursor();
      }

      switch ((tempc = gchar_cursor())) {
        case _BE:
        case _PE:
        case _TE:
        case _SE:
        case _JIM:
        case _CHE:
        case _HE_J:
        case _XE:
        case _SIN:
        case _SHIN:
        case _SAD:
        case _ZAD:
        case _FE:
        case _GHAF:
        case _KAF:
        case _KAF_H:
        case _GAF:
        case _LAM:
        case _MIM:
        case _NOON:
        case _HE:
        case _HE_:
        case _TA:
        case _ZA:
          put_curr_and_l_to_X(toF_TyA((char_u)tempc));
          break;

        case _AYN:
        case _AYN_:
          if (!p_ri) {
            if (!curwin->w_cursor.col) {
              put_curr_and_l_to_X(AYN);
              break;
            }
          }

          if (p_ri) {
            inc_cursor();
          } else {
            dec_cursor();
          }

          if (F_is_TyB_TyC_TyD(SRC_EDT, AT_CURSOR)) {
            tempc = AYN_;
          } else {
            tempc = AYN;
          }

          if (p_ri) {
            dec_cursor();
          } else {
            inc_cursor();
          }

          put_curr_and_l_to_X((char_u)tempc);
          break;

        case _GHAYN:
        case _GHAYN_:

          if (!p_ri) {
            if (!curwin->w_cursor.col) {
              put_curr_and_l_to_X(GHAYN);
              break;
            }
          }

          if (p_ri) {
            inc_cursor();
          } else {
            dec_cursor();
          }

          if (F_is_TyB_TyC_TyD(SRC_EDT, AT_CURSOR)) {
            tempc = GHAYN_;
          } else {
            tempc = GHAYN;
          }

          if (p_ri) {
            dec_cursor();
          } else {
            inc_cursor();
          }

          put_curr_and_l_to_X((char_u)tempc);
          break;

        case _YE:
        case _IE:
        case _YEE:

          if (!p_ri) {
            if (!curwin->w_cursor.col) {
              put_curr_and_l_to_X(
                  (tempc == _YE ? YE : tempc == _IE ? IE : YEE));
              break;
            }
          }

          if (p_ri) {
            inc_cursor();
          } else {
            dec_cursor();
          }

          if (F_is_TyB_TyC_TyD(SRC_EDT, AT_CURSOR)) {
            tempc = (tempc == _YE ? YE_ : tempc == _IE ? IE_ : YEE_);
          } else {
            tempc = (tempc == _YE ? YE : tempc == _IE ? IE : YEE);
          }

          if (p_ri) {
            dec_cursor();
          } else {
            inc_cursor();
          }

          put_curr_and_l_to_X((char_u)tempc);
          break;
      }

      if (!p_ri) {
        inc_cursor();
      }

      tempc = 0;

      switch (c) {
        case '0'  : return FARSI_0     ;
        case '1'  : return FARSI_1     ;
        case '2'  : return FARSI_2     ;
        case '3'  : return FARSI_3     ;
        case '4'  : return FARSI_4     ;
        case '5'  : return FARSI_5     ;
        case '6'  : return FARSI_6     ;
        case '7'  : return FARSI_7     ;
        case '8'  : return FARSI_8     ;
        case '9'  : return FARSI_9     ;
        case 'B'  : return F_PSP       ;
        case 'E'  : return JAZR_N      ;
        case 'F'  : return ALEF_D_H    ;
        case 'H'  : return ALEF_A      ;
        case 'I'  : return TASH        ;
        case 'K'  : return F_LQUOT     ;
        case 'L'  : return F_RQUOT     ;
        case 'M'  : return HAMZE       ;
        case 'O'  : return '['         ;
        case 'P'  : return ']'         ;
        case 'Q'  : return OO          ;
        case 'R'  : return MAD_N       ;
        case 'T'  : return OW          ;
        case 'U'  : return MAD         ;
        case 'W'  : return OW_OW       ;
        case 'Y'  : return JAZR        ;
        case '`'  : return F_PCN       ;
        case '!'  : return F_EXCL      ;
        case '@'  : return F_COMMA     ;
        case '#'  : return F_DIVIDE    ;
        case '$'  : return F_CURRENCY  ;
        case '%'  : return F_PERCENT   ;
        case '^'  : return F_MUL       ;
        case '&'  : return F_BCOMMA    ;
        case '*'  : return F_STAR      ;
        case '('  : return F_LPARENT   ;
        case ')'  : return F_RPARENT   ;
        case '-'  : return F_MINUS     ;
        case '_'  : return F_UNDERLINE ;
        case '='  : return F_EQUALS    ;
        case '+'  : return F_PLUS      ;
        case '\\' : return F_BSLASH    ;
        case '|'  : return F_PIPE      ;
        case ':'  : return F_DCOLON    ;
        case '"'  : return F_SEMICOLON ;
        case '.'  : return F_PERIOD    ;
        case '/'  : return F_SLASH     ;
        case '<'  : return F_LESS      ;
        case '>'  : return F_GREATER   ;
        case '?'  : return F_QUESTION  ;
        case ' '  : return F_BLANK     ;
      }
      break;

    case 'a' : tempc = _SHIN ; break;
    case 'A' : tempc = WAW_H ; break;
    case 'b' : tempc = ZAL   ; break;
    case 'c' : tempc = ZE    ; break;
    case 'C' : tempc = JE    ; break;
    case 'd' : tempc = _YE   ; break;
    case 'D' : tempc = _YEE  ; break;
    case 'e' : tempc = _SE   ; break;
    case 'f' : tempc = _BE   ; break;
    case 'g' : tempc = _LAM  ; break;

    case 'G':
      if (!curwin->w_cursor.col && STRLEN(get_cursor_line_ptr())) {
        if (gchar_cursor() == _LAM) {
          chg_c_toX_orX();
        } else if (p_ri) {
          chg_c_to_X_or_X();
        }
      }

      if (!p_ri) {
        if (!curwin->w_cursor.col) {
          return ALEF_U_H;
        }
        dec_cursor();
      }

      if (gchar_cursor() == _LAM) {
        chg_c_toX_orX();
        chg_l_toXor_X();
        tempc = ALEF_U_H;
      } else if (F_is_TyB_TyC_TyD(SRC_EDT, AT_CURSOR)) {
        tempc = ALEF_U_H_;
        chg_l_toXor_X();
      } else {
        tempc = ALEF_U_H;
      }

      if (!p_ri) {
        inc_cursor();
      }

      return tempc;

    case 'h':
      if (!curwin->w_cursor.col && STRLEN(get_cursor_line_ptr())) {
        if (p_ri) {
          chg_c_to_X_or_X();
        }
      }

      if (!p_ri) {
        if (!curwin->w_cursor.col) {
          return ALEF;
        }
        dec_cursor();
      }

      if (gchar_cursor() == _LAM) {
        chg_l_toXor_X();
        del_char(FALSE);
        AppendCharToRedobuff(K_BS);

        if (!p_ri) {
          dec_cursor();
        }

        tempc = LA;
      } else {
        if (F_is_TyB_TyC_TyD(SRC_EDT, AT_CURSOR)) {
          tempc = ALEF_;
          chg_l_toXor_X();
        } else {
          tempc = ALEF;
        }
      }

      if (!p_ri) {
        inc_cursor();
      }

      return tempc;

    case 'i':
      if (!curwin->w_cursor.col && STRLEN(get_cursor_line_ptr())) {
        if (!p_ri && !F_is_TyE(tempc)) {
          chg_c_to_X_orX_();
        }

        if (p_ri) {
          chg_c_to_X_or_X();
        }
      }

      if (!p_ri && !curwin->w_cursor.col) {
        return _HE;
      }

      if (!p_ri) {
        dec_cursor();
      }

      if (F_is_TyB_TyC_TyD(SRC_EDT, AT_CURSOR)) {
        tempc = _HE_;
      } else {
        tempc = _HE;
      }

      if (!p_ri) {
        inc_cursor();
      }
      break;

    case 'j':
      tempc = _TE;
      break;

    case 'J':
      if (!curwin->w_cursor.col && STRLEN(get_cursor_line_ptr())) {
        if (p_ri) {
          chg_c_to_X_or_X();
        }
      }

      if (!p_ri) {
        if (!curwin->w_cursor.col) {
          return TEE;
        }
        dec_cursor();
      }

      if (F_is_TyB_TyC_TyD(SRC_EDT, AT_CURSOR)) {
        tempc = TEE_;
        chg_l_toXor_X();
      } else {
        tempc = TEE;
      }

      if (!p_ri) {
        inc_cursor();
      }

      return tempc;

    case 'k' : tempc = _NOON ; break;
    case 'l' : tempc = _MIM  ; break;
    case 'm' : tempc = _PE   ; break;
    case 'n' :
    case 'N' : tempc = DAL   ; break;
    case 'o' : tempc = _XE   ; break;
    case 'p' : tempc = _HE_J ; break;
    case 'q' : tempc = _ZAD  ; break;
    case 'r' : tempc = _GHAF ; break;
    case 's' : tempc = _SIN  ; break;
    case 'S' : tempc = _IE   ; break;
    case 't' : tempc = _FE   ; break;

    case 'u':
      if (!curwin->w_cursor.col && STRLEN(get_cursor_line_ptr())) {
        if (!p_ri && !F_is_TyE(tempc)) {
          chg_c_to_X_orX_();
        }

        if (p_ri) {
          chg_c_to_X_or_X();
        }
      }

      if (!p_ri && !curwin->w_cursor.col) {
        return _AYN;
      }

      if (!p_ri) {
        dec_cursor();
      }

      if (F_is_TyB_TyC_TyD(SRC_EDT, AT_CURSOR)) {
        tempc = _AYN_;
      } else {
        tempc = _AYN;
      }

      if (!p_ri) {
        inc_cursor();
      }
      break;

    case 'v' :
    case 'V' : tempc = RE   ; break;
    case 'w' : tempc = _SAD ; break;
    case 'x' :
    case 'X' : tempc = _TA  ; break;

    case 'y':
      if (!curwin->w_cursor.col && STRLEN(get_cursor_line_ptr())) {
        if (!p_ri && !F_is_TyE(tempc)) {
          chg_c_to_X_orX_();
        }

        if (p_ri) {
          chg_c_to_X_or_X();
        }
      }

      if (!p_ri && !curwin->w_cursor.col) {
        return _GHAYN;
      }

      if (!p_ri) {
        dec_cursor();
      }

      if (F_is_TyB_TyC_TyD(SRC_EDT, AT_CURSOR)) {
        tempc = _GHAYN_;
      } else {
        tempc = _GHAYN;
      }

      if (!p_ri) {
        inc_cursor();
      }

      break;

    case 'z'  : tempc = _ZA    ; break;
    case 'Z'  : tempc = _KAF_H ; break;
    case ';'  : tempc = _KAF   ; break;
    case '\'' : tempc = _GAF   ; break;
    case ','  : tempc = WAW    ; break;
    case '['  : tempc = _JIM   ; break;
    case ']'  : tempc = _CHE   ; break;
  }

  if ((F_isalpha(tempc) || F_isdigit(tempc))) {
    if (!curwin->w_cursor.col && STRLEN(get_cursor_line_ptr())) {
      if (!p_ri && !F_is_TyE(tempc)) {
        chg_c_to_X_orX_();
      }

      if (p_ri) {
        chg_c_to_X_or_X();
      }
    }

    if (curwin->w_cursor.col) {
      if (!p_ri) {
        dec_cursor();
      }

      if (F_is_TyE(tempc)) {
        chg_l_toXor_X();
      } else {
        chg_l_to_X_orX_();
      }

      if (!p_ri) {
        inc_cursor();
      }
    }
  }

  if (tempc) {
    return tempc;
  }
  return c;
}
Esempio n. 6
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] == '#' && ascii_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;
}
Esempio n. 7
0
/*
 * Try translating a <> name at (*srcp)[], return the key and modifiers.
 * srcp is advanced to after the <> name.
 * returns 0 if there is no match.
 */
int 
find_special_key (
    char_u **srcp,
    int *modp,
    int keycode,                 /* prefer key code, e.g. K_DEL instead of DEL */
    int keep_x_key              /* don't translate xHome to Home key */
)
{
  char_u      *last_dash;
  char_u      *end_of_name;
  char_u      *src;
  char_u      *bp;
  int modifiers;
  int bit;
  int key;
  unsigned long n;
  int l;

  src = *srcp;
  if (src[0] != '<')
    return 0;

  /* Find end of modifier list */
  last_dash = src;
  for (bp = src + 1; *bp == '-' || vim_isIDc(*bp); bp++) {
    if (*bp == '-') {
      last_dash = bp;
      if (bp[1] != NUL) {
        if (has_mbyte)
          l = mb_ptr2len(bp + 1);
        else
          l = 1;
        if (bp[l + 1] == '>')
          bp += l;              /* anything accepted, like <C-?> */
      }
    }
    if (bp[0] == 't' && bp[1] == '_' && bp[2] && bp[3])
      bp += 3;          /* skip t_xx, xx may be '-' or '>' */
    else if (STRNICMP(bp, "char-", 5) == 0) {
      vim_str2nr(bp + 5, NULL, &l, TRUE, TRUE, NULL, NULL);
      bp += l + 5;
      break;
    }
  }

  if (*bp == '>') {     /* found matching '>' */
    end_of_name = bp + 1;

    /* Which modifiers are given? */
    modifiers = 0x0;
    for (bp = src + 1; bp < last_dash; bp++) {
      if (*bp != '-') {
        bit = name_to_mod_mask(*bp);
        if (bit == 0x0)
          break;                /* Illegal modifier name */
        modifiers |= bit;
      }
    }

    /*
     * Legal modifier name.
     */
    if (bp >= last_dash) {
      if (STRNICMP(last_dash + 1, "char-", 5) == 0
          && ascii_isdigit(last_dash[6])) {
        /* <Char-123> or <Char-033> or <Char-0x33> */
        vim_str2nr(last_dash + 6, NULL, NULL, TRUE, TRUE, NULL, &n);
        key = (int)n;
      } else {
        /*
         * Modifier with single letter, or special key name.
         */
        if (has_mbyte)
          l = mb_ptr2len(last_dash + 1);
        else
          l = 1;
        if (modifiers != 0 && last_dash[l + 1] == '>')
          key = PTR2CHAR(last_dash + 1);
        else {
          key = get_special_key_code(last_dash + 1);
          if (!keep_x_key)
            key = handle_x_keys(key);
        }
      }

      /*
       * get_special_key_code() may return NUL for invalid
       * special key name.
       */
      if (key != NUL) {
        /*
         * Only use a modifier when there is no special key code that
         * includes the modifier.
         */
        key = simplify_key(key, &modifiers);

        if (!keycode) {
          /* don't want keycode, use single byte code */
          if (key == K_BS)
            key = BS;
          else if (key == K_DEL || key == K_KDEL)
            key = DEL;
        }

        // Normal Key with modifier:
        // Try to make a single byte code (except for Alt/Meta modifiers).
        if (!IS_SPECIAL(key)) {
          key = extract_modifiers(key, &modifiers);
        }

        *modp = modifiers;
        *srcp = end_of_name;
        return key;
      }
    }
  }
  return 0;
}
Esempio n. 8
0
/*
 * Work out what to complete when doing command line completion of menu names.
 */
char_u *set_context_in_menu_cmd(expand_T *xp, char_u *cmd, char_u *arg, int forceit)
{
    char_u      *after_dot;
    char_u      *p;
    char_u      *path_name = NULL;
    char_u      *name;
    int unmenu;
    vimmenu_T   *menu;
    int expand_menus;

    xp->xp_context = EXPAND_UNSUCCESSFUL;


    /* Check for priority numbers, enable and disable */
    for (p = arg; *p; ++p)
        if (!ascii_isdigit(*p) && *p != '.')
            break;

    if (!ascii_iswhite(*p)) {
        if (STRNCMP(arg, "enable", 6) == 0
                && (arg[6] == NUL ||  ascii_iswhite(arg[6])))
            p = arg + 6;
        else if (STRNCMP(arg, "disable", 7) == 0
                 && (arg[7] == NUL || ascii_iswhite(arg[7])))
            p = arg + 7;
        else
            p = arg;
    }

    while (*p != NUL && ascii_iswhite(*p))
        ++p;

    arg = after_dot = p;

    for (; *p && !ascii_iswhite(*p); ++p) {
        if ((*p == '\\' || *p == Ctrl_V) && p[1] != NUL)
            p++;
        else if (*p == '.')
            after_dot = p + 1;
    }

    // ":popup" only uses menues, not entries
    expand_menus = !((*cmd == 't' && cmd[1] == 'e') || *cmd == 'p');
    expand_emenu = (*cmd == 'e');
    if (expand_menus && ascii_iswhite(*p))
        return NULL;        /* TODO: check for next command? */
    if (*p == NUL) {              /* Complete the menu name */
        /*
         * With :unmenu, you only want to match menus for the appropriate mode.
         * With :menu though you might want to add a menu with the same name as
         * one in another mode, so match menus from other modes too.
         */
        expand_modes = get_menu_cmd_modes(cmd, forceit, NULL, &unmenu);
        if (!unmenu)
            expand_modes = MENU_ALL_MODES;

        menu = root_menu;
        if (after_dot > arg) {
            size_t path_len = (size_t) (after_dot - arg);
            path_name = xmalloc(path_len);
            STRLCPY(path_name, arg, path_len);
        }
        name = path_name;
        while (name != NULL && *name) {
            p = menu_name_skip(name);
            while (menu != NULL) {
                if (menu_name_equal(name, menu)) {
                    /* Found menu */
                    if ((*p != NUL && menu->children == NULL)
                            || ((menu->modes & expand_modes) == 0x0)) {
                        /*
                         * Menu path continues, but we have reached a leaf.
                         * Or menu exists only in another mode.
                         */
                        xfree(path_name);
                        return NULL;
                    }
                    break;
                }
                menu = menu->next;
            }
            if (menu == NULL) {
                /* No menu found with the name we were looking for */
                xfree(path_name);
                return NULL;
            }
            name = p;
            menu = menu->children;
        }
        xfree(path_name);

        xp->xp_context = expand_menus ? EXPAND_MENUNAMES : EXPAND_MENUS;
        xp->xp_pattern = after_dot;
        expand_menu = menu;
    } else                        /* We're in the mapping part */
        xp->xp_context = EXPAND_NOTHING;
    return NULL;
}
Esempio n. 9
0
/*
 * Do the :menu command and relatives.
 */
void
ex_menu (
    exarg_T *eap                   /* Ex command arguments */
)
{
    char_u      *menu_path;
    int modes;
    char_u      *map_to;
    int noremap;
    bool silent = false;
    int special = FALSE;
    int unmenu;
    char_u      *map_buf;
    char_u      *arg;
    char_u      *p;
    int i;
    long pri_tab[MENUDEPTH + 1];
    int enable = MAYBE;               /* TRUE for "menu enable", FALSE for "menu
                                     * disable */
    vimmenu_T menuarg;

    modes = get_menu_cmd_modes(eap->cmd, eap->forceit, &noremap, &unmenu);
    arg = eap->arg;

    for (;; ) {
        if (STRNCMP(arg, "<script>", 8) == 0) {
            noremap = REMAP_SCRIPT;
            arg = skipwhite(arg + 8);
            continue;
        }
        if (STRNCMP(arg, "<silent>", 8) == 0) {
            silent = true;
            arg = skipwhite(arg + 8);
            continue;
        }
        if (STRNCMP(arg, "<special>", 9) == 0) {
            special = TRUE;
            arg = skipwhite(arg + 9);
            continue;
        }
        break;
    }


    /* Locate an optional "icon=filename" argument. */
    if (STRNCMP(arg, "icon=", 5) == 0) {
        arg += 5;
        while (*arg != NUL && *arg != ' ') {
            if (*arg == '\\')
                STRMOVE(arg, arg + 1);
            mb_ptr_adv(arg);
        }
        if (*arg != NUL) {
            *arg++ = NUL;
            arg = skipwhite(arg);
        }
    }

    /*
     * Fill in the priority table.
     */
    for (p = arg; *p; ++p)
        if (!ascii_isdigit(*p) && *p != '.')
            break;
    if (ascii_iswhite(*p)) {
        for (i = 0; i < MENUDEPTH && !ascii_iswhite(*arg); ++i) {
            pri_tab[i] = getdigits_long(&arg);
            if (pri_tab[i] == 0)
                pri_tab[i] = 500;
            if (*arg == '.')
                ++arg;
        }
        arg = skipwhite(arg);
    } else if (eap->addr_count && eap->line2 != 0) {
        pri_tab[0] = eap->line2;
        i = 1;
    } else
        i = 0;
    while (i < MENUDEPTH)
        pri_tab[i++] = 500;
    pri_tab[MENUDEPTH] = -1;              /* mark end of the table */

    /*
     * Check for "disable" or "enable" argument.
     */
    if (STRNCMP(arg, "enable", 6) == 0 && ascii_iswhite(arg[6])) {
        enable = TRUE;
        arg = skipwhite(arg + 6);
    } else if (STRNCMP(arg, "disable", 7) == 0 && ascii_iswhite(arg[7])) {
        enable = FALSE;
        arg = skipwhite(arg + 7);
    }

    /*
     * If there is no argument, display all menus.
     */
    if (*arg == NUL) {
        show_menus(arg, modes);
        return;
    }


    menu_path = arg;
    if (*menu_path == '.') {
        EMSG2(_(e_invarg2), menu_path);
        goto theend;
    }

    map_to = menu_translate_tab_and_shift(arg);

    /*
     * If there is only a menu name, display menus with that name.
     */
    if (*map_to == NUL && !unmenu && enable == MAYBE) {
        show_menus(menu_path, modes);
        goto theend;
    } else if (*map_to != NUL && (unmenu || enable != MAYBE)) {
        EMSG(_(e_trailing));
        goto theend;
    }

    if (enable != MAYBE) {
        /*
         * Change sensitivity of the menu.
         * For the PopUp menu, remove a menu for each mode separately.
         * Careful: menu_nable_recurse() changes menu_path.
         */
        if (STRCMP(menu_path, "*") == 0)            /* meaning: do all menus */
            menu_path = (char_u *)"";

        if (menu_is_popup(menu_path)) {
            for (i = 0; i < MENU_INDEX_TIP; ++i)
                if (modes & (1 << i)) {
                    p = popup_mode_name(menu_path, i);
                    menu_nable_recurse(root_menu, p, MENU_ALL_MODES, enable);
                    xfree(p);
                }
        }
        menu_nable_recurse(root_menu, menu_path, modes, enable);
    } else if (unmenu) {
        /*
         * Delete menu(s).
         */
        if (STRCMP(menu_path, "*") == 0)            /* meaning: remove all menus */
            menu_path = (char_u *)"";

        /*
         * For the PopUp menu, remove a menu for each mode separately.
         */
        if (menu_is_popup(menu_path)) {
            for (i = 0; i < MENU_INDEX_TIP; ++i)
                if (modes & (1 << i)) {
                    p = popup_mode_name(menu_path, i);
                    remove_menu(&root_menu, p, MENU_ALL_MODES, TRUE);
                    xfree(p);
                }
        }

        /* Careful: remove_menu() changes menu_path */
        remove_menu(&root_menu, menu_path, modes, FALSE);
    } else {
        /*
         * Add menu(s).
         * Replace special key codes.
         */
        if (STRICMP(map_to, "<nop>") == 0) {        /* "<Nop>" means nothing */
            map_to = (char_u *)"";
            map_buf = NULL;
        } else if (modes & MENU_TIP_MODE)
            map_buf = NULL;           /* Menu tips are plain text. */
        else
            map_to = replace_termcodes(map_to, &map_buf, FALSE, TRUE, special);
        menuarg.modes = modes;
        menuarg.noremap[0] = noremap;
        menuarg.silent[0] = silent;
        add_menu_path(menu_path, &menuarg, pri_tab, map_to
                     );

        /*
         * For the PopUp menu, add a menu for each mode separately.
         */
        if (menu_is_popup(menu_path)) {
            for (i = 0; i < MENU_INDEX_TIP; ++i)
                if (modes & (1 << i)) {
                    p = popup_mode_name(menu_path, i);
                    // Include all modes, to make ":amenu" work
                    menuarg.modes = modes;
                    add_menu_path(p, &menuarg, pri_tab, map_to);
                    xfree(p);
                }
        }

        xfree(map_buf);
    }


theend:
    ;
}
Esempio n. 10
0
/*
 * ":delmarks[!] [marks]"
 */
void ex_delmarks(exarg_T *eap)
{
  char_u      *p;
  int from, to;
  int i;
  int lower;
  int digit;
  int n;

  if (*eap->arg == NUL && eap->forceit)
    /* clear all marks */
    clrallmarks(curbuf);
  else if (eap->forceit)
    EMSG(_(e_invarg));
  else if (*eap->arg == NUL)
    EMSG(_(e_argreq));
  else {
    /* clear specified marks only */
    for (p = eap->arg; *p != NUL; ++p) {
      lower = ASCII_ISLOWER(*p);
      digit = ascii_isdigit(*p);
      if (lower || digit || ASCII_ISUPPER(*p)) {
        if (p[1] == '-') {
          /* clear range of marks */
          from = *p;
          to = p[2];
          if (!(lower ? ASCII_ISLOWER(p[2])
                : (digit ? ascii_isdigit(p[2])
                   : ASCII_ISUPPER(p[2])))
              || to < from) {
            EMSG2(_(e_invarg2), p);
            return;
          }
          p += 2;
        } else
          /* clear one lower case mark */
          from = to = *p;

        for (i = from; i <= to; ++i) {
          if (lower) {
            curbuf->b_namedm[i - 'a'].mark.lnum = 0;
          } else {
            if (digit) {
              n = i - '0' + NMARKS;
            } else {
              n = i - 'A';
            }
            namedfm[n].fmark.mark.lnum = 0;
            xfree(namedfm[n].fname);
            namedfm[n].fname = NULL;
          }
        }
      } else
        switch (*p) {
        case '"': CLEAR_FMARK(&curbuf->b_last_cursor); break;
        case '^': CLEAR_FMARK(&curbuf->b_last_insert); break;
        case '.': CLEAR_FMARK(&curbuf->b_last_change); break;
        case '[': curbuf->b_op_start.lnum    = 0; break;
        case ']': curbuf->b_op_end.lnum      = 0; break;
        case '<': curbuf->b_visual.vi_start.lnum = 0; break;
        case '>': curbuf->b_visual.vi_end.lnum   = 0; break;
        case ' ': break;
        default:  EMSG2(_(e_invarg2), p);
          return;
        }
    }
  }
}
Esempio n. 11
0
pos_T *getmark_buf_fnum(buf_T *buf, int c, int changefile, int *fnum)
{
  pos_T               *posp;
  pos_T               *startp, *endp;
  static pos_T pos_copy;

  posp = NULL;

  /* Check for special key, can't be a mark name and might cause islower()
   * to crash. */
  if (c < 0)
    return posp;
  if (c > '~') {                        // check for islower()/isupper()
  } else if (c == '\'' || c == '`') {   // previous context mark
    pos_copy = curwin->w_pcmark;        // need to make a copy because
    posp = &pos_copy;                   //   w_pcmark may be changed soon
  } else if (c == '"') {                // to pos when leaving buffer
    posp = &(buf->b_last_cursor.mark);
  } else if (c == '^') {                // to where Insert mode stopped
    posp = &(buf->b_last_insert.mark);
  } else if (c == '.') {                // to where last change was made
    posp = &(buf->b_last_change.mark);
  } else if (c == '[') {                // to start of previous operator
    posp = &(buf->b_op_start);
  } else if (c == ']') {                // to end of previous operator
    posp = &(buf->b_op_end);
  } else if (c == '{' || c == '}') {    // to previous/next paragraph
    pos_T pos;
    oparg_T oa;
    int slcb = listcmd_busy;

    pos = curwin->w_cursor;
    listcmd_busy = TRUE;            /* avoid that '' is changed */
    if (findpar(&oa.inclusive,
            c == '}' ? FORWARD : BACKWARD, 1L, NUL, FALSE)) {
      pos_copy = curwin->w_cursor;
      posp = &pos_copy;
    }
    curwin->w_cursor = pos;
    listcmd_busy = slcb;
  } else if (c == '(' || c == ')') {  /* to previous/next sentence */
    pos_T pos;
    int slcb = listcmd_busy;

    pos = curwin->w_cursor;
    listcmd_busy = TRUE;            /* avoid that '' is changed */
    if (findsent(c == ')' ? FORWARD : BACKWARD, 1L)) {
      pos_copy = curwin->w_cursor;
      posp = &pos_copy;
    }
    curwin->w_cursor = pos;
    listcmd_busy = slcb;
  } else if (c == '<' || c == '>') {  /* start/end of visual area */
    startp = &buf->b_visual.vi_start;
    endp = &buf->b_visual.vi_end;
    if ((c == '<') == lt(*startp, *endp))
      posp = startp;
    else
      posp = endp;
    /*
     * For Visual line mode, set mark at begin or end of line
     */
    if (buf->b_visual.vi_mode == 'V') {
      pos_copy = *posp;
      posp = &pos_copy;
      if (c == '<')
        pos_copy.col = 0;
      else
        pos_copy.col = MAXCOL;
      pos_copy.coladd = 0;
    }
  } else if (ASCII_ISLOWER(c)) {      /* normal named mark */
    posp = &(buf->b_namedm[c - 'a'].mark);
  } else if (ASCII_ISUPPER(c) || ascii_isdigit(c)) {    /* named file mark */
    if (ascii_isdigit(c))
      c = c - '0' + NMARKS;
    else
      c -= 'A';
    posp = &(namedfm[c].fmark.mark);

    if (namedfm[c].fmark.fnum == 0) {
      fname2fnum(&namedfm[c]);
    }

    if (fnum != NULL)
      *fnum = namedfm[c].fmark.fnum;
    else if (namedfm[c].fmark.fnum != buf->b_fnum) {
      /* mark is in another file */
      posp = &pos_copy;

      if (namedfm[c].fmark.mark.lnum != 0
          && changefile && namedfm[c].fmark.fnum) {
        if (buflist_getfile(namedfm[c].fmark.fnum,
                (linenr_T)1, GETF_SETMARK, FALSE) == OK) {
          /* Set the lnum now, autocommands could have changed it */
          curwin->w_cursor = namedfm[c].fmark.mark;
          return (pos_T *)-1;
        }
        pos_copy.lnum = -1;             /* can't get file */
      } else
        pos_copy.lnum = 0;              /* mark exists, but is not valid in
                                           current buffer */
    }
  }

  return posp;
}
Esempio n. 12
0
/*
 * Parse the 'guicursor' option ("what" is SHAPE_CURSOR) or 'mouseshape'
 * ("what" is SHAPE_MOUSE).
 * Returns error message for an illegal option, NULL otherwise.
 */
char_u *parse_shape_opt(int what)
{
  char_u      *modep;
  char_u      *colonp;
  char_u      *commap;
  char_u      *slashp;
  char_u      *p, *endp;
  int idx = 0;                          /* init for GCC */
  int all_idx;
  int len;
  int i;
  int found_ve = FALSE;                 /* found "ve" flag */
  int round;

  /*
   * First round: check for errors; second round: do it for real.
   */
  for (round = 1; round <= 2; ++round) {
    /*
     * Repeat for all comma separated parts.
     */
    modep = p_guicursor;
    while (*modep != NUL) {
      colonp = vim_strchr(modep, ':');
      if (colonp == NULL)
        return (char_u *)N_("E545: Missing colon");
      if (colonp == modep)
        return (char_u *)N_("E546: Illegal mode");
      commap = vim_strchr(modep, ',');

      /*
       * Repeat for all mode's before the colon.
       * For the 'a' mode, we loop to handle all the modes.
       */
      all_idx = -1;
      assert(modep < colonp);
      while (modep < colonp || all_idx >= 0) {
        if (all_idx < 0) {
          /* Find the mode. */
          if (modep[1] == '-' || modep[1] == ':')
            len = 1;
          else
            len = 2;
          if (len == 1 && TOLOWER_ASC(modep[0]) == 'a')
            all_idx = SHAPE_IDX_COUNT - 1;
          else {
            for (idx = 0; idx < SHAPE_IDX_COUNT; ++idx)
              if (STRNICMP(modep, shape_table[idx].name, len)
                  == 0)
                break;
            if (idx == SHAPE_IDX_COUNT
                || (shape_table[idx].used_for & what) == 0)
              return (char_u *)N_("E546: Illegal mode");
            if (len == 2 && modep[0] == 'v' && modep[1] == 'e')
              found_ve = TRUE;
          }
          modep += len + 1;
        }

        if (all_idx >= 0)
          idx = all_idx--;
        else if (round == 2) {
          {
            /* Set the defaults, for the missing parts */
            shape_table[idx].shape = SHAPE_BLOCK;
            shape_table[idx].blinkwait = 700L;
            shape_table[idx].blinkon = 400L;
            shape_table[idx].blinkoff = 250L;
          }
        }

        /* Parse the part after the colon */
        for (p = colonp + 1; *p && *p != ','; ) {
          {
            /*
             * First handle the ones with a number argument.
             */
            i = *p;
            len = 0;
            if (STRNICMP(p, "ver", 3) == 0)
              len = 3;
            else if (STRNICMP(p, "hor", 3) == 0)
              len = 3;
            else if (STRNICMP(p, "blinkwait", 9) == 0)
              len = 9;
            else if (STRNICMP(p, "blinkon", 7) == 0)
              len = 7;
            else if (STRNICMP(p, "blinkoff", 8) == 0)
              len = 8;
            if (len != 0) {
              p += len;
              if (!ascii_isdigit(*p))
                return (char_u *)N_("E548: digit expected");
              int n = getdigits_int(&p);
              if (len == 3) {               /* "ver" or "hor" */
                if (n == 0)
                  return (char_u *)N_("E549: Illegal percentage");
                if (round == 2) {
                  if (TOLOWER_ASC(i) == 'v')
                    shape_table[idx].shape = SHAPE_VER;
                  else
                    shape_table[idx].shape = SHAPE_HOR;
                  shape_table[idx].percentage = n;
                }
              } else if (round == 2) {
                if (len == 9)
                  shape_table[idx].blinkwait = n;
                else if (len == 7)
                  shape_table[idx].blinkon = n;
                else
                  shape_table[idx].blinkoff = n;
              }
            } else if (STRNICMP(p, "block", 5) == 0) {
              if (round == 2)
                shape_table[idx].shape = SHAPE_BLOCK;
              p += 5;
            } else {          /* must be a highlight group name then */
              endp = vim_strchr(p, '-');
              if (commap == NULL) {                         /* last part */
                if (endp == NULL)
                  endp = p + STRLEN(p);                     /* find end of part */
              } else if (endp > commap || endp == NULL)
                endp = commap;
              slashp = vim_strchr(p, '/');
              if (slashp != NULL && slashp < endp) {
                /* "group/langmap_group" */
                i = syn_check_group(p, (int)(slashp - p));
                p = slashp + 1;
              }
              if (round == 2) {
                shape_table[idx].id = syn_check_group(p,
                    (int)(endp - p));
                shape_table[idx].id_lm = shape_table[idx].id;
                if (slashp != NULL && slashp < endp)
                  shape_table[idx].id = i;
              }
              p = endp;
            }
          }           /* if (what != SHAPE_MOUSE) */

          if (*p == '-')
            ++p;
        }
      }
      modep = p;
      if (*modep == ',')
        ++modep;
    }
  }

  /* If the 's' flag is not given, use the 'v' cursor for 's' */
  if (!found_ve) {
    {
      shape_table[SHAPE_IDX_VE].shape = shape_table[SHAPE_IDX_V].shape;
      shape_table[SHAPE_IDX_VE].percentage =
        shape_table[SHAPE_IDX_V].percentage;
      shape_table[SHAPE_IDX_VE].blinkwait =
        shape_table[SHAPE_IDX_V].blinkwait;
      shape_table[SHAPE_IDX_VE].blinkon =
        shape_table[SHAPE_IDX_V].blinkon;
      shape_table[SHAPE_IDX_VE].blinkoff =
        shape_table[SHAPE_IDX_V].blinkoff;
      shape_table[SHAPE_IDX_VE].id = shape_table[SHAPE_IDX_V].id;
      shape_table[SHAPE_IDX_VE].id_lm = shape_table[SHAPE_IDX_V].id_lm;
    }
  }

  return NULL;
}
Esempio n. 13
0
/* Calls strtod in a locale-independent fashion, by looking at
 * the locale data and patching the decimal comma to a point.
 *
 * Relicensed from glib.
 */
static double
ascii_strtod (const char *nptr,
	      char      **endptr)
{
  /* FIXME: The Win32 C library's strtod() doesn't handle hex.
   * Presumably many Unixes don't either.
   */

  char *fail_pos;
  double val;
  struct lconv *locale_data;
  const char *decimal_point;
  int decimal_point_len;
  const char *p, *decimal_point_pos;
  const char *end = NULL; /* Silence gcc */

  fail_pos = NULL;

  locale_data = localeconv ();
  decimal_point = locale_data->decimal_point;
  decimal_point_len = strlen (decimal_point);

  _dbus_assert (decimal_point_len != 0);
  
  decimal_point_pos = NULL;
  if (decimal_point[0] != '.' ||
      decimal_point[1] != 0)
    {
      p = nptr;
      /* Skip leading space */
      while (ascii_isspace (*p))
	p++;
      
      /* Skip leading optional sign */
      if (*p == '+' || *p == '-')
	p++;
      
      if (p[0] == '0' &&
	  (p[1] == 'x' || p[1] == 'X'))
	{
	  p += 2;
	  /* HEX - find the (optional) decimal point */
	  
	  while (ascii_isxdigit (*p))
	    p++;
	  
	  if (*p == '.')
	    {
	      decimal_point_pos = p++;
	      
	      while (ascii_isxdigit (*p))
		p++;
	      
	      if (*p == 'p' || *p == 'P')
		p++;
	      if (*p == '+' || *p == '-')
		p++;
	      while (ascii_isdigit (*p))
		p++;
	      end = p;
	    }
	}
      else
	{
	  while (ascii_isdigit (*p))
	    p++;
	  
	  if (*p == '.')
	    {
	      decimal_point_pos = p++;
	      
	      while (ascii_isdigit (*p))
		p++;
	      
	      if (*p == 'e' || *p == 'E')
		p++;
	      if (*p == '+' || *p == '-')
		p++;
	      while (ascii_isdigit (*p))
		p++;
	      end = p;
	    }
	}
      /* For the other cases, we need not convert the decimal point */
    }

  /* Set errno to zero, so that we can distinguish zero results
     and underflows */
  errno = 0;
  
  if (decimal_point_pos)
    {
      char *copy, *c;

      /* We need to convert the '.' to the locale specific decimal point */
      copy = dbus_malloc (end - nptr + 1 + decimal_point_len);
      
      c = copy;
      memcpy (c, nptr, decimal_point_pos - nptr);
      c += decimal_point_pos - nptr;
      memcpy (c, decimal_point, decimal_point_len);
      c += decimal_point_len;
      memcpy (c, decimal_point_pos + 1, end - (decimal_point_pos + 1));
      c += end - (decimal_point_pos + 1);
      *c = 0;

      val = strtod (copy, &fail_pos);

      if (fail_pos)
	{
	  if (fail_pos > decimal_point_pos)
	    fail_pos = (char *)nptr + (fail_pos - copy) - (decimal_point_len - 1);
	  else
	    fail_pos = (char *)nptr + (fail_pos - copy);
	}
      
      dbus_free (copy);
	  
    }
  else
    val = strtod (nptr, &fail_pos);

  if (endptr)
    *endptr = fail_pos;
  
  return val;
}
Esempio n. 14
0
/*
 * Set named mark "c" to position "pos".
 * When "c" is upper case use file "fnum".
 * Returns OK on success, FAIL if bad name given.
 */
int setmark_pos(int c, pos_T *pos, int fnum)
{
  int i;

  /* Check for a special key (may cause islower() to crash). */
  if (c < 0)
    return FAIL;

  if (c == '\'' || c == '`') {
    if (pos == &curwin->w_cursor) {
      setpcmark();
      /* keep it even when the cursor doesn't move */
      curwin->w_prev_pcmark = curwin->w_pcmark;
    } else
      curwin->w_pcmark = *pos;
    return OK;
  }

  if (c == '"') {
    RESET_FMARK(&curbuf->b_last_cursor, *pos, curbuf->b_fnum);
    return OK;
  }

  /* Allow setting '[ and '] for an autocommand that simulates reading a
   * file. */
  if (c == '[') {
    curbuf->b_op_start = *pos;
    return OK;
  }
  if (c == ']') {
    curbuf->b_op_end = *pos;
    return OK;
  }

  if (c == '<' || c == '>') {
    if (c == '<')
      curbuf->b_visual.vi_start = *pos;
    else
      curbuf->b_visual.vi_end = *pos;
    if (curbuf->b_visual.vi_mode == NUL)
      /* Visual_mode has not yet been set, use a sane default. */
      curbuf->b_visual.vi_mode = 'v';
    return OK;
  }

  buf_T *buf = buflist_findnr(fnum);
  // Can't set a mark in a non-existant buffer.
  if (buf == NULL) {
    return FAIL;
  }

  if (ASCII_ISLOWER(c)) {
    i = c - 'a';
    RESET_FMARK(buf->b_namedm + i, *pos, fnum);
    return OK;
  }
  if (ASCII_ISUPPER(c) || ascii_isdigit(c)) {
    if (ascii_isdigit(c)) {
      i = c - '0' + NMARKS;
    } else {
      i = c - 'A';
    }
    RESET_XFMARK(namedfm + i, *pos, fnum, NULL);
    return OK;
  }
  return FAIL;
}