Пример #1
0
/*
 * Kill backwards by "n" words. Move backwards by the desired number of words,
 * counting the characters. When dot is finally moved to its resting place,
 * fire off the kill command. Bound to "M-Rubout" and to "M-Backspace".
 */
int
delbword(int f, int n)
{
        register long   size;

	if (curbp->b_mode&MDVIEW)	/* don't allow this command if	*/
		return(rdonly());	/* we are in read only mode	*/
        if (n < 0)
                return (FALSE);
        if (backchar(FALSE, 1) == FALSE)
                return (FALSE);
        size = 0L;
        while (n--) {
                while (inword() == FALSE) {
                        if (backchar(FALSE, 1) == FALSE)
                                return (FALSE);
                        ++size;
                }
                while (inword() != FALSE) {
                        if (backchar(FALSE, 1) == FALSE)
                                return (FALSE);
                        ++size;
                }
        }
        if (forwchar(FALSE, 1) == FALSE)
                return (FALSE);
        return (ldelete(size, kinsert));
}
Пример #2
0
/*
 * Move the cursor forward by the specified number of words. As you move,
 * convert any characters to upper case. Error if you try and move beyond the
 * end of the buffer. Bound to "M-U"
 */
int upperword(int f, int n)
{
  int c;

  if (n < 0)
    return (FALSE);
  while (n--)
    {
      while (inword() == FALSE)
	{
	  if (forwchar(FALSE, 1) == FALSE)
	    return (FALSE);
	}
      while (inword() != FALSE)
	{
	  c = lgetc(curwp->w_dotp, curwp->w_doto);
	  if (c >= 'a' && c <= 'z')
	    {
	      c -= 'a' - 'A';
	      lputc(curwp->w_dotp, curwp->w_doto, c);
	      lchange(WFHARD);
	    }
	  if (forwchar(FALSE, 1) == FALSE)
	    return (FALSE);
	}
    }
  return (TRUE);
}
Пример #3
0
/*
 * Move the cursor forward by the specified number of words. All of the motion
 * is done by "forwchar". Error if you try and move beyond the buffer's end.
 */
int
forwword(int f, int n)
{
        if (n < 0)
                return (backword(f, -n));
        while (n--) {
#if	NFWORD
                while (inword() != FALSE) {
                        if (forwchar(FALSE, 1) == FALSE)
                                return (FALSE);
                }
#endif
                while (inword() == FALSE) {
                        if (forwchar(FALSE, 1) == FALSE)
                                return (FALSE);
                }
#if	NFWORD == 0
                while (inword() != FALSE) {
                        if (forwchar(FALSE, 1) == FALSE)
                                return (FALSE);
                }
#endif
        }
	return(TRUE);
}
Пример #4
0
/*
 * Move the cursor forward by the specified number of words. As you move
 * convert characters to lower case. Error if you try and move over the end of
 * the buffer. Bound to "M-L".
 */
int
lowerword(int f, int n)
{
        register int    c;
	CELL            ac;

	ac.a = 0;
	if (curbp->b_mode&MDVIEW)	/* don't allow this command if	*/
		return(rdonly());	/* we are in read only mode	*/
        if (n < 0)
                return (FALSE);
        while (n--) {
                while (inword() == FALSE) {
                        if (forwchar(FALSE, 1) == FALSE)
                                return (FALSE);
                }
                while (inword() != FALSE) {
                        c = lgetc(curwp->w_dotp, curwp->w_doto).c;
                        if (c>='A' && c<='Z') {
                                ac.c (c += 'a'-'A');
                                lputc(curwp->w_dotp, curwp->w_doto, ac);
                                lchange(WFHARD);
                        }
                        if (forwchar(FALSE, 1) == FALSE)
                                return (FALSE);
                }
        }
        return (TRUE);
}
Пример #5
0
/*
 * Kill forward by "n" words. Remember the location of dot. Move forward by
 * the right number of words. Put dot back where it was and issue the kill
 * command for the right number of characters. Bound to "M-D"
 */
int delfword(int f, int n)
{
  LINE *dotp;
  int size, doto;

  if (n < 0)
    return (FALSE);
  dotp = curwp->w_dotp;
  doto = curwp->w_doto;
  size = 0;
  while (n--)
    {
      while (inword() != FALSE)
	{
	  if (forwchar(FALSE, 1) == FALSE)
	    return (FALSE);
	  ++size;
	}
      while (inword() == FALSE)
	{
	  if (forwchar(FALSE, 1) == FALSE)
	    return (FALSE);
	  ++size;
	}
    }
  curwp->w_dotp = dotp;
  curwp->w_doto = doto;
  return (ldelete(size, TRUE));
}
Пример #6
0
/*
 * Kill backwards by "n" words. Move backwards by the desired number of words,
 * counting the characters. When dot is finally moved to its resting place,
 * fire off the kill command. Bound to "M-Rubout" and to "M-Backspace"
 */
int delbword(int f, int n)
{
  int size;

  if (n < 0)
    return (FALSE);
  if (backchar(FALSE, 1) == FALSE)
    return (FALSE);
  size = 0;
  while (n--)
    {
      while (inword() == FALSE)
	{
	  if (backchar(FALSE, 1) == FALSE)
	    return (FALSE);
	  ++size;
	}
      while (inword() != FALSE)
	{
	  if (backchar(FALSE, 1) == FALSE)
	    return (FALSE);
	  ++size;
	}
    }
  if (forwchar(FALSE, 1) == FALSE)
    return (FALSE);
  return (ldelete(size, TRUE));
}
Пример #7
0
Файл: basic.c Проект: aksr/esnc
/* go back to the begining of the current paragraph here we look for a
 * <NL><NL> or <NL><TAB> or <NL><SPACE> combination to delimit the begining of
 * a paragraph
 */
int gotobop (int f, int n)
{
  int suc;			/* success of last backchar */

  if (n < 0)			/* the other way.. */
    return (gotoeop (f, -n));

  while (n-- > 0)
    {				/* for each one asked for */
      /* first scan back until we are in a word */
      suc = backchar (FALSE, 1);
      while (!inword () && suc)
	suc = backchar (FALSE, 1);
      curwp->w_doto = 0;	/* and go to the B-O-Line */

      /* and scan back until we hit a <NL><NL> or <NL><TAB> or a <NL><SPACE> */
      while (lback (curwp->w_dotp) != curbp->b_linep)
	if (llength (curwp->w_dotp) != 0 &&
	    lgetc (curwp->w_dotp, curwp->w_doto) != TAB &&
	    lgetc (curwp->w_dotp, curwp->w_doto) != ' ')
	  curwp->w_dotp = lback (curwp->w_dotp);
	else
	  break;

      /* and then forward until we are in a word */
      suc = forwchar (FALSE, 1);
      while (suc && !inword ())
	suc = forwchar (FALSE, 1);
    }
  curwp->w_flag |= WFMOVE;	/* force screen update */
  return (TRUE);
}
/*
 * ex_abbr -- :abbreviate [key replacement]
 *	Create an abbreviation or display abbreviations.
 *
 * PUBLIC: int ex_abbr __P((SCR *, EXCMD *));
 */
