Skip to content

Commit 2155441

Browse files
committed
patch 8.0.0768: terminal window status shows "[Scratch]"
Problem: Terminal window status shows "[Scratch]". Solution: Show "[Terminal]" when no title was set. (Yasuhiro Matsumoto) Store the terminal title that vterm sends and use it. Update the special buffer name. (closes #1869)
1 parent d60547b commit 2155441

4 files changed

Lines changed: 130 additions & 50 deletions

File tree

src/buffer.c

Lines changed: 36 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -3626,27 +3626,41 @@ maketitle(void)
36263626
#define SPACE_FOR_ARGNR (IOSIZE - 10) /* at least room for " - VIM" */
36273627
if (curbuf->b_fname == NULL)
36283628
vim_strncpy(buf, (char_u *)_("[No Name]"), SPACE_FOR_FNAME);
3629+
#ifdef FEAT_TERMINAL
3630+
else if (curbuf->b_term != NULL)
3631+
{
3632+
vim_strncpy(buf, term_get_status_text(curbuf->b_term),
3633+
SPACE_FOR_FNAME);
3634+
}
3635+
#endif
36293636
else
36303637
{
36313638
p = transstr(gettail(curbuf->b_fname));
36323639
vim_strncpy(buf, p, SPACE_FOR_FNAME);
36333640
vim_free(p);
36343641
}
36353642

3636-
switch (bufIsChanged(curbuf)
3637-
+ (curbuf->b_p_ro * 2)
3638-
+ (!curbuf->b_p_ma * 4))
3639-
{
3640-
case 1: STRCAT(buf, " +"); break;
3641-
case 2: STRCAT(buf, " ="); break;
3642-
case 3: STRCAT(buf, " =+"); break;
3643-
case 4:
3644-
case 6: STRCAT(buf, " -"); break;
3645-
case 5:
3646-
case 7: STRCAT(buf, " -+"); break;
3647-
}
3643+
#ifdef FEAT_TERMINAL
3644+
if (curbuf->b_term == NULL)
3645+
#endif
3646+
switch (bufIsChanged(curbuf)
3647+
+ (curbuf->b_p_ro * 2)
3648+
+ (!curbuf->b_p_ma * 4))
3649+
{
3650+
case 1: STRCAT(buf, " +"); break;
3651+
case 2: STRCAT(buf, " ="); break;
3652+
case 3: STRCAT(buf, " =+"); break;
3653+
case 4:
3654+
case 6: STRCAT(buf, " -"); break;
3655+
case 5:
3656+
case 7: STRCAT(buf, " -+"); break;
3657+
}
36483658

3649-
if (curbuf->b_fname != NULL)
3659+
if (curbuf->b_fname != NULL
3660+
#ifdef FEAT_TERMINAL
3661+
&& curbuf->b_term == NULL
3662+
#endif
3663+
)
36503664
{
36513665
/* Get path of file, replace home dir with ~ */
36523666
off = (int)STRLEN(buf);
@@ -3663,18 +3677,8 @@ maketitle(void)
36633677
p = gettail_sep(buf + off);
36643678
if (p == buf + off)
36653679
{
3666-
char *txt;
3667-
3668-
#ifdef FEAT_TERMINAL
3669-
if (curbuf->b_term != NULL)
3670-
txt = term_job_running(curbuf)
3671-
? _("running") : _("finished");
3672-
else
3673-
#endif
3674-
txt = _("help");
3675-
3676-
/* must be a help or terminal buffer */
3677-
vim_strncpy(buf + off, (char_u *)txt,
3680+
/* must be a help buffer */
3681+
vim_strncpy(buf + off, (char_u *)_("help"),
36783682
(size_t)(SPACE_FOR_DIR - off - 1));
36793683
}
36803684
else
@@ -5670,16 +5674,20 @@ buf_spname(buf_T *buf)
56705674
return (char_u *)_(msg_qflist);
56715675
}
56725676
#endif
5673-
#ifdef FEAT_QUICKFIX
5677+
56745678
/* There is no _file_ when 'buftype' is "nofile", b_sfname
5675-
* contains the name as specified by the user */
5679+
* contains the name as specified by the user. */
56765680
if (bt_nofile(buf))
56775681
{
5682+
#ifdef FEAT_TERMINAL
5683+
if (buf->b_term != NULL)
5684+
return term_get_status_text(buf->b_term);
5685+
#endif
56785686
if (buf->b_sfname != NULL)
56795687
return buf->b_sfname;
56805688
return (char_u *)_("[Scratch]");
56815689
}
5682-
#endif
5690+
56835691
if (buf->b_fname == NULL)
56845692
return (char_u *)_("[No Name]");
56855693
return NULL;

src/proto/terminal.pro

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,6 @@ void free_terminal(term_T *term);
44
void write_to_term(buf_T *buffer, char_u *msg, channel_T *channel);
55
void terminal_loop(void);
66
void term_job_ended(job_T *job);
7-
int term_job_running(buf_T *buf);
87
void term_update_window(win_T *wp);
8+
char_u *term_get_status_text(term_T *term);
99
/* vim: set ft=c : */

src/terminal.c

Lines changed: 91 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,6 @@
3434
*
3535
* TODO:
3636
* - do not store terminal buffer in viminfo
37-
* - put terminal title in the statusline
3837
* - Add a scrollback buffer (contains lines to scroll off the top).
3938
* Can use the buf_T lines, store attributes somewhere else?
4039
* - When the job ends:
@@ -43,6 +42,9 @@
4342
* - Free the terminal emulator.
4443
* - Display the scrollback buffer (but with attributes).
4544
* Make the buffer not modifiable, drop attributes when making changes.
45+
* - Need an option or argument to drop the window+buffer right away, to be
46+
* used for a shell or Vim.
47+
* - add a character in :ls output
4648
* - when closing window and job has not ended, make terminal hidden?
4749
* - don't allow exiting Vim when a terminal is still running a job
4850
* - use win_del_lines() to make scroll-up efficient.
@@ -95,6 +97,9 @@ struct terminal_S {
9597
int tl_rows_fixed;
9698
int tl_cols_fixed;
9799

100+
char_u *tl_title; /* NULL or allocated */
101+
char_u *tl_status_text; /* NULL or allocated */
102+
98103
/* Range of screen rows to update. Zero based. */
99104
int tl_dirty_row_start; /* -1 if nothing dirty */
100105
int tl_dirty_row_end; /* row below last one to update */
@@ -271,6 +276,8 @@ free_terminal(term_T *term)
271276
}
272277

273278
term_free(term);
279+
vim_free(term->tl_title);
280+
vim_free(term->tl_status_text);
274281
vim_free(term);
275282
}
276283

@@ -527,18 +534,36 @@ terminal_loop(void)
527534
void
528535
term_job_ended(job_T *job)
529536
{
537+
term_T *term;
538+
int did_one = FALSE;
539+
540+
for (term = first_term; term != NULL; term = term->tl_next)
541+
if (term->tl_job == job)
542+
{
543+
vim_free(term->tl_title);
544+
term->tl_title = NULL;
545+
vim_free(term->tl_status_text);
546+
term->tl_status_text = NULL;
547+
redraw_buf_and_status_later(term->tl_buffer, VALID);
548+
did_one = TRUE;
549+
}
550+
if (did_one)
551+
{
552+
redraw_statuslines();
553+
setcursor();
554+
out_flush();
555+
}
530556
if (curbuf->b_term != NULL && curbuf->b_term->tl_job == job)
531557
maketitle();
532558
}
533559

534560
/*
535561
* Return TRUE if the job for "buf" is still running.
536562
*/
537-
int
538-
term_job_running(buf_T *buf)
563+
static int
564+
term_job_running(term_T *term)
539565
{
540-
return buf->b_term != NULL && buf->b_term->tl_job != NULL
541-
&& buf->b_term->tl_job->jv_status == JOB_STARTED;
566+
return term->tl_job != NULL && term->tl_job->jv_status == JOB_STARTED;
542567
}
543568

544569
static void
@@ -548,22 +573,6 @@ position_cursor(win_T *wp, VTermPos *pos)
548573
wp->w_wcol = MIN(pos->col, MAX(0, wp->w_width - 1));
549574
}
550575

