Patch 9.0.0977
Problem:    It is not easy to see what client-server commands are doing.
Solution:   Add channel log messages if ch_log() is available.  Move the
            channel logging and make it available with the +eval feature.
Files:      Filelist, runtime/doc/starting.txt, src/if_xcmdsrv.c,
            src/clientserver.c, src/logfile.c, src/proto/logfile.pro,
            src/proto.h, src/channel.c, src/proto/channel.pro, src/evalfunc.c,
            src/gui_gtk_x11.c, src/main.c, src/message.c, src/os_unix.c,
            src/os_win32.c, src/regexp_bt.c, src/regexp_nfa.c, src/term.c,
            src/time.c, src/ui.c, src/globals.h, src/Makefile,
            src/Make_ami.mak, src/Make_mvc.mak, src/Make_vms.mms,
            src/Make_cyg_ming.mak


*** ../vim-9.0.0976/Filelist    2022-11-18 22:14:04.798988157 +0000
--- Filelist    2022-11-30 16:27:19.900260217 +0000
***************
*** 88,97 ****
                src/job.c \
                src/json.c \
                src/json_test.c \
                src/kword_test.c \
                src/list.c \
                src/locale.c \
!               src/keymap.h \
                src/macros.h \
                src/main.c \
                src/map.c \
--- 88,98 ----
                src/job.c \
                src/json.c \
                src/json_test.c \
+               src/keymap.h \
                src/kword_test.c \
                src/list.c \
                src/locale.c \
!               src/logfile.c \
                src/macros.h \
                src/main.c \
                src/map.c \
*** ../vim-9.0.0976/runtime/doc/starting.txt    2022-06-28 11:21:06.000000000 
+0100
--- runtime/doc/starting.txt    2022-11-30 16:11:41.813626987 +0000
***************
*** 348,354 ****
                Start logging and write entries to {filename}.
                This works like calling `ch_logfile({filename}, 'ao')` very
                early during startup.
!               {only available with the |+channel| feature}
  
                                                        *-D*
  -D            Debugging.  Go to debugging mode when executing the first
--- 348,354 ----
                Start logging and write entries to {filename}.
                This works like calling `ch_logfile({filename}, 'ao')` very
                early during startup.
!               {only available with the |+eval| feature}
  
                                                        *-D*
  -D            Debugging.  Go to debugging mode when executing the first
*** ../vim-9.0.0976/src/if_xcmdsrv.c    2022-09-18 13:06:36.461124371 +0100
--- src/if_xcmdsrv.c    2022-11-30 17:15:14.519414590 +0000
***************
*** 388,398 ****
      if (name == NULL || *name == NUL)
        name = (char_u *)"GVIM";    // use a default name
  
!     if (commProperty == None && dpy != NULL)
!     {
!       if (SendInit(dpy) < 0)
!           return -1;
!     }
  
      // Execute locally if no display or target is ourselves
      if (dpy == NULL || (serverName != NULL && STRICMP(name, serverName) == 0))
--- 388,399 ----
      if (name == NULL || *name == NUL)
        name = (char_u *)"GVIM";    // use a default name
  
!     if (commProperty == None && dpy != NULL && SendInit(dpy) < 0)
!       return -1;
! 
! #if defined(FEAT_EVAL)
!     ch_log(NULL, "serverSendToVim(%s, %s)", name, cmd);
! #endif
  
      // Execute locally if no display or target is ourselves
      if (dpy == NULL || (serverName != NULL && STRICMP(name, serverName) == 0))
***************
*** 494,499 ****
--- 495,505 ----
                break;
            }
      }
+ 
+ #if defined(FEAT_EVAL)
+     ch_log(NULL, "serverSendToVim() result: %s",
+           pending.result == NULL ? "NULL" : (char *)pending.result);
+ #endif
      if (result != NULL)
        *result = pending.result;
      else
***************
*** 1221,1226 ****
--- 1227,1236 ----
      int               code;
      char_u    *tofree;
  