int
ex_abbr(SCR *sp, EXCMD *cmdp)
{
	CHAR_T *p;
	size_t len;

	switch (cmdp->argc) {
	case 0:
		if (seq_dump(sp, SEQ_ABBREV, 0) == 0)
			msgq(sp, M_INFO, "105|No abbreviations to display");
		return (0);
	case 2:
		break;
	default:
		abort();
	}

	/*
	 * Check for illegal characters.
	 *
	 * !!!
	 * Another fun one, historically.  See vi/v_ntext.c:txt_abbrev() for
	 * details.  The bottom line is that all abbreviations have to end
	 * with a "word" character, because it's the transition from word to
	 * non-word characters that triggers the test for an abbreviation.  In
	 * addition, because of the way the test is done, there can't be any
	 * transitions from word to non-word character (or vice-versa) other
	 * than between the next-to-last and last characters of the string,
	 * and there can't be any <blank> characters.  Warn the user.
	 */
	if (!inword(cmdp->argv[0]->bp[cmdp->argv[0]->len - 1])) {
		msgq(sp, M_ERR,
		    "106|Abbreviations must end with a \"word\" character");
			return (1);
	}
	for (p = cmdp->argv[0]->bp; *p != '\0'; ++p)
		if (ISBLANK((UCHAR_T)p[0])) {
			msgq(sp, M_ERR,
			    "107|Abbreviations may not contain tabs or spaces");
			return (1);
		}
	if (cmdp->argv[0]->len > 2)
		for (p = cmdp->argv[0]->bp,
		    len = cmdp->argv[0]->len - 2; len; --len, ++p)
			if (inword(p[0]) != inword(p[1])) {
				msgq(sp, M_ERR,
"108|Abbreviations may not mix word/non-word characters, except at the end");
				return (1);
			}

	if (seq_set(sp, NULL, 0, cmdp->argv[0]->bp, cmdp->argv[0]->len,
	    cmdp->argv[1]->bp, cmdp->argv[1]->len, SEQ_ABBREV, SEQ_USERDEF))
		return (1);

	F_SET(sp->gp, G_ABBREV);
	return (0);
}
Пример #9
0
/* ARGSUSED */
int
delbword(int f, int n)
{
	RSIZE	size;
	int s;

	if ((s = checkdirty(curbp)) != TRUE)
		return (s);
	if (curbp->b_flag & BFREADONLY) {
		dobeep();
		ewprintf("Buffer is read-only");
		return (FALSE);
	}

	if (n < 0)
		return (FALSE);

	/* purge kill buffer */
	if ((lastflag & CFKILL) == 0)
		kdelete();
	thisflag |= CFKILL;
	if (backchar(FFRAND, 1) == FALSE)
		/* hit buffer start */
		return (TRUE);

	/* one deleted */
	size = 1;
	while (n--) {
		while (inword() == FALSE) {
			if (backchar(FFRAND, 1) == FALSE)
				/* hit buffer start */
				goto out;
			++size;
		}
		while (inword() != FALSE) {
			if (backchar(FFRAND, 1) == FALSE)
				/* hit buffer start */
				goto out;
			++size;
		}
	}
	if (forwchar(FFRAND, 1) == FALSE)
		return (FALSE);

	/* undo assumed delete */
	--size;
out:
	return (ldelete(size, KBACK));
}
Пример #10
0
/*
 * v_curword --
 *	Get the word (or non-word) the cursor is on.
 *
 * PUBLIC: int v_curword __P((SCR *));
 */
int
v_curword(SCR *sp)
{
	VI_PRIVATE *vip;
	size_t beg, end, len;
	int moved, state;
	CHAR_T *p;

	if (db_get(sp, sp->lno, DBG_FATAL, &p, &len))
		return (1);

	/*
	 * !!!
	 * Historically, tag commands skipped over any leading whitespace
	 * characters.  Make this true in general when using cursor words.
	 * If movement, getting a cursor word implies moving the cursor to
	 * its beginning.  Refresh now.
	 *
	 * !!!
	 * Find the beginning/end of the keyword.  Keywords are currently
	 * used for cursor-word searching and for tags.  Historical vi
	 * only used the word in a tag search from the cursor to the end
	 * of the word, i.e. if the cursor was on the 'b' in " abc ", the
	 * tag was "bc".  For consistency, we make cursor word searches
	 * follow the same rule.
	 */
	for (moved = 0,
	    beg = sp->cno; beg < len && ISSPACE((UCHAR_T)p[beg]); moved = 1, ++beg);
	if (beg >= len) {
		msgq(sp, M_BERR, "212|Cursor not in a word");
		return (1);
	}
	if (moved) {
		sp->cno = beg;
		(void)vs_refresh(sp, 0);
	}

	/* Find the end of the word. */
	for (state = inword(p[beg]),
	    end = beg; ++end < len && state == inword(p[end]););

	vip = VIP(sp);
	len = (end - beg);
	BINC_RETW(sp, vip->keyw, vip->klen, len+1);
	MEMMOVEW(vip->keyw, p + beg, len);
	vip->keyw[len] = '\0';				/* XXX */
	return (0);
}
Пример #11
0
/* ARGSUSED */
int
capword(int f, int n)
{
	int	c, s;
	RSIZE	size;

	if ((s = checkdirty(curbp)) != TRUE)
		return (s);
	if (curbp->b_flag & BFREADONLY) {
		dobeep();
		ewprintf("Buffer is read-only");
		return (FALSE);
	}

	if (n < 0)
		return (FALSE);
	while (n--) {
		while (inword() == FALSE) {
			if (forwchar(FFRAND, 1) == FALSE)
				return (TRUE);
		}
		size = countfword();
		undo_add_change(curwp->w_dotp, curwp->w_doto, size);

		if (inword() != FALSE) {
			c = lgetc(curwp->w_dotp, curwp->w_doto);
			if (ISLOWER(c) != FALSE) {
				c = TOUPPER(c);
				lputc(curwp->w_dotp, curwp->w_doto, c);
				lchange(WFFULL);
			}
			if (forwchar(FFRAND, 1) == FALSE)
				return (TRUE);
			while (inword() != FALSE) {
				c = lgetc(curwp->w_dotp, curwp->w_doto);
				if (ISUPPER(c) != FALSE) {
					c = TOLOWER(c);
					lputc(curwp->w_dotp, curwp->w_doto, c);
					lchange(WFFULL);
				}
				if (forwchar(FFRAND, 1) == FALSE)
					return (TRUE);
			}
		}
	}
	return (TRUE);
}
Пример #12
0
/* ARGSUSED */
int
forwword(int f, int n)
{
	if (n < 0)
		return (backword(f | FFRAND, -n));
	while (n--) {
		while (inword() == FALSE) {
			if (forwchar(FFRAND, 1) == FALSE)
				return (TRUE);
		}
		while (inword() != FALSE) {
			if (forwchar(FFRAND, 1) == FALSE)
				return (TRUE);
		}
	}
	return (TRUE);
}
Пример #13
0
/* ARGSUSED */
int
delfword(int f, int n)
{
	RSIZE		 size;
	struct line	*dotp;
	int		 doto;
	int s;

	if ((s = checkdirty(curbp)) != TRUE)
		return (s);
	if (curbp->b_flag & BFREADONLY) {
		dobeep();
		ewprintf("Buffer is read-only");
		return (FALSE);
	}
	if (n < 0)
		return (FALSE);

	/* purge kill buffer */
	if ((lastflag & CFKILL) == 0)
		kdelete();

	thisflag |= CFKILL;
	dotp = curwp->w_dotp;
	doto = curwp->w_doto;
	size = 0;

	while (n--) {
		while (inword() == FALSE) {
			if (forwchar(FFRAND, 1) == FALSE)
				/* hit the end of the buffer */
				goto out;
			++size;
		}
		while (inword() != FALSE) {
			if (forwchar(FFRAND, 1) == FALSE)
				/* hit the end of the buffer */
				goto out;
			++size;
		}
	}
out:
	curwp->w_dotp = dotp;
	curwp->w_doto = doto;
	return (ldelete(size, KFORW));
}
Пример #14
0
/*
 * v_searchw -- [count]^A
 *	Search for the word under the cursor.
 *
 * PUBLIC: int v_searchw __P((SCR *, VICMD *));
 */
