1/* 2 * ModeSwitcher.bsh - a BeanShell macro script for changing the current 3 * buffer's edit mode. 4 * 5 * Copyright (C) 2004-6 Nicholas O'Leary nick.oleary@gmail.com 6 * 7 * :mode=beanshell:tabSize=3:indentSize=3:maxLineLen=0:noTabs=false: 8 * :indentOnTab=true:indentOnEnter=true:folding=explicit:collapseFolds=1: 9 * 10 * {{{ License 11 * This program is free software; you can redistribute it and/or 12 * modify it under the terms of the GNU General Public License 13 * as published by the Free Software Foundation; either version 2 14 * of the License, or any later version. 15 * 16 * This program is distributed in the hope that it will be useful, 17 * but WITHOUT ANY WARRANTY; without even the implied warranty of 18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 19 * GNU General Public License for more details. 20 * 21 * You should have received a copy of the GNU General Public License 22 * along with the jEdit program; if not, write to the Free Software 23 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 24 * }}} 25 * 26 * Notes: 27 * There are two other ways to change the buffers mode: 28 * - enter 'buffer.mode=[mode]' in the action bar 29 * - change it in the Buffer Options dialog 30 * Whilst both of these do the job, I wanted a way to achieve it with minimum 31 * effort, and keypresses. 32 * It also has the benefit of auto-completion of mode names. 33 * 34 * $Id: Mode_Switcher.bsh 21353 2012-03-14 09:46:51Z jojaba_67 $ 35 */ 36 37import javax.swing.border.EmptyBorder; 38 39//Localization 40final static String MainDialogTitle = jEdit.getProperty("macro.rs.BufferModeSwitcher.MainDialog.title", "Buffer Mode Switcher"); 41final static String EnterBufferModeLabel = jEdit.getProperty("macro.rs.BufferModeSwitcher.EnterBufferMode.label", "Enter buffer mode:"); 42final static String ChangingBufferModeLabel = jEdit.getProperty("macro.rs.BufferModeSwitcher.ChangingBufferMode.label", "Changing mode of buffer"); 43final static String ToLabel = jEdit.getProperty("macro.rs.BufferModeSwitcher.To.label", "to"); 44final static String ModeLabel = jEdit.getProperty("macro.rs.BufferModeSwitcher.Mode.label", "Mode"); 45final static String NotFoundLabel = jEdit.getProperty("macro.rs.BufferModeSwitcher.NotFound.label", "Not found"); 46 47//class ModeSwitcherTextField extends JTextField 48void modeSwitcher() { 49 JDialog dialog = new JDialog(view, MainDialogTitle, true); 50 dialog.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE); 51 JPanel content = new JPanel(new BorderLayout()); 52 content.setBorder(new EmptyBorder(12,12,12,12)); 53 Mode[] modes = jEdit.getModes(); 54 String[] names = new String[modes.length]; 55 for(int i=0;i<modes.length;i++) { 56 names[i] = modes[i].getName(); 57 } 58 Arrays.sort(names); 59 JTextField textfield = new JTextField() { 60 protected String[] names; 61 protected boolean shifted = false; 62 //{{{ setNames 63 public void setNames(String[] a){ 64 names = a; 65 } //}}} 66 public boolean getFocusTraversalKeysEnabled(){return false;} 67 //{{{ processKeyEvent 68 protected void processKeyEvent(KeyEvent evt) 69 { 70 if (evt.getID() == KeyEvent.KEY_RELEASED) { 71 if (evt.getKeyCode() == KeyEvent.VK_SHIFT) { 72 shifted = false; 73 } 74 } else if(evt.getID() == KeyEvent.KEY_PRESSED) { 75 if (evt.getKeyCode() == KeyEvent.VK_SHIFT) { 76 shifted = true; 77 } else if(evt.getKeyCode() == KeyEvent.VK_TAB) { 78 // Get the current text 79 String txt = getText(); 80 String original = txt; 81 // See if some text is selected 82 if (getSelectedText() != null) 83 txt = txt.substring(0,txt.length()-getSelectedText().length()); 84 // txt represents the unhighlighted text in the box. This is used 85 // to find further matches. 86 87 // See if the current text is a known mode 88 int index = Arrays.binarySearch(names,original); 89 if (index < 0) index = 0; 90 int indexStep = 1; 91 if (shifted) indexStep = -1; 92 index+=indexStep; 93 if (index == names.length) index = 0; 94 if (index < 0) index = names.length-1; 95 int match = -1; 96 boolean foundExact = false; 97 boolean keepLooping = true; 98 // Loop through modes, starting at current+1 99 int i = index; 100 while(keepLooping) { 101 // Skip if the mode name is shorter than the current text 102 if (names[i].length()>=txt.length()) 103 { 104 // If the mode matches, escape 105 if (names[i].substring(0,txt.length()).equals(txt)) { 106 match = i; 107 break; 108 } 109 } 110 // Loop the loop 111 i+=indexStep; 112 if (i == names.length) i = 0; 113 if (i < 0) i = names.length-1; 114 if (i==index) break; 115 } 116 // If a match has been found... 117 if (match >= 0) { 118 setText(names[match]); 119 setSelectionStart(txt.length()); 120 setSelectionEnd(names[match].length()); 121 } 122 return; 123 } 124 } 125 super.processKeyEvent(evt); 126 } //}}} 127 }; 128 129 textfield.setColumns(20); 130 textfield.setNames(names); 131 Mode m = buffer.getMode(); 132 // Set the inital text to the current mode, and highlight it, so a key 133 // press will clear the entry. 134 if (m != null) { 135 textfield.setText(m.getName()); 136 textfield.setSelectionStart(0); 137 textfield.setSelectionEnd(m.getName().length()); 138 } 139 content.add(new JLabel(EnterBufferModeLabel), BorderLayout.NORTH); 140 content.add(textfield, BorderLayout.CENTER); 141 Vector v = new Vector(); 142 143 // KeyListener Interface 144 //{{{ keyPressed 145 void keyPressed(evt) 146 { 147 if(evt.getKeyCode() == KeyEvent.VK_ESCAPE) 148 dialog.dispose(); 149 else if(evt.getKeyCode() == KeyEvent.VK_ENTER) 150 { 151 Mode m = jEdit.getMode(textfield.getText()); 152 if (m!=null) 153 { 154 buffer.setMode(m); 155 Log.log(Log.NOTICE, 156 BeanShell.class, 157 ChangingBufferModeLabel+" ["+ 158 buffer.getName()+"] "+ToLabel+" ["+ 159 m.getName()+"]"); 160 } else { 161 Log.log(Log.WARNING, 162 BeanShell.class, 163 ModeLabel+" ["+textfield.getText()+"] "+NotFoundLabel); 164 } 165 evt.consume(); 166 dialog.dispose(); 167 } 168 }//}}} 169 void keyReleased(evt) {} 170 void keyTyped(evt) {} 171 172 dialog.addKeyListener(this); 173 textfield.addKeyListener(this); 174 dialog.setContentPane(content); 175 dialog.pack(); 176 dialog.setLocationRelativeTo(view); 177 textfield.grabFocus(); 178 dialog.setVisible(true); 179} 180 181modeSwitcher(); 182 183/* 184 185Macro index data (in DocBook format) 186 187 <listitem> 188 <para><filename>Mode_Switcher.bsh</filename></para> 189 Displays a modal dialog with the current buffer's mode in a text field, 190 allowing one to change the mode by typing in its name. 191 <keycap>ENTER</keycap> selects the current mode; if the text is not a 192 valid mode, the dialog still dismisses, but a warning is logged to the 193 activity log. 194 <keycap>ESACPE</keycap> closes the dialog with no further action. 195 <keycap>TAB</keycap> attempts to auto-complete the mode name. Pressing 196 <keycap>TAB</keycap> repeatedly cycles through the possible completions. 197 <keycap>SHIFT-TAB</keycap> cycles through the completions in reverse. 198 </para></abstract> 199 </listitem> 200 201*/ 202