+ #if defined(FEAT_EVAL)
+     ch_log(NULL, "server_parse_message() numItems: %ld", numItems);
+ #endif
+ 
      /*
       * Several commands and results could arrive in the property at
       * one time;  each iteration through the outer loop handles a
***************
*** 1240,1246 ****
            continue;
        }
  
!       if ((*p == 'c' || *p == 'k') && (p[1] == 0))
        {
            Window      resWindow;
            char_u      *name, *script, *serial, *end;
--- 1250,1256 ----
            continue;
        }
  
!       if ((*p == 'c' || *p == 'k') && p[1] == 0)
        {
            Window      resWindow;
            char_u      *name, *script, *serial, *end;
***************
*** 1261,1266 ****
--- 1271,1279 ----
            enc = NULL;
            while ((long_u)(p - propInfo) < numItems && *p == '-')
            {
+ #if defined(FEAT_EVAL)
+               ch_log(NULL, "server_parse_message() item: %c, %s", p[-2], p);
+ #endif
                switch (p[1])
                {
                    case 'r':
***************
*** 1326,1332 ****
                            ga_concat(&reply, res);
                        else
                        {
!                           ga_concat(&reply, (char_u 
*)_(e_invalid_expression_received));
                            ga_append(&reply, 0);
                            ga_concat(&reply, (char_u *)"-c 1");
                        }
--- 1339,1346 ----
                            ga_concat(&reply, res);
                        else
                        {
!                           ga_concat(&reply,
!                                  (char_u *)_(e_invalid_expression_received));
                            ga_append(&reply, 0);
                            ga_concat(&reply, (char_u *)"-c 1");
                        }
*** ../vim-9.0.0976/src/clientserver.c  2022-10-01 19:43:48.606494048 +0100
--- src/clientserver.c  2022-11-30 17:13:41.887414600 +0000
***************
*** 70,75 ****
--- 70,79 ----
      funccal_entry_T funccal_entry;
      int               did_save_funccal = FALSE;
  
+ #if defined(FEAT_EVAL)
+     ch_log(NULL, "eval_client_expr_to_string(\"%s\")", expr);
+ #endif
+ 
      // Evaluate the expression at the toplevel, don't use variables local to
      // the calling function. Except when in debug mode.
      if (!debug_mode)
*** ../vim-9.0.0976/src/logfile.c       2022-11-30 18:08:31.926958525 +0000
--- src/logfile.c       2022-11-30 16:35:44.379402674 +0000
***************
*** 0 ****
--- 1,208 ----
+ /* vi:set ts=8 sts=4 sw=4 noet:
+  *
+  * VIM - Vi IMproved  by Bram Moolenaar
+  *
+  * Do ":help uganda"  in Vim to read copying and usage conditions.
+  * Do ":help credits" in Vim to see a list of people who contributed.
+  */
+ 
+ /*
+  * Implements logging.  Originally intended for the channel feature, which is
+  * why the "ch_" prefix is used.  Also useful for any kind of low-level and
+  * async debuging.
+  */
+ 
+ #include "vim.h"
+ 
+ #if defined(FEAT_EVAL) || defined(PROTO)
+ 
+ // Log file opened with ch_logfile().
+ static FILE *log_fd = NULL;
+ static char_u *log_name = NULL;
+ #ifdef FEAT_RELTIME
+ static proftime_T log_start;
+ #endif
+ 
+     void
+ ch_logfile(char_u *fname, char_u *opt)
+ {
+     FILE      *file = NULL;
+     char      *mode = "a";
+ 
+     if (log_fd != NULL)
+     {
+       if (*fname != NUL)
+           ch_log(NULL, "closing this logfile, opening %s", fname);
+       else
+           ch_log(NULL, "closing logfile %s", log_name);
+       fclose(log_fd);
+     }
+ 
+     // The "a" flag overrules the "w" flag.
+     if (vim_strchr(opt, 'a') == NULL && vim_strchr(opt, 'w') != NULL)
+       mode = "w";
+     ch_log_output = vim_strchr(opt, 'o') != NULL ? LOG_ALWAYS : FALSE;
+ 
+     if (*fname != NUL)
+     {
+       file = fopen((char *)fname, mode);
+       if (file == NULL)
+       {
+           semsg(_(e_cant_open_file_str), fname);
+           return;
+       }
+       vim_free(log_name);
+       log_name = vim_strsave(fname);
+     }
+     log_fd = file;
+ 
+     if (log_fd != NULL)
+     {
+       fprintf(log_fd, "==== start log session %s ====\n",
+                                                get_ctime(time(NULL), FALSE));
+       // flush now, if fork/exec follows it could be written twice
+       fflush(log_fd);
+ #ifdef FEAT_RELTIME
+       profile_start(&log_start);
+ #endif
+     }
+ }
+ 
+     int
+ ch_log_active(void)
+ {
+     return log_fd != NULL;
+ }
+ 
+     static void
+ ch_log_lead(const char *what, channel_T *ch, ch_part_T part)
+ {
+     if (log_fd == NULL)
+       return;
+ 
+ #ifdef FEAT_RELTIME
+     proftime_T log_now;
+ 
+     profile_start(&log_now);
+     profile_sub(&log_now, &log_start);
+     fprintf(log_fd, "%s ", profile_msg(&log_now));
+ #endif
+ #ifdef FEAT_JOB_CHANNEL
+     if (ch != NULL)
+     {
+       if (part < PART_COUNT)
+           fprintf(log_fd, "%son %d(%s): ", what, ch->ch_id, 
ch_part_names[part]);
+       else
+           fprintf(log_fd, "%son %d: ", what, ch->ch_id);
+     }
+     else
+ #endif
+       fprintf(log_fd, "%s: ", what);
+ }
+ 
+ #ifndef PROTO  // prototype is in proto.h
+     void
+ ch_log(channel_T *ch, const char *fmt, ...)
+ {
+     if (log_fd == NULL)
+       return;
+ 
+     va_list ap;
+ 
+     ch_log_lead("", ch, PART_COUNT);
+     va_start(ap, fmt);
+     vfprintf(log_fd, fmt, ap);
+     va_end(ap);
+     fputc('\n', log_fd);
+     fflush(log_fd);
+     did_repeated_msg = 0;
+ }
+ 
+     void
+ ch_error(channel_T *ch, const char *fmt, ...)
+ {
+     if (log_fd == NULL)
+       return;
+ 
+     va_list ap;
+ 
+     ch_log_lead("ERR ", ch, PART_COUNT);
+     va_start(ap, fmt);
+     vfprintf(log_fd, fmt, ap);
+     va_end(ap);
+     fputc('\n', log_fd);
+     fflush(log_fd);
+     did_repeated_msg = 0;
+ }
+ #endif
+ 
+ #if defined(FEAT_JOB_CHANNEL) || defined(PROTO)
+ /*
+  * Log a message "buf[len]" for channel "ch" part "part".
+  * Only to be called when ch_log_active() returns TRUE.
+  */
+     void
+ ch_log_literal(
+       char        *lead,
+       channel_T   *ch,
+       ch_part_T   part,
+       char_u      *buf,
+       int         len)
+ {
+     ch_log_lead(lead, ch, part);
+     fprintf(log_fd, "'");
+     vim_ignored = (int)fwrite(buf, len, 1, log_fd);
+     fprintf(log_fd, "'\n");
+     fflush(log_fd);
+ }
+ #endif
+ 
+ /*
+  * "ch_log()" function
+  */
+     void
+ f_ch_log(typval_T *argvars, typval_T *rettv UNUSED)
+ {
+     char_u    *msg;
+     channel_T *channel = NULL;
+ 
+     if (in_vim9script()
+           && (check_for_string_arg(argvars, 0) == FAIL
+               || check_for_opt_chan_or_job_arg(argvars, 1) == FAIL))
+       return;
+ 
+     msg = tv_get_string(&argvars[0]);
+ #if defined(FEAT_JOB_CHANNEL)
+     if (argvars[1].v_type != VAR_UNKNOWN)
+       channel = get_channel_arg(&argvars[1], FALSE, FALSE, 0);
+ #endif
+ 
+     ch_log(channel, "%s", msg);
+ }
+ 
+ /*
+  * "ch_logfile()" function
+  */
+     void
+ f_ch_logfile(typval_T *argvars, typval_T *rettv UNUSED)
+ {
+     char_u *fname;
+     char_u *opt = (char_u *)"";
+     char_u buf[NUMBUFLEN];
+ 
+     // Don't open a file in restricted mode.
+     if (check_restricted() || check_secure())
+       return;
+ 
+     if (in_vim9script()
+           && (check_for_string_arg(argvars, 0) == FAIL
+               || check_for_opt_string_arg(argvars, 1) == FAIL))
+       return;
+ 
+     fname = tv_get_string(&argvars[0]);
+     if (argvars[1].v_type == VAR_STRING)
+       opt = tv_get_string_buf(&argvars[1], buf);
+     ch_logfile(fname, opt);
+ }
+ 
+ #endif // FEAT_EVAL
*** ../vim-9.0.0976/src/proto/logfile.pro       2022-11-30 18:08:31.934958523 
+0000
--- src/proto/logfile.pro       2022-11-30 16:37:41.539264137 +0000
***************
*** 0 ****
--- 1,7 ----
+ /* logfile.c */
+ void ch_logfile(char_u *fname, char_u *opt);
+ int ch_log_active(void);
+ void ch_log_literal(char *lead, channel_T *ch, ch_part_T part, char_u *buf, 
int len);
+ void f_ch_log(typval_T *argvars, typval_T *rettv);
+ void f_ch_logfile(typval_T *argvars, typval_T *rettv);
+ /* vim: set ft=c : */
*** ../vim-9.0.0976/src/proto.h 2022-10-08 13:49:41.893378443 +0100
--- src/proto.h 2022-11-30 16:14:52.293650768 +0000
***************
*** 104,109 ****
--- 104,110 ----
  # include "json.pro"
  # include "list.pro"
  # include "locale.pro"
+ # include "logfile.pro"
  # include "blob.pro"
  # include "main.pro"
  # include "map.pro"
***************
*** 263,270 ****
  #  include "job.pro"
  #  include "channel.pro"
  
! // Not generated automatically, to add extra attribute.
  void ch_log(channel_T *ch, const char *fmt, ...) ATTRIBUTE_FORMAT_PRINTF(2, 
3);
  
  # endif
  
--- 264,272 ----
  #  include "job.pro"
  #  include "channel.pro"
  
