Esempio n. 1
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);
  else if (c == '^')                    /* to where Insert mode stopped */
    posp = &(buf->b_last_insert);
  else if (c == '.')                    /* to where last change was made */
    posp = &(buf->b_last_change);
  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']);
  } else if (ASCII_ISUPPER(c) || VIM_ISDIGIT(c))   {    /* named file mark */
    if (VIM_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. 2
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 = VIM_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 ? VIM_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'].lnum = 0;
          else {
            if (digit)
              n = i - '0' + NMARKS;
            else
              n = i - 'A';
            namedfm[n].fmark.mark.lnum = 0;
            vim_free(namedfm[n].fname);
            namedfm[n].fname = NULL;
          }
        }
      } else
        switch (*p) {
        case '"': curbuf->b_last_cursor.lnum = 0; break;
        case '^': curbuf->b_last_insert.lnum = 0; break;
        case '.': curbuf->b_last_change.lnum = 0; 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. 3
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;
}