diff --git a/nsis/gvim.nsi b/nsis/gvim.nsi index 0bc9d4c6a6..2ae7d41249 100644 --- a/nsis/gvim.nsi +++ b/nsis/gvim.nsi @@ -215,6 +215,28 @@ Section "Vim executables and runtime files" SetOutPath $0\macros File ${VIMRT}\macros\*.* + SetOutPath $0\pack\dist\opt\dvorak\dvorak + File ${VIMRT}\pack\dist\opt\dvorak\dvorak\*.* + SetOutPath $0\pack\dist\opt\dvorak\plugin + File ${VIMRT}\pack\dist\opt\dvorak\plugin\*.* + + SetOutPath $0\pack\dist\opt\editexisting\plugin + File ${VIMRT}\pack\dist\opt\editexisting\plugin\*.* + + SetOutPath $0\pack\dist\opt\justify\plugin + File ${VIMRT}\pack\dist\opt\justify\plugin\*.* + + SetOutPath $0\pack\dist\opt\matchit\doc + File ${VIMRT}\pack\dist\opt\matchit\doc\*.* + SetOutPath $0\pack\dist\opt\matchit\plugin + File ${VIMRT}\pack\dist\opt\matchit\plugin\*.* + + SetOutPath $0\pack\dist\opt\shellmenu\plugin + File ${VIMRT}\pack\dist\opt\shellmenu\plugin\*.* + + SetOutPath $0\pack\dist\opt\swapmouse\plugin + File ${VIMRT}\pack\dist\opt\swapmouse\plugin\*.* + SetOutPath $0\plugin File ${VIMRT}\plugin\*.* diff --git a/src/channel.c b/src/channel.c index 92f775c023..20b4a74817 100644 --- a/src/channel.c +++ b/src/channel.c @@ -54,6 +54,8 @@ # define fd_close(sd) close(sd) #endif +static void channel_read(channel_T *channel, int part, char *func); + /* Whether a redraw is needed for appending a line to a buffer. */ static int channel_need_redraw = FALSE; @@ -440,7 +442,8 @@ free_unused_channels_contents(int copyID, int mask) channel_T *ch; for (ch = first_channel; ch != NULL; ch = ch->ch_next) - if ((ch->ch_copyID & mask) != (copyID & mask)) + if (!channel_still_useful(ch) + && (ch->ch_copyID & mask) != (copyID & mask)) { /* Free the channel and ordinary items it contains, but don't * recurse into Lists, Dictionaries etc. */ @@ -459,7 +462,8 @@ free_unused_channels(int copyID, int mask) for (ch = first_channel; ch != NULL; ch = ch_next) { ch_next = ch->ch_next; - if ((ch->ch_copyID & mask) != (copyID & mask)) + if (!channel_still_useful(ch) + && (ch->ch_copyID & mask) != (copyID & mask)) { /* Free the channel struct itself. */ channel_free_channel(ch); @@ -2120,6 +2124,18 @@ append_to_buffer(buf_T *buffer, char_u *msg, channel_T *channel) } } + static void +drop_messages(channel_T *channel, int part) +{ + char_u *msg; + + while ((msg = channel_get(channel, part)) != NULL) + { + ch_logs(channel, "Dropping message '%s'", (char *)msg); + vim_free(msg); + } +} + /* * Invoke a callback for "channel"/"part" if needed. * This does not redraw but sets channel_need_redraw when redraw is needed. @@ -2219,11 +2235,10 @@ may_invoke_callback(channel_T *channel, int part) /* If there is no callback or buffer drop the message. */ if (callback == NULL && buffer == NULL) { - while ((msg = channel_get(channel, part)) != NULL) - { - ch_logs(channel, "Dropping message '%s'", (char *)msg); - vim_free(msg); - } + /* If there is a close callback it may use ch_read() to get the + * messages. */ + if (channel->ch_close_cb == NULL) + drop_messages(channel, part); return FALSE; } @@ -2342,16 +2357,46 @@ channel_is_open(channel_T *channel) || channel->CH_ERR_FD != INVALID_FD); } +/* + * Return TRUE if "channel" has JSON or other typeahead. + */ + static int +channel_has_readahead(channel_T *channel, int part) +{ + ch_mode_T ch_mode = channel->ch_part[part].ch_mode; + + if (ch_mode == MODE_JSON || ch_mode == MODE_JS) + { + jsonq_T *head = &channel->ch_part[part].ch_json_head; + jsonq_T *item = head->jq_next; + + return item != NULL; + } + return channel_peek(channel, part) != NULL; +} + /* * Return a string indicating the status of the channel. */ char * channel_status(channel_T *channel) { + int part; + int has_readahead = FALSE; + if (channel == NULL) return "fail"; if (channel_is_open(channel)) return "open"; + for (part = PART_SOCK; part <= PART_ERR; ++part) + if (channel_has_readahead(channel, part)) + { + has_readahead = TRUE; + break; + } + + if (has_readahead) + return "buffered"; return "closed"; } @@ -2446,18 +2491,28 @@ channel_close(channel_T *channel, int invoke_close_cb) typval_T argv[1]; typval_T rettv; int dummy; + int part; - /* invoke the close callback; increment the refcount to avoid it - * being freed halfway */ - ch_logs(channel, "Invoking close callback %s", - (char *)channel->ch_close_cb); - argv[0].v_type = VAR_CHANNEL; - argv[0].vval.v_channel = channel; + /* Invoke callbacks before the close callback, since it's weird to + * first invoke the close callback. Increment the refcount to avoid + * the channel being freed halfway. */ ++channel->ch_refcount; - call_func(channel->ch_close_cb, (int)STRLEN(channel->ch_close_cb), + for (part = PART_SOCK; part <= PART_ERR; ++part) + while (may_invoke_callback(channel, part)) + ; + + /* Invoke the close callback, if still set. */ + if (channel->ch_close_cb != NULL) + { + ch_logs(channel, "Invoking close callback %s", + (char *)channel->ch_close_cb); + argv[0].v_type = VAR_CHANNEL; + argv[0].vval.v_channel = channel; + call_func(channel->ch_close_cb, (int)STRLEN(channel->ch_close_cb), &rettv, 1, argv, 0L, 0L, &dummy, TRUE, channel->ch_close_partial, NULL); - clear_tv(&rettv); + clear_tv(&rettv); + } --channel->ch_refcount; /* the callback is only called once */ @@ -2465,6 +2520,10 @@ channel_close(channel_T *channel, int invoke_close_cb) channel->ch_close_cb = NULL; partial_unref(channel->ch_close_partial); channel->ch_close_partial = NULL; + + /* any remaining messages are useless now */ + for (part = PART_SOCK; part <= PART_ERR; ++part) + drop_messages(channel, part); } channel->ch_nb_close_cb = NULL; @@ -2611,11 +2670,19 @@ channel_fill_poll_write(int nfd_in, struct pollfd *fds) } #endif +typedef enum { + CW_READY, + CW_NOT_READY, + CW_ERROR +} channel_wait_result; + /* * Check for reading from "fd" with "timeout" msec. - * Return FAIL when there is nothing to read. + * Return CW_READY when there is something to read. + * Return CW_NOT_READY when there is nothing to read. + * Return CW_ERROR when there is an error. */ - static int + static channel_wait_result channel_wait(channel_T *channel, sock_T fd, int timeout) { if (timeout > 0) @@ -2632,9 +2699,12 @@ channel_wait(channel_T *channel, sock_T fd, int timeout) /* reading from a pipe, not a socket */ while (TRUE) { - if (PeekNamedPipe((HANDLE)fd, NULL, 0, NULL, &nread, NULL) - && nread > 0) - return OK; + int r = PeekNamedPipe((HANDLE)fd, NULL, 0, NULL, &nread, NULL); + + if (r && nread > 0) + return CW_READY; + if (r == 0) + return CW_ERROR; /* perhaps write some buffer lines */ channel_write_any_lines(); @@ -2684,7 +2754,7 @@ channel_wait(channel_T *channel, sock_T fd, int timeout) if (ret > 0) { if (FD_ISSET(fd, &rfds)) - return OK; + return CW_READY; channel_write_any_lines(); continue; } @@ -2702,7 +2772,7 @@ channel_wait(channel_T *channel, sock_T fd, int timeout) if (poll(fds, nfd, timeout) > 0) { if (fds[0].revents & POLLIN) - return OK; + return CW_READY; channel_write_any_lines(); continue; } @@ -2710,7 +2780,36 @@ channel_wait(channel_T *channel, sock_T fd, int timeout) } #endif } - return FAIL; + return CW_NOT_READY; +} + + static void +channel_close_on_error(channel_T *channel, int part, char *func) +{ + /* Do not call emsg(), most likely the other end just exited. */ + ch_errors(channel, "%s(): Cannot read from channel", func); + + /* Queue a "DETACH" netbeans message in the command queue in order to + * terminate the netbeans session later. Do not end the session here + * directly as we may be running in the context of a call to + * netbeans_parse_messages(): + * netbeans_parse_messages + * -> autocmd triggered while processing the netbeans cmd + * -> ui_breakcheck + * -> gui event loop or select loop + * -> channel_read() + * Don't send "DETACH" for a JS or JSON channel. + */ + if (channel->ch_part[part].ch_mode == MODE_RAW + || channel->ch_part[part].ch_mode == MODE_NL) + channel_save(channel, part, (char_u *)DETACH_MSG_RAW, + (int)STRLEN(DETACH_MSG_RAW), FALSE, "PUT "); + + /* When reading from stdout is not possible, assume the other side has + * died. */ + channel_close(channel, TRUE); + if (channel->ch_nb_close_cb != NULL) + (*channel->ch_nb_close_cb)(); } /* @@ -2718,7 +2817,7 @@ channel_wait(channel_T *channel, sock_T fd, int timeout) * "part" is PART_SOCK, PART_OUT or PART_ERR. * The data is put in the read queue. */ - void + static void channel_read(channel_T *channel, int part, char *func) { static char_u *buf = NULL; @@ -2748,7 +2847,7 @@ channel_read(channel_T *channel, int part, char *func) * MAXMSGSIZE long. */ for (;;) { - if (channel_wait(channel, fd, 0) == FAIL) + if (channel_wait(channel, fd, 0) != CW_READY) break; if (use_socket) len = sock_read(fd, (char *)buf, MAXMSGSIZE); @@ -2766,33 +2865,7 @@ channel_read(channel_T *channel, int part, char *func) /* Reading a disconnection (readlen == 0), or an error. */ if (readlen <= 0) - { - /* Do not give an error message, most likely the other end just - * exited. */ - ch_errors(channel, "%s(): Cannot read from channel", func); - - /* Queue a "DETACH" netbeans message in the command queue in order to - * terminate the netbeans session later. Do not end the session here - * directly as we may be running in the context of a call to - * netbeans_parse_messages(): - * netbeans_parse_messages - * -> autocmd triggered while processing the netbeans cmd - * -> ui_breakcheck - * -> gui event loop or select loop - * -> channel_read() - * Don't send "DETACH" for a JS or JSON channel. - */ - if (channel->ch_part[part].ch_mode == MODE_RAW - || channel->ch_part[part].ch_mode == MODE_NL) - channel_save(channel, part, (char_u *)DETACH_MSG_RAW, - (int)STRLEN(DETACH_MSG_RAW), FALSE, "PUT "); - - /* When reading from stdout is not possible, assume the other side has - * died. */ - channel_close(channel, TRUE); - if (channel->ch_nb_close_cb != NULL) - (*channel->ch_nb_close_cb)(); - } + channel_close_on_error(channel, part, func); #if defined(CH_HAS_GUI) && defined(FEAT_GUI_GTK) /* signal the main loop that there is something to read */ @@ -2831,7 +2904,7 @@ channel_read_block(channel_T *channel, int part, int timeout) /* Wait for up to the channel timeout. */ if (fd == INVALID_FD) return NULL; - if (channel_wait(channel, fd, timeout) == FAIL) + if (channel_wait(channel, fd, timeout) != CW_READY) { ch_log(channel, "Timed out"); return NULL; @@ -2935,7 +3008,8 @@ channel_read_json_block( timeout = timeout_arg; } fd = chanpart->ch_fd; - if (fd == INVALID_FD || channel_wait(channel, fd, timeout) == FAIL) + if (fd == INVALID_FD + || channel_wait(channel, fd, timeout) != CW_READY) { if (timeout == timeout_arg) { @@ -2959,7 +3033,7 @@ channel_read_json_block( common_channel_read(typval_T *argvars, typval_T *rettv, int raw) { channel_T *channel; - int part; + int part = -1; jobopt_T opt; int mode; int timeout; @@ -2975,12 +3049,12 @@ common_channel_read(typval_T *argvars, typval_T *rettv, int raw) == FAIL) goto theend; - channel = get_channel_arg(&argvars[0], TRUE); + if (opt.jo_set & JO_PART) + part = opt.jo_part; + channel = get_channel_arg(&argvars[0], TRUE, TRUE, part); if (channel != NULL) { - if (opt.jo_set & JO_PART) - part = opt.jo_part; - else + if (part < 0) part = channel_part_read(channel); mode = channel_get_mode(channel, part); timeout = channel_get_timeout(channel, part); @@ -3056,8 +3130,16 @@ channel_handle_events(void) for (part = PART_SOCK; part <= PART_ERR; ++part) { fd = channel->ch_part[part].ch_fd; - if (fd != INVALID_FD && channel_wait(channel, fd, 0) == OK) - channel_read(channel, part, "channel_handle_events"); + if (fd != INVALID_FD) + { + int r = channel_wait(channel, fd, 0); + + if (r == CW_READY) + channel_read(channel, part, "channel_handle_events"); + else if (r == CW_ERROR) + channel_close_on_error(channel, part, + "channel_handle_events()"); + } } } } @@ -3136,7 +3218,7 @@ send_common( int part_send; clear_job_options(opt); - channel = get_channel_arg(&argvars[0], TRUE); + channel = get_channel_arg(&argvars[0], TRUE, FALSE, 0); if (channel == NULL) return NULL; part_send = channel_part_send(channel); @@ -3185,7 +3267,7 @@ ch_expr_common(typval_T *argvars, typval_T *rettv, int eval) rettv->v_type = VAR_STRING; rettv->vval.v_string = NULL; - channel = get_channel_arg(&argvars[0], TRUE); + channel = get_channel_arg(&argvars[0], TRUE, FALSE, 0); if (channel == NULL) return; part_send = channel_part_send(channel); @@ -3418,24 +3500,6 @@ channel_select_check(int ret_in, void *rfds_in, void *wfds_in) } # endif /* !WIN32 && HAVE_SELECT */ -/* - * Return TRUE if "channel" has JSON or other typeahead. - */ - static int -channel_has_readahead(channel_T *channel, int part) -{ - ch_mode_T ch_mode = channel->ch_part[part].ch_mode; - - if (ch_mode == MODE_JSON || ch_mode == MODE_JS) - { - jsonq_T *head = &channel->ch_part[part].ch_json_head; - jsonq_T *item = head->jq_next; - - return item != NULL; - } - return channel_peek(channel, part) != NULL; -} - /* * Execute queued up commands. * Invoked from the main loop when it's safe to execute received commands. @@ -3952,11 +4016,15 @@ get_job_options(typval_T *tv, jobopt_T *opt, int supported) /* * Get the channel from the argument. * Returns NULL if the handle is invalid. + * When "check_open" is TRUE check that the channel can be used. + * When "reading" is TRUE "check_open" considers typeahead useful. + * "part" is used to check typeahead, when -1 use the default part. */ channel_T * -get_channel_arg(typval_T *tv, int check_open) +get_channel_arg(typval_T *tv, int check_open, int reading, int part) { - channel_T *channel = NULL; + channel_T *channel = NULL; + int has_readahead = FALSE; if (tv->v_type == VAR_JOB) { @@ -3972,8 +4040,12 @@ get_channel_arg(typval_T *tv, int check_open) EMSG2(_(e_invarg2), get_tv_string(tv)); return NULL; } + if (channel != NULL && reading) + has_readahead = channel_has_readahead(channel, + part >= 0 ? part : channel_part_read(channel)); - if (check_open && (channel == NULL || !channel_is_open(channel))) + if (check_open && (channel == NULL || (!channel_is_open(channel) + && !(reading && has_readahead)))) { EMSG(_("E906: not an open channel")); return NULL; @@ -4028,13 +4100,16 @@ job_free(job_T *job) /* * Return TRUE if the job should not be freed yet. Do not free the job when - * it has not ended yet and there is a "stoponexit" flag or an exit callback. + * it has not ended yet and there is a "stoponexit" flag, an exit callback + * or when the associated channel will do something with the job output. */ static int job_still_useful(job_T *job) { return job->jv_status == JOB_STARTED - && (job->jv_stoponexit != NULL || job->jv_exit_cb != NULL); + && (job->jv_stoponexit != NULL || job->jv_exit_cb != NULL + || (job->jv_channel != NULL + && channel_still_useful(job->jv_channel))); } void @@ -4048,10 +4123,12 @@ job_unref(job_T *job) { job_free(job); } - else if (job->jv_channel != NULL) + else if (job->jv_channel != NULL + && !channel_still_useful(job->jv_channel)) { /* Do remove the link to the channel, otherwise it hangs * around until Vim exits. See job_free() for refcount. */ + ch_log(job->jv_channel, "detaching channel from job"); job->jv_channel->ch_job = NULL; channel_unref(job->jv_channel); job->jv_channel = NULL; diff --git a/src/eval.c b/src/eval.c index 3953f9d3b9..b264c58898 100644 --- a/src/eval.c +++ b/src/eval.c @@ -10305,7 +10305,7 @@ f_ceil(typval_T *argvars, typval_T *rettv) static void f_ch_close(typval_T *argvars, typval_T *rettv UNUSED) { - channel_T *channel = get_channel_arg(&argvars[0], TRUE); + channel_T *channel = get_channel_arg(&argvars[0], TRUE, FALSE, 0); if (channel != NULL) { @@ -10320,7 +10320,7 @@ f_ch_close(typval_T *argvars, typval_T *rettv UNUSED) static void f_ch_getbufnr(typval_T *argvars, typval_T *rettv) { - channel_T *channel = get_channel_arg(&argvars[0], TRUE); + channel_T *channel = get_channel_arg(&argvars[0], FALSE, FALSE, 0); rettv->vval.v_number = -1; if (channel != NULL) @@ -10347,7 +10347,7 @@ f_ch_getbufnr(typval_T *argvars, typval_T *rettv) static void f_ch_getjob(typval_T *argvars, typval_T *rettv) { - channel_T *channel = get_channel_arg(&argvars[0], TRUE); + channel_T *channel = get_channel_arg(&argvars[0], FALSE, FALSE, 0); if (channel != NULL) { @@ -10364,7 +10364,7 @@ f_ch_getjob(typval_T *argvars, typval_T *rettv) static void f_ch_info(typval_T *argvars, typval_T *rettv UNUSED) { - channel_T *channel = get_channel_arg(&argvars[0], TRUE); + channel_T *channel = get_channel_arg(&argvars[0], FALSE, FALSE, 0); if (channel != NULL && rettv_dict_alloc(rettv) != FAIL) channel_info(channel, rettv->vval.v_dict); @@ -10380,7 +10380,7 @@ f_ch_log(typval_T *argvars, typval_T *rettv UNUSED) channel_T *channel = NULL; if (argvars[1].v_type != VAR_UNKNOWN) - channel = get_channel_arg(&argvars[1], TRUE); + channel = get_channel_arg(&argvars[1], FALSE, FALSE, 0); ch_log(channel, (char *)msg); } @@ -10476,7 +10476,7 @@ f_ch_setoptions(typval_T *argvars, typval_T *rettv UNUSED) channel_T *channel; jobopt_T opt; - channel = get_channel_arg(&argvars[0], TRUE); + channel = get_channel_arg(&argvars[0], FALSE, FALSE, 0); if (channel == NULL) return; clear_job_options(&opt); @@ -10498,7 +10498,7 @@ f_ch_status(typval_T *argvars, typval_T *rettv) rettv->v_type = VAR_STRING; rettv->vval.v_string = NULL; - channel = get_channel_arg(&argvars[0], FALSE); + channel = get_channel_arg(&argvars[0], FALSE, FALSE, 0); rettv->vval.v_string = vim_strsave((char_u *)channel_status(channel)); } #endif diff --git a/src/gui_mac.c b/src/gui_mac.c index c87456e1f6..b3f76af700 100644 --- a/src/gui_mac.c +++ b/src/gui_mac.c @@ -3705,17 +3705,6 @@ gui_mch_free_font(GuiFont font) */ } - static int -hex_digit(int c) -{ - if (isdigit(c)) - return c - '0'; - c = TOLOWER_ASC(c); - if (c >= 'a' && c <= 'f') - return c - 'a' + 10; - return -1000; -} - /* * Return the Pixel value (color) for the given color name. This routine was * pretty much taken from example code in the Silicon Graphics OSF/Motif @@ -3728,146 +3717,13 @@ gui_mch_get_color(char_u *name) /* TODO: Add support for the new named color of MacOS 8 */ RGBColor MacColor; -// guicolor_T color = 0; - typedef struct guicolor_tTable + if (STRICMP(name, "hilite") == 0) { - char *name; - guicolor_T color; - } guicolor_tTable; - - /* - * The comment at the end of each line is the source - * (Mac, Window, Unix) and the number is the unix rgb.txt value - */ - static guicolor_tTable table[] = - { - {"Black", RGB(0x00, 0x00, 0x00)}, - {"darkgray", RGB(0x80, 0x80, 0x80)}, /*W*/ - {"darkgrey", RGB(0x80, 0x80, 0x80)}, /*W*/ - {"Gray", RGB(0xC0, 0xC0, 0xC0)}, /*W*/ - {"Grey", RGB(0xC0, 0xC0, 0xC0)}, /*W*/ - {"lightgray", RGB(0xE0, 0xE0, 0xE0)}, /*W*/ - {"lightgrey", RGB(0xE0, 0xE0, 0xE0)}, /*W*/ - {"gray10", RGB(0x1A, 0x1A, 0x1A)}, /*W*/ - {"grey10", RGB(0x1A, 0x1A, 0x1A)}, /*W*/ - {"gray20", RGB(0x33, 0x33, 0x33)}, /*W*/ - {"grey20", RGB(0x33, 0x33, 0x33)}, /*W*/ - {"gray30", RGB(0x4D, 0x4D, 0x4D)}, /*W*/ - {"grey30", RGB(0x4D, 0x4D, 0x4D)}, /*W*/ - {"gray40", RGB(0x66, 0x66, 0x66)}, /*W*/ - {"grey40", RGB(0x66, 0x66, 0x66)}, /*W*/ - {"gray50", RGB(0x7F, 0x7F, 0x7F)}, /*W*/ - {"grey50", RGB(0x7F, 0x7F, 0x7F)}, /*W*/ - {"gray60", RGB(0x99, 0x99, 0x99)}, /*W*/ - {"grey60", RGB(0x99, 0x99, 0x99)}, /*W*/ - {"gray70", RGB(0xB3, 0xB3, 0xB3)}, /*W*/ - {"grey70", RGB(0xB3, 0xB3, 0xB3)}, /*W*/ - {"gray80", RGB(0xCC, 0xCC, 0xCC)}, /*W*/ - {"grey80", RGB(0xCC, 0xCC, 0xCC)}, /*W*/ - {"gray90", RGB(0xE5, 0xE5, 0xE5)}, /*W*/ - {"grey90", RGB(0xE5, 0xE5, 0xE5)}, /*W*/ - {"white", RGB(0xFF, 0xFF, 0xFF)}, - {"darkred", RGB(0x80, 0x00, 0x00)}, /*W*/ - {"red", RGB(0xDD, 0x08, 0x06)}, /*M*/ - {"lightred", RGB(0xFF, 0xA0, 0xA0)}, /*W*/ - {"DarkBlue", RGB(0x00, 0x00, 0x80)}, /*W*/ - {"Blue", RGB(0x00, 0x00, 0xD4)}, /*M*/ - {"lightblue", RGB(0xA0, 0xA0, 0xFF)}, /*W*/ - {"DarkGreen", RGB(0x00, 0x80, 0x00)}, /*W*/ - {"Green", RGB(0x00, 0x64, 0x11)}, /*M*/ - {"lightgreen", RGB(0xA0, 0xFF, 0xA0)}, /*W*/ - {"DarkCyan", RGB(0x00, 0x80, 0x80)}, /*W ?0x307D7E */ - {"cyan", RGB(0x02, 0xAB, 0xEA)}, /*M*/ - {"lightcyan", RGB(0xA0, 0xFF, 0xFF)}, /*W*/ - {"darkmagenta", RGB(0x80, 0x00, 0x80)}, /*W*/ - {"magenta", RGB(0xF2, 0x08, 0x84)}, /*M*/ - {"lightmagenta",RGB(0xF0, 0xA0, 0xF0)}, /*W*/ - {"brown", RGB(0x80, 0x40, 0x40)}, /*W*/ - {"yellow", RGB(0xFC, 0xF3, 0x05)}, /*M*/ - {"lightyellow", RGB(0xFF, 0xFF, 0xA0)}, /*M*/ - {"darkyellow", RGB(0xBB, 0xBB, 0x00)}, /*U*/ - {"SeaGreen", RGB(0x2E, 0x8B, 0x57)}, /*W 0x4E8975 */ - {"orange", RGB(0xFC, 0x80, 0x00)}, /*W 0xF87A17 */ - {"Purple", RGB(0xA0, 0x20, 0xF0)}, /*W 0x8e35e5 */ - {"SlateBlue", RGB(0x6A, 0x5A, 0xCD)}, /*W 0x737CA1 */ - {"Violet", RGB(0x8D, 0x38, 0xC9)}, /*U*/ - }; - - int r, g, b; - int i; - - if (name[0] == '#' && strlen((char *) name) == 7) - { - /* Name is in "#rrggbb" format */ - r = hex_digit(name[1]) * 16 + hex_digit(name[2]); - g = hex_digit(name[3]) * 16 + hex_digit(name[4]); - b = hex_digit(name[5]) * 16 + hex_digit(name[6]); - if (r < 0 || g < 0 || b < 0) - return INVALCOLOR; - return RGB(r, g, b); + LMGetHiliteRGB(&MacColor); + return (RGB(MacColor.red >> 8, MacColor.green >> 8, MacColor.blue >> 8)); } - else - { - if (STRICMP(name, "hilite") == 0) - { - LMGetHiliteRGB(&MacColor); - return (RGB(MacColor.red >> 8, MacColor.green >> 8, MacColor.blue >> 8)); - } - /* Check if the name is one of the colors we know */ - for (i = 0; i < sizeof(table) / sizeof(table[0]); i++) - if (STRICMP(name, table[i].name) == 0) - return table[i].color; - } - - /* - * Last attempt. Look in the file "$VIM/rgb.txt". - */ - { -#define LINE_LEN 100 - FILE *fd; - char line[LINE_LEN]; - char_u *fname; - - fname = expand_env_save((char_u *)"$VIMRUNTIME/rgb.txt"); - if (fname == NULL) - return INVALCOLOR; - - fd = fopen((char *)fname, "rt"); - vim_free(fname); - if (fd == NULL) - return INVALCOLOR; - - while (!feof(fd)) - { - int len; - int pos; - char *color; - - fgets(line, LINE_LEN, fd); - len = strlen(line); - - if (len <= 1 || line[len-1] != '\n') - continue; - - line[len-1] = '\0'; - - i = sscanf(line, "%d %d %d %n", &r, &g, &b, &pos); - if (i != 3) - continue; - - color = line + pos; - - if (STRICMP(color, name) == 0) - { - fclose(fd); - return (guicolor_T) RGB(r, g, b); - } - } - fclose(fd); - } - - return INVALCOLOR; + return gui_get_color_cmn(name); } /* diff --git a/src/gui_photon.c b/src/gui_photon.c index 67ddc628a3..956c8e2060 100644 --- a/src/gui_photon.c +++ b/src/gui_photon.c @@ -1971,18 +1971,6 @@ gui_mch_new_colors(void) PtSetResource(gui.vimTextArea, Pt_ARG_FILL_COLOR, gui.back_pixel, 0); } - static int -hex_digit(int c) -{ - if (VIM_ISDIGIT(c)) - return c - '0'; - c = TOLOWER_ASC(c); - if (c >= 'a' && c <= 'f') - return c - 'a' + 10; - return -1000; -} - - /* * This should be split out into a separate file, * every port does basically the same thing. @@ -1994,136 +1982,7 @@ hex_digit(int c) guicolor_T gui_mch_get_color(char_u *name) { - int i; - int r, g, b; - - - typedef struct GuiColourTable - { - char *name; - guicolor_T colour; - } GuiColourTable; - - static GuiColourTable table[] = - { - {"Black", RGB(0x00, 0x00, 0x00)}, - {"DarkGray", RGB(0xA9, 0xA9, 0xA9)}, - {"DarkGrey", RGB(0xA9, 0xA9, 0xA9)}, - {"Gray", RGB(0xC0, 0xC0, 0xC0)}, - {"Grey", RGB(0xC0, 0xC0, 0xC0)}, - {"LightGray", RGB(0xD3, 0xD3, 0xD3)}, - {"LightGrey", RGB(0xD3, 0xD3, 0xD3)}, - {"Gray10", RGB(0x1A, 0x1A, 0x1A)}, - {"Grey10", RGB(0x1A, 0x1A, 0x1A)}, - {"Gray20", RGB(0x33, 0x33, 0x33)}, - {"Grey20", RGB(0x33, 0x33, 0x33)}, - {"Gray30", RGB(0x4D, 0x4D, 0x4D)}, - {"Grey30", RGB(0x4D, 0x4D, 0x4D)}, - {"Gray40", RGB(0x66, 0x66, 0x66)}, - {"Grey40", RGB(0x66, 0x66, 0x66)}, - {"Gray50", RGB(0x7F, 0x7F, 0x7F)}, - {"Grey50", RGB(0x7F, 0x7F, 0x7F)}, - {"Gray60", RGB(0x99, 0x99, 0x99)}, - {"Grey60", RGB(0x99, 0x99, 0x99)}, - {"Gray70", RGB(0xB3, 0xB3, 0xB3)}, - {"Grey70", RGB(0xB3, 0xB3, 0xB3)}, - {"Gray80", RGB(0xCC, 0xCC, 0xCC)}, - {"Grey80", RGB(0xCC, 0xCC, 0xCC)}, - {"Gray90", RGB(0xE5, 0xE5, 0xE5)}, - {"Grey90", RGB(0xE5, 0xE5, 0xE5)}, - {"White", RGB(0xFF, 0xFF, 0xFF)}, - {"DarkRed", RGB(0x80, 0x00, 0x00)}, - {"Red", RGB(0xFF, 0x00, 0x00)}, - {"LightRed", RGB(0xFF, 0xA0, 0xA0)}, - {"DarkBlue", RGB(0x00, 0x00, 0x80)}, - {"Blue", RGB(0x00, 0x00, 0xFF)}, - {"LightBlue", RGB(0xAD, 0xD8, 0xE6)}, - {"DarkGreen", RGB(0x00, 0x80, 0x00)}, - {"Green", RGB(0x00, 0xFF, 0x00)}, - {"LightGreen", RGB(0x90, 0xEE, 0x90)}, - {"DarkCyan", RGB(0x00, 0x80, 0x80)}, - {"Cyan", RGB(0x00, 0xFF, 0xFF)}, - {"LightCyan", RGB(0xE0, 0xFF, 0xFF)}, - {"DarkMagenta", RGB(0x80, 0x00, 0x80)}, - {"Magenta", RGB(0xFF, 0x00, 0xFF)}, - {"LightMagenta", RGB(0xFF, 0xA0, 0xFF)}, - {"Brown", RGB(0x80, 0x40, 0x40)}, - {"Yellow", RGB(0xFF, 0xFF, 0x00)}, - {"LightYellow", RGB(0xFF, 0xFF, 0xE0)}, - {"SeaGreen", RGB(0x2E, 0x8B, 0x57)}, - {"Orange", RGB(0xFF, 0xA5, 0x00)}, - {"Purple", RGB(0xA0, 0x20, 0xF0)}, - {"SlateBlue", RGB(0x6A, 0x5A, 0xCD)}, - {"Violet", RGB(0xEE, 0x82, 0xEE)}, - }; - - /* is name #rrggbb format? */ - if (name[0] == '#' && STRLEN(name) == 7) - { - r = hex_digit(name[1]) * 16 + hex_digit(name[2]); - g = hex_digit(name[3]) * 16 + hex_digit(name[4]); - b = hex_digit(name[5]) * 16 + hex_digit(name[6]); - if (r < 0 || g < 0 || b < 0) - return INVALCOLOR; - return RGB(r, g, b); - } - - for (i = 0; i < ARRAY_LENGTH(table); i++) - { - if (STRICMP(name, table[i].name) == 0) - return table[i].colour; - } - - /* - * Last attempt. Look in the file "$VIMRUNTIME/rgb.txt". - */ - { -#define LINE_LEN 100 - FILE *fd; - char line[LINE_LEN]; - char_u *fname; - - fname = expand_env_save((char_u *)"$VIMRUNTIME/rgb.txt"); - if (fname == NULL) - return INVALCOLOR; - - fd = fopen((char *)fname, "rt"); - vim_free(fname); - if (fd == NULL) - return INVALCOLOR; - - while (!feof(fd)) - { - int len; - int pos; - char *color; - - fgets(line, LINE_LEN, fd); - len = STRLEN(line); - - if (len <= 1 || line[len-1] != '\n') - continue; - - line[len-1] = '\0'; - - i = sscanf(line, "%d %d %d %n", &r, &g, &b, &pos); - if (i != 3) - continue; - - color = line + pos; - - if (STRICMP(color, name) == 0) - { - fclose(fd); - return (guicolor_T)RGB(r, g, b); - } - } - - fclose(fd); - } - - - return INVALCOLOR; + return gui_get_color_cmn(name); } void diff --git a/src/gui_w32.c b/src/gui_w32.c index 543d5d5a12..10c14c9d9c 100644 --- a/src/gui_w32.c +++ b/src/gui_w32.c @@ -1555,16 +1555,6 @@ gui_mch_free_font(GuiFont font) DeleteObject((HFONT)font); } - static int -hex_digit(int c) -{ - if (VIM_ISDIGIT(c)) - return c - '0'; - c = TOLOWER_ASC(c); - if (c >= 'a' && c <= 'f') - return c - 'a' + 10; - return -1000; -} /* * Return the Pixel value (color) for the given color name. * Return INVALCOLOR for error. @@ -1572,65 +1562,7 @@ hex_digit(int c) guicolor_T gui_mch_get_color(char_u *name) { - typedef struct guicolor_tTable - { - char *name; - COLORREF color; - } guicolor_tTable; - - static guicolor_tTable table[] = - { - {"Black", RGB(0x00, 0x00, 0x00)}, - {"DarkGray", RGB(0xA9, 0xA9, 0xA9)}, - {"DarkGrey", RGB(0xA9, 0xA9, 0xA9)}, - {"Gray", RGB(0xC0, 0xC0, 0xC0)}, - {"Grey", RGB(0xC0, 0xC0, 0xC0)}, - {"LightGray", RGB(0xD3, 0xD3, 0xD3)}, - {"LightGrey", RGB(0xD3, 0xD3, 0xD3)}, - {"Gray10", RGB(0x1A, 0x1A, 0x1A)}, - {"Grey10", RGB(0x1A, 0x1A, 0x1A)}, - {"Gray20", RGB(0x33, 0x33, 0x33)}, - {"Grey20", RGB(0x33, 0x33, 0x33)}, - {"Gray30", RGB(0x4D, 0x4D, 0x4D)}, - {"Grey30", RGB(0x4D, 0x4D, 0x4D)}, - {"Gray40", RGB(0x66, 0x66, 0x66)}, - {"Grey40", RGB(0x66, 0x66, 0x66)}, - {"Gray50", RGB(0x7F, 0x7F, 0x7F)}, - {"Grey50", RGB(0x7F, 0x7F, 0x7F)}, - {"Gray60", RGB(0x99, 0x99, 0x99)}, - {"Grey60", RGB(0x99, 0x99, 0x99)}, - {"Gray70", RGB(0xB3, 0xB3, 0xB3)}, - {"Grey70", RGB(0xB3, 0xB3, 0xB3)}, - {"Gray80", RGB(0xCC, 0xCC, 0xCC)}, - {"Grey80", RGB(0xCC, 0xCC, 0xCC)}, - {"Gray90", RGB(0xE5, 0xE5, 0xE5)}, - {"Grey90", RGB(0xE5, 0xE5, 0xE5)}, - {"White", RGB(0xFF, 0xFF, 0xFF)}, - {"DarkRed", RGB(0x80, 0x00, 0x00)}, - {"Red", RGB(0xFF, 0x00, 0x00)}, - {"LightRed", RGB(0xFF, 0xA0, 0xA0)}, - {"DarkBlue", RGB(0x00, 0x00, 0x80)}, - {"Blue", RGB(0x00, 0x00, 0xFF)}, - {"LightBlue", RGB(0xAD, 0xD8, 0xE6)}, - {"DarkGreen", RGB(0x00, 0x80, 0x00)}, - {"Green", RGB(0x00, 0xFF, 0x00)}, - {"LightGreen", RGB(0x90, 0xEE, 0x90)}, - {"DarkCyan", RGB(0x00, 0x80, 0x80)}, - {"Cyan", RGB(0x00, 0xFF, 0xFF)}, - {"LightCyan", RGB(0xE0, 0xFF, 0xFF)}, - {"DarkMagenta", RGB(0x80, 0x00, 0x80)}, - {"Magenta", RGB(0xFF, 0x00, 0xFF)}, - {"LightMagenta", RGB(0xFF, 0xA0, 0xFF)}, - {"Brown", RGB(0x80, 0x40, 0x40)}, - {"Yellow", RGB(0xFF, 0xFF, 0x00)}, - {"LightYellow", RGB(0xFF, 0xFF, 0xE0)}, - {"DarkYellow", RGB(0xBB, 0xBB, 0x00)}, - {"SeaGreen", RGB(0x2E, 0x8B, 0x57)}, - {"Orange", RGB(0xFF, 0xA5, 0x00)}, - {"Purple", RGB(0xA0, 0x20, 0xF0)}, - {"SlateBlue", RGB(0x6A, 0x5A, 0xCD)}, - {"Violet", RGB(0xEE, 0x82, 0xEE)}, - }; + int i; typedef struct SysColorTable { @@ -1677,27 +1609,6 @@ gui_mch_get_color(char_u *name) {"SYS_WINDOWTEXT", COLOR_WINDOWTEXT} }; - int r, g, b; - int i; - - if (name[0] == '#' && STRLEN(name) == 7) - { - /* Name is in "#rrggbb" format */ - r = hex_digit(name[1]) * 16 + hex_digit(name[2]); - g = hex_digit(name[3]) * 16 + hex_digit(name[4]); - b = hex_digit(name[5]) * 16 + hex_digit(name[6]); - if (r < 0 || g < 0 || b < 0) - return INVALCOLOR; - return RGB(r, g, b); - } - else - { - /* Check if the name is one of the colors we know */ - for (i = 0; i < sizeof(table) / sizeof(table[0]); i++) - if (STRICMP(name, table[i].name) == 0) - return table[i].color; - } - /* * Try to look up a system colour. */ @@ -1705,56 +1616,9 @@ gui_mch_get_color(char_u *name) if (STRICMP(name, sys_table[i].name) == 0) return GetSysColor(sys_table[i].color); - /* - * Last attempt. Look in the file "$VIMRUNTIME/rgb.txt". - */ - { -#define LINE_LEN 100 - FILE *fd; - char line[LINE_LEN]; - char_u *fname; - - fname = expand_env_save((char_u *)"$VIMRUNTIME/rgb.txt"); - if (fname == NULL) - return INVALCOLOR; - - fd = mch_fopen((char *)fname, "rt"); - vim_free(fname); - if (fd == NULL) - return INVALCOLOR; - - while (!feof(fd)) - { - int len; - int pos; - char *color; - - fgets(line, LINE_LEN, fd); - len = (int)STRLEN(line); - - if (len <= 1 || line[len-1] != '\n') - continue; - - line[len-1] = '\0'; - - i = sscanf(line, "%d %d %d %n", &r, &g, &b, &pos); - if (i != 3) - continue; - - color = line + pos; - - if (STRICMP(color, name) == 0) - { - fclose(fd); - return (guicolor_T) RGB(r, g, b); - } - } - - fclose(fd); - } - - return INVALCOLOR; + return gui_get_color_cmn(name); } + /* * Return OK if the key with the termcap name "name" is supported. */ diff --git a/src/os_unix.c b/src/os_unix.c index f2fb05e0e9..2836feebe4 100644 --- a/src/os_unix.c +++ b/src/os_unix.c @@ -3946,7 +3946,7 @@ mch_parse_cmd(char_u *cmd, int use_shcf, char ***argv, int *argc) */ for (i = 0; i < 2; ++i) { - p = cmd; + p = skipwhite(cmd); inquote = FALSE; *argc = 0; for (;;) diff --git a/src/proto/channel.pro b/src/proto/channel.pro index d5114cba42..d14337dc68 100644 --- a/src/proto/channel.pro +++ b/src/proto/channel.pro @@ -26,7 +26,6 @@ void channel_close(channel_T *channel, int invoke_close_cb); char_u *channel_peek(channel_T *channel, int part); void channel_clear(channel_T *channel); void channel_free_all(void); -void channel_read(channel_T *channel, int part, char *func); char_u *channel_read_block(channel_T *channel, int part, int timeout); int channel_read_json_block(channel_T *channel, int part, int timeout_arg, int id, typval_T **rettv); void common_channel_read(typval_T *argvars, typval_T *rettv, int raw); @@ -49,7 +48,7 @@ int channel_get_timeout(channel_T *channel, int part); void clear_job_options(jobopt_T *opt); void free_job_options(jobopt_T *opt); int get_job_options(typval_T *tv, jobopt_T *opt, int supported); -channel_T *get_channel_arg(typval_T *tv, int check_open); +channel_T *get_channel_arg(typval_T *tv, int check_open, int reading, int part); void job_unref(job_T *job); int free_unused_jobs_contents(int copyID, int mask); void free_unused_jobs(int copyID, int mask); diff --git a/src/proto/term.pro b/src/proto/term.pro index cd2ca26d38..3984515446 100644 --- a/src/proto/term.pro +++ b/src/proto/term.pro @@ -65,4 +65,5 @@ void show_termcodes(void); int show_one_termcode(char_u *name, char_u *code, int printit); char_u *translate_mapping(char_u *str, int expmap); void update_tcap(int attr); +guicolor_T gui_get_color_cmn(char_u *name); /* vim: set ft=c : */ diff --git a/src/regexp.c b/src/regexp.c index 733d564253..5f1fc1c150 100644 --- a/src/regexp.c +++ b/src/regexp.c @@ -2542,12 +2542,12 @@ collection: } break; case CLASS_ALNUM: - for (cu = 1; cu <= 255; cu++) + for (cu = 1; cu < 128; cu++) if (isalnum(cu)) regmbc(cu); break; case CLASS_ALPHA: - for (cu = 1; cu <= 255; cu++) + for (cu = 1; cu < 128; cu++) if (isalpha(cu)) regmbc(cu); break; @@ -2572,7 +2572,8 @@ collection: break; case CLASS_LOWER: for (cu = 1; cu <= 255; cu++) - if (MB_ISLOWER(cu)) + if (MB_ISLOWER(cu) && cu != 170 + && cu != 186) regmbc(cu); break; case CLASS_PRINT: @@ -2581,7 +2582,7 @@ collection: regmbc(cu); break; case CLASS_PUNCT: - for (cu = 1; cu <= 255; cu++) + for (cu = 1; cu < 128; cu++) if (ispunct(cu)) regmbc(cu); break; diff --git a/src/regexp_nfa.c b/src/regexp_nfa.c index 5e073eeeba..4ca29f2440 100644 --- a/src/regexp_nfa.c +++ b/src/regexp_nfa.c @@ -4837,11 +4837,11 @@ check_char_class(int class, int c) switch (class) { case NFA_CLASS_ALNUM: - if (c >= 1 && c <= 255 && isalnum(c)) + if (c >= 1 && c < 128 && isalnum(c)) return OK; break; case NFA_CLASS_ALPHA: - if (c >= 1 && c <= 255 && isalpha(c)) + if (c >= 1 && c < 128 && isalpha(c)) return OK; break; case NFA_CLASS_BLANK: @@ -4861,7 +4861,7 @@ check_char_class(int class, int c) return OK; break; case NFA_CLASS_LOWER: - if (MB_ISLOWER(c)) + if (MB_ISLOWER(c) && c != 170 && c != 186) return OK; break; case NFA_CLASS_PRINT: @@ -4869,7 +4869,7 @@ check_char_class(int class, int c) return OK; break; case NFA_CLASS_PUNCT: - if (c >= 1 && c <= 255 && ispunct(c)) + if (c >= 1 && c < 128 && ispunct(c)) return OK; break; case NFA_CLASS_SPACE: diff --git a/src/term.c b/src/term.c index f66236725a..fca83333ee 100644 --- a/src/term.c +++ b/src/term.c @@ -1266,145 +1266,10 @@ static struct builtin_term builtin_termcaps[] = }; /* end of builtin_termcaps */ #if defined(FEAT_TERMTRUECOLOR) || defined(PROTO) -# define RGB(r, g, b) ((r<<16) | (g<<8) | (b)) -struct rgbcolor_table_S { - char_u *color_name; - guicolor_T color; -}; - -static struct rgbcolor_table_S rgb_table[] = { - {(char_u *)"black", RGB(0x00, 0x00, 0x00)}, - {(char_u *)"blue", RGB(0x00, 0x00, 0xFF)}, - {(char_u *)"brown", RGB(0xA5, 0x2A, 0x2A)}, - {(char_u *)"cyan", RGB(0x00, 0xFF, 0xFF)}, - {(char_u *)"darkblue", RGB(0x00, 0x00, 0x8B)}, - {(char_u *)"darkcyan", RGB(0x00, 0x8B, 0x8B)}, - {(char_u *)"darkgray", RGB(0xA9, 0xA9, 0xA9)}, - {(char_u *)"darkgreen", RGB(0x00, 0x64, 0x00)}, - {(char_u *)"darkgrey", RGB(0xA9, 0xA9, 0xA9)}, - {(char_u *)"darkmagenta", RGB(0x8B, 0x00, 0x8B)}, - {(char_u *)"darkred", RGB(0x8B, 0x00, 0x00)}, - {(char_u *)"darkyellow", RGB(0x8B, 0x8B, 0x00)}, /* No X11 */ - {(char_u *)"gray", RGB(0xBE, 0xBE, 0xBE)}, - {(char_u *)"gray10", RGB(0x1A, 0x1A, 0x1A)}, - {(char_u *)"gray20", RGB(0x33, 0x33, 0x33)}, - {(char_u *)"gray30", RGB(0x4D, 0x4D, 0x4D)}, - {(char_u *)"gray40", RGB(0x66, 0x66, 0x66)}, - {(char_u *)"gray50", RGB(0x7F, 0x7F, 0x7F)}, - {(char_u *)"gray60", RGB(0x99, 0x99, 0x99)}, - {(char_u *)"gray70", RGB(0xB3, 0xB3, 0xB3)}, - {(char_u *)"gray80", RGB(0xCC, 0xCC, 0xCC)}, - {(char_u *)"gray90", RGB(0xE5, 0xE5, 0xE5)}, - {(char_u *)"green", RGB(0x00, 0xFF, 0x00)}, - {(char_u *)"grey", RGB(0xBE, 0xBE, 0xBE)}, - {(char_u *)"grey10", RGB(0x1A, 0x1A, 0x1A)}, - {(char_u *)"grey20", RGB(0x33, 0x33, 0x33)}, - {(char_u *)"grey30", RGB(0x4D, 0x4D, 0x4D)}, - {(char_u *)"grey40", RGB(0x66, 0x66, 0x66)}, - {(char_u *)"grey50", RGB(0x7F, 0x7F, 0x7F)}, - {(char_u *)"grey60", RGB(0x99, 0x99, 0x99)}, - {(char_u *)"grey70", RGB(0xB3, 0xB3, 0xB3)}, - {(char_u *)"grey80", RGB(0xCC, 0xCC, 0xCC)}, - {(char_u *)"grey90", RGB(0xE5, 0xE5, 0xE5)}, - {(char_u *)"lightblue", RGB(0xAD, 0xD8, 0xE6)}, - {(char_u *)"lightcyan", RGB(0xE0, 0xFF, 0xFF)}, - {(char_u *)"lightgray", RGB(0xD3, 0xD3, 0xD3)}, - {(char_u *)"lightgreen", RGB(0x90, 0xEE, 0x90)}, - {(char_u *)"lightgrey", RGB(0xD3, 0xD3, 0xD3)}, - {(char_u *)"lightmagenta", RGB(0xFF, 0x8B, 0xFF)}, /* No X11 */ - {(char_u *)"lightred", RGB(0xFF, 0x8B, 0x8B)}, /* No X11 */ - {(char_u *)"lightyellow", RGB(0xFF, 0xFF, 0xE0)}, - {(char_u *)"magenta", RGB(0xFF, 0x00, 0xFF)}, - {(char_u *)"orange", RGB(0xFF, 0xA5, 0x00)}, - {(char_u *)"purple", RGB(0xA0, 0x20, 0xF0)}, - {(char_u *)"red", RGB(0xFF, 0x00, 0x00)}, - {(char_u *)"seagreen", RGB(0x2E, 0x8B, 0x57)}, - {(char_u *)"slateblue", RGB(0x6A, 0x5A, 0xCD)}, - {(char_u *)"violet", RGB(0xEE, 0x82, 0xEE)}, - {(char_u *)"white", RGB(0xFF, 0xFF, 0xFF)}, - {(char_u *)"yellow", RGB(0xFF, 0xFF, 0x00)}, -}; - - static int -hex_digit(int c) -{ - if (isdigit(c)) - return c - '0'; - c = TOLOWER_ASC(c); - if (c >= 'a' && c <= 'f') - return c - 'a' + 10; - return 0x1ffffff; -} - guicolor_T termtrue_mch_get_color(char_u *name) { - guicolor_T color; - int i; - - if (*name == '#' && strlen((char *) name) == 7) - { - color = RGB(((hex_digit(name[1])<<4) + hex_digit(name[2])), - ((hex_digit(name[3])<<4) + hex_digit(name[4])), - ((hex_digit(name[5])<<4) + hex_digit(name[6]))); - if (color > 0xffffff) - return INVALCOLOR; - return color; - } - else - { - /* Check if the name is one of the colors we know */ - for (i = 0; i < (int)(sizeof(rgb_table) / sizeof(rgb_table[0])); i++) - if (STRICMP(name, rgb_table[i].color_name) == 0) - return rgb_table[i].color; - } - - /* - * Last attempt. Look in the file "$VIM/rgb.txt". - */ - { -#define LINE_LEN 100 - FILE *fd; - char line[LINE_LEN]; - char_u *fname; - int r, g, b; - - fname = expand_env_save((char_u *)"$VIMRUNTIME/rgb.txt"); - if (fname == NULL) - return INVALCOLOR; - - fd = fopen((char *)fname, "rt"); - vim_free(fname); - if (fd == NULL) - return INVALCOLOR; - - while (!feof(fd)) - { - int len; - int pos; - - (void)fgets(line, LINE_LEN, fd); - len = strlen(line); - - if (len <= 1 || line[len-1] != '\n') - continue; - - line[len-1] = '\0'; - - i = sscanf(line, "%d %d %d %n", &r, &g, &b, &pos); - if (i != 3) - continue; - - if (STRICMP(line + pos, name) == 0) - { - fclose(fd); - return (guicolor_T) RGB(r, g, b); - } - } - fclose(fd); - } - - return INVALCOLOR; + return gui_get_color_cmn(name); } guicolor_T @@ -6187,3 +6052,146 @@ update_tcap(int attr) } } #endif + +#if defined(FEAT_GUI) || defined(FEAT_TERMTRUECOLOR) || defined(PROTO) + static int +hex_digit(int c) +{ + if (isdigit(c)) + return c - '0'; + c = TOLOWER_ASC(c); + if (c >= 'a' && c <= 'f') + return c - 'a' + 10; + return 0x1ffffff; +} + + guicolor_T +gui_get_color_cmn(char_u *name) +{ +#define TORGB(r, g, b) ((r<<16) | (g<<8) | (b)) +#define LINE_LEN 100 + FILE *fd; + char line[LINE_LEN]; + char_u *fname; + int r, g, b, i; + guicolor_T color; + + struct rgbcolor_table_S { + char_u *color_name; + guicolor_T color; + }; + + static struct rgbcolor_table_S rgb_table[] = { + {(char_u *)"black", TORGB(0x00, 0x00, 0x00)}, + {(char_u *)"blue", TORGB(0x00, 0x00, 0xFF)}, + {(char_u *)"brown", TORGB(0xA5, 0x2A, 0x2A)}, + {(char_u *)"cyan", TORGB(0x00, 0xFF, 0xFF)}, + {(char_u *)"darkblue", TORGB(0x00, 0x00, 0x8B)}, + {(char_u *)"darkcyan", TORGB(0x00, 0x8B, 0x8B)}, + {(char_u *)"darkgray", TORGB(0xA9, 0xA9, 0xA9)}, + {(char_u *)"darkgreen", TORGB(0x00, 0x64, 0x00)}, + {(char_u *)"darkgrey", TORGB(0xA9, 0xA9, 0xA9)}, + {(char_u *)"darkmagenta", TORGB(0x8B, 0x00, 0x8B)}, + {(char_u *)"darkred", TORGB(0x8B, 0x00, 0x00)}, + {(char_u *)"darkyellow", TORGB(0x8B, 0x8B, 0x00)}, /* No X11 */ + {(char_u *)"gray", TORGB(0xBE, 0xBE, 0xBE)}, + {(char_u *)"gray10", TORGB(0x1A, 0x1A, 0x1A)}, + {(char_u *)"gray20", TORGB(0x33, 0x33, 0x33)}, + {(char_u *)"gray30", TORGB(0x4D, 0x4D, 0x4D)}, + {(char_u *)"gray40", TORGB(0x66, 0x66, 0x66)}, + {(char_u *)"gray50", TORGB(0x7F, 0x7F, 0x7F)}, + {(char_u *)"gray60", TORGB(0x99, 0x99, 0x99)}, + {(char_u *)"gray70", TORGB(0xB3, 0xB3, 0xB3)}, + {(char_u *)"gray80", TORGB(0xCC, 0xCC, 0xCC)}, + {(char_u *)"gray90", TORGB(0xE5, 0xE5, 0xE5)}, + {(char_u *)"green", TORGB(0x00, 0xFF, 0x00)}, + {(char_u *)"grey", TORGB(0xBE, 0xBE, 0xBE)}, + {(char_u *)"grey10", TORGB(0x1A, 0x1A, 0x1A)}, + {(char_u *)"grey20", TORGB(0x33, 0x33, 0x33)}, + {(char_u *)"grey30", TORGB(0x4D, 0x4D, 0x4D)}, + {(char_u *)"grey40", TORGB(0x66, 0x66, 0x66)}, + {(char_u *)"grey50", TORGB(0x7F, 0x7F, 0x7F)}, + {(char_u *)"grey60", TORGB(0x99, 0x99, 0x99)}, + {(char_u *)"grey70", TORGB(0xB3, 0xB3, 0xB3)}, + {(char_u *)"grey80", TORGB(0xCC, 0xCC, 0xCC)}, + {(char_u *)"grey90", TORGB(0xE5, 0xE5, 0xE5)}, + {(char_u *)"lightblue", TORGB(0xAD, 0xD8, 0xE6)}, + {(char_u *)"lightcyan", TORGB(0xE0, 0xFF, 0xFF)}, + {(char_u *)"lightgray", TORGB(0xD3, 0xD3, 0xD3)}, + {(char_u *)"lightgreen", TORGB(0x90, 0xEE, 0x90)}, + {(char_u *)"lightgrey", TORGB(0xD3, 0xD3, 0xD3)}, + {(char_u *)"lightmagenta", TORGB(0xFF, 0x8B, 0xFF)}, /* No X11 */ + {(char_u *)"lightred", TORGB(0xFF, 0x8B, 0x8B)}, /* No X11 */ + {(char_u *)"lightyellow", TORGB(0xFF, 0xFF, 0xE0)}, + {(char_u *)"magenta", TORGB(0xFF, 0x00, 0xFF)}, + {(char_u *)"orange", TORGB(0xFF, 0xA5, 0x00)}, + {(char_u *)"purple", TORGB(0xA0, 0x20, 0xF0)}, + {(char_u *)"red", TORGB(0xFF, 0x00, 0x00)}, + {(char_u *)"seagreen", TORGB(0x2E, 0x8B, 0x57)}, + {(char_u *)"slateblue", TORGB(0x6A, 0x5A, 0xCD)}, + {(char_u *)"violet", TORGB(0xEE, 0x82, 0xEE)}, + {(char_u *)"white", TORGB(0xFF, 0xFF, 0xFF)}, + {(char_u *)"yellow", TORGB(0xFF, 0xFF, 0x00)}, + }; + + + if (name[0] == '#' && STRLEN(name) == 7) + { + /* Name is in "#rrggbb" format */ + color = TORGB(((hex_digit(name[1]) << 4) + hex_digit(name[2])), + ((hex_digit(name[3]) << 4) + hex_digit(name[4])), + ((hex_digit(name[5]) << 4) + hex_digit(name[6]))); + if (color > 0xffffff) + return INVALCOLOR; + return color; + } + + /* Check if the name is one of the colors we know */ + for (i = 0; i < (int)(sizeof(rgb_table) / sizeof(rgb_table[0])); i++) + if (STRICMP(name, rgb_table[i].color_name) == 0) + return rgb_table[i].color; + + /* + * Last attempt. Look in the file "$VIM/rgb.txt". + */ + + fname = expand_env_save((char_u *)"$VIMRUNTIME/rgb.txt"); + if (fname == NULL) + return INVALCOLOR; + + fd = fopen((char *)fname, "rt"); + vim_free(fname); + if (fd == NULL) + { + if (p_verbose > 1) + verb_msg((char_u *)_("Cannot open $VIMRUNTIME/rgb.txt")); + return INVALCOLOR; + } + + while (!feof(fd)) + { + int len; + int pos; + + (void)fgets(line, LINE_LEN, fd); + len = strlen(line); + + if (len <= 1 || line[len - 1] != '\n') + continue; + + line[len - 1] = '\0'; + + i = sscanf(line, "%d %d %d %n", &r, &g, &b, &pos); + if (i != 3) + continue; + + if (STRICMP(line + pos, name) == 0) + { + fclose(fd); + return (guicolor_T) TORGB(r, g, b); + } + } + fclose(fd); + return INVALCOLOR; +} +#endif diff --git a/src/testdir/test_channel.vim b/src/testdir/test_channel.vim index 05df50af43..6eb3c1f04f 100644 --- a/src/testdir/test_channel.vim +++ b/src/testdir/test_channel.vim @@ -1048,6 +1048,60 @@ func Test_out_cb() endtry endfunc +func Test_out_close_cb() + if !has('job') + return + endif + call ch_log('Test_out_close_cb()') + + let s:counter = 1 + let s:outmsg = 0 + let s:closemsg = 0 + func! OutHandler(chan, msg) + let s:outmsg = s:counter + let s:counter += 1 + endfunc + func! CloseHandler(chan) + let s:closemsg = s:counter + let s:counter += 1 + endfunc + let job = job_start(s:python . " test_channel_pipe.py quit now", + \ {'out_cb': 'OutHandler', + \ 'close_cb': 'CloseHandler'}) + call assert_equal("run", job_status(job)) + try + call s:waitFor('s:closemsg != 0 && s:outmsg != 0') + call assert_equal(1, s:outmsg) + call assert_equal(2, s:closemsg) + finally + call job_stop(job) + delfunc OutHandler + delfunc CloseHandler + endtry +endfunc + +func Test_read_in_close_cb() + if !has('job') + return + endif + call ch_log('Test_read_in_close_cb()') + + let s:received = '' + func! CloseHandler(chan) + let s:received = ch_read(a:chan) + endfunc + let job = job_start(s:python . " test_channel_pipe.py quit now", + \ {'close_cb': 'CloseHandler'}) + call assert_equal("run", job_status(job)) + try + call s:waitFor('s:received != ""') + call assert_equal('quit', s:received) + finally + call job_stop(job) + delfunc CloseHandler + endtry +endfunc + """""""""" let s:unletResponse = '' diff --git a/src/testdir/test_channel_pipe.py b/src/testdir/test_channel_pipe.py index fa1a40f131..5f32506741 100644 --- a/src/testdir/test_channel_pipe.py +++ b/src/testdir/test_channel_pipe.py @@ -16,6 +16,8 @@ if __name__ == "__main__": else: print(sys.argv[1]) sys.stdout.flush() + if sys.argv[1].startswith("quit"): + sys.exit(0) while True: typed = sys.stdin.readline() diff --git a/src/version.c b/src/version.c index d3b8846d48..5af8aadcc6 100644 --- a/src/version.c +++ b/src/version.c @@ -768,6 +768,24 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ +/**/ + 1795, +/**/ + 1794, +/**/ + 1793, +/**/ + 1792, +/**/ + 1791, +/**/ + 1790, +/**/ + 1789, +/**/ + 1788, +/**/ + 1787, /**/ 1786, /**/