1 21 22 package org.armedbear.j; 23 24 import gnu.regexp.RE; 25 import gnu.regexp.REException; 26 import gnu.regexp.REMatch; 27 import gnu.regexp.UncheckedRE; 28 import java.awt.AWTEvent ; 29 import java.awt.BorderLayout ; 30 import java.awt.Cursor ; 31 import java.awt.Dimension ; 32 import java.awt.Point ; 33 import java.awt.Rectangle ; 34 import java.awt.Toolkit ; 35 import java.awt.datatransfer.DataFlavor ; 36 import java.awt.datatransfer.Transferable ; 37 import java.awt.dnd.DropTarget ; 38 import java.awt.event.ComponentEvent ; 39 import java.awt.event.ComponentListener ; 40 import java.awt.event.KeyEvent ; 41 import java.awt.event.MouseEvent ; 42 import java.awt.event.MouseWheelEvent ; 43 import java.awt.event.MouseWheelListener ; 44 import java.awt.event.WindowEvent ; 45 import java.io.BufferedReader ; 46 import java.io.BufferedWriter ; 47 import java.io.IOException ; 48 import java.io.InputStreamReader ; 49 import java.io.OutputStream ; 50 import java.io.OutputStreamWriter ; 51 import java.io.StringReader ; 52 import java.io.UnsupportedEncodingException ; 53 import java.lang.reflect.Method ; 54 import java.net.ConnectException ; 55 import java.net.MalformedURLException ; 56 import java.net.Socket ; 57 import java.text.SimpleDateFormat ; 58 import java.util.ArrayList ; 59 import java.util.Date ; 60 import java.util.Enumeration ; 61 import java.util.Hashtable ; 62 import java.util.List ; 63 import java.util.Properties ; 64 import java.util.Stack ; 65 import java.util.StringTokenizer ; 66 import java.util.Vector ; 67 import javax.swing.Box ; 68 import javax.swing.BoxLayout ; 69 import javax.swing.FocusManager ; 70 import javax.swing.JComponent ; 71 import javax.swing.JDialog ; 72 import javax.swing.JLabel ; 73 import javax.swing.JMenuBar ; 74 import javax.swing.JPanel ; 75 import javax.swing.JPopupMenu ; 76 import javax.swing.SwingUtilities ; 77 import javax.swing.undo.CompoundEdit ; 78 import org.armedbear.j.mail.MailCommands; 79 import org.armedbear.j.mail.MailboxURL; 80 import org.armedbear.lisp.Condition; 81 import org.armedbear.lisp.ConditionThrowable; 82 import org.armedbear.lisp.Interpreter; 83 import org.armedbear.lisp.Lisp; 84 import org.armedbear.lisp.LispObject; 85 import org.armedbear.lisp.LispThread; 86 87 public final class Editor extends JPanel implements Constants, 88 ComponentListener , MouseWheelListener 89 { 90 private static final long startTimeMillis = System.currentTimeMillis(); 91 92 private static boolean debug = false; 93 private static boolean saveSession = true; 94 95 static File portfile; 96 97 private static EditorList editorList = new EditorList(); 98 99 private static PendingOperations pendingOperations = new PendingOperations(); 100 101 private static Editor currentEditor; 102 103 private static KillRing killRing = new KillRing(); 104 105 public static final KillRing getKillRing() 106 { 107 return killRing; 108 } 109 110 private static String killedColumn; 111 112 private static SessionProperties sessionProperties; 113 114 public static SessionProperties getSessionProperties() 115 { 116 return sessionProperties; 117 } 118 119 private static final Preferences prefs = new Preferences(); 120 121 public static final Preferences preferences() 122 { 123 return prefs; 124 } 125 126 private static boolean isRecordingMacro; 127 128 public static synchronized boolean isRecordingMacro() 129 { 130 return isRecordingMacro; 131 } 132 133 public static synchronized void setRecordingMacro(boolean b) 134 { 135 isRecordingMacro = b; 136 } 137 138 static String lookAndFeel; 139 140 private Buffer buffer; 141 142 private final Display display; 143 private final Dispatcher dispatcher; 144 private final Frame frame; 145 146 private Search lastSearch; 147 148 public final Search getLastSearch() 149 { 150 return lastSearch; 151 } 152 153 public final void setLastSearch(Search search) 154 { 155 lastSearch = search; 156 } 157 158 private Position dot; 160 161 private Position mark; 163 164 private Selection selection; 165 private boolean isColumnSelection; 166 167 Hashtable views = new Hashtable (); 168 169 private int currentCommand = COMMAND_NOTHING; 171 private int lastCommand = COMMAND_NOTHING; 172 173 public final int getCurrentCommand() 174 { 175 return currentCommand; 176 } 177 178 public final void setCurrentCommand(int command) 179 { 180 currentCommand = command; 181 } 182 183 public final int getLastCommand() 184 { 185 return lastCommand; 186 } 187 188 public final void setLastCommand(int command) 189 { 190 lastCommand = command; 191 } 192 193 private static Marker[] bookmarks = new Marker[11]; 194 195 private static TagFileManager tagFileManager; 196 197 private static boolean tabsAreVisible = false; 198 199 public static final boolean tabsAreVisible() 200 { 201 return tabsAreVisible; 202 } 203 204 static boolean isMenuSelected = false; 205 206 DirectoryTree localDirectoryTree; 207 208 private static ModeList modeList; 209 210 public static final ModeList getModeList() 211 { 212 if (modeList == null) 213 modeList = ModeList.getInstance(); 214 return modeList; 215 } 216 217 private static final BufferList bufferList = new BufferList(); 218 219 public static final BufferList getBufferList() 220 { 221 return bufferList; 222 } 223 224 public static long getStartTimeMillis() 225 { 226 return startTimeMillis; 227 } 228 229 private static String when() 230 { 231 return String.valueOf(System.currentTimeMillis() - startTimeMillis) + " ms"; 232 } 233 234 public static void main(String [] args) 235 { 236 final File currentDir = File.getInstance(System.getProperty("user.dir")); 237 boolean forceNewInstance = false; 238 boolean restoreSession = true; 239 boolean startServer = true; 240 int quick = 0; 241 File userHomeDir = null; 242 List files = null; 243 244 for (int i = 0; i < args.length; i++) { 246 final String arg = args[i]; 247 if (arg.startsWith("-")) { 248 if (arg.equals("-h") || arg.equals("-help") || arg.equals("--help")) { 249 usage(); 250 System.exit(0); 251 } 252 if (arg.equals("-version")) { 253 version(); 254 System.exit(0); 255 } 256 if (arg.equals("-d") || arg.equals("--debug")) { 257 debug = true; 258 continue; 259 } 260 if (arg.equals("-q")) { 261 if (quick < 1) 262 quick = 1; 263 continue; 264 } 265 if (arg.equals("-n") || arg.equals("--no-restore")) { 266 restoreSession = false; 267 continue; 268 } 269 if (arg.equals("-session")) { 270 if (i < args.length-1) 271 sessionName = args[++i]; 272 continue; 273 } 274 if (arg.equals("--force-new-instance")) { 275 forceNewInstance = true; 276 continue; 277 } 278 if (arg.equals("--no-session")) { 279 restoreSession = false; 280 saveSession = false; 281 continue; 282 } 283 if (arg.equals("--no-server")) { 284 startServer = false; 285 continue; 286 } 287 if (arg.startsWith("--home")) { 288 String home = null; 289 if (arg.equals("--home")) { 290 if (i < args.length-1) 291 home = args[++i]; 292 } else if (arg.startsWith("--home=")) 293 home = arg.substring(7); 294 else 295 unknown(arg); 296 297 if (home == null || home.length() == 0) 298 fatal("Option \"--home\" requires an argument."); 299 300 userHomeDir = File.getInstance(currentDir, home); 301 302 if (userHomeDir == null || !userHomeDir.isDirectory()) { 303 fatal("Specified home directory \"" + 304 userHomeDir.canonicalPath() + 305 "\" does not exist."); 306 } 307 308 if (!userHomeDir.canWrite()) { 309 fatal("Specified home directory \"" + 310 userHomeDir.canonicalPath() + 311 "\" is not writable."); 312 } 313 314 Utilities.setUserHome(userHomeDir.canonicalPath()); 316 317 continue; 318 } 319 unknown(arg); 321 } else { 322 if (files == null) 324 files = new ArrayList (); 325 files.add(arg); 326 } 327 } 328 329 Directories.initialize(userHomeDir); 332 333 boolean alreadyRunning = false; 334 portfile = File.getInstance(Directories.getEditorDirectory(), "port"); 335 if (portfile.exists()) { 336 try { 337 BufferedReader in = new BufferedReader (new InputStreamReader (portfile.getInputStream())); 338 String s = in.readLine(); 339 in.close(); 340 341 int port = Integer.parseInt(s); 342 343 Socket socket = new Socket ("localhost", port); 344 345 alreadyRunning = true; 347 348 if (!forceNewInstance) { 349 BufferedWriter out = 350 new BufferedWriter (new OutputStreamWriter (socket.getOutputStream())); 351 File dir = File.getInstance(System.getProperty("user.dir")); 352 out.write(dir.canonicalPath()); 353 out.newLine(); 354 if (files != null) { 355 for (int i = 0; i < files.size(); i++) { 356 out.write((String )files.get(i)); 357 out.newLine(); 358 } 359 } 360 out.flush(); 361 out.close(); 362 socket.close(); 363 System.exit(0); 364 } 365 } 366 catch (ConnectException e) { 367 portfile.delete(); 368 } 369 catch (IOException e) { 370 Log.error(e); 371 } 372 } 373 374 loadPreferences(); 375 Log.initialize(); 376 Directories.moveUnsentMessagesToDraftsFolder(); 377 loadExtensions(); 378 if (quick == 0) { 379 runStartupScript(); 380 } 381 DefaultLookAndFeel.setLookAndFeel(); 382 383 sessionProperties = new SessionProperties(); 384 385 if (!alreadyRunning) 386 Autosave.recover(); 387 388 tagFileManager = new TagFileManager(); 389 390 setCurrentEditor(new Editor(null)); 391 392 currentEditor.getFrame().updateControls(); 393 394 FocusManager.setCurrentManager(new CustomFocusManager()); 397 398 currentEditor.getFrame().placeWindow(); 399 400 Buffer toBeActivated = null; 401 402 if (restoreSession) { 403 Session session = null; 404 if (sessionName != null) 405 session = Session.getSession(sessionName); 406 if (session == null) 407 session = Session.getDefaultSession(); 408 toBeActivated = session.restore(); 409 } 410 411 if (files != null) { 412 ArrayList list = new ArrayList (); 413 list.add(currentDir.canonicalPath()); 414 for (int i = 0; i < files.size(); i++) 415 list.add(files.get(i)); 416 Buffer buf = currentEditor.openFiles(list); 417 if (buf != null) { 418 Debug.assertTrue(bufferList.contains(buf)); 419 toBeActivated = buf; 420 } 421 } 422 423 if (toBeActivated == null) 424 toBeActivated = new Directory(currentDir); 425 426 currentEditor.activate(toBeActivated); 427 428 if (startServer) 429 Server.startServer(); 430 431 Runnable r = new Runnable () { 432 public void run() 433 { 434 currentEditor.getFrame().setVisible(true); 435 Sidebar sidebar = currentEditor.getSidebar(); 436 if (sidebar != null) 437 sidebar.setUpdateFlag(SIDEBAR_ALL); 438 } 439 }; 440 SwingUtilities.invokeLater(r); 441 442 Log.debug("leaving main " + when()); 443 } 444 445 private static final void usage() 446 { 447 version(); 448 System.out.println("Usage: j [options] [+linenum] file"); 449 System.out.println("Options:"); 450 System.out.println(" -h, -help"); 451 System.out.println(" -d, --debug"); 452 System.out.println(" -n, --no-restore"); 453 System.out.println(" -version"); 454 System.out.println(" --force-new-instance"); 455 System.out.println(" --no-session"); 456 System.out.println(" --no-server"); 457 System.out.println(" --home=directory"); 458 } 459 460 private static final void version() 461 { 462 String longVersionString = Version.getLongVersionString(); 463 if (longVersionString != null) 464 System.out.println(longVersionString); 465 String snapshotInformation = Version.getSnapshotInformation(); 466 if (snapshotInformation != null) 467 System.out.println(snapshotInformation); 468 } 469 470 public static final void fatal(String message) 471 { 472 System.err.println(message); 473 System.exit(1); 474 } 475 476 private static final void unknown(String arg) 477 { 478 usage(); 479 fatal("Unknown option \"" + arg + "\""); 480 } 481 482 public Editor(Frame f) 483 { 484 display = new Display(this); 485 dispatcher = new Dispatcher(this); 486 init(); 487 frame = f != null ? f : new Frame(this); 488 } 489 490 private void init() 491 { 492 editorList.add(this); 494 495 setLayout(new BorderLayout ()); 496 display.setDoubleBuffered(true); 497 add(display, BorderLayout.CENTER); 498 499 new DropTarget (display, dispatcher); 500 501 addLocationBar(); 502 addVerticalScrollBar(); 503 addHorizontalScrollBar(); 504 505 display.addKeyListener(dispatcher); 506 display.addMouseListener(dispatcher); 507 display.addMouseMotionListener(dispatcher); 508 509 addMouseWheelListener(this); 510 addComponentListener(this); 511 } 512 513 public static final boolean isDebugEnabled() 514 { 515 return debug; 516 } 517 518 public static final boolean isMailEnabled() 519 { 520 if (!prefs.getBooleanProperty(Property.ENABLE_EXPERIMENTAL_FEATURES)) 521 return false; 522 if (!prefs.getBooleanProperty(Property.ENABLE_MAIL)) 523 return false; 524 if (prefs.getStringProperty(Property.USER_MAIL_ADDRESS) == null) 526 return false; 527 return true; 528 } 529 530 private LocationBar locationBar; 531 532 public final LocationBar getLocationBar() 533 { 534 return locationBar; 535 } 536 537 public final HistoryTextField getLocationBarTextField() 538 { 539 return locationBar == null ? null : locationBar.getTextField(); 540 } 541 542 public void addLocationBar() 543 { 544 if (locationBar == null) { 545 locationBar = new LocationBar(this); 546 add(locationBar, BorderLayout.NORTH); 547 } 548 } 549 550 public void removeLocationBar() 551 { 552 if (locationBar != null) { 553 remove(locationBar); 554 locationBar = null; 555 } 556 } 557 558 public void updateLocation() 559 { 560 if (locationBar != null) { 561 HistoryTextField textField = locationBar.getTextField(); 562 if (textField == null || textField != frame.getFocusedComponent()) 563 locationBar.update(); 564 } else 565 Debug.bug(); 566 } 567 568 public boolean isPrimaryEditor() 569 { 570 return frame.isPrimaryEditor(this); 571 } 572 573 public final Editor getOtherEditor() 574 { 575 return isPrimaryEditor() ? frame.getSecondaryEditor() : frame.getPrimaryEditor(); 576 } 577 578 public static int indexOf(Editor editor) 579 { 580 for (int i = getEditorCount() - 1; i >= 0; i--) { 581 if (editor == getEditor(i)) 582 return i; 583 } 584 585 return -1; 586 } 587 588 public static final EditorList getEditorList() 589 { 590 return editorList; 591 } 592 593 public static final int getEditorCount() 594 { 595 return editorList.size(); 596 } 597 598 public static final Editor getEditor(int i) 599 { 600 return editorList.get(i); 601 } 602 603 public static final void removeEditor(Editor editor) 604 { 605 editorList.remove(editor); 606 } 607 608 public final Frame getFrame() 609 { 610 return frame; 611 } 612 613 static Vector frames = new Vector (); 614 615 public static int indexOf(Frame frame) 616 { 617 for (int i = getFrameCount() - 1; i >= 0; i--) { 618 if (frame == getFrame(i)) 619 return i; 620 } 621 622 return -1; 623 } 624 625 public static final int getFrameCount() 626 { 627 return frames.size(); 628 } 629 630 public static final Frame getFrame(int i) 631 { 632 if (i >= 0 && i < frames.size()) 633 return (Frame) frames.get(i); 634 return null; 635 } 636 637 public final Buffer getBuffer() 638 { 639 return buffer; 640 } 641 642 public final Mode getMode() 643 { 644 return buffer.getMode(); 645 } 646 647 public final int getModeId() 648 { 649 return buffer.getModeId(); 650 } 651 652 public final Formatter getFormatter() 653 { 654 return buffer.getFormatter(); 655 } 656 657 public final Display getDisplay() 658 { 659 return display; 660 } 661 662 public final Dispatcher getDispatcher() 663 { 664 return dispatcher; 665 } 666 667 public static final TagFileManager getTagFileManager() 668 { 669 return tagFileManager; 670 } 671 672 public final Sidebar getSidebar() 673 { 674 return frame.getSidebar(); 675 } 676 677 public final StatusBar getStatusBar() 678 { 679 return frame.getStatusBar(); 680 } 681 682 public static final PendingOperations getPendingOperations() 683 { 684 return pendingOperations; 685 } 686 687 private VerticalScrollBar verticalScrollBar; 688 689 private VerticalScrollBarListener verticalScrollBarListener; 690 691 public void addVerticalScrollBar() 692 { 693 if (verticalScrollBar == null) { 694 verticalScrollBar = new VerticalScrollBar(this); 695 verticalScrollBar.setMinimum(0); 696 add(verticalScrollBar, BorderLayout.EAST); 697 verticalScrollBarListener = new VerticalScrollBarListener(this, verticalScrollBar); 698 verticalScrollBar.addAdjustmentListener(verticalScrollBarListener); 699 } 700 } 701 702 public void removeVerticalScrollBar() 703 { 704 if (verticalScrollBar != null) { 705 if (verticalScrollBarListener == null) { 706 verticalScrollBar.removeAdjustmentListener(verticalScrollBarListener); 707 verticalScrollBarListener = null; 708 } 709 remove(verticalScrollBar); 710 verticalScrollBar = null; 711 } 712 } 713 714 private HorizontalScrollBar horizontalScrollBar; 715 716 private HorizontalScrollBarListener horizontalScrollBarListener; 717 718 public void addHorizontalScrollBar() 719 { 720 if (horizontalScrollBar == null) { 721 horizontalScrollBar = new HorizontalScrollBar(this); 722 horizontalScrollBar.setMinimum(0); 723 JPanel panel = new JPanel (); 724 panel.setLayout(new BoxLayout (panel, BoxLayout.X_AXIS)); 725 panel.add(horizontalScrollBar); 726 final int height = horizontalScrollBar.getPreferredSize().height; 727 panel.add(Box.createRigidArea(new Dimension (height, height))); 728 add(panel, BorderLayout.SOUTH); 729 horizontalScrollBarListener = new HorizontalScrollBarListener(this); 730 horizontalScrollBar.addAdjustmentListener(horizontalScrollBarListener); 731 } 732 } 733 734 public void removeHorizontalScrollBar() 735 { 736 if (horizontalScrollBar != null) { 737 if (horizontalScrollBarListener == null) { 738 horizontalScrollBar.removeAdjustmentListener(horizontalScrollBarListener); 739 horizontalScrollBarListener = null; 740 } 741 remove(horizontalScrollBar.getParent()); 743 horizontalScrollBar = null; 744 } 745 } 746 747 public static synchronized final Editor currentEditor() 748 { 749 return currentEditor; 750 } 751 752 public static synchronized final void setCurrentEditor(Editor editor) 753 { 754 Editor oldCurrentEditor = currentEditor; 755 currentEditor = editor; 756 editor.getFrame().setCurrentEditor(editor); 757 if (currentEditor != oldCurrentEditor) { 758 if (currentEditor != null) 759 currentEditor.getLocationBar().repaint(); 760 if (oldCurrentEditor != null) 761 oldCurrentEditor.getLocationBar().repaint(); 762 if (isLispInitialized()) 763 LispAPI.invokeBufferActivatedHook(currentEditor.getBuffer()); 764 } 765 } 766 767 public static synchronized final Buffer currentBuffer() 768 { 769 return currentEditor.buffer; 770 } 771 772 public static synchronized final Frame getCurrentFrame() 773 { 774 return currentEditor.getFrame(); 775 } 776 777 public static Editor createNewFrame() 778 { 779 Editor ed = new Editor(null); 780 ed.getFrame().updateControls(); 781 ed.getFrame().placeWindow(); 782 return ed; 783 } 784 785 public void newFrame() 786 { 787 saveView(); 788 Editor ed = createNewFrame(); 789 ed.activate(buffer); 790 ed.getFrame().setVisible(true); 791 setCurrentEditor(ed); 792 ed.updateDisplay(); 793 display.repaint(); 794 Runnable r = new Runnable () { 795 public void run() 796 { 797 currentEditor.setFocusToDisplay(); 798 } 799 }; 800 SwingUtilities.invokeLater(r); 801 } 802 803 public View getCurrentView() 804 { 805 return (View) views.get(buffer); 806 } 807 808 public final View getView(SystemBuffer buf) 810 { 811 return (View) views.get(buf); 812 } 813 814 public final void setView(SystemBuffer buf, View view) 815 { 816 views.put(buf, view); 817 } 818 819 public void removeView(SystemBuffer buf) 820 { 821 views.remove(buf); 822 } 823 824 private View findOrCreateView(Buffer buf) 826 { 827 View view = (View) views.get(buf); 828 if (view == null) { 829 view = buf.getLastView(); 830 if (view == null) 831 view = buf.getInitialView(); 832 views.put(buf, view); 833 } 834 return view; 835 } 836 837 public final void saveView() 838 { 839 buffer.saveView(this); 840 } 841 842 private final void restoreView() 843 { 844 buffer.restoreView(this); 845 } 846 847 public final Position getDot() 848 { 849 return dot; 850 } 851 852 public final Position getDotCopy() 853 { 854 return dot != null ? new Position(dot) : null; 855 } 856 857 public final void setDot(Position pos) 858 { 859 dot = pos; 860 } 861 862 public final void setDot(Line line, int offset) 863 { 864 dot = new Position(line, offset); 865 } 866 867 public void setDot(int lineNumber, int offset) 868 { 869 Line line = buffer.getLine(lineNumber); 870 if (line != null) 871 setDot(line, offset); 872 } 873 874 public final Line getDotLine() 875 { 876 return dot.getLine(); 877 } 878 879 public final int getDotLineNumber() 880 { 881 return dot.lineNumber(); 882 } 883 884 public final int getDotOffset() 885 { 886 return dot.getOffset(); 887 } 888 889 public final Selection getSelection() 890 { 891 return selection; 892 } 893 894 public final void setSelection(Selection selection) 895 { 896 this.selection = selection; 897 } 898 899 public final Position getMark() 900 { 901 return mark; 902 } 903 904 public void setMarkAtDot() 905 { 906 setMark(new Position(dot)); 907 selection = new Selection(); 908 } 909 910 public void setMark(Position pos) 911 { 912 mark = pos; 913 if (mark == null) { 914 selection = null; 915 setColumnSelection(false); 916 } 917 } 918 919 public void setMark(int lineNumber, int offset) 920 { 921 Line line = buffer.getLine(lineNumber); 922 if (line != null) 923 setMark(new Position(line, offset)); 924 } 925 926 public final void setColumnSelection(boolean b) 927 { 928 isColumnSelection = b; 929 } 930 931 public final boolean isColumnSelection() 932 { 933 return isColumnSelection; 934 } 935 936 public final void notSupportedForColumnSelections() 937 { 938 MessageDialog.showMessageDialog(this, 939 "Operation not supported for column selections", "Error"); 940 } 941 942 public final Line getMarkLine() 943 { 944 return mark.getLine(); 945 } 946 947 public final int getMarkLineNumber() 948 { 949 return mark.lineNumber(); 950 } 951 952 public final int getMarkOffset() 953 { 954 return mark.getOffset(); 955 } 956 957 public File getCurrentDirectory() 958 { 959 return buffer.getCurrentDirectory(); 960 } 961 962 public File getCompletionDirectory() 963 { 964 return buffer.getCompletionDirectory(); 965 } 966 967 public void cycleTabWidth() 970 { 971 switch (buffer.getTabWidth()) { 972 case 2: 973 buffer.setTabWidth(4); 974 break; 975 case 4: 976 buffer.setTabWidth(8); 977 break; 978 case 8: 979 default: 980 buffer.setTabWidth(2); 981 break; 982 } 983 buffer.saveProperties(); 984 status("Tab width set to " + buffer.getTabWidth()); 985 buffer.repaint(); 986 } 987 988 public void cycleIndentSize() 991 { 992 switch (buffer.getIndentSize()) { 993 case 2: 994 buffer.setIndentSize(3); 995 break; 996 case 3: 997 buffer.setIndentSize(4); 998 break; 999 case 4: 1000 buffer.setIndentSize(8); 1001 break; 1002 case 8: 1003 default: 1004 buffer.setIndentSize(2); 1005 break; 1006 } 1007 buffer.saveProperties(); 1008 status("Indent size set to " + buffer.getIndentSize()); 1009 } 1010 1011 public void adjustMarkers(Line line) 1012 { 1013 if (line == null) 1014 return; 1015 Position pos = null; if (line.next() != null) 1017 pos = new Position(line.next(), 0); 1018 else if (line.previous() != null) 1019 pos = new Position(line.previous(), line.previous().length()); 1020 if (pos == null) 1021 return; 1022 for (int i = 0; i < Editor.getEditorCount(); i++) { 1023 Editor ed = Editor.getEditor(i); 1024 if (ed.getBuffer() == buffer) { 1025 if (ed.getDotLine() == line) { 1026 ed.getDot().moveTo(pos); 1027 ed.moveCaretToDotCol(); 1028 } 1029 if (ed.getMark() != null && ed.getMarkLine() == line) 1030 ed.setMark(null); if (ed.getTopLine() == line) { 1032 ed.setTopLine(pos.getLine()); 1033 ed.setUpdateFlag(REPAINT); 1034 } 1035 } else { 1036 View view = (View) ed.views.get(buffer); 1038 if (view != null) { 1039 if (view.dot != null && view.dot.getLine() == line) 1040 view.dot.moveTo(pos); 1041 if (view.mark != null && view.mark.getLine() == line) 1042 view.mark = null; 1043 if (view.topLine == line) 1044 view.topLine = pos.getLine(); 1045 } 1046 } 1047 } 1048 for (int i = 0; i < bookmarks.length; i++) { 1049 Marker m = bookmarks[i]; 1050 if (m != null && m.getLine() == line) 1051 m.setPosition(pos); 1052 } 1053 } 1054 1055 public static Marker[] getBookmarks() 1056 { 1057 return bookmarks; 1058 } 1059 1060 public void dropBookmark() 1061 { 1062 AWTEvent e = dispatcher.getLastEvent(); 1063 if (e != null && e.getID() == KeyEvent.KEY_PRESSED) { 1064 int keyCode = ((KeyEvent )e).getKeyCode(); 1065 int index = keyCode - KeyEvent.VK_0; 1066 if (index >= 0 && index < bookmarks.length) { 1067 if (bookmarks[index] == null || 1068 confirm("Drop Bookmark", "Overwrite existing bookmark?")) { 1069 bookmarks[index] = new Marker(buffer, dot); 1070 status("Bookmark dropped"); 1071 } 1072 } 1073 } 1074 } 1075 1076 public void gotoBookmark() 1077 { 1078 AWTEvent e = dispatcher.getLastEvent(); 1079 if (e != null && e.getID() == KeyEvent.KEY_PRESSED) { 1080 int keyCode = ((KeyEvent )e).getKeyCode(); 1081 int index = keyCode - KeyEvent.VK_0; 1082 if (index >= 0 && index < bookmarks.length) { 1083 Marker m = bookmarks[index]; 1084 if (m != null) 1085 m.gotoMarker(this); 1086 } 1087 } 1088 } 1089 1090 public void dropTemporaryMarker() 1093 { 1094 bookmarks[10] = new Marker(buffer, dot); 1095 status("Temporary marker dropped"); 1096 } 1097 1098 public void gotoTemporaryMarker() 1099 { 1100 Marker m = bookmarks[10]; 1101 if (m != null) 1102 m.gotoMarker(this); 1103 } 1104 1105 public void deleteLineSeparator() 1106 { 1107 final Line dotLine = getDotLine(); 1108 final Line nextLine = dotLine.next(); 1109 if (nextLine == null) 1110 return; 1111 try { 1112 buffer.lockWrite(); 1113 } 1114 catch (InterruptedException e) { 1115 Log.error(e); 1116 return; 1117 } 1118 try { 1119 if (dotLine.length() == 0) { 1120 adjustMarkers(dotLine); 1121 FastStringBuffer sb = new FastStringBuffer(); 1123 if (dotLine.getOriginalText() != null) 1124 sb.append(dotLine.getOriginalText()); 1125 sb.append('\n'); 1126 if (nextLine.getOriginalText() != null) 1127 sb.append(nextLine.getOriginalText()); 1128 else 1129 sb.append(nextLine.getText()); 1130 nextLine.setOriginalText(sb.toString()); 1131 final Line prevLine = dotLine.previous(); 1133 if (prevLine != null) 1134 prevLine.setNext(nextLine); 1135 nextLine.setPrevious(prevLine); 1136 if (dotLine == buffer.getFirstLine()) { 1137 Log.debug("deleteLineSeparator calling buffer.setFirstLine()"); 1138 buffer.setFirstLine(nextLine); 1139 Log.debug("first line = |" + buffer.getFirstLine().getText() + "|"); 1140 } 1141 if (dotLine == display.getTopLine()) 1142 display.setTopLine(nextLine); 1143 dot.moveTo(nextLine, 0); 1144 } else { 1145 dotLine.setText(dotLine.getText() + nextLine.getText()); 1147 FastStringBuffer sb = new FastStringBuffer(); 1149 if (dotLine.getOriginalText() != null) 1150 sb.append(dotLine.getOriginalText()); 1151 else 1152 sb.append(dotLine.getText()); 1153 if (!nextLine.isNew()) { 1154 sb.append('\n'); 1155 if (nextLine.getOriginalText() != null) 1156 sb.append(nextLine.getOriginalText()); 1157 else 1158 sb.append(nextLine.getText()); 1159 } 1160 dotLine.setOriginalText(sb.toString()); 1161 adjustMarkers(nextLine); 1163 if (nextLine.next() != null) 1165 nextLine.next().setPrevious(dotLine); 1166 dotLine.setNext(nextLine.next()); 1167 } 1168 buffer.repaint(); 1169 setUpdateFlag(REFRAME); 1170 buffer.needsRenumbering = true; 1171 buffer.modified(); 1172 } 1173 finally { 1174 buffer.unlockWrite(); 1175 } 1176 } 1177 1178 private void deleteNormalChar() 1179 { 1180 addUndo(SimpleEdit.LINE_EDIT); 1181 final Line dotLine = getDotLine(); 1182 final int dotOffset = getDotOffset(); 1183 String head = dotLine.substring(0, dotOffset); 1184 String tail = ""; 1185 if (dotOffset < dotLine.length() - 1) 1186 tail = dotLine.substring(dotOffset + 1); 1187 dotLine.setText(head.concat(tail)); 1188 buffer.modified(); 1189 updateInAllEditors(dotLine); 1190 } 1191 1192 public void delete() 1194 { 1195 if (!checkReadOnly()) 1196 return; 1197 try { 1198 buffer.lockWrite(); 1199 } 1200 catch (InterruptedException e) { 1201 Log.error(e); 1202 return; 1203 } 1204 try { 1205 if (mark != null) { 1206 deleteRegion(); 1207 } else { 1208 final Line dotLine = getDotLine(); 1209 final int dotOffset = getDotOffset(); 1210 final int length = dotLine.length(); 1211 if (dotOffset < length) { 1212 deleteNormalChar(); 1213 } else if (dotOffset == length) { 1214 if (dotLine.next() != null) { 1215 CompoundEdit compoundEdit = beginCompoundEdit(); 1216 fillToCaret(); 1217 addUndo(SimpleEdit.DELETE_LINE_SEP); 1218 deleteLineSeparator(); 1219 endCompoundEdit(compoundEdit); 1220 } else 1221 status("End of buffer"); 1222 } else { 1223 Debug.bug(); 1225 } 1226 } 1227 } 1228 finally { 1229 buffer.unlockWrite(); 1230 } 1231 } 1232 1233 public void backspace() 1235 { 1236 if (!checkReadOnly()) 1237 return; 1238 try { 1239 buffer.lockWrite(); 1240 } 1241 catch (InterruptedException e) { 1242 Log.error(e); 1243 return; 1244 } 1245 try { 1246 if (mark != null) { 1247 delete(); 1248 } else if (display.getCaretCol() > buffer.getCol(getDotLine(), getDotLine().length())) { 1249 addUndo(SimpleEdit.MOVE); 1251 --display.caretCol; 1252 updateDotLine(); 1253 } else if (dot.getOffset() > 0) { 1254 addUndo(SimpleEdit.LINE_EDIT); 1255 dot.moveLeft(); 1256 deleteNormalChar(); 1257 moveCaretToDotCol(); 1258 } else if (getDotLine().previous() != null) { 1259 CompoundEdit compoundEdit = beginCompoundEdit(); 1260 addUndo(SimpleEdit.MOVE); 1261 dot.moveTo(getDotLine().previous(), getDotLine().previous().length()); 1262 addUndo(SimpleEdit.DELETE_LINE_SEP); 1263 deleteLineSeparator(); 1264 endCompoundEdit(compoundEdit); 1265 moveCaretToDotCol(); 1266 } 1267 } 1268 finally { 1269 buffer.unlockWrite(); 1270 } 1271 } 1272 1273 private boolean nextChar() 1274 { 1275 if (getDotOffset() < getDotLine().length()) { 1276 dot.skip(1); 1277 return true; 1278 } 1279 if (getDotLine().next() != null) { 1280 dot.moveTo(getDotLine().next(), 0); 1281 return true; 1282 } 1283 return false; 1284 } 1285 1286 private boolean prevChar() 1287 { 1288 if (getDotOffset() > 0) { 1289 dot.skip(-1); 1290 return true; 1291 } 1292 final Line previous = getDotLine().previous(); 1293 if (previous != null) { 1294 dot.moveTo(previous, previous.length()); 1295 return true; 1296 } 1297 return false; 1298 } 1299 1300 public char getDotChar() 1301 { 1302 Debug.assertTrue(dot != null); 1303 return dot.getChar(); 1304 } 1305 1306 public void cppFindMatch() 1307 { 1308 if (getDotLine().trim().startsWith("#")) { 1309 Line line = CMode.findMatchPreprocessor(getDotLine()); 1310 if (line != null) 1311 moveDotTo(line, 0); 1312 else 1313 status("No match"); 1314 } else 1315 findMatchingChar(); 1316 } 1317 1318 public Position findMatchInternal(Position start, int numLines) 1321 { 1322 if (start == null) 1323 return null; 1324 final String s1 = new String ("{([})]"); 1325 final char origChar = start.getChar(); 1326 int index = s1.indexOf(origChar); 1327 if (index < 0) 1328 return null; 1329 final Mode mode = getMode(); 1330 if (mode.isInComment(getBuffer(), start)) 1331 return null; 1332 boolean inQuote = mode.isInQuote(buffer, start); 1333 if (inQuote) 1334 return null; 1335 final String s2 = new String ("})]{(["); 1336 final char match = s2.charAt(index); 1337 final boolean searchBackwards = index > 2; 1338 int stopLineNumber = searchBackwards ? 0 : buffer.getLineCount(); 1339 if (numLines != 0) 1340 stopLineNumber = searchBackwards ? start.lineNumber() - numLines : start.lineNumber() + numLines; 1341 int count = 1; 1342 final SyntaxIterator it = mode.getSyntaxIterator(start); 1343 while (true) { 1344 char c; 1345 Position pos = it.getPosition(); 1346 if (searchBackwards) { 1347 if (pos.lineNumber() < stopLineNumber) 1348 return null; 1349 else 1350 c = it.prevChar(); 1351 } else { 1352 if (pos.lineNumber() > stopLineNumber) 1353 return null; 1354 else 1355 c = it.nextChar(); 1356 } 1357 if (c == SyntaxIterator.DONE) 1358 return null; 1359 if (inQuote && c == '"') 1360 return null; 1361 if (c == origChar) 1362 ++count; 1363 else if (c == match) 1364 --count; 1365 if (count == 0) { 1366 return it.getPosition(); 1368 } 1369 } 1370 } 1371 1372 public void findMatchingChar() 1373 { 1374 setWaitCursor(); 1375 Position pos = findDelimiterNearDot(); 1376 if (pos != null) { 1377 Position match = findMatchInternal(pos, 0); 1378 if (match != null) { 1379 if ("})]".indexOf(match.getChar()) >= 0) 1382 match.next(); 1383 addUndo(SimpleEdit.MOVE); 1384 unmark(); 1385 updateDotLine(); 1386 dot.moveTo(match); 1387 updateDotLine(); 1388 moveCaretToDotCol(); 1389 } else 1390 status("No match"); 1391 } 1392 setDefaultCursor(); 1393 } 1394 1395 public void selectSyntax() 1396 { 1397 setWaitCursor(); 1398 Position pos = findDelimiterNearDot(); 1399 if (pos != null) { 1400 Position match = findMatchInternal(pos, 0); 1401 if (match != null) { 1402 if ("})]".indexOf(pos.getChar()) >= 0) 1403 pos.next(); 1404 else if ("})]".indexOf(match.getChar()) >= 0) 1405 match.next(); 1406 if (pos.getLine() != match.getLine()) { 1407 Region r = new Region(buffer, pos, match); 1409 Position begin = r.getBegin(); 1410 String trim = 1411 begin.getLine().substring(0, begin.getOffset()).trim(); 1412 if (trim.length() == 0) { 1413 Position end = r.getEnd(); 1414 trim = end.getLine().substring(end.getOffset()).trim(); 1415 if (trim.length() == 0) { 1416 begin.setOffset(0); 1418 if (end.getNextLine() != null) 1419 end.moveTo(end.getNextLine(), 0); 1420 else 1421 end.setOffset(end.getLineLength()); 1422 if (pos.isBefore(match)) { 1423 pos = begin; 1424 match = end; 1425 } else { 1426 match = begin; 1427 pos = end; 1428 } 1429 } 1430 } 1431 } 1432 addUndo(SimpleEdit.MOVE); 1433 unmark(); 1434 dot.moveTo(pos); 1435 setMarkAtDot(); 1436 updateDotLine(); 1437 dot.moveTo(match); 1438 updateDotLine(); 1439 moveCaretToDotCol(); 1440 if (dot.getLine() != mark.getLine()) 1441 setUpdateFlag(REPAINT); 1442 } else 1443 status("No match"); 1444 } 1445 setDefaultCursor(); 1446 } 1447 1448 private Position findDelimiterNearDot() 1449 { 1450 Position pos = dot.copy(); 1451 if ("{([".indexOf(pos.getChar()) >= 0) { 1452 return pos; 1454 } 1455 Position saved = dot.copy(); 1456 if (pos.getOffset() > 0) { 1457 pos.prev(); 1458 if ("})]".indexOf(pos.getChar()) >= 0) { 1459 return pos; 1461 } 1462 } 1463 final String delimiters = "{([})]"; 1465 pos.moveTo(saved); 1466 while (pos.getOffset() > 0) { 1467 pos.prev(); 1469 char c = pos.getChar(); 1470 if (delimiters.indexOf(c) >= 0) 1471 return pos; 1472 if (!Character.isWhitespace(c) && c != ';') 1473 break; 1474 } 1475 pos.moveTo(saved); 1476 final int limit = pos.getLineLength(); 1477 while (pos.getOffset() < limit) { 1478 char c = pos.getChar(); 1479 if (delimiters.indexOf(c) >= 0) 1480 return pos; 1481 if (!Character.isWhitespace(c)) 1482 return null; 1483 pos.next(); 1485 } 1486 return null; 1487 } 1488 1489 public void closeParen() 1490 { 1491 insertNormalChar(')'); 1492 if (prefs.getBooleanProperty(Property.HIGHLIGHT_MATCHING_BRACKET) || 1493 prefs.getBooleanProperty(Property.HIGHLIGHT_BRACKETS)) 1494 return; 1495 Position match = 1497 findMatchInternal(new Position(getDotLine(), getDotOffset()-1), 50); 1498 if (match == null) 1499 return; 1500 if (match.lineNumber() < display.getTopLineNumber()) 1502 return; 1503 if (buffer.getCol(match) < display.getShift()) 1504 return; 1505 Position saved = new Position(dot); 1507 updateDotLine(); 1508 dot.moveTo(match); 1509 updateDotLine(); 1510 moveCaretToDotCol(); 1511 display.repaintChangedLines(); 1512 try { 1513 Thread.sleep(300); 1514 } 1515 catch (InterruptedException e) {} 1516 updateDotLine(); 1517 dot.moveTo(saved); 1518 moveCaretToDotCol(); 1519 updateDotLine(); 1520 } 1521 1522 public void insertLineSeparator() 1524 { 1525 Debug.assertTrue(mark == null); 1526 try { 1527 buffer.lockWrite(); 1528 } 1529 catch (InterruptedException e) { 1530 Log.error(e); 1531 return; 1532 } 1533 try { 1534 buffer.insertLineSeparator(dot); 1535 } 1536 finally { 1537 buffer.unlockWrite(); 1538 } 1539 final Line dotLine = getDotLine(); 1540 for (int i = 0; i < getEditorCount(); i++) { 1541 Editor ed = getEditor(i); 1542 if (ed.getTopLine() == dotLine) 1543 ed.setTopLine(dotLine.previous()); 1544 } 1545 } 1546 1547 public void newline() 1548 { 1549 if (!checkReadOnly()) 1550 return; 1551 CompoundEdit compoundEdit = beginCompoundEdit(); 1552 if (mark != null) 1553 deleteRegion(); 1554 addUndo(SimpleEdit.INSERT_LINE_SEP); 1555 insertLineSeparator(); 1556 moveCaretToDotCol(); 1557 endCompoundEdit(compoundEdit); 1558 } 1559 1560 public void newlineAndIndent() 1561 { 1562 if (isColumnSelection()) { 1563 notSupportedForColumnSelections(); 1564 return; 1565 } 1566 if (!checkReadOnly()) 1567 return; 1568 try { 1569 buffer.lockWrite(); 1570 } 1571 catch (InterruptedException e) { 1572 Log.error(e); 1573 return; 1574 } 1575 try { 1576 CompoundEdit compoundEdit = beginCompoundEdit(); 1577 if (mark != null) 1578 deleteRegion(); 1579 addUndo(SimpleEdit.INSERT_LINE_SEP); 1580 insertLineSeparator(); 1581 final Mode mode = getMode(); 1582 final Line dotLine = getDotLine(); 1583 int indent; 1584 if (mode.canIndent()) { 1585 if (buffer.needsRenumbering()) 1586 buffer.renumber(); 1587 getFormatter().parseBuffer(); 1588 indent = mode.getCorrectIndentation(dotLine, buffer); 1589 } else { 1590 indent = buffer.getIndentation(dotLine.previous()); 1592 } 1593 if (indent != buffer.getIndentation(dotLine)) { 1594 addUndo(SimpleEdit.LINE_EDIT); 1595 buffer.setIndentation(dotLine, indent); 1596 } 1597 if (dotLine.length() > 0) { 1598 moveDotToIndentation(); 1599 moveCaretToDotCol(); 1600 } else { 1601 display.setCaretCol(indent - display.getShift()); 1602 if (buffer.getBooleanProperty(Property.RESTRICT_CARET)) 1603 fillToCaret(); 1604 } 1605 endCompoundEdit(compoundEdit); 1606 } 1607 finally { 1608 buffer.unlockWrite(); 1609 } 1610 setUpdateFlag(REFRAME); 1611 } 1612 1613 public void insertNormalChar(char c) 1614 { 1615 if (isColumnSelection()) { 1616 notSupportedForColumnSelections(); 1617 return; 1618 } 1619 if (!checkReadOnly()) 1620 return; 1621 try { 1622 buffer.lockWrite(); 1623 } 1624 catch (InterruptedException e) { 1625 Log.error(e); 1626 return; 1627 } 1628 try { 1629 c = getMode().fixCase(this, c); 1630 if (mark != null) { 1631 CompoundEdit compoundEdit = beginCompoundEdit(); 1632 deleteRegion(); 1633 insertChar(c); 1634 endCompoundEdit(compoundEdit); 1635 } else { 1636 if (buffer.getBooleanProperty(Property.WRAP) && 1638 getDotCol() >= buffer.getIntegerProperty(Property.WRAP_COL)) 1639 { 1640 CompoundEdit compoundEdit = beginCompoundEdit(); 1641 insertChar(c); 1642 new WrapText(this).wrapLine(); 1643 endCompoundEdit(compoundEdit); 1644 } else 1645 insertChar(c); 1646 } 1647 } 1648 finally { 1649 buffer.unlockWrite(); 1650 } 1651 moveCaretToDotCol(); 1652 } 1653 1654 public void tab() 1655 { 1656 if (isColumnSelection()) { 1657 notSupportedForColumnSelections(); 1658 return; 1659 } 1660 if (buffer.getBooleanProperty(Property.TAB_ALWAYS_INDENT)) { 1661 indentLineOrRegion(); 1662 return; 1663 } 1664 if (mark == null) { 1665 if (dot.getOffset() <= dot.getLine().getIndentation()) 1667 indentLine(); 1668 else 1669 insertTab(); 1670 return; 1671 } 1672 if (getMarkLine() != getDotLine()) { 1673 indentRegion(); 1675 return; 1676 } 1677 Region r = new Region(this); 1679 if (r.getBeginOffset() <= getDotLine().getIndentation()) 1680 indentLine(); 1681 else 1682 insertTab(); 1683 } 1684 1685 public void insertTab() 1686 { 1687 if (isColumnSelection()) { 1688 notSupportedForColumnSelections(); 1689 return; 1690 } 1691 1692 if (!checkReadOnly()) 1693 return; 1694 1695 try { 1696 buffer.lockWrite(); 1697 } 1698 catch (InterruptedException e) { 1699 Log.error(e); 1700 return; 1701 } 1702 try { 1703 CompoundEdit compoundEdit = beginCompoundEdit(); 1704 if (mark != null) 1705 deleteRegion(); 1706 if (buffer.getUseTabs()) 1707 insertChar('\t'); 1708 else { 1709 fillToCaret(); 1710 int tabWidth = buffer.getTabWidth(); 1711 addUndo(SimpleEdit.LINE_EDIT); 1712 buffer.insertChars(dot, Utilities.spaces(tabWidth - getDotCol() % tabWidth)); 1713 updateInAllEditors(getDotLine()); 1714 } 1715 moveCaretToDotCol(); 1716 endCompoundEdit(compoundEdit); 1717 } 1718 finally { 1719 buffer.unlockWrite(); 1720 } 1721 } 1722 1723 public void moveDotToIndentation() 1724 { 1725 final Line dotLine = getDotLine(); 1726 final int limit = dotLine.length(); 1727 int i; 1728 for (i = 0; i < limit; i++) { 1729 if (!Character.isWhitespace(dotLine.charAt(i))) 1730 break; 1731 } 1732 dot.setOffset(i); 1733 } 1734 1735 public void indentLineOrRegion() 1736 { 1737 if (isColumnSelection()) { 1738 notSupportedForColumnSelections(); 1739 return; 1740 } 1741 if (getMode().canIndent()) { 1742 if (mark != null && getMarkLine() != getDotLine()) { 1743 indentRegion(); 1744 } else { 1745 unmark(); 1746 indentLine(); 1747 } 1748 } 1749 } 1750 1751 public void indentRegion() 1752 { 1753 if (isColumnSelection()) { 1754 notSupportedForColumnSelections(); 1755 return; 1756 } 1757 if (getMode().canIndent() && mark != null) { 1758 Region r = new Region(this); 1759 if (r.getBeginLine() == r.getEndLine()) { 1760 indentLine(); 1761 } else { 1762 setWaitCursor(); 1763 Position savedDot = new Position(dot); 1764 try { 1765 buffer.lockWrite(); 1766 } 1767 catch (InterruptedException e) { 1768 Log.error(e); 1769 return; 1770 } 1771 try { 1772 if (buffer.needsParsing()) { 1773 if (getFormatter().parseBuffer()) 1774 buffer.repaint(); 1775 } 1776 CompoundEdit compoundEdit = beginCompoundEdit(); 1777 addUndo(SimpleEdit.MOVE); 1778 dot.moveTo(r.getBeginLine(), 0); 1779 do { 1780 if (!dot.getLine().isBlank()) 1781 indentLineInternal(); 1782 dot.moveTo(dot.getNextLine(), 0); 1783 } while (dot.getLine() != r.getEndLine()); 1784 addUndo(SimpleEdit.MOVE); 1785 dot = savedDot; 1786 if (dot.getOffset() > getDotLine().length()) 1787 dot.setOffset(getDotLine().length()); 1788 if (mark.getOffset() > getMarkLine().length()) 1789 mark.setOffset(getMarkLine().length()); 1790 moveCaretToDotCol(); 1791 endCompoundEdit(compoundEdit); 1792 } 1793 finally { 1794 buffer.unlockWrite(); 1795 } 1796 setUpdateFlag(REFRAME); 1797 setDefaultCursor(); 1798 } 1799 } 1800 } 1801 1802 public void commentRegion() 1803 { 1804 if (isColumnSelection()) { 1805 notSupportedForColumnSelections(); 1806 return; 1807 } 1808 commentRegion(true); 1809 } 1810 1811 public void uncommentRegion() { 1812 if (isColumnSelection()) { 1813 notSupportedForColumnSelections(); 1814 return; 1815 } 1816 commentRegion(false); 1817 } 1818 1819 private void commentRegion(boolean comment) 1821 { 1822 if (!checkReadOnly()) 1823 return; 1824 if (dot == null) 1825 return; 1826 try { 1827 buffer.lockWrite(); 1828 } 1829 catch (InterruptedException e) { 1830 Log.error(e); 1831 return; 1832 } 1833 try { 1834 commentRegionInternal(comment); 1835 } 1836 finally { 1837 buffer.unlockWrite(); 1838 } 1839 } 1840 1841 private void commentRegionInternal(boolean comment) 1843 { 1844 String commentStart = buffer.getCommentStart(); 1845 if (commentStart == null) 1846 return; 1847 String commentEnd = buffer.getCommentEnd(); 1848 Position savedDot = new Position(dot); 1849 Line beginLine, endLine; 1850 if (mark != null) { 1851 Region r = new Region(buffer, dot, mark); 1852 beginLine = r.getBeginLine(); 1853 endLine = r.getEndLine(); 1854 } else { 1855 beginLine = getDotLine(); 1856 endLine = getDotLine().next(); 1857 } 1858 if (endLine == beginLine) 1859 endLine = beginLine.next(); 1860 1861 CompoundEdit compoundEdit = beginCompoundEdit(); 1862 1863 if (mark != null) { 1864 addUndo(SimpleEdit.MOVE); 1865 setMark(null); 1866 setUpdateFlag(REPAINT); 1867 } 1868 1869 if (getDotLine() != beginLine) { 1870 addUndo(SimpleEdit.MOVE); 1871 dot.moveTo(beginLine, 0); 1872 } 1873 1874 boolean modified = false; 1875 1876 while (true) { 1877 Line dotLine = getDotLine(); 1878 String trim = dotLine.trim(); 1879 if (comment) { 1880 if (trim.length() != 0) { 1881 addUndo(SimpleEdit.LINE_EDIT); 1882 if (commentEnd != null) 1883 dotLine.setText(commentStart + dotLine.getText() + commentEnd); 1884 else 1885 dotLine.setText(commentStart + dotLine.getText()); 1886 modified = true; 1887 if (dotLine == savedDot.getLine()) 1888 savedDot.setOffset(savedDot.getOffset() + commentStart.length()); 1889 updateInAllEditors(dotLine); 1890 } 1891 } else { 1892 if (trim.startsWith(commentStart)) { 1894 if (commentEnd == null || trim.endsWith(commentEnd)) { 1895 addUndo(SimpleEdit.LINE_EDIT); 1896 int index = dotLine.getText().indexOf(commentStart) + commentStart.length(); 1897 dotLine.setText(dotLine.substring(index)); 1898 if (commentEnd != null) 1899 dotLine.setText(dotLine.substring(0, dotLine.length() - commentEnd.length())); 1900 modified = true; 1901 int dotCol = 0; 1902 if (dotLine == savedDot.getLine()) { 1903 savedDot.setOffset(savedDot.getOffset() - index); 1905 if (savedDot.getOffset() < 0) 1906 savedDot.setOffset(0); 1907 dotCol = buffer.getCol(dotLine, savedDot.getOffset()); 1908 } 1909 1910 int oldIndent = buffer.getIndentation(dotLine); 1911 int indent = getMode().getCorrectIndentation(dotLine, buffer); 1912 if (indent != oldIndent) { 1913 buffer.setIndentation(dotLine, indent); 1914 if (dotLine == savedDot.getLine()) { 1915 if (dotCol >= oldIndent) { 1917 dotCol += indent - oldIndent; 1918 dot.moveToCol(dotCol, buffer.getTabWidth()); 1919 savedDot.setOffset(dot.getOffset()); 1920 } 1921 } 1922 } 1923 updateInAllEditors(dotLine); 1924 } 1925 } 1926 } 1927 1928 if (dotLine.next() == endLine) 1929 break; 1930 1931 addUndo(SimpleEdit.MOVE); 1932 dot.moveTo(dotLine.next(), 0); 1933 } 1934 1935 addUndo(SimpleEdit.MOVE); 1936 setDot(savedDot); 1937 moveCaretToDotCol(); 1938 1939 if (modified) 1940 buffer.modified(); 1941 1942 endCompoundEdit(compoundEdit); 1943 } 1944 1945 public final void moveDotTo(Position pos) 1946 { 1947 if (pos != null) 1948 moveDotTo(pos.getLine(), pos.getOffset()); 1949 } 1950 1951 public void moveDotTo(Line line, int offset) 1952 { 1953 if (dot == null) 1954 return; 1955 addUndo(SimpleEdit.MOVE); 1956 if (mark != null) { 1957 setMark(null); 1958 dot.moveTo(line, offset); 1959 setUpdateFlag(REPAINT); 1960 } else { 1961 updateDotLine(); 1962 dot.moveTo(line, offset); 1963 updateDotLine(); 1964 } 1965 moveCaretToDotCol(); 1966 } 1967 1968 public void indentLine() 1969 { 1970 if (isColumnSelection()) { 1971 notSupportedForColumnSelections(); 1972 return; 1973 } 1974 if (!checkReadOnly()) 1975 return; 1976 if (!getMode().canIndent()) 1977 return; try { 1979 buffer.lockWrite(); 1980 } 1981 catch (InterruptedException e) { 1982 Log.error(e); 1983 return; 1984 } 1985 try { 1986 if (buffer.needsParsing()) { 1987 if (getFormatter().parseBuffer()) 1988 buffer.repaint(); 1989 } 1990 indentLineInternal(); 1991 } 1992 finally { 1993 buffer.unlockWrite(); 1994 } 1995 setUpdateFlag(REFRAME); 1996 } 1997 1998 private void indentLineInternal() 1999 { 2000 final Line dotLine = getDotLine(); 2001 final int indent = getMode().getCorrectIndentation(dotLine, buffer); 2002 final int shift = display.getShift(); 2003 2004 if (dotLine.isBlank()) { 2005 addUndo(SimpleEdit.LINE_EDIT); 2007 dotLine.setText(""); 2008 dot.setOffset(0); 2009 display.setCaretCol(indent - shift); 2010 if (buffer.getBooleanProperty(Property.RESTRICT_CARET)) 2012 fillToCaret(); 2013 updateInAllEditors(dotLine); 2014 return; 2015 } 2016 2017 final int oldIndent = buffer.getIndentation(dotLine); 2019 2020 FastStringBuffer sb = null; 2021 2022 if (indent == oldIndent) { 2023 boolean ok = false; 2024 if (buffer.getBooleanProperty(Property.INDENT_LINE_FIX_WHITESPACE)) { 2025 sb = buffer.getCorrectIndentationString(indent); 2026 if (dotLine.getText().startsWith(sb.toString())) 2027 ok = true; 2028 } else 2029 ok = true; 2030 2031 if (ok) { 2032 if (display.getCaretCol() + shift < indent) { 2036 addUndo(SimpleEdit.MOVE); 2037 display.setCaretCol(indent - shift); 2038 moveDotToCaretCol(); 2039 } 2040 return; 2041 } 2042 } 2043 2044 final int existing = display.getCaretCol() + shift - oldIndent; 2048 final int goal = existing < 0 ? indent : existing + indent; 2049 2050 int i = 0; 2052 while (i < dotLine.length() && Character.isWhitespace(dotLine.charAt(i))) 2053 ++i; 2054 String nonBlank = dotLine.substring(i); 2055 2056 if (sb == null) 2058 sb = buffer.getCorrectIndentationString(indent); 2059 2060 sb.append(nonBlank); 2062 2063 addUndo(SimpleEdit.LINE_EDIT); 2065 dotLine.setText(sb.toString()); 2066 buffer.modified(); 2067 updateInAllEditors(dotLine); 2068 2069 display.setCaretCol(goal - shift); 2071 moveDotToCaretCol(); 2072 } 2073 2074 public void save() 2075 { 2076 save(buffer); 2077 } 2078 2079 public void save(Buffer toBeSaved) 2080 { 2081 if (toBeSaved.isLocked()) 2082 return; 2083 if (toBeSaved.getType() == Buffer.TYPE_NORMAL) { 2084 if (toBeSaved.isModified()) { 2085 if (toBeSaved.isUntitled()) { 2086 saveAs(toBeSaved); 2087 } else { 2088 setWaitCursor(); 2089 status("Saving..."); 2090 if (toBeSaved.getBooleanProperty(Property.REMOVE_TRAILING_WHITESPACE)) 2091 toBeSaved.removeTrailingWhitespace(); 2092 if (toBeSaved.save()) 2093 status("Saving...done"); 2094 else 2095 status("Save failed"); 2096 setDefaultCursor(); 2097 } 2098 } else 2099 status("Not modified"); 2100 } 2101 } 2102 2103 public void saveAs() 2104 { 2105 saveAs(buffer); 2106 } 2107 2108 private void saveAs(Buffer toBeSaved) 2109 { 2110 if (toBeSaved.isLocked()) 2111 return; 2112 if (toBeSaved.getType() == Buffer.TYPE_NORMAL) { 2113 final String dialogTitle = "Save As"; 2114 File destination = 2115 SaveFileDialog.getSaveFile(this, dialogTitle); 2116 if (destination == null) 2117 return; 2118 2119 repaintNow(); 2122 2123 Buffer buf = bufferList.findBuffer(destination); 2125 if (buf != null) { 2126 if (!buf.isModified()) { 2128 buf.deleteAutosaveFile(); 2129 bufferList.remove(buf); 2130 } else { 2131 setDefaultCursor(); 2133 String message = "Target file is in an active buffer. Please take care of that first."; 2134 MessageDialog.showMessageDialog(this, message, dialogTitle); 2135 return; 2136 } 2137 } 2138 2139 toBeSaved.saveAs(destination); 2140 } 2141 } 2142 2143 public void saveCopy() 2144 { 2145 if (buffer.isLocked()) 2146 return; 2147 if (buffer.getType() == Buffer.TYPE_NORMAL) { 2148 final String dialogTitle = "Save Copy"; 2149 final File destination = 2150 SaveFileDialog.getSaveFile(this, dialogTitle); 2151 if (destination == null) 2152 return; 2153 2154 repaintNow(); 2155 2156 Buffer buf = bufferList.findBuffer(destination); 2158 if (buf != null) { 2159 if (buf.isModified()) { 2161 setDefaultCursor(); 2163 String message = "Target file is in an active buffer. Please take care of that first."; 2164 MessageDialog.showMessageDialog(this, message, "Save Copy"); 2165 return; 2166 } 2167 } 2168 2169 buffer.saveCopy(destination); 2170 if (buf != null && buf.isLoaded()) 2171 reload(buf); 2172 } 2173 } 2174 2175 public void saveAll() 2176 { 2177 setWaitCursor(); 2178 int numModified = 0; 2179 int numErrors = 0; 2180 for (BufferIterator it = new BufferIterator(); it.hasNext();) { 2181 Buffer buf = it.nextBuffer(); 2182 if (buf.getModeId() == CHECKIN_MODE) 2183 continue; 2184 if (buf.isUntitled()) { 2185 setDefaultCursor(); 2186 makeNext(buf); 2187 activate(buf); 2188 saveAs(); 2189 setWaitCursor(); 2190 } else if (buf.isModified()) { 2191 status("Saving modified buffers..."); 2192 ++numModified; 2193 if (buffer.getFile() != null) 2194 if (buffer.getBooleanProperty(Property.REMOVE_TRAILING_WHITESPACE)) 2195 buffer.removeTrailingWhitespace(); 2196 if (!buf.save()) 2197 ++numErrors; 2198 } 2199 } 2200 if (numModified == 0) 2201 status("No modified buffers"); 2202 else if (numErrors == 0) 2203 status("Saving modified buffers...done"); 2204 else { 2205 status("Unable to save all modified buffers"); 2207 } 2208 setDefaultCursor(); 2209 } 2210 2211 public boolean okToClose(Buffer buf) 2212 { 2213 if (buf.getType() != Buffer.TYPE_NORMAL) 2214 return true; 2215 if (buf.isUntitled() || buf.isModified()) { 2216 makeNext(buf); 2217 activate(buf); 2218 repaintNow(); 2219 if (!CloseBufferConfirmationDialog.confirmClose(this, buf)) 2220 return false; 2221 } 2222 return true; 2223 } 2224 2225 public void closeAll() 2226 { 2227 repaintNow(); 2228 2229 for (BufferIterator it = new BufferIterator(); it.hasNext();) { 2230 if (!okToClose(it.nextBuffer())) 2231 return; 2232 } 2233 2234 Marker.invalidateAllMarkers(); 2235 2236 Buffer toBeActivated = null; 2237 2238 for (BufferIterator it = new BufferIterator(); it.hasNext();) { 2239 Buffer buf = it.nextBuffer(); 2240 if (buf instanceof Directory && buf.getFile().equals(getCurrentDirectory())) { 2241 toBeActivated = buf; 2242 break; 2243 } 2244 } 2245 2246 if (toBeActivated == null) 2247 toBeActivated = new Directory(getCurrentDirectory()); 2248 2249 setWaitCursor(); 2250 2251 for (int i = 0; i < getEditorCount(); i++) { 2252 Editor ed = getEditor(i); 2253 ed.activate(toBeActivated); 2254 } 2255 2256 for (BufferIterator iter = new BufferIterator(); iter.hasNext();) { 2257 Buffer buf = iter.nextBuffer(); 2258 if (buf != toBeActivated) { 2259 for (EditorIterator it = new EditorIterator(); it.hasNext();) { 2260 Editor ed = it.nextEditor(); 2261 ed.views.remove(buf); 2262 } 2263 buf.deleteAutosaveFile(); 2264 iter.remove(); 2265 buf.dispose(); 2266 } 2267 } 2268 2269 Sidebar.setUpdateFlagInAllFrames(SIDEBAR_BUFFER_LIST_ALL); 2270 Sidebar.refreshSidebarInAllFrames(); 2271 setDefaultCursor(); 2272 } 2273 2274 public void closeOthers() 2275 { 2276 repaintNow(); 2277 2278 Buffer toBeActivated = buffer; 2279 2280 for (BufferIterator it = new BufferIterator(); it.hasNext();) { 2281 Buffer buf = it.nextBuffer(); 2282 if (buf != buffer && !okToClose(buf)) 2283 return; 2284 } 2285 2286 List markers = Marker.getAllMarkers(); 2287 for (int i = 0; i < markers.size(); i++) { 2288 Marker m = (Marker) markers.get(i); 2289 if (m != null && m.getBuffer() != buffer) 2290 m.invalidate(); 2291 } 2292 2293 setWaitCursor(); 2294 2295 for (EditorIterator it = new EditorIterator(); it.hasNext();) 2296 it.nextEditor().activate(toBeActivated); 2297 2298 for (BufferIterator iter = new BufferIterator(); iter.hasNext();) { 2299 Buffer buf = iter.nextBuffer(); 2300 if (buf != buffer) { 2301 for (EditorIterator it = new EditorIterator(); it.hasNext();) { 2302 Editor ed = it.nextEditor(); 2303 ed.views.remove(buf); 2304 } 2305 buf.deleteAutosaveFile(); 2306 iter.remove(); 2307 buf.dispose(); 2308 } 2309 } 2310 2311 Sidebar.setUpdateFlagInAllFrames(SIDEBAR_BUFFER_LIST_ALL); 2312 Sidebar.refreshSidebarInAllFrames(); 2313 setDefaultCursor(); 2314 } 2315 2316 public boolean execute(String command) throws NoSuchMethodException 2317 { 2318 String [] array = parseCommand(command); 2319 if (array == null) 2320 return false; 2321 String methodName = array[0]; 2322 String parameters = array[1]; 2323 return execute(methodName, parameters); 2324 } 2325 2326 public boolean execute(String commandName, String parameters) throws NoSuchMethodException 2327 { 2328 if (commandName == null) 2329 return false; 2330 2331 try { 2332 String className = null; 2333 String methodName = null; 2334 Method method = null; 2335 2336 Class [] parameterTypes; 2337 if (parameters == null) 2338 parameterTypes = new Class [0]; 2339 else { 2340 parameterTypes = new Class [1]; 2341 parameterTypes[0] = Class.forName("java.lang.String"); 2342 } 2343 2344 Command command = CommandTable.getCommand(commandName); 2345 if (command != null) { 2346 method = command.getMethod(); 2347 if (method != null) { 2348 try { 2349 invoke(method, parameters); 2350 return true; 2351 } 2352 catch (IllegalArgumentException e) { 2353 } 2356 } 2357 className = command.getClassName(); 2359 methodName = command.getMethodName(); 2360 if (className == null) { 2361 method = Editor.class.getMethod(methodName, parameterTypes); 2363 } else { 2364 Class c = Class.forName("org.armedbear.j." + className); 2365 if (c != null) 2366 method = c.getMethod(methodName, parameterTypes); 2367 } 2368 if (method != null) { 2369 command.setMethod(method); 2371 invoke(method, parameters); 2372 return true; 2373 } 2374 } else { 2375 Debug.assertTrue(className == null); 2377 Debug.assertTrue(methodName == null); 2378 int index = commandName.indexOf('.'); 2379 if (index < 0) { 2380 method = Editor.class.getMethod(commandName, parameterTypes); 2382 } else if (commandName.length() > index+1) { 2383 className = commandName.substring(0, index); 2385 methodName = commandName.substring(index+1); 2386 Class c = null; 2387 try { 2388 c = Class.forName("org.armedbear.j." + className); 2389 } 2390 catch (ClassNotFoundException e) {} 2391 if (c == null) { 2392 c = loadExtensionClass(className); 2394 } 2395 if (c != null) { 2396 method = c.getMethod(methodName, parameterTypes); 2398 } 2399 } 2400 if (method != null) { 2401 invoke(method, parameters); 2402 return true; 2403 } 2404 } 2405 } 2406 catch (NoSuchMethodException e) { 2407 throw e; 2408 } 2409 catch (Throwable t) { 2410 Log.error(t); 2411 } 2412 return false; 2413 } 2414 2415 private void invoke(Method method, String parameters) throws IllegalArgumentException 2416 { 2417 Object [] args; 2418 if (parameters == null) 2419 args = new Object [0]; else { 2421 args = new Object [1]; 2422 args[0] = parameters; 2423 } 2424 try { 2425 method.invoke(this, args); 2426 } 2427 catch (IllegalArgumentException e) { 2428 throw e; 2429 } 2430 catch (Throwable t) { 2431 Log.error(t); 2432 } 2433 } 2434 2435 public boolean handleKeyEvent(char keyChar, int keyCode, int modifiers) 2436 { 2437 if (insertingKeyText) { 2438 insertKeyTextInternal(keyChar, keyCode, modifiers); 2439 return true; 2440 } 2441 KeyMapping mapping = getKeyMapping(keyChar, keyCode, modifiers); 2442 if (mapping != null) { 2443 Object command = mapping.getCommand(); 2444 if (isRecordingMacro()) { 2445 if (command != "recordMacro" && command != "playbackMacro") 2446 Macro.record(this, command); 2447 } 2448 if (command instanceof String ) { 2449 String commandString = (String ) command; 2450 if (commandString.length() > 0 && commandString.charAt(0) == '(') { 2451 executeCommand(commandString); 2453 return true; 2454 } 2455 String [] array = parseCommand(commandString); 2456 if (array != null) { 2457 String methodName = array[0]; 2458 String parameters = array[1]; 2459 try { 2460 return execute(methodName, parameters); 2461 } 2462 catch (NoSuchMethodException e) {} 2463 } 2464 } else if (command instanceof LispObject) { 2465 try { 2466 Lisp.funcall0(Lisp.coerceToFunction((LispObject)command), 2467 LispThread.currentThread()); 2468 } 2469 catch (Throwable t) { 2470 Log.error(t); 2471 } 2472 return true; 2473 } 2474 } 2475 return false; 2476 } 2477 2478 public KeyMapping getKeyMapping(char keyChar, int keyCode, int modifiers) 2479 { 2480 KeyMapping mapping = 2482 buffer.getMode().getKeyMap().lookup(keyChar, keyCode, modifiers); 2483 if (mapping != null) 2484 return mapping; 2485 return KeyMap.getGlobalKeyMap().lookup(keyChar, keyCode, modifiers); 2487 } 2488 2489 public Object [] getKeyMapping(String command) 2492 { 2493 Mode mode = null; 2494 KeyMapping mapping = buffer.getKeyMapForMode().getKeyMapping(command); 2496 if (mapping == null) { 2498 mapping = KeyMap.getGlobalKeyMap().getKeyMapping(command); 2499 if (mapping != null) { 2502 javax.swing.KeyStroke keyStroke = 2503 javax.swing.KeyStroke.getKeyStroke(mapping.getKeyCode(), 2504 mapping.getModifiers()); 2505 if (buffer.getKeyMapForMode().lookup(keyStroke) != null) 2506 mapping = null; 2507 } 2508 } else 2509 mode = getMode(); 2510 Object [] values = new Object [2]; 2511 values[0] = mapping; 2512 values[1] = mode; 2513 return values; 2514 } 2515 2516 public void pageDown() 2517 { 2518 if (dot == null) 2519 return; 2520 maybeResetGoalColumn(); 2521 if (mark != null) { 2522 CompoundEdit compoundEdit = beginCompoundEdit(); 2523 addUndo(SimpleEdit.MOVE); 2524 setMark(null); 2525 setUpdateFlag(REPAINT); 2526 pageDownInternal(); 2527 endCompoundEdit(compoundEdit); 2528 } else 2529 pageDownInternal(); 2530 setCurrentCommand(COMMAND_PAGE_DOWN); 2531 } 2532 2533 public void pageDownOtherWindow() 2534 { 2535 final Editor ed = frame.getOtherEditor(); 2536 if (ed != null) { 2537 ed.pageDown(); 2538 ed.updateDisplay(); 2539 } 2540 } 2541 2542 public void selectPageDown() 2543 { 2544 if (dot == null) 2545 return; 2546 maybeResetGoalColumn(); 2547 if (mark == null) { 2548 CompoundEdit compoundEdit = beginCompoundEdit(); 2549 addUndo(SimpleEdit.MOVE); 2550 setMarkAtDot(); 2551 pageDownInternal(); 2552 endCompoundEdit(compoundEdit); 2553 } else 2554 pageDownInternal(); 2555 setCurrentCommand(COMMAND_PAGE_DOWN); 2556 } 2557 2558 public void pageUp() 2559 { 2560 if (dot == null) 2561 return; 2562 maybeResetGoalColumn(); 2563 if (mark != null) { 2564 CompoundEdit compoundEdit = beginCompoundEdit(); 2565 addUndo(SimpleEdit.MOVE); 2566 setMark(null); 2567 setUpdateFlag(REPAINT); 2568 pageUpInternal(); 2569 endCompoundEdit(compoundEdit); 2570 } else 2571 pageUpInternal(); 2572 setCurrentCommand(COMMAND_PAGE_UP); 2573 } 2574 2575 public void pageUpOtherWindow() 2576 { 2577 final Editor ed = frame.getOtherEditor(); 2578 if (ed != null) { 2579 ed.pageUp(); 2580 ed.updateDisplay(); 2581 } 2582 } 2583 2584 public void selectPageUp() 2585 { 2586 if (dot == null) 2587 return; 2588 maybeResetGoalColumn(); 2589 if (mark == null) { 2590 CompoundEdit compoundEdit = beginCompoundEdit(); 2591 addUndo(SimpleEdit.MOVE); 2592 setMarkAtDot(); 2593 pageUpInternal(); 2594 endCompoundEdit(compoundEdit); 2595 } else 2596 pageUpInternal(); 2597 setCurrentCommand(COMMAND_PAGE_UP); 2598 } 2599 2600 private void pageDownInternal() 2601 { 2602 Debug.assertTrue(buffer.needsRenumbering == false); 2603 2604 int topLineNumber = display.getTopLineNumber(); 2605 Line dotLine = getDotLine(); 2606 int dotLineNumber = dot.lineNumber(); 2607 int numRows = display.getRows(); 2608 2609 Line[] lines = new Line[numRows]; 2610 Line line = getTopLine(); 2611 int dotRow = -1; 2612 for (int i = 0; i < numRows; i++) { 2613 lines[i] = line; 2614 if (line == dotLine) 2615 dotRow = i; 2616 if (line != null) 2617 line = line.nextVisible(); 2618 } 2619 Line bottomLine = lines[numRows - 1]; 2620 2621 if (bottomLine == null) { 2622 if (dotRow >= 0) { 2624 Position eob = getEob(); 2625 if (eob != null) { 2626 addUndo(SimpleEdit.MOVE); 2627 updateDotLine(); 2628 dot.setLine(eob.getLine()); 2629 moveDotToGoalCol(); 2630 updateDotLine(); 2631 } 2632 } 2633 return; 2634 } 2635 2636 display.setTopLine(bottomLine); 2638 setUpdateFlag(REPAINT); 2639 2640 if (dotRow >= 0) { 2641 line = getTopLine(); 2642 for (int i = 0; i < dotRow; i++) { 2643 Line next = line.nextVisible(); 2644 if (next == null) 2645 break; 2646 line = next; 2647 } 2648 addUndo(SimpleEdit.MOVE); 2649 dot.setLine(line); 2650 moveDotToGoalCol(); 2651 } 2652 } 2653 2654 private void pageUpInternal() 2655 { 2656 if (dot.getLine() == buffer.getFirstLine()) 2657 return; 2658 Debug.assertTrue(buffer.needsRenumbering == false); 2659 int topLineNumber = display.getTopLineNumber(); 2660 int dotLineNumber = dot.lineNumber(); 2661 int linesToScroll = display.getRows() - 1; 2662 boolean dotLineIsVisible = false; 2663 if (dotLineNumber >= topLineNumber) { 2664 Line bottomLine = display.getBottomLine(); 2665 if (bottomLine != null) 2666 if (dotLineNumber <= bottomLine.lineNumber()) 2667 dotLineIsVisible = true; 2668 } 2669 addUndo(SimpleEdit.MOVE); 2670 if (dotLineIsVisible) { 2671 for (int i = 0; i < linesToScroll; i++) { 2672 Line topLinePrevious = getTopLine().previousVisible(); 2673 if (topLinePrevious != null) 2674 display.setTopLine(topLinePrevious); 2675 Line dotLinePrevious = dot.getLine().previousVisible(); 2676 if (dotLinePrevious == null) 2677 break; 2678 dot.setLine(dotLinePrevious); 2679 } 2680 } else { 2681 for (int i = 0; i < linesToScroll; i++) { 2682 Line dotLinePrevious = dot.getLine().previousVisible(); 2683 if (dotLinePrevious == null) 2684 break; 2685 dot.setLine(dotLinePrevious); 2686 } 2687 } 2688 moveDotToGoalCol(); 2689 setUpdateFlag(REPAINT); 2690 } 2691 2692 public void beginningOfBlock() 2694 { 2695 if (mark != null) { 2696 Region r = new Region(buffer, mark, dot); 2697 dot.moveTo(r.getBegin()); 2698 setMark(null); 2699 moveCaretToDotCol(); 2700 if (r.getBeginLine() != r.getEndLine()) 2701 setUpdateFlag(REPAINT); 2702 else 2703 updateDotLine(); 2704 } 2705 } 2706 2707 public void endOfBlock() 2709 { 2710 if (mark != null) { 2711 Region r = new Region(buffer, mark, dot); 2712 dot.moveTo(r.getEnd()); 2713 setMark(null); 2714 moveCaretToDotCol(); 2715 if (r.getBeginLine() != r.getEndLine()) 2716 setUpdateFlag(REPAINT); 2717 else 2718 updateDotLine(); 2719 } 2720 } 2721 2722 public void right() 2723 { 2724 if (dot == null) 2725 return; 2726 if (buffer.getBooleanProperty(Property.RESTRICT_CARET)) { 2727 if (mark == null && getDotOffset() >= getDotLine().length()) { 2728 if (getDotLine().next() != null) { 2730 moveDotTo(getDotLine().next(), 0); 2731 setCurrentCommand(COMMAND_RIGHT); 2732 } 2733 return; 2734 } 2735 } 2736 if (mark != null || lastCommand != COMMAND_RIGHT) 2737 addUndo(SimpleEdit.MOVE); 2738 if (mark != null) 2739 endOfBlock(); 2740 else if (dot.getOffset() < dot.getLineLength()) { 2741 dot.skip(1); 2742 moveCaretToDotCol(); 2743 } else { 2744 ++display.caretCol; 2745 } 2746 updateDotLine(); 2747 setCurrentCommand(COMMAND_RIGHT); 2748 setUpdateFlag(REFRAME); 2749 } 2750 2751 public void selectRight() 2752 { 2753 if (dot == null) 2754 return; 2755 if (getDotOffset() < getDotLine().length()) { 2756 if (mark == null || lastCommand != COMMAND_RIGHT) 2757 addUndo(SimpleEdit.MOVE); 2758 if (mark == null) 2759 setMarkAtDot(); 2760 dot.moveRight(); 2761 moveCaretToDotCol(); 2762 } else { 2763 if (buffer.getBooleanProperty(Property.RESTRICT_CARET)) { 2765 if (getDotLine().next() == null) 2766 return; 2767 if (mark == null || lastCommand != COMMAND_RIGHT) 2768 addUndo(SimpleEdit.MOVE); 2769 if (mark == null) 2770 setMarkAtDot(); 2771 updateDotLine(); 2772 dot.moveTo(getDotLine().next(), 0); 2773 moveCaretToDotCol(); 2774 } else { 2775 if (lastCommand != COMMAND_RIGHT) 2777 addUndo(SimpleEdit.MOVE); 2778 ++display.caretCol; 2779 } 2780 } 2781 updateDotLine(); 2782 setCurrentCommand(COMMAND_RIGHT); 2783 setUpdateFlag(REFRAME); 2784 } 2785 2786 public void left() 2787 { 2788 if (dot == null) 2789 return; 2790 final Line dotLine = getDotLine(); 2791 final int dotOffset = getDotOffset(); 2792 final Line prevLine = dotLine.previous(); 2793 if (dotOffset == 0 && prevLine == null) 2794 return; 2795 if (mark != null || lastCommand != COMMAND_LEFT) 2796 addUndo(SimpleEdit.MOVE); 2797 if (mark != null) 2798 beginningOfBlock(); 2799 else { 2800 int absCaretCol = display.getCaretCol() + display.getShift(); 2801 if (absCaretCol > 0 && absCaretCol <= buffer.getCol(dotLine, dotLine.length())) { 2802 dot.setOffset(dotOffset - 1); 2804 moveCaretToDotCol(); 2805 } else if (absCaretCol > 0) { 2806 --display.caretCol; 2808 } else if (dot.getOffset() == 0) { 2809 update(dotLine); 2811 setDot(prevLine, prevLine.length()); 2812 moveCaretToDotCol(); 2813 } else { 2814 Debug.assertTrue(false); 2816 } 2817 } 2818 updateDotLine(); 2819 setCurrentCommand(COMMAND_LEFT); 2820 setUpdateFlag(REFRAME); 2821 } 2822 2823 public void selectLeft() 2824 { 2825 if (dot == null) 2826 return; 2827 final Line dotLine = getDotLine(); 2828 final int dotOffset = getDotOffset(); 2829 final Line prevLine = dotLine.previous(); 2830 if (dotOffset == 0 && prevLine == null) 2831 return; 2832 if (mark == null || lastCommand != COMMAND_LEFT) 2833 addUndo(SimpleEdit.MOVE); 2834 2835 final int absCaretCol = display.getAbsoluteCaretCol(); 2837 final int end = buffer.getCol(dotLine, dotLine.length()); 2838 if (mark == null && absCaretCol <= end) 2839 setMarkAtDot(); 2840 2841 if (absCaretCol > 0 && absCaretCol <= end) { 2842 dot.moveLeft(); 2844 moveCaretToDotCol(); 2845 } else if (absCaretCol > 0) { 2846 --display.caretCol; 2848 } else if (dotOffset == 0) { 2849 updateDotLine(); 2851 setDot(prevLine, prevLine.length()); 2852 moveCaretToDotCol(); 2853 } else { 2854 Debug.assertTrue(false); 2856 } 2857 updateDotLine(); 2858 setCurrentCommand(COMMAND_LEFT); 2859 setUpdateFlag(REFRAME); 2860 } 2861 2862 public final int getAbsoluteCaretCol() 2863 { 2864 return display.getAbsoluteCaretCol(); 2865 } 2866 2867 public final void setAbsoluteCaretCol(int col) 2868 { 2869 display.setAbsoluteCaretCol(col); 2870 } 2871 2872 private int goalColumn; 2873 2874 public final void setGoalColumn(int col) 2875 { 2876 goalColumn = col; 2877 } 2878 2879 public void moveDotToGoalCol() 2880 { 2881 if (buffer.getBooleanProperty(Property.RESTRICT_CARET)) { 2882 final int limit = 2883 buffer.getCol(getDotLine(), getDotLine().length()); 2884 moveDotToCol(goalColumn > limit ? limit : goalColumn); 2885 moveCaretToDotCol(); 2886 } else { 2887 setAbsoluteCaretCol(goalColumn); 2888 moveDotToCaretCol(); 2889 } 2890 } 2891 2892 public void down() 2895 { 2896 maybeResetGoalColumn(); 2897 display.down(false); 2898 setCurrentCommand(COMMAND_DOWN); 2899 } 2900 2901 public void selectDown() 2902 { 2903 maybeResetGoalColumn(); 2904 display.down(true); 2905 setCurrentCommand(COMMAND_DOWN); 2906 } 2907 2908 public void up() 2911 { 2912 maybeResetGoalColumn(); 2913 display.up(false); 2914 setCurrentCommand(COMMAND_UP); 2915 } 2916 2917 public void selectUp() 2918 { 2919 maybeResetGoalColumn(); 2920 display.up(true); 2921 setCurrentCommand(COMMAND_UP); 2922 } 2923 2924 private void maybeResetGoalColumn() 2925 { 2926 switch (lastCommand) { 2927 case COMMAND_UP: 2928 case COMMAND_DOWN: 2929 case COMMAND_PAGE_UP: 2930 case COMMAND_PAGE_DOWN: 2931 case COMMAND_WINDOW_UP: 2932 case COMMAND_WINDOW_DOWN: 2933 return; 2934 default: 2935 goalColumn = getAbsoluteCaretCol(); 2936 return; 2937 } 2938 } 2939 2940 public void windowUp() 2941 { 2942 maybeResetGoalColumn(); 2943 display.windowUp(); 2944 maybeScrollCaret(); 2945 setCurrentCommand(COMMAND_WINDOW_UP); 2946 } 2947 2948 public void windowDown() 2949 { 2950 maybeResetGoalColumn(); 2951 display.windowDown(); 2952 maybeScrollCaret(); 2953 setCurrentCommand(COMMAND_WINDOW_DOWN); 2954 } 2955 2956 public void maybeScrollCaret() 2957 { 2958 if (dot == null) 2959 return; 2960 if (mark != null) 2962 return; 2963 if (buffer.getBooleanProperty(Property.SCROLL_CARET)) { 2964 final int dotLineNumber = dot.lineNumber(); 2965 final Line topLine = display.getTopLine(); 2966 if (dotLineNumber < topLine.lineNumber()) { 2967 addUndo(SimpleEdit.SCROLL_CARET); 2969 dot.moveTo(topLine, 0); 2970 updateDotLine(); 2971 moveCaretToDotCol(); 2972 goalColumn = 0; 2973 return; 2974 } 2975 final Line bottomLine = display.getBottomLine(); 2976 if (dotLineNumber > bottomLine.lineNumber()) { 2977 addUndo(SimpleEdit.SCROLL_CARET); 2979 updateDotLine(); 2980 dot.moveTo(bottomLine, 0); 2981 updateDotLine(); 2982 moveCaretToDotCol(); 2983 goalColumn = 0; 2984 } 2985 } 2986 } 2987 2988 public void toCenter() 2989 { 2990 display.toCenter(); 2991 } 2992 2993 public void toTop() 2994 { 2995 display.toTop(); 2996 } 2997 2998 private void selectToPosition(Position pos) 2999 { 3000 if (!pos.equals(dot) || 3001 buffer.getCol(pos) != display.getAbsoluteCaretCol()) { 3002 addUndo(SimpleEdit.MOVE); 3003 if (mark == null) 3004 setMarkAtDot(); 3005 if (pos.getLine() != getDotLine()) 3006 setUpdateFlag(REPAINT); 3007 else 3008 updateDotLine(); 3009 dot.moveTo(pos); 3010 moveCaretToDotCol(); 3011 } 3012 } 3013 3014 public void bol() 3015 { 3016 if (dot != null) 3017 moveDotTo(dot.getLine(), 0); 3018 } 3019 3020 public void home() 3021 { 3022 if (dot == null) 3023 return; 3024 final boolean extend = prefs.getBooleanProperty(Property.EXTEND_HOME); 3025 Position pos; 3026 if (mark != null) 3027 pos = new Position(new Region(this).getBegin()); 3028 else 3029 pos = new Position(dot); 3030 int indent = pos.getLine().getIndentation(); 3031 if (extend) { 3032 if (pos.getOffset() > indent) 3033 pos.setOffset(indent); 3034 else 3035 pos.setOffset(0); 3036 } else { 3037 if (pos.getOffset() > indent) 3038 pos.setOffset(indent); 3039 else if (pos.getOffset() == indent) 3040 pos.setOffset(0); 3041 else 3042 pos.setOffset(indent); 3043 } 3044 if (mark != null || !pos.equals(dot) || 3045 buffer.getCol(pos) != display.getAbsoluteCaretCol()) { 3046 moveDotTo(pos); 3047 setCurrentCommand(COMMAND_HOME); 3048 return; 3049 } 3050 if (!extend) 3052 return; 3053 if (System.currentTimeMillis() - dispatcher.getLastEventMillis() > 1000) { 3054 setUpdateFlag(REFRAME); 3056 setCurrentCommand(COMMAND_HOME); 3057 return; 3058 } 3059 if (lastCommand == COMMAND_HOME_HOME) 3060 pos = new Position(buffer.getFirstLine(), 0); 3061 else if (lastCommand == COMMAND_HOME) { 3062 pos = new Position(getTopLine(), 0); 3063 setUpdateFlag(REFRAME); 3064 setCurrentCommand(COMMAND_HOME_HOME); 3065 } else { 3066 setUpdateFlag(REFRAME); 3067 setCurrentCommand(COMMAND_HOME); 3068 return; 3069 } 3070 if (!pos.equals(dot) || 3071 buffer.getCol(pos) != display.getAbsoluteCaretCol()) 3072 moveDotTo(pos); 3073 } 3074 3075 public void selectHome() 3076 { 3077 if (dot == null) 3078 return; 3079 final boolean extend = prefs.getBooleanProperty(Property.EXTEND_HOME); 3080 Position pos; 3081 if (mark != null) 3082 pos = new Position(new Region(buffer, mark, dot).getBegin()); 3083 else 3084 pos = new Position(dot); 3085 int indent = pos.getLine().getIndentation(); 3086 if (extend) { 3087 if (pos.getOffset() > indent) 3088 pos.setOffset(indent); 3089 else 3090 pos.setOffset(0); 3091 } else { 3092 if (pos.getOffset() > indent) 3093 pos.setOffset(indent); 3094 else if (pos.getOffset() == indent) 3095 pos.setOffset(0); 3096 else 3097 pos.setOffset(indent); 3098 } 3099 if (mark != null || !pos.equals(dot) || 3100 buffer.getCol(pos) != display.getAbsoluteCaretCol()) { 3101 selectToPosition(pos); 3102 setUpdateFlag(REFRAME); 3103 setCurrentCommand(COMMAND_SELECT_HOME); 3104 return; 3105 } 3106 if (!prefs.getBooleanProperty(Property.EXTEND_HOME)) 3108 return; 3109 if (System.currentTimeMillis() - dispatcher.getLastEventMillis() > 1000) { 3110 setUpdateFlag(REFRAME); 3112 setCurrentCommand(COMMAND_SELECT_HOME); 3113 return; 3114 } 3115 if (lastCommand == COMMAND_SELECT_HOME_HOME) 3116 pos = new Position(buffer.getFirstLine(), 0); 3117 else if (lastCommand == COMMAND_SELECT_HOME) { 3118 pos = new Position(getTopLine(), 0); 3119 setUpdateFlag(REFRAME); 3120 setCurrentCommand(COMMAND_SELECT_HOME_HOME); 3121 } else { 3122 setUpdateFlag(REFRAME); 3123 setCurrentCommand(COMMAND_SELECT_HOME); 3124 return; 3125 } 3126 if (!pos.equals(dot) || 3127 buffer.getCol(pos) != display.getAbsoluteCaretCol()) 3128 selectToPosition(pos); 3129 } 3130 3131 public void eol() 3132 { 3133 if (dot == null) 3134 return; 3135 if (mark != null || dot.getOffset() != dot.getLineLength() || 3136 buffer.getCol(dot) != display.getCaretCol() + display.getShift()) 3137 moveDotTo(dot.getLine(), dot.getLineLength()); 3138 } 3139 3140 public void end() 3141 { 3142 if (dot == null) 3143 return; 3144 Position pos; 3145 if (mark != null) 3146 pos = new Position(new Region(buffer, mark, dot).getEnd()); 3147 else 3148 pos = new Position(dot); 3149 pos.setOffset(pos.getLineLength()); 3150 if (mark != null || !pos.equals(dot) || 3151 buffer.getCol(pos) != display.getAbsoluteCaretCol()) { 3152 moveDotTo(pos); 3153 setUpdateFlag(REFRAME); 3154 setCurrentCommand(COMMAND_END); 3155 return; 3156 } 3157 if (!prefs.getBooleanProperty(Property.EXTEND_END)) 3159 return; 3160 if (System.currentTimeMillis() - dispatcher.getLastEventMillis() > 1000) { 3161 setUpdateFlag(REFRAME); 3163 setCurrentCommand(COMMAND_END); 3164 return; 3165 } 3166 if (lastCommand == COMMAND_END_END) 3167 pos = getEob(); 3168 else if (lastCommand == COMMAND_END) { 3169 Line bottomLine = display.getBottomLine(); 3170 if (bottomLine != null) 3171 pos = new Position(bottomLine, bottomLine.length()); 3172 else 3173 pos = getEob(); 3174 setUpdateFlag(REFRAME); 3175 setCurrentCommand(COMMAND_END_END); 3176 } else { 3177 setUpdateFlag(REFRAME); 3178 setCurrentCommand(COMMAND_END); 3179 return; 3180 } 3181 if (!pos.equals(dot) || 3182 buffer.getCol(pos) != display.getAbsoluteCaretCol()) 3183 moveDotTo(pos); 3184 } 3185 3186 public void selectEnd() 3187 { 3188 if (dot == null) 3189 return; 3190 Position pos; 3191 if (mark != null) 3192 pos = new Position(new Region(buffer, mark, dot).getEnd()); 3193 else 3194 pos = new Position(dot); 3195 pos.setOffset(pos.getLineLength()); 3196 if (!pos.equals(dot) || 3197 buffer.getCol(pos) != display.getAbsoluteCaretCol()) { 3198 selectToPosition(pos); 3199 setUpdateFlag(REFRAME); 3200 setCurrentCommand(COMMAND_END); 3201 return; 3202 } 3203 if (!prefs.getBooleanProperty(Property.EXTEND_END)) 3205 return; 3206 if (System.currentTimeMillis() - dispatcher.getLastEventMillis() > 1000) { 3207 setUpdateFlag(REFRAME); 3209 setCurrentCommand(COMMAND_END); 3210 return; 3211 } 3212 if (lastCommand == COMMAND_END_END) 3213 pos = getEob(); 3214 else if (lastCommand == COMMAND_END) { 3215 Line bottomLine = display.getBottomLine(); 3216 if (bottomLine != null) 3217 pos = new Position(bottomLine, bottomLine.length()); 3218 else 3219 pos = getEob(); 3220 setUpdateFlag(REFRAME); 3221 setCurrentCommand(COMMAND_END_END); 3222 } else { 3223 setCurrentCommand(COMMAND_END); 3224 return; 3225 } 3226 if (!pos.equals(dot) || 3227 buffer.getCol(pos) != display.getAbsoluteCaretCol()) 3228 selectToPosition(pos); 3229 } 3230 3231 public void bob() 3232 { 3233 if (buffer.getFirstLine() != null) 3234 moveDotTo(buffer.getFirstLine(), 0); 3235 } 3236 3237 public void selectBob() 3238 { 3239 if (dot == null) 3240 return; 3241 if (buffer.getFirstLine() == null) 3242 return; 3243 addUndo(SimpleEdit.MOVE); 3244 if (mark == null) 3245 setMarkAtDot(); 3246 dot.moveTo(buffer.getFirstLine(), 0); 3247 moveCaretToDotCol(); 3248 setUpdateFlag(REPAINT); 3249 } 3250 3251 private final Position getEob() 3252 { 3253 return buffer.getEnd(); 3254 } 3255 3256 public void eob() 3257 { 3258 moveDotTo(getEob()); 3259 } 3260 3261 public void selectEob() 3262 { 3263 if (buffer.getFirstLine() == null) 3264 return; 3265 Line line = buffer.getFirstLine(); 3266 while (line.next() != null) 3267 line = line.next(); 3268 addUndo(SimpleEdit.MOVE); 3269 if (mark == null) 3270 setMarkAtDot(); 3271 dot.moveTo(line, line.length()); 3272 moveCaretToDotCol(); 3273 setUpdateFlag(REPAINT); 3274 } 3275 3276 public void top() 3277 { 3278 if (dot == null) 3279 return; 3280 if (getDotLine() != getTopLine()) { 3281 addUndo(SimpleEdit.MOVE); 3282 updateDotLine(); 3283 dot.setLine(getTopLine()); 3284 moveDotToCaretCol(); 3285 } 3286 } 3287 3288 public void bottom() 3289 { 3290 if (dot == null) 3291 return; 3292 Line line = display.getBottomLine(); 3293 if (line != getDotLine()) { 3294 addUndo(SimpleEdit.MOVE); 3295 updateDotLine(); 3296 dot.setLine(line); 3297 updateDotLine(); 3298 moveDotToCaretCol(); 3299 } 3300 } 3301 3302 public void selectWord() 3303 { 3304 if (dot == null) 3305 return; 3306 AWTEvent e = dispatcher.getLastEvent(); 3307 CompoundEdit compoundEdit = null; 3308 if (e instanceof MouseEvent ) { 3309 compoundEdit = beginCompoundEdit(); 3310 mouseMoveDotToPoint((MouseEvent )e); 3311 } 3312 if (inWord()) { 3313 addUndo(SimpleEdit.MOVE); 3314 while (getDotOffset() > 0) { 3315 dot.moveLeft(); 3316 if (!inWord()) { 3317 dot.moveRight(); 3318 break; 3319 } 3320 } 3321 setMarkAtDot(); 3322 final int limit = getDotLine().length(); 3323 while (inWord() && getDotOffset() < limit) 3324 dot.moveRight(); 3325 moveCaretToDotCol(); 3326 } 3327 if (compoundEdit != null) 3328 endCompoundEdit(compoundEdit); 3329 } 3330 3331 public void mouseMoveDotToPoint() 3332 { 3333 AWTEvent e = dispatcher.getLastEvent(); 3334 if (e instanceof MouseEvent ) 3335 mouseMoveDotToPoint((MouseEvent )e); 3336 } 3337 3338 public void mouseMoveDotToPoint(MouseEvent e) 3339 { 3340 addUndo(SimpleEdit.MOVE); 3341 if (mark != null) 3342 unmark(); 3343 display.moveCaretToPoint(e.getPoint()); 3344 if (buffer.getBooleanProperty(Property.RESTRICT_CARET)) 3345 moveCaretToDotCol(); 3346 3347 Editor.restoreFocus(); 3352 } 3353 3354 public void mouseSelect() 3355 { 3356 if (dot != null) { 3357 AWTEvent e = dispatcher.getLastEvent(); 3358 if (e instanceof MouseEvent ) { 3359 MouseEvent mouseEvent = (MouseEvent ) e; 3360 Position pos = display.positionFromPoint(mouseEvent.getPoint()); 3361 addUndo(SimpleEdit.MOVE); 3362 Position min, max; 3363 if (mark == null) { 3364 setMarkAtDot(); 3366 dot = pos; 3367 moveCaretToDotCol(); 3368 Region r = new Region(this); 3369 min = r.getBegin(); 3370 max = r.getEnd(); 3371 } else { 3372 Region r = new Region(this); 3374 min = r.getBegin(); 3375 max = r.getEnd(); 3376 if (pos.isBefore(r.getBegin())) { 3377 min = pos; 3378 mark = r.getEnd(); 3379 } else if (pos.isAfter(r.getEnd())) { 3380 max = pos; 3381 mark = r.getBegin(); 3382 } else { 3383 if (Position.getDistance(r.getBegin(), pos) < Position.getDistance(r.getEnd(), pos)) { 3385 mark = r.getEnd(); 3387 } else 3388 mark = r.getBegin(); 3389 } 3390 dot = pos; 3391 moveCaretToDotCol(); 3392 } 3393 if (max.lineNumber() - min.lineNumber() < display.getRows()) { 3395 Line line = min.getLine(); 3396 Line endLine = max.getLine(); 3397 while (line != null && line != endLine) { 3398 update(line); 3399 line = line.next(); 3400 } 3401 update(endLine); 3402 } else 3403 setUpdateFlag(REPAINT); 3404 } 3405 } 3406 } 3407 3408 public void mouseSelectColumn() 3409 { 3410 if (dot != null) { 3411 AWTEvent e = dispatcher.getLastEvent(); 3412 if (e instanceof MouseEvent ) { 3413 MouseEvent mouseEvent = (MouseEvent ) e; 3414 if (getMark() == null) 3415 setMarkAtDot(); 3416 display.moveCaretToPoint(mouseEvent.getPoint()); 3417 setColumnSelection(true); 3418 display.setUpdateFlag(REPAINT); 3419 } 3420 } 3421 } 3422 3423 private JPopupMenu popup; 3424 3425 public void mouseShowContextMenu() 3426 { 3427 AWTEvent e = dispatcher.getLastEvent(); 3428 if (e instanceof MouseEvent ) { 3429 MouseEvent mouseEvent = (MouseEvent ) e; 3430 int x = mouseEvent.getX(); 3431 int y = mouseEvent.getY(); 3432 popup = buffer.getMode().getContextMenu(this); 3433 if (popup != null) { 3434 Dimension dimPopup = popup.getPreferredSize(); 3435 Dimension dimDisplay = display.getSize(); 3436 int xMax = dimDisplay.width - dimPopup.width - 5; 3437 int yMax = dimDisplay.height - dimPopup.height - 5; 3438 if (x > xMax) 3439 x = xMax; 3440 else 3441 ++x; 3442 if (y > yMax) 3443 y = yMax; 3444 else 3445 ++y; 3446 popup.show(mouseEvent.getComponent(), x, y); 3447 } 3448 } 3449 } 3450 3451 public final JPopupMenu getPopup() 3452 { 3453 return popup; 3454 } 3455 3456 public final void setPopup(JPopupMenu popup) 3457 { 3458 this.popup = popup; 3459 } 3460 3461 public void killPopup() 3462 { 3463 if (popup != null) { 3464 popup.setVisible(false); 3465 popup = null; 3466 restoreFocus(); 3467 } 3468 } 3469 3470 private boolean inWord() 3471 { 3472 return getMode().isIdentifierPart(getDotChar()); 3473 } 3474 3475 private boolean inWhitespace() 3476 { 3477 return Character.isWhitespace(getDotChar()); 3478 } 3479 3480 private void skipWhitespace() 3481 { 3482 while (inWhitespace()) 3483 if (!nextChar()) 3484 break; 3485 } 3486 3487 private void nextWord() 3488 { 3489 if (dot == null) 3490 return; 3491 if (inWord()) { 3492 while (nextChar()) 3493 if (!inWord()) 3494 break; 3495 skipWhitespace(); 3496 } else if (inWhitespace()) { 3497 skipWhitespace(); 3498 } else { 3499 while (nextChar() && !inWord() && !inWhitespace()) 3501 ; 3502 skipWhitespace(); 3503 } 3504 } 3505 3506 private void prevWord() 3507 { 3508 if (dot == null) 3509 return; 3510 if (!prevChar()) 3511 return; 3512 if (inWord()) { 3513 while (prevChar() && inWord()) 3514 ; 3515 if (!inWord()) 3516 nextChar(); 3517 } else if (inWhitespace()) { 3518 while (prevChar() && inWhitespace()) 3519 ; 3520 if (inWord()) { 3521 while (prevChar() && inWord()) 3522 ; 3523 if (!inWord()) 3524 nextChar(); 3525 } else { 3526 while (prevChar() && !inWord() && !inWhitespace()) 3527 ; 3528 if (inWord() || inWhitespace()) 3529 nextChar(); 3530 } 3531 } else { 3532 while (prevChar()) { 3534 if (inWord()) 3535 break; 3536 if (inWhitespace()) 3537 break; 3538 } 3539 if (inWord() || inWhitespace()) 3540 nextChar(); 3541 } 3542 } 3543 3544 public void wordRight() 3545 { 3546 if (dot == null) 3547 return; 3548 updateDotLine(); 3549 addUndo(SimpleEdit.MOVE); 3550 endOfBlock(); 3551 nextWord(); 3552 moveCaretToDotCol(); 3553 updateDotLine(); 3554 } 3555 3556 public void wordLeft() 3557 { 3558 if (dot == null) 3559 return; 3560 updateDotLine(); 3561 addUndo(SimpleEdit.MOVE); 3562 beginningOfBlock(); 3563 prevWord(); 3564 moveCaretToDotCol(); 3565 updateDotLine(); 3566 } 3567 3568 public void selectWordRight() 3569 { 3570 if (dot == null) 3571 return; 3572 addUndo(SimpleEdit.MOVE); 3573 if (mark == null) 3574 setMarkAtDot(); 3575 updateDotLine(); 3576 nextWord(); 3577 moveCaretToDotCol(); 3578 updateDotLine(); 3579 } 3580 3581 public void selectWordLeft() 3582 { 3583 if (dot == null) 3584 return; 3585 addUndo(SimpleEdit.MOVE); 3586 if (mark == null) 3587 setMarkAtDot(); 3588 updateDotLine(); 3589 prevWord(); 3590 moveCaretToDotCol(); 3591 updateDotLine(); 3592 } 3593 3594 public void selectAll() 3595 { 3596 if (dot == null) 3597 return; 3598 pushPosition(); 3599 addUndo(SimpleEdit.MOVE); 3600 unmark(); 3601 Line line = buffer.getFirstLine(); 3602 dot.moveTo(line, 0); 3603 display.setCaretCol(0); 3604 display.setShift(0); 3605 setMarkAtDot(); 3606 while (line.next() != null) 3607 line = line.next(); 3608 dot.moveTo(line, line.length()); 3609 moveCaretToDotCol(); 3610 display.setUpdateFlag(REPAINT); 3611 } 3612 3613 public void moveDotToCol(int goal) 3617 { 3618 if (dot == null) 3619 return; 3620 3621 dot.moveToCol(goal, buffer.getTabWidth()); 3622 updateDotLine(); 3623 3624 if (dot.getOffset() < dot.getLineLength()) 3627 moveCaretToDotCol(); 3628 } 3629 3630 public final void moveDotToCaretCol() 3631 { 3632 moveDotToCol(display.getAbsoluteCaretCol()); 3633 } 3634 3635 public final void moveCaretToDotCol() 3636 { 3637 display.moveCaretToDotCol(); 3638 } 3639 3640 public final void repaintDisplay() 3641 { 3642 display.setUpdateFlag(REPAINT); 3643 display.repaint(); 3644 } 3645 3646 public final void repaintNow() 3647 { 3648 display.repaintNow(); 3649 } 3650 3651 public void fillToCaret() 3656 { 3657 final int where = display.getAbsoluteCaretCol(); 3658 final Line dotLine = getDotLine(); 3659 String s = getFillString(dotLine, where); 3660 if (s != null) { 3661 try { 3662 buffer.lockWrite(); 3663 } 3664 catch (InterruptedException e) { 3665 Log.error(e); 3666 return; 3667 } 3668 try { 3669 addUndo(SimpleEdit.LINE_EDIT); 3670 dotLine.setText(dotLine.getText().concat(s)); 3671 buffer.modified(); 3672 dot.setOffset(dotLine.length()); 3673 } 3674 finally { 3675 buffer.unlockWrite(); 3676 } 3677 } 3678 } 3679 3680 private String getFillString(Line line, int where) 3681 { 3682 int end = buffer.getCol(line, line.length()); 3683 if (where <= end) 3684 return null; 3685 final int width = where - end; 3686 3687 if (buffer.getUseTabs() && line.length() == 0) { 3689 FastStringBuffer sb = new FastStringBuffer(width); 3690 int col = 0; 3691 final int tabWidth = buffer.getTabWidth(); 3692 while (col + tabWidth <= width) { 3693 sb.append('\t'); 3694 col += tabWidth; 3695 } 3696 while (col < width) { 3697 sb.append(' '); 3698 ++col; 3699 } 3700 return sb.toString(); 3701 } else 3702 return Utilities.spaces(width); 3703 } 3704 3705 public final int getDotCol() 3706 { 3707 return buffer.getCol(dot); 3708 } 3709 3710 public void insertStringInternal(String s) 3713 { 3714 updateInAllEditors(getDotLine()); 3715 buffer.insertString(dot, s); 3716 } 3717 3718 public void insertChar(char c) 3721 { 3722 final Line dotLine = getDotLine(); 3723 if (getDotOffset() > dotLine.length()) { 3724 Debug.bug(); 3726 Log.error("insertChar dot offset = " + getDotOffset() + 3727 " dotLine length = " + dotLine.length()); 3728 dot.setOffset(dotLine.length()); 3730 } 3731 try { 3732 buffer.lockWrite(); 3733 } 3734 catch (InterruptedException e) { 3735 Log.error(e); 3736 return; 3737 } 3738 try { 3739 addUndo(SimpleEdit.LINE_EDIT); 3740 fillToCaret(); 3741 FastStringBuffer sb = 3742 new FastStringBuffer(dotLine.substring(0, getDotOffset())); 3743 sb.append(c); 3744 sb.append(dotLine.substring(getDotOffset())); 3745 dotLine.setText(sb.toString()); 3746 dot.moveRight(); 3747 moveCaretToDotCol(); 3748 buffer.modified(); 3749 } 3750 finally { 3751 buffer.unlockWrite(); 3752 } 3753 updateInAllEditors(dotLine); 3754 } 3755 3756 public void insertChar() 3757 { 3758 if (!checkReadOnly()) 3759 return; 3760 String input = InputDialog.showInputDialog(this, "Character:", "Insert Character"); 3761 if (input == null || input.length() == 0) 3762 return; 3763 repaintNow(); 3764 int c = parseNumericInput(input); 3765 if (c >= 0 && c < 0xfffe) 3766 insertChar((char) c); 3767 else 3768 MessageDialog.showMessageDialog(this, "Invalid character", "Insert Character"); 3769 } 3770 3771 public void insertByte() 3772 { 3773 if (!checkReadOnly()) 3774 return; 3775 String input = InputDialog.showInputDialog(this, "Byte:", "Insert Byte"); 3776 if (input == null || input.length() == 0) 3777 return; 3778 repaintNow(); 3779 int c = parseNumericInput(input); 3780 if (c >= 0 && c <= 255) { 3781 byte[] bytes = new byte[1]; 3782 bytes[0] = (byte) c; 3783 String encoding = prefs.getStringProperty(Property.DEFAULT_ENCODING); 3784 try { 3785 String s = new String (bytes, encoding); 3786 insertChar(s.charAt(0)); 3787 } 3788 catch (UnsupportedEncodingException e) { 3789 Log.error(e); 3790 MessageDialog.showMessageDialog(this, 3791 "Unsupported encoding \"" + encoding + "\"", "Insert Byte"); 3792 } 3793 } else 3794 MessageDialog.showMessageDialog(this, 3795 "Invalid byte \"" + input + "\"", "Insert Byte"); 3796 } 3797 3798 private static int parseNumericInput(String input) 3801 { 3802 int n = -1; 3803 input = input.trim(); 3804 try { 3805 if (input.startsWith("0x") || input.startsWith("0X")) 3806 n = Integer.parseInt(input.substring(2), 16); 3807 else if (input.startsWith("0")) 3808 n = Integer.parseInt(input, 8); 3809 else 3810 n = Integer.parseInt(input, 10); 3811 } 3812 catch (NumberFormatException e) { 3813 Log.error(e); 3814 } 3815 return n; 3816 } 3817 3818 public void electricSemi() 3819 { 3820 if (!checkReadOnly()) 3821 return; 3822 if (mark != null || getDotLine().flags() == STATE_COMMENT || 3823 getMode().isInQuote(buffer, dot)) { 3824 insertNormalChar(';'); 3825 } else { 3826 CompoundEdit compoundEdit = beginCompoundEdit(); 3827 insertChar(';'); 3828 moveCaretToDotCol(); 3829 indentLine(); 3830 if (buffer.getBooleanProperty(Property.AUTO_NEWLINE)) { 3831 boolean b = true; 3832 String s = dot.getLine().trim(); 3833 if (s.startsWith("for")) { 3834 char c = s.charAt(3); 3835 if (c == ' ' || c == '\t' || c == '(') 3836 b = false; 3837 } 3838 if (b) 3839 newlineAndIndent(); 3840 } 3841 endCompoundEdit(compoundEdit); 3842 } 3843 } 3844 3845 public void electricColon() 3846 { 3847 if (!checkReadOnly()) 3848 return; 3849 try { 3850 buffer.lockWrite(); 3851 } 3852 catch (InterruptedException e) { 3853 Log.error(e); 3854 return; 3855 } 3856 try { 3857 electricColonInternal(); 3858 } 3859 finally { 3860 buffer.unlockWrite(); 3861 } 3862 } 3863 3864 private void electricColonInternal() 3865 { 3866 final Line dotLine = getDotLine(); 3867 final int dotOffset = getDotOffset(); 3868 if (mark != null || dotOffset != dotLine.length()) { 3869 insertNormalChar(':'); 3870 return; 3871 } 3872 if (dotLine.flags() == STATE_COMMENT || getMode().isInQuote(buffer, dot)) { 3873 insertNormalChar(':'); 3874 return; 3875 } 3876 CompoundEdit compoundEdit = beginCompoundEdit(); 3877 insertChar(':'); 3878 moveCaretToDotCol(); 3879 indentLine(); 3880 if (buffer.getBooleanProperty(Property.AUTO_NEWLINE)) 3881 newlineAndIndent(); 3882 endCompoundEdit(compoundEdit); 3883 } 3884 3885 public void electricStar() 3886 { 3887 if (!checkReadOnly()) 3888 return; 3889 3890 if (getDotLine().isBlank()) { 3894 if (buffer.needsParsing()) { 3895 if (getFormatter().parseBuffer()) 3896 buffer.repaint(); 3897 } 3898 CompoundEdit compoundEdit = beginCompoundEdit(); 3899 insertNormalChar('*'); 3900 indentLine(); 3901 endCompoundEdit(compoundEdit); 3902 } else 3903 insertNormalChar('*'); 3904 } 3905 3906 public void electricPound() 3907 { 3908 if (!checkReadOnly()) 3909 return; 3910 if (mark == null && getDotLine().isBlank()) { 3911 try { 3912 buffer.lockWrite(); 3913 } 3914 catch (InterruptedException e) { 3915 Log.error(e); 3916 return; 3917 } 3918 try { 3919 addUndo(SimpleEdit.LINE_EDIT); 3920 getDotLine().setText("#"); 3921 dot.setOffset(1); 3922 buffer.modified(); 3923 } 3924 finally { 3925 buffer.unlockWrite(); 3926 } 3927 updateInAllEditors(getDotLine()); 3928 moveCaretToDotCol(); 3929 } else 3930 insertNormalChar('#'); 3931 } 3932 3933 public void electricOpenBrace() 3934 { 3935 electricBraceInternal('{'); 3936 } 3937 3938 public void electricCloseBrace() 3939 { 3940 electricBraceInternal('}'); 3941 } 3942 3943 private void electricBraceInternal(char c) 3944 { 3945 if (!checkReadOnly()) 3946 return; 3947 CompoundEdit compoundEdit = beginCompoundEdit(); 3948 if (mark == null && getDotLine().isBlank()) { 3949 addUndo(SimpleEdit.LINE_EDIT); 3950 getDotLine().setText(""); 3951 dot.setOffset(0); 3952 insertChar(c); 3953 indentLine(); 3954 eol(); 3955 if (buffer.getBooleanProperty(Property.AUTO_NEWLINE)) 3956 newlineAndIndent(); 3957 } else { 3958 insertNormalChar(c); 3959 indentLine(); 3960 } 3961 endCompoundEdit(compoundEdit); 3962 } 3963 3964 public void electricCloseAngleBracket() 3965 { 3966 if (!checkReadOnly()) 3967 return; 3968 if (mark == null) { 3969 int modeId = getModeId(); 3970 if (modeId == XML_MODE || modeId == HTML_MODE) { 3971 CompoundEdit compoundEdit = beginCompoundEdit(); 3972 insertChar('>'); 3973 moveCaretToDotCol(); 3974 if (buffer.getBooleanProperty(Property.AUTO_INDENT)) { 3975 if (modeId == HTML_MODE && 3976 getDotLine().substring(0, getDotOffset()).endsWith( 3977 "</pre>")) { 3978 ; } else { 3980 indentLine(); 3981 } 3982 } 3983 endCompoundEdit(compoundEdit); 3984 return; 3985 } 3986 } 3987 insertNormalChar('>'); 3989 } 3990 3991 public void gotoline(int lineNumber) 3992 { 3993 Line line = buffer.getLine(lineNumber); 3994 if (line != null) 3995 setDot(line, 0); 3996 } 3997 3998 public void saveState() 3999 { 4000 if (saveSession) { 4001 saveView(); 4003 4004 Session.saveDefaultSession(); 4005 if (sessionName != null) 4006 if (prefs.getBooleanProperty(Property.AUTOSAVE_NAMED_SESSIONS)) 4007 Session.saveCurrentSession(); 4008 sessionProperties.saveWindowPlacement(); 4009 sessionProperties.save(); 4010 } 4011 } 4012 4013 public void reload(Buffer buf) 4015 { 4016 setWaitCursor(); 4017 if (buf.getFile() instanceof SshFile) 4018 return; Debug.assertTrue(SwingUtilities.isEventDispatchThread()); 4020 for (EditorIterator it = new EditorIterator(); it.hasNext();) { 4021 Editor ed = it.nextEditor(); 4022 if (ed.getBuffer() == buf) 4023 ed.saveView(); 4024 } 4025 4026 buf.reload(); 4028 setDefaultCursor(); 4029 } 4030 4031 public void revertBuffer() 4032 { 4033 final File file = buffer.getFile(); 4034 if (file instanceof SshFile) 4035 return; if (buffer.isModified()) { 4037 String prompt = "Discard changes to " + file.canonicalPath() + "?"; 4038 if (!confirm("Revert Buffer", prompt)) 4039 return; 4040 reload(buffer); 4041 } 4042 } 4043 4044 public boolean reactivate(Buffer buf) 4048 { 4049 if (buf instanceof ImageBuffer) 4050 return ((ImageBuffer)buf).reactivate(); 4051 4052 if (buf.getType() != Buffer.TYPE_NORMAL) 4053 return false; 4054 if (buf.isUntitled()) 4055 return false; 4056 4057 if (buf.getModeId() == BINARY_MODE) 4059 return false; 4060 4061 final File file = buf.getFile(); 4062 if (file == null || file.isRemote() || !file.isFile()) 4063 return false; 4064 4065 boolean changed = false; 4066 4067 if (buf.readOnly == file.canWrite()) { 4070 buf.readOnly = !buf.readOnly; 4072 changed = true; 4073 if (buf.readOnly && buf.isLoaded() && buf.isModified()) 4076 MessageDialog.showMessageDialog( 4077 file.canonicalPath().concat(" is no longer writable"), 4078 "Warning"); 4079 } 4080 4081 if (buf.isLoaded()) { 4082 if (file.lastModified() != buf.getLastModified()) { 4083 if (buf.isModified()) { 4084 String prompt = file.canonicalPath() + 4085 " has changed on disk. Reload and lose current changes?"; 4086 if (confirm("Reload File From Disk", prompt)) { 4087 reload(buf); 4088 changed = true; 4089 } else 4090 buf.setLastModified(file.lastModified()); 4091 } else { 4092 reload(buf); 4094 changed = true; 4095 } 4096 } 4097 } 4098 4099 return changed; 4100 } 4101 4102 public void setFocus(JComponent c) 4103 { 4104 frame.setFocus(c); 4105 } 4106 4107 public JComponent getFocusedComponent() 4108 { 4109 return frame.getFocusedComponent(); 4110 } 4111 4112 public void setFocusToDisplay() 4113 { 4114 frame.setFocus(display); 4115 } 4116 4117 public static final void restoreFocus() 4118 { 4119 Runnable r = new Runnable () { 4120 public void run() 4121 { 4122 if (currentEditor != null) 4123 currentEditor.setFocusToDisplay(); 4124 } 4125 }; 4126 SwingUtilities.invokeLater(r); 4127 } 4128 4129 public void componentHidden(ComponentEvent e) 4130 { 4131 } 4132 4133 public void componentMoved(ComponentEvent e) 4134 { 4135 } 4136 4137 public void componentResized(ComponentEvent e) 4138 { 4139 updateScrollBars(); 4140 } 4141 4142 public void componentShown(ComponentEvent e) 4143 { 4144 } 4145 4146 public void mouseWheelMoved(MouseWheelEvent e) 4147 { 4148 setFocusToDisplay(); 4153 4154 if (e.getWheelRotation() < 0) 4155 display.windowUp(5); 4156 else 4157 display.windowDown(5); 4158 } 4159 4160 public void ensureActive() 4161 { 4162 if (!frame.isActive()) { 4163 for (int i = 0; i < getFrameCount(); i++) { 4164 Frame f = getFrame(i); 4165 if (f.isActive()) { 4166 f.dispatchEvent(new WindowEvent (f, WindowEvent.WINDOW_DEACTIVATED)); 4167 break; 4168 } 4169 } 4170 frame.dispatchEvent(new WindowEvent (frame, WindowEvent.WINDOW_ACTIVATED)); 4171 } 4172 } 4173 4174 public void quit() 4175 { 4176 maybeExit(); 4177 } 4178 4179 public void saveAllExit() 4180 { 4181 tagFileManager.setEnabled(false); 4182 saveAll(); 4183 maybeExit(); tagFileManager.setEnabled(true); 4185 } 4186 4187 private void maybeExit() 4188 { 4189 int numModifiedBuffers = 0; 4190 4191 for (BufferIterator it = new BufferIterator(); it.hasNext();) { 4192 if (it.nextBuffer().isModified()) 4193 ++numModifiedBuffers; 4194 } 4195 4196 if (numModifiedBuffers > 0) { 4197 FastStringBuffer sb = new FastStringBuffer("Really exit with "); 4198 sb.append(numModifiedBuffers); 4199 sb.append(" modifed buffer"); 4200 if (numModifiedBuffers > 1) 4201 sb.append('s'); 4202 sb.append('?'); 4203 if (!confirm("Really exit?", sb.toString())) 4204 return; 4205 } 4206 4207 setWaitCursor(); 4208 4209 saveState(); 4210 RecentFiles.getInstance().save(); 4211 4212 for (BufferIterator iter = new BufferIterator(); iter.hasNext();) 4214 iter.nextBuffer().deleteAutosaveFile(); 4215 4216 Autosave.deleteCatalogFile(); 4217 4218 for (BufferIterator it = new BufferIterator(); it.hasNext();) 4220 it.nextBuffer().dispose(); 4221 4222 Directories.cleanTempDirectory(); 4224 4225 Cache.cleanup(); 4227 4228 Server.stopServer(); 4229 pendingOperations.run(); 4230 setDefaultCursor(); 4231 System.exit(0); 4232 } 4233 4234 public void killFrame() 4235 { 4236 if (getFrameCount() == 1) { 4237 maybeExit(); 4239 } else { 4240 if (indexOf(frame) != getFrameCount() - 1) { 4242 frames.remove(frame); 4243 frames.add(frame); 4244 } 4245 sessionProperties.saveWindowPlacement(); 4246 frames.remove(frame); 4247 frame.dispose(); 4248 4249 Editor ed = frame.getSecondaryEditor(); 4250 if (ed != null) 4251 removeEditor(ed); 4252 removeEditor(this); 4253 setCurrentEditor(getEditor(0)); 4254 } 4255 } 4256 4257 public static Buffer getBuffer(File file) 4260 { 4261 if (file == null) 4262 return null; 4263 Buffer buf = bufferList.findBuffer(file); 4264 if (buf != null) 4265 return buf; 4266 if (file.isRemote()) 4267 return Buffer.createBuffer(file); 4268 if (file.isDirectory()) 4269 return new Directory(file); 4270 if (file.isFile()) { 4271 if (!file.canRead()) { 4272 MessageDialog.showMessageDialog("File is not readable", 4273 "Error"); 4274 return null; 4275 } 4276 return Buffer.createBuffer(file); 4277 } 4278 if (file.exists()) { 4279 4282 currentEditor.status("I/O error"); 4285 } 4286 return null; 4287 } 4288 4289 public void nextBuffer() 4290 { 4291 Buffer buf = bufferList.getNextPrimaryBuffer(buffer); 4292 if (buf == null) 4293 return; 4294 if (buf.isPaired()) { 4295 Buffer secondary = buf.getSecondary(); 4296 if (secondary != null) { 4297 if (secondary.getLastActivated() > buf.getLastActivated()) 4298 buf = secondary; 4299 } 4300 } 4301 if (buf != buffer) 4302 switchToBuffer(buf); 4303 } 4304 4305 public void prevBuffer() 4306 { 4307 Buffer buf = bufferList.getPreviousPrimaryBuffer(buffer); 4308 if (buf == null) 4309 return; 4310 if (buf.isPaired()) { 4311 Buffer secondary = buf.getSecondary(); 4312 if (secondary != null) { 4313 if (secondary.getLastActivated() > buf.getLastActivated()) 4314 buf = secondary; 4315 } 4316 } 4317 if (buf != buffer) 4318 switchToBuffer(buf); 4319 } 4320 4321 public void switchToBuffer(Buffer buf) 4322 { 4323 if (buf != null) { 4324 if (!buf.isPaired() && (buffer == null || !buffer.isPaired())) { 4325 activate(buf); 4328 } else { 4329 frame.switchToBuffer(buf); 4333 } 4334 Sidebar sidebar = getSidebar(); 4335 if (sidebar != null) 4336 sidebar.setBuffer(); 4337 } else 4338 Debug.bug(); 4339 } 4340 4341 public void makeNext(final Buffer buf) 4342 { 4343 bufferList.makeNext(buf, buffer); 4344 } 4345 4346 public void newBuffer() 4347 { 4348 Buffer buf = new Buffer(0); 4349 makeNext(buf); 4350 switchToBuffer(buf); 4351 } 4352 4353 public final void openFile() 4354 { 4355 AWTEvent e = dispatcher.getLastEvent(); 4356 if (e != null && e.getSource() instanceof MenuItem) { 4357 Runnable r = new Runnable () { 4358 public void run() 4359 { 4360 setFocusToTextField(); 4361 } 4362 }; 4363 SwingUtilities.invokeLater(r); 4364 } else 4365 setFocusToTextField(); 4366 } 4367 4368 public void openFileInOtherWindow() 4369 { 4370 Debug.assertTrue(locationBar != null); 4371 saveView(); 4372 boolean alreadySplit = (getOtherEditor() != null); 4373 if (!alreadySplit) 4374 splitWindow(); 4375 final Editor ed = getOtherEditor(); 4376 if (ed.getLocationBar() != null) { 4377 Runnable r = new Runnable () { 4378 public void run() 4379 { 4380 frame.setFocus(ed.getLocationBar().getTextField()); 4381 } 4382 }; 4383 SwingUtilities.invokeLater(r); 4384 } 4385 setCurrentEditor(ed); 4386 if (alreadySplit) { 4387 repaint(); 4389 ed.repaint(); 4390 } 4391 } 4392 4393 public Buffer openFile(File file) 4394 { 4395 Buffer buf = getBuffer(file); 4396 if (buf != null) { 4397 Debug.assertTrue(bufferList.contains(buf)); 4398 return buf; 4399 } 4400 if (file.isRemote()) 4401 return null; 4402 if (!file.exists()) { 4404 if (confirm("Create file?", 4405 file.canonicalPath() + " does not exist. Create?")) 4406 return Buffer.createBuffer(file); 4407 } 4408 return null; 4409 } 4410 4411 public Buffer openFiles(List list) 4412 { 4413 if (list == null) 4414 return null; 4415 final int listSize = list.size(); 4416 if (listSize < 2) 4417 return null; 4418 Buffer toBeActivated = null; 4419 String dirname = (String ) list.get(0); 4421 File directory = File.getInstance(dirname); 4422 History openFileHistory = new History("openFile.file"); 4423 int lineNumber = -1; 4424 for (int i = 1; i < listSize; i++) { 4425 String s = (String ) list.get(i); 4426 if (s == null || s.length() == 0) 4427 continue; 4428 if (s.charAt(0) == '+') { 4429 try { 4430 lineNumber = Integer.parseInt(s.substring(1)) - 1; 4431 } 4432 catch (NumberFormatException e) {} 4433 continue; 4434 } 4435 String value = getAlias(s); 4437 if (value != null) 4438 s = value; 4439 if (s.startsWith("pop://") || s.startsWith("{")) { 4440 MailboxURL url = MailboxURL.parse(s); 4441 if (url != null) { 4442 Buffer buf = MailCommands.getMailboxBuffer(this, url); 4443 if (buf != null) { 4444 makeNext(buf); 4445 toBeActivated = buf; 4446 } 4447 } 4448 continue; 4449 } 4450 File file = File.getInstance(directory, s); 4451 if (file == null) { 4452 MessageDialog.showMessageDialog(this, "Invalid path ".concat(s), 4453 "Invalid Path"); 4454 continue; 4455 } 4456 if (Utilities.isFilenameAbsolute(s) || s.startsWith("./") || s.startsWith(".\\")) 4457 ; else if (!file.exists()) { 4459 File f = Utilities.findFile(this, s); 4461 if (f != null) 4462 file = f; 4463 else { 4464 if (s.startsWith("www.")) 4466 file = File.getInstance("http://".concat(s)); 4467 else if (s.startsWith("ftp.")) 4468 file = File.getInstance("ftp://".concat(s)); 4469 } 4470 } 4471 if (file.isLocal() && !file.exists()) { 4472 if (!Utilities.checkParentDirectory(file, "Open File")) 4473 continue; 4474 } 4475 Buffer buf = openFile(file); 4476 if (buf != null) { 4477 Debug.assertTrue(bufferList.contains(buf)); 4478 openFileHistory.append(file.netPath()); 4479 if (lineNumber >= 0) { 4480 if (buf.isLoaded()) { 4482 if (buf == buffer) { 4483 Line line = buffer.getLine(lineNumber); 4485 if (line == null) 4486 eob(); 4487 else { 4488 addUndo(SimpleEdit.MOVE); 4489 updateDotLine(); 4490 dot.moveTo(line, 0); 4491 updateDotLine(); 4492 moveCaretToDotCol(); 4493 } 4494 } else { 4495 Buffer oldBuffer = buffer; 4497 if (buffer != null) 4498 saveView(); 4499 buffer = buf; 4500 findOrCreateView(buffer); 4501 restoreView(); 4502 addUndo(SimpleEdit.MOVE); 4503 Line line = buffer.getLine(lineNumber); 4504 if (line == null) { 4505 line = buffer.getFirstLine(); 4506 while (line.next() != null) 4507 line = line.next(); 4508 dot.moveTo(line, line.length()); 4509 } else 4510 dot.moveTo(line, 0); 4511 saveView(); 4512 View view = (View) views.get(buffer); 4513 if (view != null) { 4514 view.shift = 0; 4515 view.caretCol = getDotCol(); 4516 } 4517 buffer = oldBuffer; 4518 if (buffer != null) 4519 restoreView(); 4520 } 4521 } else { 4522 View view = findOrCreateView(buf); 4524 view.lineNumber = lineNumber; 4525 view.offs = 0; 4526 } 4527 } 4528 Debug.assertTrue(bufferList.contains(buf)); 4529 makeNext(buf); 4530 Debug.assertTrue(bufferList.contains(buf)); 4531 toBeActivated = buf; 4532 } 4533 } 4534 openFileHistory.save(); 4535 return toBeActivated; 4536 } 4537 4538 public void unmark() 4539 { 4540 if (mark != null) { 4541 setMark(null); 4542 display.setUpdateFlag(REPAINT); } 4544 } 4545 4546 public void cancelBackgroundProcess() 4547 { 4548 BackgroundProcess backgroundProcess = buffer.getBackgroundProcess(); 4549 if (backgroundProcess != null) 4550 backgroundProcess.cancel(); 4551 } 4552 4553 public void escape() 4555 { 4556 BackgroundProcess backgroundProcess = buffer.getBackgroundProcess(); 4558 if (backgroundProcess != null) { 4559 backgroundProcess.cancel(); 4560 return; 4561 } 4562 4563 if (popup != null) { 4564 if (popup.isVisible()) { 4565 killPopup(); 4566 return; 4567 } 4568 popup = null; 4569 } 4571 4572 if (lastCommand == COMMAND_EXPAND) { 4573 Expansion expansion = Expansion.getLastExpansion(); 4574 if (expansion != null) { 4575 expansion.undo(this); 4576 return; 4577 } 4578 } 4579 4580 if (buffer instanceof RemoteBuffer && buffer.isEmpty()) { 4581 killBuffer(); 4582 return; 4583 } 4584 4585 if (escapeInternal()) 4586 return; 4587 4588 if (selection != null && selection.getSavedDot() != null) 4589 moveDotTo(selection.getSavedDot()); 4590 else if (mark != null) 4591 moveDotTo(mark); 4592 } 4593 4594 public boolean escapeInternal() 4595 { 4596 if (buffer instanceof CompilationBuffer) { 4597 if (buffer.unsplitOnClose()) { 4598 buffer.windowClosing(); 4599 otherWindow(); 4600 unsplitWindow(); 4601 } 4602 maybeKillBuffer(buffer); 4603 restoreFocus(); 4604 Sidebar.refreshSidebarInAllFrames(); 4605 return true; 4606 } 4607 if (buffer.isTransient()) { 4608 if (buffer.unsplitOnClose()) { 4609 buffer.windowClosing(); 4610 otherWindow(); 4611 unsplitWindow(); 4612 } 4613 maybeKillBuffer(buffer); 4614 restoreFocus(); 4615 Sidebar.refreshSidebarInAllFrames(); 4616 return true; 4617 } 4618 if (buffer.getModeId() == CHECKIN_MODE) { 4619 otherWindow(); 4620 unsplitWindow(); 4621 if (!buffer.isModified()) 4622 maybeKillBuffer(buffer); 4623 restoreFocus(); 4624 return true; 4625 } 4626 Editor ed = getOtherEditor(); 4628 if (ed != null) { 4629 Buffer buf = ed.getBuffer(); 4630 if (buf instanceof CompilationBuffer || buf.isTransient()) { 4631 if (buf.unsplitOnClose()) 4632 unsplitWindow(); 4633 maybeKillBuffer(buf); 4634 if (!buf.unsplitOnClose()) 4635 ed.updateDisplay(); 4636 Sidebar.refreshSidebarInAllFrames(); 4637 return true; 4638 } 4639 if (buf.getModeId() == CHECKIN_MODE) { 4640 unsplitWindow(); 4641 if (!buf.isModified()) 4642 maybeKillBuffer(buf); 4643 return true; 4644 } 4645 } 4646 return false; 4647 } 4648 4649 public void stamp() 4650 { 4651 if (!checkReadOnly()) 4652 return; 4653 Date now = new Date (System.currentTimeMillis()); 4654 String dateString = null; 4655 String stampFormat = buffer.getStringProperty(Property.STAMP_FORMAT); 4656 if (stampFormat != null) { 4657 try { 4658 SimpleDateFormat df = new SimpleDateFormat (stampFormat); 4659 dateString = df.format(now); 4660 } 4661 catch (Throwable t) { 4662 } 4664 } 4665 if (dateString == null) { 4666 SimpleDateFormat df = new SimpleDateFormat ("MMM d yyyy h:mm a"); 4667 dateString = df.format(now); 4668 } 4669 try { 4670 buffer.lockWrite(); 4671 } 4672 catch (InterruptedException e) { 4673 Log.error(e); 4674 return; 4675 } 4676 try { 4677 CompoundEdit compoundEdit = beginCompoundEdit(); 4678 if (mark != null) 4679 delete(); 4680 fillToCaret(); 4681 addUndo(SimpleEdit.INSERT_STRING); 4682 insertStringInternal(dateString); 4683 buffer.modified(); 4684 endCompoundEdit(compoundEdit); 4685 moveCaretToDotCol(); 4686 updateInAllEditors(getDotLine()); 4687 } 4688 finally { 4689 buffer.unlockWrite(); 4690 } 4691 } 4692 4693 public Search getSearchAtDot() 4694 { 4695 if (dot == null) 4696 return null; 4697 String pattern = null; 4698 boolean wholeWordsOnly = false; 4699 if (mark != null) { 4700 if (getMarkLine() == getDotLine()) 4702 pattern = (new Region(buffer, dot, mark)).toString(); 4703 } else { 4704 pattern = tokenAt(dot); 4705 wholeWordsOnly = true; 4706 } 4707 if (pattern != null && pattern.length() != 0) 4708 return new Search(pattern, false, wholeWordsOnly); 4709 else 4710 return null; 4711 } 4712 4713 public void markFoundPattern(Search search) 4715 { 4716 if (search.isRegularExpression() && search.isMultilinePattern()) { 4717 REMatch match = search.getMatch(); 4718 if (match != null) { 4719 setDot(buffer.getPosition(match.getStartIndex())); 4720 setMark(buffer.getPosition(match.getEndIndex())); 4721 final Line markLine = getMarkLine(); 4722 for (Line line = getDotLine(); line != null; line = line.next()) { 4723 update(line); 4724 if (line == markLine) 4725 break; 4726 } 4727 moveCaretToDotCol(); 4728 } 4729 } else { 4730 final int context = 2; Position saved = dot.copy(); 4732 4733 int length; 4735 if (search.getMatch() != null) 4736 length = search.getMatch().toString().length(); 4737 else 4738 length = search.getPatternLength(); 4739 4740 dot.setOffset(Math.min(dot.getOffset() + length, getDotLine().length())); 4742 4743 moveCaretToDotCol(); 4745 setMarkAtDot(); 4746 4747 int absCol = getDotCol() + context; 4750 display.ensureColumnVisible(getDotLine(), absCol); 4751 4752 dot = saved; 4754 4755 absCol = getDotCol() - context; 4758 if (absCol < 0) 4759 absCol = 0; 4760 display.ensureColumnVisible(getDotLine(), absCol); 4761 moveCaretToDotCol(); 4762 } 4763 } 4764 4765 public void findNext() 4766 { 4767 if (lastSearch != null) { 4768 Position start; 4769 if (mark != null) { 4770 Region r = new Region(this); 4771 start = new Position(r.getBegin()); 4772 } else 4773 start = new Position(dot); 4774 if (!start.next()) 4775 return; 4776 setWaitCursor(); 4777 Position pos = lastSearch.find(buffer, start); 4778 setDefaultCursor(); 4779 if (pos != null) { 4780 moveDotTo(pos); 4781 markFoundPattern(lastSearch); 4782 if (lastSearch instanceof FindInFiles) { 4783 if (buffer.getFile() != null) { 4784 ListOccurrencesInFiles buf = 4785 ((FindInFiles)lastSearch).getOutputBuffer(); 4786 if (buf != null) 4787 buf.follow(buffer.getFile(), getDotLine()); 4788 } 4789 } 4790 return; 4791 } 4792 if (lastSearch instanceof FindInFiles) { 4793 Editor ed = getOtherEditor(); 4794 if (ed != null) { 4795 ListOccurrencesInFiles buf = 4796 ((FindInFiles)lastSearch).getOutputBuffer(); 4797 if (ed.getBuffer() == buf) { 4798 buf.findNextOccurrence(ed); 4799 return; 4800 } 4801 } 4802 } 4803 lastSearch.notFound(this); 4804 } 4805 } 4806 4807 public void findPrev() 4808 { 4809 if (lastSearch != null) { 4810 Position start; 4811 if (mark != null) { 4812 Region r = new Region(this); 4813 start = new Position(r.getBegin()); 4814 } else 4815 start = new Position(dot); 4816 if (!start.prev()) 4817 return; 4818 setWaitCursor(); 4819 Position pos = lastSearch.reverseFind(buffer, start); 4820 setDefaultCursor(); 4821 if (pos != null) { 4822 moveDotTo(pos); 4823 markFoundPattern(lastSearch); 4824 if (lastSearch instanceof FindInFiles) { 4825 if (buffer.getFile() != null) { 4826 ListOccurrencesInFiles buf = 4827 ((FindInFiles)lastSearch).getOutputBuffer(); 4828 if (buf != null) 4829 buf.follow(buffer.getFile(), getDotLine()); 4830 } 4831 } 4832 return; 4833 } 4834 if (lastSearch instanceof FindInFiles) { 4835 Editor ed = getOtherEditor(); 4836 if (ed != null) { 4837 ListOccurrencesInFiles buf = 4838 ((FindInFiles)lastSearch).getOutputBuffer(); 4839 if (ed.getBuffer() == buf) { 4840 buf.findPreviousOccurrence(ed); 4841 return; 4842 } 4843 } 4844 } 4845 lastSearch.notFound(this); 4846 } 4847 } 4848 4849 public void incrementalFind() 4850 { 4851 if (dot == null) 4852 return; 4853 4854 locationBar.setLabelText(LocationBar.PROMPT_PATTERN); 4856 HistoryTextField textField = locationBar.getTextField(); 4857 textField.setHandler(new IncrementalFindTextFieldHandler(this, textField)); 4858 textField.setHistory(new History("incrementalFind.pattern")); 4859 textField.setText(""); 4860 setFocusToTextField(); 4861 } 4862 4863 public String getCurrentText() 4864 { 4865 String s = getSelectionOnCurrentLine(); 4866 if (s == null) 4867 s = getTokenAtDot(); 4868 return (s != null && s.length() > 0) ? s : null; 4869 } 4870 4871 public String getSelectionOnCurrentLine() 4872 { 4873 if (dot != null && mark != null && getMarkLine() == getDotLine()) 4874 return new Region(this).toString(); 4875 else 4876 return null; 4877 } 4878 4879 public String getFilenameAtDot() 4880 { 4881 if (dot == null) 4882 return null; 4883 Position pos; 4884 if (mark != null) { 4885 Region r = new Region(this); 4886 4887 if (r.getBeginLine() == r.getEndLine()) 4890 return r.toString(); 4891 4892 pos = r.getBegin(); 4894 } else 4895 pos = new Position(dot); 4896 final Line line = pos.getLine(); 4897 final int limit = line.length(); 4898 int offset = pos.getOffset(); 4899 if (offset == limit) 4900 --offset; 4901 FastStringBuffer sb = new FastStringBuffer(); 4902 if (offset >= 0 && offset < limit) { 4903 char c = line.charAt(offset); 4904 if (Utilities.isFilenameChar(c)) { 4905 while (offset > 0) { 4906 c = line.charAt(--offset); 4907 if (!Utilities.isFilenameChar(c)){ 4908 ++offset; 4909 break; 4910 } 4911 } 4912 4913 sb.append(line.charAt(offset)); 4915 while (++offset < limit) { 4916 c = line.charAt(offset); 4917 if (Utilities.isFilenameChar(c)) { 4918 sb.append(c); 4919 } else if (sb.toString().startsWith("http://")) { 4920 if (!Character.isWhitespace(c)) 4923 sb.append(c); 4924 else 4925 break; 4926 } else 4927 break; 4928 } 4929 4930 int length = sb.length(); 4935 while (length > 0) { 4936 c = sb.charAt(length-1); 4937 if (".,:;)]>".indexOf(c) >= 0) 4938 --length; 4939 else 4940 break; 4941 } 4942 sb.setLength(length); 4943 4944 RE re = new UncheckedRE(" line [0-9]+"); 4945 REMatch match = re.getMatch(line.getText().substring(offset)); 4946 if (match != null && match.getStartIndex() == 0) 4947 sb.append(match.toString()); 4948 } 4949 } 4950 return sb.toString(); 4951 } 4952 4953 private String getTokenAtDot() 4954 { 4955 if (mark != null) { 4958 Region r = new Region(this); 4959 return tokenAt(r.getBegin()); 4960 } 4961 return tokenAt(dot); 4962 } 4963 4964 private String tokenAt(Position pos) 4965 { 4966 return getMode().getIdentifier(pos); 4967 } 4968 4969 public void findNextWord() 4970 { 4971 if (dot == null) 4972 return; 4973 String pattern = getTokenAtDot(); 4974 if (pattern == null || pattern.length() == 0) 4975 return; 4976 lastSearch = new Search(pattern, false, true); 4977 Position start; 4978 if (mark != null && dot.isBefore(mark)) 4979 start = new Position(mark); 4980 else 4981 start = new Position(dot); 4982 Position pos = lastSearch.find(buffer.getMode(), start); 4983 if (pos != null && pos.equals(start)) { 4984 if (pos.next()) 4985 pos = lastSearch.find(buffer.getMode(), pos); 4986 } 4987 if (pos != null && !pos.equals(start)) { 4988 moveDotTo(pos); 4989 markFoundPattern(lastSearch); 4990 } else 4991 lastSearch.notFound(this); 4992 } 4993 4994 public void findPrevWord() 4995 { 4996 if (dot == null) 4997 return; 4998 String pattern = getTokenAtDot(); 4999 if (pattern == null || pattern.length() == 0) 5000 return; 5001 lastSearch = new Search(pattern, false, true); 5002 boolean found = false; 5003 Position start = null; 5004 if (mark != null) 5005 start = new Region(this).getBegin(); 5006 else 5007 start = new Position(dot); 5008 if (start.prev()) { 5009 Position pos = lastSearch.reverseFind(buffer, start); 5010 if (pos != null && pos.getLine() == start.getLine()) { 5011 if (pos.getOffset() + lastSearch.getPatternLength() > start.getOffset()) { 5012 start = new Position(pos); 5014 if (start.prev()) 5015 pos = lastSearch.reverseFind(buffer, start); 5016 else 5017 pos = null; 5018 } 5019 } 5020 if (pos != null) { 5021 found = true; 5022 moveDotTo(pos); 5023 markFoundPattern(lastSearch); 5024 } 5025 } 5026 if (!found) 5027 lastSearch.notFound(this); 5028 } 5029 5030 public void findFirstOccurrence() 5031 { 5032 if (dot == null) 5033 return; 5034 String pattern = getTokenAtDot(); 5035 if (pattern == null || pattern.length() == 0) 5036 return; 5037 lastSearch = new Search(pattern, false, true); 5038 Position pos = lastSearch.find(buffer.getMode(), 5039 new Position(buffer.getFirstLine(), 0)); 5040 if (pos != null) { 5041 moveDotTo(pos); 5042 markFoundPattern(lastSearch); 5043 } else 5044 lastSearch.notFound(this); 5045 } 5046 5047 public void copyPath() 5048 { 5049 if (buffer instanceof Directory) { 5050 String path = ((Directory) buffer).getPathAtDot(); 5051 if (path != null) { 5052 killRing.appendNew(path); 5053 killRing.copyLastKillToSystemClipboard(); 5054 status("Path copied to clipboard"); 5055 } 5056 } 5057 } 5058 5059 public void copyRegion() 5060 { 5061 if (dot == null) 5062 return; 5063 5064 String message = null; 5065 5066 if (mark != null) { 5067 Region r = new Region(this); 5068 if (isColumnSelection()) { 5069 killedColumn = r.toString(); 5070 message = "Column selection stored"; 5071 } else { 5072 killRing.appendNew(r.toString()); 5073 message = "Region copied to clipboard"; 5074 } 5075 } else if (!getDotLine().isBlank()) { 5076 killRing.appendNew(getDotLine().getText() + System.getProperty("line.separator")); 5077 message = "Line copied to clipboard"; 5078 } else 5079 return; 5081 if (!isColumnSelection()) 5082 killRing.copyLastKillToSystemClipboard(); 5083 5084 if (message != null) 5085 status(message); 5086 } 5087 5088 public void copyAppend() 5089 { 5090 if (isColumnSelection()) { 5091 notSupportedForColumnSelections(); 5092 return; 5093 } 5094 5095 if (dot == null) 5096 return; 5097 5098 String message = null; 5099 5100 if (mark != null) { 5101 Region r = new Region(buffer, mark, dot); 5102 killRing.appendToCurrent(r.toString()); 5103 message = "Region appended to clipboard"; 5104 } else if (!getDotLine().isBlank()) { 5105 killRing.appendToCurrent(getDotLine().getText() + System.getProperty("line.separator")); 5106 message = "Line appended to clipboard"; 5107 } else 5108 return; 5110 killRing.copyLastKillToSystemClipboard(); 5111 5112 if (message != null) 5113 status(message); 5114 } 5115 5116 public void deleteRegion() 5118 { 5119 if (mark == null) 5120 return; 5121 if (getMarkLine() != getDotLine() || getMarkOffset() != getDotOffset()) { 5122 try { 5123 buffer.lockWrite(); 5124 } 5125 catch (InterruptedException e) { 5126 Log.error(e); 5127 return; 5128 } 5129 try { 5130 Region r = new Region(this); 5131 if (isColumnSelection()) { 5132 deleteColumn(r); 5133 } else { 5134 boolean hard = getDotLine() != getMarkLine(); 5137 5138 CompoundEdit compoundEdit = beginCompoundEdit(); 5141 addUndo(SimpleEdit.MOVE); 5142 dot.moveTo(r.getBegin()); 5143 addUndoDeleteRegion(r); 5144 5145 r.delete(); 5147 5148 endCompoundEdit(compoundEdit); 5149 5150 if (hard) 5151 buffer.repaint(); 5152 else 5153 updateInAllEditors(getDotLine()); 5154 } 5155 } 5156 finally { 5157 buffer.unlockWrite(); 5158 } 5159 moveCaretToDotCol(); 5160 } 5161 setMark(null); 5162 } 5163 5164 private void deleteColumn(Region r) 5166 { 5167 Debug.assertTrue(r.isColumnRegion()); 5168 final int beginCol = r.getBeginCol(); 5169 final int endCol = r.getEndCol(); 5170 CompoundEdit compoundEdit = beginCompoundEdit(); 5171 addUndo(SimpleEdit.MOVE); 5172 dot.moveTo(r.getBegin()); 5173 while (true) { 5174 addUndo(SimpleEdit.LINE_EDIT); 5175 Line line = getDotLine(); 5176 deleteLineRegion(line, beginCol, endCol); 5177 updateInAllEditors(line); 5178 if (line == r.getEndLine()) 5179 break; 5180 if (line.next() == null) 5181 break; 5182 dot.moveTo(line.next(), 0); 5183 } 5184 addUndo(SimpleEdit.MOVE); 5185 dot.moveTo(r.getBegin()); 5186 endCompoundEdit(compoundEdit); 5187 buffer.modified(); 5188 } 5189 5190 private void deleteLineRegion(Line line, int beginCol, int endCol) 5191 { 5192 String text = Utilities.detab(line.getText(), buffer.getTabWidth()); 5193 if (text.length() < beginCol) 5194 return; String head = text.substring(0, beginCol); 5196 if (text.length() < endCol) { 5197 line.setText(head); 5198 return; 5199 } 5200 String tail = text.substring(endCol); 5201 line.setText(head.concat(tail)); 5202 } 5203 5204 public void killRegion() 5206 { 5207 if (!checkReadOnly()) 5208 return; 5209 try { 5210 buffer.lockWrite(); 5211 } 5212 catch (InterruptedException e) { 5213 Log.error(e); 5214 return; 5215 } 5216 try { 5217 killRegionInternal(); 5218 } 5219 finally { 5220 buffer.unlockWrite(); 5221 } 5222 } 5223 5224 private void killRegionInternal() 5225 { 5226 if (mark != null) { 5227 if (getMarkLine() != getDotLine() || getMarkOffset() != getDotOffset()) { 5228 boolean hard = getDotLine() != getMarkLine(); 5231 if (isColumnSelection()) { 5232 Region r = new Region(this); 5233 killedColumn = r.toString(); 5234 deleteColumn(r); 5235 } else { 5236 Region r = new Region(this); 5237 String kill = r.toString(); 5238 if (lastCommand == COMMAND_KILL) 5239 killRing.appendToCurrent(kill); 5240 else 5241 killRing.appendNew(kill); 5242 killRing.copyLastKillToSystemClipboard(); 5243 5244 CompoundEdit compoundEdit = beginCompoundEdit(); 5247 addUndo(SimpleEdit.MOVE); 5248 dot.moveTo(r.getBegin()); 5249 addUndoDeleteRegion(r); 5250 5251 r.delete(); 5253 5254 endCompoundEdit(compoundEdit); 5255 } 5256 moveCaretToDotCol(); 5257 if (hard) 5258 buffer.repaint(); 5259 else 5260 updateInAllEditors(getDotLine()); 5261 setCurrentCommand(COMMAND_KILL); 5262 } 5263 setMark(null); 5264 } else { 5265 final Line dotLine = getDotLine(); 5267 final Line nextLine = dotLine.next(); 5268 5269 if (nextLine == null) { 5271 CompoundEdit compoundEdit = beginCompoundEdit(); 5272 dot.setOffset(0); 5273 killLine(); 5274 endCompoundEdit(compoundEdit); 5275 setCurrentCommand(COMMAND_KILL); 5276 return; 5277 } 5278 5279 CompoundEdit compoundEdit = beginCompoundEdit(); 5280 addUndo(SimpleEdit.MOVE); 5281 dot.moveTo(dotLine, 0); 5282 mark = new Position(nextLine, 0); 5283 5284 Region r = new Region(this); 5285 String kill = r.toString(); 5286 if (lastCommand == COMMAND_KILL) 5287 killRing.appendToCurrent(kill); 5288 else 5289 killRing.appendNew(kill); 5290 killRing.copyLastKillToSystemClipboard(); 5291 5292 addUndo(SimpleEdit.MOVE); 5295 dot.moveTo(r.getBegin()); 5296 addUndoDeleteRegion(r); 5297 5298 r.delete(); 5300 5301 addUndo(SimpleEdit.MOVE); 5302 mark = null; 5303 endCompoundEdit(compoundEdit); 5304 moveCaretToDotCol(); 5305 buffer.repaint(); 5306 setCurrentCommand(COMMAND_KILL); 5307 } 5308 } 5309 5310 public void killAppend() 5311 { 5312 if (isColumnSelection()) { 5313 notSupportedForColumnSelections(); 5314 return; 5315 } 5316 setLastCommand(COMMAND_KILL); killRegion(); 5318 } 5319 5320 public void killLine() 5324 { 5325 if (!checkReadOnly()) 5326 return; 5327 5328 if (dot.getOffset() == dot.getLineLength() && dot.getNextLine() == null) 5329 return; 5330 5331 CompoundEdit compoundEdit = beginCompoundEdit(); 5332 5333 addUndo(SimpleEdit.MOVE); 5334 unmark(); 5335 5336 if (getDotOffset() < getDotLine().length()){ 5337 setMarkAtDot(); 5338 if (dot.getLine().isBlank() && dot.getNextLine() != null) 5339 dot.moveTo(dot.getNextLine(), 0); 5340 else 5341 dot.setOffset(dot.getLineLength()); 5342 } else if (dot.getOffset() == dot.getLineLength()) { 5343 fillToCaret(); setMarkAtDot(); 5345 dot.moveTo(dot.getNextLine(), 0); 5346 } 5347 5348 killRegion(); 5349 5350 endCompoundEdit(compoundEdit); 5351 } 5352 5353 public void deleteWordRight() 5354 { 5355 deleteOrKillWordRight(false); 5356 } 5357 5358 public void killWordRight() 5359 { 5360 deleteOrKillWordRight(true); 5361 } 5362 5363 private void deleteOrKillWordRight(boolean isKill) 5364 { 5365 if (!checkReadOnly()) 5366 return; 5367 CompoundEdit compoundEdit = beginCompoundEdit(); 5368 addUndo(SimpleEdit.MOVE); 5369 unmark(); 5370 fillToCaret(); 5371 setMarkAtDot(); 5372 if (inWord()) { 5373 while (inWord() && nextChar()) 5374 ; 5375 while (inWhitespace() && nextChar()) 5376 ; 5377 } else if (inWhitespace()) { 5378 while (inWhitespace() && nextChar()) 5379 ; 5380 } else { 5381 while (!inWhitespace() && !inWord() && nextChar()) 5382 ; 5383 while (inWhitespace() && nextChar()) 5384 ; 5385 } 5386 if (isKill) 5387 killRegion(); 5388 else 5389 deleteRegion(); 5390 endCompoundEdit(compoundEdit); 5391 } 5392 5393 public void deleteWordLeft() 5394 { 5395 deleteOrKillWordLeft(false); 5396 } 5397 5398 public void killWordLeft() 5399 { 5400 deleteOrKillWordLeft(true); 5401 } 5402 5403 private void deleteOrKillWordLeft(boolean isKill) 5404 { 5405 if (!checkReadOnly()) 5406 return; 5407 if (getDotOffset() == 0 && getDotLine().previous() == null) 5408 return; 5409 CompoundEdit compoundEdit = beginCompoundEdit(); 5410 addUndo(SimpleEdit.MOVE); 5411 unmark(); 5412 setMarkAtDot(); 5413 prevChar(); 5414 if (inWord()) { 5415 while (getDotOffset() > 0 && inWord() && prevChar()) 5416 ; 5417 if (!inWord()) 5418 nextChar(); 5419 } else if (inWhitespace()) { 5420 while (inWhitespace() && prevChar()) 5421 ; 5422 if (!inWhitespace()) 5423 nextChar(); 5424 } else { 5425 while (!inWhitespace() && !inWord() && prevChar()) 5426 ; 5427 while (inWhitespace() && prevChar()) 5428 ; 5429 nextChar(); 5430 } 5431 if (isKill) 5432 killRegion(); 5433 else 5434 deleteRegion(); 5435 endCompoundEdit(compoundEdit); 5436 } 5437 5438 public boolean canPaste() 5439 { 5440 if (buffer.isReadOnly()) 5441 return false; 5442 if (killRing.size() > 0) 5443 return true; 5444 String toBeInserted = null; 5445 Transferable t = getToolkit().getSystemClipboard().getContents(this); 5446 if (t != null) { 5447 try { 5448 toBeInserted = (String ) t.getTransferData(DataFlavor.stringFlavor); 5449 } 5450 catch (Exception e) {} 5451 } 5452 return toBeInserted != null; 5453 } 5454 5455 public void paste() 5456 { 5457 if (!checkReadOnly()) 5458 return; 5459 setWaitCursor(); 5460 String toBeInserted = null; 5461 Transferable t = getToolkit().getSystemClipboard().getContents(this); 5462 if (t != null) { 5463 try { 5464 toBeInserted = (String ) t.getTransferData(DataFlavor.stringFlavor); 5465 } 5466 catch (Exception e) {} 5467 } 5468 if (toBeInserted != null && toBeInserted.length() > 0) 5469 killRing.appendNew(toBeInserted); 5470 toBeInserted = killRing.pop(); 5474 if (toBeInserted != null) { 5475 paste(toBeInserted); 5476 setCurrentCommand(COMMAND_PASTE); 5477 } 5478 setDefaultCursor(); 5479 } 5480 5481 public void cyclePaste() 5482 { 5483 if (lastCommand == COMMAND_PASTE) { 5484 setWaitCursor(); 5485 String s = killRing.popNext(); 5486 if (s != null) { 5487 undo(); 5488 paste(s); 5489 setCurrentCommand(COMMAND_PASTE); 5490 } 5491 setDefaultCursor(); 5492 } else 5493 paste(); 5494 } 5495 5496 public void mousePaste() 5497 { 5498 if (dot == null) 5499 return; 5500 if (!checkReadOnly()) 5501 return; 5502 if (isColumnSelection()) { 5503 notSupportedForColumnSelections(); 5504 return; 5505 } 5506 AWTEvent e = dispatcher.getLastEvent(); 5507 if (!(e instanceof MouseEvent )) 5508 return; 5509 CompoundEdit compoundEdit = beginCompoundEdit(); 5510 if (mark != null) { 5511 Region r = new Region(this); 5512 killRing.appendNew(r.toString()); 5513 killRing.copyLastKillToSystemClipboard(); 5514 addUndo(SimpleEdit.MOVE); 5515 setMark(null); 5516 } 5517 mouseMoveDotToPoint((MouseEvent ) e); 5518 paste(); 5519 endCompoundEdit(compoundEdit); 5520 } 5521 5522 public static void promoteLastPaste() 5523 { 5524 killRing.promoteLastPaste(); 5525 } 5526 5527 public void paste(String toBeInserted) 5528 { 5529 paste(toBeInserted, false); 5530 } 5531 5532 public void paste(String toBeInserted, boolean leavePasteSelected) 5533 { 5534 if (!checkReadOnly()) 5535 return; 5536 if (toBeInserted == null || toBeInserted.length() == 0) 5537 return; 5538 try { 5539 buffer.lockWrite(); 5540 } 5541 catch (InterruptedException e) { 5542 Log.error(e); 5543 return; 5544 } 5545 try { 5546 pasteInternal(toBeInserted, leavePasteSelected); 5547 } 5548 finally { 5549 buffer.unlockWrite(); 5550 } 5551 setUpdateFlag(REFRAME); 5552 } 5553 5554 private void pasteInternal(String toBeInserted, boolean leavePasteSelected) 5555 { 5556 final Mode mode = buffer.getMode(); 5557 CompoundEdit compoundEdit = beginCompoundEdit(); 5558 if (mark == null && Utilities.isLinePaste(toBeInserted) && 5559 mode.acceptsLinePaste(this) && buffer.getBooleanProperty(Property.AUTO_PASTE_LINES)) 5560 { 5561 final int absCaretCol = display.getAbsoluteCaretCol(); 5563 5564 final Line prevLine = getDotLine().previous(); 5565 5566 addUndo(SimpleEdit.MOVE); 5567 dot.setOffset(0); 5568 Position begin = dot.copy(); 5569 addUndo(SimpleEdit.INSERT_STRING); 5570 insertStringInternal(toBeInserted); 5571 5572 if (prevLine != null && mode.canIndentPaste()) { 5573 5575 if (getFormatter().parseBuffer()) 5577 buffer.repaint(); 5578 5579 Position savedDot = dot.copy(); 5582 5583 addUndo(SimpleEdit.MOVE); 5585 dot.moveTo(prevLine.next(), 0); 5586 5587 while (dot.getLine() != null && dot.getLine() != savedDot.getLine()) { 5588 if (!dot.getLine().isBlank()) 5589 indentLineInternal(); 5590 addUndo(SimpleEdit.MOVE); 5591 dot.moveTo(dot.getNextLine(), 0); 5592 } 5593 5594 dot = savedDot; 5596 } 5597 5598 if (leavePasteSelected) { 5599 setMark(begin); 5600 final Line dotLine = getDotLine(); 5601 for (Line line = begin.getLine(); line != null; line = line.nextVisible()) { 5602 update(line); 5603 if (line == dotLine) 5604 break; 5605 } 5606 } else { 5607 addUndo(SimpleEdit.MOVE); 5609 display.setCaretCol(absCaretCol - display.getShift()); 5610 moveDotToCaretCol(); 5611 } 5612 } else { 5613 if (mark != null) 5614 deleteRegion(); 5615 fillToCaret(); 5616 Position begin = dot.copy(); 5617 addUndo(SimpleEdit.INSERT_STRING); 5618 insertStringInternal(toBeInserted); 5619 moveCaretToDotCol(); 5620 if (leavePasteSelected) { 5621 setMark(begin); 5622 final Line dotLine = getDotLine(); 5623 for (Line line = begin.getLine(); line != null; line = line.nextVisible()) { 5624 update(line); 5625 if (line == dotLine) 5626 break; 5627 } 5628 } 5629 } 5630 endCompoundEdit(compoundEdit); 5631 buffer.modified(); 5632 if (getFormatter().parseBuffer()) 5633 buffer.repaint(); 5634 } 5635 5636 public void pasteColumn() 5637 { 5638 if (!checkReadOnly()) 5639 return; 5640 if (killedColumn == null || killedColumn.length() == 0) 5641 return; 5642 try { 5643 buffer.lockWrite(); 5644 } 5645 catch (InterruptedException e) { 5646 Log.error(e); 5647 return; 5648 } 5649 try { 5650 pasteColumnInternal(killedColumn); 5651 } 5652 finally { 5653 buffer.unlockWrite(); 5654 } 5655 } 5656 5657 private void pasteColumnInternal(String toBeInserted) 5658 { 5659 Position pos = new Position(dot); 5660 final int col = display.getAbsoluteCaretCol(); 5661 CompoundEdit compoundEdit = beginCompoundEdit(); 5662 while (true) { 5663 final int index = toBeInserted.indexOf('\n'); 5664 final String s = index >= 0 ? toBeInserted.substring(0, index) : toBeInserted; 5665 if (index >= 0) 5666 toBeInserted = toBeInserted.substring(index + 1); 5667 final Line dotLine = getDotLine(); 5668 String text = Utilities.detab(dotLine.getText(), buffer.getTabWidth()); 5669 if (text.length() < col) 5670 text = text.concat(Utilities.spaces(col - text.length())); 5671 Debug.assertTrue(text.length() >= col); 5672 final String head = text.substring(0, col); 5673 final String tail = text.substring(col); 5674 addUndo(SimpleEdit.LINE_EDIT); 5675 FastStringBuffer sb = new FastStringBuffer(head); 5676 sb.append(s); 5677 sb.append(tail); 5678 dotLine.setText(sb.toString()); 5679 updateInAllEditors(dotLine); 5680 pos = new Position(dotLine, head.length() + s.length()); 5681 if (toBeInserted.length() == 0) 5682 break; 5683 if (dotLine.next() == null) { 5684 addUndo(SimpleEdit.MOVE); 5685 dot.setOffset(dotLine.length()); 5686 addUndo(SimpleEdit.INSERT_LINE_SEP); 5687 buffer.insertLineSeparator(dot); 5688 } else { 5689 addUndo(SimpleEdit.MOVE); 5690 dot.moveTo(dotLine.next(), 0); 5691 } 5692 } 5693 addUndo(SimpleEdit.MOVE); 5694 dot.moveTo(pos); 5695 moveCaretToDotCol(); 5696 endCompoundEdit(compoundEdit); 5697 } 5698 5699 public void insertString(String toBeInserted) 5700 { 5701 if (toBeInserted == null || toBeInserted.length() == 0) 5702 return; 5703 CompoundEdit compoundEdit = beginCompoundEdit(); 5704 if (mark != null) 5705 delete(); 5706 fillToCaret(); 5707 addUndo(SimpleEdit.INSERT_STRING); 5708 insertStringInternal(toBeInserted); 5709 updateInAllEditors(dot.getLine()); 5710 moveCaretToDotCol(); 5711 endCompoundEdit(compoundEdit); 5712 if (getFormatter().parseBuffer()) 5713 buffer.repaint(); 5714 } 5715 5716 public void centerDialog(JDialog d) 5717 { 5718 Dimension parent = frame.getSize(); 5719 Dimension window = d.getSize(); 5720 Point p = frame.getLocation(); 5721 p.translate((parent.width - window.width) / 2, 5722 (parent.height - window.height) / 2); 5723 d.setLocation(p); 5724 } 5725 5726 public boolean confirm(String title, String text) 5727 { 5728 int response = ConfirmDialog.showConfirmDialog(this, text, title); 5729 repaintNow(); 5730 return response == RESPONSE_YES; 5731 } 5732 5733 public int confirmAll(String title, String text) 5734 { 5735 int response = ConfirmDialog.showConfirmAllDialog(this, text, title); 5736 repaintNow(); 5737 return response; 5738 } 5739 5740 public void killBuffer() 5741 { 5742 try { 5743 if (buffer.isSecondary()) { 5744 buffer.windowClosing(); 5745 otherWindow(); 5746 unsplitWindow(); 5747 currentEditor.maybeKillBuffer(buffer); 5748 restoreFocus(); 5749 return; 5750 } 5751 Buffer buf = buffer.getSecondary(); 5752 if (buf != null) { 5753 unsplitWindow(); 5754 maybeKillBuffer(buf); 5755 return; 5756 } 5757 maybeKillBuffer(buffer); 5759 Frame frame = currentEditor.getFrame(); 5762 if (frame.getEditorCount() == 2) { 5763 Editor p = frame.getPrimaryEditor(); 5764 Editor s = frame.getSecondaryEditor(); 5765 boolean unsplit = false; 5766 if (p.getDot() != null && p.getDot().equals(s.getDot())) { 5767 if (p.getMark() == null && s.getMark() == null) 5768 unsplit = true; 5769 else if (p.getMark() != null && p.getMark().equals(s.getMark())) 5770 unsplit = true; 5771 } 5772 if (unsplit) 5773 unsplitWindow(); 5774 } 5775 } 5776 finally { 5777 Sidebar.refreshSidebarInAllFrames(); 5778 } 5779 } 5780 5781 public void maybeKillBuffer(Buffer toBeKilled) 5782 { 5783 if (!bufferList.contains(toBeKilled)) { 5784 Debug.bug("maybeKillBuffer buffer not in list " + toBeKilled); 5785 return; 5786 } 5787 5788 if (bufferList.size() == 1 && toBeKilled instanceof Directory) 5790 return; 5791 5792 BackgroundProcess backgroundProcess = toBeKilled.getBackgroundProcess(); 5794 if (backgroundProcess != null) { 5795 Log.debug("maybeKillBuffer calling backgroundProcess.cancel..."); 5796 backgroundProcess.cancel(); 5797 if (!bufferList.contains(toBeKilled)) { 5800 Log.debug("maybeKillBuffer buffer is no longer in list"); 5801 return; 5802 } 5803 } 5804 5805 Mode mode = toBeKilled.getMode(); 5806 if (mode == null || mode.confirmClose(this, toBeKilled)) 5807 toBeKilled.kill(); 5808 } 5809 5810 public void clearStatusText() 5811 { 5812 StatusBar statusBar = getStatusBar(); 5813 if (statusBar != null) { 5814 statusBar.setText(null); 5815 statusBar.repaint(); 5816 } 5817 } 5818 5819 public void activate(Buffer buf) 5820 { 5821 if (buf == null) 5822 return; 5823 Debug.assertTrue(bufferList.contains(buf)); 5824 if (buf == buffer) 5825 return; 5826 if (!buf.initialized()) 5827 buf.initialize(); 5828 clearStatusText(); 5829 if (buffer != null && bufferList.contains(buffer)) { 5830 buffer.autosave(); 5832 saveView(); 5833 RecentFiles.getInstance().bufferDeactivated(buffer, dot); 5834 } 5835 5836 reactivate(buf); 5839 5840 buf.setLastActivated(System.currentTimeMillis()); 5841 if (buf.isLoaded()) { 5842 buffer = buf; 5843 bufferActivated(false); 5844 } else { 5845 setWaitCursor(); 5846 int result = LOAD_FAILED; 5847 try { 5848 result = buf.load(); 5849 } 5850 catch (OutOfMemoryError e) { 5851 buf.kill(); 5852 Sidebar.setUpdateFlagInAllFrames(SIDEBAR_ALL); 5853 MessageDialog.showMessageDialog(this, 5854 "Insufficient memory to load buffer", 5855 "Error"); 5856 return; 5857 } 5858 switch (result) { 5859 case LOAD_COMPLETED: 5860 buffer = buf; 5861 bufferActivated(true); 5862 break; 5863 case LOAD_PENDING: 5864 buffer = buf; 5865 buffer.setBusy(true); 5866 bufferPending(); 5867 break; 5868 case LOAD_FAILED: 5869 setDefaultCursor(); 5870 buffer = buf; 5871 bufferActivated(true); 5872 MessageDialog.showMessageDialog(this, 5873 "Unable to load buffer", 5874 "Error"); 5875 break; 5876 default: 5877 Debug.assertTrue(false); 5878 } 5879 } 5880 } 5881 5882 public Editor activateInOtherWindow(Buffer buf) 5883 { 5884 return frame.activateInOtherWindow(this, buf); 5885 } 5886 5887 public Editor activateInOtherWindow(Buffer buf, float split) 5888 { 5889 return frame.activateInOtherWindow(this, buf, split); 5890 } 5891 5892 public Editor displayInOtherWindow(Buffer buf) 5893 { 5894 return frame.displayInOtherWindow(this, buf); 5895 } 5896 5897 public void bufferActivated(boolean firstTime) 5898 { 5899 if (buffer.getModeId() == IMAGE_MODE) { 5900 setDot(null); 5901 setMark(null); 5902 display.setTopLine(null); 5903 display.setShift(0); 5904 display.setCaretCol(0); 5905 } else { 5906 findOrCreateView(buffer); 5907 restoreView(); 5908 5909 if (firstTime) 5912 moveCaretToDotCol(); 5913 } 5914 5915 if (dot != null && dot.getOffset() > dot.getLineLength()) { 5916 dot.setOffset(dot.getLineLength()); 5917 moveCaretToDotCol(); 5918 } 5919 5920 frame.updateTitle(); 5921 frame.setMenu(); 5922 frame.setToolbar(); 5923 5924 if (buffer.isBusy()) 5925 setWaitCursor(); 5926 else 5927 setDefaultCursor(); 5928 5929 setUpdateFlag(REFRAME); 5930 reframe(); 5931 setUpdateFlag(REPAINT); 5932 5933 RecentFiles.getInstance().bufferActivated(buffer); 5934 5935 if (buffer.isTaggable()) { 5936 tagFileManager.addToQueue(buffer.getCurrentDirectory(), 5937 buffer.getMode()); 5938 } 5939 5940 Sidebar.setUpdateFlagInAllFrames(SIDEBAR_ALL); 5941 5942 if (isLispInitialized()) { 5943 if (firstTime) 5944 LispAPI.invokeOpenFileHook(buffer); 5945 LispAPI.invokeBufferActivatedHook(buffer); 5946 } 5947 } 5948 5949 private void bufferPending() 5950 { 5951 findOrCreateView(buffer); 5953 restoreView(); 5954 5955 frame.updateTitle(); 5956 frame.setMenu(); 5957 frame.setToolbar(); 5958 5959 display.repaint(); 5960 5961 Sidebar.setUpdateFlagInAllFrames(SIDEBAR_ALL); 5962 Sidebar sidebar = getSidebar(); 5963 if (sidebar != null) 5964 sidebar.setBuffer(); 5965 } 5966 5967 public Editor activateInOtherFrame(Buffer buf) 5969 { 5970 Editor ed = null; 5971 if (getEditorCount() == 1) { 5972 ed = createNewFrame(); 5973 ed.activate(buf); 5974 ed.getFrame().setVisible(true); 5975 ed.updateDisplay(); 5976 } else { 5977 for (int i = 0; i < getEditorCount(); i++) { 5978 ed = getEditor(i); 5979 if (ed != this) { 5980 ed.activate(buf); 5981 ed.getFrame().toFront(); 5982 break; 5983 } 5984 } 5985 } 5986 return ed; 5987 } 5988 5989 public void nextFrame() 5990 { 5991 int count = getEditorCount(); 5992 if (count > 1) { 5993 Editor ed = null; 5994 for (int i = 0; i < count; i++) { 5995 ed = Editor.getEditor(i); 5996 if (ed == this) { 5997 if (++i == count) 5998 i = 0; 5999 ed = Editor.getEditor(i); 6000 ed.getFrame().toFront(); 6001 ed.requestFocusLater(); 6002 break; 6003 } 6004 } 6005 } 6006 } 6007 6008 private void requestFocusLater() 6009 { 6010 Runnable r = new Runnable () { 6011 public void run() 6012 { 6013 Editor.this.requestFocus(); 6014 } 6015 }; 6016 SwingUtilities.invokeLater(r); 6017 } 6018 6019 public void toggleSidebar() 6020 { 6021 frame.frameToggleSidebar(); 6022 } 6023 6024 public void sidebarListBuffers() 6025 { 6026 ensureActive(); 6027 6028 if (frame.getSidebar() == null) 6029 toggleSidebar(); 6030 6031 if (frame.getSidebar() != null) 6032 frame.getSidebar().activateBufferList(); 6033 } 6034 6035 public void sidebarListTags() 6036 { 6037 if (!frame.isActive()) 6038 return; 6039 6040 if (getMode().getSidebarComponent(this) != null) { 6041 if (frame.getSidebar() == null) 6042 toggleSidebar(); 6043 if (frame.getSidebar() != null) 6044 frame.getSidebar().activateNavigationComponent(); 6045 } 6046 } 6047 6048 public void toggleToolbar() 6049 { 6050 frame.frameToggleToolbar(); 6051 } 6052 6053 public final boolean addUndo(int type) 6054 { 6055 return SimpleEdit.addUndo(this, type); 6056 } 6057 6058 public final boolean addUndoDeleteRegion(Region r) 6059 { 6060 buffer.addEdit(new UndoDeleteRegion(this, r)); 6061 return true; 6062 } 6063 6064 public final CompoundEdit beginCompoundEdit() 6065 { 6066 return buffer.beginCompoundEdit(); 6067 } 6068 6069 public final void endCompoundEdit(CompoundEdit compoundEdit) 6070 { 6071 buffer.endCompoundEdit(compoundEdit); 6072 } 6073 6074 public void undo() 6075 { 6076 setWaitCursor(); 6077 try { 6078 buffer.lockWrite(); 6079 } 6080 catch (InterruptedException e) { 6081 Log.error(e); 6082 return; 6083 } 6084 try { 6085 buffer.undo(); 6086 checkDotInOtherFrames(); 6087 setCurrentCommand(COMMAND_UNDO); 6088 } 6089 catch (Throwable t) { 6090 Log.error(t); 6091 } 6092 finally { 6093 buffer.unlockWrite(); 6094 setDefaultCursor(); 6095 } 6096 } 6097 6098 public void redo() 6099 { 6100 setWaitCursor(); 6101 try { 6102 buffer.lockWrite(); 6103 } 6104 catch (InterruptedException e) { 6105 Log.error(e); 6106 return; 6107 } 6108 try { 6109 buffer.redo(); 6110 checkDotInOtherFrames(); 6111 } 6112 catch (Throwable t) { 6113 Log.error(t); 6114 } 6115 finally { 6116 buffer.unlockWrite(); 6117 setDefaultCursor(); 6118 } 6119 } 6120 6121 private void checkDotInOtherFrames() 6122 { 6123 if (getEditorCount() > 1) { 6124 for (int i = 0; i < getEditorCount(); i++) { 6125 Editor ed = getEditor(i); 6126 if (ed != this && ed.getBuffer() == buffer) { 6127 if (ed.getDotOffset() > ed.getDotLine().length()) { 6128 ed.getDot().setOffset(ed.getDotLine().length()); 6129 ed.moveCaretToDotCol(); 6130 ed.updateDotLine(); 6131 } 6132 } 6133 } 6134 } 6135 } 6136 6137 public final void jumpToLine(int lineNumber) 6138 { 6139 jumpToLine(lineNumber, 0); 6140 } 6141 6142 public void jumpToLine(int lineNumber, int offset) 6143 { 6144 Line line = buffer.getLine(lineNumber); 6145 if (line != null) { 6146 if (offset < 0) 6147 offset = 0; 6148 else if (offset > line.length()) 6149 offset = line.length(); 6150 moveDotTo(line, offset); 6151 setUpdateFlag(REFRAME); 6152 } else 6153 eob(); 6154 } 6155 6156 public void offset() 6157 { 6158 status(String.valueOf(buffer.getAbsoluteOffset(dot))); 6159 } 6160 6161 public void executeCommand() 6162 { 6163 locationBar.setLabelText(LocationBar.PROMPT_COMMAND); 6165 HistoryTextField textField = locationBar.getTextField(); 6166 textField.setHandler(new ExecuteCommandTextFieldHandler(this, textField)); 6167 textField.setHistory(new History("executeCommand.input", 30)); 6168 textField.recallLast(); 6169 textField.selectAll(); 6170 AWTEvent e = dispatcher.getLastEvent(); 6171 if (e != null && e.getSource() instanceof MenuItem) { 6172 Runnable r = new Runnable () { 6173 public void run() 6174 { 6175 setFocusToTextField(); 6176 } 6177 }; 6178 SwingUtilities.invokeLater(r); 6179 } else 6180 setFocusToTextField(); 6181 } 6182 6183 public void executeCommand(String input) 6184 { 6185 executeCommand(input, false); 6186 } 6187 6188 public void executeCommand(String input, final boolean interactive) 6189 { 6190 input = Utilities.trimLeading(input); 6191 if (input.length() == 0) 6192 return; 6193 if (input.charAt(0) == '(') { 6194 try { 6196 String result = String.valueOf(Interpreter.evaluate(input)); 6197 if (interactive) 6198 status(result); 6199 } 6200 catch (Throwable t) { 6201 String message = null; 6202 if (t instanceof ConditionThrowable) { 6203 LispObject obj = ((ConditionThrowable)t).getCondition(); 6204 if (obj instanceof Condition) { 6205 try { 6206 message = ((Condition)obj).getConditionReport(); 6207 } 6208 catch (Throwable ignored) { 6209 } 6211 } 6212 } 6213 if (message == null || message.length() == 0) 6214 message = t.getMessage(); 6215 if (message != null && message.length() > 0) { 6216 FastStringBuffer sb = new FastStringBuffer(message); 6217 sb.setCharAt(0, Character.toUpperCase(sb.charAt(0))); 6218 message = sb.toString(); 6219 } else 6220 message = String.valueOf(t); 6221 MessageDialog.showMessageDialog(this, message, "Error"); 6222 } 6223 return; 6224 } 6225 int index = input.indexOf('='); 6226 if (index >= 0) { 6227 String key = input.substring(0, index).trim(); 6228 if (key.indexOf(' ') < 0 && key.indexOf('\t') < 0) { 6229 String value = input.substring(index+1).trim(); 6230 setProperty(key, value); 6231 return; 6232 } 6233 } 6234 String [] array = parseCommand(input); 6235 if (array != null) { 6236 final String command = array[0]; 6237 final String parameters = array[1]; 6238 Runnable r = new Runnable () { 6239 public void run() 6240 { 6241 try { 6242 StatusBar statusBar = getStatusBar(); 6243 statusBar.setText(""); 6244 execute(command, parameters); 6245 if (interactive && parameters == null) { 6246 Object [] values = getKeyMapping(command); 6248 Debug.assertTrue(values != null); 6249 Debug.assertTrue(values.length == 2); 6250 KeyMapping mapping = (KeyMapping) values[0]; 6251 Mode mode = (Mode) values[1]; 6252 if (mapping != null) { 6253 String statusText = statusBar.getText(); 6254 boolean append = 6255 statusText != null && statusText.length() > 0; 6256 FastStringBuffer sb = new FastStringBuffer(); 6257 if (append) { 6258 sb.append(statusText); 6259 sb.append(" "); 6260 } 6261 sb.append(command); 6262 sb.append(" is mapped to "); 6263 sb.append(mapping.getKeyText()); 6264 if (mode != null) { 6265 sb.append(" ("); 6266 sb.append(mode); 6267 sb.append(" mode)"); 6268 } else 6269 sb.append(" (global mapping)"); 6270 status(sb.toString()); 6271 } 6272 } 6273 } 6274 catch (NoSuchMethodException e) { 6275 FastStringBuffer sb = 6276 new FastStringBuffer("Unknown command \""); 6277 sb.append(command); 6278 sb.append('"'); 6279 MessageDialog.showMessageDialog(Editor.this, 6280 sb.toString(), "Error"); 6281 } 6282 } 6283 }; 6284 if (SwingUtilities.isEventDispatchThread()) { 6285 r.run(); 6286 } else { 6287 try { 6288 SwingUtilities.invokeAndWait(r); 6289 } 6290 catch (Throwable t) { 6291 Log.debug(t); 6292 } 6293 } 6294 } 6295 } 6296 6297 private static String [] parseCommand(String command) 6298 { 6299 command = Utilities.trimLeading(command); 6300 char delimiter = '\0'; 6302 int index = -1; 6303 int commandLength = command.length(); 6304 for (int i = 0; i < commandLength; i++) { 6305 char c = command.charAt(i); 6306 if (c == '(' || Character.isWhitespace(c)) { 6307 delimiter = c; 6308 index = i; 6309 break; 6310 } 6311 } 6312 String methodName, parameters; 6313 if (index < 0) { 6314 methodName = command; 6315 parameters = null; 6316 } else { 6317 methodName = command.substring(0, index); 6318 parameters = Utilities.trimLeading(command.substring(index)); 6319 if (delimiter != '(') { 6320 if (parameters.startsWith("(")) 6321 delimiter = '('; 6322 } 6323 if (delimiter == '(') { 6324 int length = parameters.length(); 6326 if (length < 2) 6327 return null; if (parameters.charAt(length - 1) != ')') 6329 return null; parameters = parameters.substring(1, length - 1).trim(); 6331 length = parameters.length(); 6332 if (length == 0) 6333 parameters = null; 6334 else { 6335 if (length < 2) 6337 return null; if (parameters.charAt(0) != '"' || parameters.charAt(length - 1) != '"') 6339 return null; parameters = parameters.substring(1, length - 1); } 6342 } 6343 } 6344 String [] array = new String [2]; 6345 array[0] = methodName; 6346 array[1] = parameters; 6347 return array; 6348 } 6349 6350 private void setProperty(String key, String value) 6352 { 6353 Property property = Property.findProperty(key); 6354 if (property == null) { 6355 MessageDialog.showMessageDialog( 6356 "Property \"" + key + "\" not found", 6357 "Error"); 6358 return; 6359 } 6360 final boolean succeeded; 6361 if (value.length() == 0) { 6362 succeeded = buffer.removeProperty(property); 6363 } else { 6364 succeeded = buffer.setPropertyFromString(property, value); 6365 if (!succeeded) 6366 invalidPropertyValue(property, value); 6367 } 6368 if (succeeded) 6369 buffer.saveProperties(); 6370 } 6371 6372 public static void setGlobalProperty(String key, String value) 6374 { 6375 if (value == null || value.length() == 0) 6376 prefs.removeProperty(key); 6377 else 6378 prefs.setProperty(key, value); 6379 } 6380 6381 private void invalidPropertyValue(Property property, String value) 6382 { 6383 if (property.isIntegerProperty()) 6384 status("Invalid integer value \"" + value + "\""); 6385 else if (property.isBooleanProperty()) 6386 status("Invalid boolean value \"" + value + "\""); 6387 } 6388 6389 public void slideIn() 6390 { 6391 slide(buffer.getIndentSize()); 6392 } 6393 6394 public void slideOut() 6395 { 6396 slide(-buffer.getIndentSize()); 6397 } 6398 6399 private void slide(int amount) 6400 { 6401 if (!checkReadOnly()) 6402 return; 6403 Region r = mark != null ? new Region(this) : null; 6404 if (r != null && (r.getBeginOffset() != 0 || r.getEndOffset() != 0)) 6405 return; try { 6407 buffer.lockWrite(); 6408 } 6409 catch (InterruptedException e) { 6410 Log.error(e); 6411 return; 6412 } 6413 try { 6414 if (r == null) { 6415 CompoundEdit compoundEdit = beginCompoundEdit(); 6416 int dotCol = getDotCol(); 6417 int oldIndent = buffer.getIndentation(getDotLine()); 6418 int newIndent = oldIndent + amount; 6419 addUndo(SimpleEdit.LINE_EDIT); 6420 buffer.setIndentation(getDotLine(), newIndent); 6421 updateInAllEditors(getDotLine()); 6422 if (dotCol < oldIndent) { 6423 moveDotToCol(newIndent); 6427 } else { 6428 display.setCaretCol(display.getCaretCol() + amount); 6430 moveDotToCaretCol(); 6431 } 6432 endCompoundEdit(compoundEdit); 6433 buffer.modified(); 6434 } else { 6435 CompoundEdit compoundEdit = beginCompoundEdit(); 6437 Position saved = new Position(dot); 6438 Line line = r.getBeginLine(); 6439 while (line != r.getEndLine()) { 6440 addUndo(SimpleEdit.MOVE); 6441 dot.moveTo(line, 0); 6442 addUndo(SimpleEdit.LINE_EDIT); 6443 buffer.setIndentation(getDotLine(), 6444 buffer.getIndentation(getDotLine()) + amount); 6445 updateInAllEditors(getDotLine()); 6446 line = line.next(); 6447 } 6448 addUndo(SimpleEdit.MOVE); 6449 dot = saved; 6450 endCompoundEdit(compoundEdit); 6451 buffer.modified(); 6452 } 6453 } 6454 finally { 6455 buffer.unlockWrite(); 6456 } 6457 } 6458 6459 public void dirHome() 6460 { 6461 if (buffer instanceof Directory) 6462 ((Directory) buffer).home(); 6463 } 6464 6465 public void dirTagFile() 6466 { 6467 if (buffer instanceof Directory) 6468 ((Directory) buffer).tagFileAtDot(); 6469 } 6470 6471 public void dirBrowseFile() 6472 { 6473 if (buffer instanceof Directory && !buffer.getFile().isRemote()) { 6474 Directory d = (Directory) buffer; 6475 d.browseFileAtDot(); 6476 } 6477 } 6478 6479 public void dirDeleteFiles() 6480 { 6481 if (mark != null && getMarkLine() != getDotLine()) { 6482 MessageDialog.showMessageDialog(this, 6483 "This operation is not supported with multi-line text selections.", 6484 "Delete Files"); 6485 return; 6486 } 6487 if (buffer instanceof Directory) { 6488 if (buffer.getFile() instanceof SshFile) { 6489 MessageDialog.showMessageDialog(this, "Deletions are not yet supported in ssh directory buffers.", "Error"); 6490 return; 6491 } 6492 ((Directory)buffer).deleteFiles(); 6493 } 6494 } 6495 6496 public void dirCopyFile() 6497 { 6498 if (buffer instanceof Directory && buffer.getFile().isLocal()) 6499 ((Directory) buffer).copyFileAtDot(); 6500 } 6501 6502 public void dirGetFile() 6503 { 6504 if (buffer instanceof Directory && buffer.getFile() instanceof FtpFile) 6505 ((Directory) buffer).getFileAtDot(); 6506 } 6507 6508 public void dirMoveFile() 6509 { 6510 if (buffer instanceof Directory && buffer.getFile().isLocal()) 6511 ((Directory) buffer).moveFileAtDot(); 6512 } 6513 6514 public void dirRescan() 6515 { 6516 if (buffer instanceof Directory) { 6517 setWaitCursor(); 6518 ((Directory) buffer).rescan(); 6519 setDefaultCursor(); 6520 } 6521 } 6522 6523 public void dirHomeDir() 6524 { 6525 File homeDir = File.getInstance(Utilities.getUserHome()); 6526 if (buffer instanceof Directory) { 6527 if (!buffer.getFile().equals(homeDir)) 6528 ((Directory) buffer).changeDirectory(homeDir); 6529 } else { 6530 Buffer buf = getBuffer(homeDir); 6531 if (buf != null) { 6532 makeNext(buf); 6533 activate(buf); 6534 } 6535 } 6536 } 6537 6538 public void dirUpDir() 6539 { 6540 if (buffer instanceof Directory) 6541 ((Directory) buffer).upDir(); 6542 } 6543 6544 public void setFocusToTextField() 6545 { 6546 frame.setFocus(locationBar.getTextField()); 6547 } 6548 6549 public void wrapRegion() 6550 { 6551 if (!checkReadOnly()) 6552 return; 6553 if (dot == null || mark == null) 6554 return; 6555 if (dot.getOffset() != 0 || mark.getOffset() != 0) 6557 return; 6558 new WrapText(this).wrapRegion(); 6559 } 6560 6561 public void wrapParagraph() 6562 { 6563 if (!checkReadOnly()) 6564 return; 6565 new WrapText(this).wrapParagraph(); 6566 } 6567 6568 public void unwrapParagraph() 6569 { 6570 if (!checkReadOnly()) 6571 return; 6572 new WrapText(this).unwrapParagraph(); 6573 } 6574 6575 public void wrapParagraphsInRegion() 6576 { 6577 if (!checkReadOnly()) 6578 return; 6579 new WrapText(this).wrapParagraphsInRegion(); 6580 } 6581 6582 public void visibleTabs() 6583 { 6584 tabsAreVisible = !tabsAreVisible; 6585 if (tabsAreVisible) 6586 status("Tabs are visible"); 6587 else 6588 status("Tabs are not visible"); 6589 for (int i = 0; i < getEditorCount(); i++) { 6590 Editor ed = getEditor(i); 6591 ed.getDisplay().repaint(); 6592 } 6593 } 6594 6595 public void insertBraces() 6596 { 6597 CompoundEdit compoundEdit = beginCompoundEdit(); 6598 insertChar('{'); 6599 indentLine(); 6600 eol(); 6601 newlineAndIndent(); 6602 insertChar('}'); 6603 indentLine(); 6604 up(); 6605 eol(); 6606 newlineAndIndent(); 6607 endCompoundEdit(compoundEdit); 6608 } 6609 6610 public void insertParentheses() 6611 { 6612 if (!checkReadOnly()) 6613 return; 6614 boolean parensRequireSpaces = 6615 buffer.getBooleanProperty(Property.PARENS_REQUIRE_SPACES); 6616 CompoundEdit compoundEdit = beginCompoundEdit(); 6617 if (mark != null) { 6618 Position begin, end; 6619 if (mark.isBefore(dot)) { 6620 begin = new Position(mark); 6621 end = new Position(dot); 6622 } else { 6623 begin = new Position(dot); 6624 end = new Position(mark); 6625 } 6626 addUndo(SimpleEdit.MOVE); 6627 setMark(null); 6628 dot.moveTo(end); 6629 if (parensRequireSpaces) 6630 insertChar(' '); 6631 insertChar(')'); 6632 addUndo(SimpleEdit.MOVE); 6633 dot.moveTo(begin); 6634 insertChar('('); 6635 if (parensRequireSpaces) 6636 insertChar(' '); 6637 } else { 6638 fillToCaret(); 6639 addUndo(SimpleEdit.INSERT_STRING); 6640 insertStringInternal(parensRequireSpaces ? "( )" : "()"); 6641 addUndo(SimpleEdit.MOVE); 6642 dot.skip(parensRequireSpaces ? -2 : -1); 6643 } 6644 moveCaretToDotCol(); 6645 endCompoundEdit(compoundEdit); 6646 } 6647 6648 public void movePastCloseAndReindent() 6649 { 6650 Position pos = new Position(dot); 6651 int count = 1; 6652 while (pos.next()) { 6653 char c = pos.getChar(); 6654 if (c == '(') 6655 ++count; 6656 else if (c == ')') 6657 --count; 6658 if (count == 0) 6659 break; 6660 } 6661 if (count == 0) { 6662 pos.next(); 6663 updateDotLine(); 6664 CompoundEdit compoundEdit = beginCompoundEdit(); 6665 addUndo(SimpleEdit.MOVE); 6666 dot.moveTo(pos); 6667 updateDotLine(); 6668 newlineAndIndent(); 6669 endCompoundEdit(compoundEdit); 6670 } 6671 } 6672 6673 public final void updateDotLine() 6674 { 6675 display.lineChanged(dot.getLine()); 6676 } 6677 6678 public final void update(Line line) 6680 { 6681 display.lineChanged(line); 6682 } 6683 6684 6690 public static void updateInAllEditors(Line line) 6691 { 6692 if (line != null) { 6693 for (EditorIterator it = new EditorIterator(); it.hasNext();) { 6694 Editor ed = it.nextEditor(); 6695 if (ed.getBuffer() == currentEditor.getBuffer()) 6696 ed.getDisplay().lineChanged(line); 6697 } 6698 } 6699 } 6700 6701 6708 public static void updateInAllEditors(Buffer buffer, Line line) 6709 { 6710 if (line != null) { 6711 for (EditorIterator it = new EditorIterator(); it.hasNext();) { 6712 Editor ed = it.nextEditor(); 6713 if (ed.getBuffer() == buffer) 6714 ed.getDisplay().lineChanged(line); 6715 } 6716 } 6717 } 6718 6719 public void updateScrollBars() 6720 { 6721 if (buffer == null) 6722 return; if (!displayReady) 6724 return; 6725 updateVerticalScrollBar(); 6726 updateHorizontalScrollBar(); 6727 } 6728 6729 boolean inScrollBarUpdate = false; 6730 6731 public void updateVerticalScrollBar() 6732 { 6733 if (verticalScrollBar != null) { 6734 inScrollBarUpdate = true; 6735 int y; 6736 if (getTopLine() != null) 6737 y = buffer.getY(getTopLine()) + display.getPixelsAboveTopLine(); 6738 else 6739 y = display.getPixelsAboveTopLine(); 6740 verticalScrollBar.setValues(y, display.getHeight(), 0, buffer.getDisplayHeight()); 6741 inScrollBarUpdate = false; 6742 } 6743 } 6744 6745 public void updateHorizontalScrollBar() 6746 { 6747 if (horizontalScrollBar != null) 6748 horizontalScrollBar.setValues(display.getShift() * Display.getCharWidth(), 6749 display.getWidth(), 0, buffer.getDisplayWidth()); 6750 } 6751 6752 public void updateDisplay() 6753 { 6754 if (dot != null) { 6755 if (dot.isHidden()) { 6756 buffer.appendUndoFold(this); 6757 show(getDotLine()); 6758 } 6759 reframe(); 6760 } 6761 display.repaintChangedLines(); 6762 updateScrollBars(); 6763 Sidebar sidebar = getSidebar(); 6764 if (sidebar != null) 6765 sidebar.setUpdateFlag(SIDEBAR_POSITION); 6766 frame.repaintStatusBar(); 6767 if (buffer.isBusy()) 6768 setWaitCursor(); 6769 else 6770 setDefaultCursor(); 6771 } 6772 6773 public void updateDisplayLater() 6774 { 6775 Runnable r = new Runnable () { 6776 public void run() 6777 { 6778 updateDisplay(); 6779 } 6780 }; 6781 SwingUtilities.invokeLater(r); 6782 } 6783 6784 public static void updateDisplayLater(final Buffer buf) 6786 { 6787 Runnable r = new Runnable () { 6788 public void run() 6789 { 6790 for (int i = 0; i < getEditorCount(); i++) { 6791 Editor ed = getEditor(i); 6792 if (ed.getBuffer() == buf) 6793 ed.updateDisplay(); 6794 } 6795 } 6796 }; 6797 SwingUtilities.invokeLater(r); 6798 } 6799 6800 public final Line getTopLine() 6801 { 6802 return display.getTopLine(); 6803 } 6804 6805 public final void setTopLine(Line line) 6806 { 6807 display.setTopLine(line); 6808 } 6809 6810 public final void setUpdateFlag(int mask) 6811 { 6812 display.setUpdateFlag(mask); 6813 } 6814 6815 public final void reframe() 6816 { 6817 display.reframe(); 6818 } 6819 6820 public boolean checkReadOnly() 6821 { 6822 boolean readOnly = buffer.isReadOnly(); 6823 if (readOnly && buffer.getBooleanProperty(Property.P4_AUTO_EDIT)) { 6824 if (buffer.getType() == Buffer.TYPE_NORMAL) { 6825 File file = buffer.getFile(); 6826 if (file != null && file.isLocal() && file.isFile()) 6827 if (P4.autoEdit(this)) 6828 readOnly = buffer.isReadOnly(); 6829 } 6830 } 6831 if (readOnly) { 6832 status("Buffer is read only"); 6833 return false; 6834 } 6835 if (buffer.isLocked()) 6836 return false; 6837 if (dot == null) 6838 return false; 6839 return true; 6840 } 6841 6842 public static boolean checkExperimental() 6843 { 6844 return prefs.getBooleanProperty(Property.ENABLE_EXPERIMENTAL_FEATURES); 6845 } 6846 6847 public void status(String s) 6848 { 6849 frame.setStatusText(s); 6850 } 6851 6852 private static boolean displayReady; 6853 6854 public static final boolean displayReady() 6855 { 6856 return displayReady; 6857 } 6858 6859 public static final void setDisplayReady(boolean b) 6860 { 6861 displayReady = b; 6862 } 6863 6864 private static final Cursor waitCursor = 6865 Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR); 6866 6867 public final void setWaitCursor() 6868 { 6869 display.setCursor(waitCursor); 6870 } 6871 6872 public final void setDefaultCursor() 6873 { 6874 final Cursor cursor; 6875 if (displayReady && buffer != null) 6876 cursor = buffer.getDefaultCursor(); 6877 else 6878 cursor = waitCursor; 6879 display.setCursor(cursor); 6880 } 6881 6882 public final void setCursor(Cursor cursor) 6883 { 6884 display.setCursor(cursor); 6885 } 6886 6887 public static void loadPreferences() 6888 { 6889 prefs.reload(); 6890 debug = prefs.getBooleanProperty(Property.DEBUG); 6891 } 6892 6893 private boolean insertingKeyText = false; 6894 6895 public void insertKeyText() 6896 { 6897 if (!checkReadOnly()) 6898 return; 6899 insertingKeyText = true; } 6901 6902 private void insertKeyTextInternal(char keyChar, int keyCode, int modifiers) 6903 { 6904 Log.debug("keycode = 0x" + Integer.toString(keyCode, 16)); 6905 Log.debug("modifiers = 0x" + Integer.toString(modifiers, 16)); 6906 Log.debug("character = " + String.valueOf(keyChar)); 6907 Log.debug("character = 0x" + Integer.toString((int) keyChar, 16)); 6908 6909 insertingKeyText = false; 6910 6911 try { 6912 buffer.lockWrite(); 6913 } 6914 catch (InterruptedException e) { 6915 Log.error(e); 6916 return; 6917 } 6918 try { 6919 KeyMapping km; 6920 if (keyCode != 0) 6921 km = new KeyMapping(keyCode, modifiers, null); 6922 else 6923 km = new KeyMapping(keyChar, null); 6924 6925 CompoundEdit compoundEdit = beginCompoundEdit(); 6926 if (mark != null) 6927 delete(); 6928 fillToCaret(); 6929 addUndo(SimpleEdit.INSERT_STRING); 6930 insertStringInternal(km.toString()); 6931 buffer.modified(); 6932 moveCaretToDotCol(); 6933 endCompoundEdit(compoundEdit); 6934 } 6935 finally { 6936 buffer.unlockWrite(); 6937 } 6938 } 6939 6940 public void whatChar() 6941 { 6942 if (dot.getOffset() < dot.getLineLength()) { 6943 char c = getDotChar(); 6944 FastStringBuffer sb = new FastStringBuffer(Integer.toString(c)); 6945 sb.append(" 0x"); 6946 sb.append(Integer.toHexString(c)); 6947 if (c >= ' ' && c < 0x7f) { 6948 sb.append(" '"); 6949 if (c == '\'') 6950 sb.append('\\'); 6951 sb.append(c); 6952 sb.append('\''); 6953 } 6954 status(sb.toString()); 6955 } 6956 } 6957 6958 public void jmips() 6959 { 6960 setWaitCursor(); 6961 long loopsPerSecond = 0; 6962 long loops = 1; 6963 Thread thread = Thread.currentThread(); 6964 int oldPriority = thread.getPriority(); 6965 thread.setPriority(Thread.MAX_PRIORITY); 6966 do { 6967 long start = System.currentTimeMillis(); 6968 for (long i = loops; i >= 0; i--) 6969 ; 6970 long elapsed = System.currentTimeMillis() - start; 6971 if (elapsed >= 1000) { 6972 loopsPerSecond = (loops / elapsed) * 1000; 6973 break; 6974 } 6975 loops *= 2; 6976 } while (true); 6977 thread.setPriority(oldPriority); 6978 String s = String.valueOf(((float) loopsPerSecond) / 500000); 6979 currentEditor.status(s); 6980 setDefaultCursor(); 6981 } 6982 6983 public void httpDeleteCookies() 6984 { 6985 Cookie.deleteCookies(); 6986 } 6987 6988 private static Class extensionClass = null; 6989 6990 private static void loadExtensions() 6991 { 6992 String extension = prefs.getStringProperty(Property.EXTENSION); 6993 if (extension != null) { 6994 Log.debug("loading extension " + extension); 6995 try { 6996 ExtensionClassLoader loader = new ExtensionClassLoader(); 6997 extensionClass = loader.loadClass(extension, true); 6998 if (extensionClass != null) { 6999 Method method = extensionClass.getMethod("run", new Class [0]); 7000 if (method != null) 7001 method.invoke(extensionClass.newInstance(), new Class [0]); 7002 } else 7003 Log.error("extension " + extension + " not found"); 7004 } 7005 catch (Exception e) { 7006 Log.error(e); 7007 } 7008 } 7009 } 7010 7011 private static Class loadExtensionClass(String className) 7012 { 7013 Class c = null; 7014 try { 7015 ExtensionClassLoader loader = new ExtensionClassLoader(); 7016 c = loader.loadClass(className, true); 7017 } 7018 catch (Exception e) { 7019 Log.error(e); 7020 } 7021 return c; 7022 } 7023 7024 private static void runStartupScript() 7025 { 7026 File file = 7027 File.getInstance(Directories.getEditorDirectory(), "init.lisp"); 7028 if (file != null && file.isFile()) { 7029 try { 7030 long start = System.currentTimeMillis(); 7031 JLisp.runStartupScript(file); 7032 long elapsed = System.currentTimeMillis() - start; 7033 FastStringBuffer sb = new FastStringBuffer("loaded "); 7034 sb.append(file.canonicalPath()); 7035 sb.append(" ("); 7036 sb.append(elapsed); 7037 sb.append(" ms)"); 7038 Log.info(sb.toString()); 7039 } 7040 catch (Throwable t) { 7041 Log.error(t); 7042 Log.error("error loading " + file.canonicalPath()); 7043 } 7044 } 7045 } 7046 7047 public static void runLispCommand(String command) 7048 { 7049 try { 7050 JLisp.runLispCommand(command); 7051 } 7052 catch (Throwable t) { 7053 Log.error(t); 7054 } 7055 } 7056 7057 private static boolean isLispInitialized; 7058 7059 public static synchronized boolean isLispInitialized() 7060 { 7061 return isLispInitialized; 7062 } 7063 7064 public static synchronized void setLispInitialized(boolean b) 7065 { 7066 isLispInitialized = b; 7067 } 7068 7069 public static void invokeHook(String hook) 7070 { 7071 invokeHook(hook, null); 7072 } 7073 7074 public static void invokeHook(String hook, String args) 7075 { 7076 FastStringBuffer sb = new FastStringBuffer("(invoke-hook '"); 7077 sb.append(hook); 7078 if (args != null && args.length() > 0) { 7079 sb.append(' '); 7080 sb.append(args); 7081 } 7082 sb.append(')'); 7083 runLispCommand(sb.toString()); 7084 } 7085 7086 public void mode() 7087 { 7088 String modeName = 7089 InputDialog.showInputDialog(this, "New mode:", "Change Mode"); 7090 if (modeName != null) { 7091 modeName = modeName.trim(); 7092 if (modeName.length() > 0) { 7093 repaintNow(); 7094 mode(modeName); 7095 } 7096 } 7097 } 7098 7099 public void mode(String modeName) 7100 { 7101 int modeId = getModeList().getModeIdFromModeName(modeName); 7102 if (modeId < 0) { 7103 MessageDialog.showMessageDialog("Unknown mode \"" + modeName + '"', 7104 "Error"); 7105 } else if (modeId != buffer.getMode().getId()) { 7106 if (buffer.isModified() && modeId == BINARY_MODE ) { 7107 String prompt = 7108 "Buffer will be reloaded in binary mode; discard changes?"; 7109 if (!confirm("Change Mode", prompt)) 7110 return; 7111 } 7112 Mode mode = getModeList().getMode(modeId); 7113 if (mode != null) { 7114 setWaitCursor(); 7115 buffer.changeMode(mode); 7116 buffer.saveProperties(); 7117 setDefaultCursor(); 7118 } 7119 } 7120 } 7121 7122 public void defaultMode() 7123 { 7124 Mode mode = buffer.getDefaultMode(); 7125 if (mode != null && mode != buffer.getMode()) { 7126 if (buffer.isModified()) { 7127 FastStringBuffer sb = 7128 new FastStringBuffer("Buffer will be reloaded in "); 7129 sb.append(mode.toString()); 7130 sb.append(" mode; discard changes?"); 7131 if (!confirm("Change Mode", sb.toString())) 7132 return; 7133 } 7134 setWaitCursor(); 7135 buffer.changeMode(mode); 7136 setDefaultCursor(); 7137 } 7138 } 7139 7140 public void textMode() 7141 { 7142 if (buffer.getModeId() == BINARY_MODE) { 7143 if (buffer.isModified()) { 7144 String prompt = 7145 "Buffer will be reloaded in text mode; discard changes?"; 7146 if (!confirm("Change Mode", prompt)) 7147 return; 7148 } 7149 setWaitCursor(); 7150 buffer.changeMode(modeList.getMode(PLAIN_TEXT_MODE)); 7151 setDefaultCursor(); 7152 } 7153 } 7154 7155 public void splitWindow() 7156 { 7157 currentEditor.getFrame().splitWindow(); 7158 } 7159 7160 public void unsplitWindow() 7161 { 7162 IdleThread.killFollowContextTask(); 7163 frame.unsplitWindow(); 7164 } 7165 7166 public void killWindow() 7167 { 7168 frame.unsplitWindowKeepOther(); 7169 Sidebar sidebar = getSidebar(); 7170 if (sidebar != null) { 7171 sidebar.setUpdateFlag(SIDEBAR_ALL); 7172 sidebar.refreshSidebar(); 7173 } 7174 } 7175 7176 public void otherWindow() 7177 { 7178 final Editor ed = frame.getOtherEditor(); 7179 if (ed != null) { 7180 saveView(); 7181 setCurrentEditor(ed); 7182 ed.getBuffer().setLastActivated(System.currentTimeMillis()); 7183 ed.setFocusToDisplay(); 7184 if (ed.getDot() != null) { 7185 ed.update(ed.getDotLine()); 7186 ed.getDisplay().repaintChangedLines(); 7187 } 7188 if (dot != null) { 7189 updateDotLine(); 7190 display.repaintChangedLines(); 7191 } 7192 frame.setMenu(); 7193 frame.setToolbar(); 7194 Sidebar sidebar = getSidebar(); 7195 if (sidebar != null) { 7196 sidebar.setUpdateFlag(SIDEBAR_ALL); 7197 sidebar.refreshSidebar(); 7198 } 7199 } 7200 } 7201 7202 public void fold() 7203 { 7204 if (dot == null) 7205 return; 7206 if (!foldRegionInternal() && !foldExplicit()) 7207 foldNearLine(getDotLine()); 7208 } 7209 7210 public void foldRegion() 7211 { 7212 if (dot == null) 7213 return; 7214 foldRegionInternal(); 7215 } 7216 7217 private boolean foldRegionInternal() 7218 { 7219 if (mark == null) 7220 return false; 7221 if (dot.getLine() == mark.getLine()) 7222 return false; 7223 if (dot.getOffset() > 0) 7224 return false; 7225 if (mark.getOffset() > 0) 7226 return false; 7227 Region r = new Region(buffer, mark, dot); 7228 Line begin = r.getBegin().getLine().next(); 7229 Line end = r.getEnd().getLine(); 7230 addUndo(SimpleEdit.FOLD); 7231 setMark(null); 7232 for (Line line = begin; line != end; line = line.next()) 7233 line.hide(); 7234 buffer.renumber(); 7235 unhideDotInAllFrames(buffer); 7236 return true; 7237 } 7238 7239 private boolean foldExplicit() 7240 { 7241 final Line dotLine = getDotLine(); 7242 String text = dotLine.getText(); 7243 Line begin = null; 7244 Line end = null; 7245 if (text.indexOf(EXPLICIT_FOLD_END) >= 0) { 7246 int count = 1; 7248 end = dotLine.next(); 7249 begin = dotLine.previous(); 7250 while (begin != null) { 7251 text = begin.getText(); 7252 if (text.indexOf(EXPLICIT_FOLD_START) >= 0) { 7253 --count; 7254 if (count == 0) { 7255 begin = begin.next(); 7256 break; 7257 } 7258 } else if (text.indexOf(EXPLICIT_FOLD_END) >= 0) { 7259 ++count; 7260 } 7261 begin = begin.previous(); 7262 } 7263 } else if (text.indexOf(EXPLICIT_FOLD_START) >= 0) { 7264 int count = 1; 7265 begin = dotLine.next(); 7266 if (begin == null) 7267 return false; 7268 end = begin.next(); 7269 while (end != null) { 7270 text = end.getText(); 7271 if (text.indexOf(EXPLICIT_FOLD_START) >= 0) { 7272 ++count; 7273 } else if (text.indexOf(EXPLICIT_FOLD_END) >= 0) { 7274 --count; 7275 if (count == 0) { 7276 end = end.next(); 7277 break; 7278 } 7279 } 7280 end = end.next(); 7281 } 7282 } 7283 if (begin == null) 7284 return false; 7285 addUndo(SimpleEdit.FOLD); 7286 for (Line line = begin; line != end; line = line.next()) 7287 line.hide(); 7288 buffer.renumber(); 7289 unhideDotInAllFrames(buffer); 7290 return true; 7291 } 7292 7293 public void foldNearLine(Line line) 7294 { 7295 while (line != null && line.isBlank()) 7296 line = line.previous(); 7297 if (line == null) 7298 return; 7299 setWaitCursor(); 7300 Line next = line.next(); 7301 while (next != null && next.isBlank()) 7302 next = next.next(); 7303 if (next != null) { 7304 final String trim = line.trim(); 7305 switch (getModeId()) { 7306 case JAVA_MODE: 7307 case JAVASCRIPT_MODE: 7308 case C_MODE: 7309 case CPP_MODE: 7310 case PERL_MODE: 7311 case PHP_MODE: 7312 if (trim.endsWith("{")) { 7313 if (!next.isHidden()) { 7314 fold(next); 7315 return; 7316 } 7317 } 7318 if (trim.startsWith("}")) { 7319 Position end = 7322 new Position(line, line.getText().indexOf('}')); 7323 Position start = findMatchInternal(end, 0); 7324 if (start != null) { 7325 foldNearLine(start.getLine()); 7326 return; 7327 } 7328 } 7329 if (next.trim().startsWith("}")) { 7330 Position end = 7332 new Position(next, next.getText().indexOf('}')); 7333 Position start = findMatchInternal(end, 0); 7334 if (start != null) { 7335 foldNearLine(start.getLine()); 7336 return; 7337 } 7338 } else if (next.trim().endsWith("{")) { 7339 Line nextNext = next.next(); 7340 while (nextNext != null && nextNext.isBlank()) 7341 nextNext = nextNext.next(); 7342 if (nextNext != null && !nextNext.isHidden()) { 7343 fold(nextNext); 7344 return; 7345 } 7346 } 7347 break; 7348 case XML_MODE: { 7349 if (trim.startsWith("/>") || trim.startsWith("</")) { 7350 Line prev = line.previous(); 7351 while (prev != null && prev.isBlank()) 7352 prev = prev.previous(); 7353 if (prev != null) { 7354 int indent = 7355 buffer.getCol(line, line.getIndentation()); 7356 int prevIndent = 7357 buffer.getCol(prev, prev.getIndentation()); 7358 if (indent < prevIndent) { 7359 fold(prev); 7360 return; 7361 } 7362 } 7363 } else if (trim.startsWith("<")) { 7364 int indent = 7365 buffer.getCol(line, line.getIndentation()); 7366 int nextIndent = 7367 buffer.getCol(next, next.getIndentation()); 7368 if (indent < nextIndent) { 7369 fold(next); 7370 return; 7371 } 7372 } 7373 } 7374 default: 7375 break; 7376 } 7377 } 7378 fold(line); 7379 } 7380 7381 private void fold(Line target) 7382 { 7383 if (target == null) 7384 return; 7385 int indent = buffer.getCol(target, target.getIndentation()); 7386 if (indent == 0) 7387 return; 7388 Line begin = target; 7389 while (true) { 7390 Line prev = begin.previous(); 7391 if (prev == null) 7392 break; 7393 if (prev.isBlank() || getMode().isCommentLine(prev) || 7394 isLabelLine(prev) || isPreprocessorLine(prev)) { 7395 begin = prev; 7396 continue; 7397 } 7398 if (buffer.getCol(prev, prev.getIndentation()) < indent) 7399 break; 7400 if (prev.getText().endsWith("{")) 7401 break; 7402 begin = prev; 7403 } 7404 Line end = target.next(); 7405 while (end != null) { 7406 if (end.isBlank() || getMode().isCommentLine(end) || 7407 isLabelLine(end) || isPreprocessorLine(end)) { 7408 end = end.next(); 7409 continue; 7410 } 7411 if (buffer.getCol(end, end.getIndentation()) < indent) 7412 break; 7413 end = end.next(); 7414 } 7415 addUndo(SimpleEdit.FOLD); 7416 for (Line line = begin; line != end; line = line.next()) 7417 line.hide(); 7418 buffer.renumber(); 7419 unhideDotInAllFrames(buffer); 7420 } 7421 7422 private static RE labelRE = new UncheckedRE("^\\s*\\w+:"); 7423 7424 private boolean isLabelLine(Line line) 7425 { 7426 Mode mode = getMode(); 7427 if (mode instanceof JavaMode || mode instanceof PerlMode) 7428 return labelRE.getMatch(line.getText()) != null; 7429 return false; 7430 } 7431 7432 private boolean isPreprocessorLine(Line line) 7433 { 7434 if (getMode() instanceof CMode) 7435 if (line.trim().startsWith("#")) 7436 return true; 7437 7438 return false; 7439 } 7440 7441 public static void unhideDotInAllFrames(Buffer buffer) 7443 { 7444 for (int i = 0; i < Editor.getEditorCount(); i++) { 7445 Editor ed = Editor.getEditor(i); 7446 if (ed.getBuffer() == buffer) { 7447 if (ed.getDot().isHidden()) { 7449 ed.setMark(null); 7450 Line line = ed.getDotLine().previousVisible(); 7451 if (line != null) { 7452 ed.setDot(line, 0); 7453 ed.moveCaretToDotCol(); 7454 } 7455 } 7456 ed.setUpdateFlag(REFRAME); 7457 ed.reframe(); 7458 ed.getDisplay().repaint(); 7459 } 7460 } 7461 } 7462 7463 public void unfold() 7464 { 7465 if (dot == null) 7466 return; 7467 Line dotLine = getDotLine(); 7468 Line begin = null; 7469 if (dotLine.isHidden()) { 7470 begin = dotLine; 7471 while (begin.previous() != null && begin.previous().isHidden()) 7472 begin = begin.previous(); 7473 } else { 7474 begin = dotLine.next(); 7476 while (begin != null && !begin.isHidden()) 7477 begin = begin.next(); 7478 } 7479 if (begin == null) 7480 return; 7481 if (!begin.isHidden()) 7482 return; 7483 Line end = begin; 7484 while (true) { 7485 Line line = end.next(); 7486 if (line == null) 7487 break; 7488 if (!line.isHidden()) 7489 break; 7490 end = line; 7491 } 7492 if (begin != null && end != null) { 7493 addUndo(SimpleEdit.FOLD); 7494 for (Line line = begin; line != end.next(); line = line.next()) 7495 line.unhide(); 7496 buffer.renumber(); 7497 for (int i = 0; i < Editor.getEditorCount(); i++) { 7498 Editor ed = Editor.getEditor(i); 7499 if (ed.getBuffer() == buffer) 7500 ed.getDisplay().repaint(); 7501 } 7502 } 7503 } 7504 7505 public void unfold(Line line) 7506 { 7507 if (line == null) 7508 return; 7509 if (!line.isHidden()) 7510 return; 7511 Line begin = line; 7512 while (begin.previous() != null && begin.previous().isHidden()) 7513 begin = begin.previous(); 7514 Line end = line.next(); 7515 while (end != null && end.isHidden()) 7516 end = end.next(); 7517 addUndo(SimpleEdit.FOLD); 7518 for (Line l = begin; l != end; l = l.next()) 7519 l.unhide(); 7520 buffer.renumber(); 7521 for (int i = 0; i < Editor.getEditorCount(); i++) { 7522 Editor ed = Editor.getEditor(i); 7523 if (ed.getBuffer() == buffer) 7524 ed.getDisplay().repaint(); 7525 } 7526 } 7527 7528 private void show(Line target) 7529 { 7530 if (target == null) 7531 return; 7532 if (!target.isHidden()) 7533 return; 7534 Line begin = target; 7535 while (begin.previous() != null && begin.previous().isHidden()) 7536 begin = begin.previous(); 7537 Line end = target.next(); 7538 while (end != null && end.isHidden()) 7539 end = end.next(); 7540 for (Line line = begin; line != end; line = line.next()) 7541 line.show(); 7542 buffer.renumber(); 7543 for (int i = 0; i < Editor.getEditorCount(); i++) { 7544 Editor ed = Editor.getEditor(i); 7545 if (ed.getBuffer() == buffer) 7546 ed.getDisplay().repaint(); 7547 } 7548 } 7549 7550 public void unfoldAll() 7551 { 7552 addUndo(SimpleEdit.FOLD); 7553 for (Line line = buffer.getFirstLine(); line != null; line = line.next()) 7554 line.show(); 7555 buffer.renumber(); 7556 for (int i = 0; i < Editor.getEditorCount(); i++) { 7557 Editor ed = Editor.getEditor(i); 7558 if (ed.getBuffer() == buffer) 7559 ed.getDisplay().repaint(); 7560 } 7561 } 7562 7563 public void foldMethods() 7564 { 7565 Mode mode = getMode(); 7566 if (mode instanceof JavaMode || mode instanceof PerlMode) { 7567 setWaitCursor(); 7568 List tags = buffer.getTags(); 7569 if (tags != null) { 7570 addUndo(SimpleEdit.FOLD); 7571 for (Line line = buffer.getFirstLine(); line != null; line = line.next()) 7572 line.show(); 7573 for (int i = 0; i < tags.size(); i++) { 7574 LocalTag tag = (LocalTag) tags.get(i); 7575 if (tag.getType() == TAG_METHOD) 7576 foldMethod(tag.getLine()); 7577 } 7578 unhideDotInAllFrames(buffer); 7579 } 7580 } 7581 } 7582 7583 private final void foldMethod(Line line) 7584 { 7585 foldOrUnfoldMethod(line, true); 7586 } 7587 7588 public final void unfoldMethod(Line line) 7589 { 7590 foldOrUnfoldMethod(line, false); 7591 } 7592 7593 private void foldOrUnfoldMethod(Line line, boolean fold) 7594 { 7595 Mode mode = getMode(); 7596 while (line != null) { 7597 String s = line.trim(); 7598 if (mode instanceof PerlMode) 7599 s = PerlMode.trimSyntacticWhitespace(s); 7600 else if (mode instanceof JavaMode) 7601 s = JavaMode.trimSyntacticWhitespace(s); 7602 if (s.endsWith("{")) 7603 break; 7604 line = line.next(); 7605 } 7606 if (line == null) 7607 return; 7608 if (line.next() == null) 7609 return; Position start = new Position(line, line.length()); 7611 Line begin = line.next(); 7612 final SyntaxIterator it = mode.getSyntaxIterator(start); 7613 Position match = null; 7614 int count = 1; 7615 while (true) { 7616 char c = it.nextChar(); 7617 if (c == SyntaxIterator.DONE) 7618 break; 7619 if (c == '{') 7620 ++count; 7621 else if (c == '}') 7622 --count; 7623 if (count == 0) { 7624 match = it.getPosition(); 7626 break; 7627 } 7628 } 7629 if (match == null) 7630 return; 7631 Line end = match.getLine(); 7632 if (fold) { 7633 for (Line toBeHidden = begin; toBeHidden != end && toBeHidden != null; toBeHidden = toBeHidden.next()) 7634 toBeHidden.hide(); 7635 } else { 7636 for (Line toBeShown = begin; toBeShown != end && toBeShown != null; toBeShown = toBeShown.next()) 7637 toBeShown.show(); 7638 } 7639 buffer.needsRenumbering = true; 7640 } 7641 7642 private static Aliases aliases; 7643 7644 private static final Aliases getAliases() 7645 { 7646 if (aliases == null) 7647 aliases = new Aliases(); 7648 return aliases; 7649 } 7650 7651 public static final File getAliasesFile() 7652 { 7653 return aliases != null ? aliases.getFile() : null; 7654 } 7655 7656 public static final void reloadAliases() 7657 { 7658 if (aliases != null) 7659 aliases.reload(); 7660 } 7661 7662 public final String getAlias(String alias) 7663 { 7664 return getAliases().get(alias); 7665 } 7666 7667 public final void setAlias(String alias, String value) 7668 { 7669 getAliases().setAlias(alias, value); 7670 } 7671 7672 public final void setAliasForBuffer(String alias, Buffer buf) 7673 { 7674 getAliases().setAliasForBuffer(alias, buf); 7675 } 7676 7677 public final void removeAlias(String alias) 7678 { 7679 getAliases().remove(alias); 7680 } 7681 7682 public void setEncoding() 7683 { 7684 File file = buffer.getFile(); 7685 if (file != null) { 7686 InputDialog d = 7687 new InputDialog(this, "Encoding:", "Set Encoding", 7688 buffer.getSaveEncoding()); 7689 d.setHistory(new History("setEncoding")); 7690 centerDialog(d); 7691 d.show(); 7692 String encoding = d.getInput(); 7693 if (encoding != null) 7694 setEncoding(encoding); 7695 } 7696 } 7697 7698 public void setEncoding(String encoding) 7699 { 7700 File file = buffer.getFile(); 7701 if (file != null) { 7702 if (Utilities.isSupportedEncoding(encoding)) { 7703 file.setEncoding(encoding); 7704 buffer.saveProperties(); 7705 } else { 7706 FastStringBuffer sb = 7707 new FastStringBuffer("Unsupported encoding \""); 7708 sb.append(encoding); 7709 sb.append('"'); 7710 MessageDialog.showMessageDialog(this, sb.toString(), "Error"); 7711 } 7712 } 7713 } 7714 7715 private static final ArrayList protectList = new ArrayList (); 7716 7717 public static synchronized void protect(Object obj) 7719 { 7720 protectList.add(obj); 7721 } 7722 7723 private static String sessionName; 7724 7725 7731 public static String getSessionName() 7732 { 7733 return sessionName; 7734 } 7735 7736 7743 public static void setSessionName(String name) 7744 { 7745 sessionName = name; 7746 for (int i = 0; i < getFrameCount(); i++) { 7748 Frame frame = getFrame(i); 7749 if (frame != null) 7750 frame.titleChanged(); 7751 } 7752 } 7753 7754 private static Stack positionStack = new Stack (); 7756 7757 public static List getPositionStack() 7758 { 7759 return positionStack; 7760 } 7761 7762 public void pushPosition() 7763 { 7764 if (buffer.getFile() != null) { 7765 pushMarker(new Marker(buffer, dot)); 7766 status("Position saved"); 7767 } 7768 } 7769 7770 public void popPosition() 7771 { 7772 if (positionStack.empty()) { 7773 status("Position stack is empty"); 7774 } else { 7775 Marker m = (Marker) positionStack.pop(); 7776 if (m != null) 7777 m.gotoMarker(this); 7778 } 7779 } 7780 7781 public static void pushMarker(Marker m) 7782 { 7783 while (positionStack.size() >= 30) 7784 positionStack.removeElementAt(0); 7785 positionStack.push(m); 7786 } 7787 7788 public static void resetDisplay() 7789 { 7790 if (!displayReady()) 7791 return; 7792 for (BufferIterator it = new BufferIterator(); it.hasNext();) { 7794 Buffer buf = it.nextBuffer(); 7795 if (buf.getFormatter() != null) 7796 buf.getFormatter().reset(); 7797 } 7798 Display.initializeStaticValues(); 7799 for (EditorIterator it = new EditorIterator(); it.hasNext();) { 7800 Display display = it.nextEditor().getDisplay(); 7801 display.initialize(); 7802 display.repaint(); 7803 } 7804 Editor.restoreFocus(); 7805 } 7806} 7807 | Popular Tags |