To: vim_dev@googlegroups.com Subject: Patch 8.0.0768 Fcc: outbox From: Bram Moolenaar Mime-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ------------ Patch 8.0.0768 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) Files: src/terminal.c, src/proto/terminal.pro, src/buffer.c *** ../vim-8.0.0767/src/terminal.c 2017-07-23 22:50:47.263173163 +0200 --- src/terminal.c 2017-07-24 21:38:10.771875305 +0200 *************** *** 34,40 **** * * TODO: * - do not store terminal buffer in viminfo - * - put terminal title in the statusline * - Add a scrollback buffer (contains lines to scroll off the top). * Can use the buf_T lines, store attributes somewhere else? * - When the job ends: --- 34,39 ---- *************** *** 43,48 **** --- 42,50 ---- * - Free the terminal emulator. * - Display the scrollback buffer (but with attributes). * Make the buffer not modifiable, drop attributes when making changes. + * - Need an option or argument to drop the window+buffer right away, to be + * used for a shell or Vim. + * - add a character in :ls output * - when closing window and job has not ended, make terminal hidden? * - don't allow exiting Vim when a terminal is still running a job * - use win_del_lines() to make scroll-up efficient. *************** *** 95,100 **** --- 97,105 ---- int tl_rows_fixed; int tl_cols_fixed; + char_u *tl_title; /* NULL or allocated */ + char_u *tl_status_text; /* NULL or allocated */ + /* Range of screen rows to update. Zero based. */ int tl_dirty_row_start; /* -1 if nothing dirty */ int tl_dirty_row_end; /* row below last one to update */ *************** *** 271,276 **** --- 276,283 ---- } term_free(term); + vim_free(term->tl_title); + vim_free(term->tl_status_text); vim_free(term); } *************** *** 527,532 **** --- 534,558 ---- void term_job_ended(job_T *job) { + term_T *term; + int did_one = FALSE; + + for (term = first_term; term != NULL; term = term->tl_next) + if (term->tl_job == job) + { + vim_free(term->tl_title); + term->tl_title = NULL; + vim_free(term->tl_status_text); + term->tl_status_text = NULL; + redraw_buf_and_status_later(term->tl_buffer, VALID); + did_one = TRUE; + } + if (did_one) + { + redraw_statuslines(); + setcursor(); + out_flush(); + } if (curbuf->b_term != NULL && curbuf->b_term->tl_job == job) maketitle(); } *************** *** 534,544 **** /* * Return TRUE if the job for "buf" is still running. */ ! int ! term_job_running(buf_T *buf) { ! return buf->b_term != NULL && buf->b_term->tl_job != NULL ! && buf->b_term->tl_job->jv_status == JOB_STARTED; } static void --- 560,569 ---- /* * Return TRUE if the job for "buf" is still running. */ ! static int ! term_job_running(term_T *term) { ! return term->tl_job != NULL && term->tl_job->jv_status == JOB_STARTED; } static void *************** *** 548,569 **** wp->w_wcol = MIN(pos->col, MAX(0, wp->w_width - 1)); } - static int handle_damage(VTermRect rect, void *user); - static int handle_moverect(VTermRect dest, VTermRect src, void *user); - static int handle_movecursor(VTermPos pos, VTermPos oldpos, int visible, void *user); - static int handle_resize(int rows, int cols, void *user); - - static VTermScreenCallbacks screen_callbacks = { - handle_damage, /* damage */ - handle_moverect, /* moverect */ - handle_movecursor, /* movecursor */ - NULL, /* settermprop */ - NULL, /* bell */ - handle_resize, /* resize */ - NULL, /* sb_pushline */ - NULL /* sb_popline */ - }; - static int handle_damage(VTermRect rect, void *user) { --- 573,578 ---- *************** *** 615,620 **** --- 624,653 ---- return 1; } + static int + handle_settermprop( + VTermProp prop, + VTermValue *value, + void *user) + { + term_T *term = (term_T *)user; + + switch (prop) + { + case VTERM_PROP_TITLE: + vim_free(term->tl_title); + term->tl_title = vim_strsave((char_u *)value->string); + vim_free(term->tl_status_text); + term->tl_status_text = NULL; + if (term == curbuf->b_term) + maketitle(); + return 1; + default: + break; + } + return 0; + } + /* * The job running in the terminal resized the terminal. */ *************** *** 639,644 **** --- 672,688 ---- return 1; } + static VTermScreenCallbacks screen_callbacks = { + handle_damage, /* damage */ + handle_moverect, /* moverect */ + handle_movecursor, /* movecursor */ + handle_settermprop, /* settermprop */ + NULL, /* bell */ + handle_resize, /* resize */ + NULL, /* sb_pushline */ + NULL /* sb_popline */ + }; + /* * Reverse engineer the RGB value into a cterm color index. * First color is 1. Return 0 if no match found. *************** *** 950,955 **** --- 994,1025 ---- vterm_screen_reset(screen, 1 /* hard */); } + /* + * Return the text to show for the buffer name and status. + */ + char_u * + term_get_status_text(term_T *term) + { + if (term->tl_status_text == NULL) + { + char_u *txt; + size_t len; + + if (term->tl_title != NULL) + txt = term->tl_title; + else if (term_job_running(term)) + txt = (char_u *)_("running"); + else + txt = (char_u *)_("finished"); + len = 9 + STRLEN(term->tl_buffer->b_fname) + STRLEN(txt); + term->tl_status_text = alloc(len); + if (term->tl_status_text != NULL) + vim_snprintf((char *)term->tl_status_text, len, "%s [%s]", + term->tl_buffer->b_fname, txt); + } + return term->tl_status_text; + } + # ifdef WIN3264 #define WINPTY_SPAWN_FLAG_AUTO_SHUTDOWN 1ul *** ../vim-8.0.0767/src/proto/terminal.pro 2017-07-23 19:50:39.028922806 +0200 --- src/proto/terminal.pro 2017-07-24 21:25:53.941263725 +0200 *************** *** 4,9 **** void write_to_term(buf_T *buffer, char_u *msg, channel_T *channel); void terminal_loop(void); void term_job_ended(job_T *job); - int term_job_running(buf_T *buf); void term_update_window(win_T *wp); /* vim: set ft=c : */ --- 4,9 ---- void write_to_term(buf_T *buffer, char_u *msg, channel_T *channel); void terminal_loop(void); void term_job_ended(job_T *job); void term_update_window(win_T *wp); + char_u *term_get_status_text(term_T *term); /* vim: set ft=c : */ *** ../vim-8.0.0767/src/buffer.c 2017-07-23 19:50:39.032922776 +0200 --- src/buffer.c 2017-07-24 21:36:24.420686472 +0200 *************** *** 3626,3631 **** --- 3626,3638 ---- #define SPACE_FOR_ARGNR (IOSIZE - 10) /* at least room for " - VIM" */ if (curbuf->b_fname == NULL) vim_strncpy(buf, (char_u *)_("[No Name]"), SPACE_FOR_FNAME); + #ifdef FEAT_TERMINAL + else if (curbuf->b_term != NULL) + { + vim_strncpy(buf, term_get_status_text(curbuf->b_term), + SPACE_FOR_FNAME); + } + #endif else { p = transstr(gettail(curbuf->b_fname)); *************** *** 3633,3652 **** vim_free(p); } ! switch (bufIsChanged(curbuf) ! + (curbuf->b_p_ro * 2) ! + (!curbuf->b_p_ma * 4)) ! { ! case 1: STRCAT(buf, " +"); break; ! case 2: STRCAT(buf, " ="); break; ! case 3: STRCAT(buf, " =+"); break; ! case 4: ! case 6: STRCAT(buf, " -"); break; ! case 5: ! case 7: STRCAT(buf, " -+"); break; ! } ! if (curbuf->b_fname != NULL) { /* Get path of file, replace home dir with ~ */ off = (int)STRLEN(buf); --- 3640,3666 ---- vim_free(p); } ! #ifdef FEAT_TERMINAL ! if (curbuf->b_term == NULL) ! #endif ! switch (bufIsChanged(curbuf) ! + (curbuf->b_p_ro * 2) ! + (!curbuf->b_p_ma * 4)) ! { ! case 1: STRCAT(buf, " +"); break; ! case 2: STRCAT(buf, " ="); break; ! case 3: STRCAT(buf, " =+"); break; ! case 4: ! case 6: STRCAT(buf, " -"); break; ! case 5: ! case 7: STRCAT(buf, " -+"); break; ! } ! if (curbuf->b_fname != NULL ! #ifdef FEAT_TERMINAL ! && curbuf->b_term == NULL ! #endif ! ) { /* Get path of file, replace home dir with ~ */ off = (int)STRLEN(buf); *************** *** 3663,3680 **** p = gettail_sep(buf + off); if (p == buf + off) { ! char *txt; ! ! #ifdef FEAT_TERMINAL ! if (curbuf->b_term != NULL) ! txt = term_job_running(curbuf) ! ? _("running") : _("finished"); ! else ! #endif ! txt = _("help"); ! ! /* must be a help or terminal buffer */ ! vim_strncpy(buf + off, (char_u *)txt, (size_t)(SPACE_FOR_DIR - off - 1)); } else --- 3677,3684 ---- p = gettail_sep(buf + off); if (p == buf + off) { ! /* must be a help buffer */ ! vim_strncpy(buf + off, (char_u *)_("help"), (size_t)(SPACE_FOR_DIR - off - 1)); } else *************** *** 5670,5685 **** return (char_u *)_(msg_qflist); } #endif ! #ifdef FEAT_QUICKFIX /* There is no _file_ when 'buftype' is "nofile", b_sfname ! * contains the name as specified by the user */ if (bt_nofile(buf)) { if (buf->b_sfname != NULL) return buf->b_sfname; return (char_u *)_("[Scratch]"); } ! #endif if (buf->b_fname == NULL) return (char_u *)_("[No Name]"); return NULL; --- 5674,5693 ---- return (char_u *)_(msg_qflist); } #endif ! /* There is no _file_ when 'buftype' is "nofile", b_sfname ! * contains the name as specified by the user. */ if (bt_nofile(buf)) { + #ifdef FEAT_TERMINAL + if (buf->b_term != NULL) + return term_get_status_text(buf->b_term); + #endif if (buf->b_sfname != NULL) return buf->b_sfname; return (char_u *)_("[Scratch]"); } ! if (buf->b_fname == NULL) return (char_u *)_("[No Name]"); return NULL; *** ../vim-8.0.0767/src/version.c 2017-07-24 20:15:25.551360752 +0200 --- src/version.c 2017-07-24 20:25:25.327169980 +0200 *************** *** 771,772 **** --- 771,774 ---- { /* Add new patch number below this line */ + /**/ + 768, /**/ -- hundred-and-one symptoms of being an internet addict: 231. You sprinkle Carpet Fresh on the rugs and put your vacuum cleaner in the front doorway permanently so it always looks like you are actually attempting to do something about that mess that has amassed since you discovered the Internet. /// Bram Moolenaar -- Bram@Moolenaar.net -- http://www.Moolenaar.net \\\ /// sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\ \\\ an exciting new programming language -- http://www.Zimbu.org /// \\\ help me help AIDS victims -- http://ICCF-Holland.org ///