551-
static int handle_damage(VTermRect rect, void *user);
552-
static int handle_moverect(VTermRect dest, VTermRect src, void *user);
553-
static int handle_movecursor(VTermPos pos, VTermPos oldpos, int visible, void *user);
554-
static int handle_resize(int rows, int cols, void *user);
555-
556-
static VTermScreenCallbacks screen_callbacks = {
557-
handle_damage, /* damage */
558-
handle_moverect, /* moverect */
559-
handle_movecursor, /* movecursor */
560-
NULL, /* settermprop */
561-
NULL, /* bell */
562-
handle_resize, /* resize */
563-
NULL, /* sb_pushline */
564-
NULL /* sb_popline */
565-
};
566-
567576
static int
568577
handle_damage(VTermRect rect, void *user)
569578
{
@@ -615,6 +624,30 @@ handle_movecursor(
615624
return 1;
616625
}
617626

627+
static int
628+
handle_settermprop(
629+
VTermProp prop,
630+
VTermValue *value,
631+
void *user)
632+
{
633+
term_T *term = (term_T *)user;
634+
635+
switch (prop)
636+
{
637+
case VTERM_PROP_TITLE:
638+
vim_free(term->tl_title);
639+
term->tl_title = vim_strsave((char_u *)value->string);
640+
vim_free(term->tl_status_text);
641+
term->tl_status_text = NULL;
642+
if (term == curbuf->b_term)
643+
maketitle();
644+
return 1;
645+
default:
646+
break;
647+
}
648+
return 0;
649+
}
650+
618651
/*
619652
* The job running in the terminal resized the terminal.
620653
*/
@@ -639,6 +672,17 @@ handle_resize(int rows, int cols, void *user)
639672
return 1;
640673
}
641674

