257 lines
		
	
	
		
			4.2 KiB
		
	
	
	
		
			C
		
	
	
		
			Executable File
		
	
	
	
	
			
		
		
	
	
			257 lines
		
	
	
		
			4.2 KiB
		
	
	
	
		
			C
		
	
	
		
			Executable File
		
	
	
	
	
| /* move5.c */
 | |
| 
 | |
| /* Author:
 | |
|  *	Steve Kirkendall
 | |
|  *	14407 SW Teal Blvd. #C
 | |
|  *	Beaverton, OR 97005
 | |
|  *	kirkenda@cs.pdx.edu
 | |
|  */
 | |
| 
 | |
| 
 | |
| /* This file contains the word-oriented movement functions */
 | |
| 
 | |
| #include "config.h"
 | |
| #include "ctype.h"
 | |
| #include "vi.h"
 | |
| 
 | |
| MARK	m_fword(m, cnt, cmd, prevkey)
 | |
| 	MARK	m;	/* movement is relative to this mark */
 | |
| 	long	cnt;	/* a numeric argument */
 | |
| 	int	cmd;	/* either 'w' or 'W' */
 | |
| 	int	prevkey;/* previous command... if 'c' then exclude whitespace */
 | |
| {
 | |
| 	REG long	l;
 | |
| 	REG char	*text;
 | |
| 	REG int		i;
 | |
| 
 | |
| 	DEFAULT(1);
 | |
| 
 | |
| 	l = markline(m);
 | |
| 	pfetch(l);
 | |
| 	text = ptext + markidx(m);
 | |
| 
 | |
| #ifndef CRUNCH
 | |
| 	/* As a special case, "cw" or "cW" on whitespace without a count
 | |
| 	 * treats the single whitespace character under the cursor as a word.
 | |
| 	 */
 | |
| 	if (cnt == 1L && prevkey == 'c' && isspace(*text))
 | |
| 	{
 | |
| 		return m + 1L;
 | |
| 	}
 | |
| #endif
 | |
| 
 | |
| 	while (cnt-- > 0) /* yes, ASSIGNMENT! */
 | |
| 	{
 | |
| 		i = *text++;
 | |
| 
 | |
| 		if (cmd == 'W')
 | |
| 		{
 | |
| 			/* include any non-whitespace */
 | |
| 			while (i && !isspace(i))
 | |
| 			{
 | |
| 				i = *text++;
 | |
| 			}
 | |
| 		}
 | |
| 		else if (isalnum(i) || i == '_')
 | |
| 		{
 | |
| 			/* include an alphanumeric word */
 | |
| 			while (i && isalnum(i))
 | |
| 			{
 | |
| 				i = *text++;
 | |
| 			}
 | |
| 		}
 | |
| 		else
 | |
| 		{
 | |
| 			/* include contiguous punctuation */
 | |
| 			while (i && !isalnum(i) && !isspace(i))
 | |
| 			{
 | |
| 				i = *text++;
 | |
| 			}
 | |
| 		}
 | |
| 
 | |
| 		/* if not part of "cw" or "cW" command... */
 | |
| 		if (prevkey != 'c' || cnt > 0)
 | |
| 		{
 | |
| 			/* include trailing whitespace */
 | |
| 			while (!i || isspace(i))
 | |
| 			{
 | |
| 				/* did we hit the end of this line? */
 | |
| 				if (!i)
 | |
| 				{
 | |
| 					/* "dw" shouldn't delete newline after word */
 | |
| 					if (prevkey && cnt == 0)
 | |
| 					{
 | |
| 						break;
 | |
| 					}
 | |
| 
 | |
| 					/* move to next line, if there is one */
 | |
| 					l++;
 | |
| 					if (l > nlines)
 | |
| 					{
 | |
| 						return MARK_UNSET;
 | |
| 					}
 | |
| 					pfetch(l);
 | |
| 					text = ptext;
 | |
| 				}
 | |
| 
 | |
| 				i = *text++;
 | |
| 			}
 | |
| 		}
 | |
| 		text--;
 | |
| 	}
 | |
| 
 | |
| 	/* if argument to operator, then back off 1 char since "w" and "W"
 | |
| 	 * include the last char in the affected text.
 | |
| 	 */
 | |
| 	if (prevkey)
 | |
| 	{
 | |
| 		text--;
 | |
| 	}
 | |
| 
 | |
| 	/* construct a MARK for this place */
 | |
| 	m = buildmark(text);
 | |
| 	return m;
 | |
| }
 | |
| 
 | |
| 
 | |
| MARK	m_bword(m, cnt, cmd)
 | |
| 	MARK	m;	/* movement is relative to this mark */
 | |
| 	long	cnt;	/* a numeric argument */
 | |
