1 23 24 package org.gjt.sp.jedit.search; 25 26 import bsh.*; 28 import java.awt.*; 29 import javax.swing.JOptionPane ; 30 import javax.swing.text.Segment ; 31 import org.gjt.sp.jedit.*; 32 import org.gjt.sp.jedit.gui.TextAreaDialog; 33 import org.gjt.sp.jedit.io.VFSManager; 34 import org.gjt.sp.jedit.msg.SearchSettingsChanged; 35 import org.gjt.sp.jedit.textarea.*; 36 import org.gjt.sp.util.SegmentCharSequence; 37 import org.gjt.sp.util.Log; 38 40 67 public class SearchAndReplace 68 { 69 71 76 public static void setSearchString(String search) 77 { 78 if(search.equals(SearchAndReplace.search)) 79 return; 80 81 SearchAndReplace.search = search; 82 matcher = null; 83 84 EditBus.send(new SearchSettingsChanged(null)); 85 } 87 91 public static String getSearchString() 92 { 93 return search; 94 } 96 101 public static void setReplaceString(String replace) 102 { 103 if(replace.equals(SearchAndReplace.replace)) 104 return; 105 106 SearchAndReplace.replace = replace; 107 108 EditBus.send(new SearchSettingsChanged(null)); 109 } 111 115 public static String getReplaceString() 116 { 117 return replace; 118 } 120 126 public static void setIgnoreCase(boolean ignoreCase) 127 { 128 if(ignoreCase == SearchAndReplace.ignoreCase) 129 return; 130 131 SearchAndReplace.ignoreCase = ignoreCase; 132 matcher = null; 133 134 EditBus.send(new SearchSettingsChanged(null)); 135 } 137 143 public static boolean getIgnoreCase() 144 { 145 return ignoreCase; 146 } 148 154 public static void setRegexp(boolean regexp) 155 { 156 if(regexp == SearchAndReplace.regexp) 157 return; 158 159 SearchAndReplace.regexp = regexp; 160 if(regexp && reverse) 161 reverse = false; 162 163 matcher = null; 164 165 EditBus.send(new SearchSettingsChanged(null)); 166 } 168 173 public static boolean getRegexp() 174 { 175 return regexp; 176 } 178 187 public static void setReverseSearch(boolean reverse) 188 { 189 if(reverse == SearchAndReplace.reverse) 190 return; 191 192 SearchAndReplace.reverse = reverse; 193 194 EditBus.send(new SearchSettingsChanged(null)); 195 } 197 203 public static boolean getReverseSearch() 204 { 205 return reverse; 206 } 208 214 public static void setBeanShellReplace(boolean beanshell) 215 { 216 if(beanshell == SearchAndReplace.beanshell) 217 return; 218 219 SearchAndReplace.beanshell = beanshell; 220 221 EditBus.send(new SearchSettingsChanged(null)); 222 } 224 230 public static boolean getBeanShellReplace() 231 { 232 return beanshell; 233 } 235 242 public static void setAutoWrapAround(boolean wrap) 243 { 244 if(wrap == SearchAndReplace.wrap) 245 return; 246 247 SearchAndReplace.wrap = wrap; 248 249 EditBus.send(new SearchSettingsChanged(null)); 250 } 252 257 public static boolean getAutoWrapAround() 258 { 259 return wrap; 260 } 262 269 public static void setSearchMatcher(SearchMatcher matcher) 270 { 271 SearchAndReplace.matcher = matcher; 272 273 EditBus.send(new SearchSettingsChanged(null)); 274 } 276 285 public static SearchMatcher getSearchMatcher() 286 throws Exception { 287 if (matcher != null) 288 return matcher; 289 290 if (search == null || "".equals(search)) 291 return null; 292 293 if (regexp) 294 matcher = new PatternSearchMatcher(search, ignoreCase); 295 else 296 matcher = new BoyerMooreSearchMatcher(search, ignoreCase); 297 298 if (matcher.nextMatch("", true, true, true, false) != null) { 299 Log.log(Log.WARNING, SearchAndReplace.class, "The matcher " + matcher + " can match empty string !"); 300 matcher = null; 301 } 302 303 return matcher; 304 } 306 314 public static void setSearchFileSet(SearchFileSet fileset) 315 { 316 SearchAndReplace.fileset = fileset; 317 318 EditBus.send(new SearchSettingsChanged(null)); 319 } 321 325 public static SearchFileSet getSearchFileSet() 326 { 327 return fileset; 328 } 330 336 public static boolean getSmartCaseReplace() 337 { 338 return (replace != null 339 && TextUtilities.getStringCase(replace) 340 == TextUtilities.LOWER_CASE); 341 } 343 345 347 353 public static boolean hyperSearch(View view) 354 { 355 return hyperSearch(view,false); 356 } 358 367 public static boolean hyperSearch(View view, boolean selection) 368 { 369 Component comp = SearchDialog.getSearchDialog(view); 371 if(comp == null) 372 comp = view; 373 374 record(view,"hyperSearch(view," + selection + ')',false, 375 !selection); 376 377 view.getDockableWindowManager().addDockableWindow( 378 HyperSearchResults.NAME); 379 final HyperSearchResults results = (HyperSearchResults) 380 view.getDockableWindowManager() 381 .getDockable(HyperSearchResults.NAME); 382 results.searchStarted(); 383 384 try 385 { 386 SearchMatcher matcher = getSearchMatcher(); 387 if(matcher == null) 388 { 389 view.getToolkit().beep(); 390 results.searchFailed(); 391 return false; 392 } 393 394 Selection[] s; 395 if(selection) 396 { 397 s = view.getTextArea().getSelection(); 398 if(s == null) 399 { 400 results.searchFailed(); 401 return false; 402 } 403 } 404 else 405 s = null; 406 VFSManager.runInWorkThread(new HyperSearchRequest(view, 407 matcher,results,s)); 408 return true; 409 } 410 catch(Exception e) 411 { 412 results.searchFailed(); 413 handleError(comp,e); 414 return false; 415 } 416 } 418 424 public static boolean find(View view) 425 { 426 Component comp = SearchDialog.getSearchDialog(view); 428 if(comp == null || !comp.isShowing()) 429 comp = view; 430 431 String path = fileset.getNextFile(view,null); 432 if(path == null) 433 { 434 GUIUtilities.error(comp,"empty-fileset",null); 435 return false; 436 } 437 438 boolean _reverse = reverse && fileset instanceof CurrentBufferSet; 439 if(_reverse && regexp) 440 { 441 GUIUtilities.error(comp,"regexp-reverse",null); 442 return false; 443 } 444 445 try 446 { 447 view.showWaitCursor(); 448 449 SearchMatcher matcher = getSearchMatcher(); 450 if(matcher == null) 451 { 452 view.getToolkit().beep(); 453 return false; 454 } 455 456 record(view,"find(view)",false,true); 457 458 boolean repeat = false; 459 loop: for(;;) 460 { 461 while(path != null) 462 { 463 Buffer buffer = jEdit.openTemporary( 464 view,null,path,false); 465 466 474 path = fileset.getNextFile(view,path); 475 476 if(buffer == null) 477 continue loop; 478 479 if(!buffer.isLoaded()) 481 VFSManager.waitForRequests(); 482 483 int start; 484 485 if(view.getBuffer() == buffer && !repeat) 486 { 487 JEditTextArea textArea = view.getTextArea(); 488 Selection s = textArea.getSelectionAtOffset( 489 textArea.getCaretPosition()); 490 if(s == null) 491 start = textArea.getCaretPosition(); 492 else if(_reverse) 493 start = s.getStart(); 494 else 495 start = s.getEnd(); 496 } 497 else if(_reverse) 498 start = buffer.getLength(); 499 else 500 start = 0; 501 502 boolean _search = true; 503 if (!_reverse && matcher.isMatchingEOL()) 504 { 505 if (start < buffer.getLength()) 506 start += 1; 507 else 508 _search = false; 509 } 510 511 if(_search && find(view,buffer,start,repeat,_reverse)) 512 return true; 513 } 514 515 if(repeat) 516 { 517 if(!BeanShell.isScriptRunning()) 518 { 519 view.getStatus().setMessageAndClear( 520 jEdit.getProperty("view.status.search-not-found")); 521 522 view.getToolkit().beep(); 523 } 524 return false; 525 } 526 527 boolean restart; 528 529 if(wrap) 534 { 535 if(!BeanShell.isScriptRunning()) 536 { 537 view.getStatus().setMessageAndClear( 538 jEdit.getProperty("view.status.auto-wrap")); 539 if(jEdit.getBooleanProperty("search.beepOnSearchAutoWrap")) 541 { 542 view.getToolkit().beep(); 543 } 544 } 545 restart = true; 546 } 547 else if(BeanShell.isScriptRunning()) 548 { 549 restart = false; 550 } 551 else 552 { 553 Integer [] args = {Integer.valueOf(_reverse ? 1 : 0)}; 554 int result = GUIUtilities.confirm(comp, 555 "keepsearching",args, 556 JOptionPane.YES_NO_OPTION, 557 JOptionPane.QUESTION_MESSAGE); 558 restart = (result == JOptionPane.YES_OPTION); 559 } 560 561 if(restart) 562 { 563 path = fileset.getFirstFile(view); 565 repeat = true; 566 } 567 else 568 break loop; 569 } 570 } 571 catch(Exception e) 572 { 573 handleError(comp,e); 574 } 575 finally 576 { 577 view.hideWaitCursor(); 578 } 579 580 return false; 581 } 583 591 public static boolean find(View view, Buffer buffer, int start) 592 throws Exception 593 { 594 return find(view,buffer,start,false,false); 595 } 597 607 public static boolean find(View view, Buffer buffer, int start, 608 boolean firstTime, boolean reverse) throws Exception 609 { 610 SearchMatcher matcher = getSearchMatcher(); 611 if(matcher == null) 612 { 613 view.getToolkit().beep(); 614 return false; 615 } 616 617 Segment text = new Segment (); 618 if(reverse) 619 buffer.getText(0,start,text); 620 else 621 buffer.getText(start,buffer.getLength() - start,text); 622 623 SearchMatcher.Match match = matcher.nextMatch(new SegmentCharSequence(text,reverse), 629 start == 0,true,firstTime,reverse); 630 631 if(match != null) 632 { 633 jEdit.commitTemporary(buffer); 634 view.setBuffer(buffer); 635 JEditTextArea textArea = view.getTextArea(); 636 637 if(reverse) 638 { 639 textArea.setSelection(new Selection.Range( 640 start - match.end, 641 start - match.start)); 642 textArea.scrollTo(start - match.start,false); 644 textArea.moveCaretPosition(start - match.end); 645 } 646 else 647 { 648 textArea.setSelection(new Selection.Range( 649 start + match.start, 650 start + match.end)); 651 textArea.moveCaretPosition(start + match.end); 652 textArea.scrollTo(start + match.start,false); 654 } 655 656 return true; 657 } 658 else 659 return false; 660 } 662 668 public static boolean replace(View view) 669 { 670 Component comp = SearchDialog.getSearchDialog(view); 672 if(comp == null) 673 comp = view; 674 675 JEditTextArea textArea = view.getTextArea(); 676 677 Buffer buffer = view.getBuffer(); 678 if(!buffer.isEditable()) 679 return false; 680 681 boolean smartCaseReplace = getSmartCaseReplace(); 682 683 Selection[] selection = textArea.getSelection(); 684 if (selection.length == 0) 685 { 686 try 687 { 688 SearchMatcher matcher = getSearchMatcher(); 689 if ((matcher != null) && (matcher.isMatchingEOL())) 690 { 691 int caretPosition = textArea.getCaretPosition(); 692 selection = new Selection[] { new Selection.Range(caretPosition,caretPosition) }; 693 } 694 else 695 { 696 view.getToolkit().beep(); 697 return false; 698 } 699 } 700 catch (Exception e) 701 { 702 handleError(comp,e); 703 return false; 704 } 705 } 706 707 record(view,"replace(view)",true,false); 708 709 int caret = textArea.getCaretPosition(); 711 Selection s = textArea.getSelectionAtOffset(caret); 712 if(s != null) 713 caret = s.getStart(); 714 715 try 716 { 717 buffer.beginCompoundEdit(); 718 719 SearchMatcher matcher = getSearchMatcher(); 720 if(matcher == null) 721 return false; 722 723 initReplace(); 724 725 int retVal = 0; 726 727 for(int i = 0; i < selection.length; i++) 728 { 729 s = selection[i]; 730 731 retVal += replaceInSelection(view,textArea, 732 buffer,matcher,smartCaseReplace,s); 733 } 734 735 boolean _reverse = !regexp && reverse && fileset instanceof CurrentBufferSet; 736 if(_reverse) 737 { 738 textArea.moveCaretPosition(caret); 741 } 742 else 743 { 744 s = textArea.getSelectionAtOffset( 745 textArea.getCaretPosition()); 746 if(s != null) 747 textArea.moveCaretPosition(s.getEnd()); 748 } 749 750 if(!BeanShell.isScriptRunning()) 751 { 752 Object [] args = {Integer.valueOf(retVal), 753 Integer.valueOf(1)}; 754 view.getStatus().setMessageAndClear(jEdit.getProperty( 755 "view.status.replace-all",args)); 756 } 757 758 if(retVal == 0) 759 { 760 view.getToolkit().beep(); 761 return false; 762 } 763 764 return true; 765 } 766 catch(Exception e) 767 { 768 handleError(comp,e); 769 } 770 finally 771 { 772 buffer.endCompoundEdit(); 773 } 774 775 return false; 776 } 778 787 public static boolean replace(View view, Buffer buffer, int start, int end) 788 { 789 if(!buffer.isEditable()) 790 return false; 791 792 Component comp = SearchDialog.getSearchDialog(view); 794 if(comp == null) 795 comp = view; 796 797 boolean smartCaseReplace = getSmartCaseReplace(); 798 799 try 800 { 801 buffer.beginCompoundEdit(); 802 803 SearchMatcher matcher = getSearchMatcher(); 804 if(matcher == null) 805 return false; 806 807 initReplace(); 808 809 int retVal = 0; 810 811 retVal += _replace(view,buffer,matcher,start,end, 812 smartCaseReplace); 813 814 if(retVal != 0) 815 return true; 816 } 817 catch(Exception e) 818 { 819 handleError(comp,e); 820 } 821 finally 822 { 823 buffer.endCompoundEdit(); 824 } 825 826 return false; 827 } 829 835 public static boolean replaceAll(View view) 836 { 837 Component comp = SearchDialog.getSearchDialog(view); 839 if(comp == null) 840 comp = view; 841 842 if(fileset.getFileCount(view) == 0) 843 { 844 GUIUtilities.error(comp,"empty-fileset",null); 845 return false; 846 } 847 848 record(view,"replaceAll(view)",true,true); 849 850 view.showWaitCursor(); 851 852 boolean smartCaseReplace = (replace != null 853 && TextUtilities.getStringCase(replace) 854 == TextUtilities.LOWER_CASE); 855 856 int fileCount = 0; 857 int occurCount = 0; 858 try 859 { 860 SearchMatcher matcher = getSearchMatcher(); 861 if(matcher == null) 862 return false; 863 864 initReplace(); 865 866 String path = fileset.getFirstFile(view); 867 loop: while(path != null) 868 { 869 Buffer buffer = jEdit.openTemporary( 870 view,null,path,false); 871 872 880 path = fileset.getNextFile(view,path); 881 882 if(buffer == null) 883 continue loop; 884 885 if(buffer.isPerformingIO()) 887 VFSManager.waitForRequests(); 888 889 if(!buffer.isEditable()) 890 continue loop; 891 892 int retVal = 0; 895 896 try 897 { 898 buffer.beginCompoundEdit(); 899 retVal = _replace(view,buffer,matcher, 900 0,buffer.getLength(), 901 smartCaseReplace); 902 } 903 finally 904 { 905 buffer.endCompoundEdit(); 906 } 907 908 if(retVal != 0) 909 { 910 fileCount++; 911 occurCount += retVal; 912 jEdit.commitTemporary(buffer); 913 } 914 } 915 } 916 catch(Exception e) 917 { 918 handleError(comp,e); 919 } 920 finally 921 { 922 view.hideWaitCursor(); 923 } 924 925 926 if(!BeanShell.isScriptRunning()) 927 { 928 Object [] args = {Integer.valueOf(occurCount), 929 Integer.valueOf(fileCount)}; 930 view.getStatus().setMessageAndClear(jEdit.getProperty( 931 "view.status.replace-all",args)); 932 if(occurCount == 0) 933 view.getToolkit().beep(); 934 } 935 936 return (fileCount != 0); 937 } 939 941 947 public static String escapeRegexp(String str, boolean multiline) 948 { 949 return MiscUtilities.charsToEscapes(str, 950 "\r\t\\()[]{}$^*+?|." 951 + (multiline ? "" : "\n")); 952 } 954 958 public static void load() 959 { 960 search = jEdit.getProperty("search.find.value"); 961 replace = jEdit.getProperty("search.replace.value"); 962 ignoreCase = jEdit.getBooleanProperty("search.ignoreCase.toggle"); 963 regexp = jEdit.getBooleanProperty("search.regexp.toggle"); 964 beanshell = jEdit.getBooleanProperty("search.beanshell.toggle"); 965 wrap = jEdit.getBooleanProperty("search.wrap.toggle"); 966 967 fileset = new CurrentBufferSet(); 968 969 matcher = null; 973 EditBus.send(new SearchSettingsChanged(null)); 974 } 976 980 public static void save() 981 { 982 jEdit.setProperty("search.find.value",search); 983 jEdit.setProperty("search.replace.value",replace); 984 jEdit.setBooleanProperty("search.ignoreCase.toggle",ignoreCase); 985 jEdit.setBooleanProperty("search.regexp.toggle",regexp); 986 jEdit.setBooleanProperty("search.beanshell.toggle",beanshell); 987 jEdit.setBooleanProperty("search.wrap.toggle",wrap); 988 } 990 static void handleError(Component comp, Exception e) 992 { 993 Log.log(Log.ERROR,SearchAndReplace.class,e); 994 if(comp instanceof Dialog) 995 { 996 new TextAreaDialog((Dialog)comp, 997 beanshell ? "searcherror-bsh" 998 : "searcherror",e); 999 } 1000 else 1001 { 1002 new TextAreaDialog((Frame)comp, 1003 beanshell ? "searcherror-bsh" 1004 : "searcherror",e); 1005 } 1006 } 1008 1010 private static String search; 1012 private static String replace; 1013 private static BshMethod replaceMethod; 1014 private static NameSpace replaceNS = new NameSpace( 1015 BeanShell.getNameSpace(), 1016 BeanShell.getNameSpace().getClassManager(), 1017 "search and replace"); 1018 private static boolean regexp; 1019 private static boolean ignoreCase; 1020 private static boolean reverse; 1021 private static boolean beanshell; 1022 private static boolean wrap; 1023 private static SearchMatcher matcher; 1024 private static SearchFileSet fileset; 1025 1027 1031 private static void initReplace() throws Exception 1032 { 1033 if(beanshell && replace.length() != 0) 1034 { 1035 replaceMethod = BeanShell.cacheBlock("replace", 1036 "return (" + replace + ");",true); 1037 } 1038 else 1039 replaceMethod = null; 1040 } 1042 private static void record(View view, String action, 1044 boolean replaceAction, boolean recordFileSet) 1045 { 1046 Macros.Recorder recorder = view.getMacroRecorder(); 1047 1048 if(recorder != null) 1049 { 1050 recorder.record("SearchAndReplace.setSearchString(\"" 1051 + MiscUtilities.charsToEscapes(search) + "\");"); 1052 1053 if(replaceAction) 1054 { 1055 recorder.record("SearchAndReplace.setReplaceString(\"" 1056 + MiscUtilities.charsToEscapes(replace) + "\");"); 1057 recorder.record("SearchAndReplace.setBeanShellReplace(" 1058 + beanshell + ");"); 1059 } 1060 else 1061 { 1062 recorder.record("SearchAndReplace.setAutoWrapAround(" 1064 + wrap + ");"); 1065 recorder.record("SearchAndReplace.setReverseSearch(" 1066 + reverse + ");"); 1067 } 1068 1069 recorder.record("SearchAndReplace.setIgnoreCase(" 1070 + ignoreCase + ");"); 1071 recorder.record("SearchAndReplace.setRegexp(" 1072 + regexp + ");"); 1073 1074 if(recordFileSet) 1075 { 1076 recorder.record("SearchAndReplace.setSearchFileSet(" 1077 + fileset.getCode() + ");"); 1078 } 1079 1080 recorder.record("SearchAndReplace." + action + ';'); 1081 } 1082 } 1084 private static int replaceInSelection(View view, JEditTextArea textArea, 1086 Buffer buffer, SearchMatcher matcher, boolean smartCaseReplace, 1087 Selection s) throws Exception 1088 { 1089 1093 int start = s.getStart(); 1094 1095 int returnValue; 1096 1097 if(s instanceof Selection.Range) 1098 { 1099 returnValue = _replace(view,buffer,matcher, 1100 s.getStart(),s.getEnd(), 1101 smartCaseReplace); 1102 1103 textArea.removeFromSelection(s); 1104 textArea.addToSelection(new Selection.Range( 1105 start,s.getEnd())); 1106 } 1107 else if(s instanceof Selection.Rect) 1108 { 1109 Selection.Rect rect = (Selection.Rect)s; 1110 int startCol = rect.getStartColumn( 1111 buffer); 1112 int endCol = rect.getEndColumn( 1113 buffer); 1114 1115 returnValue = 0; 1116 for(int j = s.getStartLine(); j <= s.getEndLine(); j++) 1117 { 1118 returnValue += _replace(view,buffer,matcher, 1119 getColumnOnOtherLine(buffer,j,startCol), 1120 getColumnOnOtherLine(buffer,j,endCol), 1121 smartCaseReplace); 1122 } 1123 textArea.addToSelection(new Selection.Rect( 1124 start,s.getEnd())); 1125 } 1126 else 1127 throw new RuntimeException ("Unsupported: " + s); 1128 1129 return returnValue; 1130 } 1132 1144 private static int _replace(View view, Buffer buffer, 1145 SearchMatcher matcher, int start, int end, 1146 boolean smartCaseReplace) 1147 throws Exception 1148 { 1149 int occurCount = 0; 1150 1151 boolean endOfLine = (buffer.getLineEndOffset( 1152 buffer.getLineOfOffset(end)) - 1 == end); 1153 1154 Segment text = new Segment (); 1155 int offset = start; 1156loop: for(int counter = 0; ; counter++) 1157 { 1158 buffer.getText(offset,end - offset,text); 1159 1160 boolean startOfLine = (buffer.getLineStartOffset( 1161 buffer.getLineOfOffset(offset)) == offset); 1162 1163 SearchMatcher.Match occur = matcher.nextMatch( 1164 new SegmentCharSequence(text,false), 1165 startOfLine,endOfLine,counter == 0, 1166 false); 1167 if(occur == null) 1168 break loop; 1169 1170 String found = new String (text.array, 1171 text.offset + occur.start, 1172 occur.end - occur.start); 1173 1174 int length = replaceOne(view,buffer,occur,offset, 1175 found,smartCaseReplace); 1176 if(length == -1) 1177 offset += occur.end; 1178 else 1179 { 1180 offset += occur.start + length; 1181 end += (length - found.length()); 1182 occurCount++; 1183 } 1184 1185 if (matcher.isMatchingEOL()) 1186 { 1187 if (offset < buffer.getLength()) 1188 offset += 1; 1189 else 1190 break loop; 1191 1192 if (offset >= end) 1193 break loop; 1194 } 1195 } 1196 1197 return occurCount; 1198 } 1200 1205 private static int replaceOne(View view, Buffer buffer, 1206 SearchMatcher.Match occur, int offset, String found, 1207 boolean smartCaseReplace) 1208 throws Exception 1209 { 1210 String subst = replaceOne(view,occur,found); 1211 if(smartCaseReplace && ignoreCase) 1212 { 1213 int strCase = TextUtilities.getStringCase(found); 1214 if(strCase == TextUtilities.LOWER_CASE) 1215 subst = subst.toLowerCase(); 1216 else if(strCase == TextUtilities.UPPER_CASE) 1217 subst = subst.toUpperCase(); 1218 else if(strCase == TextUtilities.TITLE_CASE) 1219 subst = TextUtilities.toTitleCase(subst); 1220 } 1221 1222 if(subst != null) 1223 { 1224 int start = offset + occur.start; 1225 int end = offset + occur.end; 1226 1227 if (end - start > 0) 1228 buffer.remove(start,end - start); 1229 buffer.insert(start,subst); 1230 return subst.length(); 1231 } 1232 else 1233 return -1; 1234 } 1236 private static String replaceOne(View view, 1238 SearchMatcher.Match occur, String found) 1239 throws Exception 1240 { 1241 if(regexp) 1242 { 1243 if(replaceMethod != null) 1244 return regexpBeanShellReplace(view,occur); 1245 else 1246 return regexpReplace(occur,found); 1247 } 1248 else 1249 { 1250 if(replaceMethod != null) 1251 return literalBeanShellReplace(view,found); 1252 else 1253 return replace; 1254 } 1255 } 1257 private static String regexpBeanShellReplace(View view, 1259 SearchMatcher.Match occur) throws Exception 1260 { 1261 for(int i = 0; i < occur.substitutions.length; i++) 1262 { 1263 replaceNS.setVariable("_" + i, 1264 occur.substitutions[i]); 1265 } 1266 1267 Object obj = BeanShell.runCachedBlock( 1268 replaceMethod,view,replaceNS); 1269 if(obj == null) 1270 return ""; 1271 else 1272 return obj.toString(); 1273 } 1275 private static String regexpReplace(SearchMatcher.Match occur, 1277 String found) throws Exception 1278 { 1279 StringBuilder buf = new StringBuilder (); 1280 1281 for(int i = 0; i < replace.length(); i++) 1282 { 1283 char ch = replace.charAt(i); 1284 switch(ch) 1285 { 1286 case '$': 1287 if(i == replace.length() - 1) 1288 { 1289 buf.append(ch); 1290 break; 1291 } 1292 1293 ch = replace.charAt(++i); 1294 if(ch == '$') 1295 buf.append('$'); 1296 else if(ch == '0') 1297 buf.append(found); 1298 else if(Character.isDigit(ch)) 1299 { 1300 int n = ch - '0'; 1301 if(n < occur 1302 .substitutions 1303 .length) 1304 { 1305 buf.append( 1306 occur 1307 .substitutions 1308 [n] 1309 ); 1310 } 1311 } 1312 break; 1313 case '\\': 1314 if(i == replace.length() - 1) 1315 { 1316 buf.append('\\'); 1317 break; 1318 } 1319 ch = replace.charAt(++i); 1320 switch(ch) 1321 { 1322 case 'n': 1323 buf.append('\n'); 1324 break; 1325 case 't': 1326 buf.append('\t'); 1327 break; 1328 default: 1329 buf.append(ch); 1330 break; 1331 } 1332 break; 1333 default: 1334 buf.append(ch); 1335 break; 1336 } 1337 } 1338 1339 return buf.toString(); 1340 } 1342 private static String literalBeanShellReplace(View view, String found) 1344 throws Exception 1345 { 1346 replaceNS.setVariable("_0",found); 1347 Object obj = BeanShell.runCachedBlock( 1348 replaceMethod, 1349 view,replaceNS); 1350 if(obj == null) 1351 return ""; 1352 else 1353 return obj.toString(); 1354 } 1356 1360 private static int getColumnOnOtherLine(Buffer buffer, int line, 1361 int col) 1362 { 1363 int returnValue = buffer.getOffsetOfVirtualColumn( 1364 line,col,null); 1365 if(returnValue == -1) 1366 return buffer.getLineEndOffset(line) - 1; 1367 else 1368 return buffer.getLineStartOffset(line) + returnValue; 1369 } 1371 } 1373 | Popular Tags |