int
v_searchw(SCR *sp, VICMD *vp)
{
	size_t blen, len;
	int rval;
	CHAR_T *bp, *p;

	/* An upper bound for the SIZE of the RE under construction. */
	len = VIP(sp)->klen + MAX(RE_WSTART_LEN, 1)
	    + MAX(RE_WSTOP_LEN, RE_NWSTOP_LEN);
	GET_SPACE_RETW(sp, bp, blen, len);
	p = bp;

	/* Only the first character can be non-word, see v_curword. */
	if (inword(VIP(sp)->keyw[0])) {
		MEMCPY(p, RE_WSTART, RE_WSTART_LEN);
		p += RE_WSTART_LEN;
	} else if (is_special(VIP(sp)->keyw[0])) {
		MEMCPY(p, L("\\"), 1);
		p += 1;
	}

	MEMCPY(p, VIP(sp)->keyw, VIP(sp)->klen);
	p += VIP(sp)->klen;

	if (inword(p[-1])) {
		MEMCPY(p, RE_WSTOP, RE_WSTOP_LEN);
		p += RE_WSTOP_LEN;
	} else {
		/*
		 * The keyword is a single non-word character.
		 * We want it to stay the same when typing ^A several times
		 * in a row, just the way the other cases behave.
		 */
		MEMCPY(p, RE_NWSTOP, RE_NWSTOP_LEN);
		p += RE_NWSTOP_LEN;
	}

	len = p - bp;
	rval = v_search(sp, vp, bp, len, SEARCH_SET, FORWARD);

	FREE_SPACEW(sp, bp, blen);
	return (rval);
}
Пример #15
0
/*
 * Move the cursor backward by "n" words. All of the details of motion are
 * performed by the "backchar" and "forwchar" routines. Error if you try to
 * move beyond the buffers.
 */
int
backword(int f, int n)
{
        if (n < 0)
                return (forwword(f, -n));
        if (backchar_no_header_editor(FALSE, 1) == FALSE)
                return (FALSE);
        while (n--) {
                while (inword() == FALSE) {
                        if (backchar_no_header_editor(FALSE, 1) == FALSE)
                                return (FALSE);
                }
                while (inword() != FALSE) {
                        if (backchar_no_header_editor(FALSE, 1) == FALSE)
                                return (FALSE);
                }
        }
        return (forwchar(FALSE, 1));
}
Пример #16
0
/*
 * Kill forward by "n" words. Remember the location of dot. Move forward by
 * the right number of words. Put dot back where it was and issue the kill
 * command for the right number of characters. Bound to "M-D".
 */
int
delfword(int f, int n)
{
        register long   size;
        register LINE   *dotp;
        register int    doto;

	if (curbp->b_mode&MDVIEW)	/* don't allow this command if	*/
		return(rdonly());	/* we are in read only mode	*/
        if (n < 0)
                return (FALSE);
        dotp = curwp->w_dotp;
        doto = curwp->w_doto;
        size = 0L;
        while (n--) {
#if	NFWORD
		while (inword() != FALSE) {
			if (forwchar(FALSE,1) == FALSE)
				return(FALSE);
			++size;
		}
#endif
                while (inword() == FALSE) {
                        if (forwchar(FALSE, 1) == FALSE)
                                return (FALSE);
                        ++size;
                }
#if	NFWORD == 0
                while (inword() != FALSE) {
                        if (forwchar(FALSE, 1) == FALSE)
                                return (FALSE);
                        ++size;
                }
#endif
        }
        curwp->w_dotp = dotp;
        curwp->w_doto = doto;
        return (ldelete(size, kinsert));
}
Пример #17
0
/*
 * v_searchw -- [count]^A
 *	Search for the word under the cursor.
 *
 * PUBLIC: int v_searchw __P((SCR *, VICMD *));
 */
int
v_searchw(SCR *sp, VICMD *vp)
{
	size_t blen, len;
	int rval;
	CHAR_T *bp, *p;

	len = VIP(sp)->klen + MAX(RE_WSTART_LEN, 1)
	    + MAX(RE_WSTOP_LEN, RE_NWSTOP_LEN);

	GET_SPACE_RETW(sp, bp, blen, len);
	p = bp;

	/* Only the first character can be non-word, see v_curword. */
	if (inword(VIP(sp)->keyw[0]))
		p = MEMPCPY(p, RE_WSTART, RE_WSTART_LEN);
	else if (is_especial(VIP(sp)->keyw[0]))
		p = MEMPCPY(p, L("\\"), 1);

	p = MEMPCPY(p, VIP(sp)->keyw, VIP(sp)->klen);

	if (inword(p[-1]))
		p = MEMPCPY(p, RE_WSTOP, RE_WSTOP_LEN);
	else
		/*
		 * The keyword is a single non-word character.
		 * We want it to stay the same when typing ^A several times
		 * in a row, just the way the other cases behave.
		 */
		p = MEMPCPY(p, RE_NWSTOP, RE_NWSTOP_LEN);

	len = p - bp;
	rval = v_search(sp, vp, bp, len, SEARCH_SET | SEARCH_EXTEND, FORWARD);

	FREE_SPACEW(sp, bp, blen);
	return (rval);
}
Пример #18
0
/* ARGSUSED */
int
gotobop(int f, int n)
{
	/* the other way... */
	if (n < 0)
		return (gotoeop(f, -n));

	while (n-- > 0) {
		/* first scan back until we are in a word */
		while (backchar(FFRAND, 1) && inword() == 0);

		/* and go to the B-O-Line */
		curwp->w_doto = 0;

		/*
		 * and scan back until we hit a <NL><SP> <NL><TAB> or
		 * <NL><NL>
		 */
		while (lback(curwp->w_dotp) != curbp->b_headp)
			if (llength(lback(curwp->w_dotp)) &&
			    lgetc(curwp->w_dotp, 0) != ' ' &&
			    lgetc(curwp->w_dotp, 0) != '.' &&
			    lgetc(curwp->w_dotp, 0) != '\t')
				curwp->w_dotp = lback(curwp->w_dotp);
			else {
				if (llength(lback(curwp->w_dotp)) &&
				    lgetc(curwp->w_dotp, 0) == '.') {
					curwp->w_dotp = lforw(curwp->w_dotp);
					if (curwp->w_dotp == curbp->b_headp) {
						/*
						 * beyond end of buffer,
						 * cleanup time
						 */
						curwp->w_dotp =
						    lback(curwp->w_dotp);
						curwp->w_doto =
						    llength(curwp->w_dotp);
					}
				}
				break;
			}
	}
	/* force screen update */
	curwp->w_rflag |= WFMOVE;
	return (TRUE);
}
Пример #19
0
/*
 * Count characters in word, from current position
 */
RSIZE
countfword()
{
	RSIZE		 size;
	struct line	*dotp;
	int		 doto;

	dotp = curwp->w_dotp;
	doto = curwp->w_doto;
	size = 0;

	while (inword() != FALSE) {
		if (forwchar(FFRAND, 1) == FALSE)
			/* hit the end of the buffer */
			goto out;
		++size;
	}
out:
	curwp->w_dotp = dotp;
	curwp->w_doto = doto;
	return (size);
}
Пример #20
0
/*
 * Go forward to the end of the current paragraph.
 * We look for a <NL><NL> or <NL><TAB> or <NL><SPACE>
 * or <NL>@ or <NL>. (scribe and nroff commands)
 * combination to delimit the begining of a paragraph.
 */
