コード例 #1
0
ファイル: fakegpm.c プロジェクト: WoodyGuo/vimtouch
int Gpm_GetEvent(Gpm_Event *e){
    VimEvent event;

    int n = read(gpm_fd, (void*)&event, sizeof(VimEvent));
    if(event.type == VIM_EVENT_TYPE_GPM) {
        memcpy(e, (void*)&event.event.gpm, sizeof(Gpm_Event));
        return 1;
    }else if(event.type == VIM_EVENT_TYPE_CMD) {
        do_cmdline_cmd((char_u *) event.event.cmd);
    }else if(event.type == VIM_EVENT_TYPE_RELINE) {
        char* str = event.event.cmd;
        ml_replace(curwin->w_cursor.lnum,(char_u*)str, TRUE);
        changed_lines(curwin->w_cursor.lnum, 0, curwin->w_cursor.lnum, 1L);
    }else if(event.type == VIM_EVENT_TYPE_UPDATE){
        vimtouch_lock();
        update_screen(0);
        setcursor();
        out_flush();
        vimtouch_unlock();
    }else if(event.type == VIM_EVENT_TYPE_SETCOL){
        curwin->w_cursor.col = event.event.num;
    }else if(event.type == VIM_EVENT_TYPE_SCROLL){
        int do_scroll = event.event.num;
        scroll_redraw(do_scroll > 0, do_scroll>0?do_scroll:-do_scroll);
    }else if(event.type == VIM_EVENT_TYPE_RESIZE){
        out_flush();
        shell_resized_check();
        redraw_later(CLEAR);
        update_screen(CLEAR);
        out_flush();
    }
    return 0;
}
コード例 #2
0
ファイル: fakegpm.c プロジェクト: kvj/vimtouch
int Gpm_GetEvent(Gpm_Event *e){
    VimEvent event;

    int n = read(gpm_fd, (void*)&event, sizeof(VimEvent));
    if(event.type == VIM_EVENT_TYPE_GPM) {
        memcpy(e, (void*)&event.event.gpm, sizeof(Gpm_Event));
        return 1;
    }else if(event.type == VIM_EVENT_TYPE_ANDROID_SEND) {
        vimtouch_send_android_event(event.event.num, (char_u *) &event.event.nums[1]);
		return 0;
    }else if(event.type == VIM_EVENT_TYPE_CMD) {
        do_cmdline_cmd((char_u *) event.event.cmd);
    }else if(event.type == VIM_EVENT_TYPE_RELINE) {
        char* str = event.event.cmd;
        ml_replace(curwin->w_cursor.lnum,(char_u*)str, TRUE);
        changed_lines(curwin->w_cursor.lnum, 0, curwin->w_cursor.lnum, 1L);
    }else if(event.type == VIM_EVENT_TYPE_UPDATE){
        //vimtouch_lock();
        update_screen(0);
        setcursor();
        out_flush();
        //vimtouch_unlock();
    }else if(event.type == VIM_EVENT_TYPE_CURSOR){
        mouse_col = event.event.nums[0];
        mouse_row = event.event.nums[1];

        jump_to_mouse(MOUSE_DID_MOVE, NULL, 0);
    }else if(event.type == VIM_EVENT_TYPE_SETCOL){
        curwin->w_cursor.col = event.event.num;
    }else if(event.type == VIM_EVENT_TYPE_SCROLL){
        int do_scroll = event.event.num;
        scroll_redraw(do_scroll > 0, do_scroll>0?do_scroll:-do_scroll);
    }else if(event.type == VIM_EVENT_TYPE_RESIZE){
        out_flush();
        shell_resized_check();
        redraw_later(CLEAR);
        out_flush();
    }else if(event.type == VIM_EVENT_TYPE_SETTAB){
        int nr = event.event.nums[0];

        if (nr != tabpage_index(curtab)){
            current_tab = nr;
            if (current_tab == 255)     /* -1 in a byte gives 255 */
            current_tab = -1;
            goto_tabpage(current_tab);
            update_screen(CLEAR);
            out_flush();
        }
    }else if(event.type == VIM_EVENT_TYPE_HISTORY){
        char buf[1024];
        int i = 1;
        for(i = 1; i <= 10; i++){
            sprintf(buf, "HISTORY:%d,%s\n",i-1,get_history_entry(HIST_CMD,i));
            write(gpm_fd,buf,strlen(buf));
        }
    }
    vimtouch_sync();
    return 0;
}
コード例 #3
0
ファイル: if_ruby.c プロジェクト: LemonBoy/vim
void ex_rubydo(exarg_T *eap)
{
    int state;
    linenr_T i;

    if (ensure_ruby_initialized())
    {
	if (u_save(eap->line1 - 1, eap->line2 + 1) != OK)
	    return;
	for (i = eap->line1; i <= eap->line2; i++)
	{
	    VALUE line;

	    line = vim_str2rb_enc_str((char *)ml_get(i));
	    rb_lastline_set(line);
	    eval_enc_string_protect((char *) eap->arg, &state);
	    if (state)
	    {
		error_print(state);
		break;
	    }
	    line = rb_lastline_get();
	    if (!NIL_P(line))
	    {
		if (TYPE(line) != T_STRING)
		{
		    EMSG(_("E265: $_ must be an instance of String"));
		    return;
		}
		ml_replace(i, (char_u *) StringValuePtr(line), 1);
		changed();
#ifdef SYNTAX_HL
		syn_changed(i); /* recompute syntax hl. for this line */
#endif
	    }
	}
	check_cursor();
	update_curbuf(NOT_VALID);
    }
}
コード例 #4
0
ファイル: indent.c プロジェクト: cschneid/neovim
// Set the indent of the current line.
// Leaves the cursor on the first non-blank in the line.
// Caller must take care of undo.
// "flags":
//  SIN_CHANGED:    call changed_bytes() if the line was changed.
//  SIN_INSERT: insert the indent in front of the line.
//  SIN_UNDO:   save line for undo before changing it.
//  @param size measured in spaces
// Returns true if the line was changed.
int set_indent(int size, int flags)
{
  char_u *p;
  char_u *newline;
  char_u *oldline;
  char_u *s;
  int todo;
  int ind_len;  // Measured in characters.
  int line_len;
  int doit = false;
  int ind_done = 0;  // Measured in spaces.
  int tab_pad;
  int retval = false;

  // Number of initial whitespace chars when 'et' and 'pi' are both set.
  int orig_char_len = -1;

  // First check if there is anything to do and compute the number of
  // characters needed for the indent.
  todo = size;
  ind_len = 0;
  p = oldline = ml_get_curline();

  // Calculate the buffer size for the new indent, and check to see if it
  // isn't already set.
  // If 'expandtab' isn't set: use TABs; if both 'expandtab' and
  // 'preserveindent' are set count the number of characters at the
  // beginning of the line to be copied.
  if (!curbuf->b_p_et || (!(flags & SIN_INSERT) && curbuf->b_p_pi)) {
    // If 'preserveindent' is set then reuse as much as possible of
    // the existing indent structure for the new indent.
    if (!(flags & SIN_INSERT) && curbuf->b_p_pi) {
      ind_done = 0;

      // Count as many characters as we can use.
      while (todo > 0 && vim_iswhite(*p)) {
        if (*p == TAB) {
          tab_pad = (int)curbuf->b_p_ts - (ind_done % (int)curbuf->b_p_ts);

          // Stop if this tab will overshoot the target.
          if (todo < tab_pad) {
            break;
          }
          todo -= tab_pad;
          ind_len++;
          ind_done += tab_pad;
        } else {
          todo--;
          ind_len++;
          ind_done++;
        }
        p++;
      }

      // Set initial number of whitespace chars to copy if we are
      // preserving indent but expandtab is set.
      if (curbuf->b_p_et) {
        orig_char_len = ind_len;
      }

      // Fill to next tabstop with a tab, if possible.
      tab_pad = (int)curbuf->b_p_ts - (ind_done % (int)curbuf->b_p_ts);

      if ((todo >= tab_pad) && (orig_char_len == -1)) {
        doit = true;
        todo -= tab_pad;
        ind_len++;

        // ind_done += tab_pad;
      }
    }

    // Count tabs required for indent.
    while (todo >= (int)curbuf->b_p_ts) {
      if (*p != TAB) {
        doit = true;
      } else {
        p++;
      }
      todo -= (int)curbuf->b_p_ts;
      ind_len++;

      // ind_done += (int)curbuf->b_p_ts;
    }
  }

  // Count spaces required for indent.
  while (todo > 0) {
    if (*p != ' ') {
      doit = true;
    } else {
      p++;
    }
    todo--;
    ind_len++;

    // ind_done++;
  }

  // Return if the indent is OK already.
  if (!doit && !vim_iswhite(*p) && !(flags & SIN_INSERT)) {
    return false;
  }

  // Allocate memory for the new line.
  if (flags & SIN_INSERT) {
    p = oldline;
  } else {
    p = skipwhite(p);
  }
  line_len = (int)STRLEN(p) + 1;

  // If 'preserveindent' and 'expandtab' are both set keep the original
  // characters and allocate accordingly.  We will fill the rest with spaces
  // after the if (!curbuf->b_p_et) below.
  if (orig_char_len != -1) {
    newline = alloc(orig_char_len + size - ind_done + line_len);
    todo = size - ind_done;

    // Set total length of indent in characters, which may have been
    // undercounted until now.
    ind_len = orig_char_len + todo;
    p = oldline;
    s = newline;

    while (orig_char_len > 0) {
      *s++ = *p++;
      orig_char_len--;
    }

    // Skip over any additional white space (useful when newindent is less
    // than old).
    while (vim_iswhite(*p)) {
      p++;
    }
  } else {
    todo = size;
    newline = alloc(ind_len + line_len);
    s = newline;
  }

  // Put the characters in the new line.
  // if 'expandtab' isn't set: use TABs
  if (!curbuf->b_p_et) {
    // If 'preserveindent' is set then reuse as much as possible of
    // the existing indent structure for the new indent.
    if (!(flags & SIN_INSERT) && curbuf->b_p_pi) {
      p = oldline;
      ind_done = 0;

      while (todo > 0 && vim_iswhite(*p)) {
        if (*p == TAB) {
          tab_pad = (int)curbuf->b_p_ts - (ind_done % (int)curbuf->b_p_ts);

          // Stop if this tab will overshoot the target.
          if (todo < tab_pad) {
            break;
          }
          todo -= tab_pad;
          ind_done += tab_pad;
        } else {
          todo--;
          ind_done++;
        }
        *s++ = *p++;
      }

      // Fill to next tabstop with a tab, if possible.
      tab_pad = (int)curbuf->b_p_ts - (ind_done % (int)curbuf->b_p_ts);

      if (todo >= tab_pad) {
        *s++ = TAB;
        todo -= tab_pad;
      }
      p = skipwhite(p);
    }

    while (todo >= (int)curbuf->b_p_ts) {
      *s++ = TAB;
      todo -= (int)curbuf->b_p_ts;
    }
  }

  while (todo > 0) {
    *s++ = ' ';
    todo--;
  }
  memmove(s, p, (size_t)line_len);

  // Replace the line (unless undo fails).
  if (!(flags & SIN_UNDO) || (u_savesub(curwin->w_cursor.lnum) == OK)) {
    ml_replace(curwin->w_cursor.lnum, newline, false);

    if (flags & SIN_CHANGED) {
      changed_bytes(curwin->w_cursor.lnum, 0);
    }

    // Correct saved cursor position if it is in this line.
    if (saved_cursor.lnum == curwin->w_cursor.lnum) {
      if (saved_cursor.col >= (colnr_T)(p - oldline)) {
        // Cursor was after the indent, adjust for the number of
        // bytes added/removed.
        saved_cursor.col += ind_len - (colnr_T)(p - oldline);

      } else if (saved_cursor.col >= (colnr_T)(s - newline)) {
        // Cursor was in the indent, and is now after it, put it back
        // at the start of the indent (replacing spaces with TAB).
        saved_cursor.col = (colnr_T)(s - newline);
      }
    }
    retval = true;
  } else {
    vim_free(newline);
  }
  curwin->w_cursor.col = ind_len;
  return retval;
}
コード例 #5
0
ファイル: indent.c プロジェクト: cschneid/neovim
// Copy the indent from ptr to the current line (and fill to size).
// Leaves the cursor on the first non-blank in the line.
// @return true if the line was changed.
int copy_indent(int size, char_u *src)
{
  char_u *p = NULL;
  char_u *line = NULL;
  char_u *s;
  int todo;
  int ind_len;
  int line_len = 0;
  int tab_pad;
  int ind_done;
  int round;

  // Round 1: compute the number of characters needed for the indent
  // Round 2: copy the characters.
  for (round = 1; round <= 2; ++round) {
    todo = size;
    ind_len = 0;
    ind_done = 0;
    s = src;

    // Count/copy the usable portion of the source line.
    while (todo > 0 && vim_iswhite(*s)) {
      if (*s == TAB) {
        tab_pad = (int)curbuf->b_p_ts
                  - (ind_done % (int)curbuf->b_p_ts);

        // Stop if this tab will overshoot the target.
        if (todo < tab_pad) {
          break;
        }
        todo -= tab_pad;
        ind_done += tab_pad;
      } else {
        todo--;
        ind_done++;
      }
      ind_len++;

      if (p != NULL) {
        *p++ = *s;
      }
      s++;
    }

    // Fill to next tabstop with a tab, if possible.
    tab_pad = (int)curbuf->b_p_ts - (ind_done % (int)curbuf->b_p_ts);

    if ((todo >= tab_pad) && !curbuf->b_p_et) {
      todo -= tab_pad;
      ind_len++;

      if (p != NULL) {
        *p++ = TAB;
      }
    }

    // Add tabs required for indent.
    while (todo >= (int)curbuf->b_p_ts && !curbuf->b_p_et) {
      todo -= (int)curbuf->b_p_ts;
      ind_len++;

      if (p != NULL) {
        *p++ = TAB;
      }
    }

    // Count/add spaces required for indent.
    while (todo > 0) {
      todo--;
      ind_len++;

      if (p != NULL) {
        *p++ = ' ';
      }
    }

    if (p == NULL) {
      // Allocate memory for the result: the copied indent, new indent
      // and the rest of the line.
      line_len = (int)STRLEN(ml_get_curline()) + 1;
      line = alloc(ind_len + line_len);
      p = line;
    }
  }

  // Append the original line
  memmove(p, ml_get_curline(), (size_t)line_len);

  // Replace the line
  ml_replace(curwin->w_cursor.lnum, line, false);

  // Put the cursor after the indent.
  curwin->w_cursor.col = ind_len;
  return true;
}
コード例 #6
0
ファイル: cursor.c プロジェクト: ZyX-I/neovim
static int coladvance2(
    pos_T *pos,
    bool addspaces,                /* change the text to achieve our goal? */
    bool finetune,                 /* change char offset for the exact column */
    colnr_T wcol                   /* column to move to */
)
{
  int idx;
  char_u      *ptr;
  char_u      *line;
  colnr_T col = 0;
  int csize = 0;
  int one_more;
  int head = 0;

  one_more = (State & INSERT)
             || restart_edit != NUL
             || (VIsual_active && *p_sel != 'o')
             || ((ve_flags & VE_ONEMORE) && wcol < MAXCOL);
  line = ml_get_buf(curbuf, pos->lnum, false);

  if (wcol >= MAXCOL) {
    idx = (int)STRLEN(line) - 1 + one_more;
    col = wcol;

    if ((addspaces || finetune) && !VIsual_active) {
      curwin->w_curswant = linetabsize(line) + one_more;
      if (curwin->w_curswant > 0)
        --curwin->w_curswant;
    }
  } else {
    int width = curwin->w_width - win_col_off(curwin);

    if (finetune
        && curwin->w_p_wrap
        && curwin->w_width != 0
        && wcol >= (colnr_T)width) {
      csize = linetabsize(line);
      if (csize > 0)
        csize--;

      if (wcol / width > (colnr_T)csize / width
          && ((State & INSERT) == 0 || (int)wcol > csize + 1)) {
        /* In case of line wrapping don't move the cursor beyond the
         * right screen edge.  In Insert mode allow going just beyond
         * the last character (like what happens when typing and
         * reaching the right window edge). */
        wcol = (csize / width + 1) * width - 1;
      }
    }

    ptr = line;
    while (col <= wcol && *ptr != NUL) {
      /* Count a tab for what it's worth (if list mode not on) */
      csize = win_lbr_chartabsize(curwin, line, ptr, col, &head);
      MB_PTR_ADV(ptr);
      col += csize;
    }
    idx = (int)(ptr - line);
    /*
     * Handle all the special cases.  The virtual_active() check
     * is needed to ensure that a virtual position off the end of
     * a line has the correct indexing.  The one_more comparison
     * replaces an explicit add of one_more later on.
     */
    if (col > wcol || (!virtual_active() && one_more == 0)) {
      idx -= 1;
      /* Don't count the chars from 'showbreak'. */
      csize -= head;
      col -= csize;
    }

    if (virtual_active()
        && addspaces
        && ((col != wcol && col != wcol + 1) || csize > 1)) {
      /* 'virtualedit' is set: The difference between wcol and col is
       * filled with spaces. */

      if (line[idx] == NUL) {
        /* Append spaces */
        int correct = wcol - col;
        char_u *newline = xmallocz((size_t)(idx + correct));
        memcpy(newline, line, (size_t)idx);
        memset(newline + idx, ' ', (size_t)correct);

        ml_replace(pos->lnum, newline, false);
        changed_bytes(pos->lnum, (colnr_T)idx);
        idx += correct;
        col = wcol;
      } else {
        /* Break a tab */
        int linelen = (int)STRLEN(line);
        int correct = wcol - col - csize + 1;             /* negative!! */
        char_u  *newline;

        if (-correct > csize)
          return FAIL;

        newline = xmallocz((size_t)(linelen - 1 + csize));
        // Copy first idx chars
        memcpy(newline, line, (size_t)idx);
        // Replace idx'th char with csize spaces
        memset(newline + idx, ' ', (size_t)csize);
        // Copy the rest of the line
        memcpy(newline + idx + csize, line + idx + 1,
               (size_t)(linelen - idx - 1));

        ml_replace(pos->lnum, newline, false);
        changed_bytes(pos->lnum, idx);
        idx += (csize - 1 + correct);
        col += correct;
      }
    }
  }

  if (idx < 0)
    pos->col = 0;
  else
    pos->col = idx;

  pos->coladd = 0;

  if (finetune) {
    if (wcol == MAXCOL) {
      /* The width of the last character is used to set coladd. */
      if (!one_more) {
        colnr_T scol, ecol;

        getvcol(curwin, pos, &scol, NULL, &ecol);
        pos->coladd = ecol - scol;
      }
    } else {
      int b = (int)wcol - (int)col;

      /* The difference between wcol and col is used to set coladd. */
      if (b > 0 && b < (MAXCOL - 2 * curwin->w_width))
        pos->coladd = b;

      col += b;
    }
  }

  // Prevent from moving onto a trail byte.
  if (has_mbyte) {
    mark_mb_adjustpos(curbuf, pos);
  }

  if (col < wcol)
    return FAIL;
  return OK;
}
コード例 #7
0
ファイル: if_lua.c プロジェクト: LeonB/vim
    static int
