Mercurial > vim
comparison src/channel.c @ 8538:c337c813c64d v7.4.1559
commit https://github.com/vim/vim/commit/1735bc988c546cc962c5f94792815b4d7cb79710
Author: Bram Moolenaar <Bram@vim.org>
Date: Mon Mar 14 23:05:14 2016 +0100
patch 7.4.1559
Problem: Passing cookie to a callback is clumsy.
Solution: Change function() to take arguments and return a partial.
author | Christian Brabandt <cb@256bit.org> |
---|---|
date | Mon, 14 Mar 2016 23:15:05 +0100 |
parents | 13e5a1f02be4 |
children | fec8655cf1bf |
comparison
equal
deleted
inserted
replaced
8537:cc20abebafa3 | 8538:c337c813c64d |
---|---|
1023 * Set various properties from an "opt" argument. | 1023 * Set various properties from an "opt" argument. |
1024 */ | 1024 */ |
1025 void | 1025 void |
1026 channel_set_options(channel_T *channel, jobopt_T *opt) | 1026 channel_set_options(channel_T *channel, jobopt_T *opt) |
1027 { | 1027 { |
1028 int part; | 1028 int part; |
1029 char_u **cbp; | 1029 char_u **cbp; |
1030 partial_T **pp; | |
1030 | 1031 |
1031 if (opt->jo_set & JO_MODE) | 1032 if (opt->jo_set & JO_MODE) |
1032 for (part = PART_SOCK; part <= PART_IN; ++part) | 1033 for (part = PART_SOCK; part <= PART_IN; ++part) |
1033 channel->ch_part[part].ch_mode = opt->jo_mode; | 1034 channel->ch_part[part].ch_mode = opt->jo_mode; |
1034 if (opt->jo_set & JO_IN_MODE) | 1035 if (opt->jo_set & JO_IN_MODE) |
1047 channel->ch_part[PART_ERR].ch_timeout = opt->jo_err_timeout; | 1048 channel->ch_part[PART_ERR].ch_timeout = opt->jo_err_timeout; |
1048 | 1049 |
1049 if (opt->jo_set & JO_CALLBACK) | 1050 if (opt->jo_set & JO_CALLBACK) |
1050 { | 1051 { |
1051 cbp = &channel->ch_callback; | 1052 cbp = &channel->ch_callback; |
1053 pp = &channel->ch_partial; | |
1052 vim_free(*cbp); | 1054 vim_free(*cbp); |
1055 partial_unref(*pp); | |
1053 if (opt->jo_callback != NULL && *opt->jo_callback != NUL) | 1056 if (opt->jo_callback != NULL && *opt->jo_callback != NUL) |
1054 *cbp = vim_strsave(opt->jo_callback); | 1057 *cbp = vim_strsave(opt->jo_callback); |
1055 else | 1058 else |
1056 *cbp = NULL; | 1059 *cbp = NULL; |
1060 *pp = opt->jo_partial; | |
1061 if (*pp != NULL) | |
1062 ++(*pp)->pt_refcount; | |
1057 } | 1063 } |
1058 if (opt->jo_set & JO_OUT_CALLBACK) | 1064 if (opt->jo_set & JO_OUT_CALLBACK) |
1059 { | 1065 { |
1060 cbp = &channel->ch_part[PART_OUT].ch_callback; | 1066 cbp = &channel->ch_part[PART_OUT].ch_callback; |
1067 pp = &channel->ch_part[PART_OUT].ch_partial; | |
1061 vim_free(*cbp); | 1068 vim_free(*cbp); |
1069 partial_unref(*pp); | |
1062 if (opt->jo_out_cb != NULL && *opt->jo_out_cb != NUL) | 1070 if (opt->jo_out_cb != NULL && *opt->jo_out_cb != NUL) |
1063 *cbp = vim_strsave(opt->jo_out_cb); | 1071 *cbp = vim_strsave(opt->jo_out_cb); |
1064 else | 1072 else |
1065 *cbp = NULL; | 1073 *cbp = NULL; |
1074 *pp = opt->jo_out_partial; | |
1075 if (*pp != NULL) | |
1076 ++(*pp)->pt_refcount; | |
1066 } | 1077 } |
1067 if (opt->jo_set & JO_ERR_CALLBACK) | 1078 if (opt->jo_set & JO_ERR_CALLBACK) |
1068 { | 1079 { |
1069 cbp = &channel->ch_part[PART_ERR].ch_callback; | 1080 cbp = &channel->ch_part[PART_ERR].ch_callback; |
1081 pp = &channel->ch_part[PART_ERR].ch_partial; | |
1070 vim_free(*cbp); | 1082 vim_free(*cbp); |
1083 partial_unref(*pp); | |
1071 if (opt->jo_err_cb != NULL && *opt->jo_err_cb != NUL) | 1084 if (opt->jo_err_cb != NULL && *opt->jo_err_cb != NUL) |
1072 *cbp = vim_strsave(opt->jo_err_cb); | 1085 *cbp = vim_strsave(opt->jo_err_cb); |
1073 else | 1086 else |
1074 *cbp = NULL; | 1087 *cbp = NULL; |
1088 *pp = opt->jo_err_partial; | |
1089 if (*pp != NULL) | |
1090 ++(*pp)->pt_refcount; | |
1075 } | 1091 } |
1076 if (opt->jo_set & JO_CLOSE_CALLBACK) | 1092 if (opt->jo_set & JO_CLOSE_CALLBACK) |
1077 { | 1093 { |
1078 cbp = &channel->ch_close_cb; | 1094 cbp = &channel->ch_close_cb; |
1095 pp = &channel->ch_close_partial; | |
1079 vim_free(*cbp); | 1096 vim_free(*cbp); |
1097 partial_unref(*pp); | |
1080 if (opt->jo_close_cb != NULL && *opt->jo_close_cb != NUL) | 1098 if (opt->jo_close_cb != NULL && *opt->jo_close_cb != NUL) |
1081 *cbp = vim_strsave(opt->jo_close_cb); | 1099 *cbp = vim_strsave(opt->jo_close_cb); |
1082 else | 1100 else |
1083 *cbp = NULL; | 1101 *cbp = NULL; |
1102 *pp = opt->jo_err_partial; | |
1103 if (*pp != NULL) | |
1104 ++(*pp)->pt_refcount; | |
1084 } | 1105 } |
1085 | 1106 |
1086 if ((opt->jo_set & JO_OUT_IO) && opt->jo_io[PART_OUT] == JIO_BUFFER) | 1107 if ((opt->jo_set & JO_OUT_IO) && opt->jo_io[PART_OUT] == JIO_BUFFER) |
1087 { | 1108 { |
1088 /* writing output to a buffer. Default mode is NL. */ | 1109 /* writing output to a buffer. Default mode is NL. */ |
1122 /* | 1143 /* |
1123 * Set the callback for "channel"/"part" for the response with "id". | 1144 * Set the callback for "channel"/"part" for the response with "id". |
1124 */ | 1145 */ |
1125 void | 1146 void |
1126 channel_set_req_callback( | 1147 channel_set_req_callback( |
1127 channel_T *channel, | 1148 channel_T *channel, |
1128 int part, | 1149 int part, |
1129 char_u *callback, | 1150 char_u *callback, |
1130 int id) | 1151 partial_T *partial, |
1152 int id) | |
1131 { | 1153 { |
1132 cbq_T *head = &channel->ch_part[part].ch_cb_head; | 1154 cbq_T *head = &channel->ch_part[part].ch_cb_head; |
1133 cbq_T *item = (cbq_T *)alloc((int)sizeof(cbq_T)); | 1155 cbq_T *item = (cbq_T *)alloc((int)sizeof(cbq_T)); |
1134 | 1156 |
1135 if (item != NULL) | 1157 if (item != NULL) |
1136 { | 1158 { |
1137 item->cq_callback = vim_strsave(callback); | 1159 item->cq_callback = vim_strsave(callback); |
1160 item->cq_partial = partial; | |
1161 if (partial != NULL) | |
1162 ++partial->pt_refcount; | |
1138 item->cq_seq_nr = id; | 1163 item->cq_seq_nr = id; |
1139 item->cq_prev = head->cq_prev; | 1164 item->cq_prev = head->cq_prev; |
1140 head->cq_prev = item; | 1165 head->cq_prev = item; |
1141 item->cq_next = NULL; | 1166 item->cq_next = NULL; |
1142 if (item->cq_prev == NULL) | 1167 if (item->cq_prev == NULL) |
1245 | 1270 |
1246 /* | 1271 /* |
1247 * Invoke the "callback" on channel "channel". | 1272 * Invoke the "callback" on channel "channel". |
1248 */ | 1273 */ |
1249 static void | 1274 static void |
1250 invoke_callback(channel_T *channel, char_u *callback, typval_T *argv) | 1275 invoke_callback(channel_T *channel, char_u *callback, partial_T *partial, |
1276 typval_T *argv) | |
1251 { | 1277 { |
1252 typval_T rettv; | 1278 typval_T rettv; |
1253 int dummy; | 1279 int dummy; |
1254 | 1280 |
1255 argv[0].v_type = VAR_CHANNEL; | 1281 argv[0].v_type = VAR_CHANNEL; |
1256 argv[0].vval.v_channel = channel; | 1282 argv[0].vval.v_channel = channel; |
1257 | 1283 |
1258 call_func(callback, (int)STRLEN(callback), | 1284 call_func(callback, (int)STRLEN(callback), |
1259 &rettv, 2, argv, 0L, 0L, &dummy, TRUE, NULL); | 1285 &rettv, 2, argv, 0L, 0L, &dummy, TRUE, partial, NULL); |
1260 clear_tv(&rettv); | 1286 clear_tv(&rettv); |
1261 | 1287 |
1262 /* If an echo command was used the cursor needs to be put back where | 1288 /* If an echo command was used the cursor needs to be put back where |
1263 * it belongs. If highlighting was changed a redraw is needed. */ | 1289 * it belongs. If highlighting was changed a redraw is needed. */ |
1264 update_screen(0); | 1290 update_screen(0); |
1627 | 1653 |
1628 /* Don't pollute the display with errors. */ | 1654 /* Don't pollute the display with errors. */ |
1629 ++emsg_skip; | 1655 ++emsg_skip; |
1630 if (!is_call) | 1656 if (!is_call) |
1631 tv = eval_expr(arg, NULL); | 1657 tv = eval_expr(arg, NULL); |
1632 else if (func_call(arg, &argv[2], NULL, &res_tv) == OK) | 1658 else if (func_call(arg, &argv[2], NULL, NULL, &res_tv) == OK) |
1633 tv = &res_tv; | 1659 tv = &res_tv; |
1634 else | 1660 else |
1635 tv = NULL; | 1661 tv = NULL; |
1636 | 1662 |
1637 if (argv[id_idx].v_type == VAR_NUMBER) | 1663 if (argv[id_idx].v_type == VAR_NUMBER) |
1683 ch_logs(channel, "Invoking one-time callback %s", | 1709 ch_logs(channel, "Invoking one-time callback %s", |
1684 (char *)item->cq_callback); | 1710 (char *)item->cq_callback); |
1685 /* Remove the item from the list first, if the callback | 1711 /* Remove the item from the list first, if the callback |
1686 * invokes ch_close() the list will be cleared. */ | 1712 * invokes ch_close() the list will be cleared. */ |
1687 remove_cb_node(cbhead, item); | 1713 remove_cb_node(cbhead, item); |
1688 invoke_callback(channel, item->cq_callback, argv); | 1714 invoke_callback(channel, item->cq_callback, item->cq_partial, argv); |
1689 vim_free(item->cq_callback); | 1715 vim_free(item->cq_callback); |
1716 partial_unref(item->cq_partial); | |
1690 vim_free(item); | 1717 vim_free(item); |
1691 } | 1718 } |
1692 | 1719 |
1693 static void | 1720 static void |
1694 append_to_buffer(buf_T *buffer, char_u *msg, channel_T *channel) | 1721 append_to_buffer(buf_T *buffer, char_u *msg, channel_T *channel) |
1773 int seq_nr = -1; | 1800 int seq_nr = -1; |
1774 ch_mode_T ch_mode = channel->ch_part[part].ch_mode; | 1801 ch_mode_T ch_mode = channel->ch_part[part].ch_mode; |
1775 cbq_T *cbhead = &channel->ch_part[part].ch_cb_head; | 1802 cbq_T *cbhead = &channel->ch_part[part].ch_cb_head; |
1776 cbq_T *cbitem; | 1803 cbq_T *cbitem; |
1777 char_u *callback = NULL; | 1804 char_u *callback = NULL; |
1805 partial_T *partial = NULL; | |
1778 buf_T *buffer = NULL; | 1806 buf_T *buffer = NULL; |
1779 | 1807 |
1780 if (channel->ch_nb_close_cb != NULL) | 1808 if (channel->ch_nb_close_cb != NULL) |
1781 /* this channel is handled elsewhere (netbeans) */ | 1809 /* this channel is handled elsewhere (netbeans) */ |
1782 return FALSE; | 1810 return FALSE; |
1784 /* Use a message-specific callback, part callback or channel callback */ | 1812 /* Use a message-specific callback, part callback or channel callback */ |
1785 for (cbitem = cbhead->cq_next; cbitem != NULL; cbitem = cbitem->cq_next) | 1813 for (cbitem = cbhead->cq_next; cbitem != NULL; cbitem = cbitem->cq_next) |
1786 if (cbitem->cq_seq_nr == 0) | 1814 if (cbitem->cq_seq_nr == 0) |
1787 break; | 1815 break; |
1788 if (cbitem != NULL) | 1816 if (cbitem != NULL) |
1817 { | |
1789 callback = cbitem->cq_callback; | 1818 callback = cbitem->cq_callback; |
1819 partial = cbitem->cq_partial; | |
1820 } | |
1790 else if (channel->ch_part[part].ch_callback != NULL) | 1821 else if (channel->ch_part[part].ch_callback != NULL) |
1822 { | |
1791 callback = channel->ch_part[part].ch_callback; | 1823 callback = channel->ch_part[part].ch_callback; |
1824 partial = channel->ch_part[part].ch_partial; | |
1825 } | |
1792 else | 1826 else |
1827 { | |
1793 callback = channel->ch_callback; | 1828 callback = channel->ch_callback; |
1829 partial = channel->ch_partial; | |
1830 } | |
1794 | 1831 |
1795 buffer = channel->ch_part[part].ch_buffer; | 1832 buffer = channel->ch_part[part].ch_buffer; |
1796 if (buffer != NULL && !buf_valid(buffer)) | 1833 if (buffer != NULL && !buf_valid(buffer)) |
1797 { | 1834 { |
1798 /* buffer was wiped out */ | 1835 /* buffer was wiped out */ |
1934 else | 1971 else |
1935 { | 1972 { |
1936 /* invoke the channel callback */ | 1973 /* invoke the channel callback */ |
1937 ch_logs(channel, "Invoking channel callback %s", | 1974 ch_logs(channel, "Invoking channel callback %s", |
1938 (char *)callback); | 1975 (char *)callback); |
1939 invoke_callback(channel, callback, argv); | 1976 invoke_callback(channel, callback, partial, argv); |
1940 } | 1977 } |
1941 } | 1978 } |
1942 } | 1979 } |
1943 else | 1980 else |
1944 ch_log(channel, "Dropping message"); | 1981 ch_log(channel, "Dropping message"); |
2022 (char *)channel->ch_close_cb); | 2059 (char *)channel->ch_close_cb); |
2023 argv[0].v_type = VAR_CHANNEL; | 2060 argv[0].v_type = VAR_CHANNEL; |
2024 argv[0].vval.v_channel = channel; | 2061 argv[0].vval.v_channel = channel; |
2025 ++channel->ch_refcount; | 2062 ++channel->ch_refcount; |
2026 call_func(channel->ch_close_cb, (int)STRLEN(channel->ch_close_cb), | 2063 call_func(channel->ch_close_cb, (int)STRLEN(channel->ch_close_cb), |
2027 &rettv, 1, argv, 0L, 0L, &dummy, TRUE, NULL); | 2064 &rettv, 1, argv, 0L, 0L, &dummy, TRUE, |
2065 channel->ch_close_partial, NULL); | |
2028 clear_tv(&rettv); | 2066 clear_tv(&rettv); |
2029 --channel->ch_refcount; | 2067 --channel->ch_refcount; |
2030 | 2068 |
2031 /* the callback is only called once */ | 2069 /* the callback is only called once */ |
2032 vim_free(channel->ch_close_cb); | 2070 vim_free(channel->ch_close_cb); |
2033 channel->ch_close_cb = NULL; | 2071 channel->ch_close_cb = NULL; |
2072 partial_unref(channel->ch_close_partial); | |
2073 channel->ch_close_partial = NULL; | |
2034 } | 2074 } |
2035 | 2075 |
2036 channel->ch_nb_close_cb = NULL; | 2076 channel->ch_nb_close_cb = NULL; |
2037 } | 2077 } |
2038 | 2078 |
2066 { | 2106 { |
2067 cbq_T *node = cb_head->cq_next; | 2107 cbq_T *node = cb_head->cq_next; |
2068 | 2108 |
2069 remove_cb_node(cb_head, node); | 2109 remove_cb_node(cb_head, node); |
2070 vim_free(node->cq_callback); | 2110 vim_free(node->cq_callback); |
2111 partial_unref(node->cq_partial); | |
2071 vim_free(node); | 2112 vim_free(node); |
2072 } | 2113 } |
2073 | 2114 |
2074 while (json_head->jq_next != NULL) | 2115 while (json_head->jq_next != NULL) |
2075 { | 2116 { |
2077 remove_json_node(json_head, json_head->jq_next); | 2118 remove_json_node(json_head, json_head->jq_next); |
2078 } | 2119 } |
2079 | 2120 |
2080 vim_free(channel->ch_part[part].ch_callback); | 2121 vim_free(channel->ch_part[part].ch_callback); |
2081 channel->ch_part[part].ch_callback = NULL; | 2122 channel->ch_part[part].ch_callback = NULL; |
2123 partial_unref(channel->ch_part[part].ch_partial); | |
2124 channel->ch_part[part].ch_partial = NULL; | |
2082 } | 2125 } |
2083 | 2126 |
2084 /* | 2127 /* |
2085 * Clear all the read buffers on "channel". | 2128 * Clear all the read buffers on "channel". |
2086 */ | 2129 */ |
2091 channel_clear_one(channel, PART_SOCK); | 2134 channel_clear_one(channel, PART_SOCK); |
2092 channel_clear_one(channel, PART_OUT); | 2135 channel_clear_one(channel, PART_OUT); |
2093 channel_clear_one(channel, PART_ERR); | 2136 channel_clear_one(channel, PART_ERR); |
2094 vim_free(channel->ch_callback); | 2137 vim_free(channel->ch_callback); |
2095 channel->ch_callback = NULL; | 2138 channel->ch_callback = NULL; |
2139 partial_unref(channel->ch_partial); | |
2140 channel->ch_partial = NULL; | |
2096 vim_free(channel->ch_close_cb); | 2141 vim_free(channel->ch_close_cb); |
2097 channel->ch_close_cb = NULL; | 2142 channel->ch_close_cb = NULL; |
2143 partial_unref(channel->ch_close_partial); | |
2144 channel->ch_close_partial = NULL; | |
2098 } | 2145 } |
2099 | 2146 |
2100 #if defined(EXITFREE) || defined(PROTO) | 2147 #if defined(EXITFREE) || defined(PROTO) |
2101 void | 2148 void |
2102 channel_free_all(void) | 2149 channel_free_all(void) |
2590 if (eval) | 2637 if (eval) |
2591 { | 2638 { |
2592 EMSG2(_("E917: Cannot use a callback with %s()"), fun); | 2639 EMSG2(_("E917: Cannot use a callback with %s()"), fun); |
2593 return NULL; | 2640 return NULL; |
2594 } | 2641 } |
2595 channel_set_req_callback(channel, part_send, opt->jo_callback, id); | 2642 channel_set_req_callback(channel, part_send, |
2643 opt->jo_callback, opt->jo_partial, id); | |
2596 } | 2644 } |
2597 | 2645 |
2598 if (channel_send(channel, part_send, text, fun) == OK | 2646 if (channel_send(channel, part_send, text, fun) == OK |
2599 && opt->jo_callback == NULL) | 2647 && opt->jo_callback == NULL) |
2600 return channel; | 2648 return channel; |
2980 * Get a callback from "arg". It can be a Funcref or a function name. | 3028 * Get a callback from "arg". It can be a Funcref or a function name. |
2981 * When "arg" is zero return an empty string. | 3029 * When "arg" is zero return an empty string. |
2982 * Return NULL for an invalid argument. | 3030 * Return NULL for an invalid argument. |
2983 */ | 3031 */ |
2984 static char_u * | 3032 static char_u * |
2985 get_callback(typval_T *arg) | 3033 get_callback(typval_T *arg, partial_T **pp) |
2986 { | 3034 { |
3035 if (arg->v_type == VAR_PARTIAL && arg->vval.v_partial != NULL) | |
3036 { | |
3037 *pp = arg->vval.v_partial; | |
3038 return (*pp)->pt_name; | |
3039 } | |
3040 *pp = NULL; | |
2987 if (arg->v_type == VAR_FUNC || arg->v_type == VAR_STRING) | 3041 if (arg->v_type == VAR_FUNC || arg->v_type == VAR_STRING) |
2988 return arg->vval.v_string; | 3042 return arg->vval.v_string; |
2989 if (arg->v_type == VAR_NUMBER && arg->vval.v_number == 0) | 3043 if (arg->v_type == VAR_NUMBER && arg->vval.v_number == 0) |
2990 return (char_u *)""; | 3044 return (char_u *)""; |
2991 EMSG(_("E999: Invalid callback argument")); | 3045 EMSG(_("E921: Invalid callback argument")); |
2992 return NULL; | 3046 return NULL; |
2993 } | 3047 } |
2994 | 3048 |
2995 static int | 3049 static int |
2996 handle_mode(typval_T *item, jobopt_T *opt, ch_mode_T *modep, int jo) | 3050 handle_mode(typval_T *item, jobopt_T *opt, ch_mode_T *modep, int jo) |
3199 else if (STRCMP(hi->hi_key, "callback") == 0) | 3253 else if (STRCMP(hi->hi_key, "callback") == 0) |
3200 { | 3254 { |
3201 if (!(supported & JO_CALLBACK)) | 3255 if (!(supported & JO_CALLBACK)) |
3202 break; | 3256 break; |
3203 opt->jo_set |= JO_CALLBACK; | 3257 opt->jo_set |= JO_CALLBACK; |
3204 opt->jo_callback = get_callback(item); | 3258 opt->jo_callback = get_callback(item, &opt->jo_partial); |
3205 if (opt->jo_callback == NULL) | 3259 if (opt->jo_callback == NULL) |
3206 { | 3260 { |
3207 EMSG2(_(e_invarg2), "callback"); | 3261 EMSG2(_(e_invarg2), "callback"); |
3208 return FAIL; | 3262 return FAIL; |
3209 } | 3263 } |
3211 else if (STRCMP(hi->hi_key, "out-cb") == 0) | 3265 else if (STRCMP(hi->hi_key, "out-cb") == 0) |
3212 { | 3266 { |
3213 if (!(supported & JO_OUT_CALLBACK)) | 3267 if (!(supported & JO_OUT_CALLBACK)) |
3214 break; | 3268 break; |
3215 opt->jo_set |= JO_OUT_CALLBACK; | 3269 opt->jo_set |= JO_OUT_CALLBACK; |
3216 opt->jo_out_cb = get_callback(item); | 3270 opt->jo_out_cb = get_callback(item, &opt->jo_out_partial); |
3217 if (opt->jo_out_cb == NULL) | 3271 if (opt->jo_out_cb == NULL) |
3218 { | 3272 { |
3219 EMSG2(_(e_invarg2), "out-cb"); | 3273 EMSG2(_(e_invarg2), "out-cb"); |
3220 return FAIL; | 3274 return FAIL; |
3221 } | 3275 } |
3223 else if (STRCMP(hi->hi_key, "err-cb") == 0) | 3277 else if (STRCMP(hi->hi_key, "err-cb") == 0) |
3224 { | 3278 { |
3225 if (!(supported & JO_ERR_CALLBACK)) | 3279 if (!(supported & JO_ERR_CALLBACK)) |
3226 break; | 3280 break; |
3227 opt->jo_set |= JO_ERR_CALLBACK; | 3281 opt->jo_set |= JO_ERR_CALLBACK; |
3228 opt->jo_err_cb = get_callback(item); | 3282 opt->jo_err_cb = get_callback(item, &opt->jo_err_partial); |
3229 if (opt->jo_err_cb == NULL) | 3283 if (opt->jo_err_cb == NULL) |
3230 { | 3284 { |
3231 EMSG2(_(e_invarg2), "err-cb"); | 3285 EMSG2(_(e_invarg2), "err-cb"); |
3232 return FAIL; | 3286 return FAIL; |
3233 } | 3287 } |
3235 else if (STRCMP(hi->hi_key, "close-cb") == 0) | 3289 else if (STRCMP(hi->hi_key, "close-cb") == 0) |
3236 { | 3290 { |
3237 if (!(supported & JO_CLOSE_CALLBACK)) | 3291 if (!(supported & JO_CLOSE_CALLBACK)) |
3238 break; | 3292 break; |
3239 opt->jo_set |= JO_CLOSE_CALLBACK; | 3293 opt->jo_set |= JO_CLOSE_CALLBACK; |
3240 opt->jo_close_cb = get_callback(item); | 3294 opt->jo_close_cb = get_callback(item, &opt->jo_close_partial); |
3241 if (opt->jo_close_cb == NULL) | 3295 if (opt->jo_close_cb == NULL) |
3242 { | 3296 { |
3243 EMSG2(_(e_invarg2), "close-cb"); | 3297 EMSG2(_(e_invarg2), "close-cb"); |
3244 return FAIL; | 3298 return FAIL; |
3245 } | 3299 } |
3309 else if (STRCMP(hi->hi_key, "exit-cb") == 0) | 3363 else if (STRCMP(hi->hi_key, "exit-cb") == 0) |
3310 { | 3364 { |
3311 if (!(supported & JO_EXIT_CB)) | 3365 if (!(supported & JO_EXIT_CB)) |
3312 break; | 3366 break; |
3313 opt->jo_set |= JO_EXIT_CB; | 3367 opt->jo_set |= JO_EXIT_CB; |
3314 opt->jo_exit_cb = get_tv_string_buf_chk(item, opt->jo_ecb_buf); | 3368 if (item->v_type == VAR_PARTIAL && item->vval.v_partial != NULL) |
3369 { | |
3370 opt->jo_exit_partial = item->vval.v_partial; | |
3371 opt->jo_exit_cb = item->vval.v_partial->pt_name; | |
3372 } | |
3373 else | |
3374 opt->jo_exit_cb = get_tv_string_buf_chk( | |
3375 item, opt->jo_ecb_buf); | |
3315 if (opt->jo_exit_cb == NULL) | 3376 if (opt->jo_exit_cb == NULL) |
3316 { | 3377 { |
3317 EMSG2(_(e_invarg2), "exit-cb"); | 3378 EMSG2(_(e_invarg2), "exit-cb"); |
3318 return FAIL; | 3379 return FAIL; |
3319 } | 3380 } |
3388 else | 3449 else |
3389 job->jv_prev->jv_next = job->jv_next; | 3450 job->jv_prev->jv_next = job->jv_next; |
3390 | 3451 |
3391 vim_free(job->jv_stoponexit); | 3452 vim_free(job->jv_stoponexit); |
3392 vim_free(job->jv_exit_cb); | 3453 vim_free(job->jv_exit_cb); |
3454 partial_unref(job->jv_exit_partial); | |
3393 vim_free(job); | 3455 vim_free(job); |
3394 } | 3456 } |
3395 | 3457 |
3396 void | 3458 void |
3397 job_unref(job_T *job) | 3459 job_unref(job_T *job) |
3452 job->jv_stoponexit = vim_strsave(opt->jo_stoponexit); | 3514 job->jv_stoponexit = vim_strsave(opt->jo_stoponexit); |
3453 } | 3515 } |
3454 if (opt->jo_set & JO_EXIT_CB) | 3516 if (opt->jo_set & JO_EXIT_CB) |
3455 { | 3517 { |
3456 vim_free(job->jv_exit_cb); | 3518 vim_free(job->jv_exit_cb); |
3519 partial_unref(job->jv_exit_partial); | |
3457 if (opt->jo_exit_cb == NULL || *opt->jo_exit_cb == NUL) | 3520 if (opt->jo_exit_cb == NULL || *opt->jo_exit_cb == NUL) |
3521 { | |
3458 job->jv_exit_cb = NULL; | 3522 job->jv_exit_cb = NULL; |
3523 job->jv_exit_partial = NULL; | |
3524 } | |
3459 else | 3525 else |
3526 { | |
3460 job->jv_exit_cb = vim_strsave(opt->jo_exit_cb); | 3527 job->jv_exit_cb = vim_strsave(opt->jo_exit_cb); |
3528 job->jv_exit_partial = opt->jo_exit_partial; | |
3529 if (job->jv_exit_partial != NULL) | |
3530 ++job->jv_exit_partial->pt_refcount; | |
3531 } | |
3461 } | 3532 } |
3462 } | 3533 } |
3463 | 3534 |
3464 /* | 3535 /* |
3465 * Called when Vim is exiting: kill all jobs that have the "stoponexit" flag. | 3536 * Called when Vim is exiting: kill all jobs that have the "stoponexit" flag. |
3719 argv[0].v_type = VAR_JOB; | 3790 argv[0].v_type = VAR_JOB; |
3720 argv[0].vval.v_job = job; | 3791 argv[0].vval.v_job = job; |
3721 argv[1].v_type = VAR_NUMBER; | 3792 argv[1].v_type = VAR_NUMBER; |
3722 argv[1].vval.v_number = job->jv_exitval; | 3793 argv[1].vval.v_number = job->jv_exitval; |
3723 call_func(job->jv_exit_cb, (int)STRLEN(job->jv_exit_cb), | 3794 call_func(job->jv_exit_cb, (int)STRLEN(job->jv_exit_cb), |
3724 &rettv, 2, argv, 0L, 0L, &dummy, TRUE, NULL); | 3795 &rettv, 2, argv, 0L, 0L, &dummy, TRUE, |
3796 job->jv_exit_partial, NULL); | |
3725 clear_tv(&rettv); | 3797 clear_tv(&rettv); |
3726 --job->jv_refcount; | 3798 --job->jv_refcount; |
3727 } | 3799 } |
3728 if (job->jv_status == JOB_ENDED && job->jv_refcount == 0) | 3800 if (job->jv_status == JOB_ENDED && job->jv_refcount == 0) |
3729 { | 3801 { |