4 * Copyright (C) 2015 Ali Gholami Rudi <ali at rudi dot ir>
6 * This program is released under the Modified BSD license.
15 char xpath
[PATHLEN
]; /* current file */
16 char xpath_alt
[PATHLEN
]; /* alternate file */
17 struct lbuf
*xb
; /* current buffer */
18 int xrow
, xcol
, xtop
; /* current row, column, and top row */
19 int xrow_alt
; /* alternate row, column, and top row */
20 int xled
= 1; /* use the line editor */
21 int xdir
= 'L'; /* current direction context */
22 int xvis
; /* visual mode */
25 static char vi_findlast
[256]; /* the last searched keyword */
26 static int vi_finddir
; /* the last search direction */
27 static char vi_charlast
[8]; /* the last character searched via f, t, F, or T */
28 static int vi_charcmd
; /* the character finding command */
30 static void vi_draw(void)
34 for (i
= xtop
; i
< xtop
+ xrows
; i
++) {
35 char *s
= lbuf_get(xb
, i
);
36 led_print(s
? s
: "~", i
- xtop
);
39 term_pos(xrow
, led_pos(lbuf_get(xb
, i
), xcol
));
43 static int vi_buf
[128];
46 static int vi_read(void)
48 return vi_buflen
? vi_buf
[--vi_buflen
] : term_read(1000);
51 static void vi_back(int c
)
53 if (vi_buflen
< sizeof(vi_buf
))
54 vi_buf
[vi_buflen
++] = c
;
57 static char *vi_char(void)
60 return TK_INT(key
) ? NULL
: led_keymap(key
);
63 static int vi_prefix(void)
67 if ((c
>= '1' && c
<= '9')) {
69 pre
= pre
* 10 + c
- '0';
77 static int lbuf_lnnext(struct lbuf
*lb
, int *r
, int *c
, int dir
)
79 char *ln
= lbuf_get(lb
, *r
);
80 int col
= ln
? ren_next(ln
, *c
, dir
) : -1;
87 static void lbuf_eol(struct lbuf
*lb
, int *r
, int *c
, int dir
)
89 char *ln
= lbuf_get(lb
, *r
);
90 *c
= dir
< 0 ? 0 : MAX(0, ren_wid(ln
? ln
: "") - 1);
93 static int lbuf_next(struct lbuf
*lb
, int *r
, int *c
, int dir
)
95 if (dir
< 0 && *r
>= lbuf_len(lb
))
96 *r
= MAX(0, lbuf_len(lb
) - 1);
97 if (lbuf_lnnext(lb
, r
, c
, dir
)) {
98 if (!lbuf_get(lb
, *r
+ dir
))
101 lbuf_eol(lb
, r
, c
, -dir
);
107 /* return a pointer to the character at visual position c of line r */
108 static char *lbuf_chr(struct lbuf
*lb
, int r
, int c
)
110 char *ln
= lbuf_get(lb
, r
);
111 return ln
? uc_chr(ln
, ren_off(ln
, c
)) : "";
114 static void lbuf_postindents(struct lbuf
*lb
, int *r
, int *c
)
116 lbuf_eol(lb
, r
, c
, -1);
117 while (uc_isspace(lbuf_chr(lb
, *r
, *c
)))
118 if (lbuf_lnnext(lb
, r
, c
, +1))
122 static int lbuf_findchar(struct lbuf
*lb
, int *row
, int *col
, char *cs
, int cmd
, int n
)
124 int dir
= (cmd
== 'f' || cmd
== 't') ? +1 : -1;
130 strcpy(vi_charlast
, cs
);
132 while (n
> 0 && !lbuf_lnnext(lb
, row
, &c
, dir
))
133 if (uc_code(lbuf_chr(lb
, *row
, c
)) == uc_code(cs
))
137 if (!n
&& (cmd
== 't' || cmd
== 'T'))
138 lbuf_lnnext(lb
, row
, col
, -dir
);
142 static int lbuf_search(struct lbuf
*lb
, char *kw
, int dir
, int *r
, int *c
, int *len
)
146 int row
= *r
, col
= *c
;
148 struct rset
*re
= rset_make(1, &kw
, 0);
151 for (i
= row
; !found
&& i
>= 0 && i
< lbuf_len(lb
); i
+= dir
) {
152 char *s
= lbuf_get(lb
, i
);
153 int off
= dir
> 0 && row
== i
? uc_chr(s
, col
+ 1) - s
: 0;
154 int flg
= off
? RE_NOTBOL
: 0;
155 while (rset_find(re
, s
+ off
, 1, offs
, flg
) >= 0) {
156 if (dir
< 0 && row
== i
&& off
+ offs
[0] >= col
)
159 *c
= uc_off(s
, off
+ offs
[0]);
161 *len
= offs
[1] - offs
[0];
171 static int vi_search(int cmd
, int cnt
, int *row
, int *col
)
179 if (cmd
== '/' || cmd
== '?') {
180 char sign
[4] = {cmd
};
182 term_pos(xrows
, led_pos(sign
, 0));
184 if (!(kw
= led_prompt(sign
, "")))
186 vi_finddir
= cmd
== '/' ? +1 : -1;
188 snprintf(vi_findlast
, sizeof(vi_findlast
), "%s", kw
);
189 if (strchr(vi_findlast
, cmd
)) {
190 off
= strchr(vi_findlast
, cmd
) + 1;
191 *strchr(vi_findlast
, cmd
) = '\0';
195 dir
= cmd
== 'N' ? -vi_finddir
: vi_finddir
;
196 if (!vi_findlast
[0] || !lbuf_len(xb
))
198 c
= ren_off(lbuf_get(xb
, *row
), *col
);
199 for (i
= 0; i
< cnt
; i
++) {
200 if (lbuf_search(xb
, vi_findlast
, dir
, &r
, &c
, &len
)) {
204 if (i
+ 1 < cnt
&& cmd
== '/')
209 *col
= ren_pos(lbuf_get(xb
, r
), c
);
210 while (off
[0] && isspace((unsigned char) off
[0]))
214 if (*row
+ atoi(off
) < 0 || *row
+ atoi(off
) >= lbuf_len(xb
))
223 /* move to the last character of the word */
224 static int lbuf_wordlast(struct lbuf
*lb
, int *row
, int *col
, int kind
, int dir
)
226 if (!kind
|| !(uc_kind(lbuf_chr(lb
, *row
, *col
)) & kind
))
228 while (uc_kind(lbuf_chr(lb
, *row
, *col
)) & kind
)
229 if (lbuf_next(lb
, row
, col
, dir
))
231 if (!(uc_kind(lbuf_chr(lb
, *row
, *col
)) & kind
))
232 lbuf_next(lb
, row
, col
, -dir
);
236 static int lbuf_wordbeg(struct lbuf
*lb
, int *row
, int *col
, int big
, int dir
)
239 lbuf_wordlast(lb
, row
, col
, big
? 3 : uc_kind(lbuf_chr(lb
, *row
, *col
)), dir
);
240 if (lbuf_next(lb
, row
, col
, dir
))
242 while (uc_isspace(lbuf_chr(lb
, *row
, *col
))) {
243 nl
= uc_code(lbuf_chr(lb
, *row
, *col
)) == '\n' ? nl
+ 1 : 0;
246 if (lbuf_next(lb
, row
, col
, dir
))
252 static int lbuf_wordend(struct lbuf
*lb
, int *row
, int *col
, int big
, int dir
)
254 int nl
= uc_code(lbuf_chr(lb
, *row
, *col
)) == '\n' ? -1 : 0;
255 if (!uc_isspace(lbuf_chr(lb
, *row
, *col
)))
256 if (lbuf_next(lb
, row
, col
, dir
))
258 while (uc_isspace(lbuf_chr(lb
, *row
, *col
))) {
259 nl
= uc_code(lbuf_chr(lb
, *row
, *col
)) == '\n' ? nl
+ 1 : 0;
262 lbuf_next(lb
, row
, col
, -dir
);
265 if (lbuf_next(lb
, row
, col
, dir
))
268 if (lbuf_wordlast(lb
, row
, col
, big
? 3 : uc_kind(lbuf_chr(lb
, *row
, *col
)), dir
))
273 /* read a line motion */
274 static int vi_motionln(int *row
, int cmd
, int pre1
, int pre2
)
276 int pre
= (pre1
? pre1
: 1) * (pre2
? pre2
: 1);
282 *row
= MIN(*row
+ pre
, lbuf_len(xb
) - 1);
285 *row
= MAX(*row
- pre
, 0);
288 *row
= MIN(*row
+ pre
- 1, lbuf_len(xb
) - 1);
291 if ((mark
= vi_read()) > 0 && (isalpha(mark
) || mark
== '\''))
292 if (lbuf_markpos(xb
, mark
) >= 0)
293 *row
= lbuf_markpos(xb
, mark
);
296 *row
= MIN(*row
+ pre
, lbuf_len(xb
) - 1);
299 *row
= MAX(*row
- pre
, 0);
302 *row
= (pre1
|| pre2
) ? pre
- 1 : lbuf_len(xb
) - 1;
306 *row
= MIN(xtop
+ pre
- 1, lbuf_len(xb
) - 1);
312 *row
= MIN(xtop
+ xrows
- 1 - pre
+ 1, lbuf_len(xb
) - 1);
318 *row
= MIN(xtop
+ xrows
/ 2, lbuf_len(xb
) - 1);
324 *row
= MIN(*row
+ pre
- 1, lbuf_len(xb
) - 1);
334 static int vi_motion(int *row
, int *col
, int pre1
, int pre2
)
336 int pre
= (pre1
? pre1
: 1) * (pre2
? pre2
: 1);
337 char *ln
= lbuf_get(xb
, *row
);
338 int dir
= dir_context(ln
? ln
: "");
342 if ((mv
= vi_motionln(row
, 0, pre1
, pre2
))) {
349 for (i
= 0; i
< pre
; i
++)
350 if (lbuf_lnnext(xb
, row
, col
, 1))
354 if ((cs
= vi_char()))
355 if (lbuf_findchar(xb
, row
, col
, cs
, mv
, pre
))
359 if ((cs
= vi_char()))
360 if (lbuf_findchar(xb
, row
, col
, cs
, mv
, pre
))
365 if (lbuf_findchar(xb
, row
, col
, vi_charlast
, vi_charcmd
, pre
))
370 if (lbuf_findchar(xb
, row
, col
, vi_charlast
, vi_charcmd
, -pre
))
374 for (i
= 0; i
< pre
; i
++)
375 if (lbuf_lnnext(xb
, row
, col
, -1 * dir
))
379 for (i
= 0; i
< pre
; i
++)
380 if (lbuf_lnnext(xb
, row
, col
, +1 * dir
))
384 if ((cs
= vi_char()))
385 if (lbuf_findchar(xb
, row
, col
, cs
, mv
, pre
))
389 if ((cs
= vi_char()))
390 if (lbuf_findchar(xb
, row
, col
, cs
, mv
, pre
))
394 for (i
= 0; i
< pre
; i
++)
395 if (lbuf_wordend(xb
, row
, col
, 1, -1))
399 for (i
= 0; i
< pre
; i
++)
400 if (lbuf_wordend(xb
, row
, col
, 1, +1))
404 for (i
= 0; i
< pre
; i
++)
405 if (lbuf_wordbeg(xb
, row
, col
, 1, +1))
409 for (i
= 0; i
< pre
; i
++)
410 if (lbuf_wordend(xb
, row
, col
, 0, -1))
414 for (i
= 0; i
< pre
; i
++)
415 if (lbuf_wordend(xb
, row
, col
, 0, +1))
419 for (i
= 0; i
< pre
; i
++)
420 if (lbuf_wordbeg(xb
, row
, col
, 0, +1))
424 lbuf_eol(xb
, row
, col
, -1);
427 lbuf_postindents(xb
, row
, col
);
430 lbuf_eol(xb
, row
, col
, +1);
431 lbuf_lnnext(xb
, row
, col
, -1);
437 if (vi_search(mv
, pre
, row
, col
))
441 if (vi_search(mv
, pre
, row
, col
))
445 if (vi_search(mv
, pre
, row
, col
))
449 if (vi_search(mv
, pre
, row
, col
))
454 for (i
= 0; i
< pre
; i
++)
455 if (lbuf_lnnext(xb
, row
, col
, -1))
465 static void swap(int *a
, int *b
)
472 static char *lbuf_region(struct lbuf
*lb
, int r1
, int l1
, int r2
, int l2
)
477 return uc_sub(lbuf_get(lb
, r1
), l1
, l2
);
479 s1
= uc_sub(lbuf_get(lb
, r1
), l1
, -1);
480 s3
= uc_sub(lbuf_get(lb
, r2
), 0, l2
);
481 s2
= lbuf_cp(lb
, r1
+ 1, r2
);
488 return sbuf_done(sb
);
491 /* insertion offset before or after the given visual position */
492 static int vi_insertionoffset(char *s
, int c1
, int before
)
495 c2
= ren_next(s
, c1
, before
? -1 : +1);
496 l2
= c2
>= 0 ? ren_off(s
, c2
) : 0;
497 if (c1
== c2
|| c2
< 0 || uc_chr(s
, l2
)[0] == '\n') {
498 c2
= ren_next(s
, c1
, before
? +1 : -1);
500 l2
= c2
>= 0 ? ren_off(s
, c2
) : 0;
501 if (c1
== c2
|| c2
< 0 || uc_chr(s
, l2
)[0] == '\n')
502 return before
? l1
: l1
+ 1;
504 return l1
< l2
? l1
: l1
+ 1;
506 return l2
< l1
? l1
+ 1 : l1
;
508 ren_region(s
, c1
, c2
, &l1
, &l2
, 0);
512 return l1
< l2
? l2
: l1
;
514 return l1
< l2
? l1
: l2
;
517 static void vi_commandregion(int *r1
, int *r2
, int *c1
, int *c2
, int *l1
, int *l2
, int closed
)
519 if (*r2
< *r1
|| (*r2
== *r1
&& *c2
< *c1
)) {
523 *l1
= lbuf_get(xb
, *r1
) ? vi_insertionoffset(lbuf_get(xb
, *r1
), *c1
, 1) : 0;
524 *l2
= lbuf_get(xb
, *r2
) ? vi_insertionoffset(lbuf_get(xb
, *r2
), *c2
, !closed
) : 0;
525 if (*r1
== *r2
&& lbuf_get(xb
, *r1
))
526 ren_region(lbuf_get(xb
, *r1
), *c1
, *c2
, l1
, l2
, closed
);
527 if (*r1
== *r2
&& *l2
< *l1
)
531 static void vi_yank(int r1
, int c1
, int r2
, int c2
, int lnmode
, int closed
)
535 vi_commandregion(&r1
, &r2
, &c1
, &c2
, &l1
, &l2
, closed
);
536 region
= lbuf_region(xb
, r1
, lnmode
? 0 : l1
, r2
, lnmode
? -1 : l2
);
537 reg_put(0, region
, lnmode
);
540 xcol
= lnmode
? xcol
: c1
;
543 static void vi_delete(int r1
, int c1
, int r2
, int c2
, int lnmode
, int closed
)
548 vi_commandregion(&r1
, &r2
, &c1
, &c2
, &l1
, &l2
, closed
);
549 region
= lbuf_region(xb
, r1
, lnmode
? 0 : l1
, r2
, lnmode
? -1 : l2
);
550 reg_put(0, region
, lnmode
);
552 pref
= lnmode
? uc_dup("") : uc_sub(lbuf_get(xb
, r1
), 0, l1
);
553 post
= lnmode
? uc_dup("\n") : uc_sub(lbuf_get(xb
, r2
), l2
, -1);
554 lbuf_rm(xb
, r1
, r2
+ 1);
556 struct sbuf
*sb
= sbuf_make();
559 lbuf_put(xb
, r1
, sbuf_buf(sb
));
565 lbuf_postindents(xb
, &xrow
, &xcol
);
570 static int lastline(char *str
)
576 s
= strchr(s
== str
? s
: s
+ 1, '\n');
581 static int linecount(char *s
)
585 if ((s
= strchr(s
, '\n')))
590 static int indentscopy(char *d
, char *s
, int len
)
593 for (i
= 0; i
< len
- 1 && (s
[i
] == ' ' || s
[i
] == '\t'); i
++)
599 static char *vi_input(char *pref
, char *post
, int *row
, int *col
)
606 pref
+= indentscopy(ai
, pref
, sizeof(ai
));
607 rep
= led_input(pref
, post
, ai
, xautoindent
? sizeof(ai
) - 1 : 0);
614 last
= lastline(sbuf_buf(sb
));
615 off
= uc_slen(sbuf_buf(sb
) + last
);
617 while (xautoindent
&& (post
[0] == ' ' || post
[0] == '\t'))
620 *row
= linecount(sbuf_buf(sb
)) - 1;
621 *col
= ren_pos(sbuf_buf(sb
) + last
, MAX(0, off
- 1));
623 return sbuf_done(sb
);
626 static char *vi_indents(char *ln
)
628 struct sbuf
*sb
= sbuf_make();
629 while (xautoindent
&& ln
&& (*ln
== ' ' || *ln
== '\t'))
631 return sbuf_done(sb
);
634 static void vi_change(int r1
, int c1
, int r2
, int c2
, int lnmode
, int closed
)
641 vi_commandregion(&r1
, &r2
, &c1
, &c2
, &l1
, &l2
, closed
);
642 region
= lbuf_region(xb
, r1
, lnmode
? 0 : l1
, r2
, lnmode
? -1 : l2
);
643 reg_put(0, region
, lnmode
);
645 pref
= lnmode
? vi_indents(lbuf_get(xb
, r1
)) : uc_sub(lbuf_get(xb
, r1
), 0, l1
);
646 post
= lnmode
? uc_dup("\n") : uc_sub(lbuf_get(xb
, r2
), l2
, -1);
647 rep
= vi_input(pref
, post
, &row
, &col
);
649 lbuf_rm(xb
, r1
, r2
+ 1);
650 lbuf_put(xb
, r1
, rep
);
659 static void vc_motion(int cmd
, int pre1
)
661 int r1
= xrow
, r2
= xrow
; /* region rows */
662 int c1
= xcol
, c2
= xcol
; /* visual region columns */
663 int lnmode
= 0; /* line-based region */
664 int closed
= 1; /* include the last character */
666 int pre2
= vi_prefix();
669 if ((mv
= vi_motionln(&r2
, cmd
, pre1
, pre2
))) {
671 } else if (!(mv
= vi_motion(&r2
, &c2
, pre1
, pre2
))) {
676 if (!strchr("fFtTeE$", mv
))
680 lbuf_eol(xb
, &r1
, &c1
, -1);
681 lbuf_eol(xb
, &r2
, &c2
, +1);
684 vi_yank(r1
, c1
, r2
, c2
, lnmode
, closed
);
686 vi_delete(r1
, c1
, r2
, c2
, lnmode
, closed
);
688 vi_change(r1
, c1
, r2
, c2
, lnmode
, closed
);
691 static void vc_insert(int cmd
)
694 char *ln
= lbuf_get(xb
, xrow
);
695 int row
, col
, off
= 0;
698 lbuf_postindents(xb
, &xrow
, &xcol
);
700 lbuf_eol(xb
, &xrow
, &xcol
, +1);
701 lbuf_lnnext(xb
, &xrow
, &xcol
, -1);
705 if (cmd
== 'i' || cmd
== 'I')
706 off
= ln
? vi_insertionoffset(ln
, xcol
, 1) : 0;
707 if (cmd
== 'a' || cmd
== 'A')
708 off
= ln
? vi_insertionoffset(ln
, xcol
, 0) : 0;
709 pref
= ln
&& cmd
!= 'o' && cmd
!= 'O' ? uc_sub(ln
, 0, off
) : vi_indents(ln
);
710 post
= ln
&& cmd
!= 'o' && cmd
!= 'O' ? uc_sub(ln
, off
, -1) : uc_dup("\n");
711 rep
= vi_input(pref
, post
, &row
, &col
);
712 if ((cmd
== 'o' || cmd
== 'O') && !lbuf_len(xb
))
713 lbuf_put(xb
, 0, "\n");
715 if (cmd
!= 'o' && cmd
!= 'O')
716 lbuf_rm(xb
, xrow
, xrow
+ 1);
717 lbuf_put(xb
, xrow
, rep
);
726 static void vc_put(int cmd
, int cnt
)
730 char *buf
= reg_get(0, &lnmode
);
736 ln
= lnmode
? NULL
: lbuf_get(xb
, xrow
);
737 off
= ln
? vi_insertionoffset(ln
, xcol
, cmd
== 'P') : 0;
738 if (cmd
== 'p' && !ln
)
742 char *s
= uc_sub(ln
, 0, off
);
746 for (i
= 0; i
< MAX(cnt
, 1); i
++)
749 char *s
= uc_sub(ln
, off
, -1);
754 lbuf_rm(xb
, xrow
, xrow
+ 1);
755 lbuf_put(xb
, xrow
, sbuf_buf(sb
));
760 static int join_spaces(char *prev
, char *next
)
762 int prevlen
= strlen(prev
);
765 if (prev
[prevlen
- 1] == ' ' || next
[0] == ')')
767 return prev
[prevlen
- 1] == '.' ? 2 : 1;
770 static void vc_join(int arg
)
773 int cnt
= arg
<= 1 ? 2 : arg
;
775 int end
= xrow
+ cnt
;
778 if (!lbuf_get(xb
, beg
) || !lbuf_get(xb
, end
- 1))
781 for (i
= beg
; i
< end
; i
++) {
782 char *ln
= lbuf_get(xb
, i
);
783 char *lnend
= strchr(ln
, '\n');
786 while (ln
[0] == ' ' || ln
[0] == '\t')
788 spaces
= i
> beg
? join_spaces(sbuf_buf(sb
), ln
) : 0;
789 off
= uc_slen(sbuf_buf(sb
));
792 sbuf_mem(sb
, ln
, lnend
- ln
);
795 lbuf_rm(xb
, beg
, end
);
796 lbuf_put(xb
, beg
, sbuf_buf(sb
));
797 xcol
= ren_pos(sbuf_buf(sb
), off
);
801 static int vi_scrollforeward(int cnt
)
803 if (xtop
>= lbuf_len(xb
) - 1)
805 xtop
= MIN(lbuf_len(xb
) - 1, xtop
+ cnt
);
806 xrow
= MAX(xrow
, xtop
);
810 static int vi_scrollbackward(int cnt
)
814 xtop
= MAX(0, xtop
- cnt
);
815 xrow
= MIN(xrow
, xtop
+ xrows
- 1);
819 static void vi_status(void)
822 sprintf(stat
, "[%s] %d lines, %d,%d\n",
823 xpath
[0] ? xpath
: "unnamed", lbuf_len(xb
), xrow
+ 1, xcol
+ 1);
824 led_print(stat
, xrows
);
827 static int vc_replace(int arg
)
829 int cnt
= MAX(1, arg
);
830 char *cs
= vi_char();
831 char *ln
= lbuf_get(xb
, xrow
);
838 off
= ren_off(ln
, xcol
);
840 for (i
= 0; s
[0] != '\n' && i
< cnt
; i
++)
844 pref
= uc_sub(ln
, 0, off
);
845 post
= uc_sub(ln
, off
+ cnt
, -1);
848 for (i
= 0; i
< cnt
; i
++)
851 lbuf_rm(xb
, xrow
, xrow
+ 1);
852 lbuf_put(xb
, xrow
, sbuf_buf(sb
));
854 xcol
= ren_pos(sbuf_buf(sb
), off
);
868 lbuf_eol(xb
, &xrow
, &xcol
, -1);
870 term_pos(xrow
, led_pos(lbuf_get(xb
, xrow
), xcol
));
876 if ((pre1
= vi_prefix()) < 0)
878 mv
= vi_motion(&xrow
, &xcol
, pre1
, 0);
880 if (strchr("\'GHML/?", mv
))
881 lbuf_mark(xb
, '\'', orow
);
883 if (strchr("jk", mv
))
886 lbuf_postindents(xb
, &xrow
, &xcol
);
888 } else if (mv
== 0) {
895 if (vi_scrollbackward((pre1
? pre1
: 1) * (xrows
- 1)))
897 lbuf_postindents(xb
, &xrow
, &xcol
);
901 if (vi_scrollforeward((pre1
? pre1
: 1) * (xrows
- 1)))
903 lbuf_postindents(xb
, &xrow
, &xcol
);
907 if (vi_scrollforeward((pre1
? pre1
: 1)))
912 if (vi_scrollbackward((pre1
? pre1
: 1)))
932 term_pos(xrows
, led_pos(":", 0));
934 ln
= led_prompt(":", "");
963 if ((mark
= vi_read()) > 0 && isalpha(mark
))
964 lbuf_mark(xb
, mark
, xrow
);
975 xtop
= pre1
? pre1
: xrow
;
978 xtop
= MAX(0, (pre1
? pre1
: xrow
) - xrows
/ 2);
981 xtop
= MAX(0, (pre1
? pre1
: xrow
) - xrows
+ 1);
994 vc_motion('d', pre1
);
998 vi_back(TK_CTL('h'));
999 vc_motion('d', pre1
);
1004 vc_motion('c', pre1
);
1009 vc_motion('d', pre1
);
1018 vc_motion('c', pre1
);
1023 vc_motion('c', pre1
);
1028 vc_motion('y', pre1
);
1035 if (xrow
< 0 || xrow
>= lbuf_len(xb
))
1036 xrow
= lbuf_len(xb
) ? lbuf_len(xb
) - 1 : 0;
1037 if (xrow
< xtop
|| xrow
>= xtop
+ xrows
) {
1038 xtop
= xrow
< xtop
? xrow
: MAX(0, xrow
- xrows
+ 1);
1043 term_pos(xrow
- xtop
, led_pos(lbuf_get(xb
, xrow
),
1044 ren_cursor(lbuf_get(xb
, xrow
), xcol
)));
1052 int main(int argc
, char *argv
[])
1058 for (i
= 1; i
< argc
&& argv
[i
][0] == '-'; i
++) {
1059 if (argv
[i
][1] == 's')
1061 if (argv
[i
][1] == 'e')
1063 if (argv
[i
][1] == 'v')
1068 snprintf(ecmd
, PATHLEN
, "e %s", argv
[i
]);