! // Not generated automatically so that we can add an extra attribute.
  void ch_log(channel_T *ch, const char *fmt, ...) ATTRIBUTE_FORMAT_PRINTF(2, 
3);
+ void ch_error(channel_T *ch, const char *fmt, ...) ATTRIBUTE_FORMAT_PRINTF(2, 
3);
  
  # endif
  
*** ../vim-9.0.0976/src/channel.c       2022-11-28 18:51:38.959571588 +0000
--- src/channel.c       2022-11-30 16:37:31.963274907 +0000
***************
*** 81,88 ****
  // is safe to invoke callbacks.
  static int safe_to_invoke_callback = 0;
  
- static char *part_names[] = {"sock", "out", "err", "in"};
- 
  #ifdef MSWIN
      static int
  fd_read(sock_T fd, char *buf, size_t len)
--- 81,86 ----
***************
*** 142,269 ****
  }
  #endif
  
- // Log file opened with ch_logfile().
- static FILE *log_fd = NULL;
- static char_u *log_name = NULL;
- #ifdef FEAT_RELTIME
- static proftime_T log_start;
- #endif
- 
-     void
- ch_logfile(char_u *fname, char_u *opt)
- {
-     FILE      *file = NULL;
-     char      *mode = "a";
- 
-     if (log_fd != NULL)
-     {
-       if (*fname != NUL)
-           ch_log(NULL, "closing this logfile, opening %s", fname);
-       else
-           ch_log(NULL, "closing logfile %s", log_name);
-       fclose(log_fd);
-     }
- 
-     // The "a" flag overrules the "w" flag.
-     if (vim_strchr(opt, 'a') == NULL && vim_strchr(opt, 'w') != NULL)
-       mode = "w";
-     ch_log_output = vim_strchr(opt, 'o') != NULL ? LOG_ALWAYS : FALSE;
- 
-     if (*fname != NUL)
-     {
-       file = fopen((char *)fname, mode);
-       if (file == NULL)
-       {
-           semsg(_(e_cant_open_file_str), fname);
-           return;
-       }
-       vim_free(log_name);
-       log_name = vim_strsave(fname);
-     }
-     log_fd = file;
- 
-     if (log_fd != NULL)
-     {
-       fprintf(log_fd, "==== start log session %s ====\n",
-                                                get_ctime(time(NULL), FALSE));
-       // flush now, if fork/exec follows it could be written twice
-       fflush(log_fd);
- #ifdef FEAT_RELTIME
-       profile_start(&log_start);
- #endif
-     }
- }
- 
-     int
- ch_log_active(void)
- {
-     return log_fd != NULL;
- }
- 
-     static void
- ch_log_lead(const char *what, channel_T *ch, ch_part_T part)
- {
-     if (log_fd == NULL)
-       return;
- 
- #ifdef FEAT_RELTIME
-     proftime_T log_now;
- 
-     profile_start(&log_now);
-     profile_sub(&log_now, &log_start);
-     fprintf(log_fd, "%s ", profile_msg(&log_now));
- #endif
-     if (ch != NULL)
-     {
-       if (part < PART_COUNT)
-           fprintf(log_fd, "%son %d(%s): ",
-                   what, ch->ch_id, part_names[part]);
-       else
-           fprintf(log_fd, "%son %d: ", what, ch->ch_id);
-     }
-     else
-       fprintf(log_fd, "%s: ", what);
- }
- 
- #ifndef PROTO  // prototype is in proto.h
-     void
- ch_log(channel_T *ch, const char *fmt, ...)
- {
-     if (log_fd == NULL)
-       return;
- 
-     va_list ap;
- 
-     ch_log_lead("", ch, PART_COUNT);
-     va_start(ap, fmt);
-     vfprintf(log_fd, fmt, ap);
-     va_end(ap);
-     fputc('\n', log_fd);
-     fflush(log_fd);
-     did_repeated_msg = 0;
- }
- #endif
- 
-     static void
- ch_error(channel_T *ch, const char *fmt, ...) ATTRIBUTE_FORMAT_PRINTF(2, 3);
- 
-     static void
- ch_error(channel_T *ch, const char *fmt, ...)
- {
-     if (log_fd == NULL)
-       return;
- 
-     va_list ap;
- 
-     ch_log_lead("ERR ", ch, PART_COUNT);
-     va_start(ap, fmt);
-     vfprintf(log_fd, fmt, ap);
-     va_end(ap);
-     fputc('\n', log_fd);
-     fflush(log_fd);
-     did_repeated_msg = 0;
- }
- 
  #ifdef MSWIN
  # undef PERROR
  # define PERROR(msg) (void)semsg("%s: %s", msg, strerror_win32(errno))
--- 140,145 ----
***************
*** 620,626 ****
      if (channel->ch_part[part].ch_inputHandler == (XtInputId)NULL)
      {
        ch_log(channel, "Registering part %s with fd %d",
!               part_names[part], channel->ch_part[part].ch_fd);
  
        channel->ch_part[part].ch_inputHandler = XtAppAddInput(
                (XtAppContext)app_context,
--- 496,502 ----
      if (channel->ch_part[part].ch_inputHandler == (XtInputId)NULL)
      {
        ch_log(channel, "Registering part %s with fd %d",
!               ch_part_names[part], channel->ch_part[part].ch_fd);
  
        channel->ch_part[part].ch_inputHandler = XtAppAddInput(
                (XtAppContext)app_context,
***************
*** 636,642 ****
      if (channel->ch_part[part].ch_inputHandler == 0)
      {
        ch_log(channel, "Registering part %s with fd %d",
!               part_names[part], channel->ch_part[part].ch_fd);
  #   if GTK_CHECK_VERSION(3,0,0)
        GIOChannel *chnnl = g_io_channel_unix_new(
                (gint)channel->ch_part[part].ch_fd);
--- 512,518 ----
      if (channel->ch_part[part].ch_inputHandler == 0)
      {
        ch_log(channel, "Registering part %s with fd %d",
!               ch_part_names[part], channel->ch_part[part].ch_fd);
  #   if GTK_CHECK_VERSION(3,0,0)
        GIOChannel *chnnl = g_io_channel_unix_new(
                (gint)channel->ch_part[part].ch_fd);
***************
*** 694,700 ****
  # ifdef FEAT_GUI_X11
      if (channel->ch_part[part].ch_inputHandler != (XtInputId)NULL)
      {
!       ch_log(channel, "Unregistering part %s", part_names[part]);
        XtRemoveInput(channel->ch_part[part].ch_inputHandler);
        channel->ch_part[part].ch_inputHandler = (XtInputId)NULL;
      }
--- 570,576 ----
  # ifdef FEAT_GUI_X11
      if (channel->ch_part[part].ch_inputHandler != (XtInputId)NULL)
      {
!       ch_log(channel, "Unregistering part %s", ch_part_names[part]);
        XtRemoveInput(channel->ch_part[part].ch_inputHandler);
        channel->ch_part[part].ch_inputHandler = (XtInputId)NULL;
      }
***************
*** 702,708 ****
  #  ifdef FEAT_GUI_GTK
      if (channel->ch_part[part].ch_inputHandler != 0)
      {
!       ch_log(channel, "Unregistering part %s", part_names[part]);
  #   if GTK_CHECK_VERSION(3,0,0)
        g_source_remove(channel->ch_part[part].ch_inputHandler);
  #   else
--- 578,584 ----
  #  ifdef FEAT_GUI_GTK
      if (channel->ch_part[part].ch_inputHandler != 0)
      {
!       ch_log(channel, "Unregistering part %s", ch_part_names[part]);
  #   if GTK_CHECK_VERSION(3,0,0)
        g_source_remove(channel->ch_part[part].ch_inputHandler);
  #   else
***************
*** 1786,1792 ****
            if (ch_part->ch_bufref.br_buf == buf)
            {
                ch_log(channel, "%s buffer has been wiped out",
!                                                           part_names[part]);
                ch_part->ch_bufref.br_buf = NULL;
            }
        }
--- 1662,1668 ----
            if (ch_part->ch_bufref.br_buf == buf)
            {
                ch_log(channel, "%s buffer has been wiped out",
!                                                         ch_part_names[part]);
                ch_part->ch_bufref.br_buf = NULL;
            }
        }
***************
*** 2165,2176 ****
      }
  
      if (ch_log_active() && lead != NULL)
!     {
!       ch_log_lead(lead, channel, part);
!       fprintf(log_fd, "'");
!       vim_ignored = (int)fwrite(buf, len, 1, log_fd);
!       fprintf(log_fd, "'\n");
!     }
      return OK;
  }
  
--- 2041,2048 ----
      }
  
      if (ch_log_active() && lead != NULL)
!       ch_log_literal(lead, channel, part, buf, len);
! 
      return OK;
  }
  
***************
*** 3018,3024 ****
                                               || buffer->b_ml.ml_mfp == NULL))
      {
        // buffer was wiped out or unloaded
!       ch_log(channel, "%s buffer has been wiped out", part_names[part]);
        ch_part->ch_bufref.br_buf = NULL;
        buffer = NULL;
      }