| 	int	cmd;	/* either 'b' or 'B' */
 | |
| {
 | |
| 	REG long	l;
 | |
| 	REG char	*text;
 | |
| 
 | |
| 	DEFAULT(1);
 | |
| 
 | |
| 	l = markline(m);
 | |
| 	pfetch(l);
 | |
| 	text = ptext + markidx(m);
 | |
| 	while (cnt-- > 0) /* yes, ASSIGNMENT! */
 | |
| 	{
 | |
| 		text--;
 | |
| 
 | |
| 		/* include preceding whitespace */
 | |
| 		while (text < ptext || isspace(*text))
 | |
| 		{
 | |
| 			/* did we hit the end of this line? */
 | |
| 			if (text < ptext)
 | |
| 			{
 | |
| 				/* move to preceding line, if there is one */
 | |
| 				l--;
 | |
| 				if (l <= 0)
 | |
| 				{
 | |
| 					return MARK_UNSET;
 | |
| 				}
 | |
| 				pfetch(l);
 | |
| 				text = ptext + plen - 1;
 | |
| 			}
 | |
| 			else
 | |
| 			{
 | |
| 				text--;
 | |
| 			}
 | |
| 		}
 | |
| 
 | |
| 		if (cmd == 'B')
 | |
| 		{
 | |
| 			/* include any non-whitespace */
 | |
| 			while (text >= ptext && !isspace(*text))
 | |
| 			{
 | |
| 				text--;
 | |
| 			}
 | |
| 		}
 | |
| 		else if (isalnum(*text) || *text == '_')
 | |
| 		{
 | |
| 			/* include an alphanumeric word */
 | |
| 			while (text >= ptext && isalnum(*text))
 | |
| 			{
 | |
| 				text--;
 | |
| 			}
 | |
| 		}
 | |
| 		else
 | |
| 		{
 | |
| 			/* include contiguous punctuation */
 | |
| 			while (text >= ptext && !isalnum(*text) && !isspace(*text))
 | |
| 			{
 | |
| 				text--;
 | |
| 			}
 | |
| 		}
 | |
| 		text++;
 | |
| 	}
 | |
| 
 | |
| 	/* construct a MARK for this place */
 | |
| 	m = buildmark(text);
 | |
| 	return m;
 | |
| }
 | |
| 
 | |
| MARK	m_eword(m, cnt, cmd)
 | |
| 	MARK	m;	/* movement is relative to this mark */
 | |
| 	long	cnt;	/* a numeric argument */
 | |
| 	int	cmd;	/* either 'e' or 'E' */
 | |
| {
 | |
| 	REG long	l;
 | |
| 	REG char	*text;
 | |
| 	REG int		i;
 | |
| 
 | |
| 	DEFAULT(1);
 | |
| 
 | |
| 	l = markline(m);
 | |
| 	pfetch(l);
 | |
| 	text = ptext + markidx(m);
 | |
| 	while (cnt-- > 0) /* yes, ASSIGNMENT! */
 | |
| 	{
 | |
| 		if (*text)
 | |
| 			text++;
 | |
| 		i = *text++;
 | |
| 
 | |
| 		/* include preceding whitespace */
 | |
| 		while (!i || isspace(i))
 | |
| 		{
 | |
| 			/* did we hit the end of this line? */
 | |
| 			if (!i)
 | |
| 			{
 | |
| 				/* move to next line, if there is one */
 | |
| 				l++;
 | |
| 				if (l > nlines)
 | |
| 				{
 | |
| 					return MARK_UNSET;
 | |
| 				}
 | |
| 				pfetch(l);
 | |
| 				text = ptext;
 | |
| 			}
 | |
| 
 | |
| 			i = *text++;
 | |
| 		}
 | |
| 
 | |
| 		if (cmd == 'E')
 | |
| 		{
 | |
| 			/* include any non-whitespace */
 | |
| 			while (i && !isspace(i))
 | |
| 			{
 | |
| 				i = *text++;
 | |
| 			}
 | |
| 		}
 | |
| 		else if (isalnum(i) || i == '_')
 | |
| 		{
 | |
| 			/* include an alphanumeric word */
 | |
| 			while (i && isalnum(i))
 | |
| 			{
 | |
| 				i = *text++;
 | |
| 			}
 | |
| 		}
 | |
| 		else
 | |
| 		{
 | |
| 			/* include contiguous punctuation */
 | |
| 			while (i && !isalnum(i) && !isspace(i))
 | |
| 			{
 | |
| 				i = *text++;
 | |
| 			}
 | |
| 		}
 | |
| 		text -= 2;
 | |
| 	}
 | |
| 
 | |
| 	/* construct a MARK for this place */
 | |
| 	m = buildmark(text);
 | |
| 	return m;
 | |
| }
 | 
