To: vim_dev@googlegroups.com Subject: Patch 7.4.2344 Fcc: outbox From: Bram Moolenaar Mime-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ------------ Patch 7.4.2344 Problem: The "Reading from channel output..." message can be unwanted. Appending to a buffer leaves an empty first line behind. Solution: Add the "out_msg" and "err_msg" options. Writing the first line overwrites the first, empty line. Files: src/structs.h, src/channel.c, src/testdir/test_channel.vim, runtime/doc/channel.txt *** ../vim-7.4.2343/src/structs.h 2016-09-05 22:45:25.068731124 +0200 --- src/structs.h 2016-09-07 22:48:11.546530092 +0200 *************** *** 1634,1639 **** --- 1634,1643 ---- #define JO_ERR_MODIFIABLE 0x40000000 /* "err_modifiable" (JO_OUT_ << 1) */ #define JO_ALL 0x7fffffff + #define JO2_OUT_MSG 0x0001 /* "out_msg" */ + #define JO2_ERR_MSG 0x0002 /* "err_msg" (JO_OUT_ << 1) */ + #define JO2_ALL 0x0003 + #define JO_MODE_ALL (JO_MODE + JO_IN_MODE + JO_OUT_MODE + JO_ERR_MODE) #define JO_CB_ALL \ (JO_CALLBACK + JO_OUT_CALLBACK + JO_ERR_CALLBACK + JO_CLOSE_CALLBACK) *************** *** 1645,1650 **** --- 1649,1655 ---- typedef struct { int jo_set; /* JO_ bits for values that were set */ + int jo_set2; /* JO2_ bits for values that were set */ ch_mode_T jo_mode; ch_mode_T jo_in_mode; *************** *** 1656,1661 **** --- 1661,1667 ---- char_u *jo_io_name[4]; /* not allocated! */ int jo_io_buf[4]; int jo_modifiable[4]; + int jo_message[4]; channel_T *jo_channel; linenr_T jo_in_top; *** ../vim-7.4.2343/src/channel.c 2016-09-04 20:44:38.502814059 +0200 --- src/channel.c 2016-09-07 23:15:55.504080975 +0200 *************** *** 1079,1085 **** * Returns NULL if there is something very wrong (error already reported). */ static buf_T * ! find_buffer(char_u *name, int err) { buf_T *buf = NULL; buf_T *save_curbuf = curbuf; --- 1079,1085 ---- * Returns NULL if there is something very wrong (error already reported). */ static buf_T * ! find_buffer(char_u *name, int err, int msg) { buf_T *buf = NULL; buf_T *save_curbuf = curbuf; *************** *** 1104,1110 **** #endif if (curbuf->b_ml.ml_mfp == NULL) ml_open(curbuf); ! ml_replace(1, (char_u *)(err ? "Reading from channel error..." : "Reading from channel output..."), TRUE); changed_bytes(1, 0); curbuf = save_curbuf; --- 1104,1111 ---- #endif if (curbuf->b_ml.ml_mfp == NULL) ml_open(curbuf); ! if (msg) ! ml_replace(1, (char_u *)(err ? "Reading from channel error..." : "Reading from channel output..."), TRUE); changed_bytes(1, 0); curbuf = save_curbuf; *************** *** 1196,1202 **** } else { ! buf = find_buffer(opt->jo_io_name[PART_OUT], FALSE); } if (buf != NULL) { --- 1197,1207 ---- } else { ! int msg = TRUE; ! ! if (opt->jo_set2 & JO2_OUT_MSG) ! msg = opt->jo_message[PART_OUT]; ! buf = find_buffer(opt->jo_io_name[PART_OUT], FALSE, msg); } if (buf != NULL) { *************** *** 1235,1241 **** EMSGN(_(e_nobufnr), (long)opt->jo_io_buf[PART_ERR]); } else ! buf = find_buffer(opt->jo_io_name[PART_ERR], TRUE); if (buf != NULL) { if (opt->jo_set & JO_ERR_MODIFIABLE) --- 1240,1252 ---- EMSGN(_(e_nobufnr), (long)opt->jo_io_buf[PART_ERR]); } else ! { ! int msg = TRUE; ! ! if (opt->jo_set2 & JO2_ERR_MSG) ! msg = opt->jo_message[PART_ERR]; ! buf = find_buffer(opt->jo_io_name[PART_ERR], TRUE, msg); ! } if (buf != NULL) { if (opt->jo_set & JO_ERR_MODIFIABLE) *************** *** 2227,2232 **** --- 2238,2244 ---- int save_write_to = buffer->b_write_to_channel; chanpart_T *ch_part = &channel->ch_part[part]; int save_p_ma = buffer->b_p_ma; + int empty = (buffer->b_ml.ml_flags & ML_EMPTY); if (!buffer->b_p_ma && !ch_part->ch_nomodifiable) { *************** *** 2253,2261 **** curbuf = buffer; u_sync(TRUE); /* ignore undo failure, undo is not very useful here */ ! ignored = u_save(lnum, lnum + 1); ! ml_append(lnum, msg, 0, FALSE); appended_lines_mark(lnum, 1L); curbuf = save_curbuf; if (ch_part->ch_nomodifiable) --- 2265,2280 ---- curbuf = buffer; u_sync(TRUE); /* ignore undo failure, undo is not very useful here */ ! ignored = u_save(lnum, lnum + 1 + (empty ? 1 : 0)); ! if (empty) ! { ! /* The buffer is empty, replace the first (dummy) line. */ ! ml_replace(lnum, msg, TRUE); ! lnum = 0; ! } ! else ! ml_append(lnum, msg, 0, FALSE); appended_lines_mark(lnum, 1L); curbuf = save_curbuf; if (ch_part->ch_nomodifiable) *************** *** 4083,4088 **** --- 4102,4117 ---- opt->jo_set |= JO_OUT_MODIFIABLE << (part - PART_OUT); opt->jo_modifiable[part] = get_tv_number(item); } + else if (STRCMP(hi->hi_key, "out_msg") == 0 + || STRCMP(hi->hi_key, "err_msg") == 0) + { + part = part_from_char(*hi->hi_key); + + if (!(supported & JO_OUT_IO)) + break; + opt->jo_set2 |= JO2_OUT_MSG << (part - PART_OUT); + opt->jo_message[part] = get_tv_number(item); + } else if (STRCMP(hi->hi_key, "in_top") == 0 || STRCMP(hi->hi_key, "in_bot") == 0) { *** ../vim-7.4.2343/src/testdir/test_channel.vim 2016-09-03 18:47:19.205586286 +0200 --- src/testdir/test_channel.vim 2016-09-07 23:23:56.155913213 +0200 *************** *** 638,658 **** let g:Ch_bufClosed = 'yes' endfunc ! func Run_test_pipe_to_buffer(use_name, nomod) if !has('job') return endif call ch_log('Test_pipe_to_buffer()') let g:Ch_bufClosed = 'no' let options = {'out_io': 'buffer', 'close_cb': 'BufCloseCb'} if a:use_name let options['out_name'] = 'pipe-output' ! let firstline = 'Reading from channel output...' else sp pipe-output let options['out_buf'] = bufnr('%') quit ! let firstline = '' endif if a:nomod let options['out_modifiable'] = 0 --- 638,664 ---- let g:Ch_bufClosed = 'yes' endfunc ! func Run_test_pipe_to_buffer(use_name, nomod, do_msg) if !has('job') return endif call ch_log('Test_pipe_to_buffer()') let g:Ch_bufClosed = 'no' let options = {'out_io': 'buffer', 'close_cb': 'BufCloseCb'} + let expected = ['', 'line one', 'line two', 'this', 'AND this', 'Goodbye!'] if a:use_name let options['out_name'] = 'pipe-output' ! if a:do_msg ! let expected[0] = 'Reading from channel output...' ! else ! let options['out_msg'] = 0 ! call remove(expected, 0) ! endif else sp pipe-output let options['out_buf'] = bufnr('%') quit ! call remove(expected, 0) endif if a:nomod let options['out_modifiable'] = 0 *************** *** 667,673 **** call ch_sendraw(handle, "quit\n") sp pipe-output call WaitFor('line("$") >= 6 && g:Ch_bufClosed == "yes"') ! call assert_equal([firstline, 'line one', 'line two', 'this', 'AND this', 'Goodbye!'], getline(1, '$')) if a:nomod call assert_equal(0, &modifiable) else --- 673,679 ---- call ch_sendraw(handle, "quit\n") sp pipe-output call WaitFor('line("$") >= 6 && g:Ch_bufClosed == "yes"') ! call assert_equal(expected, getline(1, '$')) if a:nomod call assert_equal(0, &modifiable) else *************** *** 681,711 **** endfunc func Test_pipe_to_buffer_name() ! call Run_test_pipe_to_buffer(1, 0) endfunc func Test_pipe_to_buffer_nr() ! call Run_test_pipe_to_buffer(0, 0) endfunc func Test_pipe_to_buffer_name_nomod() ! call Run_test_pipe_to_buffer(1, 1) endfunc ! func Run_test_pipe_err_to_buffer(use_name, nomod) if !has('job') return endif call ch_log('Test_pipe_err_to_buffer()') let options = {'err_io': 'buffer'} if a:use_name let options['err_name'] = 'pipe-err' ! let firstline = 'Reading from channel error...' else sp pipe-err let options['err_buf'] = bufnr('%') quit ! let firstline = '' endif if a:nomod let options['err_modifiable'] = 0 --- 687,727 ---- endfunc func Test_pipe_to_buffer_name() ! call Run_test_pipe_to_buffer(1, 0, 1) endfunc func Test_pipe_to_buffer_nr() ! call Run_test_pipe_to_buffer(0, 0, 1) endfunc func Test_pipe_to_buffer_name_nomod() ! call Run_test_pipe_to_buffer(1, 1, 1) ! endfunc ! ! func Test_pipe_to_buffer_name_nomsg() ! call Run_test_pipe_to_buffer(1, 0, 1) endfunc ! func Run_test_pipe_err_to_buffer(use_name, nomod, do_msg) if !has('job') return endif call ch_log('Test_pipe_err_to_buffer()') let options = {'err_io': 'buffer'} + let expected = ['', 'line one', 'line two', 'this', 'AND this'] if a:use_name let options['err_name'] = 'pipe-err' ! if a:do_msg ! let expected[0] = 'Reading from channel error...' ! else ! let options['err_msg'] = 0 ! call remove(expected, 0) ! endif else sp pipe-err let options['err_buf'] = bufnr('%') quit ! call remove(expected, 0) endif if a:nomod let options['err_modifiable'] = 0 *************** *** 720,726 **** call ch_sendraw(handle, "quit\n") sp pipe-err call WaitFor('line("$") >= 5') ! call assert_equal([firstline, 'line one', 'line two', 'this', 'AND this'], getline(1, '$')) if a:nomod call assert_equal(0, &modifiable) else --- 736,742 ---- call ch_sendraw(handle, "quit\n") sp pipe-err call WaitFor('line("$") >= 5') ! call assert_equal(expected, getline(1, '$')) if a:nomod call assert_equal(0, &modifiable) else *************** *** 733,747 **** endfunc func Test_pipe_err_to_buffer_name() ! call Run_test_pipe_err_to_buffer(1, 0) endfunc func Test_pipe_err_to_buffer_nr() ! call Run_test_pipe_err_to_buffer(0, 0) endfunc func Test_pipe_err_to_buffer_name_nomod() ! call Run_test_pipe_err_to_buffer(1, 1) endfunc func Test_pipe_both_to_buffer() --- 749,767 ---- endfunc func Test_pipe_err_to_buffer_name() ! call Run_test_pipe_err_to_buffer(1, 0, 1) endfunc func Test_pipe_err_to_buffer_nr() ! call Run_test_pipe_err_to_buffer(0, 0, 1) endfunc func Test_pipe_err_to_buffer_name_nomod() ! call Run_test_pipe_err_to_buffer(1, 1, 1) ! endfunc ! ! func Test_pipe_err_to_buffer_name_nomsg() ! call Run_test_pipe_err_to_buffer(1, 0, 0) endfunc func Test_pipe_both_to_buffer() *************** *** 1407,1413 **** 1,$delete call job_start('cat test_channel.vim', {'out_io': 'buffer', 'out_name': 'testout'}) call WaitFor('line("$") > g:linecount') ! call assert_inrange(g:linecount + 1, g:linecount + 2, line('$')) bwipe! endfunc --- 1427,1433 ---- 1,$delete call job_start('cat test_channel.vim', {'out_io': 'buffer', 'out_name': 'testout'}) call WaitFor('line("$") > g:linecount') ! call assert_inrange(g:linecount, g:linecount + 1, line('$')) bwipe! endfunc *************** *** 1425,1433 **** 1,$delete call job_start('cat Xtestread', {'out_io': 'buffer', 'out_name': 'testout'}) call WaitFor('line("$") > 2') ! call assert_equal("asdf\nasdf", getline(2)) ! call assert_equal("xxx\n", getline(3)) ! call assert_equal("\nyyy", getline(4)) call delete('Xtestread') bwipe! --- 1445,1453 ---- 1,$delete call job_start('cat Xtestread', {'out_io': 'buffer', 'out_name': 'testout'}) call WaitFor('line("$") > 2') ! call assert_equal("asdf\nasdf", getline(1)) ! call assert_equal("xxx\n", getline(2)) ! call assert_equal("\nyyy", getline(3)) call delete('Xtestread') bwipe! *** ../vim-7.4.2343/runtime/doc/channel.txt 2016-09-01 15:11:13.548265402 +0200 --- runtime/doc/channel.txt 2016-09-07 22:41:32.602001595 +0200 *************** *** 1,4 **** ! *channel.txt* For Vim version 7.4. Last change: 2016 Mar 14 VIM REFERENCE MANUAL by Bram Moolenaar --- 1,4 ---- ! *channel.txt* For Vim version 7.4. Last change: 2016 Sep 07 VIM REFERENCE MANUAL by Bram Moolenaar *************** *** 6,18 **** Inter-process communication *channel* - DRAFT DRAFT DRAFT DRAFT DRAFT DRAFT DRAFT DRAFT DRAFT DRAFT - Vim uses channels to communicate with other processes. ! A channel uses a socket or pipes *socket-interface* Jobs can be used to start processes and communicate with them. - - Vim current supports up to 10 simultaneous channels. The Netbeans interface also uses a channel. |netbeans| 1. Overview |job-channel-overview| --- 6,14 ---- Inter-process communication *channel* Vim uses channels to communicate with other processes. ! A channel uses a socket or pipes. *socket-interface* Jobs can be used to start processes and communicate with them. The Netbeans interface also uses a channel. |netbeans| 1. Overview |job-channel-overview| *************** *** 29,35 **** --- 25,33 ---- {Vi does not have any of these features} {only when compiled with the |+channel| feature for channel stuff} + You can check this with: `has('channel')` {only when compiled with the |+job| feature for job stuff} + You can check this with: `has('job')` ============================================================================== 1. Overview *job-channel-overview* *************** *** 58,67 **** - Using a job connected through pipes in NL mode. E.g., to run a style checker and receive errors and warnings. - Using a deamon, connecting over a socket in JSON mode. E.g. to lookup ! crosss-refrences in a database. ============================================================================== ! 2. Channel demo *channel-demo* This requires Python. The demo program can be found in $VIMRUNTIME/tools/demoserver.py --- 56,65 ---- - Using a job connected through pipes in NL mode. E.g., to run a style checker and receive errors and warnings. - Using a deamon, connecting over a socket in JSON mode. E.g. to lookup ! cross-references in a database. ============================================================================== ! 2. Channel demo *channel-demo* *demoserver.py* This requires Python. The demo program can be found in $VIMRUNTIME/tools/demoserver.py *************** *** 120,143 **** {address} has the form "hostname:port". E.g., "localhost:8765". ! {options} is a dictionary with optional entries: "mode" can be: *channel-mode* "json" - Use JSON, see below; most convenient way. Default. "js" - Use JS (JavaScript) encoding, more efficient than JSON. "nl" - Use messages that end in a NL character "raw" - Use raw messages - *in_mode* *out_mode* *err_mode* - "in_mode" mode specifically for stdin, only when using pipes - "out_mode" mode specifically for stdout, only when using pipes - "err_mode" mode specifically for stderr, only when using pipes - Note: when setting "mode" the part specific mode is - overwritten. Therefore set "mode" first and the part specific - mode later. - - Note: when writing to a file or buffer and when reading from a - buffer NL mode is used by default. - *channel-callback* *E921* "callback" A function that is called when a message is received that is not handled otherwise. It gets two arguments: the channel --- 118,130 ---- {address} has the form "hostname:port". E.g., "localhost:8765". ! {options} is a dictionary with optional entries: *channel-open-options* "mode" can be: *channel-mode* "json" - Use JSON, see below; most convenient way. Default. "js" - Use JS (JavaScript) encoding, more efficient than JSON. "nl" - Use messages that end in a NL character "raw" - Use raw messages *channel-callback* *E921* "callback" A function that is called when a message is received that is not handled otherwise. It gets two arguments: the channel *************** *** 153,172 **** excluding the NL. When "mode" is "raw" the "msg" argument is the whole message as a string. ! *out_cb* ! "out_cb" A function like "callback" but used for stdout. Only for when ! the channel uses pipes. When "out_cb" wasn't set the channel ! callback is used. ! *err_cb* ! "err_cb" A function like "callback" but used for stderr. Only for when ! the channel uses pipes. When "err_cb" wasn't set the channel ! callback is used. *close_cb* "close_cb" A function that is called when the channel gets closed, other than by calling ch_close(). It should be defined like this: > func MyCloseHandler(channel) ! < *waittime* "waittime" The time to wait for the connection to be made in milliseconds. A negative number waits forever. --- 140,162 ---- excluding the NL. When "mode" is "raw" the "msg" argument is the whole message as a string. ! ! For all callbacks: Use |function()| to bind it to arguments ! and/or a Dictionary. Or use the form "dict.function" to bind ! the Dictionary. ! ! Callbacks are only called at a "safe" moment, usually when Vim ! is waiting for the user to type a character. Vim does not use ! multi-threading. *close_cb* "close_cb" A function that is called when the channel gets closed, other than by calling ch_close(). It should be defined like this: > func MyCloseHandler(channel) ! < Vim will invoke callbacks that handle data before invoking ! close_cb, thus when this function is called no more data will ! be received. ! *waittime* "waittime" The time to wait for the connection to be made in milliseconds. A negative number waits forever. *************** *** 175,190 **** actually uses a 1 msec timeout, that is required on many systems. Use a larger value for a remote server, e.g. 10 msec at least. ! "timeout" The time to wait for a request when blocking, E.g. when using ch_evalexpr(). In milliseconds. The default is 2000 (2 seconds). - *out_timeout* *err_timeout* - "out_timeout" Timeout for stdout. Only when using pipes. - "err_timeout" Timeout for stderr. Only when using pipes. - Note: when setting "timeout" the part specific mode is - overwritten. Therefore set "timeout" first and the part - specific mode later. When "mode" is "json" or "js" the "callback" is optional. When omitted it is only possible to receive a message after sending one. --- 165,174 ---- actually uses a 1 msec timeout, that is required on many systems. Use a larger value for a remote server, e.g. 10 msec at least. ! *channel-timeout* "timeout" The time to wait for a request when blocking, E.g. when using ch_evalexpr(). In milliseconds. The default is 2000 (2 seconds). When "mode" is "json" or "js" the "callback" is optional. When omitted it is only possible to receive a message after sending one. *************** *** 212,224 **** what you want! Stopping the job with job_stop() might be better. All readahead is discarded, callbacks will no longer be invoked. When the channel can't be opened you will get an error message. There is a difference between MS-Windows and Unix: On Unix when the port doesn't exist ch_open() fails quickly. On MS-Windows "waittime" applies. ! *E898* *E899* *E900* *E901* *E902* If there is an error reading or writing a channel it will be closed. ! *E896* *E630* *E631* ============================================================================== 4. Using a JSON or JS channel *channel-use* --- 196,215 ---- what you want! Stopping the job with job_stop() might be better. All readahead is discarded, callbacks will no longer be invoked. + Note that a channel is closed in three stages: + - The I/O ends, log message: "Closing channel". There can still be queued + messages to read or callbacks to invoke. + - The readahead is cleared, log message: "Clearing channel". Some variables + may still reference the channel. + - The channel is freed, log message: "Freeing channel". + When the channel can't be opened you will get an error message. There is a difference between MS-Windows and Unix: On Unix when the port doesn't exist ch_open() fails quickly. On MS-Windows "waittime" applies. ! *E898* *E901* *E902* If there is an error reading or writing a channel it will be closed. ! *E630* *E631* ============================================================================== 4. Using a JSON or JS channel *channel-use* *************** *** 275,284 **** Then channel handler will then get {response} converted to Vim types. If the channel does not have a handler the message is dropped. - On read error or ch_close(), when using a socket with RAW or NL mode, the - string "DETACH\n" is sent, if still possible. The channel will then be - inactive. - It is also possible to use ch_sendraw() and ch_evalraw() on a JSON or JS channel. The caller is then completely responsible for correct encoding and decoding. --- 266,271 ---- *************** *** 329,334 **** --- 316,324 ---- You can also use "call |feedkeys()|" to insert any key sequence. + When there is an error a message is written to the channel log, if it exists, + and v:errmsg is set to the error. + Command "normal" ~ *************** *** 407,412 **** --- 397,405 ---- It is not possible to use |ch_evalexpr()| or |ch_sendexpr()| on a raw channel. + A String in Vim cannot contain NUL bytes. To send or receive NUL bytes read + or write from a buffer. See |in_io-buffer| and |out_io-buffer|. + ============================================================================== 7. More channel functions *channel-more* *************** *** 414,419 **** --- 407,413 ---- are: "fail" Failed to open the channel. "open" The channel can be used. + "buffered" The channel was closed but there is data to read. "closed" The channel was closed. To obtain the job associated with a channel: ch_getjob(channel) *************** *** 431,436 **** --- 425,447 ---- To read the error output: > let output = ch_readraw(channel, {"part": "err"}) + ch_read() and ch_readraw() use the channel timeout. When there is nothing to + read within that time an empty string is returned. To specify a different + timeout in msec use the "timeout" option: + {"timeout": 123} ~ + To read from the error output use the "part" option: + {"part": "err"} ~ + To read a message with a specific ID, on a JS or JSON channel: + {"id": 99} ~ + When no ID is specified or the ID is -1, the first message is returned. This + overrules any callback waiting for this message. + + For a RAW channel this returns whatever is available, since Vim does not know + where a message ends. + For a NL channel this returns one message. + For a JS or JSON channel this returns one decoded message. + This includes any sequence number. + ============================================================================== 8. Starting a job with a channel *job-start* *job* *************** *** 452,458 **** func MyHandler(channel, msg) Without the handler you need to read the output with |ch_read()| or ! |ch_readraw()|. The handler defined for "out_cb" will not receive stderr. If you want to handle that separately, add an "err_cb" handler: > --- 463,469 ---- func MyHandler(channel, msg) Without the handler you need to read the output with |ch_read()| or ! |ch_readraw()|. You can do this in the close callback, see |read-in-close-cb|. The handler defined for "out_cb" will not receive stderr. If you want to handle that separately, add an "err_cb" handler: > *************** *** 474,480 **** Job input from a buffer ~ ! To run a job that reads from a buffer: > let job = job_start({command}, \ {'in_io': 'buffer', 'in_name': 'mybuffer'}) --- 485,491 ---- Job input from a buffer ~ ! *in_io-buffer* To run a job that reads from a buffer: > let job = job_start({command}, \ {'in_io': 'buffer', 'in_name': 'mybuffer'}) *************** *** 549,572 **** related to the job, using ch_setoptions(channel, {options}). See |job_setoptions()| and |ch_setoptions()|. *job-callback* "callback": handler Callback for something to read on any part of the channel. ! *job-out_cb* "out_cb": handler Callback for when there is something to read on ! stdout. ! *job-err_cb* "err_cb": handler Callback for when there is something to read on ! stderr. *job-close_cb* "close_cb": handler Callback for when the channel is closed. Same as ! "close_cb" on ch_open(). *job-exit_cb* "exit_cb": handler Callback for when the job ends. The arguments are the job and the exit status. Vim checks about every 10 seconds for jobs that ended. ! The callback can also be triggered by calling ! |job_status()|. *job-stoponexit* "stoponexit": {signal} Send {signal} to the job when Vim exits. See |job_stop()| for possible values. --- 560,614 ---- related to the job, using ch_setoptions(channel, {options}). See |job_setoptions()| and |ch_setoptions()|. + *in_mode* *out_mode* *err_mode* + "in_mode" mode specifically for stdin, only when using pipes + "out_mode" mode specifically for stdout, only when using pipes + "err_mode" mode specifically for stderr, only when using pipes + See |channel-mode| for the values. + + Note: when setting "mode" the part specific mode is + overwritten. Therefore set "mode" first and the part + specific mode later. + + Note: when writing to a file or buffer and when + reading from a buffer NL mode is used by default. + *job-callback* "callback": handler Callback for something to read on any part of the channel. ! *job-out_cb* *out_cb* "out_cb": handler Callback for when there is something to read on ! stdout. Only for when the channel uses pipes. When ! "out_cb" wasn't set the channel callback is used. ! The two arguments are the channel and the message. ! ! *job-err_cb* *err_cb* "err_cb": handler Callback for when there is something to read on ! stderr. Only for when the channel uses pipes. When ! "err_cb" wasn't set the channel callback is used. ! The two arguments are the channel and the message. *job-close_cb* "close_cb": handler Callback for when the channel is closed. Same as ! "close_cb" on |ch_open()|, see |close_cb|. *job-exit_cb* "exit_cb": handler Callback for when the job ends. The arguments are the job and the exit status. Vim checks about every 10 seconds for jobs that ended. ! The check also be triggered by calling |job_status()|, ! which may then invoke the exit_cb handler. ! Note that data can be buffered, callbacks may still be ! called after the process ends. ! *job-timeout* ! "timeout" The time to wait for a request when blocking, E.g. ! when using ch_evalexpr(). In milliseconds. The ! default is 2000 (2 seconds). ! *out_timeout* *err_timeout* ! "out_timeout" Timeout for stdout. Only when using pipes. ! "err_timeout" Timeout for stderr. Only when using pipes. ! Note: when setting "timeout" the part specific mode is ! overwritten. Therefore set "timeout" first and the ! part specific mode later. ! *job-stoponexit* "stoponexit": {signal} Send {signal} to the job when Vim exits. See |job_stop()| for possible values. *************** *** 604,609 **** --- 646,653 ---- "out_buf": number the number of the buffer to write to "out_modifiable": 0 when writing to a buffer, 'modifiable' will be off (see below) + "out_msg": 0 when writing to a new buffer, the first line will be + set to "Reading from channel output..." *job-err_io* *err_name* *err_buf* "err_io": "out" stderr messages to go to stdout *************** *** 615,627 **** "err_buf": number the number of the buffer to write to "err_modifiable": 0 when writing to a buffer, 'modifiable' will be off (see below) "block_write": number only for testing: pretend every other write to stdin will block Writing to a buffer ~ ! When the out_io or err_io mode is "buffer" and there is a callback, the text is appended to the buffer before invoking the callback. --- 659,673 ---- "err_buf": number the number of the buffer to write to "err_modifiable": 0 when writing to a buffer, 'modifiable' will be off (see below) + "err_msg": 0 when writing to a new buffer, the first line will be + set to "Reading from channel error..." "block_write": number only for testing: pretend every other write to stdin will block Writing to a buffer ~ ! *out_io-buffer* When the out_io or err_io mode is "buffer" and there is a callback, the text is appended to the buffer before invoking the callback. *************** *** 633,650 **** ID will be added to the buffer, after decoding + encoding. Messages with a positive number will be handled by a callback, commands are handled as usual. ! The name of the buffer is compared the full name of existing buffers. If ! there is a match that buffer is used. Otherwise a new buffer is created. ! Use an empty name to always create a new buffer. |ch_getbufnr()| can then be ! used to get the buffer number. For a new buffer 'buftype' is set to "nofile" and 'bufhidden' to "hide". If you prefer other settings, create the buffer first and pass the buffer number. ! The "out_modifiable" and "err_modifiable" options can be used to set the 'modifiable' option off, or write to a buffer that has 'modifiable' off. That means that lines will be appended to the buffer, but the user can't easily change the buffer. When an existing buffer is to be written where 'modifiable' is off and the "out_modifiable" or "err_modifiable" options is not zero, an error is given --- 679,708 ---- ID will be added to the buffer, after decoding + encoding. Messages with a positive number will be handled by a callback, commands are handled as usual. ! The name of the buffer from "out_name" or "err_name" is compared the full name ! of existing buffers, also after expanding the name for the current directory. ! E.g., when a buffer was created with ":edit somename" and the buffer name is ! "somename" it will use that buffer. ! ! If there is no matching buffer a new buffer is created. Use an empty name to ! always create a new buffer. |ch_getbufnr()| can then be used to get the ! buffer number. For a new buffer 'buftype' is set to "nofile" and 'bufhidden' to "hide". If you prefer other settings, create the buffer first and pass the buffer number. ! *out_modifiable* *err_modifiable* The "out_modifiable" and "err_modifiable" options can be used to set the 'modifiable' option off, or write to a buffer that has 'modifiable' off. That means that lines will be appended to the buffer, but the user can't easily change the buffer. + *out_msg* *err_msg* + The "out_msg" option can be used to specify whether a new buffer will have the + first line set to "Reading from channel output...". The default is to add the + message. "err_msg" does the same for channel error. + + 'modifiable' option off, or write to a buffer that has 'modifiable' off. That + means that lines will be appended to the buffer, but the user can't easily + change the buffer. When an existing buffer is to be written where 'modifiable' is off and the "out_modifiable" or "err_modifiable" options is not zero, an error is given *************** *** 654,660 **** first column of the last line, the cursor will be moved to the newly added line and the window is scrolled up to show the cursor if needed. ! Undo is synced for every added line. Writing to a file ~ --- 712,719 ---- first column of the last line, the cursor will be moved to the newly added line and the window is scrolled up to show the cursor if needed. ! Undo is synced for every added line. NUL bytes are accepted (internally Vim ! stores these as NL bytes). Writing to a file ~ *** ../vim-7.4.2343/src/version.c 2016-09-07 20:46:13.769431891 +0200 --- src/version.c 2016-09-07 23:25:02.919334450 +0200 *************** *** 765,766 **** --- 765,768 ---- { /* Add new patch number below this line */ + /**/ + 2344, /**/ -- Some of the well known MS-Windows errors: EMEMORY Memory error caused by..., eh... ELICENSE Your license has expired, give us more money! EMOUSE Mouse moved, reinstall Windows EILLEGAL Illegal error, you are not allowed to see this EVIRUS Undetectable virus found /// 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 ///