luaV_buffer_newindex(lua_State *L)
{
    buf_T *b = (buf_T *) luaV_checkvalid(L, luaV_Buffer, 1);
    linenr_T n = (linenr_T) luaL_checkinteger(L, 2);
#ifdef HAVE_SANDBOX
    luaV_checksandbox(L);
#endif
    if (n < 1 || n > b->b_ml.ml_line_count)
	luaL_error(L, "invalid line number");
    if (lua_isnil(L, 3)) /* delete line */
    {
	buf_T *buf = curbuf;
	curbuf = b;
	if (u_savedel(n, 1L) == FAIL)
	{
	    curbuf = buf;
	    luaL_error(L, "cannot save undo information");
	}
	else if (ml_delete(n, FALSE) == FAIL)
	{
	    curbuf = buf;
	    luaL_error(L, "cannot delete line");
	}
	else {
	    deleted_lines_mark(n, 1L);
	    if (b == curwin->w_buffer) /* fix cursor in current window? */
	    {
		if (curwin->w_cursor.lnum >= n)
		{
		    if (curwin->w_cursor.lnum > n)
		    {
			curwin->w_cursor.lnum -= 1;
			check_cursor_col();
		    }
		    else check_cursor();
		    changed_cline_bef_curs();
		}
		invalidate_botline();
	    }
	}
	curbuf = buf;
    }
    else if (lua_isstring(L, 3)) /* update line */
    {
	buf_T *buf = curbuf;
	curbuf = b;
	if (u_savesub(n) == FAIL)
	{
	    curbuf = buf;
	    luaL_error(L, "cannot save undo information");
	}
	else if (ml_replace(n, luaV_toline(L, 3), TRUE) == FAIL)
	{
	    curbuf = buf;
	    luaL_error(L, "cannot replace line");
	}
	else changed_bytes(n, 0);
	curbuf = buf;
	if (b == curwin->w_buffer)
	    check_cursor_col();
    }
    else
	luaL_error(L, "wrong argument to change line");
    return 0;
}