1/* 2 * zle_word.c - word-related editor functions 3 * 4 * This file is part of zsh, the Z shell. 5 * 6 * Copyright (c) 1992-1997 Paul Falstad 7 * All rights reserved. 8 * 9 * Permission is hereby granted, without written agreement and without 10 * license or royalty fees, to use, copy, modify, and distribute this 11 * software and to distribute modified versions of this software for any 12 * purpose, provided that the above copyright notice and the following 13 * two paragraphs appear in all copies of this software. 14 * 15 * In no event shall Paul Falstad or the Zsh Development Group be liable 16 * to any party for direct, indirect, special, incidental, or consequential 17 * damages arising out of the use of this software and its documentation, 18 * even if Paul Falstad and the Zsh Development Group have been advised of 19 * the possibility of such damage. 20 * 21 * Paul Falstad and the Zsh Development Group specifically disclaim any 22 * warranties, including, but not limited to, the implied warranties of 23 * merchantability and fitness for a particular purpose. The software 24 * provided hereunder is on an "as is" basis, and Paul Falstad and the 25 * Zsh Development Group have no obligation to provide maintenance, 26 * support, updates, enhancements, or modifications. 27 * 28 */ 29 30#include "zle.mdh" 31#include "zle_word.pro" 32 33/* 34 * In principle we shouldn't consider a zero-length punctuation 35 * character (i.e. a modifier of some sort) part of the word unless 36 * the base character has. However, we only consider them part of 37 * a word if we so consider all alphanumerics, so the distinction 38 * only applies if the characters are modifying something they probably 39 * ought not to be modifying. It's not really clear we need to 40 * be clever about this not very useful case. 41 */ 42 43/**/ 44int 45forwardword(char **args) 46{ 47 int n = zmult; 48 49 if (n < 0) { 50 int ret; 51 zmult = -n; 52 ret = backwardword(args); 53 zmult = n; 54 return ret; 55 } 56 while (n--) { 57 while (zlecs != zlell && ZC_iword(zleline[zlecs])) 58 INCCS(); 59 if (wordflag && !n) 60 return 0; 61 while (zlecs != zlell && !ZC_iword(zleline[zlecs])) 62 INCCS(); 63 } 64 return 0; 65} 66 67#define Z_vialnum(X) (ZC_ialnum(X) || (ZWC('_') == X)) 68 69/**/ 70int 71viforwardword(char **args) 72{ 73 int n = zmult; 74 75 if (n < 0) { 76 int ret; 77 zmult = -n; 78 ret = backwardword(args); 79 zmult = n; 80 return ret; 81 } 82 while (n--) { 83 if (Z_vialnum(zleline[zlecs])) 84 while (zlecs != zlell && Z_vialnum(zleline[zlecs])) 85 INCCS(); 86 else 87 while (zlecs != zlell && !Z_vialnum(zleline[zlecs]) && !ZC_iblank(zleline[zlecs])) 88 INCCS(); 89 if (wordflag && !n) 90 return 0; 91 while (zlecs != zlell && ZC_inblank(zleline[zlecs])) 92 INCCS(); 93 } 94 return 0; 95} 96 97/**/ 98int 99viforwardblankword(char **args) 100{ 101 int n = zmult; 102 103 if (n < 0) { 104 int ret; 105 zmult = -n; 106 ret = vibackwardblankword(args); 107 zmult = n; 108 return ret; 109 } 110 while (n--) { 111 while (zlecs != zlell && !ZC_iblank(zleline[zlecs])) 112 INCCS(); 113 if (wordflag && !n) 114 return 0; 115 while (zlecs != zlell && ZC_iblank(zleline[zlecs])) 116 INCCS(); 117 } 118 return 0; 119} 120 121/**/ 122int 123emacsforwardword(char **args) 124{ 125 int n = zmult; 126 127 if (n < 0) { 128 int ret; 129 zmult = -n; 130 ret = emacsbackwardword(args); 131 zmult = n; 132 return ret; 133 } 134 while (n--) { 135 while (zlecs != zlell && !ZC_iword(zleline[zlecs])) 136 INCCS(); 137 if (wordflag && !n) 138 return 0; 139 while (zlecs != zlell && ZC_iword(zleline[zlecs])) 140 INCCS(); 141 } 142 return 0; 143} 144 145/**/ 146int 147viforwardblankwordend(UNUSED(char **args)) 148{ 149 int n = zmult; 150 151 if (n < 0) 152 return 1; 153 while (n--) { 154 while (zlecs != zlell) { 155 int pos = zlecs; 156 INCPOS(pos); 157 if (!ZC_iblank(zleline[pos])) 158 break; 159 zlecs = pos; 160 } 161 while (zlecs != zlell) { 162 int pos = zlecs; 163 INCPOS(pos); 164 if (ZC_iblank(zleline[pos])) 165 break; 166 zlecs = pos; 167 } 168 } 169 if (zlecs != zlell && virangeflag) 170 INCCS(); 171 return 0; 172} 173 174/**/ 175int 176viforwardwordend(char **args) 177{ 178 int n = zmult; 179 180 if (n < 0) { 181 int ret; 182 zmult = -n; 183 ret = backwardword(args); 184 zmult = n; 185 return ret; 186 } 187 while (n--) { 188 int pos; 189 while (zlecs != zlell) { 190 pos = zlecs; 191 INCPOS(pos); 192 if (!ZC_inblank(zleline[pos])) 193 break; 194 zlecs = pos; 195 } 196 if (zlecs != zlell) { 197 pos = zlecs; 198 INCPOS(pos); 199 if (Z_vialnum(zleline[pos])) { 200 for (;;) { 201 zlecs = pos; 202 if (zlecs == zlell) 203 break; 204 INCPOS(pos); 205 if (!Z_vialnum(zleline[pos])) 206 break; 207 } 208 } else { 209 for (;;) { 210 zlecs = pos; 211 if (zlecs == zlell) 212 break; 213 INCPOS(pos); 214 if (Z_vialnum(zleline[pos]) || ZC_iblank(zleline[pos])) 215 break; 216 } 217 } 218 } 219 } 220 if (zlecs != zlell && virangeflag) 221 INCCS(); 222 return 0; 223} 224 225/**/ 226int 227backwardword(char **args) 228{ 229 int n = zmult; 230 231 if (n < 0) { 232 int ret; 233 zmult = -n; 234 ret = forwardword(args); 235 zmult = n; 236 return ret; 237 } 238 while (n--) { 239 while (zlecs) { 240 int pos = zlecs; 241 DECPOS(pos); 242 if (ZC_iword(zleline[pos])) 243 break; 244 zlecs = pos; 245 } 246 while (zlecs) { 247 int pos = zlecs; 248 DECPOS(pos); 249 if (!ZC_iword(zleline[pos])) 250 break; 251 zlecs = pos; 252 } 253 } 254 return 0; 255} 256 257/**/ 258int 259vibackwardword(char **args) 260{ 261 int n = zmult; 262 263 if (n < 0) { 264 int ret; 265 zmult = -n; 266 ret = backwardword(args); 267 zmult = n; 268 return ret; 269 } 270 while (n--) { 271 while (zlecs) { 272 int pos = zlecs; 273 DECPOS(pos); 274 if (!ZC_iblank(zleline[pos])) 275 break; 276 zlecs = pos; 277 } 278 if (zlecs) { 279 int pos = zlecs; 280 DECPOS(pos); 281 if (Z_vialnum(zleline[pos])) { 282 for (;;) { 283 zlecs = pos; 284 if (zlecs == 0) 285 break; 286 DECPOS(pos); 287 if (!Z_vialnum(zleline[pos])) 288 break; 289 } 290 } else { 291 for (;;) { 292 zlecs = pos; 293 if (zlecs == 0) 294 break; 295 DECPOS(pos); 296 if (Z_vialnum(zleline[pos]) || ZC_iblank(zleline[pos])) 297 break; 298 } 299 } 300 } 301 } 302 return 0; 303} 304 305/**/ 306int 307vibackwardblankword(char **args) 308{ 309 int n = zmult; 310 311 if (n < 0) { 312 int ret; 313 zmult = -n; 314 ret = viforwardblankword(args); 315 zmult = n; 316 return ret; 317 } 318 while (n--) { 319 while (zlecs) { 320 int pos = zlecs; 321 DECPOS(pos); 322 if (!ZC_iblank(zleline[pos])) 323 break; 324 zlecs = pos; 325 } 326 while (zlecs) { 327 int pos = zlecs; 328 DECPOS(pos); 329 if (ZC_iblank(zleline[pos])) 330 break; 331 zlecs = pos; 332 } 333 } 334 return 0; 335} 336 337/**/ 338int 339emacsbackwardword(char **args) 340{ 341 int n = zmult; 342 343 if (n < 0) { 344 int ret; 345 zmult = -n; 346 ret = emacsforwardword(args); 347 zmult = n; 348 return ret; 349 } 350 while (n--) { 351 while (zlecs) { 352 int pos = zlecs; 353 DECPOS(pos); 354 if (ZC_iword(zleline[pos])) 355 break; 356 zlecs = pos; 357 } 358 while (zlecs) { 359 int pos = zlecs; 360 DECPOS(pos); 361 if (!ZC_iword(zleline[pos])) 362 break; 363 zlecs = pos; 364 } 365 } 366 return 0; 367} 368 369/**/ 370int 371backwarddeleteword(char **args) 372{ 373 int x = zlecs, n = zmult; 374 375 if (n < 0) { 376 int ret; 377 zmult = -n; 378 ret = deleteword(args); 379 zmult = n; 380 return ret; 381 } 382 while (n--) { 383 while (x) { 384 int pos = x; 385 DECPOS(pos); 386 if (ZC_iword(zleline[pos])) 387 break; 388 x = pos; 389 } 390 while (x) { 391 int pos = x; 392 DECPOS(pos); 393 if (!ZC_iword(zleline[pos])) 394 break; 395 x = pos; 396 } 397 } 398 backdel(zlecs - x, CUT_RAW); 399 return 0; 400} 401 402/**/ 403int 404vibackwardkillword(UNUSED(char **args)) 405{ 406 int x = zlecs, lim = (viinsbegin > findbol()) ? viinsbegin : findbol(); 407 int n = zmult; 408 409 if (n < 0) 410 return 1; 411/* this taken from "vibackwardword" */ 412 while (n--) { 413 while (x > lim) { 414 int pos = x; 415 DECPOS(pos); 416 if (!ZC_iblank(zleline[pos])) 417 break; 418 x = pos; 419 } 420 if (x > lim) { 421 int pos = x; 422 DECPOS(pos); 423 if (Z_vialnum(zleline[pos])) { 424 for (;;) { 425 x = pos; 426 if (x <= lim) 427 break; 428 DECPOS(pos); 429 if (!Z_vialnum(zleline[pos])) 430 break; 431 } 432 } else { 433 for (;;) { 434 x = pos; 435 if (x <= lim) 436 break; 437 DECPOS(pos); 438 if (Z_vialnum(zleline[pos]) || ZC_iblank(zleline[pos])) 439 break; 440 } 441 } 442 } 443 } 444 backkill(zlecs - x, CUT_FRONT|CUT_RAW); 445 return 0; 446} 447 448/**/ 449int 450backwardkillword(char **args) 451{ 452 int x = zlecs; 453 int n = zmult; 454 455 if (n < 0) { 456 int ret; 457 zmult = -n; 458 ret = killword(args); 459 zmult = n; 460 return ret; 461 } 462 while (n--) { 463 while (x) { 464 int pos = x; 465 DECPOS(pos); 466 if (ZC_iword(zleline[pos])) 467 break; 468 x = pos; 469 } 470 while (x) { 471 int pos = x; 472 DECPOS(pos); 473 if (!ZC_iword(zleline[pos])) 474 break; 475 x = pos; 476 } 477 } 478 backkill(zlecs - x, CUT_FRONT|CUT_RAW); 479 return 0; 480} 481 482/**/ 483int 484upcaseword(UNUSED(char **args)) 485{ 486 int n = zmult; 487 int neg = n < 0, ocs = zlecs; 488 489 if (neg) 490 n = -n; 491 while (n--) { 492 while (zlecs != zlell && !ZC_iword(zleline[zlecs])) 493 INCCS(); 494 while (zlecs != zlell && ZC_iword(zleline[zlecs])) { 495 zleline[zlecs] = ZC_toupper(zleline[zlecs]); 496 INCCS(); 497 } 498 } 499 if (neg) 500 zlecs = ocs; 501 return 0; 502} 503 504/**/ 505int 506downcaseword(UNUSED(char **args)) 507{ 508 int n = zmult; 509 int neg = n < 0, ocs = zlecs; 510 511 if (neg) 512 n = -n; 513 while (n--) { 514 while (zlecs != zlell && !ZC_iword(zleline[zlecs])) 515 INCCS(); 516 while (zlecs != zlell && ZC_iword(zleline[zlecs])) { 517 zleline[zlecs] = ZC_tolower(zleline[zlecs]); 518 INCCS(); 519 } 520 } 521 if (neg) 522 zlecs = ocs; 523 return 0; 524} 525 526/**/ 527int 528capitalizeword(UNUSED(char **args)) 529{ 530 int first, n = zmult; 531 int neg = n < 0, ocs = zlecs; 532 533 if (neg) 534 n = -n; 535 while (n--) { 536 first = 1; 537 while (zlecs != zlell && !ZC_iword(zleline[zlecs])) 538 INCCS(); 539 while (zlecs != zlell && ZC_iword(zleline[zlecs]) && !ZC_ialpha(zleline[zlecs])) 540 INCCS(); 541 while (zlecs != zlell && ZC_iword(zleline[zlecs])) { 542 zleline[zlecs] = (first) ? ZC_toupper(zleline[zlecs]) : 543 ZC_tolower(zleline[zlecs]); 544 first = 0; 545 INCCS(); 546 } 547 } 548 if (neg) 549 zlecs = ocs; 550 return 0; 551} 552 553/**/ 554int 555deleteword(char **args) 556{ 557 int x = zlecs; 558 int n = zmult; 559 560 if (n < 0) { 561 int ret; 562 zmult = -n; 563 ret = backwarddeleteword(args); 564 zmult = n; 565 return ret; 566 } 567 while (n--) { 568 while (x != zlell && !ZC_iword(zleline[x])) 569 INCPOS(x); 570 while (x != zlell && ZC_iword(zleline[x])) 571 INCPOS(x); 572 } 573 foredel(x - zlecs, CUT_RAW); 574 return 0; 575} 576 577/**/ 578int 579killword(char **args) 580{ 581 int x = zlecs; 582 int n = zmult; 583 584 if (n < 0) { 585 int ret; 586 zmult = -n; 587 ret = backwardkillword(args); 588 zmult = n; 589 return ret; 590 } 591 while (n--) { 592 while (x != zlell && !ZC_iword(zleline[x])) 593 INCPOS(x); 594 while (x != zlell && ZC_iword(zleline[x])) 595 INCPOS(x); 596 } 597 forekill(x - zlecs, CUT_RAW); 598 return 0; 599} 600 601/**/ 602int 603transposewords(UNUSED(char **args)) 604{ 605 int p1, p2, p3, p4, len, x = zlecs, pos; 606 ZLE_STRING_T temp, pp; 607 int n = zmult; 608 int neg = n < 0, ocs = zlecs; 609 610 if (neg) 611 n = -n; 612 while (n--) { 613 while (x != zlell && zleline[x] != ZWC('\n') && !ZC_iword(zleline[x])) 614 INCPOS(x); 615 if (x == zlell || zleline[x] == ZWC('\n')) { 616 x = zlecs; 617 while (x) { 618 if (ZC_iword(zleline[x])) 619 break; 620 pos = x; 621 DECPOS(pos); 622 if (zleline[pos] == ZWC('\n')) 623 break; 624 x = pos; 625 } 626 if (!x) 627 return 1; 628 pos = x; 629 DECPOS(pos); 630 if (zleline[pos] == ZWC('\n')) 631 return 1; 632 x = pos; 633 } 634 for (p4 = x; p4 != zlell && ZC_iword(zleline[p4]); INCPOS(p4)) 635 ; 636 for (p3 = p4; p3; ) { 637 pos = p3; 638 DECPOS(pos); 639 if (!ZC_iword(zleline[pos])) 640 break; 641 p3 = pos; 642 } 643 if (!p3) 644 return 1; 645 for (p2 = p3; p2; ) { 646 pos = p2; 647 DECPOS(pos); 648 if (ZC_iword(zleline[pos])) 649 break; 650 p2 = pos; 651 } 652 if (!p2) 653 return 1; 654 for (p1 = p2; p1; ) { 655 pos = p1; 656 DECPOS(pos); 657 if (!ZC_iword(zleline[pos])) 658 break; 659 p1 = pos; 660 } 661 pp = temp = (ZLE_STRING_T)zhalloc((p4 - p1)*ZLE_CHAR_SIZE); 662 len = p4 - p3; 663 ZS_memcpy(pp, zleline + p3, len); 664 pp += len; 665 len = p3 - p2; 666 ZS_memcpy(pp, zleline + p2, len); 667 pp += len; 668 ZS_memcpy(pp, zleline + p1, p2 - p1); 669 670 ZS_memcpy(zleline + p1, temp, p4 - p1); 671 672 zlecs = p4; 673 } 674 if (neg) 675 zlecs = ocs; 676 return 0; 677} 678