--- 2890,2896 ----
                                               || buffer->b_ml.ml_mfp == NULL))
      {
        // buffer was wiped out or unloaded
!       ch_log(channel, "%s buffer has been wiped out", ch_part_names[part]);
        ch_part->ch_bufref.br_buf = NULL;
        buffer = NULL;
      }
***************
*** 3458,3464 ****
                ++channel->ch_refcount;
                if (channel->ch_close_cb.cb_name == NULL)
                    ch_log(channel, "flushing %s buffers before closing",
!                                                            part_names[part]);
                while (may_invoke_callback(channel, part))
                    ;
                --channel->ch_refcount;
--- 3330,3336 ----
                ++channel->ch_refcount;
                if (channel->ch_close_cb.cb_name == NULL)
                    ch_log(channel, "flushing %s buffers before closing",
!                                                         ch_part_names[part]);
                while (may_invoke_callback(channel, part))
                    ;
                --channel->ch_refcount;
***************
*** 3860,3866 ****
      if (fd == INVALID_FD)
      {
        ch_error(channel, "channel_read() called while %s part is closed",
!                                                           part_names[part]);
        return;
      }
      use_socket = fd == channel->CH_SOCK_FD;
--- 3732,3738 ----
      if (fd == INVALID_FD)
      {
        ch_error(channel, "channel_read() called while %s part is closed",
!                                                         ch_part_names[part]);
        return;
      }
      use_socket = fd == channel->CH_SOCK_FD;
***************
*** 4129,4135 ****
   * When "reading" is TRUE "check_open" considers typeahead useful.
   * "part" is used to check typeahead, when PART_COUNT use the default part.
   */
