@@ -201,12 +201,18 @@ static LineInfo *get_lineinfo(Term *term, int row) {
201
201
}
202
202
static bool is_eol (Term * term , int end_col , int row , int col ) {
203
203
/* This cell is EOL if this and every cell to the right is black */
204
- VTermScreenCell cell ;
205
- for (int c = col ; c < end_col ; c ++ ) {
206
- fetch_cell (term , row , c , & cell );
207
- if (!(!cell .chars [0 ] || (cell .width == 1 && cell .chars [0 ] == ' ' ))) {
204
+ if (row >= 0 ) {
205
+ VTermPos pos = {.row = row , .col = col };
206
+ return vterm_screen_is_eol (term -> vts , pos );
207
+ }
208
+
209
+ ScrollbackLine * sbrow = term -> sb_buffer [- row - 1 ];
210
+ int c ;
211
+ for (c = col ; c < end_col && c < sbrow -> cols ;) {
212
+ if (sbrow -> cells [c ].chars [0 ]) {
208
213
return 0 ;
209
214
}
215
+ c += sbrow -> cells [c ].width ;
210
216
}
211
217
return 1 ;
212
218
}
@@ -226,8 +232,8 @@ static int is_end_of_prompt(Term *term, int end_col, int row, int col) {
226
232
}
227
233
return 0 ;
228
234
}
229
- static void goto_col ( Term * term , emacs_env * env , int row , int end_col ,
230
- bool insert_beyond_eol ) {
235
+
236
+ static void goto_col ( Term * term , emacs_env * env , int row , int end_col ) {
231
237
int col = 0 ;
232
238
size_t offset = 0 ;
233
239
size_t beyond_eol = 0 ;
@@ -242,9 +248,6 @@ static void goto_col(Term *term, emacs_env *env, int row, int end_col,
242
248
if (cell .chars [0 ]) {
243
249
if (cell .width > 1 ) {
244
250
offset += cell .width - 1 ;
245
- } else if (is_eol (term , term -> width , row , col )) {
246
- beyond_eol += cell .width ;
247
- offset += cell .width ;
248
251
}
249
252
} else {
250
253
if (is_eol (term , term -> width , row , col )) {
@@ -254,15 +257,11 @@ static void goto_col(Term *term, emacs_env *env, int row, int end_col,
254
257
}
255
258
col += cell .width ;
256
259
}
257
- int n = end_col - offset ;
258
- if (!insert_beyond_eol )
259
- n += beyond_eol ;
260
- forward_char (env , env -> make_integer (env , n ));
261
- if (insert_beyond_eol ) {
262
- emacs_value space = env -> make_string (env , " " , 1 );
263
- for (int i = 0 ; i < beyond_eol ; i += 1 )
264
- insert (env , space );
265
- }
260
+
261
+ forward_char (env , env -> make_integer (env , end_col - offset ));
262
+ emacs_value space = env -> make_string (env , " " , 1 );
263
+ for (int i = 0 ; i < beyond_eol ; i += 1 )
264
+ insert (env , space );
266
265
}
267
266
268
267
static void refresh_lines (Term * term , emacs_env * env , int start_row ,
@@ -274,95 +273,53 @@ static void refresh_lines(Term *term, emacs_env *env, int start_row,
274
273
275
274
#define PUSH_BUFFER (c ) \
276
275
do { \
277
- if (length + spacelength == capacity) { \
276
+ if (length == capacity) { \
278
277
capacity += end_col * 4; \
279
278
buffer = realloc(buffer, capacity * sizeof(char)); \
280
279
} \
281
- if (c == ' ') { \
282
- buffer[length + spacelength] = ' '; \
283
- spacelength++; \
284
- } else { \
285
- /* only increase the line length if the last character is not \
286
- * whitespace*/ \
287
- buffer [length + spacelength ] = (c ); \
288
- length += 1 + spacelength ; \
289
- spacelength = 0 ; \
290
- } \
280
+ buffer[length] = (c); \
281
+ length++; \
291
282
} while (0)
292
283
293
284
int capacity = ((end_row - start_row + 1 ) * end_col ) * 4 ;
294
285
int length = 0 ;
295
- int spacelength = 0 ; // count of trailing whitespace
296
286
char * buffer = malloc (capacity * sizeof (char ));
297
287
VTermScreenCell cell ;
298
288
VTermScreenCell lastCell ;
299
289
fetch_cell (term , start_row , 0 , & lastCell );
300
290
301
291
for (i = start_row ; i < end_row ; i ++ ) {
302
- spacelength = 0 ;
292
+
303
293
int newline = 0 ;
304
- int isprompt = 0 ; // is end of prompt
294
+ int isprompt = 0 ;
305
295
for (j = 0 ; j < end_col ; j ++ ) {
306
296
fetch_cell (term , i , j , & cell );
307
- // This cell is EOL if this and every cell to the right is black
308
- bool eol = is_eol (term , end_col , i , j );
309
- if (isprompt ) { // previous cell is prompt
310
- if (length > 0 ) { // if the prompt char is not whitespace
311
- emacs_value text = render_text (env , term , buffer , length , & lastCell );
312
- insert (env , render_prompt (env , text ));
313
- memmove (buffer , buffer + length , spacelength );
314
- length = 0 ;
315
- } else if (spacelength > 0 && !eol ) {
316
- // if the prompt char is whitespace and the cell is not at the end of
317
- // line, then render the whitespace as prompt
318
- emacs_value text =
319
- render_text (env , term , buffer , length + spacelength , & lastCell );
320
- insert (env , render_prompt (env , text ));
321
- length = 0 ;
322
- spacelength = 0 ;
323
- } else if (eol ) {
324
- // trim trailing whitespace at end of line
325
- // and the prompt would be rendered after break
326
- spacelength = 0 ;
327
- PUSH_BUFFER ('\n' );
328
- newline = 1 ;
329
- break ;
330
- }
297
+ if (isprompt && length > 0 ) {
298
+ emacs_value text = render_text (env , term , buffer , length , & lastCell );
299
+ insert (env , render_prompt (env , text ));
300
+ length = 0 ;
331
301
}
332
302
333
303
isprompt = is_end_of_prompt (term , end_col , i , j );
334
- if (isprompt && length + spacelength > 0 ) {
335
- insert (env ,
336
- render_text (env , term , buffer , length + spacelength , & lastCell ));
304
+ if (isprompt && length > 0 ) {
305
+ insert (env , render_text (env , term , buffer , length , & lastCell ));
337
306
length = 0 ;
338
- spacelength = 0 ;
339
307
}
340
308
341
309
if (!compare_cells (& cell , & lastCell )) {
342
- if (eol ) {
343
- emacs_value text = render_text (env , term , buffer , length , & lastCell );
344
- insert (env , text );
345
- // move the trailing whitespace to the start of buffer
346
- memmove (buffer , buffer + length , spacelength );
347
- length = 0 ;
348
- } else {
349
- emacs_value text =
350
- render_text (env , term , buffer , length + spacelength , & lastCell );
351
- insert (env , text );
352
- spacelength = 0 ;
353
- length = 0 ;
354
- }
310
+ emacs_value text = render_text (env , term , buffer , length , & lastCell );
311
+ insert (env , text );
312
+ length = 0 ;
355
313
}
356
- lastCell = cell ;
357
314
358
- if (eol ) {
359
- // trim trailing whitespace at end of line
360
- spacelength = 0 ;
361
- PUSH_BUFFER ('\n' );
362
- newline = 1 ;
363
- break ;
364
- }
315
+ lastCell = cell ;
365
316
if (cell .chars [0 ] == 0 ) {
317
+ if (is_eol (term , end_col , i , j )) {
318
+ /* This cell is EOL if this and every cell to the right is black */
319
+ PUSH_BUFFER ('\n' );
320
+ newline = 1 ;
321
+ break ;
322
+ }
366
323
PUSH_BUFFER (' ' );
367
324
} else {
368
325
for (int k = 0 ; k < VTERM_MAX_CHARS_PER_CELL && cell .chars [k ]; ++ k ) {
@@ -378,21 +335,18 @@ static void refresh_lines(Term *term, emacs_env *env, int start_row,
378
335
int w = cell .width - 1 ;
379
336
j = j + w ;
380
337
}
381
- } // end of range of columns
382
- if (isprompt && length + spacelength > 0 ) {
383
- emacs_value text =
384
- render_text (env , term , buffer , length + spacelength , & lastCell );
338
+ }
339
+ if (isprompt && length > 0 ) {
340
+ emacs_value text = render_text (env , term , buffer , length , & lastCell );
385
341
insert (env , render_prompt (env , text ));
386
342
length = 0 ;
387
- spacelength = 0 ;
388
343
isprompt = 0 ;
389
344
}
390
345
391
346
if (!newline ) {
392
347
emacs_value text = render_text (env , term , buffer , length , & lastCell );
393
348
insert (env , text );
394
349
length = 0 ;
395
- spacelength = 0 ;
396
350
text = render_fake_newline (env , term );
397
351
insert (env , text );
398
352
}
@@ -532,7 +486,7 @@ static void adjust_topline(Term *term, emacs_env *env) {
532
486
*/
533
487
534
488
goto_line (env , pos .row - term -> height );
535
- goto_col (term , env , pos .row , pos .col , true );
489
+ goto_col (term , env , pos .row , pos .col );
536
490
537
491
emacs_value windows = get_buffer_window_list (env );
538
492
emacs_value swindow = selected_window (env );
@@ -1439,7 +1393,7 @@ emacs_value Fvterm_reset_cursor_point(emacs_env *env, ptrdiff_t nargs,
1439
1393
Term * term = env -> get_user_ptr (env , args [0 ]);
1440
1394
int line = row_to_linenr (term , term -> cursor .row );
1441
1395
goto_line (env , line );
1442
- goto_col (term , env , term -> cursor .row , term -> cursor .col , false );
1396
+ goto_col (term , env , term -> cursor .row , term -> cursor .col );
1443
1397
return point (env );
1444
1398
}
1445
1399
@@ -1558,5 +1512,6 @@ int emacs_module_init(struct emacs_runtime *ert) {
1558
1512
bind_function (env , "vterm--get-icrnl" , fun );
1559
1513
1560
1514
provide (env , "vterm-module" );
1515
+
1561
1516
return 0 ;
1562
1517
}
0 commit comments