1919 * Uses pseudo-tty's (pty's).
2020 *
2121 * For each terminal one VTerm is constructed. This uses libvterm. A copy of
22- * that library is in the libvterm directory.
22+ * this library is in the libvterm directory.
2323 *
2424 * When a terminal window is opened, a job is started that will be connected to
2525 * the terminal emulator.
3232 * line range is stored in tl_dirty_row_start and tl_dirty_row_end. Once in a
3333 * while, if the terminal window is visible, the screen contents is drawn.
3434 *
35+ * When the job ends the text is put in a buffer. Redrawing then happens from
36+ * that buffer, attributes come from the scrollback buffer tl_scrollback.
37+ *
3538 * TODO:
39+ * - Patch for functions: Yasuhiro Matsumoto, #1871
3640 * - For the scrollback buffer store lines in the buffer, only attributes in
3741 * tl_scrollback.
3842 * - When the job ends:
39- * - Display the scrollback buffer (but with attributes).
40- * Make the buffer not modifiable, drop attributes when making changes.
4143 * - Need an option or argument to drop the window+buffer right away, to be
4244 * used for a shell or Vim.
4345 * - To set BS correctly, check get_stty(); Pass the fd of the pty.
44- * - Patch for functions: Yasuhiro Matsumoto, #1871
4546 * - do not store terminal buffer in viminfo. Or prefix term:// ?
4647 * - add a character in :ls output
4748 * - when closing window and job has not ended, make terminal hidden?
@@ -253,6 +254,19 @@ ex_terminal(exarg_T *eap)
253254 /* TODO: Setup pty, see mch_call_shell(). */
254255}
255256
257+ /*
258+ * Free the scrollback buffer for "term".
259+ */
260+ static void
261+ free_scrollback (term_T * term )
262+ {
263+ int i ;
264+
265+ for (i = 0 ; i < term -> tl_scrollback .ga_len ; ++ i )
266+ vim_free (((sb_line_T * )term -> tl_scrollback .ga_data + i )-> sb_cells );
267+ ga_clear (& term -> tl_scrollback );
268+ }
269+
256270/*
257271 * Free a terminal and everything it refers to.
258272 * Kills the job if there is one.
@@ -263,7 +277,6 @@ free_terminal(buf_T *buf)
263277{
264278 term_T * term = buf -> b_term ;
265279 term_T * tp ;
266- int i ;
267280
268281 if (term == NULL )
269282 return ;
@@ -285,9 +298,7 @@ free_terminal(buf_T *buf)
285298 job_unref (term -> tl_job );
286299 }
287300
288- for (i = 0 ; i < term -> tl_scrollback .ga_len ; ++ i )
289- vim_free (((sb_line_T * )term -> tl_scrollback .ga_data + i ) -> sb_cells );
290- ga_clear (& term -> tl_scrollback );
301+ free_scrollback (term );
291302
292303 term_free_vterm (term );
293304 vim_free (term -> tl_title );
@@ -1222,6 +1233,48 @@ term_update_window(win_T *wp)
12221233 return OK ;
12231234}
12241235
1236+ /*
1237+ * Return TRUE if "wp" is a terminal window where the job has finished.
1238+ */
1239+ int
1240+ term_is_finished (buf_T * buf )
1241+ {
1242+ return buf -> b_term != NULL && buf -> b_term -> tl_vterm == NULL ;
1243+ }
1244+
1245+ /*
1246+ * The current buffer is going to be changed. If there is terminal
1247+ * highlighting remove it now.
1248+ */
1249+ void
1250+ term_change_in_curbuf (void )
1251+ {
1252+ term_T * term = curbuf -> b_term ;
1253+
1254+ if (term_is_finished (curbuf ) && term -> tl_scrollback .ga_len > 0 )
1255+ {
1256+ free_scrollback (term );
1257+ redraw_buf_later (term -> tl_buffer , NOT_VALID );
1258+ }
1259+ }
1260+
1261+ /*
1262+ * Get the screen attribute for a position in the buffer.
1263+ */
1264+ int
1265+ term_get_attr (buf_T * buf , linenr_T lnum , int col )
1266+ {
1267+ term_T * term = buf -> b_term ;
1268+ sb_line_T * line ;
1269+
1270+ if (lnum >= term -> tl_scrollback .ga_len )
1271+ return 0 ;
1272+ line = (sb_line_T * )term -> tl_scrollback .ga_data + lnum - 1 ;
1273+ if (col >= line -> sb_cols )
1274+ return 0 ;
1275+ return cell2attr (line -> sb_cells + col );
1276+ }
1277+
12251278/*
12261279 * Set job options common for Unix and MS-Windows.
12271280 */
@@ -1559,7 +1612,7 @@ term_free_vterm(term_T *term)
15591612 term -> tl_winpty_config = NULL ;
15601613 if (term -> tl_vterm != NULL )
15611614 vterm_free (term -> tl_vterm );
1562- term -> tl_vterm = NULL
1615+ term -> tl_vterm = NULL ;
15631616}
15641617
15651618/*
0 commit comments