!     static channel_T *
  get_channel_arg(typval_T *tv, int check_open, int reading, ch_part_T part)
  {
      channel_T *channel = NULL;
--- 4001,4007 ----
   * When "reading" is TRUE "check_open" considers typeahead useful.
   * "part" is used to check typeahead, when PART_COUNT use the default part.
   */
!     channel_T *
  get_channel_arg(typval_T *tv, int check_open, int reading, ch_part_T part)
  {
      channel_T *channel = NULL;
***************
*** 4375,4385 ****
  
      if (ch_log_active())
      {
!       ch_log_lead("SEND ", channel, part);
!       fprintf(log_fd, "'");
!       vim_ignored = (int)fwrite(buf_arg, len_arg, 1, log_fd);
!       fprintf(log_fd, "'\n");
!       fflush(log_fd);
        did_repeated_msg = 0;
      }
  
--- 4247,4253 ----
  
      if (ch_log_active())
      {
!       ch_log_literal("SEND ", channel, part, buf_arg, len_arg);
        did_repeated_msg = 0;
      }
  
***************
*** 5293,5344 ****
  }
  
  /*
-  * "ch_log()" function
-  */
-     void
- f_ch_log(typval_T *argvars, typval_T *rettv UNUSED)
- {
-     char_u    *msg;
-     channel_T *channel = NULL;
- 
-     if (in_vim9script()
-           && (check_for_string_arg(argvars, 0) == FAIL
-               || check_for_opt_chan_or_job_arg(argvars, 1) == FAIL))
-       return;
- 
-     msg = tv_get_string(&argvars[0]);
-     if (argvars[1].v_type != VAR_UNKNOWN)
-       channel = get_channel_arg(&argvars[1], FALSE, FALSE, 0);
- 
-     ch_log(channel, "%s", msg);
- }
- 
- /*
-  * "ch_logfile()" function
-  */
-     void
- f_ch_logfile(typval_T *argvars, typval_T *rettv UNUSED)
- {
-     char_u *fname;
-     char_u *opt = (char_u *)"";
-     char_u buf[NUMBUFLEN];
- 
-     // Don't open a file in restricted mode.
-     if (check_restricted() || check_secure())
-       return;
- 
-     if (in_vim9script()
-           && (check_for_string_arg(argvars, 0) == FAIL
-               || check_for_opt_string_arg(argvars, 1) == FAIL))
-       return;
- 
-     fname = tv_get_string(&argvars[0]);
-     if (argvars[1].v_type == VAR_STRING)
-       opt = tv_get_string_buf(&argvars[1], buf);
-     ch_logfile(fname, opt);
- }
- 
- /*
   * "ch_open()" function
   */
      void
--- 5161,5166 ----
*** ../vim-9.0.0976/src/proto/channel.pro       2022-06-27 23:14:57.000000000 
+0100
--- src/proto/channel.pro       2022-11-30 16:26:56.836314739 +0000
***************
*** 1,6 ****
  /* channel.c */
- void ch_logfile(char_u *fname, char_u *opt);
- int ch_log_active(void);
  channel_T *add_channel(void);
  int has_any_channel(void);
  int channel_still_useful(channel_T *channel);
--- 1,4 ----
***************
*** 28,33 ****
--- 26,32 ----
  void channel_clear(channel_T *channel);
  void channel_free_all(void);
  int channel_in_blocking_wait(void);
+ channel_T *get_channel_arg(typval_T *tv, int check_open, int reading, 
ch_part_T part);
  void channel_handle_events(int only_keep_open);
  int channel_any_keep_open(void);
  void channel_set_nonblock(channel_T *channel, ch_part_T part);
***************
*** 45,52 ****
  void f_ch_getbufnr(typval_T *argvars, typval_T *rettv);
  void f_ch_getjob(typval_T *argvars, typval_T *rettv);
  void f_ch_info(typval_T *argvars, typval_T *rettv);
- void f_ch_log(typval_T *argvars, typval_T *rettv);
- void f_ch_logfile(typval_T *argvars, typval_T *rettv);
  void f_ch_open(typval_T *argvars, typval_T *rettv);
  void f_ch_read(typval_T *argvars, typval_T *rettv);
  void f_ch_readblob(typval_T *argvars, typval_T *rettv);
--- 44,49 ----
*** ../vim-9.0.0976/src/evalfunc.c      2022-11-24 11:31:26.029276217 +0000
--- src/evalfunc.c      2022-11-30 16:10:19.289616941 +0000
***************
*** 1750,1758 ****
      {"ch_info",               1, 1, FEARG_1,      arg1_chan_or_job,
                        ret_dict_any,       JOB_FUNC(f_ch_info)},
      {"ch_log",                1, 2, FEARG_1,      arg2_string_chan_or_job,
!                       ret_void,           JOB_FUNC(f_ch_log)},
      {"ch_logfile",    1, 2, FEARG_1,      arg2_string,
!                       ret_void,           JOB_FUNC(f_ch_logfile)},
      {"ch_open",               1, 2, FEARG_1,      arg2_string_dict,
                        ret_channel,        JOB_FUNC(f_ch_open)},
      {"ch_read",               1, 2, FEARG_1,      arg2_chan_or_job_dict,
--- 1750,1758 ----
      {"ch_info",               1, 1, FEARG_1,      arg1_chan_or_job,
                        ret_dict_any,       JOB_FUNC(f_ch_info)},
      {"ch_log",                1, 2, FEARG_1,      arg2_string_chan_or_job,
!                       ret_void,           f_ch_log},
      {"ch_logfile",    1, 2, FEARG_1,      arg2_string,
!                       ret_void,           f_ch_logfile},
      {"ch_open",               1, 2, FEARG_1,      arg2_string_dict,
                        ret_channel,        JOB_FUNC(f_ch_open)},
      {"ch_read",               1, 2, FEARG_1,      arg2_chan_or_job_dict,
*** ../vim-9.0.0976/src/gui_gtk_x11.c   2022-11-02 13:30:37.534314540 +0000
--- src/gui_gtk_x11.c   2022-11-30 17:14:17.835415111 +0000
***************
*** 407,413 ****
   * See https://github.com/vim/vim/issues/10123
   */
  # if 0  // Change to 1 to enable ch_log() calls for debugging.
! #  ifdef FEAT_JOB_CHANNEL
  #   define ENABLE_RESIZE_HISTORY_LOG
  #  endif
  # endif
--- 407,413 ----
   * See https://github.com/vim/vim/issues/10123
   */
  # if 0  // Change to 1 to enable ch_log() calls for debugging.
! #  ifdef FEAT_EVAL
  #   define ENABLE_RESIZE_HISTORY_LOG
  #  endif
  # endif
*** ../vim-9.0.0976/src/main.c  2022-11-28 18:51:38.951571546 +0000
--- src/main.c  2022-11-30 17:16:44.427410755 +0000
***************
*** 152,158 ****
            TIME_MSG("--- VIM STARTING ---");
        }
  # endif
! # ifdef FEAT_JOB_CHANNEL
        if (STRICMP(argv[i], "--log") == 0)
            ch_logfile((char_u *)(argv[i + 1]), (char_u *)"ao");
  # endif
--- 152,158 ----
            TIME_MSG("--- VIM STARTING ---");
        }
  # endif
! # ifdef FEAT_EVAL
        if (STRICMP(argv[i], "--log") == 0)
            ch_logfile((char_u *)(argv[i + 1]), (char_u *)"ao");
  # endif
***************
*** 1084,1090 ****
  {
      int is_safe = safe && is_safe_now();
  
! #ifdef FEAT_JOB_CHANNEL
      if (was_safe != is_safe)
        // Only log when the state changes, otherwise it happens at nearly
        // every key stroke.
--- 1084,1090 ----
  {
      int is_safe = safe && is_safe_now();
  
! #ifdef FEAT_EVAL
      if (was_safe != is_safe)
        // Only log when the state changes, otherwise it happens at nearly
        // every key stroke.
***************
*** 1104,1110 ****
      void
  state_no_longer_safe(char *reason UNUSED)
  {
! #ifdef FEAT_JOB_CHANNEL
      if (was_safe)
        ch_log(NULL, "SafeState: reset: %s", reason);
  #endif
--- 1104,1110 ----
      void
  state_no_longer_safe(char *reason UNUSED)
  {
! #ifdef FEAT_EVAL
      if (was_safe)
        ch_log(NULL, "SafeState: reset: %s", reason);
  #endif
***************
*** 1133,1146 ****
        // of calling feedkeys(), we check if it's now safe again (all keys
        // were consumed).
        was_safe = is_safe_now();
! #ifdef FEAT_JOB_CHANNEL
        if (was_safe)
            ch_log(NULL, "SafeState: undo reset");
  #endif
      }
      if (was_safe)
      {
! #ifdef FEAT_JOB_CHANNEL
        // Only do this message when another message was given, otherwise we
        // get lots of them.
        if ((did_repeated_msg & REPEATED_MSG_SAFESTATE) == 0)
--- 1133,1146 ----
        // of calling feedkeys(), we check if it's now safe again (all keys
        // were consumed).
        was_safe = is_safe_now();
! #ifdef FEAT_EVAL
        if (was_safe)
            ch_log(NULL, "SafeState: undo reset");
  #endif
      }
      if (was_safe)
      {
! #ifdef FEAT_EVAL
        // Only do this message when another message was given, otherwise we
        // get lots of them.
        if ((did_repeated_msg & REPEATED_MSG_SAFESTATE) == 0)
***************
*** 1154,1160 ****
  #endif
        apply_autocmds(EVENT_SAFESTATEAGAIN, NULL, NULL, FALSE, curbuf);
      }
! #ifdef FEAT_JOB_CHANNEL
      else
        ch_log(NULL,
                  "SafeState: back to waiting, not triggering SafeStateAgain");
--- 1154,1160 ----
  #endif
        apply_autocmds(EVENT_SAFESTATEAGAIN, NULL, NULL, FALSE, curbuf);
      }
! #ifdef FEAT_EVAL
      else
        ch_log(NULL,
                  "SafeState: back to waiting, not triggering SafeStateAgain");
***************
*** 1563,1569 ****
  getout(int exitval)
  {
      exiting = TRUE;
! #if defined(FEAT_JOB_CHANNEL)
      ch_log(NULL, "Exiting...");
  #endif
  
--- 1563,1569 ----
  getout(int exitval)
  {
      exiting = TRUE;
! #if defined(FEAT_EVAL)
      ch_log(NULL, "Exiting...");
  #endif
  
*** ../vim-9.0.0976/src/message.c       2022-11-29 16:09:14.408617365 +0000
--- src/message.c       2022-11-30 17:17:05.523409381 +0000
***************
*** 161,167 ****
                && STRCMP(s, last_msg_hist->msg)))
        add_msg_hist((char_u *)s, -1, attr);
  
! #ifdef FEAT_JOB_CHANNEL
      if (emsg_to_channel_log)
        // Write message in the channel log.
        ch_log(NULL, "ERROR: %s", s);
--- 161,167 ----
                && STRCMP(s, last_msg_hist->msg)))
        add_msg_hist((char_u *)s, -1, attr);
  
! #ifdef FEAT_EVAL
      if (emsg_to_channel_log)
        // Write message in the channel log.
        ch_log(NULL, "ERROR: %s", s);
***************
*** 725,731 ****
            if (emsg_silent == emsg_silent_def)
                ++did_emsg_def;
  #endif
! #ifdef FEAT_JOB_CHANNEL
            ch_log(NULL, "ERROR silent: %s", (char *)s);
  #endif
            return TRUE;
--- 725,731 ----
            if (emsg_silent == emsg_silent_def)
                ++did_emsg_def;
  #endif
! #ifdef FEAT_EVAL
            ch_log(NULL, "ERROR silent: %s", (char *)s);
  #endif
            return TRUE;
*** ../vim-9.0.0976/src/os_unix.c       2022-11-28 18:51:38.963571609 +0000
--- src/os_unix.c       2022-11-30 18:03:59.915039171 +0000
***************
*** 4747,4753 ****
            reset_signals();            // handle signals normally
            UNBLOCK_SIGNALS(&curset);
  
! # ifdef FEAT_JOB_CHANNEL
            if (ch_log_active())
            {
                ch_log(NULL, "closing channel log in the child process");
--- 4747,4753 ----
            reset_signals();            // handle signals normally
            UNBLOCK_SIGNALS(&curset);
  
! # ifdef FEAT_EVAL
            if (ch_log_active())
            {
                ch_log(NULL, "closing channel log in the child process");
***************
*** 5465,5471 ****
      char_u    *cmd,
      int               options)        // SHELL_*, see vim.h
  {
! #ifdef FEAT_JOB_CHANNEL
      ch_log(NULL, "executing shell command: %s", cmd);
  #endif
  #if defined(FEAT_GUI) && defined(FEAT_TERMINAL)
--- 5465,5471 ----
      char_u    *cmd,
      int               options)        // SHELL_*, see vim.h
  {
! #ifdef FEAT_EVAL
      ch_log(NULL, "executing shell command: %s", cmd);
  #endif
  #if defined(FEAT_GUI) && defined(FEAT_TERMINAL)
***************
*** 5597,5603 ****
        reset_signals();                // handle signals normally
        UNBLOCK_SIGNALS(&curset);
  
! # ifdef FEAT_JOB_CHANNEL
        if (ch_log_active())
            // close the log file in the child
            ch_logfile((char_u *)"", (char_u *)"");
--- 5597,5603 ----
        reset_signals();                // handle signals normally
        UNBLOCK_SIGNALS(&curset);
  
! # ifdef FEAT_EVAL
        if (ch_log_active())
            // close the log file in the child
            ch_logfile((char_u *)"", (char_u *)"");
***************
*** 8324,8330 ****
        timer_created = TRUE;
      }
  
! # ifdef FEAT_JOB_CHANNEL
      ch_log(NULL, "setting timeout timer to %d sec %ld nsec",
               (int)interval.it_value.tv_sec, (long)interval.it_value.tv_nsec);
  # endif
--- 8324,8330 ----
        timer_created = TRUE;
      }
  
! # ifdef FEAT_EVAL
      ch_log(NULL, "setting timeout timer to %d sec %ld nsec",
               (int)interval.it_value.tv_sec, (long)interval.it_value.tv_nsec);
  # endif
*** ../vim-9.0.0976/src/os_win32.c      2022-11-28 18:51:38.963571609 +0000
--- src/os_win32.c      2022-11-30 18:04:24.159031543 +0000
***************
*** 2222,2228 ****
        buf[len++] = typeahead[0];
        mch_memmove(typeahead, typeahead + 1, --typeaheadlen);
      }
