16 /* This array describes what each key does */
17 #define NO_FUNC (MARK (*)())0
21 #define CURSOR_CNT_KEY 2
22 #define CURSOR_MOVED 3
29 #define C_C_K_REP1 (CURSOR_CNT_KEY | 0x10)
30 #define C_C_K_CUT (CURSOR_CNT_KEY | 0x20)
31 #define C_C_K_MARK (CURSOR_CNT_KEY | 0x30)
32 #define C_C_K_CHAR (CURSOR_CNT_KEY | 0x40)
34 static int keymodes
[] = {0, WHEN_REP1
, WHEN_CUT
, WHEN_MARK
, WHEN_CHAR
};
35 # define KEYMODE(args) (keymodes[(args) >> 4])
37 # define KEYMODE(args) 0
42 MARK (*func
)(); /* the function to run */
43 uchar args
; /* description of the args needed */
47 uchar flags
; /* other stuff */
52 /* NUL not defined */ {NO_FUNC
, NO_ARGS
, NO_FLAGS
},
54 /* ^A find cursor word */ {m_wsrch
, KEYWORD
, MVMT
|NREL
|VIZ
},
56 /* ^A not defined */ {NO_FUNC
, NO_ARGS
, NO_FLAGS
},
58 /* ^B page backward */ {m_scroll
, CURSOR
, FRNT
|VIZ
},
59 /* ^C not defined */ {NO_FUNC
, NO_ARGS
, NO_FLAGS
},
60 /* ^D scroll dn 1/2page*/ {m_scroll
, CURSOR
, NCOL
|VIZ
},
61 /* ^E scroll up */ {m_scroll
, CURSOR
, NCOL
|VIZ
},
62 /* ^F page forward */ {m_scroll
, CURSOR
, FRNT
|VIZ
},
63 /* ^G show file status */ {v_status
, NO_ARGS
, NO_FLAGS
},
64 /* ^H move left, like h*/ {m_left
, CURSOR
, MVMT
|VIZ
},
65 /* ^I not defined */ {NO_FUNC
, NO_ARGS
, NO_FLAGS
},
66 /* ^J move down */ {m_updnto
, CURSOR
, MVMT
|LNMD
|VIZ
|INCL
},
67 /* ^K not defined */ {NO_FUNC
, NO_ARGS
, NO_FLAGS
},
68 /* ^L redraw screen */ {v_redraw
, NO_ARGS
, NO_FLAGS
|VIZ
},
69 /* ^M mv front next ln */ {m_updnto
, CURSOR
, MVMT
|FRNT
|LNMD
|VIZ
|INCL
},
70 /* ^N move down */ {m_updnto
, CURSOR
, MVMT
|LNMD
|VIZ
|INCL
|NCOL
},
71 /* ^O not defined */ {NO_FUNC
, NO_ARGS
, NO_FLAGS
},
72 /* ^P move up */ {m_updnto
, CURSOR
, MVMT
|LNMD
|VIZ
|INCL
|NCOL
},
73 /* ^Q not defined */ {NO_FUNC
, NO_ARGS
, NO_FLAGS
},
74 /* ^R redraw screen */ {v_redraw
, NO_ARGS
, NO_FLAGS
|VIZ
},
75 /* ^S not defined */ {NO_FUNC
, NO_ARGS
, NO_FLAGS
},
76 /* ^T not defined */ {NO_FUNC
, NO_ARGS
, NO_FLAGS
},
77 /* ^U scroll up 1/2page*/ {m_scroll
, CURSOR
, NCOL
|VIZ
},
78 /* ^V not defined */ {NO_FUNC
, NO_ARGS
, NO_FLAGS
},
79 /* ^W not defined */ {NO_FUNC
, NO_ARGS
, NO_FLAGS
},
80 /* ^X move to phys col */ {m_tocol
, CURSOR
, MVMT
|NREL
|VIZ
},
81 /* ^Y scroll down */ {m_scroll
, CURSOR
, NCOL
|VIZ
},
83 /* ^Z suspend elvis */ {v_suspend
, NO_ARGS
, NO_FLAGS
},
85 /* ^Z not defined */ {NO_FUNC
, NO_ARGS
, NO_FLAGS
},
87 /* ESC not defined */ {NO_FUNC
, NO_ARGS
, NO_FLAGS
},
88 /* ^\ not defined */ {NO_FUNC
, NO_ARGS
, NO_FLAGS
},
89 /* ^] keyword is tag */ {v_tag
, KEYWORD
, NO_FLAGS
},
90 /* ^^ previous file */ {v_switch
, CURSOR
, NO_FLAGS
},
91 /* ^_ not defined */ {NO_FUNC
, NO_ARGS
, NO_FLAGS
},
92 /* SPC move right,like l*/ {m_right
, CURSOR
, MVMT
|INCL
|VIZ
},
93 /* ! run thru filter */ {v_filter
, CURSOR_MOVED
, FRNT
|LNMD
|INCL
|VIZ
},
94 /* " select cut buffer*/ {v_selcut
, C_C_K_CUT
, PTMV
|VIZ
},
96 /* # increment number */ {v_increment
, KEYWORD
, SDOT
},
98 /* # not defined */ {NO_FUNC
, NO_ARGS
, NO_FLAGS
},
100 /* $ move to rear */ {m_rear
, CURSOR
, MVMT
|INCL
|VIZ
},
101 /* % move to match */ {m_match
, CURSOR
, MVMT
|INCL
|VIZ
},
102 /* & repeat subst */ {v_again
, CURSOR_MOVED
, SDOT
|NCOL
|LNMD
|INCL
},
103 /* ' move to a mark */ {m_tomark
, C_C_K_MARK
, MVMT
|FRNT
|NREL
|LNMD
|INCL
|VIZ
},
105 /* ( mv back sentence */ {m_sentence
, CURSOR
, MVMT
|VIZ
},
106 /* ) mv fwd sentence */ {m_sentence
, CURSOR
, MVMT
|VIZ
},
108 /* ( not defined */ {NO_FUNC
, NO_ARGS
, NO_FLAGS
},
109 /* ) not defined */ {NO_FUNC
, NO_ARGS
, NO_FLAGS
},
112 /* * errlist */ {v_errlist
, CURSOR
, FRNT
|NREL
},
114 /* * not defined */ {NO_FUNC
, NO_ARGS
, NO_FLAGS
},
116 /* + mv front next ln */ {m_updnto
, CURSOR
, MVMT
|FRNT
|LNMD
|VIZ
|INCL
},
117 #ifndef NO_CHARSEARCH
118 /* , reverse [fFtT] cmd*/ {m__ch
, CURSOR
, MVMT
|INCL
|VIZ
},
120 /* , not defined */ {NO_FUNC
, NO_ARGS
, NO_FLAGS
},
122 /* - mv front prev ln */ {m_updnto
, CURSOR
, MVMT
|FRNT
|LNMD
|VIZ
|INCL
},
123 /* . special... */ {NO_FUNC
, NO_ARGS
, NO_FLAGS
},
124 /* / forward search */ {m_fsrch
, CURSOR_TEXT
, MVMT
|NREL
|VIZ
},
125 /* 0 part of count? */ {NO_FUNC
, ZERO
, MVMT
|PTMV
|VIZ
},
126 /* 1 part of count */ {NO_FUNC
, DIGIT
, PTMV
|VIZ
},
127 /* 2 part of count */ {NO_FUNC
, DIGIT
, PTMV
|VIZ
},
128 /* 3 part of count */ {NO_FUNC
, DIGIT
, PTMV
|VIZ
},
129 /* 4 part of count */ {NO_FUNC
, DIGIT
, PTMV
|VIZ
},
130 /* 5 part of count */ {NO_FUNC
, DIGIT
, PTMV
|VIZ
},
131 /* 6 part of count */ {NO_FUNC
, DIGIT
, PTMV
|VIZ
},
132 /* 7 part of count */ {NO_FUNC
, DIGIT
, PTMV
|VIZ
},
133 /* 8 part of count */ {NO_FUNC
, DIGIT
, PTMV
|VIZ
},
134 /* 9 part of count */ {NO_FUNC
, DIGIT
, PTMV
|VIZ
},
135 /* : run single EX cmd*/ {v_1ex
, CURSOR_TEXT
, NO_FLAGS
},
136 #ifndef NO_CHARSEARCH
137 /* ; repeat [fFtT] cmd*/ {m__ch
, CURSOR
, MVMT
|INCL
|VIZ
},
139 /* ; not defined */ {NO_FUNC
, NO_ARGS
, NO_FLAGS
|VIZ
},
141 /* < shift text left */ {v_lshift
, CURSOR_MOVED
, SDOT
|FRNT
|LNMD
|INCL
|VIZ
},
142 /* = preset filter */ {v_reformat
, CURSOR_MOVED
, SDOT
|FRNT
|LNMD
|INCL
|VIZ
},
143 /* > shift text right */ {v_rshift
, CURSOR_MOVED
, SDOT
|FRNT
|LNMD
|INCL
|VIZ
},
144 /* ? backward search */ {m_bsrch
, CURSOR_TEXT
, MVMT
|NREL
|VIZ
},
146 /* @ execute a cutbuf */ {v_at
, C_C_K_CUT
, NO_FLAGS
},
148 /* @ not defined */ {NO_FUNC
, NO_ARGS
, NO_FLAGS
},
150 /* A append at EOL */ {v_insert
, CURSOR
, SDOT
},
151 /* B move back Word */ {m_bword
, CURSOR
, MVMT
|VIZ
},
152 /* C change to EOL */ {v_change
, CURSOR_EOL
, SDOT
},
153 /* D delete to EOL */ {v_delete
, CURSOR_EOL
, SDOT
},
154 /* E move end of Word */ {m_eword
, CURSOR
, MVMT
|INCL
|VIZ
},
155 #ifndef NO_CHARSEARCH
156 /* F move bk to char */ {m_Fch
, C_C_K_CHAR
, MVMT
|INCL
|VIZ
},
158 /* F not defined */ {NO_FUNC
, NO_ARGS
, NO_FLAGS
},
160 /* G move to line # */ {m_updnto
, CURSOR
, MVMT
|NREL
|LNMD
|FRNT
|INCL
|VIZ
},
161 /* H move to row */ {m_row
, CURSOR
, MVMT
|LNMD
|FRNT
|VIZ
|INCL
},
162 /* I insert at front */ {v_insert
, CURSOR
, SDOT
},
163 /* J join lines */ {v_join
, CURSOR
, SDOT
},
164 #ifndef NO_EXTENSIONS
165 /* K look up keyword */ {v_keyword
, KEYWORD
, NO_FLAGS
},
167 /* K not defined */ {NO_FUNC
, NO_ARGS
, NO_FLAGS
},
169 /* L move to last row */ {m_row
, CURSOR
, MVMT
|LNMD
|FRNT
|VIZ
|INCL
},
170 /* M move to mid row */ {m_row
, CURSOR
, MVMT
|LNMD
|FRNT
|VIZ
|INCL
},
171 /* N reverse prev srch*/ {m_Nsrch
, CURSOR
, MVMT
|NREL
|VIZ
},
172 /* O insert above line*/ {v_insert
, CURSOR
, SDOT
},
173 /* P paste before */ {v_paste
, CURSOR
, SDOT
},
174 /* Q quit to EX mode */ {v_quit
, NO_ARGS
, NO_FLAGS
},
175 /* R overtype */ {v_overtype
, CURSOR
, SDOT
},
176 /* S change line */ {v_change
, CURSOR_MOVED
, SDOT
},
177 #ifndef NO_CHARSEARCH
178 /* T move bk to char */ {m_Tch
, C_C_K_CHAR
, MVMT
|INCL
|VIZ
},
180 /* T not defined */ {NO_FUNC
, NO_ARGS
, NO_FLAGS
},
182 /* U undo whole line */ {v_undoline
, CURSOR
, FRNT
},
184 /* V start visible */ {v_start
, CURSOR
, INCL
|LNMD
|VIZ
},
186 /* V not defined */ {NO_FUNC
, NO_ARGS
, NO_FLAGS
},
188 /* W move forward Word*/ {m_fword
, CURSOR
, MVMT
|INCL
|VIZ
},
189 /* X delete to left */ {v_xchar
, CURSOR
, SDOT
},
190 /* Y yank text */ {v_yank
, CURSOR_MOVED
, NCOL
},
191 /* Z save file & exit */ {v_xit
, CURSOR_CNT_KEY
, NO_FLAGS
},
192 /* [ move back section*/ {m_paragraph
, CURSOR
, MVMT
|LNMD
|NREL
|VIZ
},
194 /* \ pop-up menu */ {v_popup
, CURSOR_MOVED
, VIZ
},
196 /* \ not defined */ {NO_FUNC
, NO_ARGS
, NO_FLAGS
},
198 /* ] move fwd section */ {m_paragraph
, CURSOR
, MVMT
|LNMD
|NREL
|VIZ
},
199 /* ^ move to front */ {m_front
, CURSOR
, MVMT
|VIZ
},
200 /* _ current line */ {m_updnto
, CURSOR
, MVMT
|LNMD
|FRNT
|INCL
},
201 /* ` move to mark */ {m_tomark
, C_C_K_MARK
, MVMT
|NREL
|VIZ
},
202 /* a append at cursor */ {v_insert
, CURSOR
, SDOT
},
203 /* b move back word */ {m_bword
, CURSOR
, MVMT
|VIZ
},
204 /* c change text */ {v_change
, CURSOR_MOVED
, SDOT
|VIZ
},
205 /* d delete op */ {v_delete
, CURSOR_MOVED
, SDOT
|VIZ
},
206 /* e move end word */ {m_eword
, CURSOR
, MVMT
|INCL
|VIZ
},
207 #ifndef NO_CHARSEARCH
208 /* f move fwd for char*/ {m_fch
, C_C_K_CHAR
, MVMT
|INCL
|VIZ
},
210 /* f not defined */ {NO_FUNC
, NO_ARGS
, NO_FLAGS
},
212 /* g not defined */ {NO_FUNC
, NO_ARGS
, NO_FLAGS
},
213 /* h move left */ {m_left
, CURSOR
, MVMT
|VIZ
},
214 /* i insert at cursor */ {v_insert
, CURSOR
, SDOT
},
215 /* j move down */ {m_updnto
, CURSOR
, MVMT
|NCOL
|LNMD
|VIZ
|INCL
},
216 /* k move up */ {m_updnto
, CURSOR
, MVMT
|NCOL
|LNMD
|VIZ
|INCL
},
217 /* l move right */ {m_right
, CURSOR
, MVMT
|INCL
|VIZ
},
218 /* m define a mark */ {v_mark
, C_C_K_MARK
, NO_FLAGS
},
219 /* n repeat prev srch */ {m_nsrch
, CURSOR
, MVMT
|NREL
|VIZ
},
220 /* o insert below line*/ {v_insert
, CURSOR
, SDOT
},
221 /* p paste after */ {v_paste
, CURSOR
, SDOT
},
222 /* q not defined */ {NO_FUNC
, NO_ARGS
, NO_FLAGS
},
223 /* r replace chars */ {v_replace
, C_C_K_REP1
, SDOT
},
224 /* s subst N chars */ {v_subst
, CURSOR
, SDOT
},
225 #ifndef NO_CHARSEARCH
226 /* t move fwd to char */ {m_tch
, C_C_K_CHAR
, MVMT
|INCL
|VIZ
},
228 /* t not defined */ {NO_FUNC
, NO_ARGS
, NO_FLAGS
},
230 /* u undo */ {v_undo
, CURSOR
, NO_FLAGS
},
232 /* v start visible */ {v_start
, CURSOR
, INCL
|VIZ
},
234 /* v not defined */ {NO_FUNC
, NO_ARGS
, NO_FLAGS
},
236 /* w move fwd word */ {m_fword
, CURSOR
, MVMT
|INCL
|VIZ
},
237 /* x delete character */ {v_xchar
, CURSOR
, SDOT
},
238 /* y yank text */ {v_yank
, CURSOR_MOVED
, NCOL
|VIZ
},
239 /* z adjust scrn row */ {m_z
, CURSOR_CNT_KEY
, NCOL
|VIZ
},
240 /* { back paragraph */ {m_paragraph
, CURSOR
, MVMT
|LNMD
|VIZ
},
241 /* | move to column */ {m_tocol
, CURSOR
, MVMT
|NREL
|VIZ
},
242 /* } fwd paragraph */ {m_paragraph
, CURSOR
, MVMT
|LNMD
|VIZ
},
243 /* ~ upper/lowercase */ {v_ulcase
, CURSOR
, SDOT
},
244 /* DEL not defined */ {NO_FUNC
, NO_ARGS
, NO_FLAGS
}
251 REG
int key
; /* keystroke from user */
252 long count
; /* numeric argument to some functions */
253 REG
struct keystru
*keyptr
;/* pointer to vikeys[] element */
254 MARK tcurs
; /* temporary cursor */
255 int prevkey
;/* previous key, if d/c/y/</>/! */
256 MARK range
; /* start of range for d/c/y/</>/! */
258 int dotkey
; /* last "key" of a change */
259 int dotpkey
;/* last "prevkey" of a change */
260 int dotkey2
;/* last extra "getkey()" of a change */
261 int dotcnt
; /* last "count" of a change */
265 /* tell the redraw() function to start from scratch */
266 redraw(MARK_UNSET
, FALSE
);
269 /* lint says that "range" might be used before it is set. This
270 * can't really happen due to the way "range" and "prevkey" are used,
271 * but lint doesn't know that. This line is here ONLY to keep lint
277 /* safeguard against '.' with no previous command */
278 dotkey
= dotpkey
= dotkey2
= dotcnt
= 0;
280 /* go immediately into insert mode, if ":set inputmode" */
282 #ifndef NO_EXTENSIONS
289 /* Repeatedly handle VI commands */
290 for (count
= 0, prevkey
= '\0'; mode
== MODE_VI
; )
292 /* if we've moved off the undoable line, then we can't undo it at all */
293 if (markline(cursor
) != U_line
)
298 /* report any changes from the previous command */
299 if (rptlines
>= *o_report
)
301 redraw(cursor
, FALSE
);
302 msg("%ld line%s %s", rptlines
, (rptlines
==1?"":"s"), rptlabel
);
306 /* get the next command key. It must be ASCII */
316 key
= getkey(WHEN_VICMD
);
317 } while (key
< 0 || key
> 127);
320 /* Convert a doubled-up operator such as "dd" into "d_" */
321 if (prevkey
&& key
== prevkey
)
326 /* look up the structure describing this command */
327 keyptr
= &vikeys
[key
];
329 /* '&' and uppercase operators always act like doubled */
330 if (!prevkey
&& keyptr
->args
== CURSOR_MOVED
331 && (key
== '&' || isupper(key
)))
336 keyptr
= &vikeys
[key
];
340 /* if we're in the middle of a v/V command, reject commands
341 * that aren't operators or movement commands
343 if (V_from
&& !(keyptr
->flags
& VIZ
))
352 /* if we're in the middle of a d/c/y/</>/! command, reject
353 * anything but movement.
355 if (prevkey
&& !(keyptr
->flags
& (MVMT
|PTMV
)))
363 /* set the "dot" variables, if we're supposed to */
364 if (((keyptr
->flags
& SDOT
)
365 || (prevkey
&& vikeys
[prevkey
].flags
& SDOT
))
376 /* remember the line before any changes are made */
377 if (U_line
!= markline(cursor
))
379 U_line
= markline(cursor
);
380 strcpy(U_text
, fetchline(U_line
));
384 /* if this is "." then set other vars from the "dot" vars */
388 keyptr
= &vikeys
[key
];
400 /* remember the line before any changes are made */
401 if (U_line
!= markline(cursor
))
403 U_line
= markline(cursor
);
404 strcpy(U_text
, fetchline(U_line
));
412 /* process the key as a command */
414 force_flags
= NO_FLAGS
;
415 switch (keyptr
->args
& ARGSMASK
)
420 tcurs
= cursor
& ~(BLKSIZE
- 1);
423 /* else fall through & treat like other digits... */
426 count
= count
* 10 + key
- '0';
430 /* if not on a keyword, fail */
431 pfetch(markline(cursor
));
432 key
= markidx(cursor
);
433 if (!isalnum(ptext
[key
]))
439 /* find the start of the keyword */
440 while (key
> 0 && isalnum(ptext
[key
- 1]))
444 tcurs
= (cursor
& ~(BLKSIZE
- 1)) + key
;
446 /* copy it into a buffer, and NUL-terminate it */
450 text
[i
++] = ptext
[key
++];
451 } while (isalnum(ptext
[key
]));
454 /* call the function */
455 tcurs
= (*keyptr
->func
)(text
, tcurs
, count
);
472 tcurs
= (*keyptr
->func
)(cursor
, count
, key
, prevkey
);
479 tcurs
= (*keyptr
->func
)(cursor
, count
, dotkey2
);
484 i
= getkey(KEYMODE(keyptr
->args
));
485 if (i
== '\033') /* ESC */
489 break; /* exit from "case CURSOR_CNT_KEY" */
491 else if (i
== ctrl('V'))
496 /* if part of an SDOT command, remember it */
497 if (keyptr
->flags
& SDOT
498 || (prevkey
&& vikeys
[prevkey
].flags
& SDOT
))
504 tcurs
= (*keyptr
->func
)(cursor
, count
, i
);
517 key
= (V_linemd
? 'V' : 'v');
518 keyptr
= &vikeys
[key
];
525 force_flags
= LNMD
|INCL
;
531 /* a zero-length line needs special treatment */
532 pfetch(markline(cursor
));
535 /* act on a zero-length section of text */
536 range
= tcurs
= cursor
;
541 /* act like CURSOR_MOVED with '$' movement */
543 tcurs
= m_rear(cursor
, 1L);
547 keyptr
= &vikeys
[key
];
554 if (vgets(key
, text
+ 1, sizeof text
- 1) >= 0)
556 /* reassure user that <CR> was hit */
560 /* call the function with the text */
561 tcurs
= (*keyptr
->func
)(cursor
, text
);
565 if (exwrote
|| mode
== MODE_COLON
)
567 redraw(MARK_UNSET
, FALSE
);
571 } while (mode
== MODE_COLON
);
576 /* if that command took us out of vi mode, then exit the loop
577 * NOW, without tweaking the cursor or anything. This is very
578 * important when mode == MODE_QUIT.
585 /* now move the cursor, as appropriate */
586 if (keyptr
->args
== CURSOR_MOVED
)
588 /* the < and > keys have FRNT,
589 * but it shouldn't be applied yet
591 tcurs
= adjmove(cursor
, tcurs
, 0);
595 tcurs
= adjmove(cursor
, tcurs
, (int)keyptr
->flags
| force_flags
);
598 /* was that the end of a d/c/y/</>/! command? */
599 if (prevkey
&& ((keyptr
->flags
& MVMT
)
606 /* turn off the hilight */
610 /* if the movement command failed, cancel operation */
611 if (tcurs
== MARK_UNSET
)
618 /* make sure range=front and tcurs=rear. Either way,
619 * leave cursor=range since that's where we started.
628 /* The 'w' and 'W' destinations should never take us
629 * to the front of a line. Instead, they should take
630 * us only to the end of the preceding line.
632 if ((keyptr
->flags
& (MVMT
|NREL
|LNMD
|FRNT
|INCL
)) == MVMT
633 && markline(range
) < markline(tcurs
)
634 && (markline(tcurs
) > nlines
|| tcurs
== m_front(tcurs
, 0L)))
636 tcurs
= (tcurs
& ~(BLKSIZE
- 1)) - BLKSIZE
;
637 pfetch(markline(tcurs
));
641 /* adjust for line mode & inclusion of last char/line */
642 i
= (keyptr
->flags
| vikeys
[prevkey
].flags
);
643 switch ((i
| force_flags
) & (INCL
|LNMD
))
651 /* fall through... */
654 range
&= ~(BLKSIZE
- 1);
655 tcurs
&= ~(BLKSIZE
- 1);
659 /* run the function */
660 tcurs
= (*vikeys
[prevkey
].func
)(range
, tcurs
);
663 (void)adjmove(cursor
, cursor
, 0);
664 cursor
= adjmove(cursor
, tcurs
, (int)vikeys
[prevkey
].flags
);
672 if (tcurs
!= MARK_UNSET
)
678 /* This function adjusts the MARK value that they return; here we make sure
679 * it isn't past the end of the line, and that the column hasn't been
680 * *accidentally* changed.
682 MARK
adjmove(old
, new, flags
)
683 MARK old
; /* the cursor position before the command */
684 REG MARK
new; /* the cursor position after the command */
685 int flags
; /* various flags regarding cursor mvmt */
687 static int colno
; /* the column number that we want */
688 REG
char *text
; /* used to scan through the line's text */
695 /* if the command failed, bag it! */
696 if (new == MARK_UNSET
)
702 /* if this is a non-relative movement, set the '' mark */
708 /* make sure it isn't past the end of the file */
709 if (markline(new) < 1)
713 else if (markline(new) > nlines
)
718 /* fetch the new line */
719 pfetch(markline(new));
721 /* move to the front, if we're supposed to */
724 new = m_front(new, 1L);
727 /* change the column#, or change the mark to suit the column# */
730 /* change the column# */
732 if (i
== BLKSIZE
- 1)
734 new &= ~(BLKSIZE
- 1);
739 colno
= BLKSIZE
* 8; /* one heck of a big colno */
745 new = (new & ~(BLKSIZE
- 1)) + plen
- 1;
747 colno
= idx2col(new, ptext
, FALSE
);
751 new &= ~(BLKSIZE
- 1);
757 /* adjust the mark to get as close as possible to column# */
758 for (i
= 0, text
= ptext
; i
<= colno
&& *text
; text
++)
760 if (*text
== '\t' && !*o_list
)
762 i
+= *o_tabstop
- (i
% *o_tabstop
);
764 else if (UCHAR(*text
) < ' ' || *text
== 127)
769 else if (*o_charattr
&& text
[0] == '\\' && text
[1] == 'f' && text
[2])
771 text
+= 2; /* plus one more in "for()" stmt */
783 new = (new & ~(BLKSIZE
- 1)) + (int)(text
- ptext
);
802 msg("origname was clobbered");
807 if (wasset
&& nlines
== 0)