Mercurial > vim
comparison src/ex_cmds.c @ 294:1c1cbdc42f75 v7.0077
updated for version 7.0077
author | vimboss |
---|---|
date | Tue, 31 May 2005 22:22:17 +0000 |
parents | 9a10e4d195b3 |
children | 006e9c8a6a8a |
comparison
equal
deleted
inserted
replaced
293:f811be6fa9b5 | 294:1c1cbdc42f75 |
---|---|
264 /* Buffer for one line used during sorting. It's allocated to contain the | 264 /* Buffer for one line used during sorting. It's allocated to contain the |
265 * longest line being sorted. */ | 265 * longest line being sorted. */ |
266 static char_u *sortbuf; | 266 static char_u *sortbuf; |
267 | 267 |
268 static int sort_ic; /* ignore case */ | 268 static int sort_ic; /* ignore case */ |
269 static int sort_nr; /* sort on number */ | |
270 | |
271 /* Struct to store info to be sorted. */ | |
272 typedef struct | |
273 { | |
274 linenr_T lnum; /* line number */ | |
275 long col_nr; /* column number or number */ | |
276 } sorti_T; | |
269 | 277 |
270 static int | 278 static int |
271 #ifdef __BORLANDC__ | 279 #ifdef __BORLANDC__ |
272 _RTLENTRYF | 280 _RTLENTRYF |
273 #endif | 281 #endif |
279 #endif | 287 #endif |
280 sort_compare(s1, s2) | 288 sort_compare(s1, s2) |
281 const void *s1; | 289 const void *s1; |
282 const void *s2; | 290 const void *s2; |
283 { | 291 { |
284 lpos_T l1 = *(lpos_T *)s1; | 292 sorti_T l1 = *(sorti_T *)s1; |
285 lpos_T l2 = *(lpos_T *)s2; | 293 sorti_T l2 = *(sorti_T *)s2; |
286 char_u *s; | 294 char_u *s; |
295 | |
296 /* When sorting numbers "col_nr" is the number, not the column number. */ | |
297 if (sort_nr) | |
298 return l1.col_nr - l2.col_nr; | |
287 | 299 |
288 /* We need to copy one line into "sortbuf", because there is no guarantee | 300 /* We need to copy one line into "sortbuf", because there is no guarantee |
289 * that the first pointer becomes invalid when obtaining the second one. */ | 301 * that the first pointer becomes invalid when obtaining the second one. */ |
290 STRCPY(sortbuf, ml_get(l1.lnum) + l1.col); | 302 STRCPY(sortbuf, ml_get(l1.lnum) + l1.col_nr); |
291 s = ml_get(l2.lnum) + l2.col; | 303 s = ml_get(l2.lnum) + l2.col_nr; |
304 | |
292 return sort_ic ? STRICMP(sortbuf, s) : STRCMP(sortbuf, s); | 305 return sort_ic ? STRICMP(sortbuf, s) : STRCMP(sortbuf, s); |
293 } | 306 } |
294 | 307 |
295 /* | 308 /* |
296 * ":sort". | 309 * ":sort". |
301 { | 314 { |
302 regmatch_T regmatch; | 315 regmatch_T regmatch; |
303 int len; | 316 int len; |
304 linenr_T lnum; | 317 linenr_T lnum; |
305 long maxlen = 0; | 318 long maxlen = 0; |
306 lpos_T *nrs; | 319 sorti_T *nrs; |
307 size_t count = eap->line2 - eap->line1 + 1; | 320 size_t count = eap->line2 - eap->line1 + 1; |
308 int i; | 321 size_t i; |
309 char_u *p; | 322 char_u *p; |
310 char_u *s; | 323 char_u *s; |
311 int unique = FALSE; | 324 int unique = FALSE; |
312 long deleted; | 325 long deleted; |
326 colnr_T col; | |
327 int sort_oct; /* sort on octal number */ | |
328 int sort_hex; /* sort on hex number */ | |
313 | 329 |
314 if (u_save((linenr_T)(eap->line1 - 1), (linenr_T)(eap->line2 + 1)) == FAIL) | 330 if (u_save((linenr_T)(eap->line1 - 1), (linenr_T)(eap->line2 + 1)) == FAIL) |
315 return; | 331 return; |
316 sortbuf = NULL; | 332 sortbuf = NULL; |
317 regmatch.regprog = NULL; | 333 regmatch.regprog = NULL; |
318 nrs = (lpos_T *)lalloc((long_u)(count * sizeof(lpos_T)), TRUE); | 334 nrs = (sorti_T *)lalloc((long_u)(count * sizeof(sorti_T)), TRUE); |
319 if (nrs == NULL) | 335 if (nrs == NULL) |
320 goto theend; | 336 goto theend; |
337 | |
338 sort_ic = sort_nr = sort_oct = sort_hex = 0; | |
321 | 339 |
322 for (p = eap->arg; *p != NUL; ++p) | 340 for (p = eap->arg; *p != NUL; ++p) |
323 { | 341 { |
324 if (vim_iswhite(*p)) | 342 if (vim_iswhite(*p)) |
325 ; | 343 ; |
326 else if (*p == 'i') | 344 else if (*p == 'i') |
327 sort_ic = TRUE; | 345 sort_ic = TRUE; |
346 else if (*p == 'n') | |
347 sort_nr = 2; | |
348 else if (*p == 'o') | |
349 sort_oct = 2; | |
350 else if (*p == 'x') | |
351 sort_hex = 2; | |
328 else if (*p == 'u') | 352 else if (*p == 'u') |
329 unique = TRUE; | 353 unique = TRUE; |
330 else if (*p == '"') /* comment start */ | 354 else if (*p == '"') /* comment start */ |
331 break; | 355 break; |
332 else if (check_nextcmd(p) != NULL) | 356 else if (check_nextcmd(p) != NULL) |
354 EMSG2(_(e_invarg2), p); | 378 EMSG2(_(e_invarg2), p); |
355 goto theend; | 379 goto theend; |
356 } | 380 } |
357 } | 381 } |
358 | 382 |
383 /* Can only have one of 'n', 'o' and 'x'. */ | |
384 if (sort_nr + sort_oct + sort_hex > 2) | |
385 { | |
386 EMSG(_(e_invarg)); | |
387 goto theend; | |
388 } | |
389 | |
390 /* From here on "sort_nr" is used as a flag for any number sorting. */ | |
391 sort_nr += sort_oct + sort_hex; | |
392 | |
359 /* | 393 /* |
360 * Make an array with all line numbers, so that we don't have to copy all | 394 * Make an array with all line numbers. This avoids having to copy all |
361 * the lines into allocated memory. | 395 * the lines into allocated memory. |
362 * Also get the longest line length. | 396 * When sorting on strings "col_nr" is de offset in the line, for numbers |
397 * sorting it's the number to sort on. This means the pattern matching | |
398 * and number conversion only has to be done once per line. | |
399 * Also get the longest line length for allocating "sortbuf". | |
363 */ | 400 */ |
364 for (lnum = eap->line1; lnum <= eap->line2; ++lnum) | 401 for (lnum = eap->line1; lnum <= eap->line2; ++lnum) |
365 { | 402 { |
366 nrs[lnum - eap->line1].lnum = lnum; | |
367 nrs[lnum - eap->line1].col = 0; | |
368 | |
369 s = ml_get(lnum); | 403 s = ml_get(lnum); |
370 if (regmatch.regprog != NULL && vim_regexec(®match, s, 0)) | |
371 nrs[lnum - eap->line1].col = regmatch.endp[0] - s; | |
372 | |
373 len = STRLEN(s); | 404 len = STRLEN(s); |
374 if (maxlen < len) | 405 if (maxlen < len) |
375 maxlen = len; | 406 maxlen = len; |
376 } | 407 |
377 | 408 if (regmatch.regprog != NULL && vim_regexec(®match, s, 0)) |
409 col = regmatch.endp[0] - s; | |
410 else | |
411 col = 0; | |
412 | |
413 if (sort_nr) | |
414 { | |
415 /* Sorting on number: Store the number itself. */ | |
416 if (sort_hex) | |
417 s = skiptohex(s + col); | |
418 else | |
419 s = skiptodigit(s + col); | |
420 vim_str2nr(s, NULL, NULL, sort_oct, sort_hex, | |
421 &nrs[lnum - eap->line1].col_nr, NULL); | |
422 } | |
423 else | |
424 /* Store the column to sort at. */ | |
425 nrs[lnum - eap->line1].col_nr = col; | |
426 | |
427 nrs[lnum - eap->line1].lnum = lnum; | |
428 } | |
429 | |
430 /* Allocate a buffer that can hold the longest line. */ | |
378 sortbuf = alloc((unsigned)maxlen + 1); | 431 sortbuf = alloc((unsigned)maxlen + 1); |
379 if (sortbuf == NULL) | 432 if (sortbuf == NULL) |
380 goto theend; | 433 goto theend; |
381 | 434 |
382 /* sort the array of line numbers */ | 435 /* sort the array of line numbers */ |
383 qsort((void *)nrs, count, sizeof(lpos_T), sort_compare); | 436 qsort((void *)nrs, count, sizeof(sorti_T), sort_compare); |
384 | 437 |
385 /* Insert the lines in the sorted order below the last one. */ | 438 /* Insert the lines in the sorted order below the last one. */ |
386 lnum = eap->line2; | 439 lnum = eap->line2; |
387 for (i = 0; i < count; ++i) | 440 for (i = 0; i < count; ++i) |
388 { | 441 { |
390 if (!unique || i == 0 | 443 if (!unique || i == 0 |
391 || (sort_ic ? STRICMP(s, sortbuf) : STRCMP(s, sortbuf)) != 0) | 444 || (sort_ic ? STRICMP(s, sortbuf) : STRCMP(s, sortbuf)) != 0) |
392 { | 445 { |
393 if (ml_append(lnum++, s, (colnr_T)0, FALSE) == FAIL) | 446 if (ml_append(lnum++, s, (colnr_T)0, FALSE) == FAIL) |
394 break; | 447 break; |
395 STRCPY(sortbuf, s); | 448 if (unique) |
449 STRCPY(sortbuf, s); | |
396 } | 450 } |
397 } | 451 } |
398 | 452 |
399 /* delete the original lines if appending worked */ | 453 /* delete the original lines if appending worked */ |
400 if (i == count) | 454 if (i == count) |
401 for (i = 0; i < count; ++i) | 455 for (i = 0; i < count; ++i) |
402 ml_delete(eap->line1, FALSE); | 456 ml_delete(eap->line1, FALSE); |
403 else | 457 else |
404 count = 0; | 458 count = 0; |
405 | 459 |
460 /* Adjust marks for deleted (or added) lines and prepare for displaying. */ | |
406 deleted = count - (lnum - eap->line2); | 461 deleted = count - (lnum - eap->line2); |
407 if (deleted > 0) | 462 if (deleted > 0) |
408 mark_adjust(eap->line2 - deleted, eap->line2, (long)MAXLNUM, -deleted); | 463 mark_adjust(eap->line2 - deleted, eap->line2, (long)MAXLNUM, -deleted); |
409 else if (deleted < 0) | 464 else if (deleted < 0) |
410 mark_adjust(eap->line2, MAXLNUM, -deleted, 0L); | 465 mark_adjust(eap->line2, MAXLNUM, -deleted, 0L); |
411 changed_lines(eap->line1, 0, eap->line2 + 1, -deleted); | 466 changed_lines(eap->line1, 0, eap->line2 + 1, -deleted); |
467 | |
412 curwin->w_cursor.lnum = eap->line1; | 468 curwin->w_cursor.lnum = eap->line1; |
413 beginline(BL_WHITE | BL_FIX); | 469 beginline(BL_WHITE | BL_FIX); |
414 | 470 |
415 theend: | 471 theend: |
416 vim_free(nrs); | 472 vim_free(nrs); |
1530 if (fname == NULL) | 1586 if (fname == NULL) |
1531 return FAIL; | 1587 return FAIL; |
1532 fp = mch_fopen((char *)fname, READBIN); | 1588 fp = mch_fopen((char *)fname, READBIN); |
1533 | 1589 |
1534 if (p_verbose > 0) | 1590 if (p_verbose > 0) |
1591 { | |
1592 verbose_enter(); | |
1535 smsg((char_u *)_("Reading viminfo file \"%s\"%s%s%s"), | 1593 smsg((char_u *)_("Reading viminfo file \"%s\"%s%s%s"), |
1536 fname, | 1594 fname, |
1537 want_info ? _(" info") : "", | 1595 want_info ? _(" info") : "", |
1538 want_marks ? _(" marks") : "", | 1596 want_marks ? _(" marks") : "", |
1539 fp == NULL ? _(" FAILED") : ""); | 1597 fp == NULL ? _(" FAILED") : ""); |
1598 verbose_leave(); | |
1599 } | |
1540 | 1600 |
1541 vim_free(fname); | 1601 vim_free(fname); |
1542 if (fp == NULL) | 1602 if (fp == NULL) |
1543 return FAIL; | 1603 return FAIL; |
1544 | 1604 |
1758 fclose(fp_in); | 1818 fclose(fp_in); |
1759 goto end; | 1819 goto end; |
1760 } | 1820 } |
1761 | 1821 |
1762 if (p_verbose > 0) | 1822 if (p_verbose > 0) |
1823 { | |
1824 verbose_enter(); | |
1763 smsg((char_u *)_("Writing viminfo file \"%s\""), fname); | 1825 smsg((char_u *)_("Writing viminfo file \"%s\""), fname); |
1826 verbose_leave(); | |
1827 } | |
1764 | 1828 |
1765 viminfo_errcnt = 0; | 1829 viminfo_errcnt = 0; |
1766 do_viminfo(fp_in, fp_out, !forceit, !forceit, FALSE); | 1830 do_viminfo(fp_in, fp_out, !forceit, !forceit, FALSE); |
1767 | 1831 |
1768 fclose(fp_out); /* errors are ignored !? */ | 1832 fclose(fp_out); /* errors are ignored !? */ |