! # ifdef FEAT_JOB_CHANNEL
      if (len > 0)
      {
        buf[len] = NUL;
--- 2222,2228 ----
        buf[len++] = typeahead[0];
        mch_memmove(typeahead, typeahead + 1, --typeaheadlen);
      }
! # ifdef FEAT_EVAL
      if (len > 0)
      {
        buf[len] = NUL;
***************
*** 4923,4929 ****
      int               tmode = cur_tmode;
      WCHAR     szShellTitle[512];
  
! #ifdef FEAT_JOB_CHANNEL
      ch_log(NULL, "executing shell command: %s", cmd);
  #endif
      // Change the title to reflect that we are in a subshell.
--- 4923,4929 ----
      int               tmode = cur_tmode;
      WCHAR     szShellTitle[512];
  
! #ifdef FEAT_EVAL
      ch_log(NULL, "executing shell command: %s", cmd);
  #endif
      // Change the title to reflect that we are in a subshell.
*** ../vim-9.0.0976/src/regexp_bt.c     2022-11-26 11:47:07.175323334 +0000
--- src/regexp_bt.c     2022-11-30 18:04:44.815025130 +0000
***************
*** 3163,3169 ****
      {
        if (timed_out != NULL)
        {
! # ifdef FEAT_JOB_CHANNEL
            if (!*timed_out)
                ch_log(NULL, "BT regexp timed out");
  # endif
--- 3163,3169 ----
      {
        if (timed_out != NULL)
        {
! # ifdef FEAT_EVAL
            if (!*timed_out)
                ch_log(NULL, "BT regexp timed out");
  # endif
*** ../vim-9.0.0976/src/regexp_nfa.c    2022-11-26 11:47:07.175323334 +0000
--- src/regexp_nfa.c    2022-11-30 18:05:01.039020134 +0000
***************
*** 4250,4256 ****
      {
        if (nfa_timed_out != NULL)
        {
! # ifdef FEAT_JOB_CHANNEL
            if (!*nfa_timed_out)
                ch_log(NULL, "NFA regexp timed out");
  # endif
--- 4250,4256 ----
      {
        if (nfa_timed_out != NULL)
        {
! # ifdef FEAT_EVAL
            if (!*nfa_timed_out)
                ch_log(NULL, "NFA regexp timed out");
  # endif
*** ../vim-9.0.0976/src/term.c  2022-11-30 10:23:11.691069019 +0000
--- src/term.c  2022-11-30 18:05:32.451010578 +0000
***************
*** 2641,2647 ****
        len = out_pos;
        out_pos = 0;
        ui_write(out_buf, len, FALSE);
! #ifdef FEAT_JOB_CHANNEL
        if (ch_log_output != FALSE)
        {
            out_buf[len] = NUL;
--- 2641,2647 ----
        len = out_pos;
        out_pos = 0;
        ui_write(out_buf, len, FALSE);
! #ifdef FEAT_EVAL
        if (ch_log_output != FALSE)
        {
            out_buf[len] = NUL;
*** ../vim-9.0.0976/src/time.c  2022-10-15 16:28:59.622401541 +0100
--- src/time.c  2022-11-30 18:06:10.566999179 +0000
***************
*** 491,497 ****
      typval_T  rettv;
      typval_T  argv[2];
  
! #ifdef FEAT_JOB_CHANNEL
      if (ch_log_active())
      {
        callback_T *cb = &timer->tr_callback;
--- 491,497 ----
      typval_T  rettv;
      typval_T  argv[2];
  
! #ifdef FEAT_EVAL
      if (ch_log_active())
      {
        callback_T *cb = &timer->tr_callback;
***************
*** 509,515 ****
      call_callback(&timer->tr_callback, -1, &rettv, 1, argv);
      clear_tv(&rettv);
  
! #ifdef FEAT_JOB_CHANNEL
      ch_log(NULL, "timer callback finished");
  #endif
  }
--- 509,515 ----
      call_callback(&timer->tr_callback, -1, &rettv, 1, argv);
      clear_tv(&rettv);
  
! #ifdef FEAT_EVAL
      ch_log(NULL, "timer callback finished");
  #endif
  }
*** ../vim-9.0.0976/src/ui.c    2022-11-15 17:43:28.442135533 +0000
--- src/ui.c    2022-11-30 18:06:45.530988898 +0000
***************
*** 538,545 ****
  #ifdef FEAT_EVAL
      if (ui_delay_for_testing > 0)
        msec = ui_delay_for_testing;
- #endif
- #ifdef FEAT_JOB_CHANNEL
      ch_log(NULL, "ui_delay(%ld)", msec);
  #endif
  #ifdef FEAT_GUI
--- 538,543 ----
***************
*** 968,974 ****
  #  else
        len = read(read_cmd_fd, (char *)inbuf + inbufcount, readlen);
  #  endif
! #  ifdef FEAT_JOB_CHANNEL
        if (len > 0)
        {
            inbuf[inbufcount + len] = NUL;
--- 966,972 ----
  #  else
        len = read(read_cmd_fd, (char *)inbuf + inbufcount, readlen);
  #  endif
! #  ifdef FEAT_EVAL
        if (len > 0)
        {
            inbuf[inbufcount + len] = NUL;
*** ../vim-9.0.0976/src/globals.h       2022-11-28 20:34:47.704140309 +0000
--- src/globals.h       2022-11-30 16:38:18.815223080 +0000
***************
*** 20,31 ****
  EXTERN long   Rows                    // nr of rows in the screen
  #ifdef DO_INIT
  # if defined(MSWIN)
!                           = 25L
  # else
!                           = 24L
  # endif
  #endif
!                           ;
  EXTERN long   Columns INIT(= 80);     // nr of columns in the screen
  
  /*
--- 20,31 ----
  EXTERN long   Rows                    // nr of rows in the screen
  #ifdef DO_INIT
  # if defined(MSWIN)
!                   = 25L
  # else
!                   = 24L
  # endif
  #endif
!                   ;
  EXTERN long   Columns INIT(= 80);     // nr of columns in the screen
  
  /*
***************
*** 1218,1226 ****
  
  EXTERN pos_T  saved_cursor            // w_cursor before formatting text.
  #ifdef DO_INIT
!       = {0, 0, 0}
  #endif
!       ;
  
  /*
   * Stuff for insert mode.
--- 1218,1226 ----
  
  EXTERN pos_T  saved_cursor            // w_cursor before formatting text.
  #ifdef DO_INIT
!                   = {0, 0, 0}
  #endif
!                   ;
  
  /*
   * Stuff for insert mode.
***************
*** 1589,1597 ****
  EXTERN int    did_cursorhold INIT(= FALSE); // set when CursorHold t'gerd
  EXTERN pos_T  last_cursormoved              // for CursorMoved event
  # ifdef DO_INIT
!                       = {0, 0, 0}
  # endif
!                       ;
  
  EXTERN int    postponed_split INIT(= 0);  // for CTRL-W CTRL-] command
  EXTERN int    postponed_split_flags INIT(= 0);  // args for win_split()
--- 1589,1597 ----
  EXTERN int    did_cursorhold INIT(= FALSE); // set when CursorHold t'gerd
  EXTERN pos_T  last_cursormoved              // for CursorMoved event
  # ifdef DO_INIT
!                   = {0, 0, 0}
  # endif
!                   ;
  
  EXTERN int    postponed_split INIT(= 0);  // for CTRL-W CTRL-] command
  EXTERN int    postponed_split_flags INIT(= 0);  // args for win_split()
***************
*** 1751,1775 ****
  
  EXTERN option_table_T printer_opts[OPT_PRINT_NUM_OPTIONS]
  # ifdef DO_INIT
!  =
! {
!     {"top",   TRUE, 0, NULL, 0, FALSE},
!     {"bottom",        TRUE, 0, NULL, 0, FALSE},
!     {"left",  TRUE, 0, NULL, 0, FALSE},
!     {"right", TRUE, 0, NULL, 0, FALSE},
!     {"header",        TRUE, 0, NULL, 0, FALSE},
!     {"syntax",        FALSE, 0, NULL, 0, FALSE},
!     {"number",        FALSE, 0, NULL, 0, FALSE},
!     {"wrap",  FALSE, 0, NULL, 0, FALSE},
!     {"duplex",        FALSE, 0, NULL, 0, FALSE},
!     {"portrait", FALSE, 0, NULL, 0, FALSE},
!     {"paper", FALSE, 0, NULL, 0, FALSE},
!     {"collate",       FALSE, 0, NULL, 0, FALSE},
!     {"jobsplit", FALSE, 0, NULL, 0, FALSE},
!     {"formfeed", FALSE, 0, NULL, 0, FALSE},
! }
  # endif
! ;
  
  // For prt_get_unit().
  # define PRT_UNIT_NONE        -1
--- 1751,1774 ----
  
  EXTERN option_table_T printer_opts[OPT_PRINT_NUM_OPTIONS]
  # ifdef DO_INIT
!     = {
!       {"top", TRUE, 0, NULL, 0, FALSE},
!       {"bottom",      TRUE, 0, NULL, 0, FALSE},
!       {"left",        TRUE, 0, NULL, 0, FALSE},
!       {"right",       TRUE, 0, NULL, 0, FALSE},
!       {"header",      TRUE, 0, NULL, 0, FALSE},
!       {"syntax",      FALSE, 0, NULL, 0, FALSE},
!       {"number",      FALSE, 0, NULL, 0, FALSE},
!       {"wrap",        FALSE, 0, NULL, 0, FALSE},
!       {"duplex",      FALSE, 0, NULL, 0, FALSE},
!       {"portrait", FALSE, 0, NULL, 0, FALSE},
!       {"paper",       FALSE, 0, NULL, 0, FALSE},
!       {"collate",     FALSE, 0, NULL, 0, FALSE},
!       {"jobsplit", FALSE, 0, NULL, 0, FALSE},
!       {"formfeed", FALSE, 0, NULL, 0, FALSE},
!     }
  # endif
!     ;
  
  // For prt_get_unit().
  # define PRT_UNIT_NONE        -1
***************
*** 1871,1879 ****
  // Grow array to collect error messages in until they can be displayed.
  EXTERN garray_T error_ga
  # ifdef DO_INIT
!       = {0, 0, 0, 0, NULL}
  # endif
!       ;
  #endif
  
  #ifdef FEAT_NETBEANS_INTG
--- 1870,1878 ----
  // Grow array to collect error messages in until they can be displayed.
  EXTERN garray_T error_ga
  # ifdef DO_INIT
!                   = {0, 0, 0, 0, NULL}
  # endif
!                   ;
  #endif
  
  #ifdef FEAT_NETBEANS_INTG
***************
*** 1991,1997 ****
--- 1990,2003 ----
  EXTERN HINSTANCE g_hinst INIT(= NULL);
  #endif
  
+ 
  #if defined(FEAT_JOB_CHANNEL)
+ EXTERN char *ch_part_names[]
+ # ifdef DO_INIT
+               = {"sock", "out", "err", "in"}
+ # endif
+               ;
+ 
  EXTERN int did_repeated_msg INIT(= 0);
  # define REPEATED_MSG_LOOKING     1
  # define REPEATED_MSG_SAFESTATE           2
*** ../vim-9.0.0976/src/Makefile        2022-11-18 22:14:04.798988157 +0000
--- src/Makefile        2022-11-30 16:13:22.541639488 +0000
***************
*** 1531,1536 ****
--- 1532,1538 ----
        json.c \
        list.c \
        locale.c \
+       logfile.c \
        main.c \
        map.c \
        mark.c \
***************
*** 1690,1695 ****
--- 1692,1698 ----
        objects/insexpand.o \
        objects/list.o \
        objects/locale.o \
+       objects/logfile.o \
        objects/map.o \
        objects/mark.o \
        objects/match.o \
***************
*** 1874,1879 ****
--- 1877,1883 ----
        json.pro \
        list.pro \
        locale.pro \
+       logfile.pro \
        main.pro \
        map.pro \
        mark.pro \
***************
*** 3306,3311 ****
--- 3310,3318 ----
  objects/locale.o: locale.c
        $(CCC) -o $@ locale.c
  
+ objects/logfile.o: logfile.c
+       $(CCC) -o $@ logfile.c
+ 
  objects/main.o: main.c
        $(CCC) -o $@ main.c
  
***************
*** 3896,3901 ****
--- 3903,3913 ----
   auto/osdef.h ascii.h keymap.h termdefs.h macros.h option.h beval.h \
   proto/gui_beval.pro structs.h regexp.h gui.h libvterm/include/vterm.h \
   libvterm/include/vterm_keycodes.h alloc.h ex_cmds.h spell.h proto.h \
+  globals.h errors.h
+ objects/logfile.o: logfile.c vim.h protodef.h auto/config.h feature.h 
os_unix.h \
+  auto/osdef.h ascii.h keymap.h termdefs.h macros.h option.h beval.h \
+  proto/gui_beval.pro structs.h regexp.h gui.h libvterm/include/vterm.h \
+  libvterm/include/vterm_keycodes.h alloc.h ex_cmds.h spell.h proto.h \
   globals.h errors.h
  objects/main.o: main.c vim.h protodef.h auto/config.h feature.h os_unix.h \
   auto/osdef.h ascii.h keymap.h termdefs.h macros.h option.h beval.h \
*** ../vim-9.0.0976/src/Make_ami.mak    2022-10-08 19:26:35.694195418 +0100
--- src/Make_ami.mak    2022-11-30 16:40:15.867102172 +0000
***************
*** 124,129 ****
--- 124,130 ----
        json.c \
        list.c \
        locale.c \
+       logfile.c \
        main.c \
        mark.c \
        map.c \
*** ../vim-9.0.0976/src/Make_mvc.mak    2022-11-10 23:17:15.863670823 +0000
--- src/Make_mvc.mak    2022-11-30 16:43:01.074948224 +0000
***************
*** 685,690 ****
--- 685,691 ----
        $(OUTDIR)\json.obj \
        $(OUTDIR)\list.obj \
        $(OUTDIR)\locale.obj \
+       $(OUTDIR)\logfile.obj \
        $(OUTDIR)\main.obj \
        $(OUTDIR)\map.obj \
        $(OUTDIR)\mark.obj \
***************
*** 1586,1591 ****
--- 1587,1594 ----
  
  $(OUTDIR)/locale.obj: $(OUTDIR) locale.c  $(INCL)
  
+ $(OUTDIR)/logfile.obj:        $(OUTDIR) logfile.c  $(INCL)
+ 
  $(OUTDIR)/main.obj:   $(OUTDIR) main.c  $(INCL) $(CUI_INCL)
  
  $(OUTDIR)/map.obj:    $(OUTDIR) map.c  $(INCL)
***************
*** 1862,1867 ****
--- 1865,1871 ----
        proto/json.pro \
        proto/list.pro \
        proto/locale.pro \
+       proto/logfile.pro \
        proto/main.pro \
        proto/map.pro \
        proto/mark.pro \
*** ../vim-9.0.0976/src/Make_vms.mms    2022-10-08 19:26:35.698195391 +0100
--- src/Make_vms.mms    2022-11-30 16:43:19.654931909 +0000
***************
*** 357,362 ****
--- 357,363 ----
        json.c \
        list.c \
        locale.c \
+       logfile.c \
        main.c \
        map.c \
        mark.c \
***************
*** 481,486 ****
--- 482,488 ----
        json.obj \
        list.obj \
        locale.obj \
+       logfile.obj \
        main.obj \
        map.obj \
        mark.obj \
***************
*** 928,933 ****
--- 930,939 ----
   ascii.h keymap.h termdefs.h macros.h option.h structs.h regexp.h gui.h \
   beval.h [.proto]gui_beval.pro alloc.h ex_cmds.h spell.h proto.h \
   errors.h globals.h
+ logfile.obj : logfile.c vim.h [.auto]config.h feature.h os_unix.h \
+  ascii.h keymap.h termdefs.h macros.h option.h structs.h regexp.h gui.h \
+  beval.h [.proto]gui_beval.pro alloc.h ex_cmds.h spell.h proto.h \
+  errors.h globals.h
  main.obj : main.c vim.h [.auto]config.h feature.h os_unix.h   \
   ascii.h keymap.h termdefs.h macros.h structs.h regexp.h gui.h beval.h \
   [.proto]gui_beval.pro option.h ex_cmds.h proto.h errors.h globals.h \
*** ../vim-9.0.0976/src/Make_cyg_ming.mak       2022-11-14 14:50:11.924510877 
+0000
--- src/Make_cyg_ming.mak       2022-11-30 16:42:28.146977596 +0000
***************
*** 800,805 ****
--- 800,806 ----
        $(OUTDIR)/json.o \
        $(OUTDIR)/list.o \
        $(OUTDIR)/locale.o \
+       $(OUTDIR)/logfile.o \
        $(OUTDIR)/main.o \
        $(OUTDIR)/map.o \
        $(OUTDIR)/mark.o \
*** ../vim-9.0.0976/src/version.c       2022-11-30 10:23:11.691069019 +0000
--- src/version.c       2022-11-30 15:35:06.173296172 +0000
***************
*** 697,698 ****
--- 697,700 ----
  {   /* Add new patch number below this line */
+ /**/
+     977,
  /**/

-- 
hundred-and-one symptoms of being an internet addict:
188. You purchase a laptop so you can surf while sitting on the can.

 /// Bram Moolenaar -- [email protected] -- http://www.Moolenaar.net   \\\
///                                                                      \\\
\\\        sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ ///
 \\\            help me help AIDS victims -- http://ICCF-Holland.org    ///

-- 
-- 
You received this message from the "vim_dev" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php

--- 
You received this message because you are subscribed to the Google Groups 
"vim_dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To view this discussion on the web visit 
https://groups.google.com/d/msgid/vim_dev/20221130181251.BA5E71C06AE%40moolenaar.net.

Raspunde prin e-mail lui