int
gotoeop (f, n, k)
{
  register int c;		/* first character in current line */

  if (n < 0)			/* the other way... */
    return (gotobop (f, -n, KRANDOM));

  while (n-- > 0)
    {				/* for each one asked for */

      /* Find the first word on/after the current line */
      curwp->w_dot.o = 0;
      while (forwchar (FALSE, 1, KRANDOM))
	if (inword ())
	  break;
      curwp->w_dot.o = 0;
      curwp->w_dot.p = lforw (curwp->w_dot.p);

      /* Scan forward until we hit a paragraph delimiter as
       * described above.
       */
      while (curwp->w_dot.p != curbp->b_linep)
	{
	  if (llength (curwp->w_dot.p) == 0)
	    break;
	  c = lgetc (curwp->w_dot.p, 0);
	  if (c == ' ' || c == '\t' || c == '@' || c == '.')
	    break;
	  else
	    curwp->w_dot.p = lforw (curwp->w_dot.p);
	}
    }
  if (curwp->w_dot.p == curbp->b_linep)	/* at end of buffer?    */
    backchar (FALSE, 1, KRANDOM);	/* back up to prev line */
  curwp->w_flag |= WFMOVE;	/* force screen update */
  return (TRUE);
}
Пример #21
0
/*
 * Go back to the begining of the current paragraph.
 * We look for a <NL><NL> or <NL><TAB> or <NL><SPACE>
 * or <NL>@ or <NL>. (scribe and nroff commands)
 * combination to delimit the begining of a paragraph.
 */
int
gotobop (int f, int n, int k)
{
  register int c;		/* first character in current line */
  register LINE *prev;		/* previous line */

  if (n < 0)			/* the other way... */
    return (gotoeop (f, -n, KRANDOM));

  while (n-- > 0)
    {				/* for each one asked for */

      /* first scan back until we are in a word */
      while (backchar (FALSE, 1, KRANDOM))
	if (inword ())
	  break;
      curwp->w_dot.o = 0;	/* and go to the B-O-Line */

      /* and scan back until we hit a paragraph delimiter as
       * described above.
       */
      while ((prev = lback (curwp->w_dot.p)) != curbp->b_linep)
	{
	  if (llength (prev) == 0)
	    break;
	  c = lgetc (curwp->w_dot.p, 0);
	  if (c == ' ' || c == '\t')
	    break;
	  c = lgetc (prev, 0);
	  if (c == '@' || c == '.')
	    break;
	  else
	    curwp->w_dot.p = prev;
	}
    }
  curwp->w_flag |= WFMOVE;	/* force screen update */
  return TRUE;
}
Пример #22
0
/* ARGSUSED */
int
gotoeop(int f, int n)
{
	/* the other way... */
	if (n < 0)
		return (gotobop(f, -n));

	/* for each one asked for */
	while (n-- > 0) {
		/* Find the first word on/after the current line */
		curwp->w_doto = 0;
		while (forwchar(FFRAND, 1) && inword() == 0);

		curwp->w_doto = 0;
		curwp->w_dotp = lforw(curwp->w_dotp);

		/* and scan forword until we hit a <NL><SP> or ... */
		while (curwp->w_dotp != curbp->b_headp) {
			if (llength(curwp->w_dotp) &&
			    lgetc(curwp->w_dotp, 0) != ' ' &&
			    lgetc(curwp->w_dotp, 0) != '.' &&
			    lgetc(curwp->w_dotp, 0) != '\t')
				curwp->w_dotp = lforw(curwp->w_dotp);
			else
				break;
		}
		if (curwp->w_dotp == curbp->b_headp) {
			/* beyond end of buffer, cleanup time */
			curwp->w_dotp = lback(curwp->w_dotp);
			curwp->w_doto = llength(curwp->w_dotp);
			break;
		}
	}
	/* force screen update */
	curwp->w_rflag |= WFMOVE;
	return (TRUE);
}
Пример #23
0
/* set the current selection. Invoked by ioctl() or by kernel code. */
int set_selection(const struct tiocl_selection *sel, struct tty_struct *tty, int user)
{
	int sel_mode, new_sel_start, new_sel_end, spc;
	char *bp, *obp;
	int i, ps, pe;
	unsigned int currcons = fg_console;

	poke_blanked_console();

	{ unsigned short xs, ys, xe, ye;

	  if (user) {
		  if (verify_area(VERIFY_READ, sel, sizeof(*sel)))
		  	return -EFAULT;
		  __get_user(xs, &sel->xs);
		  __get_user(ys, &sel->ys);
		  __get_user(xe, &sel->xe);
		  __get_user(ye, &sel->ye);
		  __get_user(sel_mode, &sel->sel_mode);
	  } else {
		  xs = sel->xs; /* set selection from kernel */
		  ys = sel->ys;
		  xe = sel->xe;
		  ye = sel->ye;
		  sel_mode = sel->sel_mode;
	  }
	  xs--; ys--; xe--; ye--;
	  xs = limit(xs, video_num_columns - 1);
	  ys = limit(ys, video_num_lines - 1);
	  xe = limit(xe, video_num_columns - 1);
	  ye = limit(ye, video_num_lines - 1);
	  ps = ys * video_size_row + (xs << 1);
	  pe = ye * video_size_row + (xe << 1);

	  if (sel_mode == TIOCL_SELCLEAR) {
	      /* useful for screendump without selection highlights */
	      clear_selection();
	      return 0;
	  }

	  if (mouse_reporting() && (sel_mode & TIOCL_SELMOUSEREPORT)) {
	      mouse_report(tty, sel_mode & TIOCL_SELBUTTONMASK, xs, ys);
	      return 0;
	  }
        }

	if (ps > pe)	/* make sel_start <= sel_end */
	{
		int tmp = ps;
		ps = pe;
		pe = tmp;
	}

	if (sel_cons != fg_console) {
		clear_selection();
		sel_cons = fg_console;
	}

	switch (sel_mode)
	{
		case TIOCL_SELCHAR:	/* character-by-character selection */
			new_sel_start = ps;
			new_sel_end = pe;
			break;
		case TIOCL_SELWORD:	/* word-by-word selection */
			spc = isspace(sel_pos(ps));
			for (new_sel_start = ps; ; ps -= 2)
			{
				if ((spc && !isspace(sel_pos(ps))) ||
				    (!spc && !inword(sel_pos(ps))))
					break;
				new_sel_start = ps;
				if (!(ps % video_size_row))
					break;
			}
			spc = isspace(sel_pos(pe));
			for (new_sel_end = pe; ; pe += 2)
			{
				if ((spc && !isspace(sel_pos(pe))) ||
				    (!spc && !inword(sel_pos(pe))))
					break;
				new_sel_end = pe;
				if (!((pe + 2) % video_size_row))
					break;
			}
			break;
		case TIOCL_SELLINE:	/* line-by-line selection */
			new_sel_start = ps - ps % video_size_row;
			new_sel_end = pe + video_size_row
				    - pe % video_size_row - 2;
			break;
		case TIOCL_SELPOINTER:
			highlight_pointer(pe);
			return 0;
		default:
			return -EINVAL;
	}

	/* remove the pointer */
	highlight_pointer(-1);

	/* select to end of line if on trailing space */
	if (new_sel_end > new_sel_start &&
		!atedge(new_sel_end, video_size_row) &&
		isspace(sel_pos(new_sel_end))) {
		for (pe = new_sel_end + 2; ; pe += 2)
			if (!isspace(sel_pos(pe)) ||
			    atedge(pe, video_size_row))
				break;
		if (isspace(sel_pos(pe)))
			new_sel_end = pe;
	}
	if (sel_start == -1)	/* no current selection */
		highlight(new_sel_start, new_sel_end);
	else if (new_sel_start == sel_start)
	{
		if (new_sel_end == sel_end)	/* no action required */
			return 0;
		else if (new_sel_end > sel_end)	/* extend to right */
			highlight(sel_end + 2, new_sel_end);
		else				/* contract from right */
			highlight(new_sel_end + 2, sel_end);
	}
	else if (new_sel_end == sel_end)
	{
		if (new_sel_start < sel_start)	/* extend to left */
			highlight(new_sel_start, sel_start - 2);
		else				/* contract from left */
			highlight(sel_start, new_sel_start - 2);
	}
	else	/* some other case; start selection from scratch */
	{
		clear_selection();
		highlight(new_sel_start, new_sel_end);
	}
	sel_start = new_sel_start;
	sel_end = new_sel_end;

	/* Allocate a new buffer before freeing the old one ... */
	bp = kmalloc((sel_end-sel_start)/2+1, GFP_KERNEL);
	if (!bp) {
		printk(KERN_WARNING "selection: kmalloc() failed\n");
		clear_selection();
		return -ENOMEM;
	}
	if (sel_buffer)
		kfree(sel_buffer);
	sel_buffer = bp;

	obp = bp;
	for (i = sel_start; i <= sel_end; i += 2) {
		*bp = sel_pos(i);
		if (!isspace(*bp++))
			obp = bp;
		if (! ((i + 2) % video_size_row)) {
			/* strip trailing blanks from line and add newline,
			   unless non-space at end of line. */
			if (obp != bp) {
				bp = obp;
				*bp++ = '\r';
			}
			obp = bp;
		}
	}
	sel_buffer_lth = bp - sel_buffer;
	return 0;
}
Пример #24
0
/*
 * bword --
 *	Move backward by words.
 */
