예제 #1
0
파일: farsi.c 프로젝트: cschneid/neovim
/// Convert the Farsi 3342 standard into Farsi VIM.
void conv_to_pvim(void)
{
  char_u *ptr;
  int lnum, llen, i;

  for (lnum = 1; lnum <= curbuf->b_ml.ml_line_count; ++lnum) {
    ptr = ml_get((linenr_T)lnum);
    llen = (int)STRLEN(ptr);
    for (i = 0; i < llen - 1; i++) {
      if (canF_Ljoin(ptr[i]) && canF_Rjoin(ptr[i + 1])) {
        ptr[i] = toF_leading(ptr[i]);
        i++;

        while (canF_Rjoin(ptr[i]) && i < llen) {
          ptr[i] = toF_Rjoin(ptr[i]);
          if (F_isterm(ptr[i]) || !F_isalpha(ptr[i])) {
            break;
          }
          i++;
        }

        if (!F_isalpha(ptr[i]) || !canF_Rjoin(ptr[i])) {
          ptr[i - 1] = toF_ending(ptr[i - 1]);
        }
      } else {
        ptr[i] = toF_TyA(ptr[i]);
      }
    }
  }

  // Following lines contains Farsi encoded character.
  do_cmdline_cmd((char_u *)"%s/\202\231/\232/g");
  do_cmdline_cmd((char_u *)"%s/\201\231/\370\334/g");

  // Assume the screen has been messed up: clear it and redraw.
  redraw_later(CLEAR);
  MSG_ATTR(farsi_text_1, hl_attr(HLF_S));
}
예제 #2
0
파일: farsi.c 프로젝트: Aldemarka/neovim
/*
 * swap all the Farsi characters in reverse direction
 */
