diff options
| author | Richard M. Stallman | 1994-09-23 22:18:59 +0000 |
|---|---|---|
| committer | Richard M. Stallman | 1994-09-23 22:18:59 +0000 |
| commit | 080c45fd0b8ce128a681ebf772fcb07048cde4eb (patch) | |
| tree | 33f5c249a14ae95a489a598b7d61efe9e951f02c /src | |
| parent | a2b38b3c3a102a38dd14df18116a265f320b0b83 (diff) | |
| download | emacs-080c45fd0b8ce128a681ebf772fcb07048cde4eb.tar.gz emacs-080c45fd0b8ce128a681ebf772fcb07048cde4eb.zip | |
(Freplace_match): New 4th arg OBJECT can specify string to replace in.
Diffstat (limited to 'src')
| -rw-r--r-- | src/search.c | 113 |
1 files changed, 103 insertions, 10 deletions
diff --git a/src/search.c b/src/search.c index f3835ff0743..c77f7b7c202 100644 --- a/src/search.c +++ b/src/search.c | |||
| @@ -1186,7 +1186,7 @@ See also the functions `match-beginning', `match-end' and `replace-match'.") | |||
| 1186 | return search_command (regexp, bound, noerror, count, 1, 1); | 1186 | return search_command (regexp, bound, noerror, count, 1, 1); |
| 1187 | } | 1187 | } |
| 1188 | 1188 | ||
| 1189 | DEFUN ("replace-match", Freplace_match, Sreplace_match, 1, 3, 0, | 1189 | DEFUN ("replace-match", Freplace_match, Sreplace_match, 1, 4, 0, |
| 1190 | "Replace text matched by last search with NEWTEXT.\n\ | 1190 | "Replace text matched by last search with NEWTEXT.\n\ |
| 1191 | If second arg FIXEDCASE is non-nil, do not alter case of replacement text.\n\ | 1191 | If second arg FIXEDCASE is non-nil, do not alter case of replacement text.\n\ |
| 1192 | Otherwise maybe capitalize the whole text, or maybe just word initials,\n\ | 1192 | Otherwise maybe capitalize the whole text, or maybe just word initials,\n\ |
| @@ -1202,9 +1202,13 @@ Otherwise treat `\\' as special:\n\ | |||
| 1202 | If Nth parens didn't match, substitute nothing.\n\ | 1202 | If Nth parens didn't match, substitute nothing.\n\ |
| 1203 | `\\\\' means insert one `\\'.\n\ | 1203 | `\\\\' means insert one `\\'.\n\ |
| 1204 | FIXEDCASE and LITERAL are optional arguments.\n\ | 1204 | FIXEDCASE and LITERAL are optional arguments.\n\ |
| 1205 | Leaves point at end of replacement text.") | 1205 | Leaves point at end of replacement text.\n\ |
| 1206 | (newtext, fixedcase, literal) | 1206 | \n\ |
| 1207 | Lisp_Object newtext, fixedcase, literal; | 1207 | The optional fourth argument STRING can be a string to modify.\n\ |
| 1208 | In that case, this function creates and returns a new string\n\ | ||
| 1209 | which is made by replacing the part of STRING that was matched.") | ||
| 1210 | (newtext, fixedcase, literal, string) | ||
| 1211 | Lisp_Object newtext, fixedcase, literal, string; | ||
| 1208 | { | 1212 | { |
| 1209 | enum { nochange, all_caps, cap_initial } case_action; | 1213 | enum { nochange, all_caps, cap_initial } case_action; |
| 1210 | register int pos, last; | 1214 | register int pos, last; |
| @@ -1217,17 +1221,31 @@ Leaves point at end of replacement text.") | |||
| 1217 | 1221 | ||
| 1218 | CHECK_STRING (newtext, 0); | 1222 | CHECK_STRING (newtext, 0); |
| 1219 | 1223 | ||
| 1224 | if (! NILP (string)) | ||
| 1225 | CHECK_STRING (string, 4); | ||
| 1226 | |||
| 1220 | case_action = nochange; /* We tried an initialization */ | 1227 | case_action = nochange; /* We tried an initialization */ |
| 1221 | /* but some C compilers blew it */ | 1228 | /* but some C compilers blew it */ |
| 1222 | 1229 | ||
| 1223 | if (search_regs.num_regs <= 0) | 1230 | if (search_regs.num_regs <= 0) |
| 1224 | error ("replace-match called before any match found"); | 1231 | error ("replace-match called before any match found"); |
| 1225 | 1232 | ||
| 1226 | if (search_regs.start[0] < BEGV | 1233 | if (NILP (string)) |
| 1227 | || search_regs.start[0] > search_regs.end[0] | 1234 | { |
| 1228 | || search_regs.end[0] > ZV) | 1235 | if (search_regs.start[0] < BEGV |
| 1229 | args_out_of_range (make_number (search_regs.start[0]), | 1236 | || search_regs.start[0] > search_regs.end[0] |
| 1230 | make_number (search_regs.end[0])); | 1237 | || search_regs.end[0] > ZV) |
| 1238 | args_out_of_range (make_number (search_regs.start[0]), | ||
| 1239 | make_number (search_regs.end[0])); | ||
| 1240 | } | ||
| 1241 | else | ||
| 1242 | { | ||
| 1243 | if (search_regs.start[0] < 0 | ||
| 1244 | || search_regs.start[0] > search_regs.end[0] | ||
| 1245 | || search_regs.end[0] > XSTRING (string)->size) | ||
| 1246 | args_out_of_range (make_number (search_regs.start[0]), | ||
| 1247 | make_number (search_regs.end[0])); | ||
| 1248 | } | ||
| 1231 | 1249 | ||
| 1232 | if (NILP (fixedcase)) | 1250 | if (NILP (fixedcase)) |
| 1233 | { | 1251 | { |
| @@ -1246,7 +1264,11 @@ Leaves point at end of replacement text.") | |||
| 1246 | 1264 | ||
| 1247 | for (pos = search_regs.start[0]; pos < last; pos++) | 1265 | for (pos = search_regs.start[0]; pos < last; pos++) |
| 1248 | { | 1266 | { |
| 1249 | c = FETCH_CHAR (pos); | 1267 | if (NILP (string)) |
| 1268 | c = FETCH_CHAR (pos); | ||
| 1269 | else | ||
| 1270 | c = XSTRING (string)->data[pos]; | ||
| 1271 | |||
| 1250 | if (LOWERCASEP (c)) | 1272 | if (LOWERCASEP (c)) |
| 1251 | { | 1273 | { |
| 1252 | /* Cannot be all caps if any original char is lower case */ | 1274 | /* Cannot be all caps if any original char is lower case */ |
| @@ -1291,6 +1313,77 @@ Leaves point at end of replacement text.") | |||
| 1291 | case_action = nochange; | 1313 | case_action = nochange; |
| 1292 | } | 1314 | } |
| 1293 | 1315 | ||
| 1316 | /* Do replacement in a string. */ | ||
| 1317 | if (!NILP (string)) | ||
| 1318 | { | ||
| 1319 | Lisp_Object before, after; | ||
| 1320 | |||
| 1321 | before = Fsubstring (string, make_number (0), | ||
| 1322 | make_number (search_regs.start[0])); | ||
| 1323 | after = Fsubstring (string, make_number (search_regs.end[0]), Qnil); | ||
| 1324 | |||
| 1325 | /* Do case substitution into NEWTEXT if desired. */ | ||
| 1326 | if (NILP (literal)) | ||
| 1327 | { | ||
| 1328 | int lastpos = -1; | ||
| 1329 | /* We build up the substituted string in ACCUM. */ | ||
| 1330 | Lisp_Object accum; | ||
| 1331 | Lisp_Object middle; | ||
| 1332 | |||
| 1333 | accum = Qnil; | ||
| 1334 | |||
| 1335 | for (pos = 0; pos < XSTRING (newtext)->size; pos++) | ||
| 1336 | { | ||
| 1337 | int substart = -1; | ||
| 1338 | int subend; | ||
| 1339 | |||
| 1340 | c = XSTRING (newtext)->data[pos]; | ||
| 1341 | if (c == '\\') | ||
| 1342 | { | ||
| 1343 | c = XSTRING (newtext)->data[++pos]; | ||
| 1344 | if (c == '&') | ||
| 1345 | { | ||
| 1346 | substart = search_regs.start[0]; | ||
| 1347 | subend = search_regs.end[0]; | ||
| 1348 | } | ||
| 1349 | else if (c >= '1' && c <= '9' && c <= search_regs.num_regs + '0') | ||
| 1350 | { | ||
| 1351 | if (search_regs.start[c - '0'] >= 1) | ||
| 1352 | { | ||
| 1353 | substart = search_regs.start[c - '0']; | ||
| 1354 | subend = search_regs.end[c - '0']; | ||
| 1355 | } | ||
| 1356 | } | ||
| 1357 | } | ||
| 1358 | if (substart >= 0) | ||
| 1359 | { | ||
| 1360 | if (pos - 1 != lastpos + 1) | ||
| 1361 | middle = Fsubstring (newtext, lastpos + 1, pos - 1); | ||
| 1362 | else | ||
| 1363 | middle = Qnil; | ||
| 1364 | accum = concat3 (accum, middle, | ||
| 1365 | Fsubstring (string, make_number (substart), | ||
| 1366 | make_number (subend))); | ||
| 1367 | lastpos = pos; | ||
| 1368 | } | ||
| 1369 | } | ||
| 1370 | |||
| 1371 | if (pos != lastpos + 1) | ||
| 1372 | middle = Fsubstring (newtext, lastpos + 1, pos); | ||
| 1373 | else | ||
| 1374 | middle = Qnil; | ||
| 1375 | |||
| 1376 | newtext = concat2 (accum, middle); | ||
| 1377 | } | ||
| 1378 | |||
| 1379 | if (case_action == all_caps) | ||
| 1380 | newtext = Fupcase (newtext); | ||
| 1381 | else if (case_action == cap_initial) | ||
| 1382 | newtext = upcase_initials (newtext); | ||
| 1383 | |||
| 1384 | return concat3 (before, newtext, after); | ||
| 1385 | } | ||
| 1386 | |||
| 1294 | /* We insert the replacement text before the old text, and then | 1387 | /* We insert the replacement text before the old text, and then |
| 1295 | delete the original text. This means that markers at the | 1388 | delete the original text. This means that markers at the |
| 1296 | beginning or end of the original will float to the corresponding | 1389 | beginning or end of the original will float to the corresponding |