static int
bword(SCR *sp, VICMD *vp, enum which type)
{
	enum { INWORD, NOTWORD } state;
	VCS cs;
	u_long cnt;
	int nmw, omw;

	cnt = F_ISSET(vp, VC_C1SET) ? vp->count : 1;
	cs.cs_lno = vp->m_start.lno;
	cs.cs_cno = vp->m_start.cno;
	if (cs_init(sp, &cs))
		return (1);

	/*
	 * !!!
	 * If in whitespace, or the previous character is whitespace, move
	 * past it.  (This doesn't count as a word move.)  Stay at the
	 * character before the current one, it sets word "state" for the
	 * 'b' command.
	 */
	if (cs.cs_flags == 0 && !ISBLANK2(cs.cs_ch)) {
		if (cs_prev(sp, &cs))
			return (1);
		if (cs.cs_flags == 0 && !ISBLANK2(cs.cs_ch))
			goto start;
	}
	if (cs_bblank(sp, &cs))
		return (1);

	/*
	 * Cyclically move to the beginning of the previous word -- this
	 * involves skipping over word characters and then any trailing
	 * non-word characters.  Note, for the 'b' command, the definition
	 * of a word keeps switching.
	 */
start:	if (type == BIGWORD)
		while (cnt--) {
			nmw = ISMULTIWIDTH(sp, cs.cs_ch);
			for (;;) {
				omw = nmw;
				if (cs_prev(sp, &cs))
					return (1);
				if (cs.cs_flags == CS_SOF)
					goto ret;
				if (cs.cs_flags != 0 || ISBLANK2(cs.cs_ch) ||
				    (nmw = ISMULTIWIDTH(sp, cs.cs_ch)) != omw)
					break;
			}
			/*
			 * When we reach the end of the word before the last
			 * word, we're done.  If we changed state, move forward
			 * one to the end of the next word.
			 */
			if (cnt == 0) {
				if (cs.cs_flags == 0 && cs_next(sp, &cs))
					return (1);
				break;
			}

			/* Eat whitespace characters. */
			if (nmw == omw && cs_bblank(sp, &cs))
				return (1);
			if (cs.cs_flags == CS_SOF)
				goto ret;
		}
	else
		while (cnt--) {
			state = cs.cs_flags == 0 &&
			    inword(cs.cs_ch) ? INWORD : NOTWORD;
			nmw = ISMULTIWIDTH(sp, cs.cs_ch);
			for (;;) {
				omw = nmw;
				if (cs_prev(sp, &cs))
					return (1);
				if (cs.cs_flags == CS_SOF)
					goto ret;
				if (cs.cs_flags != 0 || ISBLANK2(cs.cs_ch) ||
				    (nmw = ISMULTIWIDTH(sp, cs.cs_ch)) != omw)
					break;
				if (state == INWORD) {
					if (!inword(cs.cs_ch))
						break;
				} else
					if (inword(cs.cs_ch))
						break;
			}
			/* See comment above. */
			if (cnt == 0) {
				if (cs.cs_flags == 0 && cs_next(sp, &cs))
					return (1);
				break;
			}

			/* Eat whitespace characters. */
			if (cs.cs_flags != 0 || ISBLANK2(cs.cs_ch))
				if (cs_bblank(sp, &cs))
					return (1);
			if (cs.cs_flags == CS_SOF)
				goto ret;
		}

	/* If we didn't move, we must be at SOF. */
ret:	if (cs.cs_lno == vp->m_start.lno && cs.cs_cno == vp->m_start.cno) {
		v_sof(sp, &vp->m_start);
		return (1);
	}

	/* Set the end of the range for motion commands. */
	vp->m_stop.lno = cs.cs_lno;
	vp->m_stop.cno = cs.cs_cno;

	/*
	 * All commands move to the end of the range.  Motion commands
	 * adjust the starting point to the character before the current
	 * one.
	 *
	 * !!!
	 * The historic vi didn't get this right -- the `yb' command yanked
	 * the right stuff and even updated the cursor value, but the cursor
	 * was not actually updated on the screen.
	 */
	vp->m_final = vp->m_stop;
	if (ISMOTION(vp))
		--vp->m_start.cno;
	return (0);
}
Пример #25
0
/*
 * eword --
 *	Move forward to the end of the word.
 */
static int
eword(SCR *sp, VICMD *vp, enum which type)
{
	enum { INWORD, NOTWORD } state;
	VCS cs;
	u_long cnt;
	int nmw, omw;

	cnt = F_ISSET(vp, VC_C1SET) ? vp->count : 1;
	cs.cs_lno = vp->m_start.lno;
	cs.cs_cno = vp->m_start.cno;
	if (cs_init(sp, &cs))
		return (1);

	/*
	 * !!!
	 * If in whitespace, or the next character is whitespace, move past
	 * it.  (This doesn't count as a word move.)  Stay at the character
	 * past the current one, it sets word "state" for the 'e' command.
	 */
	if (cs.cs_flags == 0 && !ISBLANK2(cs.cs_ch)) {
		if (cs_next(sp, &cs))
			return (1);
		if (cs.cs_flags == 0 && !ISBLANK2(cs.cs_ch))
			goto start;
	}
	if (cs_fblank(sp, &cs))
		return (1);

	/*
	 * Cyclically move to the next word -- this involves skipping
	 * over word characters and then any trailing non-word characters.
	 * Note, for the 'e' command, the definition of a word keeps
	 * switching.
	 */
start:	if (type == BIGWORD)
		while (cnt--) {
			nmw = ISMULTIWIDTH(sp, cs.cs_ch);
			for (;;) {
				omw = nmw;
				if (cs_next(sp, &cs))
					return (1);
				if (cs.cs_flags == CS_EOF)
					goto ret;
				if (cs.cs_flags != 0 || ISBLANK2(cs.cs_ch) ||
				    (nmw = ISMULTIWIDTH(sp, cs.cs_ch)) != omw)
					break;
			}
			/*
			 * When we reach the start of the word after the last
			 * word, we're done.  If we changed state, back up one
			 * to the end of the previous word.
			 */
			if (cnt == 0) {
				if (cs.cs_flags == 0 && cs_prev(sp, &cs))
					return (1);
				break;
			}

			/* Eat whitespace characters. */
			if (nmw == omw && cs_fblank(sp, &cs))
				return (1);
			if (cs.cs_flags == CS_EOF)
				goto ret;
		}
	else
		while (cnt--) {
			state = cs.cs_flags == 0 &&
			    inword(cs.cs_ch) ? INWORD : NOTWORD;
			nmw = ISMULTIWIDTH(sp, cs.cs_ch);
			for (;;) {
				omw = nmw;
				if (cs_next(sp, &cs))
					return (1);
				if (cs.cs_flags == CS_EOF)
					goto ret;
				if (cs.cs_flags != 0 || ISBLANK2(cs.cs_ch) ||
				    (nmw = ISMULTIWIDTH(sp, cs.cs_ch)) != omw)
					break;
				if (state == INWORD) {
					if (!inword(cs.cs_ch))
						break;
				} else
					if (inword(cs.cs_ch))
						break;
			}
			/* See comment above. */
			if (cnt == 0) {
				if (cs.cs_flags == 0 && cs_prev(sp, &cs))
					return (1);
				break;
			}

			/* Eat whitespace characters. */
			if (cs.cs_flags != 0 || ISBLANK2(cs.cs_ch))
				if (cs_fblank(sp, &cs))
					return (1);
			if (cs.cs_flags == CS_EOF)
				goto ret;
		}

	/*
	 * If we didn't move, we must be at EOF.
	 *
	 * !!!
	 * That's okay for motion commands, however.
	 */
ret:	if (!ISMOTION(vp) &&
	    cs.cs_lno == vp->m_start.lno && cs.cs_cno == vp->m_start.cno) {
		v_eof(sp, &vp->m_start);
		return (1);
	}

	/* Set the end of the range for motion commands. */
	vp->m_stop.lno = cs.cs_lno;
	vp->m_stop.cno = cs.cs_cno;

	/*
	 * Non-motion commands move to the end of the range.
	 * Delete and yank stay at the start, ignore others.
	 */
	vp->m_final = ISMOTION(vp) ? vp->m_start : vp->m_stop;
	return (0);
}
Пример #26
0
/*
 * fword --
 *	Move forward by words.
 */
