PageRenderTime 45ms CodeModel.GetById 23ms RepoModel.GetById 0ms app.codeStats 1ms

/bundles/plugins-trunk/RubyPlugin/src/org/jedit/ruby/RubyPlugin.java

#
Java | 301 lines | 231 code | 45 blank | 25 comment | 49 complexity | e6ab3ec45e20a5162f698431d6132737 MD5 | raw file
Possible License(s): BSD-3-Clause, AGPL-1.0, Apache-2.0, LGPL-2.0, LGPL-3.0, GPL-2.0, CC-BY-SA-3.0, LGPL-2.1, GPL-3.0, MPL-2.0-no-copyleft-exception, IPL-1.0
  1. /*
  2. * RubyPlugin.java - Ruby editor plugin for jEdit
  3. *
  4. * Copyright 2005 Robert McKinnon
  5. *
  6. * This program is free software; you can redistribute it and/or
  7. * modify it under the terms of the GNU General Public License
  8. * as published by the Free Software Foundation; either version 2
  9. * of the License, or any later version.
  10. *
  11. * This program is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. * GNU General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU General Public License
  17. * along with this program; if not, write to the Free Software
  18. * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  19. */
  20. package org.jedit.ruby;
  21. import org.gjt.sp.jedit.*;
  22. import org.gjt.sp.jedit.msg.ViewUpdate;
  23. import org.gjt.sp.jedit.msg.EditPaneUpdate;
  24. import org.gjt.sp.jedit.msg.BufferUpdate;
  25. import org.gjt.sp.jedit.msg.PropertiesChanged;
  26. import org.gjt.sp.jedit.textarea.JEditTextArea;
  27. import org.gjt.sp.util.Log;
  28. import org.jedit.ruby.parser.JRubyParser;
  29. import org.jedit.ruby.ri.RiParser;
  30. import org.jedit.ruby.completion.RubyKeyBindings;
  31. import org.jedit.ruby.structure.RubyStructureMatcher;
  32. import org.jedit.ruby.structure.BufferChangeHandler;
  33. import org.jedit.ruby.utils.CharCaretListener;
  34. import org.jedit.ruby.utils.EditorView;
  35. import org.jedit.ruby.utils.ViewWrapper;
  36. import org.jedit.ruby.utils.CommandUtils;
  37. import javax.swing.*;
  38. import java.awt.*;
  39. import java.awt.event.KeyEvent;
  40. import java.io.*;
  41. import java.util.Map;
  42. import java.util.HashMap;
  43. /**
  44. * @author robmckinnon at users,sourceforge,net
  45. */
  46. public final class RubyPlugin extends EBPlugin {
  47. private static final boolean debug = System.getProperty("user.home").equals("/Users/x");
  48. private static final CharCaretListener CHAR_CARET_LISTENER = new CharCaretListener();
  49. private static final Map<View, EditorView> views = new HashMap<View, EditorView>();
  50. public final void start() {
  51. super.start();
  52. JRubyParser.setExpectedLabel(jEdit.getProperty("ruby.syntax-error.expected.label"));
  53. JRubyParser.setFoundLabel(jEdit.getProperty("ruby.syntax-error.found.label"));
  54. JRubyParser.setNothingLabel(jEdit.getProperty("ruby.syntax-error.nothing.label"));
  55. RiParser.parseRdoc();
  56. View view = jEdit.getFirstView();
  57. while (view != null) {
  58. EditPane[] panes = view.getEditPanes();
  59. for (EditPane pane : panes) {
  60. addKeyListener(pane.getTextArea());
  61. }
  62. view = view.getNext();
  63. }
  64. }
  65. public void handleMessage(EBMessage message) {
  66. if (message instanceof ViewUpdate) {
  67. handleViewUpdate((ViewUpdate)message);
  68. } else if (message instanceof EditPaneUpdate) {
  69. handleEditUpdate((EditPaneUpdate)message);
  70. } else if (message instanceof BufferUpdate) {
  71. handleBufferUpdate((BufferUpdate)message);
  72. } else if (message instanceof PropertiesChanged) {
  73. // SideKickActions.propertiesChanged();
  74. }
  75. }
  76. private static void handleViewUpdate(ViewUpdate update) {
  77. if (ViewUpdate.CREATED == update.getWhat()) {
  78. //
  79. } else if (ViewUpdate.CLOSED == update.getWhat()) {
  80. views.remove(update.getView());
  81. }
  82. }
  83. private static void handleBufferUpdate(BufferUpdate update) {
  84. if (BufferUpdate.LOADED == update.getWhat()) {
  85. update.getBuffer().addBufferListener(BufferChangeHandler.instance());
  86. } if (BufferUpdate.CLOSED == update.getWhat()) {
  87. update.getBuffer().addBufferListener(BufferChangeHandler.instance());
  88. }
  89. }
  90. private void handleEditUpdate(EditPaneUpdate update) {
  91. JEditTextArea textArea = update.getEditPane().getTextArea();
  92. if (EditPaneUpdate.CREATED == update.getWhat()) {
  93. addKeyListener(textArea);
  94. } else if (EditPaneUpdate.DESTROYED == update.getWhat()) {
  95. removeKeyListener(textArea);
  96. }
  97. }
  98. private static void addKeyListener(JEditTextArea textArea) {
  99. RubyKeyBindings bindings = new RubyKeyBindings(textArea);
  100. RubyStructureMatcher structureMatcher = new RubyStructureMatcher();
  101. textArea.putClientProperty(RubyKeyBindings.class, bindings);
  102. textArea.putClientProperty(RubyStructureMatcher.class, structureMatcher);
  103. textArea.addKeyListener(bindings);
  104. textArea.addStructureMatcher(structureMatcher);
  105. textArea.addCaretListener(CHAR_CARET_LISTENER);
  106. }
  107. private static void removeKeyListener(JEditTextArea textArea) {
  108. RubyKeyBindings bindings = (RubyKeyBindings)textArea.getClientProperty(RubyKeyBindings.class);
  109. RubyStructureMatcher structureMatcher = (RubyStructureMatcher)textArea.getClientProperty(RubyStructureMatcher.class);
  110. textArea.putClientProperty(RubyKeyBindings.class, null);
  111. textArea.putClientProperty(RubyStructureMatcher.class, null);
  112. textArea.removeKeyListener(bindings);
  113. textArea.removeStructureMatcher(structureMatcher);
  114. textArea.removeCaretListener(CHAR_CARET_LISTENER);
  115. }
  116. public static void log(String message, Class clas) {
  117. if (debug) {
  118. try {
  119. Log.log(Log.MESSAGE, clas, message);
  120. } catch (Exception e) {
  121. System.out.println(message);
  122. }
  123. }
  124. }
  125. public static void error(Exception e, Class clas) {
  126. String message = e.getClass().getName();
  127. message = message.substring(message.lastIndexOf('.') + 1);
  128. if (e.getMessage() != null && e.getMessage().length() > 0) {
  129. message += ": " + e.getMessage();
  130. }
  131. e.printStackTrace();
  132. error(message, clas);
  133. }
  134. public static EditorView getActiveView() {
  135. final View view = jEdit.getActiveView();
  136. if (!views.containsKey(view)) {
  137. EditorView editorView = view != null ? new ViewWrapper(view) : EditorView.NULL;
  138. views.put(view, editorView);
  139. }
  140. return views.get(view);
  141. }
  142. public static void error(String message, Class clas) {
  143. try {
  144. Log.log(Log.ERROR, clas, message);
  145. View view = jEdit.getActiveView();
  146. if (view != null) {
  147. if (debug) {
  148. show("", message, view, JOptionPane.ERROR_MESSAGE);
  149. }
  150. }
  151. } catch (Exception e) {
  152. System.err.println(message);
  153. }
  154. }
  155. public static int getNonSpaceStartOffset(int line) {
  156. return getActiveView().getNonSpaceStartOffset(line);
  157. }
  158. public static int getEndOffset(int line) {
  159. return getActiveView().getEndOffset(line);
  160. }
  161. public static int getStartOffset(int line) {
  162. return getActiveView().getStartOffset(line);
  163. }
  164. public static int getEndOfFileOffset() {
  165. return getActiveView().getEndOfFileOffset();
  166. }
  167. public static String readFile(File file) {
  168. StringBuffer buffer = new StringBuffer();
  169. try {
  170. BufferedReader bufferedReader = new BufferedReader(new FileReader(file));
  171. try {
  172. char[] chars = new char[1024];
  173. int length;
  174. while (-1 != (length = bufferedReader.read(chars))) {
  175. buffer.append(chars, 0, length);
  176. }
  177. } catch (IOException e) {
  178. error(e, RubyPlugin.class);
  179. }
  180. } catch (FileNotFoundException e) {
  181. error(e, RubyPlugin.class);
  182. }
  183. return buffer.toString();
  184. }
  185. public static Point getCaretPopupLocation(View view) {
  186. JEditTextArea textArea = view.getTextArea();
  187. textArea.scrollToCaret(false);
  188. Point location = textArea.offsetToXY(textArea.getCaretPosition());
  189. location.y += textArea.getPainter().getFontMetrics().getHeight();
  190. SwingUtilities.convertPointToScreen(location, textArea.getPainter());
  191. return location;
  192. }
  193. public static Point getCenteredPopupLocation(View view) {
  194. JEditTextArea textArea = view.getTextArea();
  195. textArea.scrollToCaret(false);
  196. return new Point(textArea.getSize().width / 3, textArea.getSize().height / 5);
  197. }
  198. public static boolean isRuby(org.gjt.sp.jedit.textarea.TextArea textArea) {
  199. return isRuby(CommandUtils.getBuffer(textArea));
  200. }
  201. private static boolean isRuby(Object buffer) {
  202. if (buffer instanceof Buffer) {
  203. return isRuby((Buffer)buffer);
  204. } else {
  205. throw new IllegalArgumentException("expecting buffer to be of type Buffer");
  206. }
  207. }
  208. public static boolean isRuby(Buffer buffer) {
  209. boolean isRubyBuffer = buffer.getMode() == rubyMode();
  210. return isRubyBuffer || isRuby(new File(buffer.getPath()));
  211. }
  212. public static boolean isRuby(File file) {
  213. return file.isFile() && rubyMode().accept(file.getPath(), "");
  214. }
  215. private static Mode rubyMode() {
  216. return jEdit.getMode("ruby");
  217. }
  218. public static void showMessage(String titleKey, String messageKey, View view) {
  219. String title = titleKey == null ? null : jEdit.getProperty(titleKey);
  220. String message = jEdit.getProperty(messageKey);
  221. show(title, message, view, JOptionPane.INFORMATION_MESSAGE);
  222. }
  223. public static void showMessage(String messageKey, View view) {
  224. showMessage(null, messageKey, view);
  225. }
  226. private static void show(String title, String message, View view, int type) {
  227. GUIUtilities.hideSplashScreen();
  228. JOptionPane.showMessageDialog(view, message, title, type);
  229. }
  230. public static boolean ignoreKeyTyped(int keyCode, char keyChar, KeyEvent event) {
  231. boolean ignore;
  232. switch (keyCode) {
  233. case KeyEvent.VK_ENTER:
  234. case KeyEvent.VK_ESCAPE:
  235. case KeyEvent.VK_UP:
  236. case KeyEvent.VK_DOWN:
  237. case KeyEvent.VK_PAGE_UP:
  238. case KeyEvent.VK_PAGE_DOWN:
  239. case KeyEvent.VK_HOME:
  240. case KeyEvent.VK_END:
  241. case KeyEvent.VK_LEFT:
  242. case KeyEvent.VK_RIGHT:
  243. ignore = true;
  244. break;
  245. default:
  246. // for some reason have to match backspace and tab using keyChar
  247. ignore = keyChar == KeyEvent.VK_BACK_SPACE
  248. || keyChar == KeyEvent.VK_TAB
  249. || event.isActionKey()
  250. || event.isControlDown()
  251. || event.isAltDown()
  252. || event.isMetaDown();
  253. }
  254. return ignore;
  255. }
  256. }