Fix wrong current column position in the status line.
[eco.git] / update.c
blobc8ae39bf33cfbf0e016a6a97c1227256ba41f4ac
1 /*
2 * Copyright (C) 2008 Diego Hernan Borghetti.
3 * Eco
4 */
6 #include <stdio.h>
8 #include "debug.h"
9 #include "term.h"
10 #include "screen.h"
11 #include "buffer.h"
12 #include "view.h"
13 #include "config.h"
14 #include "eco.h"
17 int e_update_get_tab(E_Eco *ec, int col)
19 int tab;
21 tab= 8 + ec->view->col;
22 while (tab <= col)
23 tab+= 8;
24 return(tab);
27 int e_update_line(E_Eco *ec, E_Line *ln, int row)
29 int i, col, tab;
30 int fgcol, bgcol;
32 if (ec->view->b->line == ln) {
33 fgcol= e_config_get_int("Screen", "current_line_foreground");
34 bgcol= e_config_get_int("Screen", "current_line_background");
35 if (fgcol == -1)
36 fgcol= E_TR_YELLOW;
37 if (bgcol == -1)
38 bgcol= E_TR_BLACK;
40 e_screen_color(ec->sc, row, fgcol, bgcol);
41 i= ec->view->b->dot_pad;
43 else {
44 e_screen_color(ec->sc, row, E_TR_WHITE, E_TR_BLACK);
45 i= 0;
48 for (col= ec->view->col; col < ec->view->rcol && i < ln->used; i++, col++) {
49 if (ln->text[i] == '\t') {
50 tab= e_update_get_tab(ec, col);
51 while (col != tab) {
52 e_screen_move(ec->sc, row, col);
53 e_screen_putc(ec->sc, ' ');
54 col++;
56 col--;
58 else {
59 e_screen_move(ec->sc, row, col);
60 if (ln->text[i] >= 0x20 && ln->text[i] < 0x7f)
61 e_screen_putc(ec->sc, ln->text[i]);
62 else
63 e_screen_putc(ec->sc, ' ');
67 /* clean the rest of the line. */
68 if (col < ec->view->rcol) {
69 e_screen_move(ec->sc, row, col);
70 e_screen_eeol(ec->sc);
72 return(row);
75 int __get_real_col(E_Eco *ec, E_Line *ln, int dot)
77 int col, i;
79 for (i= dot, col= ec->view->col; i < ec->view->b->dot; i++) {
80 if (ec->view->b->line->text[i] == '\t')
81 col= e_update_get_tab(ec, col);
82 else
83 col++;
85 return(col);
88 void __reframe(E_Eco *ec)
90 E_Line *p;
91 int row, col, found, i;
93 /* check if we need pad the dot. */
94 col= __get_real_col(ec, ec->view->b->line, 0);
95 ec->view->b->dot_pad= 0;
97 while (col > ec->view->rcol) {
98 /* ok we need pad this, but go one-by-one so the
99 * left/right keys work fine.
101 ec->view->b->dot_pad++;
102 col= __get_real_col(ec, ec->view->b->line, ec->view->b->dot_pad);
105 p= ec->view->b->first;
106 row= ec->view->row;
107 found= 0;
108 while (p) {
109 if (p == ec->view->b->line) {
110 found= 1;
111 break;
114 row++;
115 p= p->next;
118 e_debug_printf("Check if need reframe\n");
120 * This can happen, the current line is before
121 * the first line and from the first to the end
122 * is < nrow, so need be sure.
124 if ((row < ec->view->rrow) && (found))
125 return;
128 * The first line of the buffer is out of the screen,
129 * need re-frame it.
130 * The easy why is just make the current line, the first
131 * line of the buffer, so we have a complet scroll, but
132 * we can define some number here, so the user can
133 * set the number of line to scroll.
135 ec->view->b->first= ec->view->b->line;
136 for (i= 0; i < 3; i++) {
137 if (!ec->view->b->first->prev)
138 break;
139 ec->view->b->first= ec->view->b->first->prev;
141 e_debug_printf("Reframe buffer\n");
144 void e_update_cursor(E_Eco *ec)
146 E_Line *p;
147 int row, col;
150 * This function sync the physical and virtual
151 * cursor position, assume that the buffer don't
152 * need reframe.
154 * First, match the current row.
156 row= ec->view->row;
157 p= ec->view->b->first;
158 while (p) {
159 if (p == ec->view->b->line)
160 break;
162 row++;
163 p= p->next;
166 /* second check if the line is "extend" or not. */
167 col= __get_real_col(ec, ec->view->b->line, 0);
169 if (col > ec->view->rcol)
170 col= __get_real_col(ec, ec->view->b->line, ec->view->b->dot_pad);
172 e_screen_move(ec->sc, row, col);
173 e_term_move(row, col);
176 void e_update(E_Eco *ec)
178 E_View *v, *vp;
179 E_Line *ln;
180 int row;
182 /* first save the active view. */
183 v= ec->view;
185 /* now update all the view that are show and need redraw. */
186 vp= ec->view_list;
187 while (vp) {
188 if ((vp->flag & VIEW_REDRAW) && (vp->flag & VIEW_SHOW)) {
189 /* make the active, just for draw. */
190 ec->view= vp;
192 /* check for scroll. */
193 __reframe(ec);
195 ln= ec->view->b->first;
196 row= ec->view->row;
197 while (ln && (row < ec->view->rrow)) {
198 row= e_update_line(ec, ln, row);
199 row++;
200 ln= ln->next;
203 /* fill the unused lines. */
204 while (row < ec->view->rrow) {
205 e_screen_move(ec->sc, row, ec->view->col);
206 e_screen_putc(ec->sc, '~');
207 e_screen_move(ec->sc, row, ec->view->col+1);
208 e_screen_eeol(ec->sc);
209 row++;
212 vp->flag &= ~VIEW_REDRAW;
214 vp= vp->next;
217 /* restore the active view. */
218 ec->view= v;
219 e_update_cursor(ec);