/* This file contains most movement functions */
MARK
m_updnto(m
, cnt
, cmd
)
MARK m
; /* movement is relative to this mark */
long cnt
; /* a numeric argument */
int cmd
; /* the command character */
DEFAULT(cmd
== 'G' ? nlines
: 1L);
/* move up or down 'cnt' lines */
if (cnt
< 1L || cnt
> nlines
)
msg("Only %ld lines", nlines
);
/* if that left us screwed up, then fail */
if (m
< MARK_FIRST
|| markline(m
) > nlines
)
MARK
m_right(m
, cnt
, key
, prevkey
)
MARK m
; /* movement is relative to this mark */
long cnt
; /* a numeric argument */
int key
; /* movement keystroke */
int prevkey
;/* operator keystroke, or 0 if none */
int idx
; /* index of the new cursor position */
/* If used with an operator, then move 1 less character, since the 'l'
* command includes the character that it moves onto.
/* move to right, if that's OK */
MARK m
; /* movement is relative to this mark */
long cnt
; /* a numeric argument */
/* move to the left, if that's OK */
MARK
m_tocol(m
, cnt
, cmd
)
MARK m
; /* movement is relative to this mark */
long cnt
; /* a numeric argument */
int cmd
; /* either ctrl('X') or '|' */
char *text
; /* text of the line */
int col
; /* column number */
int idx
; /* index into the line */
/* if doing ^X, then adjust for sideways scrolling */
DEFAULT(*o_columns
& 0xff);
/* internally, columns are numbered 0..COLS-1, not 1..COLS */
/* find that column within the line */
for (col
= idx
= 0; col
< cnt
&& *text
; text
++, idx
++)
if (*text
== '\t' && !*o_list
)
else if (UCHAR(*text
) < ' ' || *text
== '\177')
else if (text
[0] == '\\' && text
[1] == 'f' && text
[2] && *o_charattr
)
text
+= 2; /* plus one more as part of for loop */
/* the desired column was past the end of the line, so
* act like the user pressed "$" instead.
return m
| (BLKSIZE
- 1);
m
= (m
& ~(BLKSIZE
- 1)) + idx
;
MARK m
; /* movement is relative to this mark */
long cnt
; /* a numeric argument (ignored) */
/* move to the first non-whitespace character */
while (*scan
== ' ' || *scan
== '\t')
MARK m
; /* movement is relative to this mark */
long cnt
; /* a numeric argument (ignored) */
/* Try to move *EXTREMELY* far to the right. It is fervently hoped
* that other code will convert this to a more reasonable MARK before
* anything tries to actually use it. (See adjmove() in vi.c)
return m
| (BLKSIZE
- 1);
char *ptr
; /* pointer to possible sentence-ender */
/* if not '.', '?', or '!', then it isn't a sentence ender */
if (*ptr
!= '.' && *ptr
!= '?' && *ptr
!= '!')
/* skip any intervening ')', ']', or '"' characters */
} while (*ptr
== ')' || *ptr
== ']' || *ptr
== '"');
/* do we have two spaces or EOL? */
if (!*ptr
|| ptr
[0] == ' ' && ptr
[1] == ' ')
MARK
m_sentence(m
, cnt
, cmd
)
MARK m
; /* movement is relative to this mark */
long cnt
; /* a numeric argument */
int cmd
; /* either '(' or ')' */
/* figure out where the paragraph boundary is */
MARK pp
= m_paragraph(m
, 1L, cmd
=='(' ? '{' : '}');
/* If '(' command, then move back one word, so that if we hit '(' at
* the start of a sentence we don't simply stop at the end of the
* previous sentence and bounce back to the start of this one again.
/* get the current line */
text
= ptext
+ markidx(m
);
/* for each requested sentence... */
/* search forward for one of [.?!] followed by spaces or EOL */
/* move forward, wrap at end of line */
/* move backward, wrap at beginning of line */
} while (!isperiod(text
));
/* construct a mark for this location */
/* move forward to the first word of the next sentence */
m
= m_fword(m
, 1L, 'w', '\0');
/* don't cross the paragraph boundary */
if (pp
&& ((cmd
=='(') ? (m
<pp
) : (m
>pp
)))
MARK
m_paragraph(m
, cnt
, cmd
)
MARK m
; /* movement is relative to this mark */
long cnt
; /* a numeric argument */
int cmd
; /* either '{' or '}' */
char *text
; /* text of the current line */
char *pscn
; /* used to scan thru value of "paragraphs" option */
long l
, ol
; /* current line number, original line number */
int dir
; /* -1 if we're moving up, or 1 if down */
char col0
; /* character to expect in column 0 */
long limit
; /* line where searching must stop */
char *list
; /* either o_sections or o_paragraph */
/* set the direction, based on the command */
SENTENCE(list
= o_paragraphs
);
ss
= m_paragraph(m
, 1L, '<');
SENTENCE(list
= o_paragraphs
);
ss
= m_paragraph(m
, 1L, '>');
SENTENCE(list
= o_sections
);
SENTENCE(list
= o_sections
);
/* for each paragraph that we want to travel through... */
while (l
!= limit
&& cnt
-- > 0)
/* skip blank lines between paragraphs */
while (l
!= limit
&& col0
== *(text
= fetchline(l
)))
/* skip non-blank lines that aren't paragraph separators
if (*text
== '.' && l
!= ol
)
for (pscn
= list
; pscn
[0] && pscn
[1]; pscn
+= 2)
if (pscn
[0] == text
[1] && pscn
[1] == text
[2])
} while (l
!= limit
&& col0
!= *(text
= fetchline(l
)));
debout("m_paragraph() returning %ld.%d\n", markline(m
), markidx(m
));
MARK m
; /* movement is relative to this mark */
long cnt
; /* a numeric argument (normally 0) */
/* if we're given a number, then treat it as a percentage of the file */
/* make sure it is a reasonable number */
msg("can only be from 1%% to 100%%");
/* return the appropriate line number */
l
= (nlines
- 1L) * cnt
/ 100L + 1L;
#endif /* undef NO_EXTENSIONS */
/* get the current line */
text
= ptext
+ markidx(m
);
/* search forward within line for one of "[](){}" */
for (match
= '\0'; !match
&& *text
; text
++)
/* tricky way to recognize 'em in ASCII */
if ((nest
& 0xdf) == ']' || (nest
& 0xdf) == '[')
match
= nest
^ ('[' ^ ']');
else if ((nest
& 0xfe) == '(')
match
= nest
^ ('(' ^ ')');
/* search forward or backward for match */
if (match
== '(' || match
== '[' || match
== '{')
for (count
= 1; count
> 0; )
/* wrap at beginning of line */
for (count
= 1; count
> 0; )
/* wrap at end of line */
/* construct a mark for this place */
MARK
m_tomark(m
, cnt
, key
)
MARK m
; /* movement is relative to this mark */
long cnt
; /* (ignored) */
int key
; /* keystroke - the mark to move to */
/* mark '' is a special case */
if (key
== '\'' || key
== '`')
if (mark
[26] == MARK_UNSET
)
/* if not a valid mark number, don't move */
if (key
< 'a' || key
> 'z')
/* return the selected mark -- may be MARK_UNSET */
msg("mark '%c is unset", key
);