4 * Copyright (C) 2015 Ali Gholami Rudi <ali at rudi dot ir>
6 * This program is released under the Modified BSD license.
15 char vi_msg
[512]; /* current message */
16 static char vi_findlast
[256]; /* the last searched keyword */
17 static int vi_finddir
; /* the last search direction */
18 static char vi_charlast
[8]; /* the last character searched via f, t, F, or T */
19 static int vi_charcmd
; /* the character finding command */
20 static int vi_arg1
, vi_arg2
; /* the first and second arguments */
21 static int vi_ybuf
; /* current yank buffer */
22 static char *vi_kmap
; /* current insertion keymap */
23 static int vi_pcol
; /* the column requested by | command */
25 static void vi_drawmsg(void)
27 led_print(vi_msg
, xrows
);
31 static void vi_draw(int xcol
)
35 for (i
= xtop
; i
< xtop
+ xrows
; i
++) {
36 char *s
= lbuf_get(xb
, i
);
37 led_print(s
? s
: (i
? "~" : ""), i
- xtop
);
40 term_pos(xrow
, led_pos(lbuf_get(xb
, i
), xcol
));
44 static int vi_buf
[128];
47 static int vi_read(void)
49 return vi_buflen
? vi_buf
[--vi_buflen
] : term_read(1000);
52 static void vi_back(int c
)
54 if (vi_buflen
< sizeof(vi_buf
))
55 vi_buf
[vi_buflen
++] = c
;
58 static char *vi_char(void)
60 return led_read(&vi_kmap
);
63 static char *vi_prompt(char *msg
, char **kmap
)
65 term_pos(xrows
, led_pos(msg
, 0));
67 return led_prompt(msg
, "", kmap
);
70 char *ex_read(char *msg
)
75 char *s
= led_prompt(msg
, "", &vi_kmap
);
81 while ((c
= getchar()) != EOF
&& c
!= '\n')
90 void ex_show(char *msg
)
93 snprintf(vi_msg
, sizeof(vi_msg
), "%s", msg
);
102 static int vi_yankbuf(void)
111 static int vi_prefix(void)
115 if ((c
>= '1' && c
<= '9')) {
117 n
= n
* 10 + c
- '0';
125 static int vi_col2off(struct lbuf
*lb
, int row
, int col
)
127 char *ln
= lbuf_get(lb
, row
);
128 return ln
? ren_off(ln
, col
) : 0;
131 static int vi_off2col(struct lbuf
*lb
, int row
, int off
)
133 char *ln
= lbuf_get(lb
, row
);
134 return ln
? ren_pos(ln
, off
) : 0;
137 static int vi_nextoff(struct lbuf
*lb
, int dir
, int *row
, int *off
)
140 if (o
< 0 || !lbuf_get(lb
, *row
) || o
>= uc_slen(lbuf_get(lb
, *row
)))
146 static int vi_nextcol(struct lbuf
*lb
, int dir
, int *row
, int *off
)
148 char *ln
= lbuf_get(lb
, *row
);
149 int col
= ln
? ren_pos(ln
, *off
) : 0;
150 int o
= ln
? ren_next(ln
, col
, dir
) : -1;
153 *off
= ren_off(ln
, o
);
157 static int vi_findchar(struct lbuf
*lb
, char *cs
, int cmd
, int n
, int *row
, int *off
)
159 strcpy(vi_charlast
, cs
);
161 return lbuf_findchar(lb
, cs
, cmd
, n
, row
, off
);
164 static int vi_search(int cmd
, int cnt
, int *row
, int *off
)
172 if (cmd
== '/' || cmd
== '?') {
173 char sign
[4] = {cmd
};
174 char *kw
= vi_prompt(sign
, &vi_kmap
);
177 vi_finddir
= cmd
== '/' ? +1 : -1;
179 snprintf(vi_findlast
, sizeof(vi_findlast
), "%s", kw
);
180 if (strchr(vi_findlast
, cmd
)) {
181 soff
= strchr(vi_findlast
, cmd
) + 1;
182 *strchr(vi_findlast
, cmd
) = '\0';
186 dir
= cmd
== 'N' ? -vi_finddir
: vi_finddir
;
187 if (!vi_findlast
[0] || !lbuf_len(xb
))
190 for (i
= 0; i
< cnt
; i
++) {
191 if (lbuf_search(xb
, vi_findlast
, dir
, &r
, &o
, &len
)) {
195 if (i
+ 1 < cnt
&& cmd
== '/')
201 while (soff
[0] && isspace((unsigned char) soff
[0]))
205 if (*row
+ atoi(soff
) < 0 || *row
+ atoi(soff
) >= lbuf_len(xb
))
212 snprintf(vi_msg
, sizeof(vi_msg
), "\"%s\" not found\n", vi_findlast
);
216 /* read a line motion */
217 static int vi_motionln(int *row
, int cmd
)
219 int cnt
= (vi_arg1
? vi_arg1
: 1) * (vi_arg2
? vi_arg2
: 1);
221 int mark
, mark_row
, mark_off
;
225 *row
= MIN(*row
+ cnt
, lbuf_len(xb
) - 1);
228 *row
= MAX(*row
- cnt
, 0);
231 *row
= MIN(*row
+ cnt
- 1, lbuf_len(xb
) - 1);
234 if ((mark
= vi_read()) <= 0)
236 if (!islower(mark
) && !strchr("'`", mark
))
238 if (lbuf_markpos(xb
, mark
, &mark_row
, &mark_off
))
243 *row
= MIN(*row
+ cnt
, lbuf_len(xb
) - 1);
246 *row
= MAX(*row
- cnt
, 0);
249 *row
= (vi_arg1
|| vi_arg2
) ? cnt
- 1 : lbuf_len(xb
) - 1;
253 *row
= MIN(xtop
+ cnt
- 1, lbuf_len(xb
) - 1);
259 *row
= MIN(xtop
+ xrows
- 1 - cnt
+ 1, lbuf_len(xb
) - 1);
265 *row
= MIN(xtop
+ xrows
/ 2, lbuf_len(xb
) - 1);
271 *row
= MAX(0, MIN(*row
+ cnt
- 1, lbuf_len(xb
) - 1));
280 static char *vi_curword(struct lbuf
*lb
, int row
, int off
)
283 char *ln
= lbuf_get(lb
, row
);
287 beg
= uc_chr(ln
, ren_noeol(ln
, off
));
289 while (*end
&& uc_kind(end
) == 1)
291 while (beg
> ln
&& uc_kind(uc_beg(ln
, beg
- 1)) == 1)
292 beg
= uc_beg(ln
, beg
- 1);
297 sbuf_mem(sb
, beg
, end
- beg
);
299 return sbuf_done(sb
);
303 static int vi_motion(int *row
, int *off
)
305 int cnt
= (vi_arg1
? vi_arg1
: 1) * (vi_arg2
? vi_arg2
: 1);
306 char *ln
= lbuf_get(xb
, *row
);
307 int dir
= dir_context(ln
? ln
: "");
308 int mark
, mark_row
, mark_off
;
312 if ((mv
= vi_motionln(row
, 0))) {
319 if (!(cs
= vi_char()))
321 if (vi_findchar(xb
, cs
, mv
, cnt
, row
, off
))
325 if (!(cs
= vi_char()))
327 if (vi_findchar(xb
, cs
, mv
, cnt
, row
, off
))
333 if (vi_findchar(xb
, vi_charlast
, vi_charcmd
, cnt
, row
, off
))
339 if (vi_findchar(xb
, vi_charlast
, vi_charcmd
, -cnt
, row
, off
))
343 for (i
= 0; i
< cnt
; i
++)
344 if (vi_nextcol(xb
, -1 * dir
, row
, off
))
348 for (i
= 0; i
< cnt
; i
++)
349 if (vi_nextcol(xb
, +1 * dir
, row
, off
))
353 if (!(cs
= vi_char()))
355 if (vi_findchar(xb
, cs
, mv
, cnt
, row
, off
))
359 if (!(cs
= vi_char()))
361 if (vi_findchar(xb
, cs
, mv
, cnt
, row
, off
))
365 for (i
= 0; i
< cnt
; i
++)
366 if (lbuf_wordend(xb
, 1, -1, row
, off
))
370 for (i
= 0; i
< cnt
; i
++)
371 if (lbuf_wordend(xb
, 1, +1, row
, off
))
375 for (i
= 0; i
< cnt
; i
++)
376 if (lbuf_wordbeg(xb
, 1, +1, row
, off
))
380 for (i
= 0; i
< cnt
; i
++)
381 if (lbuf_wordend(xb
, 0, -1, row
, off
))
385 for (i
= 0; i
< cnt
; i
++)
386 if (lbuf_wordend(xb
, 0, +1, row
, off
))
390 for (i
= 0; i
< cnt
; i
++)
391 if (lbuf_wordbeg(xb
, 0, +1, row
, off
))
395 for (i
= 0; i
< cnt
; i
++)
396 if (lbuf_paragraphbeg(xb
, -1, row
, off
))
400 for (i
= 0; i
< cnt
; i
++)
401 if (lbuf_paragraphbeg(xb
, +1, row
, off
))
405 if (vi_read() != '[')
407 for (i
= 0; i
< cnt
; i
++)
408 if (lbuf_sectionbeg(xb
, -1, row
, off
))
412 if (vi_read() != ']')
414 for (i
= 0; i
< cnt
; i
++)
415 if (lbuf_sectionbeg(xb
, +1, row
, off
))
422 *off
= lbuf_indents(xb
, *row
);
425 *off
= lbuf_eol(xb
, *row
);
428 *off
= vi_col2off(xb
, *row
, cnt
- 1);
432 if (vi_search(mv
, cnt
, row
, off
))
436 if (vi_search(mv
, cnt
, row
, off
))
440 if (vi_search(mv
, cnt
, row
, off
))
444 if (vi_search(mv
, cnt
, row
, off
))
448 if (!(cs
= vi_curword(xb
, *row
, *off
)))
450 strcpy(vi_findlast
, cs
);
453 if (vi_search('n', cnt
, row
, off
))
457 for (i
= 0; i
< cnt
; i
++)
458 if (vi_nextoff(xb
, +1, row
, off
))
463 for (i
= 0; i
< cnt
; i
++)
464 if (vi_nextoff(xb
, -1, row
, off
))
468 if ((mark
= vi_read()) <= 0)
470 if (!islower(mark
) && !strchr("'`", mark
))
472 if (lbuf_markpos(xb
, mark
, &mark_row
, &mark_off
))
484 static void swap(int *a
, int *b
)
491 static char *lbuf_region(struct lbuf
*lb
, int r1
, int o1
, int r2
, int o2
)
496 return uc_sub(lbuf_get(lb
, r1
), o1
, o2
);
498 s1
= uc_sub(lbuf_get(lb
, r1
), o1
, -1);
499 s3
= uc_sub(lbuf_get(lb
, r2
), 0, o2
);
500 s2
= lbuf_cp(lb
, r1
+ 1, r2
);
507 return sbuf_done(sb
);
510 static void vi_yank(int r1
, int o1
, int r2
, int o2
, int lnmode
)
513 region
= lbuf_region(xb
, r1
, lnmode
? 0 : o1
, r2
, lnmode
? -1 : o2
);
514 reg_put(vi_ybuf
, region
, lnmode
);
517 xoff
= lnmode
? xoff
: o1
;
520 static void vi_delete(int r1
, int o1
, int r2
, int o2
, int lnmode
)
524 region
= lbuf_region(xb
, r1
, lnmode
? 0 : o1
, r2
, lnmode
? -1 : o2
);
525 reg_put(vi_ybuf
, region
, lnmode
);
527 pref
= lnmode
? uc_dup("") : uc_sub(lbuf_get(xb
, r1
), 0, o1
);
528 post
= lnmode
? uc_dup("\n") : uc_sub(lbuf_get(xb
, r2
), o2
, -1);
529 lbuf_rm(xb
, r1
, r2
+ 1);
531 struct sbuf
*sb
= sbuf_make();
534 lbuf_put(xb
, r1
, sbuf_buf(sb
));
538 xoff
= lnmode
? lbuf_indents(xb
, xrow
) : o1
;
543 static int linecount(char *s
)
547 if ((s
= strchr(s
, '\n')))
552 static int indentscopy(char *d
, char *s
, int len
)
555 for (i
= 0; i
< len
- 1 && (s
[i
] == ' ' || s
[i
] == '\t'); i
++)
561 static char *vi_input(char *pref
, char *post
, int *row
, int *off
)
568 pref
+= indentscopy(ai
, pref
, sizeof(ai
));
569 rep
= led_input(pref
, post
, ai
, xai
? sizeof(ai
) - 1 : 0, &vi_kmap
);
577 last
= uc_lastline(s
) - s
;
578 *off
= MAX(0, uc_slen(sbuf_buf(sb
) + last
) - 1);
580 while (xai
&& (post
[0] == ' ' || post
[0] == '\t'))
583 *row
= linecount(sbuf_buf(sb
)) - 1;
585 return sbuf_done(sb
);
588 static char *vi_indents(char *ln
)
590 struct sbuf
*sb
= sbuf_make();
591 while (xai
&& ln
&& (*ln
== ' ' || *ln
== '\t'))
593 return sbuf_done(sb
);
596 static void vi_change(int r1
, int o1
, int r2
, int o2
, int lnmode
)
602 region
= lbuf_region(xb
, r1
, lnmode
? 0 : o1
, r2
, lnmode
? -1 : o2
);
603 reg_put(vi_ybuf
, region
, lnmode
);
605 pref
= lnmode
? vi_indents(lbuf_get(xb
, r1
)) : uc_sub(lbuf_get(xb
, r1
), 0, o1
);
606 post
= lnmode
? uc_dup("\n") : uc_sub(lbuf_get(xb
, r2
), o2
, -1);
607 rep
= vi_input(pref
, post
, &row
, &off
);
609 lbuf_rm(xb
, r1
, r2
+ 1);
610 lbuf_put(xb
, r1
, rep
);
619 static void vi_case(int r1
, int o1
, int r2
, int o2
, int lnmode
, int cmd
)
623 region
= lbuf_region(xb
, r1
, lnmode
? 0 : o1
, r2
, lnmode
? -1 : o2
);
626 int c
= (unsigned char) s
[0];
633 s
[0] = islower(c
) ? toupper(c
) : tolower(c
);
637 pref
= lnmode
? uc_dup("") : uc_sub(lbuf_get(xb
, r1
), 0, o1
);
638 post
= lnmode
? uc_dup("\n") : uc_sub(lbuf_get(xb
, r2
), o2
, -1);
639 lbuf_rm(xb
, r1
, r2
+ 1);
641 struct sbuf
*sb
= sbuf_make();
643 sbuf_str(sb
, region
);
645 lbuf_put(xb
, r1
, sbuf_buf(sb
));
648 lbuf_put(xb
, r1
, region
);
651 xoff
= lnmode
? lbuf_indents(xb
, r2
) : o2
;
657 static void vi_pipe(int r1
, int r2
)
662 char *cmd
= vi_prompt("!", &kmap
);
665 text
= lbuf_cp(xb
, r1
, r2
+ 1);
666 rep
= cmd_pipe(cmd
, text
);
668 lbuf_rm(xb
, r1
, r2
+ 1);
669 lbuf_put(xb
, r1
, rep
);
676 static void vi_shift(int r1
, int r2
, int dir
)
681 for (i
= r1
; i
<= r2
; i
++) {
682 if (!(ln
= lbuf_get(xb
, i
)))
688 ln
= ln
[0] == ' ' || ln
[0] == '\t' ? ln
+ 1 : ln
;
690 lbuf_rm(xb
, i
, i
+ 1);
691 lbuf_put(xb
, i
, sbuf_buf(sb
));
695 xoff
= lbuf_indents(xb
, xrow
);
698 static int vc_motion(int cmd
)
700 int r1
= xrow
, r2
= xrow
; /* region rows */
701 int o1
= xoff
, o2
= xoff
; /* visual region columns */
702 int lnmode
= 0; /* line-based region */
704 vi_arg2
= vi_prefix();
707 o1
= ren_noeol(lbuf_get(xb
, r1
), o1
);
709 if ((mv
= vi_motionln(&r2
, cmd
))) {
711 } else if (!(mv
= vi_motion(&r2
, &o2
))) {
720 o2
= lbuf_eol(xb
, r2
);
726 if (r1
== r2
&& o1
> o2
)
728 o1
= ren_noeol(lbuf_get(xb
, r1
), o1
);
729 if (!lnmode
&& strchr("fFtTeE", mv
))
730 if (o2
< lbuf_eol(xb
, r2
))
731 o2
= ren_noeol(lbuf_get(xb
, r2
), o2
) + 1;
733 vi_yank(r1
, o1
, r2
, o2
, lnmode
);
735 vi_delete(r1
, o1
, r2
, o2
, lnmode
);
737 vi_change(r1
, o1
, r2
, o2
, lnmode
);
738 if (cmd
== '~' || cmd
== 'u' || cmd
== 'U')
739 vi_case(r1
, o1
, r2
, o2
, lnmode
, cmd
);
742 if (cmd
== '>' || cmd
== '<')
743 vi_shift(r1
, r2
, cmd
== '>' ? +1 : -1);
747 static int vc_insert(int cmd
)
750 char *ln
= lbuf_get(xb
, xrow
);
754 xoff
= lbuf_indents(xb
, xrow
);
756 xoff
= lbuf_eol(xb
, xrow
);
757 xoff
= ren_noeol(ln
, xoff
);
760 if (cmd
== 'i' || cmd
== 'I')
762 if (cmd
== 'a' || cmd
== 'A')
764 pref
= ln
&& cmd
!= 'o' && cmd
!= 'O' ? uc_sub(ln
, 0, off
) : vi_indents(ln
);
765 post
= ln
&& cmd
!= 'o' && cmd
!= 'O' ? uc_sub(ln
, off
, -1) : uc_dup("\n");
766 rep
= vi_input(pref
, post
, &row
, &off
);
767 if ((cmd
== 'o' || cmd
== 'O') && !lbuf_len(xb
))
768 lbuf_put(xb
, 0, "\n");
770 if (cmd
!= 'o' && cmd
!= 'O')
771 lbuf_rm(xb
, xrow
, xrow
+ 1);
772 lbuf_put(xb
, xrow
, rep
);
782 static int vc_put(int cmd
)
784 int cnt
= MAX(1, vi_arg1
);
786 char *buf
= reg_get(vi_ybuf
, &lnmode
);
791 struct sbuf
*sb
= sbuf_make();
792 for (i
= 0; i
< cnt
; i
++)
795 lbuf_put(xb
, 0, "\n");
798 lbuf_put(xb
, xrow
, sbuf_buf(sb
));
799 xoff
= lbuf_indents(xb
, xrow
);
802 struct sbuf
*sb
= sbuf_make();
803 char *ln
= xrow
< lbuf_len(xb
) ? lbuf_get(xb
, xrow
) : "\n";
804 int off
= ren_noeol(ln
, xoff
) + (ln
[0] != '\n' && cmd
== 'p');
805 char *s
= uc_sub(ln
, 0, off
);
808 for (i
= 0; i
< cnt
; i
++)
810 s
= uc_sub(ln
, off
, -1);
813 lbuf_rm(xb
, xrow
, xrow
+ 1);
814 lbuf_put(xb
, xrow
, sbuf_buf(sb
));
815 xoff
= off
+ uc_slen(buf
) * cnt
- 1;
821 static int join_spaces(char *prev
, char *next
)
823 int prevlen
= strlen(prev
);
826 if (prev
[prevlen
- 1] == ' ' || next
[0] == ')')
828 return prev
[prevlen
- 1] == '.' ? 2 : 1;
831 static int vc_join(void)
834 int cnt
= vi_arg1
<= 1 ? 2 : vi_arg1
;
836 int end
= xrow
+ cnt
;
839 if (!lbuf_get(xb
, beg
) || !lbuf_get(xb
, end
- 1))
842 for (i
= beg
; i
< end
; i
++) {
843 char *ln
= lbuf_get(xb
, i
);
844 char *lnend
= strchr(ln
, '\n');
847 while (ln
[0] == ' ' || ln
[0] == '\t')
849 spaces
= i
> beg
? join_spaces(sbuf_buf(sb
), ln
) : 0;
850 off
= uc_slen(sbuf_buf(sb
));
853 sbuf_mem(sb
, ln
, lnend
- ln
);
856 lbuf_rm(xb
, beg
, end
);
857 lbuf_put(xb
, beg
, sbuf_buf(sb
));
863 static int vi_scrollforeward(int cnt
)
865 if (xtop
>= lbuf_len(xb
) - 1)
867 xtop
= MIN(lbuf_len(xb
) - 1, xtop
+ cnt
);
868 xrow
= MAX(xrow
, xtop
);
872 static int vi_scrollbackward(int cnt
)
876 xtop
= MAX(0, xtop
- cnt
);
877 xrow
= MIN(xrow
, xtop
+ xrows
- 1);
881 static void vc_status(void)
883 int col
= vi_off2col(xb
, xrow
, xoff
);
884 snprintf(vi_msg
, sizeof(vi_msg
), "\"%s\" line %d of %d, col %d\n",
885 xpath
[0] ? xpath
: "unnamed", xrow
+ 1, lbuf_len(xb
),
886 ren_cursor(lbuf_get(xb
, xrow
), col
) + 1);
889 static int vc_replace(void)
891 int cnt
= MAX(1, vi_arg1
);
892 char *cs
= vi_char();
893 char *ln
= lbuf_get(xb
, xrow
);
900 off
= ren_noeol(ln
, xoff
);
902 for (i
= 0; s
[0] != '\n' && i
< cnt
; i
++)
906 pref
= uc_sub(ln
, 0, off
);
907 post
= uc_sub(ln
, off
+ cnt
, -1);
910 for (i
= 0; i
< cnt
; i
++)
913 lbuf_rm(xb
, xrow
, xrow
+ 1);
914 lbuf_put(xb
, xrow
, sbuf_buf(sb
));
923 static char rep_cmd
[4096]; /* the last command */
926 static void vc_repeat(void)
928 term_push(rep_cmd
, rep_len
);
931 static void vc_execute(void)
942 buf
= reg_get(exec_buf
, &lnmode
);
944 term_push(buf
, strlen(buf
));
957 xcol
= vi_off2col(xb
, xrow
, xoff
);
959 term_pos(xrow
, led_pos(lbuf_get(xb
, xrow
), xcol
));
963 int noff
= ren_noeol(lbuf_get(xb
, xrow
), xoff
);
968 vi_ybuf
= vi_yankbuf();
969 vi_arg1
= vi_prefix();
971 vi_ybuf
= vi_yankbuf();
972 mv
= vi_motion(&nrow
, &noff
);
974 if (strchr("\'`GHML/?{}[]nN", mv
)) {
975 lbuf_mark(xb
, '\'', xrow
, xoff
);
976 lbuf_mark(xb
, '`', xrow
, xoff
);
979 if (noff
< 0 && !strchr("jk", mv
))
980 noff
= lbuf_indents(xb
, xrow
);
981 if (strchr("jk", mv
))
982 noff
= vi_col2off(xb
, xrow
, xcol
);
983 xoff
= ren_noeol(lbuf_get(xb
, xrow
), noff
);
984 if (!strchr("|jk", mv
))
985 xcol
= vi_off2col(xb
, xrow
, xoff
);
988 } else if (mv
== 0) {
996 if (vi_scrollbackward(MAX(1, vi_arg1
) * (xrows
- 1)))
998 xoff
= lbuf_indents(xb
, xrow
);
1002 if (vi_scrollforeward(MAX(1, vi_arg1
) * (xrows
- 1)))
1004 xoff
= lbuf_indents(xb
, xrow
);
1008 if (vi_scrollforeward(MAX(1, vi_arg1
)))
1013 if (vi_scrollbackward(MAX(1, vi_arg1
)))
1038 ln
= vi_prompt(":", &kmap
);
1070 if ((mark
= vi_read()) > 0 && islower(mark
))
1071 lbuf_mark(xb
, mark
, xrow
, xoff
);
1082 xtop
= vi_arg1
? vi_arg1
: xrow
;
1085 n
= vi_arg1
? vi_arg1
: xrow
;
1086 xtop
= MAX(0, n
- xrows
/ 2);
1089 n
= vi_arg1
? vi_arg1
: xrow
;
1090 xtop
= MAX(0, n
- xrows
+ 1);
1094 xdir
= z
== 'r' ? -1 : +1;
1098 xdir
= z
== 'R' ? -2 : +2;
1105 if (g
== '~' || g
== 'u' || g
== 'U')
1111 if (!vc_motion('d'))
1115 vi_back(TK_CTL('h'));
1116 if (!vc_motion('d'))
1121 if (!vc_motion('c'))
1126 if (!vc_motion('d'))
1135 if (!vc_motion('c'))
1140 if (!vc_motion('c'))
1145 if (!vc_motion('y'))
1150 if (!vc_motion('~'))
1163 if (strchr("!<>ACDIJOPRSXYacdioprsxy~", c
)) {
1164 if (n
< sizeof(rep_cmd
)) {
1165 memcpy(rep_cmd
, cmd
, n
);
1170 if (xrow
< 0 || xrow
>= lbuf_len(xb
))
1171 xrow
= lbuf_len(xb
) ? lbuf_len(xb
) - 1 : 0;
1173 xtop
= xtop
- xrows
/ 2 > xrow
?
1174 MAX(0, xrow
- xrows
/ 2) : xrow
;
1175 if (xtop
+ xrows
<= xrow
)
1176 xtop
= xtop
+ xrows
+ xrows
/ 2 <= xrow
?
1177 xrow
- xrows
/ 2 : xrow
- xrows
+ 1;
1178 xoff
= ren_noeol(lbuf_get(xb
, xrow
), xoff
);
1180 xcol
= vi_off2col(xb
, xrow
, xoff
);
1181 if (redraw
|| xtop
!= otop
)
1185 term_pos(xrow
- xtop
, led_pos(lbuf_get(xb
, xrow
),
1186 ren_cursor(lbuf_get(xb
, xrow
), xcol
)));
1194 int main(int argc
, char *argv
[])
1200 for (i
= 1; i
< argc
&& argv
[i
][0] == '-'; i
++) {
1201 if (argv
[i
][1] == 's')
1203 if (argv
[i
][1] == 'e')
1205 if (argv
[i
][1] == 'v')
1211 snprintf(ecmd
, PATHLEN
, "e %s", argv
[i
]);