char_u *lrFswap(char_u *cmdbuf, int len)
{
  int i, cnt;

  if (cmdbuf == NULL)
    return cmdbuf;

  if (len == 0 && (len = (int)STRLEN(cmdbuf)) == 0)
    return cmdbuf;

  for (i = 0; i < len; i++) {
    for (cnt = 0; i + cnt < len
         && (F_isalpha(cmdbuf[i + cnt])
             || F_isdigit(cmdbuf[i + cnt])
             || cmdbuf[i + cnt] == ' '); ++cnt)
      ;

    lrswapbuf(cmdbuf + i, cnt);
    i += cnt;
  }
  return cmdbuf;
}
예제 #3
0
파일: charset.c 프로젝트: ashleyh/neovim
/// 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;
  char_u *p;
  int i;
  int tilde;
  int 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.
    //
    // EBCDIC: all chars below ' ' are not printable, all others are
    // printable.
    c = 0;

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

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

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

    while (c < 256) {
      if (enc_utf8 && (c >= 0xa0)) {
        // UTF-8: bytes 0xa0 - 0xff are printable (latin1)
        chartab[c++] = CT_PRINT_CHAR + 1;
      } else if ((enc_dbcs == DBCS_JPNU) && (c == 0x8e)) {
        // euc-jp characters starting with 0x8e are single width
        chartab[c++] = CT_PRINT_CHAR + 1;
      } else if ((enc_dbcs != 0) && (MB_BYTE2LEN(c) == 2)) {
        // other double-byte chars can be printable AND double-width
        chartab[c++] = CT_PRINT_CHAR + 2;
      } else {
        // the rest is unprintable by default
        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 (((enc_dbcs != 0) && (MB_BYTE2LEN(c) > 1))
          || ((enc_dbcs == DBCS_JPNU) && (c == 0x8e))
          || (enc_utf8 && (c >= 0xa0))) {
        chartab[c] |= CT_FNAME_CHAR;
      }
    }
  }

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

  if (enc_dbcs != 0) {
    for (c = 0; c < 256; ++c) {
      // double-byte characters are probably word characters
      if (MB_BYTE2LEN(c) == 2) {
        SET_CHARTAB(buf, c);
      }
    }
  }

  // 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) {
    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 (VIM_ISDIGIT(*p)) {
        c = getdigits(&p);
      } else if (has_mbyte) {
        c = mb_ptr2char_adv(&p);
      } else {
        c = *p++;
      }
      c2 = -1;

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

        if (VIM_ISDIGIT(*p)) {
          c2 = getdigits(&p);
        } else if (has_mbyte) {
          c2 = mb_ptr2char_adv(&p);
        } else {
          c2 = *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) {
              chartab[c] &= ~CT_ID_CHAR;
            } else {
              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))))
                && !(enc_dbcs && (MB_BYTE2LEN(c) == 2))) {
              if (tilde) {
                chartab[c] = (chartab[c] & ~CT_CELL_MASK)
                             + ((dy_flags & DY_UHEX) ? 4 : 2);
                chartab[c] &= ~CT_PRINT_CHAR;
              } else {
                chartab[c] = (chartab[c] & ~CT_CELL_MASK) + 1;
                chartab[c] |= CT_PRINT_CHAR;
              }
            }
          } else if (i == 2) {
            // (re)set fname flag
            if (tilde) {
              chartab[c] &= ~CT_FNAME_CHAR;
            } else {
              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;
}
예제 #4
0
파일: charset.c 프로젝트: Gaelan/neovim
int 
buf_init_chartab (
    buf_T *buf,
    int global                     /* FALSE: only set buf->b_chartab[] */
)
{
  int c;
  int c2;
  char_u      *p;
  int i;
  int tilde;
  int 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.
     *
     * EBCDIC: all chars below ' ' are not printable, all others are
     * printable.
     */
    c = 0;
    while (c < ' ')
      chartab[c++] = (dy_flags & DY_UHEX) ? 4 : 2;
    while (c <= '~')
      chartab[c++] = 1 + CT_PRINT_CHAR;
    if (p_altkeymap) {
      while (c < YE)
        chartab[c++] = 1 + CT_PRINT_CHAR;
    }
    while (c < 256) {
      /* UTF-8: bytes 0xa0 - 0xff are printable (latin1) */
      if (enc_utf8 && c >= 0xa0)
        chartab[c++] = CT_PRINT_CHAR + 1;
      /* euc-jp characters starting with 0x8e are single width */
      else if (enc_dbcs == DBCS_JPNU && c == 0x8e)
        chartab[c++] = CT_PRINT_CHAR + 1;
      /* other double-byte chars can be printable AND double-width */
      else if (enc_dbcs != 0 && MB_BYTE2LEN(c) == 2)
        chartab[c++] = CT_PRINT_CHAR + 2;
      else
        /* the rest is unprintable by default */
        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 ((enc_dbcs != 0 && MB_BYTE2LEN(c) > 1)
          || (enc_dbcs == DBCS_JPNU && c == 0x8e)
          || (enc_utf8 && c >= 0xa0))
        chartab[c] |= CT_FNAME_CHAR;
  }

  /*
   * Init word char flags all to FALSE
   */
  vim_memset(buf->b_chartab, 0, (size_t)32);
  if (enc_dbcs != 0)
    for (c = 0; c < 256; ++c) {
      /* double-byte characters are probably word characters */
      if (MB_BYTE2LEN(c) == 2)
        SET_CHARTAB(buf, c);
    }

  /*
   * 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) {
    if (i == 0)
      p = p_isi;                /* first round: 'isident' */
    else if (i == 1)
      p = p_isp;                /* second round: 'isprint' */
    else if (i == 2)
      p = p_isf;                /* third round: 'isfname' */
    else        /* i == 3 */
      p = buf->b_p_isk;         /* fourth round: 'iskeyword' */

    while (*p) {
      tilde = FALSE;
      do_isalpha = FALSE;
      if (*p == '^' && p[1] != NUL) {
        tilde = TRUE;
        ++p;
      }
      if (VIM_ISDIGIT(*p))
        c = getdigits(&p);
      else if (has_mbyte)
        c = mb_ptr2char_adv(&p);
      else
        c = *p++;
      c2 = -1;
      if (*p == '-' && p[1] != NUL) {
        ++p;
        if (VIM_ISDIGIT(*p))
          c2 = getdigits(&p);
        else if (has_mbyte)
          c2 = mb_ptr2char_adv(&p);
        else
          c2 = *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)
              chartab[c] &= ~CT_ID_CHAR;
            else
              chartab[c] |= CT_ID_CHAR;
          } else if (i == 1)   {                /* (re)set printable */
            if ((c < ' '
                 || c > '~'
                 || (p_altkeymap
                     && (F_isalpha(c) || F_isdigit(c)))
                 )
                /* For double-byte we keep the cell width, so
                 * that we can detect it from the first byte. */
                && !(enc_dbcs && MB_BYTE2LEN(c) == 2)
                ) {
              if (tilde) {
                chartab[c] = (chartab[c] & ~CT_CELL_MASK)
                             + ((dy_flags & DY_UHEX) ? 4 : 2);
                chartab[c] &= ~CT_PRINT_CHAR;
              } else   {
                chartab[c] = (chartab[c] & ~CT_CELL_MASK) + 1;
                chartab[c] |= CT_PRINT_CHAR;
              }
            }
          } else if (i == 2)   {                /* (re)set fname flag */
            if (tilde)
              chartab[c] &= ~CT_FNAME_CHAR;
            else
              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;
}
예제 #5
0
파일: farsi.c 프로젝트: cschneid/neovim
/// Map Farsi keyboard when in fkmap mode.
int fkmap(int c)
{
  int tempc;
  static int revins;

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

  if (VIM_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() != '\0') {
          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(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(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(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(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(ml_get_curline())) {
        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;
        }
      }

      if (!p_ri) {
        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(ml_get_curline())) {
        if (p_ri) {
          chg_c_to_X_or_X();
        }
      }

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

      if (!p_ri) {
        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(ml_get_curline())) {
        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(ml_get_curline())) {
        if (p_ri) {
          chg_c_to_X_or_X();
        }
      }

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

      if (!p_ri) {
        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(ml_get_curline())) {
        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(ml_get_curline())) {
        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(ml_get_curline())) {
      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;
}
예제 #6
0
파일: charset.c 프로젝트: jessonfoo/neovim
/// 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;
}