static int
fword(SCR *sp, VICMD *vp, enum which type)
{
	enum { INWORD, NOTWORD } state;
	VCS cs;
	u_long cnt;
	int nmw, omw;

	cnt = F_ISSET(vp, VC_C1SET) ? vp->count : 1;
	cs.cs_lno = vp->m_start.lno;
	cs.cs_cno = vp->m_start.cno;
	if (cs_init(sp, &cs))
		return (1);

	/*
	 * If in white-space:
	 *	If the count is 1, and it's a change command, we're done.
	 *	Else, move to the first non-white-space character, which
	 *	counts as a single word move.  If it's a motion command,
	 *	don't move off the end of the line.
	 */
	if (cs.cs_flags == CS_EMP || (cs.cs_flags == 0 && ISBLANK2(cs.cs_ch))) {
		if (ISMOTION(vp) && cs.cs_flags != CS_EMP && cnt == 1) {
			if (ISCMD(vp->rkp, 'c'))
				return (0);
			if (ISCMD(vp->rkp, 'd') || ISCMD(vp->rkp, 'y')) {
				if (cs_fspace(sp, &cs))
					return (1);
				goto ret;
			}
		}
		if (cs_fblank(sp, &cs))
			return (1);
		--cnt;
	}

	/*
	 * Cyclically move to the next word -- this involves skipping
	 * over word characters and then any trailing non-word characters.
	 * Note, for the 'w' command, the definition of a word keeps
	 * switching.
	 */
	if (type == BIGWORD)
		while (cnt--) {
			nmw = ISMULTIWIDTH(sp, cs.cs_ch);
			for (;;) {
				omw = nmw;
				if (cs_next(sp, &cs))
					return (1);
				if (cs.cs_flags == CS_EOF)
					goto ret;
				if (cs.cs_flags != 0 || ISBLANK2(cs.cs_ch) ||
				    (nmw = ISMULTIWIDTH(sp, cs.cs_ch)) != omw)
					break;
			}
			/*
			 * If a motion command and we're at the end of the
			 * last word, we're done.  Delete and yank eat any
			 * trailing blanks, but we don't move off the end
			 * of the line regardless.
			 */
			if (cnt == 0 && ISMOTION(vp)) {
				if ((ISCMD(vp->rkp, 'd') ||
				    ISCMD(vp->rkp, 'y')) &&
				    cs_fspace(sp, &cs))
					return (1);
				break;
			}

			/* Eat whitespace characters. */
			if (nmw == omw && cs_fblank(sp, &cs))
				return (1);
			if (cs.cs_flags == CS_EOF)
				goto ret;
		}
	else
		while (cnt--) {
			state = cs.cs_flags == 0 &&
			    inword(cs.cs_ch) ? INWORD : NOTWORD;
			nmw = ISMULTIWIDTH(sp, cs.cs_ch);
			for (;;) {
				omw = nmw;
				if (cs_next(sp, &cs))
					return (1);
				if (cs.cs_flags == CS_EOF)
					goto ret;
				if (cs.cs_flags != 0 || ISBLANK2(cs.cs_ch) ||
				    (nmw = ISMULTIWIDTH(sp, cs.cs_ch)) != omw)
					break;
				if (state == INWORD) {
					if (!inword(cs.cs_ch))
						break;
				} else
					if (inword(cs.cs_ch))
						break;
			}
			/* See comment above. */
			if (cnt == 0 && ISMOTION(vp)) {
				if ((ISCMD(vp->rkp, 'd') ||
				    ISCMD(vp->rkp, 'y')) &&
				    cs_fspace(sp, &cs))
					return (1);
				break;
			}

			/* Eat whitespace characters. */
			if (cs.cs_flags != 0 || ISBLANK2(cs.cs_ch))
				if (cs_fblank(sp, &cs))
					return (1);
			if (cs.cs_flags == CS_EOF)
				goto ret;
		}

	/*
	 * If we didn't move, we must be at EOF.
	 *
	 * !!!
	 * That's okay for motion commands, however.
	 */
ret:	if (!ISMOTION(vp) &&
	    cs.cs_lno == vp->m_start.lno && cs.cs_cno == vp->m_start.cno) {
		v_eof(sp, &vp->m_start);
		return (1);
	}

	/* Adjust the end of the range for motion commands. */
	vp->m_stop.lno = cs.cs_lno;
	vp->m_stop.cno = cs.cs_cno;
	if (ISMOTION(vp) && cs.cs_flags == 0)
		--vp->m_stop.cno;

	/*
	 * Non-motion commands move to the end of the range.  Delete
	 * and yank stay at the start, ignore others.
	 */
	vp->m_final = ISMOTION(vp) ? vp->m_start : vp->m_stop;
	return (0);
}
Пример #27
0
/*
 * Fill the current paragraph according to the current fill column.
 */
