Annotation of src/usr.bin/vim/linefunc.c, Revision 1.1.1.1
1.1 downsj 1: /* $OpenBSD$ */
2: /* vi:set ts=4 sw=4:
3: *
4: * VIM - Vi IMproved by Bram Moolenaar
5: *
6: * Do ":help uganda" in Vim to read copying and usage conditions.
7: * Do ":help credits" in Vim to see a list of people who contributed.
8: */
9:
10: /*
11: * linefunc.c: some functions to move to the next/previous line and
12: * to the next/previous character
13: */
14:
15: #include "vim.h"
16: #include "globals.h"
17: #include "proto.h"
18:
19: /*
20: * coladvance(col)
21: *
22: * Try to advance the Cursor to the specified column.
23: *
24: * return OK if desired column is reached, FAIL if not
25: */
26:
27: int
28: coladvance(wcol)
29: colnr_t wcol;
30: {
31: int idx;
32: register char_u *ptr;
33: register colnr_t col;
34:
35: ptr = ml_get_curline();
36:
37: /* try to advance to the specified column */
38: idx = -1;
39: col = 0;
40: while (col <= wcol && *ptr)
41: {
42: ++idx;
43: /* Count a tab for what it's worth (if list mode not on) */
44: col += lbr_chartabsize(ptr, col);
45: ++ptr;
46: }
47: /*
48: * in insert mode it is allowed to be one char beyond the end of the line
49: */
50: if ((State & INSERT) && col <= wcol)
51: ++idx;
52: if (idx < 0)
53: curwin->w_cursor.col = 0;
54: else
55: curwin->w_cursor.col = idx;
56: if (col <= wcol)
57: return FAIL; /* Couldn't reach column */
58: else
59: return OK; /* Reached column */
60: }
61:
62: /*
63: * inc(p)
64: *
65: * Increment the line pointer 'p' crossing line boundaries as necessary.
66: * Return 1 when crossing a line, -1 when at end of file, 0 otherwise.
67: */
68: int
69: inc_cursor()
70: {
71: return inc(&curwin->w_cursor);
72: }
73:
74: int
75: inc(lp)
76: register FPOS *lp;
77: {
78: register char_u *p = ml_get_pos(lp);
79:
80: if (*p != NUL) /* still within line, move to next char (may be NUL) */
81: {
82: lp->col++;
83: return ((p[1] != NUL) ? 0 : 1);
84: }
85: if (lp->lnum != curbuf->b_ml.ml_line_count) /* there is a next line */
86: {
87: lp->col = 0;
88: lp->lnum++;
89: return 1;
90: }
91: return -1;
92: }
93:
94: /*
95: * incl(lp): same as inc(), but skip the NUL at the end of non-empty lines
96: */
97: int
98: incl(lp)
99: register FPOS *lp;
100: {
101: register int r;
102:
103: if ((r = inc(lp)) == 1 && lp->col)
104: r = inc(lp);
105: return r;
106: }
107:
108: /*
109: * dec(p)
110: *
111: * Decrement the line pointer 'p' crossing line boundaries as necessary.
112: * Return 1 when crossing a line, -1 when at start of file, 0 otherwise.
113: */
114: int
115: dec_cursor()
116: {
117: return dec(&curwin->w_cursor);
118: }
119:
120: int
121: dec(lp)
122: register FPOS *lp;
123: {
124: if (lp->col > 0)
125: { /* still within line */
126: lp->col--;
127: return 0;
128: }
129: if (lp->lnum > 1)
130: { /* there is a prior line */
131: lp->lnum--;
132: lp->col = STRLEN(ml_get(lp->lnum));
133: return 1;
134: }
135: return -1; /* at start of file */
136: }
137:
138: /*
139: * decl(lp): same as dec(), but skip the NUL at the end of non-empty lines
140: */
141: int
142: decl(lp)
143: register FPOS *lp;
144: {
145: register int r;
146:
147: if ((r = dec(lp)) == 1 && lp->col)
148: r = dec(lp);
149: return r;
150: }
151:
152: /*
153: * make sure curwin->w_cursor in on a valid character
154: */
155: void
156: adjust_cursor()
157: {
158: colnr_t len;
159:
160: if (curwin->w_cursor.lnum == 0)
161: curwin->w_cursor.lnum = 1;
162: if (curwin->w_cursor.lnum > curbuf->b_ml.ml_line_count)
163: curwin->w_cursor.lnum = curbuf->b_ml.ml_line_count;
164:
165: len = STRLEN(ml_get_curline());
166: if (len == 0)
167: curwin->w_cursor.col = 0;
168: else if (curwin->w_cursor.col >= len)
169: curwin->w_cursor.col = len - 1;
170: }