From be82c254862e475a582c0717455e1db6bf96b0d0 Mon Sep 17 00:00:00 2001 From: Bram Moolenaar Date: Sun, 6 Mar 2016 14:44:08 +0100 Subject: [PATCH 01/13] patch 7.4.1499 Problem: No error message when :packadd does not find anything. Solution: Add an error message. (Hirohito Higashi) --- runtime/doc/repeat.txt | 2 +- src/ex_cmds.h | 2 +- src/ex_cmds2.c | 37 ++++++++++++++++++++++++++---------- src/globals.h | 1 + src/testdir/test_packadd.vim | 4 ++++ src/version.c | 2 ++ 6 files changed, 36 insertions(+), 12 deletions(-) diff --git a/runtime/doc/repeat.txt b/runtime/doc/repeat.txt index d5d78638ae..1b9e54fcb3 100644 --- a/runtime/doc/repeat.txt +++ b/runtime/doc/repeat.txt @@ -213,7 +213,7 @@ For writing a Vim script, see chapter 41 of the user manual |usr_41.txt|. about each searched file. {not in Vi} - *:pa* *:packadd* + *:pa* *:packadd* *E919* :pa[ckadd][!] {name} Search for an optional plugin directory in 'packpath' and source any plugin files found. The directory must match: diff --git a/src/ex_cmds.h b/src/ex_cmds.h index 24f83aade4..c25ee2ee65 100644 --- a/src/ex_cmds.h +++ b/src/ex_cmds.h @@ -1012,7 +1012,7 @@ EX(CMD_print, "print", ex_print, RANGE|WHOLEFOLD|COUNT|EXFLAGS|TRLBAR|CMDWIN|SBOXOK, ADDR_LINES), EX(CMD_packadd, "packadd", ex_packadd, - BANG|FILE1|TRLBAR|SBOXOK|CMDWIN, + BANG|FILE1|NEEDARG|TRLBAR|SBOXOK|CMDWIN, ADDR_LINES), EX(CMD_pclose, "pclose", ex_pclose, BANG|TRLBAR, diff --git a/src/ex_cmds2.c b/src/ex_cmds2.c index b6992b2bb9..7a0d0bd94b 100644 --- a/src/ex_cmds2.c +++ b/src/ex_cmds2.c @@ -2918,8 +2918,7 @@ source_callback(char_u *fname, void *cookie UNUSED) /* * Source the file "name" from all directories in 'runtimepath'. * "name" can contain wildcards. - * When "flags" has DIP_ALL: source all files, otherwise only the first one. - * When "flags" has DIP_DIR: find directories instead of files. + * When "all" is TRUE: source all files, otherwise only the first one. * * return FAIL when no file could be sourced, OK otherwise. */ @@ -2931,7 +2930,18 @@ source_runtime(char_u *name, int all) #define DIP_ALL 1 /* all matches, not just the first one */ #define DIP_DIR 2 /* find directories instead of files. */ +#define DIP_ERR 4 /* give an error message when none found. */ +/* + * Find the file "name" in all directories in "path" and invoke + * "callback(fname, cookie)". + * "name" can contain wildcards. + * When "flags" has DIP_ALL: source all files, otherwise only the first one. + * When "flags" has DIP_DIR: find directories instead of files. + * When "flags" has DIP_ERR: give an error message if there is no match. + * + * return FAIL when no file could be sourced, OK otherwise. + */ static int do_in_path( char_u *path, @@ -3022,11 +3032,18 @@ do_in_path( } vim_free(buf); vim_free(rtp_copy); - if (p_verbose > 0 && !did_one && name != NULL) + if (!did_one && name != NULL) { - verbose_enter(); - smsg((char_u *)_("not found in 'runtimepath': \"%s\""), name); - verbose_leave(); + char *basepath = path == p_rtp ? "runtimepath" : "packpath"; + + if (flags & DIP_ERR) + EMSG3(_(e_dirnotf), basepath, name); + else if (p_verbose > 0) + { + verbose_enter(); + smsg((char_u *)_("not found in '%s': \"%s\""), basepath, name); + verbose_leave(); + } } #ifdef AMIGA @@ -3178,8 +3195,8 @@ theend: void source_packages() { - do_in_path(p_pp, (char_u *)"pack/*/ever/*", - DIP_ALL + DIP_DIR, add_pack_plugin, p_pp); + do_in_path(p_pp, (char_u *)"pack/*/ever/*", DIP_ALL + DIP_DIR, + add_pack_plugin, p_pp); } /* @@ -3197,8 +3214,8 @@ ex_packadd(exarg_T *eap) if (pat == NULL) return; vim_snprintf(pat, len, plugpat, eap->arg); - do_in_path(p_pp, (char_u *)pat, DIP_ALL + DIP_DIR, add_pack_plugin, - eap->forceit ? NULL : p_pp); + do_in_path(p_pp, (char_u *)pat, DIP_ALL + DIP_DIR + DIP_ERR, + add_pack_plugin, eap->forceit ? NULL : p_pp); vim_free(pat); } diff --git a/src/globals.h b/src/globals.h index 6fd86fba56..bd9ef5c877 100644 --- a/src/globals.h +++ b/src/globals.h @@ -1577,6 +1577,7 @@ EXTERN char_u e_notset[] INIT(= N_("E764: Option '%s' is not set")); #ifndef FEAT_CLIPBOARD EXTERN char_u e_invalidreg[] INIT(= N_("E850: Invalid register name")); #endif +EXTERN char_u e_dirnotf[] INIT(= N_("E919: Directory not found in '%s': \"%s\"")); #ifdef MACOS_X_UNIX EXTERN short disallow_gui INIT(= FALSE); diff --git a/src/testdir/test_packadd.vim b/src/testdir/test_packadd.vim index 091fec24b2..a0a270149b 100644 --- a/src/testdir/test_packadd.vim +++ b/src/testdir/test_packadd.vim @@ -31,6 +31,10 @@ func Test_packadd() call assert_equal(17, g:ftdetect_works) call assert_true(len(&rtp) > len(rtp)) call assert_true(&rtp =~ 'testdir/Xdir/pack/mine/opt/mytest\($\|,\)') + + " Check exception + call assert_fails("packadd directorynotfound", 'E919:') + call assert_fails("packadd", 'E471:') endfunc func Test_packadd_noload() diff --git a/src/version.c b/src/version.c index 1bcccd8646..6ce39932ad 100644 --- a/src/version.c +++ b/src/version.c @@ -743,6 +743,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ +/**/ + 1499, /**/ 1498, /**/ From 9ef00be261115acb5bae3b3ca45c1d86a19ba2c7 Mon Sep 17 00:00:00 2001 From: Bram Moolenaar Date: Sun, 6 Mar 2016 14:58:28 +0100 Subject: [PATCH 02/13] patch 7.4.1500 Problem: Should_free flag set to FALSE. Solution: Set it to TRUE. (Neovim 4415) --- src/ex_eval.c | 4 ++-- src/version.c | 2 ++ 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/ex_eval.c b/src/ex_eval.c index c68c6ad189..3fd470c10b 100644 --- a/src/ex_eval.c +++ b/src/ex_eval.c @@ -432,7 +432,7 @@ get_exception_string( if (type == ET_ERROR) { - *should_free = FALSE; + *should_free = TRUE; mesg = ((struct msglist *)value)->throw_msg; if (cmdname != NULL && *cmdname != NUL) { @@ -489,7 +489,7 @@ get_exception_string( else { *should_free = FALSE; - ret = (char_u *) value; + ret = (char_u *)value; } return ret; diff --git a/src/version.c b/src/version.c index 6ce39932ad..106fa20819 100644 --- a/src/version.c +++ b/src/version.c @@ -743,6 +743,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ +/**/ + 1500, /**/ 1499, /**/ From 38fd4bb2842df7634823b99c655b3896a7a2e988 Mon Sep 17 00:00:00 2001 From: Bram Moolenaar Date: Sun, 6 Mar 2016 16:38:28 +0100 Subject: [PATCH 03/13] patch 7.4.1501 Problem: Garbage collection with an option channel is not tested. Solution: Call garbagecollect() in the test. --- src/testdir/test_channel.vim | 3 +++ src/version.c | 2 ++ 2 files changed, 5 insertions(+) diff --git a/src/testdir/test_channel.vim b/src/testdir/test_channel.vim index 3bdfd4cbf8..31a4ff6eb2 100644 --- a/src/testdir/test_channel.vim +++ b/src/testdir/test_channel.vim @@ -146,6 +146,9 @@ func s:communicate(port) endif call assert_equal('got it', s:responseMsg) + " Collect garbage, tests that our handle isn't collected. + call garbagecollect() + " check setting options (without testing the effect) call ch_setoptions(handle, {'callback': 's:NotUsed'}) call ch_setoptions(handle, {'timeout': 1111}) diff --git a/src/version.c b/src/version.c index 106fa20819..0e51caa34a 100644 --- a/src/version.c +++ b/src/version.c @@ -743,6 +743,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ +/**/ + 1501, /**/ 1500, /**/ From 99ef06296f3c37490511c03786a2c8672e015c56 Mon Sep 17 00:00:00 2001 From: Bram Moolenaar Date: Sun, 6 Mar 2016 20:22:25 +0100 Subject: [PATCH 04/13] patch 7.4.1502 Problem: Writing last-but-one line of buffer to a channel isn't implemented yet. Solution: Implement it. Fix leaving a swap file behind. --- src/channel.c | 215 ++++++++++++++++++++++++++++++------------ src/memline.c | 5 + src/proto/channel.pro | 1 + src/structs.h | 4 + src/version.c | 2 + 5 files changed, 168 insertions(+), 59 deletions(-) diff --git a/src/channel.c b/src/channel.c index 6ede9160df..f0207bc258 100644 --- a/src/channel.c +++ b/src/channel.c @@ -837,7 +837,18 @@ channel_set_job(channel_T *channel, job_T *job, jobopt_T *options) ch_logs(channel, "reading from buffer '%s'", (char *)in_part->ch_buffer->b_ffname); if (options->jo_set & JO_IN_TOP) - in_part->ch_buf_top = options->jo_in_top; + { + if (options->jo_in_top == 0 && !(options->jo_set & JO_IN_BOT)) + { + /* Special mode: send last-but-one line when appending a line + * to the buffer. */ + in_part->ch_buffer->b_write_to_channel = TRUE; + in_part->ch_buf_top = + in_part->ch_buffer->b_ml.ml_line_count + 1; + } + else + in_part->ch_buf_top = options->jo_in_top; + } else in_part->ch_buf_top = 1; if (options->jo_set & JO_IN_BOT) @@ -864,13 +875,12 @@ find_buffer(char_u *name) NULL, (linenr_T)0, BLN_LISTED); buf_copy_options(buf, BCO_ENTER); #ifdef FEAT_QUICKFIX - clear_string_option(&buf->b_p_bt); - buf->b_p_bt = vim_strsave((char_u *)"nofile"); - clear_string_option(&buf->b_p_bh); - buf->b_p_bh = vim_strsave((char_u *)"hide"); + set_option_value((char_u *)"bt", 0L, (char_u *)"nofile", OPT_LOCAL); + set_option_value((char_u *)"bh", 0L, (char_u *)"hide", OPT_LOCAL); #endif curbuf = buf; - ml_open(curbuf); + if (curbuf->b_ml.ml_mfp == NULL) + ml_open(curbuf); ml_replace(1, (char_u *)"Reading from channel output...", TRUE); changed_bytes(1, 0); curbuf = save_curbuf; @@ -982,8 +992,25 @@ channel_set_req_callback( } } + static void +write_buf_line(buf_T *buf, linenr_T lnum, channel_T *channel) +{ + char_u *line = ml_get_buf(buf, lnum, FALSE); + int len = STRLEN(line); + char_u *p; + + /* TODO: check if channel can be written to, do not block on write */ + if ((p = alloc(len + 2)) == NULL) + return; + STRCPY(p, line); + p[len] = NL; + p[len + 1] = NUL; + channel_send(channel, PART_IN, p, "write_buf_line()"); + vim_free(p); +} + /* - * Write any lines to the in channel. + * Write any lines to the input channel. */ void channel_write_in(channel_T *channel) @@ -991,6 +1018,7 @@ channel_write_in(channel_T *channel) chanpart_T *in_part = &channel->ch_part[PART_IN]; linenr_T lnum; buf_T *buf = in_part->ch_buffer; + int written = 0; if (buf == NULL) return; @@ -1007,22 +1035,60 @@ channel_write_in(channel_T *channel) for (lnum = in_part->ch_buf_top; lnum <= in_part->ch_buf_bot && lnum <= buf->b_ml.ml_line_count; ++lnum) { - char_u *line = ml_get_buf(buf, lnum, FALSE); - int len = STRLEN(line); - char_u *p; - - /* TODO: check if channel can be written to */ - if ((p = alloc(len + 2)) == NULL) - break; - STRCPY(p, line); - p[len] = NL; - p[len + 1] = NUL; - channel_send(channel, PART_IN, p, "channel_write_in()"); - vim_free(p); + write_buf_line(buf, lnum, channel); + ++written; } + + if (written == 1) + ch_logn(channel, "written line %d to channel", (int)lnum - 1); + else if (written > 1) + ch_logn(channel, "written %d lines to channel", written); + in_part->ch_buf_top = lnum; } +/* + * Write appended lines above the last one in "buf" to the channel. + */ + void +channel_write_new_lines(buf_T *buf) +{ + channel_T *channel; + int found_one = FALSE; + + /* There could be more than one channel for the buffer, loop over all of + * them. */ + for (channel = first_channel; channel != NULL; channel = channel->ch_next) + { + chanpart_T *in_part = &channel->ch_part[PART_IN]; + linenr_T lnum; + int written = 0; + + if (in_part->ch_buffer == buf) + { + if (in_part->ch_fd == INVALID_FD) + /* pipe was closed */ + continue; + found_one = TRUE; + for (lnum = in_part->ch_buf_bot; lnum < buf->b_ml.ml_line_count; + ++lnum) + { + write_buf_line(buf, lnum, channel); + ++written; + } + + if (written == 1) + ch_logn(channel, "written line %d to channel", (int)lnum - 1); + else if (written > 1) + ch_logn(channel, "written %d lines to channel", written); + + in_part->ch_buf_bot = lnum; + } + } + if (!found_one) + buf->b_write_to_channel = FALSE; +} + /* * Invoke the "callback" on channel "channel". */ @@ -1470,6 +1536,76 @@ invoke_one_time_callback( vim_free(item); } + static void +append_to_buffer(buf_T *buffer, char_u *msg, channel_T *channel) +{ + buf_T *save_curbuf = curbuf; + linenr_T lnum = buffer->b_ml.ml_line_count; + int save_write_to = buffer->b_write_to_channel; + + /* If the buffer is also used as input insert above the last + * line. Don't write these lines. */ + if (save_write_to) + { + --lnum; + buffer->b_write_to_channel = FALSE; + } + + /* Append to the buffer */ + ch_logn(channel, "appending line %d to buffer", (int)lnum + 1); + + 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 (buffer->b_nwindows > 0) + { + win_T *wp; + win_T *save_curwin; + + FOR_ALL_WINDOWS(wp) + { + if (wp->w_buffer == buffer + && (save_write_to + ? wp->w_cursor.lnum == lnum + 1 + : (wp->w_cursor.lnum == lnum + && wp->w_cursor.col == 0))) + { + ++wp->w_cursor.lnum; + save_curwin = curwin; + curwin = wp; + curbuf = curwin->w_buffer; + scroll_cursor_bot(0, FALSE); + curwin = save_curwin; + curbuf = curwin->w_buffer; + } + } + redraw_buf_later(buffer, VALID); + channel_need_redraw = TRUE; + } + + if (save_write_to) + { + channel_T *ch; + + /* Find channels reading from this buffer and adjust their + * next-to-read line number. */ + buffer->b_write_to_channel = TRUE; + for (ch = first_channel; ch != NULL; ch = ch->ch_next) + { + chanpart_T *in_part = &ch->ch_part[PART_IN]; + + if (in_part->ch_buffer == buffer) + in_part->ch_buf_bot = buffer->b_ml.ml_line_count; + } + } +} + /* * Invoke a callback for "channel"/"part" if needed. * Return TRUE when a message was handled, there might be another one. @@ -1634,46 +1770,7 @@ may_invoke_callback(channel_T *channel, int part) /* JSON or JS mode: re-encode the message. */ msg = json_encode(listtv, ch_mode); if (msg != NULL) - { - buf_T *save_curbuf = curbuf; - linenr_T lnum = buffer->b_ml.ml_line_count; - - /* Append to the buffer */ - ch_logn(channel, "appending line %d to buffer", (int)lnum + 1); - - 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 (buffer->b_nwindows > 0) - { - win_T *wp; - win_T *save_curwin; - - FOR_ALL_WINDOWS(wp) - { - if (wp->w_buffer == buffer - && wp->w_cursor.lnum == lnum - && wp->w_cursor.col == 0) - { - ++wp->w_cursor.lnum; - save_curwin = curwin; - curwin = wp; - curbuf = curwin->w_buffer; - scroll_cursor_bot(0, FALSE); - curwin = save_curwin; - curbuf = curwin->w_buffer; - } - } - redraw_buf_later(buffer, VALID); - channel_need_redraw = TRUE; - } - } + append_to_buffer(buffer, msg, channel); } if (callback != NULL) diff --git a/src/memline.c b/src/memline.c index 17062823b3..334392b36d 100644 --- a/src/memline.c +++ b/src/memline.c @@ -3059,6 +3059,11 @@ ml_append_int( (char_u *)"\n", 1); } #endif +#ifdef FEAT_CHANNEL + if (buf->b_write_to_channel) + channel_write_new_lines(buf); +#endif + return OK; } diff --git a/src/proto/channel.pro b/src/proto/channel.pro index 7e9d3a82e6..18dceb521a 100644 --- a/src/proto/channel.pro +++ b/src/proto/channel.pro @@ -14,6 +14,7 @@ void channel_set_job(channel_T *channel, job_T *job, jobopt_T *options); void channel_set_options(channel_T *channel, jobopt_T *opt); void channel_set_req_callback(channel_T *channel, int part, char_u *callback, int id); void channel_write_in(channel_T *channel); +void channel_write_new_lines(buf_T *buf); char_u *channel_get(channel_T *channel, int part); int channel_collapse(channel_T *channel, int part); int channel_can_write_to(channel_T *channel); diff --git a/src/structs.h b/src/structs.h index 42ca96c283..d70c024db9 100644 --- a/src/structs.h +++ b/src/structs.h @@ -2051,6 +2051,10 @@ struct file_buffer int b_netbeans_file; /* TRUE when buffer is owned by NetBeans */ int b_was_netbeans_file;/* TRUE if b_netbeans_file was once set */ #endif +#ifdef FEAT_CHANNEL + int b_write_to_channel; /* TRUE when appended lines are written to + * a channel. */ +#endif #ifdef FEAT_CRYPT cryptstate_T *b_cryptstate; /* Encryption state while reading or writing diff --git a/src/version.c b/src/version.c index 0e51caa34a..4d8c525005 100644 --- a/src/version.c +++ b/src/version.c @@ -743,6 +743,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ +/**/ + 1502, /**/ 1501, /**/ From 839fd11d7ed1a96bace3159c4d1861658864aae3 Mon Sep 17 00:00:00 2001 From: Bram Moolenaar Date: Sun, 6 Mar 2016 21:34:03 +0100 Subject: [PATCH 05/13] patch 7.4.1503 Problem: Crash when using ch_getjob(). (Damien) Solution: Check for a NULL job. --- src/eval.c | 7 ++++++- src/testdir/test_channel.vim | 4 ++++ src/version.c | 2 ++ 3 files changed, 12 insertions(+), 1 deletion(-) diff --git a/src/eval.c b/src/eval.c index 23154061c4..510dd128da 100644 --- a/src/eval.c +++ b/src/eval.c @@ -15249,6 +15249,7 @@ f_job_start(typval_T *argvars UNUSED, typval_T *rettv) #endif #ifdef FEAT_CHANNEL + /* If the channel is reading from a buffer, write lines now. */ channel_write_in(job->jv_channel); #endif @@ -22601,7 +22602,11 @@ get_tv_string_buf_chk(typval_T *varp, char_u *buf) #ifdef FEAT_JOB { job_T *job = varp->vval.v_job; - char *status = job->jv_status == JOB_FAILED ? "fail" + char *status; + + if (job == NULL) + return (char_u *)"no process"; + status = job->jv_status == JOB_FAILED ? "fail" : job->jv_status == JOB_ENDED ? "dead" : "run"; # ifdef UNIX diff --git a/src/testdir/test_channel.vim b/src/testdir/test_channel.vim index 31a4ff6eb2..5133a24965 100644 --- a/src/testdir/test_channel.vim +++ b/src/testdir/test_channel.vim @@ -108,6 +108,10 @@ func s:communicate(port) call assert_false(1, "Can't open channel") return endif + if has('job') + " check that no job is handled correctly + call assert_equal('no process', string(ch_getjob(handle))) + endif " Simple string request and reply. call assert_equal('got it', ch_evalexpr(handle, 'hello!')) diff --git a/src/version.c b/src/version.c index 4d8c525005..92fb02a7dd 100644 --- a/src/version.c +++ b/src/version.c @@ -743,6 +743,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ +/**/ + 1503, /**/ 1502, /**/ From 3f39f648662bf8723f687d14694041779ed0780c Mon Sep 17 00:00:00 2001 From: Bram Moolenaar Date: Sun, 6 Mar 2016 21:35:57 +0100 Subject: [PATCH 06/13] patch 7.4.1504 Problem: No test for reading last-but-one line. Solution: Add a test. --- src/testdir/test_channel.vim | 77 ++++++++++++++++++++++++++++++++++++ src/version.c | 2 + 2 files changed, 79 insertions(+) diff --git a/src/testdir/test_channel.vim b/src/testdir/test_channel.vim index 5133a24965..5321cce23f 100644 --- a/src/testdir/test_channel.vim +++ b/src/testdir/test_channel.vim @@ -629,6 +629,83 @@ func Test_pipe_to_buffer_json() endtry endfunc +" Wait a little while for the last line, minus "offset", to equal "line". +func Wait_for_last_line(line, offset) + for i in range(100) + sleep 10m + if getline(line('$') - a:offset) == a:line + break + endif + endfor +endfunc + +func Test_pipe_io_two_buffers() + if !has('job') + return + endif + call ch_log('Test_pipe_io_two_buffers()') + + " Create two buffers, one to read from and one to write to. + split pipe-output + set buftype=nofile + split pipe-input + set buftype=nofile + + let job = job_start(s:python . " test_channel_pipe.py", + \ {'in-io': 'buffer', 'in-name': 'pipe-input', 'in-top': 0, + \ 'out-io': 'buffer', 'out-name': 'pipe-output'}) + call assert_equal("run", job_status(job)) + try + exe "normal Gaecho hello\" + exe bufwinnr('pipe-output') . "wincmd w" + call Wait_for_last_line('hello', 0) + call assert_equal('hello', getline('$')) + + exe bufwinnr('pipe-input') . "wincmd w" + exe "normal Gadouble this\" + exe bufwinnr('pipe-output') . "wincmd w" + call Wait_for_last_line('AND this', 0) + call assert_equal('this', getline(line('$') - 1)) + call assert_equal('AND this', getline('$')) + + bwipe! + exe bufwinnr('pipe-input') . "wincmd w" + bwipe! + finally + call job_stop(job) + endtry +endfunc + +func Test_pipe_io_one_buffer() + if !has('job') + return + endif + call ch_log('Test_pipe_io_one_buffer()') + + " Create one buffer to read from and to write to. + split pipe-io + set buftype=nofile + + let job = job_start(s:python . " test_channel_pipe.py", + \ {'in-io': 'buffer', 'in-name': 'pipe-io', 'in-top': 0, + \ 'out-io': 'buffer', 'out-name': 'pipe-io'}) + call assert_equal("run", job_status(job)) + try + exe "normal Goecho hello\" + call Wait_for_last_line('hello', 1) + call assert_equal('hello', getline(line('$') - 1)) + + exe "normal Gadouble this\" + call Wait_for_last_line('AND this', 1) + call assert_equal('this', getline(line('$') - 2)) + call assert_equal('AND this', getline(line('$') - 1)) + + bwipe! + finally + call job_stop(job) + endtry +endfunc + """""""""" let s:unletResponse = '' diff --git a/src/version.c b/src/version.c index 92fb02a7dd..1ba0ab0b98 100644 --- a/src/version.c +++ b/src/version.c @@ -743,6 +743,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ +/**/ + 1504, /**/ 1503, /**/ From d0b6502a7ace39d6cd30874110a572371d10beae Mon Sep 17 00:00:00 2001 From: Bram Moolenaar Date: Sun, 6 Mar 2016 21:50:33 +0100 Subject: [PATCH 07/13] patch 7.4.1505 Problem: When channel log is enabled get too many "looking for messages" log entries. Solution: Only give the message after another message. --- src/channel.c | 18 +++++++++++++++++- src/version.c | 2 ++ 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/src/channel.c b/src/channel.c index f0207bc258..e7c25ac3fa 100644 --- a/src/channel.c +++ b/src/channel.c @@ -136,6 +136,8 @@ ch_log_lead(char *what, channel_T *ch) } } +static int did_log_msg = TRUE; + void ch_log(channel_T *ch, char *msg) { @@ -145,6 +147,7 @@ ch_log(channel_T *ch, char *msg) fputs(msg, log_fd); fputc('\n', log_fd); fflush(log_fd); + did_log_msg = TRUE; } } @@ -157,6 +160,7 @@ ch_logn(channel_T *ch, char *msg, int nr) fprintf(log_fd, msg, nr); fputc('\n', log_fd); fflush(log_fd); + did_log_msg = TRUE; } } @@ -169,6 +173,7 @@ ch_logs(channel_T *ch, char *msg, char *name) fprintf(log_fd, msg, name); fputc('\n', log_fd); fflush(log_fd); + did_log_msg = TRUE; } } @@ -181,6 +186,7 @@ ch_logsn(channel_T *ch, char *msg, char *name, int nr) fprintf(log_fd, msg, name, nr); fputc('\n', log_fd); fflush(log_fd); + did_log_msg = TRUE; } } @@ -193,6 +199,7 @@ ch_error(channel_T *ch, char *msg) fputs(msg, log_fd); fputc('\n', log_fd); fflush(log_fd); + did_log_msg = TRUE; } } @@ -205,6 +212,7 @@ ch_errorn(channel_T *ch, char *msg, int nr) fprintf(log_fd, msg, nr); fputc('\n', log_fd); fflush(log_fd); + did_log_msg = TRUE; } } @@ -217,6 +225,7 @@ ch_errors(channel_T *ch, char *msg, char *arg) fprintf(log_fd, msg, arg); fputc('\n', log_fd); fflush(log_fd); + did_log_msg = TRUE; } } @@ -2352,6 +2361,7 @@ channel_send(channel_T *channel, int part, char_u *buf, char *fun) ignored = (int)fwrite(buf, len, 1, log_fd); fprintf(log_fd, "'\n"); fflush(log_fd); + did_log_msg = TRUE; } if (part == PART_SOCK) @@ -2541,7 +2551,13 @@ channel_parse_messages(void) int r; int part = PART_SOCK; - ch_log(NULL, "looking for messages on channels"); + /* Only do this message when another message was given, otherwise we get + * lots of them. */ + if (did_log_msg) + { + ch_log(NULL, "looking for messages on channels"); + did_log_msg = FALSE; + } while (channel != NULL) { if (channel->ch_refcount == 0 && !channel_still_useful(channel)) diff --git a/src/version.c b/src/version.c index 1ba0ab0b98..9c94df8b37 100644 --- a/src/version.c +++ b/src/version.c @@ -743,6 +743,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ +/**/ + 1505, /**/ 1504, /**/ From b69fccf377f43544b86817b0de6cc1498a4ff9ec Mon Sep 17 00:00:00 2001 From: Bram Moolenaar Date: Sun, 6 Mar 2016 23:06:25 +0100 Subject: [PATCH 08/13] patch 7.4.1506 Problem: Job cannot read from a file. Solution: Implement reading from a file for Unix. --- src/eval.c | 12 ++++++++++++ src/os_unix.c | 34 +++++++++++++++++++++++++++------- src/os_win32.c | 25 +++++++++++++++++++------ src/testdir/test_channel.vim | 27 +++++++++++++++++++++++++-- src/version.c | 2 ++ 5 files changed, 85 insertions(+), 15 deletions(-) diff --git a/src/eval.c b/src/eval.c index 510dd128da..77638d5612 100644 --- a/src/eval.c +++ b/src/eval.c @@ -15118,6 +15118,7 @@ f_job_start(typval_T *argvars UNUSED, typval_T *rettv) garray_T ga; #endif jobopt_T opt; + int part; rettv->v_type = VAR_JOB; job = job_alloc(); @@ -15135,6 +15136,17 @@ f_job_start(typval_T *argvars UNUSED, typval_T *rettv) + JO_STOPONEXIT + JO_EXIT_CB + JO_OUT_IO) == FAIL) return; + /* Check that when io is "file" that there is a file name. */ + for (part = PART_OUT; part <= PART_IN; ++part) + if ((opt.jo_set & (JO_OUT_IO << (part - PART_OUT))) + && opt.jo_io[part] == JIO_FILE + && (!(opt.jo_set & (JO_OUT_NAME << (part - PART_OUT))) + || *opt.jo_io_name[part] == NUL)) + { + EMSG(_("E920: -io file requires -name to be set")); + return; + } + if ((opt.jo_set & JO_IN_IO) && opt.jo_io[PART_IN] == JIO_BUFFER) { buf_T *buf; diff --git a/src/os_unix.c b/src/os_unix.c index ed2b1298cd..565dbd089d 100644 --- a/src/os_unix.c +++ b/src/os_unix.c @@ -5045,6 +5045,7 @@ mch_start_job(char **argv, job_T *job, jobopt_T *options UNUSED) int fd_out[2]; /* for stdout */ int fd_err[2]; /* for stderr */ channel_T *channel = NULL; + int use_file_for_in = options->jo_io[PART_IN] == JIO_FILE; int use_out_for_err = options->jo_io[PART_ERR] == JIO_OUT; /* default is to fail */ @@ -5055,8 +5056,22 @@ mch_start_job(char **argv, job_T *job, jobopt_T *options UNUSED) /* TODO: without the channel feature connect the child to /dev/null? */ /* Open pipes for stdin, stdout, stderr. */ - if (pipe(fd_in) < 0 || pipe(fd_out) < 0 - || (!use_out_for_err && pipe(fd_err) < 0)) + if (use_file_for_in) + { + char_u *fname = options->jo_io_name[PART_IN]; + + fd_in[0] = mch_open((char *)fname, O_RDONLY, 0); + if (fd_in[0] < 0) + { + EMSG2(_(e_notopen), fname); + goto failed; + } + } + else if (pipe(fd_in) < 0) + goto failed; + if (pipe(fd_out) < 0) + goto failed; + if (!use_out_for_err && pipe(fd_err) < 0) goto failed; channel = add_channel(); @@ -5088,7 +5103,8 @@ mch_start_job(char **argv, job_T *job, jobopt_T *options UNUSED) /* TODO: re-enable this when pipes connect without a channel */ # ifdef FEAT_CHANNEL /* set up stdin for the child */ - close(fd_in[1]); + if (!use_file_for_in) + close(fd_in[1]); close(0); ignored = dup(fd_in[0]); close(fd_in[0]); @@ -5130,12 +5146,15 @@ mch_start_job(char **argv, job_T *job, jobopt_T *options UNUSED) # ifdef FEAT_CHANNEL /* child stdin, stdout and stderr */ - close(fd_in[0]); + if (!use_file_for_in) + close(fd_in[0]); close(fd_out[1]); if (!use_out_for_err) close(fd_err[1]); - channel_set_pipes(channel, fd_in[1], fd_out[0], - use_out_for_err ? INVALID_FD : fd_err[0]); + channel_set_pipes(channel, + use_file_for_in ? INVALID_FD : fd_in[1], + fd_out[0], + use_out_for_err ? INVALID_FD : fd_err[0]); channel_set_job(channel, job, options); # ifdef FEAT_GUI channel_gui_register(channel); @@ -5151,7 +5170,8 @@ failed: ; if (fd_in[0] >= 0) { close(fd_in[0]); - close(fd_in[1]); + if (!use_file_for_in) + close(fd_in[1]); } if (fd_out[0] >= 0) { diff --git a/src/os_win32.c b/src/os_win32.c index 42e8672468..9201b34972 100644 --- a/src/os_win32.c +++ b/src/os_win32.c @@ -5000,6 +5000,7 @@ mch_start_job(char *cmd, job_T *job, jobopt_T *options) HANDLE jo; # ifdef FEAT_CHANNEL channel_T *channel; + int use_file_for_in = options->jo_io[PART_IN] == JIO_FILE; int use_out_for_err = options->jo_io[PART_ERR] == JIO_OUT; HANDLE ifd[2]; HANDLE ofd[2]; @@ -5035,13 +5036,25 @@ mch_start_job(char *cmd, job_T *job, jobopt_T *options) saAttr.nLength = sizeof(SECURITY_ATTRIBUTES); saAttr.bInheritHandle = TRUE; saAttr.lpSecurityDescriptor = NULL; - if (!CreatePipe(&ifd[0], &ifd[1], &saAttr, 0) - || !pSetHandleInformation(ifd[1], HANDLE_FLAG_INHERIT, 0) - || !CreatePipe(&ofd[0], &ofd[1], &saAttr, 0) - || !pSetHandleInformation(ofd[0], HANDLE_FLAG_INHERIT, 0) - || (!use_out_for_err + if (use_file_for_in) + { + char_u *fname = options->jo_io_name[PART_IN]; + + // TODO + EMSG2(_(e_notopen), fname); + goto failed; + } + else if (!CreatePipe(&ifd[0], &ifd[1], &saAttr, 0) + || !pSetHandleInformation(ifd[1], HANDLE_FLAG_INHERIT, 0)) + goto failed; + + if (!CreatePipe(&ofd[0], &ofd[1], &saAttr, 0) + || !pSetHandleInformation(ofd[0], HANDLE_FLAG_INHERIT, 0)) + goto failed; + + if (!use_out_for_err && (!CreatePipe(&efd[0], &efd[1], &saAttr, 0) - || !pSetHandleInformation(efd[0], HANDLE_FLAG_INHERIT, 0)))) + || !pSetHandleInformation(efd[0], HANDLE_FLAG_INHERIT, 0))) goto failed; si.dwFlags |= STARTF_USESTDHANDLES; si.hStdInput = ifd[0]; diff --git a/src/testdir/test_channel.vim b/src/testdir/test_channel.vim index 5321cce23f..299bb2ba7b 100644 --- a/src/testdir/test_channel.vim +++ b/src/testdir/test_channel.vim @@ -524,6 +524,31 @@ func Test_nl_err_to_out_pipe() endtry endfunc +func Test_nl_read_file() + if !has('job') + return + endif + " TODO: make this work for MS-Windows. + if !has('unix') + return + endif + call ch_log('Test_nl_read_file()') + call writefile(['echo something', 'echoerr wrong', 'double this'], 'Xinput') + let job = job_start(s:python . " test_channel_pipe.py", + \ {'in-io': 'file', 'in-name': 'Xinput'}) + call assert_equal("run", job_status(job)) + try + let handle = job_getchannel(job) + call assert_equal("something", ch_readraw(handle)) + call assert_equal("wrong", ch_readraw(handle, {'part': 'err'})) + call assert_equal("this", ch_readraw(handle)) + call assert_equal("AND this", ch_readraw(handle)) + finally + call job_stop(job) + call delete('Xinput') + endtry +endfunc + func Test_pipe_to_buffer() if !has('job') return @@ -556,7 +581,6 @@ func Test_pipe_from_buffer() if !has('job') return endif -call ch_logfile('channellog', 'w') call ch_log('Test_pipe_from_buffer()') sp pipe-input @@ -574,7 +598,6 @@ call ch_logfile('channellog', 'w') finally call job_stop(job) endtry -call ch_logfile('') endfunc func Test_pipe_to_nameless_buffer() diff --git a/src/version.c b/src/version.c index 9c94df8b37..7e86ba6a39 100644 --- a/src/version.c +++ b/src/version.c @@ -743,6 +743,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ +/**/ + 1506, /**/ 1505, /**/ From 4e329fcaf7122370a6d1815a30aaf29476d3f722 Mon Sep 17 00:00:00 2001 From: Bram Moolenaar Date: Mon, 7 Mar 2016 15:24:03 +0100 Subject: [PATCH 09/13] patch 7.4.1507 Problem: Crash when starting a job fails. Solution: Check for the channel to be NULL. (idea by Yasuhiro Matsumoto) --- src/eval.c | 3 ++- src/version.c | 2 ++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/src/eval.c b/src/eval.c index 77638d5612..f65c9a0b1b 100644 --- a/src/eval.c +++ b/src/eval.c @@ -15262,7 +15262,8 @@ f_job_start(typval_T *argvars UNUSED, typval_T *rettv) #ifdef FEAT_CHANNEL /* If the channel is reading from a buffer, write lines now. */ - channel_write_in(job->jv_channel); + if (job->jv_channel != NULL) + channel_write_in(job->jv_channel); #endif theend: diff --git a/src/version.c b/src/version.c index 7e86ba6a39..40690ec805 100644 --- a/src/version.c +++ b/src/version.c @@ -743,6 +743,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ +/**/ + 1507, /**/ 1506, /**/ From 47cff3a444be7e99bae52b39b2174c22d58d2f86 Mon Sep 17 00:00:00 2001 From: Bram Moolenaar Date: Mon, 7 Mar 2016 20:58:50 +0100 Subject: [PATCH 10/13] patch 7.4.1508 Problem: Can't build GvimExt with MingW. Solution: Adjust the makefile. (Ben Fritz) --- src/GvimExt/Make_ming.mak | 6 +++++- src/version.c | 2 ++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/src/GvimExt/Make_ming.mak b/src/GvimExt/Make_ming.mak index 2976ea05cf..a6ab3ae10e 100644 --- a/src/GvimExt/Make_ming.mak +++ b/src/GvimExt/Make_ming.mak @@ -43,6 +43,10 @@ else DEL = del endif endif +# Set the default $(WINVER) to make it work with WinXP. +ifndef WINVER +WINVER = 0x0501 +endif CXX := $(CROSS_COMPILE)g++ WINDRES := $(CROSS_COMPILE)windres WINDRES_CXX = $(CXX) @@ -68,7 +72,7 @@ $(DLL): $(OBJ) $(RES) $(DEFFILE) $(LIBS) gvimext.o: gvimext.cpp - $(CXX) $(CXXFLAGS) -DFEAT_GETTEXT -c $? -o $@ + $(CXX) $(CXXFLAGS) -DFEAT_GETTEXT -DWINVER=$(WINVER) -D_WIN32_WINNT=$(WINVER) -c $? -o $@ $(RES): gvimext_ming.rc $(WINDRES) $(WINDRES_FLAGS) --input-format=rc --output-format=coff -DMING $? -o $@ diff --git a/src/version.c b/src/version.c index 40690ec805..c4012e265e 100644 --- a/src/version.c +++ b/src/version.c @@ -743,6 +743,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ +/**/ + 1508, /**/ 1507, /**/ From 151f656e171f6ffbb0cbeb343cbcf2ffac0c36b0 Mon Sep 17 00:00:00 2001 From: Bram Moolenaar Date: Mon, 7 Mar 2016 21:19:38 +0100 Subject: [PATCH 11/13] patch 7.4.1509 Problem: Keeping both a variable for a job and the channel it refers to is a hassle. Solution: Allow passing the job where a channel is expected. (Damien) --- src/eval.c | 16 ++++++++++++---- src/testdir/test_channel.vim | 12 ++++++------ src/version.c | 2 ++ 3 files changed, 20 insertions(+), 10 deletions(-) diff --git a/src/eval.c b/src/eval.c index f65c9a0b1b..70a1daa44d 100644 --- a/src/eval.c +++ b/src/eval.c @@ -10285,14 +10285,22 @@ get_job_options(typval_T *tv, jobopt_T *opt, int supported) static channel_T * get_channel_arg(typval_T *tv) { - channel_T *channel; + channel_T *channel = NULL; - if (tv->v_type != VAR_CHANNEL) + if (tv->v_type == VAR_JOB) + { + if (tv->vval.v_job != NULL) + channel = tv->vval.v_job->jv_channel; + } + else if (tv->v_type == VAR_CHANNEL) + { + channel = tv->vval.v_channel; + } + else { EMSG2(_(e_invarg2), get_tv_string(tv)); return NULL; } - channel = tv->vval.v_channel; if (channel == NULL || !channel_is_open(channel)) { @@ -15106,7 +15114,7 @@ f_job_setoptions(typval_T *argvars, typval_T *rettv UNUSED) * "job_start()" function */ static void -f_job_start(typval_T *argvars UNUSED, typval_T *rettv) +f_job_start(typval_T *argvars, typval_T *rettv) { job_T *job; char_u *cmd = NULL; diff --git a/src/testdir/test_channel.vim b/src/testdir/test_channel.vim index 299bb2ba7b..5a315679cb 100644 --- a/src/testdir/test_channel.vim +++ b/src/testdir/test_channel.vim @@ -463,16 +463,16 @@ func Test_raw_pipe() let job = job_start(s:python . " test_channel_pipe.py", {'mode': 'raw'}) call assert_equal("run", job_status(job)) try - let handle = job_getchannel(job) - call ch_sendraw(handle, "echo something\n") - let msg = ch_readraw(handle) + " For a change use the job where a channel is expected. + call ch_sendraw(job, "echo something\n") + let msg = ch_readraw(job) call assert_equal("something\n", substitute(msg, "\r", "", 'g')) - call ch_sendraw(handle, "double this\n") - let msg = ch_readraw(handle) + call ch_sendraw(job, "double this\n") + let msg = ch_readraw(job) call assert_equal("this\nAND this\n", substitute(msg, "\r", "", 'g')) - let reply = ch_evalraw(handle, "quit\n", {'timeout': 100}) + let reply = ch_evalraw(job, "quit\n", {'timeout': 100}) call assert_equal("Goodbye!\n", substitute(reply, "\r", "", 'g')) finally call job_stop(job) diff --git a/src/version.c b/src/version.c index c4012e265e..417a0e374e 100644 --- a/src/version.c +++ b/src/version.c @@ -743,6 +743,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ +/**/ + 1509, /**/ 1508, /**/ From 304563c0b3e24895322ce3a29378388665b4769b Mon Sep 17 00:00:00 2001 From: Bram Moolenaar Date: Mon, 7 Mar 2016 22:26:28 +0100 Subject: [PATCH 12/13] patch 7.4.1510 Problem: Channel test fails on AppVeyor. Solution: Wait longer than 10 msec if needed. --- src/testdir/test_channel.vim | 14 ++++++++++++-- src/version.c | 2 ++ 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/src/testdir/test_channel.vim b/src/testdir/test_channel.vim index 5a315679cb..3f6511ad07 100644 --- a/src/testdir/test_channel.vim +++ b/src/testdir/test_channel.vim @@ -395,11 +395,21 @@ func s:raw_one_time_callback(port) " The message are sent raw, we do our own JSON strings here. call ch_sendraw(handle, "[1, \"hello!\"]", {'callback': 's:HandleRaw1'}) - sleep 10m + for i in range(50) + sleep 10m + if s:reply1 != '' + break + endif + endfor call assert_equal("[1, \"got it\"]", s:reply1) call ch_sendraw(handle, "[2, \"echo something\"]", {'callback': 's:HandleRaw2'}) call ch_sendraw(handle, "[3, \"wait a bit\"]", {'callback': 's:HandleRaw3'}) - sleep 10m + for i in range(50) + sleep 10m + if s:reply2 != '' + break + endif + endfor call assert_equal("[2, \"something\"]", s:reply2) " wait for up to 500 msec for the 200 msec delayed reply for i in range(50) diff --git a/src/version.c b/src/version.c index 417a0e374e..e2615be189 100644 --- a/src/version.c +++ b/src/version.c @@ -743,6 +743,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ +/**/ + 1510, /**/ 1509, /**/ From 5f148ec0b5a6cedd9129b3abac351034b83cc4f7 Mon Sep 17 00:00:00 2001 From: Bram Moolenaar Date: Mon, 7 Mar 2016 22:59:26 +0100 Subject: [PATCH 13/13] Update runtime files. --- runtime/doc/channel.txt | 23 +++++---- runtime/doc/eval.txt | 87 ++++++++++++++++++--------------- runtime/doc/os_win32.txt | 27 ++++++++++- runtime/doc/repeat.txt | 90 +++++++++++++++++++++------------- runtime/doc/starting.txt | 3 +- runtime/doc/tags | 2 + runtime/doc/todo.txt | 87 ++++++++------------------------- runtime/syntax/vhdl.vim | 101 +++++++++++++++++++++++++-------------- 8 files changed, 233 insertions(+), 187 deletions(-) diff --git a/runtime/doc/channel.txt b/runtime/doc/channel.txt index 0c9f70d3a3..a89bdb7875 100644 --- a/runtime/doc/channel.txt +++ b/runtime/doc/channel.txt @@ -1,4 +1,4 @@ -*channel.txt* For Vim version 7.4. Last change: 2016 Mar 03 +*channel.txt* For Vim version 7.4. Last change: 2016 Mar 06 VIM REFERENCE MANUAL by Bram Moolenaar @@ -467,6 +467,9 @@ For example, to start a job and write its output in buffer "dummy": > \ {'out-io': 'buffer', 'out-name': 'dummy'}) sbuf dummy + +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'}) @@ -478,10 +481,10 @@ be loaded when job_start() is called. By default this reads the whole buffer. This can be changed with the "in-top" and "in-bot" options. -TODO -A special mode is when "in-top" is set to zero and "in-bot" is not set: The -last-but-one line will be send to the job stdin. This allows for editing the -last line and sending it when pressing Enter. +A special mode is when "in-top" is set to zero and "in-bot" is not set: Every +time a line is added to the buffer, the last-but-one line will be send to the +job stdin. This allows for editing the last line and sending it when pressing +Enter. TODO: To run a job and read its output once it is done: > @@ -568,7 +571,7 @@ TODO: *job-term* "in-io": "buffer" stdin reads from a buffer "in-top": number when using "buffer": first line to send (default: 1) "in-bot": number when using "buffer": last line to send (default: last) -"in-name": "/path/file" the name of he file or buffer to read from +"in-name": "/path/file" the name of the file or buffer to read from "in-buf": number the number of the buffer to read from TODO *job-out-io* @@ -588,8 +591,12 @@ TODO: *job-term* "err-name": "/path/file" the name of the file or buffer to write to "err-buf": number the number of the buffer to write to TODO -When the IO mode is "buffer" and there is a callback, the text is appended to -the buffer before invoking the callback. +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. + +When a buffer is used both for input and output, the output lines are put +above the last line, since the last line is what is written to the channel +input. Otherwise lines are appened below the last line. When using JS or JSON mode with "buffer", only messages with zero or negative ID will be added to the buffer, after decoding + encoding. Messages with a diff --git a/runtime/doc/eval.txt b/runtime/doc/eval.txt index 7693ee399e..4251eb45ad 100644 --- a/runtime/doc/eval.txt +++ b/runtime/doc/eval.txt @@ -1,4 +1,4 @@ -*eval.txt* For Vim version 7.4. Last change: 2016 Mar 03 +*eval.txt* For Vim version 7.4. Last change: 2016 Mar 07 VIM REFERENCE MANUAL by Bram Moolenaar @@ -1817,24 +1817,24 @@ byteidxcomp( {expr}, {nr}) Number byte index of {nr}'th char in {expr} call( {func}, {arglist} [, {dict}]) any call {func} with arguments {arglist} ceil( {expr}) Float round {expr} up -ch_close( {channel}) none close {channel} -ch_evalexpr( {channel}, {expr} [, {options}]) - any evaluate {expr} on JSON {channel} -ch_evalraw( {channel}, {string} [, {options}]) - any evaluate {string} on raw {channel} -ch_getbufnr( {channel}, {what}) Number get buffer number for {channel}/{what} +ch_close( {handle}) none close {handle} +ch_evalexpr( {handle}, {expr} [, {options}]) + any evaluate {expr} on JSON {handle} +ch_evalraw( {handle}, {string} [, {options}]) + any evaluate {string} on raw {handle} +ch_getbufnr( {handle}, {what}) Number get buffer number for {handle}/{what} ch_getjob( {channel}) Job get the Job of {channel} -ch_log( {msg} [, {channel}]) none write {msg} in the channel log file +ch_log( {msg} [, {handle}]) none write {msg} in the channel log file ch_logfile( {fname} [, {mode}]) none start logging channel activity ch_open( {address} [, {options}]) Channel open a channel to {address} -ch_read( {channel} [, {options}]) String read from {channel} -ch_readraw( {channel} [, {options}]) String read raw from {channel} -ch_sendexpr( {channel}, {expr} [, {options}]) - any send {expr} over JSON {channel} -ch_sendraw( {channel}, {string} [, {options}]) - any send {string} over raw {channel} -ch_setoptions( {channel}, {options}) none set options for {channel} -ch_status( {channel}) String status of {channel} +ch_read( {handle} [, {options}]) String read from {handle} +ch_readraw( {handle} [, {options}]) String read raw from {handle} +ch_sendexpr( {handle}, {expr} [, {options}]) + any send {expr} over JSON {handle} +ch_sendraw( {handle}, {string} [, {options}]) + any send {string} over raw {handle} +ch_setoptions( {handle}, {options}) none set options for {handle} +ch_status( {handle}) String status of {handle} changenr() Number current change number char2nr( {expr}[, {utf8}]) Number ASCII/UTF8 value of first char in {expr} cindent( {lnum}) Number C indent for line {lnum} @@ -2693,8 +2693,9 @@ confirm({msg} [, {choices} [, {default} [, {type}]]]) don't fit, a vertical layout is used anyway. For some systems the horizontal layout is always used. -ch_close({channel}) *ch_close()* - Close {channel}. See |channel-close|. +ch_close({handle}) *ch_close()* + Close {handle}. See |channel-close|. + {handle} can be Channel or a Job that has a Channel. Note that a channel is closed in three stages: - The I/O ends, log message: "Closing channel". There can @@ -2705,10 +2706,11 @@ ch_close({channel}) *ch_close()* {only available when compiled with the |+channel| feature} -ch_evalexpr({channel}, {expr} [, {options}]) *ch_evalexpr()* - Send {expr} over {channel}. The {expr} is encoded +ch_evalexpr({handle}, {expr} [, {options}]) *ch_evalexpr()* + Send {expr} over {handle}. The {expr} is encoded according to the type of channel. The function cannot be used with a raw channel. See |channel-use|. + {handle} can be Channel or a Job that has a Channel. *E917* {options} must be a Dictionary. It must not have a "callback" entry. It can have a "timeout" entry. @@ -2719,8 +2721,10 @@ ch_evalexpr({channel}, {expr} [, {options}]) *ch_evalexpr()* {only available when compiled with the |+channel| feature} -ch_evalraw({channel}, {string} [, {options}]) *ch_evalraw()* - Send {string} over {channel}. +ch_evalraw({handle}, {string} [, {options}]) *ch_evalraw()* + Send {string} over {handle}. + {handle} can be Channel or a Job that has a Channel. + Works like |ch_evalexpr()|, but does not encode the request or decode the response. The caller is responsible for the correct contents. Also does not add a newline for a channel @@ -2730,8 +2734,9 @@ ch_evalraw({channel}, {string} [, {options}]) *ch_evalraw()* {only available when compiled with the |+channel| feature} -ch_getbufnr({channel}, {what}) *ch_getbufnr()* - Get the buffer number that {channel} is using for {what}. +ch_getbufnr({handle}, {what}) *ch_getbufnr()* + Get the buffer number that {handle} is using for {what}. + {handle} can be Channel or a Job that has a Channel. {what} can be "err" for stderr, "out" for stdout or empty for socket output. Returns -1 when there is no buffer. @@ -2745,11 +2750,13 @@ ch_getjob({channel}) *ch_getjob()* {only available when compiled with the |+channel| and |+job| features} -ch_log({msg} [, {channel}]) *ch_log()* +ch_log({msg} [, {handle}]) *ch_log()* Write {msg} in the channel log file, if it was opened with |ch_logfile()|. - When {channel} is passed the channel number is used for the - message. {channel} must be an open channel. + When {handle} is passed the channel number is used for the + message. + {handle} can be Channel or a Job that has a Channel. The + Channel must open. ch_logfile({fname} [, {mode}]) *ch_logfile()* Start logging channel activity to {fname}. @@ -2785,8 +2792,9 @@ ch_open({address} [, {options}]) *ch_open()* Default: 2000. {only available when compiled with the |+channel| feature} -ch_read({channel} [, {options}]) *ch_read()* - Read from {channel} and return the received message. +ch_read({handle} [, {options}]) *ch_read()* + Read from {handle} and return the received message. + {handle} can be Channel or a Job that has a Channel. This uses the channel timeout. When there is nothing to read within that time an empty string is returned. To specify a @@ -2806,14 +2814,15 @@ ch_read({channel} [, {options}]) *ch_read()* For a JS or JSON channel this returns one decoded message. This includes any sequence number. -ch_readraw({channel} [, {options}]) *ch_readraw()* +ch_readraw({handle} [, {options}]) *ch_readraw()* Like ch_read() but for a JS and JSON channel does not decode the message. -ch_sendexpr({channel}, {expr} [, {options}]) *ch_sendexpr()* - Send {expr} over {channel}. The {expr} is encoded +ch_sendexpr({handle}, {expr} [, {options}]) *ch_sendexpr()* + Send {expr} over {handle}. The {expr} is encoded according to the type of channel. The function cannot be used with a raw channel. See |channel-use|. *E912* + {handle} can be Channel or a Job that has a Channel. {options} must be a Dictionary. The "callback" item is a Funcref or the name of a function it is invoked when the @@ -2823,8 +2832,8 @@ ch_sendexpr({channel}, {expr} [, {options}]) *ch_sendexpr()* {only available when compiled with the |+channel| feature} -ch_sendraw({channel}, {string} [, {options}]) *ch_sendraw()* - Send {string} over {channel}. +ch_sendraw({handle}, {string} [, {options}]) *ch_sendraw()* + Send {string} over {handle}. Works like |ch_sendexpr()|, but does not encode the request or decode the response. The caller is responsible for the correct contents. Also does not add a newline for a channel @@ -2834,12 +2843,13 @@ ch_sendraw({channel}, {string} [, {options}]) *ch_sendraw()* {only available when compiled with the |+channel| feature} -ch_setoptions({channel}, {options}) *ch_setoptions()* - Set options on {channel}: +ch_setoptions({handle}, {options}) *ch_setoptions()* + Set options on {handle}: "callback" the channel callback "timeout" default read timeout in msec "mode" mode for the whole channel See |ch_open()| for more explanation. + {handle} can be Channel or a Job that has a Channel. Note that changing the mode may cause queued messages to be lost. @@ -2847,11 +2857,12 @@ ch_setoptions({channel}, {options}) *ch_setoptions()* These options cannot be changed: "waittime" only applies to "ch_open()| -ch_status({channel}) *ch_status()* - Return the status of {channel}: +ch_status({handle}) *ch_status()* + Return the status of {handle}: "fail" failed to open the channel "open" channel can be used "closed" channel can not be used + {handle} can be Channel or a Job that has a Channel. *copy()* copy({expr}) Make a copy of {expr}. For Numbers and Strings this isn't diff --git a/runtime/doc/os_win32.txt b/runtime/doc/os_win32.txt index 9637d7e82a..f60cb0383d 100644 --- a/runtime/doc/os_win32.txt +++ b/runtime/doc/os_win32.txt @@ -1,4 +1,4 @@ -*os_win32.txt* For Vim version 7.4. Last change: 2014 Sep 25 +*os_win32.txt* For Vim version 7.4. Last change: 2016 Mar 05 VIM REFERENCE MANUAL by George Reilly @@ -96,6 +96,31 @@ The directory of the Vim executable is appended to $PATH. This is mostly to make "!xxd" work, as it is in the Tools menu. And it also means that when executable() returns 1 the executable can actually be executed. +Quotes in file names *win32-quotes* + +Quotes inside a file name (or any other command line argument) can be escaped +with a backslash. E.g. > + vim -c "echo 'foo\"bar'" + +Alternatively use three quotes to get one: > + vim -c "echo 'foo"""bar'" + +The quotation rules are: + +1. A `"` starts quotation. +2. Another `"` or `""` ends quotation. If the quotation ends with `""`, a `"` + is produced at the end of the quoted string. + +Examples, with [] around an argument: + "foo" -> [foo] + "foo"" -> [foo"] + "foo"bar -> [foobar] + "foo" bar -> [foo], [bar] + "foo""bar -> [foo"bar] + "foo"" bar -> [foo"], [bar] + "foo"""bar" -> [foo"bar] + + ============================================================================== 3. Restore screen contents *win32-restore* diff --git a/runtime/doc/repeat.txt b/runtime/doc/repeat.txt index 1b9e54fcb3..30be59cf49 100644 --- a/runtime/doc/repeat.txt +++ b/runtime/doc/repeat.txt @@ -1,4 +1,4 @@ -*repeat.txt* For Vim version 7.4. Last change: 2016 Mar 04 +*repeat.txt* For Vim version 7.4. Last change: 2016 Mar 07 VIM REFERENCE MANUAL by Bram Moolenaar @@ -420,57 +420,79 @@ Rationale: A Vim package is a directory that contains one or more plugins. The advantages over normal plugins: - A package can be downloaded as an archive and unpacked in its own directory. - That makes it easy to updated and/or remove. + Thus the files are not mixed with files of other plugins. That makes it + easy to update and remove. - A package can be a git, mercurial, etc. repository. That makes it really easy to update. - A package can contain multiple plugins that depend on each other. - A package can contain plugins that are automatically loaded on startup and - ones that are only loaded when needed with `:loadplugin`. + ones that are only loaded when needed with `:packadd`. + + +Using a package and loading automatically ~ Let's assume your Vim files are in the "~/.vim" directory and you want to add a -package from a zip archive "/tmp/mypack.zip": - % mkdir -p ~/.vim/pack/my - % cd ~/.vim/pack/my - % unzip /tmp/mypack.zip +package from a zip archive "/tmp/foopack.zip": + % mkdir -p ~/.vim/pack/foo + % cd ~/.vim/pack/foo + % unzip /tmp/foopack.zip -The directory name "my" is arbitrary, you can pick anything you like. +The directory name "foo" is arbitrary, you can pick anything you like. You would now have these files under ~/.vim: - pack/my/README.txt - pack/my/ever/always/plugin/always.vim - pack/my/ever/always/syntax/always.vim - pack/my/opt/mydebug/plugin/debugger.vim + pack/foo/README.txt + pack/foo/ever/foobar/plugin/foo.vim + pack/foo/ever/foobar/syntax/some.vim + pack/foo/opt/foodebug/plugin/debugger.vim -If you don't have a package but a single plugin, you need to create the extra -directory level: - % mkdir -p ~/.vim/pack/my/ever/always - % cd ~/.vim/pack/my/ever/always - % unzip /tmp/myplugin.zip +When Vim starts up, after processing your .vimrc, it scans all directories in +'packpath' for plugins under the "pack/*/ever" directory and loads them. The +directory is added to 'runtimepath'. -When Vim starts up it scans all directories in 'packpath' for plugins under the -"ever" directory and loads them. When found that directory is added to -'runtimepath'. +In the example Vim will find "pack/foo/ever/foobar/plugin/foo.vim" and adds +"~/.vim/pack/foo/ever/foobar" to 'runtimepath'. -In the example Vim will find "my/ever/always/plugin/always.vim" and adds -"~/.vim/pack/my/ever/always" to 'runtimepath'. +If the "foobar" plugin kicks in and sets the 'filetype' to "some", Vim will +find the syntax/some.vim file, because its directory is in 'runtimepath'. -If the "always" plugin kicks in and sets the 'filetype' to "always", Vim will -find the syntax/always.vim file, because its directory is in 'runtimepath'. +Vim will also load ftdetect files, if there are any. -Vim will also load ftdetect files, like with |:packadd|. - - *pack-add* -To load an optional plugin from a pack use the `:packadd` command: > - :packadd mydebug -This could be done inside always.vim, if some conditions are met. -Or you could add this command to your |.vimrc|. - -It is perfectly normal for a package to only have files in the "opt" -directory. You then need to load each plugin when you want to use it. +Note that the files under "pack/foo/opt" or not loaded automatically, only the +ones under "pack/foo/ever". See |pack-add| below for how the "opt" directory +is used. Loading packages will not happen if loading plugins is disabled, see |load-plugins|. + +Using a single plugin and loading it automatically ~ + +If you don't have a package but a single plugin, you need to create the extra +directory level: + % mkdir -p ~/.vim/pack/foo/ever/foobar + % cd ~/.vim/pack/foo/ever/foobar + % unzip /tmp/someplugin.zip + +You would now have these files: + pack/foo/ever/foobar/plugin/foo.vim + pack/foo/ever/foobar/syntax/some.vim + +From here it works like above. + + +Optional plugins ~ + *pack-add* +To load an optional plugin from a pack use the `:packadd` command: > + :packadd foodebug +This searches for "pack/*/opt/foodebug" in 'packpath' and will find +~/.vim/pack/foo/opt/foodebug/plugin/debugger.vim and source it. + +This could be done inside always.vim, if some conditions are met. Or you +could add this command to your |.vimrc|. + +It is perfectly normal for a package to only have files in the "opt" +directory. You then need to load each plugin when you want to use it. + ============================================================================== 6. Debugging scripts *debug-scripts* diff --git a/runtime/doc/starting.txt b/runtime/doc/starting.txt index 450fdaf17a..4b32a50cd4 100644 --- a/runtime/doc/starting.txt +++ b/runtime/doc/starting.txt @@ -1,4 +1,4 @@ -*starting.txt* For Vim version 7.4. Last change: 2016 Mar 03 +*starting.txt* For Vim version 7.4. Last change: 2016 Mar 05 VIM REFERENCE MANUAL by Bram Moolenaar @@ -45,6 +45,7 @@ filename One or more file names. The first one will be the current vim -- -filename < All arguments after the "--" will be interpreted as file names, no other options or "+command" argument can follow. + For behavior of quotes on MS-Windows, see |win32-quotes|. *--* - This argument can mean two things, depending on whether Ex diff --git a/runtime/doc/tags b/runtime/doc/tags index 8e822c6f39..7deba0ca7c 100644 --- a/runtime/doc/tags +++ b/runtime/doc/tags @@ -4442,6 +4442,7 @@ E915 channel.txt /*E915* E916 eval.txt /*E916* E917 eval.txt /*E917* E918 channel.txt /*E918* +E919 repeat.txt /*E919* E92 message.txt /*E92* E93 windows.txt /*E93* E94 windows.txt /*E94* @@ -9010,6 +9011,7 @@ win32-mouse os_win32.txt /*win32-mouse* win32-open-with-menu gui_w32.txt /*win32-open-with-menu* win32-popup-menu gui_w32.txt /*win32-popup-menu* win32-problems os_win32.txt /*win32-problems* +win32-quotes os_win32.txt /*win32-quotes* win32-restore os_win32.txt /*win32-restore* win32-startup os_win32.txt /*win32-startup* win32-term os_win32.txt /*win32-term* diff --git a/runtime/doc/todo.txt b/runtime/doc/todo.txt index 5fed9ac608..c6c38e14c0 100644 --- a/runtime/doc/todo.txt +++ b/runtime/doc/todo.txt @@ -1,4 +1,4 @@ -*todo.txt* For Vim version 7.4. Last change: 2016 Mar 04 +*todo.txt* For Vim version 7.4. Last change: 2016 Mar 07 VIM REFERENCE MANUAL by Bram Moolenaar @@ -35,10 +35,10 @@ not be repeated below, unless there is extra information. -------------------- Known bugs and current work ----------------------- +channel: +- move code from eval.c to channel.c - implement TODO items in ":help channel": - - Send last line of buffer when it's added. - job_start() options: - in-io: null, file (in-name), in-buf + in-io: null, in-buf out-io: null, file, out-buf err-io: null, file (err-name), buffer (err-buf) existing channel to use @@ -54,7 +54,6 @@ not be repeated below, unless there is extra information. - When a message in the queue but there is no callback, drop it after a while? Add timestamp to queued messages and callbacks with ID, remove after a minute. -- cleanup on exit? in mch_getout() and getout(). - Add more log calls, basically at every branch, before every callback, etc. - add remark about undo sync, is there a way to force it? - When starting a job, have an option to open the server socket, so we know @@ -72,6 +71,14 @@ Later emoji patch from Yasuhiro Matsumoto. Asked Thomas Dickey. +Packages: +- Add command to update help tags in 'runtimepath'. Pathogen has something + like that. +- colorscheme command in .vimrc doesn't work. + - Postpone until later? + - Also search in 'packpath'? + - command to load packages now? + More plugin support: - Have a way to install a callback from the main loop. Called every second or so. @@ -114,6 +121,9 @@ Allow for an empty dictionary key? Patch to improve I/O for Perl. (Damien, 2016 Jan 9, update Jan 22 2nd one) +Patch to fix ml_get error. (Alexander Freiherr von Buddenbrock, 2016 Mar 4, +#676) + Regexp problems: - The regexp engines are not reentrant, causing havoc when interrupted by a remote expression or something else. Move global variables onto the stack @@ -169,14 +179,14 @@ Patch to have better check for {action} argument of setqflist(). Nikolai Pavlov, Feb 25, #661. Can be even more strict. Also see patch from Hirohito Higash, Feb 25. -Patch for clearing history. (Yegappan Lakshmanan, 2016 Jan 31, second message -has tests) - Patch to update the GTK icon cache when installing. (Kazunobu Kuriyama, 2016 Feb 3) Patch for test86 and test87. (Roland Puntaier, #622) +We can use '. to go to the last change in the current buffer, but how about +the last change in any buffer? Can we use ', (, is next to .)? + Patch for Python: #622. (Roland Puntaier, 2016 Feb 2) What does it change? @@ -334,6 +344,7 @@ Use v:none. var == v:none Patch to add arguments to argc() and argv(). (Yegappan Lakshmanan, 2016 Jan 24) Also need a way to get the global arg list? Update later on Jan 24 +Update Mar 5. To support Thai (and other languages) word boundaries, include the ICU library: http://userguide.icu-project.org/boundaryanalysis @@ -1750,9 +1761,6 @@ Fail to edit file after failed register access. Error flag remains set? Patch for redo register. (Ben Schmidt, 2007 Oct 19) Await response to question to make the register writable. -src/testdir/Make_dos.mak: not all tests are included, e.g., test49, without a -remark why. - Problem with 'ts' set to 9 and 'showbreak' to ">>>". (Matthew Winn, 2007 Oct 1) @@ -2720,64 +2728,7 @@ GUI: currently. This is very obvious on a 66Mhz 486. -MSDOS/DJGPP: -9 Pressing CTRL-C often crashes the console Vim runs in. (Ken Liao) - When 'bioskey' isn't set it doesn't happen. Could be a problem with the - BIOS emulation of the console. Version 5.6 already had this problem. -8 DJGPP: "cd c:" can take us to a directory that no longer exists. - change_drive() doesn't check this. How to check for this error? -9 The 16 bit version runs out of memory very quickly. Should find unused - code and reduce static data. Resetting 'writebackup' helps to be able to - write a file. -9 Crash when running on Windows 98 in a console window and pressing CTRL-C. - Happens now and then. When debugging Vim in gdb this also happens. Since - the console crashes, might be a bug in the DOS console. Resetting - 'bioskey' avoids it, but then CTRL-C doesn't work. -9 DOS: Make CTRL-Fx and ALT-Fx work. - CTRL-F1 = CE-5E, CTRL-F2 = CE-5F, .., CTRL-F10 = CE-67 - ALT-F1 = CE-68, ALT-F2 = CE-69, .., ALT-F10 = CE-71 - Shifted cursor keys produce same codes as unshifted keys. Use bioskey(2) - to get modifier mask for . - Use K_SPECIAL/KS_MODIFIER codes to insert modifier mask in input stream? - Make this work like in Win32 console. - Mapping things like doesn't work, because it generates an extended - key code. Use a translation table? -9 Can't read an opened swap file when the "share" command has not been used. - At least ignore the swap files that Vim has opened itself. -8 Use DJGPP 2.03. -8 The Dos32 version (DJGPP) can't use long file names on Windows NT. - Check if new package can be used (v2misc/ntlfn08[bs].zip). -8 setlocale() is bogus. -8 Vim busy waits for new characters or mouse clicks. Should put in some - sort of sleep, to avoid eating 50% of the CPU time. Test on an unpatched - Windows 95 system! -8 DJGPP: when shell is bash, make fails. (Donahoe) -7 Hitting CTRL-P twice quickly (e.g., in keyword completion) on a 8088 - machine, starts printer echo! (John Mullin). -7 MSDOS 16 bit version can't work with COMSPEC that has an argument, e.g.: - COMSPEC=C:\WINDOWS\COMMAND.COM /E:4096 (Bradley) - Caused by BCC system() function (Borland "make" has the same problem). -8 Mouse: handle left&right button pressed as middle button pressed. Add - modifier keys shift, ctrl and alt. -7 When too many files are open (depends on FILES), strange things happen. - The Dos16 version runs out of memory, in the Dos32 version "!ls" causes a - crash. Another symptom: .swp files are not deleted, existing files are - "[New file]". -7 DJGPP version doesn't work with graphics display mode. Switch to a mode - that is supported? -8 DJGPP: ":mode" doesn't work for many modes. Disable them. -8 DJGPP: When starting in Ex mode, shouldn't clear the screen. (Walter - Briscoe) - - -MSDOS, OS/2 and Win32: -8 OS/2: Add backtick expansion. Undefine NO_EXPANDPATH and use - gen_expand_wildcards(). -8 OS/2: Add clipboard support? See example clipbrd.exe from Alexander - Wagner. -8 OS/2: Add Extended Attributes support and define HAVE_ACL. -8 OS/2: When editing a file name "foo.txt" that is actually called FOO.txt, - writing uses "foo.txt". Should obtain the real file name. +Win32 console: 8 Should $USERPROFILE be preferred above $HOMEDRIVE/$HOMEPATH? No, but it's a good fallback, thus use: $HOME diff --git a/runtime/syntax/vhdl.vim b/runtime/syntax/vhdl.vim index 916bd9635d..044ef83d17 100644 --- a/runtime/syntax/vhdl.vim +++ b/runtime/syntax/vhdl.vim @@ -1,14 +1,10 @@ " Vim syntax file -" Language: VHDL -" Maintainer: Daniel Kho +" Language: VHDL [VHSIC (Very High Speed Integrated Circuit) Hardware Description Language] +" Maintainer: Daniel Kho " Previous Maintainer: Czo -" Credits: Stephan Hegel -" Last Changed: 2015 Dec 4 by Daniel Kho +" Credits: Stephan Hegel +" Last Changed: 2016 Mar 05 by Daniel Kho -" VHSIC (Very High Speed Integrated Circuit) Hardware Description Language - -" For version 5.x: Clear all syntax items -" For version 6.x: Quit when a syntax file was already loaded if version < 600 syntax clear elseif exists("b:current_syntax") @@ -56,17 +52,40 @@ syn keyword vhdlStatement note warning error failure syn match vhdlStatement "\<\(if\|else\)\>" syn match vhdlError "\" -" Predefined VHDL types -syn keyword vhdlType bit bit_vector -syn keyword vhdlType character boolean integer real time -syn keyword vhdlType boolean_vector integer_vector real_vector time_vector -syn keyword vhdlType string severity_level -" Predefined standard ieee VHDL types -syn keyword vhdlType positive natural signed unsigned -syn keyword vhdlType unresolved_signed unresolved_unsigned u_signed u_unsigned -syn keyword vhdlType line text -syn keyword vhdlType std_logic std_logic_vector -syn keyword vhdlType std_ulogic std_ulogic_vector +" Types and type qualifiers +" Predefined standard VHDL types +syn match vhdlType "bit[\']*" +syn match vhdlType "boolean[\']*" +syn match vhdlType "natural[\']*" +syn match vhdlType "positive[\']*" +syn match vhdlType "integer[\']*" +syn match vhdlType "real[\']*" +syn match vhdlType "time[\']*" + +syn match vhdlType "bit_vector[\']*" +syn match vhdlType "boolean_vector[\']*" +syn match vhdlType "integer_vector[\']*" +syn match vhdlType "real_vector[\']*" +syn match vhdlType "time_vector[\']*" + +syn match vhdlType "character[\']*" +syn match vhdlType "string[\']*" +"syn keyword vhdlType severity_level +syn match vhdlType "line[\']*" +syn match vhdlType "text[\']*" + +" Predefined standard IEEE VHDL types +syn match vhdlType "std_ulogic[\']*" +syn match vhdlType "std_logic[\']*" +syn match vhdlType "std_ulogic_vector[\']*" +syn match vhdlType "std_logic_vector[\']*" +syn match vhdlType "unresolved_signed[\']*" +syn match vhdlType "unresolved_unsigned[\']*" +syn match vhdlType "u_signed[\']*" +syn match vhdlType "u_unsigned[\']*" +syn match vhdlType "signed[\']*" +syn match vhdlType "unsigned[\']*" + " array attributes syn match vhdlAttribute "\'high" @@ -191,15 +210,23 @@ syn case ignore syn region vhdlComment start="/\*" end="\*/" contains=vhdlTodo,vhdlFixme,@Spell syn match vhdlComment "\(^\|\s\)--.*" contains=vhdlTodo,vhdlFixme,@Spell +" Standard IEEE P1076.6 preprocessor directives (metacomments). +syn match vhdlPreProc "/\*\s*rtl_synthesis\s\+\(on\|off\)\s*\*/" +syn match vhdlPreProc "\(^\|\s\)--\s*rtl_synthesis\s\+\(on\|off\)\s*" +syn match vhdlPreProc "/\*\s*rtl_syn\s\+\(on\|off\)\s*\*/" +syn match vhdlPreProc "\(^\|\s\)--\s*rtl_syn\s\+\(on\|off\)\s*" + " Industry-standard directives. These are not standard VHDL, but are commonly " used in the industry. syn match vhdlPreProc "/\*\s*synthesis\s\+translate_\(on\|off\)\s*\*/" "syn match vhdlPreProc "/\*\s*simulation\s\+translate_\(on\|off\)\s*\*/" +syn match vhdlPreProc "/\*\s*pragma\s\+translate_\(on\|off\)\s*\*/" syn match vhdlPreProc "/\*\s*pragma\s\+synthesis_\(on\|off\)\s*\*/" syn match vhdlPreProc "/\*\s*synopsys\s\+translate_\(on\|off\)\s*\*/" syn match vhdlPreProc "\(^\|\s\)--\s*synthesis\s\+translate_\(on\|off\)\s*" "syn match vhdlPreProc "\(^\|\s\)--\s*simulation\s\+translate_\(on\|off\)\s*" +syn match vhdlPreProc "\(^\|\s\)--\s*pragma\s\+translate_\(on\|off\)\s*" syn match vhdlPreProc "\(^\|\s\)--\s*pragma\s\+synthesis_\(on\|off\)\s*" syn match vhdlPreProc "\(^\|\s\)--\s*synopsys\s\+translate_\(on\|off\)\s*" @@ -216,24 +243,24 @@ if version >= 508 || !exists("did_vhdl_syntax_inits") else command -nargs=+ HiLink hi def link endif - - HiLink vhdlSpecial Special - HiLink vhdlStatement Statement - HiLink vhdlCharacter Character - HiLink vhdlString String - HiLink vhdlVector Number - HiLink vhdlBoolean Number - HiLink vhdlTodo Todo - HiLink vhdlFixme Fixme - HiLink vhdlComment Comment - HiLink vhdlNumber Number - HiLink vhdlTime Number - HiLink vhdlType Type - HiLink vhdlOperator Operator - HiLink vhdlError Error - HiLink vhdlAttribute Special - HiLink vhdlPreProc PreProc - + + HiLink vhdlSpecial Special + HiLink vhdlStatement Statement + HiLink vhdlCharacter Character + HiLink vhdlString String + HiLink vhdlVector Number + HiLink vhdlBoolean Number + HiLink vhdlTodo Todo + HiLink vhdlFixme Fixme + HiLink vhdlComment Comment + HiLink vhdlNumber Number + HiLink vhdlTime Number + HiLink vhdlType Type + HiLink vhdlOperator Operator + HiLink vhdlError Error + HiLink vhdlAttribute Special + HiLink vhdlPreProc PreProc + delcommand HiLink endif