int
fillpara (int f, int n, int k)
{
  register int c;		/* current char durring scan    */
  register int wordlen;		/* length of current word       */
  register int clength;		/* position on line during fill */
  register int eopflag;		/* Are we at the End-Of-Paragraph? */
  int firstflag;		/* first word? (needs no space) */
  int newlength;		/* tentative new line length    */
  int eolflag;			/* was at end of line           */
  LINE *eopline;		/* pointer to line just past EOP */
  char wbuf[MAXWORD];		/* buffer for current word      */

  /* Record the pointer to the line just past the
   * end of the paragraph.
   */
  gotoeop (FALSE, 1, KRANDOM);
  eopline = curwp->w_dot.p;
  if (lforw (eopline) == curbp->b_linep)
    eopline = curbp->b_linep;

  /* Move to the begining of the paragraph.
   */
  gotobop (FALSE, 1, KRANDOM);

  /* Skip to the start of the first word in the paragraph,
   * and set our current column position.
   */
  while (!inword ())
    if (forwchar (FALSE, 1, KRANDOM) == FALSE)
      break;
  clength = getcolpos () - 1;
  wordlen = 0;

  /* scan through lines, filling words
   */
  firstflag = TRUE;
  eopflag = FALSE;
  while (!eopflag)
    {
      /* get the next character in the paragraph
       */
      if ((eolflag = (curwp->w_dot.o == llength (curwp->w_dot.p))) == TRUE)
	{
	  c = ' ';
	  if (lforw (curwp->w_dot.p) == eopline)
	    eopflag = TRUE;
	}
      else
	c = lgetc (curwp->w_dot.p, curwp->w_dot.o);

      /* and then delete it
       */
      if (ldelete (1, FALSE) == FALSE)
	return (FALSE);

      /* if not a separator, just add it in
       */
      if (c != ' ' && c != '\t')
	{
	  if (wordlen < MAXWORD - 1)
	    wbuf[wordlen++] = c;
	  else
	    {
	      /* You lose chars beyond MAXWORD if the word
	       * is to long. I'm to lazy to fix it now; it
	       * just silently truncated the word before, so
	       * I get to feel smug.
	       */
	      eprintf ("Word too long!");
	    }
	}
      else if (wordlen)
	{
	  /* calculate tenatitive new length with word added
	   */
	  newlength = clength + 1 + wordlen;

	  /* if at end of line or at doublespace and previous
	   * character was one of '.','?','!' doublespace here.
	   */
	  if ((eolflag || curwp->w_dot.o == llength (curwp->w_dot.p)
	       || (c = lgetc (curwp->w_dot.p, curwp->w_dot.o)) == ' '
	       || c == '\t')
	      && ISEOSP (wbuf[wordlen - 1]) && wordlen < MAXWORD - 1)
	    wbuf[wordlen++] = ' ';

	  /* at a word break with a word waiting
	   */
	  if (newlength <= fillcol)
	    {
	      /* add word to current line */
	      if (!firstflag)
		{
		  linsert (1, ' ', NULLPTR);
		  ++clength;
		}
	      firstflag = FALSE;
	    }
	  else
	    {
	      if (curwp->w_dot.o > 0 &&
		  lgetc (curwp->w_dot.p, curwp->w_dot.o - 1) == ' ')
		{
		  curwp->w_dot.o -= 1;
		  ldelete (1, FALSE);
		}
	      /* start a new line */
	      lnewline ();
	      clength = 0;
	    }

	  /* and add the word in in either case */
	  linsert (wordlen, 0, wbuf);
	  clength += wordlen;
	  wordlen = 0;
	}
    }
  /* and add a last newline for the end of our new paragraph */
  lnewline ();

  /* we realy should wind up where we started, (which is hard to keep
   * track of) but I think the end of the last line is better than the
   * begining of the blank line.
   */
  backchar (FALSE, 1, KRANDOM);
  return (TRUE);
}
Пример #28
0
PASCAL NEAR gotoeop( /* go forword to the end of the current paragraph
			     looking for a member of $paralead or $fmtlead
			     or a blank line to delimit the start of the
			     next paragraph
			     OR A FOLDLINE (MJB: 03-Oct-89),
*/

  int f,
  int n )	/* default Flag & Numeric argument */

