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 );
@@ -1217,6 +1228,48 @@ term_update_window(win_T *wp)
12171228 return OK ;
12181229}
12191230
1231+ /*
1232+ * Return TRUE if "wp" is a terminal window where the job has finished.
1233+ */
1234+ int
1235+ term_is_finished (buf_T * buf )
1236+ {
1237+ return buf -> b_term != NULL && buf -> b_term -> tl_vterm == NULL ;
1238+ }
1239+
1240+ /*
1241+ * The current buffer is going to be changed. If there is terminal
1242+ * highlighting remove it now.
1243+ */
1244+ void
1245+ term_change_in_curbuf (void )
1246+ {
1247+ term_T * term = curbuf -> b_term ;
1248+
1249+ if (term_is_finished (curbuf ) && term -> tl_scrollback .ga_len > 0 )
1250+ {
1251+ free_scrollback (term );
1252+ redraw_buf_later (term -> tl_buffer , NOT_VALID );
1253+ }
1254+ }
1255+
1256+ /*
1257+ * Get the screen attribute for a position in the buffer.
1258+ */
1259+ int
1260+ term_get_attr (buf_T * buf , linenr_T lnum , int col )
1261+ {
1262+ term_T * term = buf -> b_term ;
1263+ sb_line_T * line ;
1264+
1265+ if (lnum >= term -> tl_scrollback .ga_len )
1266+ return 0 ;
1267+ line = (sb_line_T * )term -> tl_scrollback .ga_data + lnum - 1 ;
1268+ if (col >= line -> sb_cols )
1269+ return 0 ;
1270+ return cell2attr (line -> sb_cells + col );
1271+ }
1272+
12201273/*
12211274 * Set job options common for Unix and MS-Windows.
12221275 */
0 commit comments