Mercurial > vim
comparison src/channel.c @ 9147:053bc64433ec v7.4.1857
commit https://github.com/vim/vim/commit/9f5842e63fc63d438cbffcec503e072a06f74dc2
Author: Bram Moolenaar <Bram@vim.org>
Date: Sun May 29 16:17:08 2016 +0200
patch 7.4.1857
Problem: When a channel appends to a buffer that is 'nomodifiable' there is
an error but appending is done anyway.
Solution: Add the 'modifiable' option. Refuse to write to a 'nomodifiable'
when the value is 1.
author | Christian Brabandt <cb@256bit.org> |
---|---|
date | Sun, 29 May 2016 16:30:06 +0200 |
parents | b9c1a397a8a6 |
children | 18bbf31015c2 |
comparison
equal
deleted
inserted
replaced
9146:23a544d11064 | 9147:053bc64433ec |
---|---|
1207 { | 1207 { |
1208 buf = find_buffer(opt->jo_io_name[PART_OUT], FALSE); | 1208 buf = find_buffer(opt->jo_io_name[PART_OUT], FALSE); |
1209 } | 1209 } |
1210 if (buf != NULL) | 1210 if (buf != NULL) |
1211 { | 1211 { |
1212 ch_logs(channel, "writing out to buffer '%s'", | 1212 if (opt->jo_set & JO_OUT_MODIFIABLE) |
1213 channel->ch_part[PART_OUT].ch_nomodifiable = | |
1214 !opt->jo_modifiable[PART_OUT]; | |
1215 | |
1216 if (!buf->b_p_ma && !channel->ch_part[PART_OUT].ch_nomodifiable) | |
1217 { | |
1218 EMSG(_(e_modifiable)); | |
1219 } | |
1220 else | |
1221 { | |
1222 ch_logs(channel, "writing out to buffer '%s'", | |
1213 (char *)buf->b_ffname); | 1223 (char *)buf->b_ffname); |
1214 channel->ch_part[PART_OUT].ch_buffer = buf; | 1224 channel->ch_part[PART_OUT].ch_buffer = buf; |
1225 } | |
1215 } | 1226 } |
1216 } | 1227 } |
1217 | 1228 |
1218 if ((opt->jo_set & JO_ERR_IO) && (opt->jo_io[PART_ERR] == JIO_BUFFER | 1229 if ((opt->jo_set & JO_ERR_IO) && (opt->jo_io[PART_ERR] == JIO_BUFFER |
1219 || (opt->jo_io[PART_ERR] == JIO_OUT && (opt->jo_set & JO_OUT_IO) | 1230 || (opt->jo_io[PART_ERR] == JIO_OUT && (opt->jo_set & JO_OUT_IO) |
1234 } | 1245 } |
1235 else | 1246 else |
1236 buf = find_buffer(opt->jo_io_name[PART_ERR], TRUE); | 1247 buf = find_buffer(opt->jo_io_name[PART_ERR], TRUE); |
1237 if (buf != NULL) | 1248 if (buf != NULL) |
1238 { | 1249 { |
1239 ch_logs(channel, "writing err to buffer '%s'", | 1250 if (opt->jo_set & JO_ERR_MODIFIABLE) |
1251 channel->ch_part[PART_ERR].ch_nomodifiable = | |
1252 !opt->jo_modifiable[PART_ERR]; | |
1253 if (!buf->b_p_ma && !channel->ch_part[PART_ERR].ch_nomodifiable) | |
1254 { | |
1255 EMSG(_(e_modifiable)); | |
1256 } | |
1257 else | |
1258 { | |
1259 ch_logs(channel, "writing err to buffer '%s'", | |
1240 (char *)buf->b_ffname); | 1260 (char *)buf->b_ffname); |
1241 channel->ch_part[PART_ERR].ch_buffer = buf; | 1261 channel->ch_part[PART_ERR].ch_buffer = buf; |
1262 } | |
1242 } | 1263 } |
1243 } | 1264 } |
1244 | 1265 |
1245 channel->ch_part[PART_OUT].ch_io = opt->jo_io[PART_OUT]; | 1266 channel->ch_part[PART_OUT].ch_io = opt->jo_io[PART_OUT]; |
1246 channel->ch_part[PART_ERR].ch_io = opt->jo_io[PART_ERR]; | 1267 channel->ch_part[PART_ERR].ch_io = opt->jo_io[PART_ERR]; |
2105 partial_unref(item->cq_partial); | 2126 partial_unref(item->cq_partial); |
2106 vim_free(item); | 2127 vim_free(item); |
2107 } | 2128 } |
2108 | 2129 |
2109 static void | 2130 static void |
2110 append_to_buffer(buf_T *buffer, char_u *msg, channel_T *channel) | 2131 append_to_buffer(buf_T *buffer, char_u *msg, channel_T *channel, int part) |
2111 { | 2132 { |
2112 buf_T *save_curbuf = curbuf; | 2133 buf_T *save_curbuf = curbuf; |
2113 linenr_T lnum = buffer->b_ml.ml_line_count; | 2134 linenr_T lnum = buffer->b_ml.ml_line_count; |
2114 int save_write_to = buffer->b_write_to_channel; | 2135 int save_write_to = buffer->b_write_to_channel; |
2136 chanpart_T *ch_part = &channel->ch_part[part]; | |
2137 int save_p_ma = buffer->b_p_ma; | |
2138 | |
2139 if (!buffer->b_p_ma && !ch_part->ch_nomodifiable) | |
2140 { | |
2141 if (!ch_part->ch_nomod_error) | |
2142 { | |
2143 ch_error(channel, "Buffer is not modifiable, cannot append"); | |
2144 ch_part->ch_nomod_error = TRUE; | |
2145 } | |
2146 return; | |
2147 } | |
2115 | 2148 |
2116 /* If the buffer is also used as input insert above the last | 2149 /* If the buffer is also used as input insert above the last |
2117 * line. Don't write these lines. */ | 2150 * line. Don't write these lines. */ |
2118 if (save_write_to) | 2151 if (save_write_to) |
2119 { | 2152 { |
2122 } | 2155 } |
2123 | 2156 |
2124 /* Append to the buffer */ | 2157 /* Append to the buffer */ |
2125 ch_logn(channel, "appending line %d to buffer", (int)lnum + 1); | 2158 ch_logn(channel, "appending line %d to buffer", (int)lnum + 1); |
2126 | 2159 |
2160 buffer->b_p_ma = TRUE; | |
2127 curbuf = buffer; | 2161 curbuf = buffer; |
2128 u_sync(TRUE); | 2162 u_sync(TRUE); |
2129 /* ignore undo failure, undo is not very useful here */ | 2163 /* ignore undo failure, undo is not very useful here */ |
2130 ignored = u_save(lnum, lnum + 1); | 2164 ignored = u_save(lnum, lnum + 1); |
2131 | 2165 |
2132 ml_append(lnum, msg, 0, FALSE); | 2166 ml_append(lnum, msg, 0, FALSE); |
2133 appended_lines_mark(lnum, 1L); | 2167 appended_lines_mark(lnum, 1L); |
2134 curbuf = save_curbuf; | 2168 curbuf = save_curbuf; |
2169 if (ch_part->ch_nomodifiable) | |
2170 buffer->b_p_ma = FALSE; | |
2171 else | |
2172 buffer->b_p_ma = save_p_ma; | |
2135 | 2173 |
2136 if (buffer->b_nwindows > 0) | 2174 if (buffer->b_nwindows > 0) |
2137 { | 2175 { |
2138 win_T *wp; | 2176 win_T *wp; |
2139 win_T *save_curwin; | 2177 win_T *save_curwin; |
2357 { | 2395 { |
2358 if (msg == NULL) | 2396 if (msg == NULL) |
2359 /* JSON or JS mode: re-encode the message. */ | 2397 /* JSON or JS mode: re-encode the message. */ |
2360 msg = json_encode(listtv, ch_mode); | 2398 msg = json_encode(listtv, ch_mode); |
2361 if (msg != NULL) | 2399 if (msg != NULL) |
2362 append_to_buffer(buffer, msg, channel); | 2400 append_to_buffer(buffer, msg, channel, part); |
2363 } | 2401 } |
2364 | 2402 |
2365 if (callback != NULL) | 2403 if (callback != NULL) |
2366 { | 2404 { |
2367 if (cbitem != NULL) | 2405 if (cbitem != NULL) |
3912 if (buflist_findnr(opt->jo_io_buf[part]) == NULL) | 3950 if (buflist_findnr(opt->jo_io_buf[part]) == NULL) |
3913 { | 3951 { |
3914 EMSGN(_(e_nobufnr), (long)opt->jo_io_buf[part]); | 3952 EMSGN(_(e_nobufnr), (long)opt->jo_io_buf[part]); |
3915 return FAIL; | 3953 return FAIL; |
3916 } | 3954 } |
3955 } | |
3956 else if (STRCMP(hi->hi_key, "out_modifiable") == 0 | |
3957 || STRCMP(hi->hi_key, "err_modifiable") == 0) | |
3958 { | |
3959 part = part_from_char(*hi->hi_key); | |
3960 | |
3961 if (!(supported & JO_OUT_IO)) | |
3962 break; | |
3963 opt->jo_set |= JO_OUT_MODIFIABLE << (part - PART_OUT); | |
3964 opt->jo_modifiable[part] = get_tv_number(item); | |
3917 } | 3965 } |
3918 else if (STRCMP(hi->hi_key, "in_top") == 0 | 3966 else if (STRCMP(hi->hi_key, "in_top") == 0 |
3919 || STRCMP(hi->hi_key, "in_bot") == 0) | 3967 || STRCMP(hi->hi_key, "in_bot") == 0) |
3920 { | 3968 { |
3921 linenr_T *lp; | 3969 linenr_T *lp; |