{
	register int suc;	/* success of last backchar */
	register int c;		/* current character in scan */
	register char *sp;	/* ptr into character leadin lists */
	LINE *startp;

	if (n < 0)	/* the other way...*/
		return(gotobop(f, -n));

	while (n-- > 0) {	/* for each one asked for */

		/* first scan forward until we are in a word */
		suc = forwchar(FALSE, 1);
		startp = curwp->w_dotp;
		while (!inword() && suc &&
		       ((curwp->w_dotp->l_type == LNORMAL) ||
			(curwp->w_dotp->l_type == LSOEFOLD)))
			suc = forwchar(FALSE, 1);

		/* and go to the B-O-Line */
		curwp->w_doto = 0;

		/* of next line if not at EOF */
		if (suc && ((curwp->w_dotp->l_type == LNORMAL) ||
			    (curwp->w_dotp->l_type == LSOEFOLD))) /* of next line if not at EOF or fold */
			curwp->w_dotp = lforw(curwp->w_dotp);

		/* scan forward */
		while (curwp->w_dotp != curbp->b_linep) {

			/* at blank line */
			if (llength(curwp->w_dotp) == 0 ||
			    curwp->w_dotp->l_type != LNORMAL ||
			    lgetc(curwp->w_dotp, curwp->w_doto) == TAB ||
			    lgetc(curwp->w_dotp, curwp->w_doto) == ' ')
				break;

			/* current line start with member of $paralead? */
			c = lgetc(curwp->w_dotp, 0);
			sp = paralead;
			while (*sp) {
				if (c == *sp)
					break;
				++sp;
			}
			if (c == *sp)
				break;			

			/* current line start with member of $fmtlead? */
			c = lgetc(curwp->w_dotp, 0);
			sp = fmtlead;
			while (*sp) {
				if (c == *sp)
					break;
				++sp;
			}
			if (c == *sp)
				break;			

			/* forward one line... */
			curwp->w_dotp = lforw(curwp->w_dotp);
		}

		/* and then backward until we are in a word */
		/* don't do anything if fold line, just goto the EOL */
		if (curwp->w_dotp->l_type == LNORMAL) {
			suc = backchar(FALSE, 1);
			while (suc && !inword())
				suc = backchar(FALSE, 1);
		}
		/* goto end of line, unless LSOFOLD beyond start point */
		if ((curwp->w_dotp->l_type == LSOFOLD) &&
		    (curwp->w_dotp != startp))
			curwp->w_doto = 0;
		else
			curwp->w_doto = llength(curwp->w_dotp);	/* and to the EOL */
	}
	curwp->w_flag |= WFMOVE;	/* force screen update */
	return(TRUE);
}
Пример #29
0
/* set the current selection. Invoked by ioctl() or by kernel code. */
int set_selection(const unsigned long arg, struct tty_struct *tty, int user)
{
	int sel_mode, new_sel_start, new_sel_end, spc;
	char *bp, *obp;
	int i, ps, pe;

	do_unblank_screen();

	{ unsigned short *args, xs, ys, xe, ye;

	  args = (unsigned short *)(arg + 1);
	  if (user) {
	  	  int err;
		  err = verify_area(VERIFY_READ, args, sizeof(short) * 5);
		  if (err)
		  	return err;
		  xs = get_user(args++) - 1;
		  ys = get_user(args++) - 1;
		  xe = get_user(args++) - 1;
		  ye = get_user(args++) - 1;
		  sel_mode = get_user(args);
	  } else {
		  xs = *(args++) - 1; /* set selection from kernel */
		  ys = *(args++) - 1;
		  xe = *(args++) - 1;
		  ye = *(args++) - 1;
		  sel_mode = *args;
	  }
	  xs = limit(xs, video_num_columns - 1);
	  ys = limit(ys, video_num_lines - 1);
	  xe = limit(xe, video_num_columns - 1);
	  ye = limit(ye, video_num_lines - 1);
	  ps = ys * video_size_row + (xs << 1);
	  pe = ye * video_size_row + (xe << 1);

	  if (sel_mode == 4) {
	      /* useful for screendump without selection highlights */
	      clear_selection();
	      return 0;
	  }

	  if (mouse_reporting() && (sel_mode & 16)) {
	      mouse_report(tty, sel_mode & 15, xs, ys);
	      return 0;
	  }
        }

	if (ps > pe)	/* make sel_start <= sel_end */
	{
		int tmp = ps;
		ps = pe;
		pe = tmp;
	}

	if (sel_cons != fg_console) {
		clear_selection();
		sel_cons = fg_console;
	}

	switch (sel_mode)
	{
		case 0:	/* character-by-character selection */
			new_sel_start = ps;
			new_sel_end = pe;
			break;
		case 1:	/* word-by-word selection */
			spc = isspace(sel_pos(ps));
			for (new_sel_start = ps; ; ps -= 2)
			{
				if ((spc && !isspace(sel_pos(ps))) ||
				    (!spc && !inword(sel_pos(ps))))
					break;
				new_sel_start = ps;
				if (!(ps % video_size_row))
					break;
			}
			spc = isspace(sel_pos(pe));
			for (new_sel_end = pe; ; pe += 2)
			{
				if ((spc && !isspace(sel_pos(pe))) ||
				    (!spc && !inword(sel_pos(pe))))
					break;
				new_sel_end = pe;
				if (!((pe + 2) % video_size_row))
					break;
			}
			break;
		case 2:	/* line-by-line selection */
			new_sel_start = ps - ps % video_size_row;
			new_sel_end = pe + video_size_row
				    - pe % video_size_row - 2;
			break;
		case 3:
			highlight_pointer(pe);
			return 0;
		default:
			return -EINVAL;
	}

	/* remove the pointer */
	highlight_pointer(-1);

	/* select to end of line if on trailing space */
	if (new_sel_end > new_sel_start &&
		!atedge(new_sel_end) && isspace(sel_pos(new_sel_end))) {
		for (pe = new_sel_end + 2; ; pe += 2)
			if (!isspace(sel_pos(pe)) || atedge(pe))
				break;
		if (isspace(sel_pos(pe)))
			new_sel_end = pe;
	}
	if (sel_start == -1)	/* no current selection */
		highlight(new_sel_start, new_sel_end);
	else if (new_sel_start == sel_start)
	{
		if (new_sel_end == sel_end)	/* no action required */
			return 0;
		else if (new_sel_end > sel_end)	/* extend to right */
			highlight(sel_end + 2, new_sel_end);
		else				/* contract from right */
			highlight(new_sel_end + 2, sel_end);
	}
	else if (new_sel_end == sel_end)
	{
		if (new_sel_start < sel_start)	/* extend to left */
			highlight(new_sel_start, sel_start - 2);
		else				/* contract from left */
			highlight(sel_start, new_sel_start - 2);
	}
	else	/* some other case; start selection from scratch */
	{
		clear_selection();
		highlight(new_sel_start, new_sel_end);
	}
	sel_start = new_sel_start;
	sel_end = new_sel_end;

	if (sel_buffer)
		kfree(sel_buffer);
	sel_buffer = kmalloc((sel_end-sel_start)/2+1, GFP_KERNEL);
	if (!sel_buffer) {
		printk("selection: kmalloc() failed\n");
		clear_selection();
		return -ENOMEM;
	}

	obp = bp = sel_buffer;
	for (i = sel_start; i <= sel_end; i += 2) {
		*bp = sel_pos(i);
		if (!isspace(*bp++))
			obp = bp;
		if (! ((i + 2) % video_size_row)) {
			/* strip trailing blanks from line and add newline,
			   unless non-space at end of line. */
			if (obp != bp) {
				bp = obp;
				*bp++ = '\r';
			}
			obp = bp;
		}
	}
	sel_buffer_lth = bp - sel_buffer;
	return 0;
}
Пример #30
0
/* ARGSUSED */
int
fillpara(int f, int n)
{
    int	 c;		/* current char during scan		*/
    int	 wordlen;	/* length of current word		*/
    int	 clength;	/* position on line during fill		*/
    int	 i;		/* index during word copy		*/
    int	 eopflag;	/* Are we at the End-Of-Paragraph?	*/
    int	 firstflag;	/* first word? (needs no space)		*/
    int	 newlength;	/* tentative new line length		*/
    int	 eolflag;	/* was at end of line			*/
    int	 retval;	/* return value				*/
    struct line	*eopline;	/* pointer to line just past EOP	*/
    char	 wbuf[MAXWORD];	/* buffer for current word		*/

    if (n == 0)
        return (TRUE);

    undo_boundary_enable(FFRAND, 0);

    /* record the pointer to the line just past the EOP */
    (void)gotoeop(FFRAND, 1);
    if (curwp->w_doto != 0) {
        /* paragraph ends at end of buffer */
        (void)lnewline();
        eopline = lforw(curwp->w_dotp);
    } else
        eopline = curwp->w_dotp;

    /* and back top the beginning of the paragraph */
    (void)gotobop(FFRAND, 1);

    /* initialize various info */
    while (inword() == 0 && forwchar(FFRAND, 1));

    clength = curwp->w_doto;
    wordlen = 0;

    /* scan through lines, filling words */
    firstflag = TRUE;
    eopflag = FALSE;
    while (!eopflag) {

        /* get the next character in the paragraph */
        if ((eolflag = (curwp->w_doto == llength(curwp->w_dotp)))) {
            c = ' ';
            if (lforw(curwp->w_dotp) == eopline)
                eopflag = TRUE;
        } else
            c = lgetc(curwp->w_dotp, curwp->w_doto);

        /* and then delete it */
        if (ldelete((RSIZE) 1, KNONE) == FALSE && !eopflag) {
            retval = FALSE;
            goto cleanup;
        }

        /* if not a separator, just add it in */
        if (c != ' ' && c != '\t') {
            if (wordlen < MAXWORD - 1)
                wbuf[wordlen++] = c;
            else {
                /*
                 * You lose chars beyond MAXWORD if the word
                 * is too long. I'm too lazy to fix it now; it
                 * just silently truncated the word before,
                 * so I get to feel smug.
                 */
                ewprintf("Word too long!");
            }
        } else if (wordlen) {

            /* calculate tentative new length with word added */
            newlength = clength + 1 + wordlen;

            /*
             * if at end of line or at doublespace and previous
             * character was one of '.','?','!' doublespace here.
             * behave the same way if a ')' is preceded by a
             * [.?!] and followed by a doublespace.
             */
            if (dblspace && (!eopflag && ((eolflag ||
                                           curwp->w_doto == llength(curwp->w_dotp) ||
                                           (c = lgetc(curwp->w_dotp, curwp->w_doto)) == ' '
                                           || c == '\t') && (ISEOSP(wbuf[wordlen - 1]) ||
                                                   (wbuf[wordlen - 1] == ')' && wordlen >= 2 &&
                                                    ISEOSP(wbuf[wordlen - 2])))) &&
                             wordlen < MAXWORD - 1))
                wbuf[wordlen++] = ' ';

            /* at a word break with a word waiting */
            if (newlength <= fillcol) {
                /* add word to current line */
                if (!firstflag) {
                    (void)linsert(1, ' ');
                    ++clength;
                }
                firstflag = FALSE;
            } else {
                if (curwp->w_doto > 0 &&
                        lgetc(curwp->w_dotp, curwp->w_doto - 1) == ' ') {
                    curwp->w_doto -= 1;
                    (void)ldelete((RSIZE) 1, KNONE);
                }
                /* start a new line */
                (void)lnewline();
                clength = 0;
            }

            /* and add the word in in either case */
            for (i = 0; i < wordlen; i++) {
                (void)linsert(1, wbuf[i]);
                ++clength;
            }
            wordlen = 0;
        }
    }
    /* and add a last newline for the end of our new paragraph */
    (void)lnewline();

    /*
     * We really should wind up where we started, (which is hard to keep
     * track of) but I think the end of the last line is better than the
     * beginning of the blank line.
     */
    (void)backchar(FFRAND, 1);
    retval = TRUE;
cleanup:
    undo_boundary_enable(FFRAND, 1);
    return (retval);
}