675+
static VTermScreenCallbacks screen_callbacks = {
676+
handle_damage, /* damage */
677+
handle_moverect, /* moverect */
678+
handle_movecursor, /* movecursor */
679+
handle_settermprop, /* settermprop */
680+
NULL, /* bell */
681+
handle_resize, /* resize */
682+
NULL, /* sb_pushline */
683+
NULL /* sb_popline */
684+
};
685+
642686
/*
643687
* Reverse engineer the RGB value into a cterm color index.
644688
* First color is 1. Return 0 if no match found.
@@ -950,6 +994,32 @@ create_vterm(term_T *term, int rows, int cols)
950994
vterm_screen_reset(screen, 1 /* hard */);
951995
}
952996

997+
/*
998+
* Return the text to show for the buffer name and status.
999+
*/
1000+
char_u *
1001+
term_get_status_text(term_T *term)
1002+
{
1003+
if (term->tl_status_text == NULL)
1004+
{
1005+
char_u *txt;
1006+
size_t len;
1007+
1008+
if (term->tl_title != NULL)
1009+
txt = term->tl_title;
1010+
else if (term_job_running(term))
1011+
txt = (char_u *)_("running");
1012+
else
1013+
txt = (char_u *)_("finished");
1014+
len = 9 + STRLEN(term->tl_buffer->b_fname) + STRLEN(txt);
1015+
term->tl_status_text = alloc(len);
1016+
if (term->tl_status_text != NULL)
1017+
vim_snprintf((char *)term->tl_status_text, len, "%s [%s]",
1018+
term->tl_buffer->b_fname, txt);
1019+
}
1020+
return term->tl_status_text;
1021+
}
1022+
9531023
# ifdef WIN3264
9541024

9551025
#define WINPTY_SPAWN_FLAG_AUTO_SHUTDOWN 1ul

src/version.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -769,6 +769,8 @@ static char *(features[]) =
769769

770770
static int included_patches[] =
771771
{ /* Add new patch number below this line */
772+
/**/
773+
768,
772774
/**/
773775
767,
774776
/**/

0 commit comments

Comments
 (0)