[sikuli] 210/385: some refactoring and first fixes to allow other scripting languages in IDE

Gilles Filippini pini at moszumanska.debian.org
Sun Jun 29 19:26:14 UTC 2014


This is an automated email from the git hooks/post-receive script.

pini pushed a commit to tag upstream/1.1.0_beta1
in repository sikuli.

commit d3bba27f3f55ff565fa6b292056c4b1576a1d700
Author: Raimund Hocke <info at its-me-raiman.de>
Date:   Fri Feb 14 07:35:19 2014 +0100

    some refactoring and first fixes to allow other scripting languages in IDE
---
 .../main/java/org/sikuli/basics/IDESupport.java    |    5 +
 .../java/org/sikuli/basics/IndentationLogic.java   |   31 +
 IDE/src/main/java/org/sikuli/ide/EditorKit.java    | 1078 ++++++++++----------
 IDE/src/main/java/org/sikuli/ide/EditorPane.java   |   70 +-
 .../java/org/sikuli/ide/EditorViewFactory.java     |    6 +
 IDE/src/main/java/org/sikuli/ide/SikuliIDE.java    |    5 +-
 .../org/sikuli/idesupport/JRubyIDESupport.java     |   16 +
 .../src/main/java/org/sikuli/jruby/IDESupport.java |   14 -
 .../org/sikuli/idesupport/JythonIDESupport.java    |   20 +
 .../{jython => idesupport}/PythonIndentation.java  |    6 +-
 .../sikuli/{jython => idesupport}/PythonState.java |    2 +-
 .../main/java/org/sikuli/jython/IDESupport.java    |   14 -
 12 files changed, 675 insertions(+), 592 deletions(-)

diff --git a/Basics/src/main/java/org/sikuli/basics/IDESupport.java b/Basics/src/main/java/org/sikuli/basics/IDESupport.java
new file mode 100644
index 0000000..c655b48
--- /dev/null
+++ b/Basics/src/main/java/org/sikuli/basics/IDESupport.java
@@ -0,0 +1,5 @@
+package org.sikuli.basics;
+
+public interface IDESupport {
+
+}
diff --git a/Basics/src/main/java/org/sikuli/basics/IndentationLogic.java b/Basics/src/main/java/org/sikuli/basics/IndentationLogic.java
new file mode 100644
index 0000000..a9f8a23
--- /dev/null
+++ b/Basics/src/main/java/org/sikuli/basics/IndentationLogic.java
@@ -0,0 +1,31 @@
+/*
+ * To change this license header, choose License Headers in Project Properties.
+ * To change this template file, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package org.sikuli.basics;
+
+/**
+ *
+ * @author rhocke
+ */
+public interface IndentationLogic {
+
+	public void setTabWidth(int tabwidth);
+
+	public int checkDedent(String leadingWhitespace, int line);
+
+	public void checkIndent(String leadingWhitespace, int line);
+
+	public boolean shouldAddColon();
+
+	public void setLastLineEndsWithColon();
+
+	public int shouldChangeLastLineIndentation();
+
+	public int shouldChangeNextLineIndentation();
+
+	public void reset();
+
+	public void addText(String text);
+}
diff --git a/IDE/src/main/java/org/sikuli/ide/EditorKit.java b/IDE/src/main/java/org/sikuli/ide/EditorKit.java
index 22bbe1a..8cafded 100755
--- a/IDE/src/main/java/org/sikuli/ide/EditorKit.java
+++ b/IDE/src/main/java/org/sikuli/ide/EditorKit.java
@@ -13,549 +13,565 @@ import java.io.*;
 import java.util.Map;
 import javax.swing.*;
 import javax.swing.text.*;
-import org.sikuli.jython.PythonIndentation;
+import org.sikuli.idesupport.PythonIndentation;
 import org.sikuli.basics.Debug;
+import org.sikuli.basics.IndentationLogic;
 
 public class EditorKit extends StyledEditorKit {
 
-  private static final String me = "EditorKit: ";
-  private ViewFactory _viewFactory;
-
-  public EditorKit() {
-    _viewFactory = new EditorViewFactory();
-  }
-  public static final String deIndentAction = "SKL.DeindentAction";
-  private static final TextAction[] defaultActions = {
-    new InsertTabAction(),
-    new DeindentAction(),
-    new InsertBreakAction(),
-    new NextVisualPositionAction(forwardAction, false, SwingConstants.EAST),
-    new NextVisualPositionAction(backwardAction, false, SwingConstants.WEST),
-    new NextVisualPositionAction(selectionForwardAction, true, SwingConstants.EAST),
-    new NextVisualPositionAction(selectionBackwardAction, true, SwingConstants.WEST),
-    new NextVisualPositionAction(upAction, false, SwingConstants.NORTH),
-    new NextVisualPositionAction(downAction, false, SwingConstants.SOUTH),
-    new NextVisualPositionAction(selectionUpAction, true, SwingConstants.NORTH),
-    new NextVisualPositionAction(selectionDownAction, true, SwingConstants.SOUTH),};
-
-  public static class InsertTabAction extends TextAction {
-
-    private  PythonIndentation indentationLogic;
-
-    public InsertTabAction() {
-      super(insertTabAction);
-    }
-
-    public InsertTabAction(String name) {
-      super(name);
-    }
-
-    @Override
-    public void actionPerformed(ActionEvent e) {
-      Debug.log(5, "InsertTabAction " + e);
-      JTextComponent text = (JTextComponent) e.getSource();
-      actionPerformed(text);
-    }
-
-    public void actionPerformed(JTextComponent text) {
-      indentationLogic = ((EditorPane) text).getIndentationLogic();
-      boolean indentError = false;
-      Document doc = text.getDocument();
-      Element map = doc.getDefaultRootElement();
-      String tabWhitespace = PreferencesUser.getInstance().getTabWhitespace();
-      Caret c = text.getCaret();
-      int dot = c.getDot();
-      int mark = c.getMark();
-      int dotLine = map.getElementIndex(dot);
-      int markLine = map.getElementIndex(mark);
-
-      if (dotLine != markLine) {
-        int first = Math.min(dotLine, markLine);
-        int last = Math.max(dotLine, markLine);
-        Element elem;
-        int start;
-        try {
-          for (int i = first; i < last; i++) {
-            elem = map.getElement(i);
-            start = elem.getStartOffset();
-            doc.insertString(start, tabWhitespace, null);
-          }
-          elem = map.getElement(last);
-          start = elem.getStartOffset();
-          if (Math.max(c.getDot(), c.getMark()) != start) {
-            doc.insertString(start, tabWhitespace, null);
-          }
-        } catch (BadLocationException ble) {
-           Debug.error(me + "Problem while indenting line\n%s", ble.getMessage());
-           UIManager.getLookAndFeel().provideErrorFeedback(text);
-        }
-      } else {
-        text.replaceSelection(tabWhitespace);
-      }
-    }
-  }
-
-  public static class DeindentAction extends TextAction {
+	private static final String me = "EditorKit: ";
+	private ViewFactory _viewFactory;
+	private EditorPane pane;
+
+	public EditorKit(EditorPane p) {
+		_viewFactory = new EditorViewFactory();
+		pane = p;
+	}
+	public static final String deIndentAction = "SKL.DeindentAction";
+	private static final TextAction[] defaultActions = {
+		new InsertTabAction(),
+		new DeindentAction(),
+		new InsertBreakAction(),
+		new NextVisualPositionAction(forwardAction, false, SwingConstants.EAST),
+		new NextVisualPositionAction(backwardAction, false, SwingConstants.WEST),
+		new NextVisualPositionAction(selectionForwardAction, true, SwingConstants.EAST),
+		new NextVisualPositionAction(selectionBackwardAction, true, SwingConstants.WEST),
+		new NextVisualPositionAction(upAction, false, SwingConstants.NORTH),
+		new NextVisualPositionAction(downAction, false, SwingConstants.SOUTH),
+		new NextVisualPositionAction(selectionUpAction, true, SwingConstants.NORTH),
+		new NextVisualPositionAction(selectionDownAction, true, SwingConstants.SOUTH),};
+
+
+	public static class InsertTabAction extends TextAction {
+
+		private IndentationLogic indentationLogic;
+
+		public InsertTabAction() {
+			super(insertTabAction);
+		}
+
+		public InsertTabAction(String name) {
+			super(name);
+		}
+
+		@Override
+		public void actionPerformed(ActionEvent e) {
+			Debug.log(5, "InsertTabAction " + e);
+			JTextComponent text = (JTextComponent) e.getSource();
+			actionPerformed(text);
+		}
+
+		public void actionPerformed(JTextComponent text) {
+			indentationLogic = ((EditorPane) text).getIndentationLogic();
+			if (indentationLogic == null) {
+				return;
+			}
+			boolean indentError = false;
+			Document doc = text.getDocument();
+			Element map = doc.getDefaultRootElement();
+			String tabWhitespace = PreferencesUser.getInstance().getTabWhitespace();
+			Caret c = text.getCaret();
+			int dot = c.getDot();
+			int mark = c.getMark();
+			int dotLine = map.getElementIndex(dot);
+			int markLine = map.getElementIndex(mark);
+
+			if (dotLine != markLine) {
+				int first = Math.min(dotLine, markLine);
+				int last = Math.max(dotLine, markLine);
+				Element elem;
+				int start;
+				try {
+					for (int i = first; i < last; i++) {
+						elem = map.getElement(i);
+						start = elem.getStartOffset();
+						doc.insertString(start, tabWhitespace, null);
+					}
+					elem = map.getElement(last);
+					start = elem.getStartOffset();
+					if (Math.max(c.getDot(), c.getMark()) != start) {
+						doc.insertString(start, tabWhitespace, null);
+					}
+				} catch (BadLocationException ble) {
+					Debug.error(me + "Problem while indenting line\n%s", ble.getMessage());
+					UIManager.getLookAndFeel().provideErrorFeedback(text);
+				}
+			} else {
+				text.replaceSelection(tabWhitespace);
+			}
+		}
+	}
+
+	public static class DeindentAction extends TextAction {
 //TODO dedent not working consistently on last line (no last empty line)
 
-    private Segment segLine;
-    private  PythonIndentation indentationLogic;
-
-    public DeindentAction() {
-      this(deIndentAction);
-    }
-
-    public DeindentAction(String name) {
-      super(name);
-      segLine = new Segment();
-    }
-
-    @Override
-    public void actionPerformed(ActionEvent e) {
-      Debug.log(5, "DedentAction " + e);
-      JTextComponent text = (JTextComponent) e.getSource();
-      actionPerformed(text);
-    }
-
-    public void actionPerformed(JTextComponent text) {
-      indentationLogic = ((EditorPane) text).getIndentationLogic();
-      StyledDocument doc = (StyledDocument) text.getDocument();
-      Element map = doc.getDefaultRootElement();
-      Caret c = text.getCaret();
-      int dot = c.getDot();
-      int mark = c.getMark();
-      int line1 = map.getElementIndex(dot);
-
-      if (dot != mark) {
-        int line2 = map.getElementIndex(mark);
-        int begin = Math.min(line1, line2);
-        int end = Math.max(line1, line2);
-        Element elem;
-        try {
-          for (line1 = begin; line1 < end; line1++) {
-            elem = map.getElement(line1);
-            handleDecreaseIndent(line1, elem, doc);
-          }
-          elem = map.getElement(end);
-          int start = elem.getStartOffset();
-          if (Math.max(c.getDot(), c.getMark()) != start) {
-            handleDecreaseIndent(end, elem, doc);
-          }
-        } catch (BadLocationException ble) {
-          Debug.error(me + "Problem while de-indenting line\n%s", ble.getMessage());
-          UIManager.getLookAndFeel().provideErrorFeedback(text);
-        }
-      } else {
-        Element elem = map.getElement(line1);
-        try {
-          handleDecreaseIndent(line1, elem, doc);
-        } catch (BadLocationException ble) {
-          Debug.error(me + "Problem while de-indenting line\n%s", ble.getMessage());
-          UIManager.getLookAndFeel().provideErrorFeedback(text);
-        }
-      }
-
-    }
-
-    private void handleDecreaseIndent(int line, Element elem, StyledDocument doc)
-            throws BadLocationException {
-      int start = elem.getStartOffset();
-      int end = elem.getEndOffset() - 1;
-      doc.getText(start, end - start, segLine);
-      int i = segLine.offset;
-      end = i + segLine.count;
-      if (end > i) {
-        String leadingWS = PythonIndentation.getLeadingWhitespace(doc, start, end - start);
-        int toRemove = indentationLogic.checkDedent(leadingWS, line+1);
-        doc.remove(start, toRemove);
-      }
-    }
-  }
-
-  public static class InsertBreakAction extends TextAction {
-
-    private  PythonIndentation indentationLogic;
-
-    public InsertBreakAction() {
-      super(insertBreakAction);
-    }
-
-    public InsertBreakAction(String name) {
-      super(name);
-    }
-
-    @Override
-    public void actionPerformed(ActionEvent e) {
-      Debug.log(5, "InsertBreakAction " + e);
-      JTextComponent text = (JTextComponent) e.getSource();
-      insertBreak(text);
-    }
-
-    public void insertBreak(JTextComponent text) {
-      indentationLogic = ((EditorPane) text).getIndentationLogic();
-      boolean noSelection = text.getSelectionStart() == text.getSelectionEnd();
-      if (noSelection) {
-        insertNewlineWithAutoIndent(text);
-      } else {
-        text.replaceSelection("\n");
+		private IndentationLogic indentationLogic;
+		private Segment segLine;
+
+		public DeindentAction() {
+			this(deIndentAction);
+		}
+
+		public DeindentAction(String name) {
+			super(name);
+			segLine = new Segment();
+		}
+
+		@Override
+		public void actionPerformed(ActionEvent e) {
+			Debug.log(5, "DedentAction " + e);
+			JTextComponent text = (JTextComponent) e.getSource();
+			actionPerformed(text);
+		}
+
+		public void actionPerformed(JTextComponent text) {
+			indentationLogic = ((EditorPane) text).getIndentationLogic();
+			if (indentationLogic == null) {
+				return;
+			}
+			StyledDocument doc = (StyledDocument) text.getDocument();
+			Element map = doc.getDefaultRootElement();
+			Caret c = text.getCaret();
+			int dot = c.getDot();
+			int mark = c.getMark();
+			int line1 = map.getElementIndex(dot);
+
+			if (dot != mark) {
+				int line2 = map.getElementIndex(mark);
+				int begin = Math.min(line1, line2);
+				int end = Math.max(line1, line2);
+				Element elem;
+				try {
+					for (line1 = begin; line1 < end; line1++) {
+						elem = map.getElement(line1);
+						handleDecreaseIndent(line1, elem, doc);
+					}
+					elem = map.getElement(end);
+					int start = elem.getStartOffset();
+					if (Math.max(c.getDot(), c.getMark()) != start) {
+						handleDecreaseIndent(end, elem, doc);
+					}
+				} catch (BadLocationException ble) {
+					Debug.error(me + "Problem while de-indenting line\n%s", ble.getMessage());
+					UIManager.getLookAndFeel().provideErrorFeedback(text);
+				}
+			} else {
+				Element elem = map.getElement(line1);
+				try {
+					handleDecreaseIndent(line1, elem, doc);
+				} catch (BadLocationException ble) {
+					Debug.error(me + "Problem while de-indenting line\n%s", ble.getMessage());
+					UIManager.getLookAndFeel().provideErrorFeedback(text);
+				}
+			}
+
+		}
+
+		private void handleDecreaseIndent(int line, Element elem, StyledDocument doc)
+						throws BadLocationException {
+			int start = elem.getStartOffset();
+			int end = elem.getEndOffset() - 1;
+			doc.getText(start, end - start, segLine);
+			int i = segLine.offset;
+			end = i + segLine.count;
+			if (end > i) {
+				String leadingWS = PythonIndentation.getLeadingWhitespace(doc, start, end - start);
+				int toRemove = indentationLogic.checkDedent(leadingWS, line + 1);
+				doc.remove(start, toRemove);
+			}
+		}
+	}
+
+	public static class InsertBreakAction extends TextAction {
+
+		private IndentationLogic indentationLogic;
+
+		public InsertBreakAction() {
+			super(insertBreakAction);
+		}
+
+		public InsertBreakAction(String name) {
+			super(name);
+		}
+
+		@Override
+		public void actionPerformed(ActionEvent e) {
+			Debug.log(5, "InsertBreakAction " + e);
+			JTextComponent text = (JTextComponent) e.getSource();
+			insertBreak(text);
+		}
+
+		public void insertBreak(JTextComponent text) {
+			boolean noSelection = text.getSelectionStart() == text.getSelectionEnd();
+			if (noSelection) {
+				insertNewlineWithAutoIndent(text);
+			} else {
+				text.replaceSelection("\n");
 //TODO insertNewlineWithAutoIndent
-      }
-    }
-
-    private void insertNewlineWithAutoIndent(JTextComponent text) {
-      try {
-        int caretPos = text.getCaretPosition();
-        StyledDocument doc = (StyledDocument) text.getDocument();
-        Element map = doc.getDefaultRootElement();
-        int lineNum = map.getElementIndex(caretPos);
-        Element line = map.getElement(lineNum);
-        int start = line.getStartOffset();
-        int end = line.getEndOffset() - 1;
-        int len = end - start;
-        String s = doc.getText(start, len);
-
-        String leadingWS = PythonIndentation.getLeadingWhitespace(doc, start, caretPos - start);
-        StringBuffer sb = new StringBuffer("\n");
-        sb.append(leadingWS);
+			}
+		}
+
+		private void insertNewlineWithAutoIndent(JTextComponent text) {
+			indentationLogic = ((EditorPane) text).getIndentationLogic();
+			if (indentationLogic == null) {
+				text.replaceSelection("\n");
+				return;
+			}
+			try {
+				int caretPos = text.getCaretPosition();
+				StyledDocument doc = (StyledDocument) text.getDocument();
+				Element map = doc.getDefaultRootElement();
+				int lineNum = map.getElementIndex(caretPos);
+				Element line = map.getElement(lineNum);
+				int start = line.getStartOffset();
+				int end = line.getEndOffset() - 1;
+				int len = end - start;
+				String s = doc.getText(start, len);
+				StringBuilder sb = new StringBuilder("\n");
+
+				String leadingWS = PythonIndentation.getLeadingWhitespace(doc, start, caretPos - start);
+				sb.append(leadingWS);
 //TODO better control over automatic indentation
-        indentationLogic.checkIndent(leadingWS, lineNum+1);
-
-        // If there is only whitespace between the caret and
-        // the EOL, pressing Enter auto-indents the new line to
-        // the same place as the previous line.
-        int nonWhitespacePos = PythonIndentation.atEndOfLine(doc, caretPos, start, s, len);
-        if (nonWhitespacePos == -1) {
-          if (leadingWS.length() == len) {
-            // If the line was nothing but whitespace, select it
-            // so its contents get removed.
-            text.setSelectionStart(start);
-          } else {
-            // Select the whitespace between the caret and the EOL
-            // to remove it
-            text.setSelectionStart(caretPos);
-          }
-          text.setSelectionEnd(end);
-          text.replaceSelection(sb.toString());
-          // auto-indentation for python statements like if, while, for, try,
-          // except, def, class and auto-deindentation for break, continue,
-          // pass, return
-          analyseDocument(doc, lineNum, indentationLogic);
-          // auto-completion: add colon if it is obvious
-          if (indentationLogic.shouldAddColon()) {
-            doc.insertString(caretPos, ":", null);
-            indentationLogic.setLastLineEndsWithColon();
-          }
-          int lastLineChange = indentationLogic.shouldChangeLastLineIndentation();
-          int nextLineChange = indentationLogic.shouldChangeNextLineIndentation();
-          if (lastLineChange != 0) {
-            Debug.log(5, "change line %d indentation by %d columns", lineNum + 1,
-                    lastLineChange);
-            changeIndentation((DefaultStyledDocument) doc, lineNum, lastLineChange);
-            // nextLineChange was determined based on indentation of last line before
-            // the change
-            nextLineChange += lastLineChange;
-          }
-          if (nextLineChange != 0) {
-            Debug.log(5, "change line %d indentation by %d columns", lineNum + 2,
-                    nextLineChange);
-            changeIndentation((DefaultStyledDocument) doc, lineNum + 1, nextLineChange);
-          }
-        } // If there is non-whitespace between the caret and the
-        // EOL, pressing Enter takes that text to the next line
-        // and auto-indents it to the same place as the last
-        // line. Additional auto-indentation or dedentation for
-        // specific python statements is only done for the next line.
-        else {
-          text.setCaretPosition(nonWhitespacePos);
-          doc.insertString(nonWhitespacePos, sb.toString(), null);
-          analyseDocument(doc, lineNum, indentationLogic);
-          int nextLineChange = indentationLogic.shouldChangeNextLineIndentation();
-          if (nextLineChange != 0) {
-            Debug.log(5, "change line %d indentation by %d columns", lineNum + 2,
-                    nextLineChange);
-            changeIndentation((DefaultStyledDocument) doc, lineNum + 1, nextLineChange);
-          }
-        }
-
-      } catch (BadLocationException ble) {
-        text.replaceSelection("\n");
-        Debug.error(me + "Problem while inserting new line with auto-indent\n%s", ble.getMessage());
-      }
-
-    }
-
-    private void analyseDocument(Document document, int lineNum,
-            PythonIndentation indentationLogic) throws BadLocationException {
-      Element map = document.getDefaultRootElement();
-      int endPos = map.getElement(lineNum).getEndOffset();
-      indentationLogic.reset();
-      indentationLogic.addText(document.getText(0, endPos));
-    }
-
-    /**
-     * Change the indentation of a line. Any existing leading whitespace is replaced by the
-     * appropriate number of tab characters (padded with blank characters if necessary) if tab
-     * expansion in the user preferences is true, or the appropriate number of blank characters if
-     * tab expansion is false.
-     *
-     * @param linenum the line number (0-based)
-     * @param columns the number of columns by which to increase the indentation (if columns is
-     * greater than 0) or decrease the indentation (if columns is less than 0)
-     * @throws BadLocationException if the specified line does not exist
-     */
-    // TODO: make this a method of SikuliDocument, no need to pass document as argument
-    private void changeIndentation(DefaultStyledDocument doc, int linenum,
-            int columns) throws BadLocationException {
-      PreferencesUser pref = PreferencesUser.getInstance();
-      boolean expandTab = pref.getExpandTab();
-      int tabWidth = pref.getTabWidth();
-
-      if (linenum < 0) {
-        throw new BadLocationException("Negative line", -1);
-      }
-      Element map = doc.getDefaultRootElement();
-      if (linenum >= map.getElementCount()) {
-        throw new BadLocationException("No such line", doc.getLength() + 1);
-      }
-      if (columns == 0) {
-        return;
-      }
-
-      Element lineElem = map.getElement(linenum);
-      int lineStart = lineElem.getStartOffset();
-      int lineLength = lineElem.getEndOffset() - lineStart;
-      String line = doc.getText(lineStart, lineLength);
-
-      // determine current indentation and number of whitespace characters
-      int wsChars;
-      int indentation = 0;
-      for (wsChars = 0; wsChars < line.length(); wsChars++) {
-        char c = line.charAt(wsChars);
-        if (c == ' ') {
-          indentation++;
-        } else if (c == '\t') {
-          indentation += tabWidth;
-        } else {
-          break;
-        }
-      }
-
-      int newIndentation = indentation + columns;
-      if (newIndentation <= 0) {
-        doc.remove(lineStart, wsChars);
-        return;
-      }
-
-      // build whitespace string for new indentation
-      StringBuilder newWs = new StringBuilder(newIndentation / tabWidth + tabWidth - 1);
-      int ind = 0;
-      if (!expandTab) {
-        for (; ind + tabWidth <= newIndentation; ind += tabWidth) {
-          newWs.append('\t');
-        }
-      }
-      for (; ind < newIndentation; ind++) {
-        newWs.append(' ');
-      }
-      doc.replace(lineStart, wsChars, newWs.toString(), null);
-    }
-  }
-
-  private static class NextVisualPositionAction extends TextAction {
-
-    private boolean select;
-    private int direction;
-
-    NextVisualPositionAction(String nm, boolean select, int dir) {
+				indentationLogic.checkIndent(leadingWS, lineNum + 1);
+
+				// If there is only whitespace between the caret and
+				// the EOL, pressing Enter auto-indents the new line to
+				// the same place as the previous line.
+				int nonWhitespacePos = PythonIndentation.atEndOfLine(doc, caretPos, start, s, len);
+				if (nonWhitespacePos == -1) {
+					if (leadingWS.length() == len) {
+						// If the line was nothing but whitespace, select it
+						// so its contents get removed.
+						text.setSelectionStart(start);
+					} else {
+						// Select the whitespace between the caret and the EOL
+						// to remove it
+						text.setSelectionStart(caretPos);
+					}
+					text.setSelectionEnd(end);
+					text.replaceSelection(sb.toString());
+					// auto-indentation for python statements like if, while, for, try,
+					// except, def, class and auto-deindentation for break, continue,
+					// pass, return
+					analyseDocument(doc, lineNum, indentationLogic);
+					// auto-completion: add colon if it is obvious
+					if (indentationLogic.shouldAddColon()) {
+						doc.insertString(caretPos, ":", null);
+						indentationLogic.setLastLineEndsWithColon();
+					}
+					int lastLineChange = indentationLogic.shouldChangeLastLineIndentation();
+					int nextLineChange = indentationLogic.shouldChangeNextLineIndentation();
+					if (lastLineChange != 0) {
+						Debug.log(5, "change line %d indentation by %d columns", lineNum + 1,
+										lastLineChange);
+						changeIndentation((DefaultStyledDocument) doc, lineNum, lastLineChange);
+						// nextLineChange was determined based on indentation of last line before
+						// the change
+						nextLineChange += lastLineChange;
+					}
+					if (nextLineChange != 0) {
+						Debug.log(5, "change line %d indentation by %d columns", lineNum + 2,
+										nextLineChange);
+						changeIndentation((DefaultStyledDocument) doc, lineNum + 1, nextLineChange);
+					}
+				} // If there is non-whitespace between the caret and the
+				// EOL, pressing Enter takes that text to the next line
+				// and auto-indents it to the same place as the last
+				// line. Additional auto-indentation or dedentation for
+				// specific python statements is only done for the next line.
+				else {
+					text.setCaretPosition(nonWhitespacePos);
+					doc.insertString(nonWhitespacePos, sb.toString(), null);
+					analyseDocument(doc, lineNum, indentationLogic);
+					int nextLineChange = indentationLogic.shouldChangeNextLineIndentation();
+					if (nextLineChange != 0) {
+						Debug.log(5, "change line %d indentation by %d columns", lineNum + 2,
+										nextLineChange);
+						changeIndentation((DefaultStyledDocument) doc, lineNum + 1, nextLineChange);
+					}
+				}
+
+			} catch (BadLocationException ble) {
+				text.replaceSelection("\n");
+				Debug.error(me + "Problem while inserting new line with auto-indent\n%s", ble.getMessage());
+			}
+
+		}
+
+		private void analyseDocument(Document document, int lineNum,
+						IndentationLogic indentationLogic) throws BadLocationException {
+			Element map = document.getDefaultRootElement();
+			int endPos = map.getElement(lineNum).getEndOffset();
+			indentationLogic.reset();
+			indentationLogic.addText(document.getText(0, endPos));
+		}
+
+		/**
+		 * Change the indentation of a line. Any existing leading whitespace is
+		 * replaced by the appropriate number of tab characters (padded with blank
+		 * characters if necessary) if tab expansion in the user preferences is
+		 * true, or the appropriate number of blank characters if tab expansion is
+		 * false.
+		 *
+		 * @param linenum the line number (0-based)
+		 * @param columns the number of columns by which to increase the indentation
+		 * (if columns is greater than 0) or decrease the indentation (if columns is
+		 * less than 0)
+		 * @throws BadLocationException if the specified line does not exist
+		 */
+		// TODO: make this a method of SikuliDocument, no need to pass document as argument
+		private void changeIndentation(DefaultStyledDocument doc, int linenum,
+						int columns) throws BadLocationException {
+			PreferencesUser pref = PreferencesUser.getInstance();
+			boolean expandTab = pref.getExpandTab();
+			int tabWidth = pref.getTabWidth();
+
+			if (linenum < 0) {
+				throw new BadLocationException("Negative line", -1);
+			}
+			Element map = doc.getDefaultRootElement();
+			if (linenum >= map.getElementCount()) {
+				throw new BadLocationException("No such line", doc.getLength() + 1);
+			}
+			if (columns == 0) {
+				return;
+			}
+
+			Element lineElem = map.getElement(linenum);
+			int lineStart = lineElem.getStartOffset();
+			int lineLength = lineElem.getEndOffset() - lineStart;
+			String line = doc.getText(lineStart, lineLength);
+
+			// determine current indentation and number of whitespace characters
+			int wsChars;
+			int indentation = 0;
+			for (wsChars = 0; wsChars < line.length(); wsChars++) {
+				char c = line.charAt(wsChars);
+				if (c == ' ') {
+					indentation++;
+				} else if (c == '\t') {
+					indentation += tabWidth;
+				} else {
+					break;
+				}
+			}
+
+			int newIndentation = indentation + columns;
+			if (newIndentation <= 0) {
+				doc.remove(lineStart, wsChars);
+				return;
+			}
+
+			// build whitespace string for new indentation
+			StringBuilder newWs = new StringBuilder(newIndentation / tabWidth + tabWidth - 1);
+			int ind = 0;
+			if (!expandTab) {
+				for (; ind + tabWidth <= newIndentation; ind += tabWidth) {
+					newWs.append('\t');
+				}
+			}
+			for (; ind < newIndentation; ind++) {
+				newWs.append(' ');
+			}
+			doc.replace(lineStart, wsChars, newWs.toString(), null);
+		}
+	}
+
+	private static class NextVisualPositionAction extends TextAction {
+
+		private boolean select;
+		private int direction;
+
+		NextVisualPositionAction(String nm, boolean select, int dir) {
 //TODO forward selection space+image - space not selected alone
 //TODO up/down might step left or right
-      super(nm);
-      this.select = select;
-      this.direction = dir;
-    }
-
-    private static int getNSVisualPosition(EditorPane txt, int pos, int direction) {
-      Element root = txt.getDocument().getDefaultRootElement();
-      int numLines = root.getElementIndex(txt.getDocument().getLength() - 1) + 1;
-      int line = root.getElementIndex(pos) + 1;
-      int tarLine = direction == SwingConstants.NORTH ? line - 1 : line + 1;
-      try {
-        if (tarLine <= 0) {
-          return 0;
-        }
-        if (tarLine > numLines) {
-          return txt.getDocument().getLength();
-        }
-
-        Rectangle curRect = txt.modelToView(pos);
-        Rectangle tarEndRect;
-        if (tarLine < numLines) {
-          tarEndRect = txt.modelToView(txt.getLineStartOffset(tarLine) - 1);
-        } else {
-          tarEndRect = txt.modelToView(txt.getDocument().getLength() - 1);
-        }
-        Debug.log(9, "curRect: " + curRect + ", tarEnd: " + tarEndRect);
-
-        if (curRect.x > tarEndRect.x) {
-          pos = txt.viewToModel(new Point(tarEndRect.x, tarEndRect.y));
-        } else {
-          pos = txt.viewToModel(new Point(curRect.x, tarEndRect.y));
-        }
-      } catch (BadLocationException e) {
-        Debug.error(me + "Problem getting next visual position\n%s", e.getMessage());
-      }
-
-      return pos;
-
-    }
-
-    @Override
-    public void actionPerformed(ActionEvent e) {
-      JTextComponent textArea = (JTextComponent) e.getSource();
-
-      Caret caret = textArea.getCaret();
-      int dot = caret.getDot();
-
-      /*
-       * Move to the beginning/end of selection on a "non-shifted"
-       * left- or right-keypress.  We shouldn't have to worry about
-       * navigation filters as, if one is being used, it let us get
-       * to that position before.
-       */
-      if (!select) {
-        switch (direction) {
-          case SwingConstants.EAST:
-            int mark = caret.getMark();
-            if (dot != mark) {
-              caret.setDot(Math.max(dot, mark));
-              return;
-            }
-            break;
-          case SwingConstants.WEST:
-            mark = caret.getMark();
-            if (dot != mark) {
-              caret.setDot(Math.min(dot, mark));
-              return;
-            }
-            break;
-          default:
-        }
-      }
-
-      Position.Bias[] bias = new Position.Bias[1];
-      Point magicPosition = caret.getMagicCaretPosition();
-
-      try {
-
-        if (magicPosition == null
-                && (direction == SwingConstants.NORTH
-                || direction == SwingConstants.SOUTH)) {
-          Rectangle r = textArea.modelToView(dot);
-          magicPosition = new Point(r.x, r.y);
-        }
-
-        NavigationFilter filter = textArea.getNavigationFilter();
-
-        if (filter != null) {
-          dot = filter.getNextVisualPositionFrom(textArea, dot,
-                  Position.Bias.Forward, direction, bias);
-        } else {
-          if (direction == SwingConstants.NORTH
-                  || direction == SwingConstants.SOUTH) {
-            dot = getNSVisualPosition((EditorPane) textArea, dot, direction);
-          } else {
-            dot = textArea.getUI().getNextVisualPositionFrom(
-                    textArea, dot,
-                    Position.Bias.Forward, direction, bias);
-          }
-        }
-        if (select) {
-          caret.moveDot(dot);
-        } else {
-          caret.setDot(dot);
-        }
-
-        if (magicPosition != null
-                && (direction == SwingConstants.NORTH
-                || direction == SwingConstants.SOUTH)) {
-          caret.setMagicCaretPosition(magicPosition);
-        }
-
-      } catch (BadLocationException ble) {
-        Debug.error(me + "Problem while trying to move caret\n%s", ble.getMessage());
-      }
-
-    }
-  }
+			super(nm);
+			this.select = select;
+			this.direction = dir;
+		}
+
+		private static int getNSVisualPosition(EditorPane txt, int pos, int direction) {
+			Element root = txt.getDocument().getDefaultRootElement();
+			int numLines = root.getElementIndex(txt.getDocument().getLength() - 1) + 1;
+			int line = root.getElementIndex(pos) + 1;
+			int tarLine = direction == SwingConstants.NORTH ? line - 1 : line + 1;
+			try {
+				if (tarLine <= 0) {
+					return 0;
+				}
+				if (tarLine > numLines) {
+					return txt.getDocument().getLength();
+				}
+
+				Rectangle curRect = txt.modelToView(pos);
+				Rectangle tarEndRect;
+				if (tarLine < numLines) {
+					tarEndRect = txt.modelToView(txt.getLineStartOffset(tarLine) - 1);
+				} else {
+					tarEndRect = txt.modelToView(txt.getDocument().getLength() - 1);
+				}
+				Debug.log(9, "curRect: " + curRect + ", tarEnd: " + tarEndRect);
+
+				if (curRect.x > tarEndRect.x) {
+					pos = txt.viewToModel(new Point(tarEndRect.x, tarEndRect.y));
+				} else {
+					pos = txt.viewToModel(new Point(curRect.x, tarEndRect.y));
+				}
+			} catch (BadLocationException e) {
+				Debug.error(me + "Problem getting next visual position\n%s", e.getMessage());
+			}
+
+			return pos;
+
+		}
+
+		@Override
+		public void actionPerformed(ActionEvent e) {
+			JTextComponent textArea = (JTextComponent) e.getSource();
+
+			Caret caret = textArea.getCaret();
+			int dot = caret.getDot();
+
+			/*
+			 * Move to the beginning/end of selection on a "non-shifted"
+			 * left- or right-keypress.  We shouldn't have to worry about
+			 * navigation filters as, if one is being used, it let us get
+			 * to that position before.
+			 */
+			if (!select) {
+				switch (direction) {
+					case SwingConstants.EAST:
+						int mark = caret.getMark();
+						if (dot != mark) {
+							caret.setDot(Math.max(dot, mark));
+							return;
+						}
+						break;
+					case SwingConstants.WEST:
+						mark = caret.getMark();
+						if (dot != mark) {
+							caret.setDot(Math.min(dot, mark));
+							return;
+						}
+						break;
+					default:
+				}
+			}
+
+			Position.Bias[] bias = new Position.Bias[1];
+			Point magicPosition = caret.getMagicCaretPosition();
+
+			try {
+
+				if (magicPosition == null
+								&& (direction == SwingConstants.NORTH
+								|| direction == SwingConstants.SOUTH)) {
+					Rectangle r = textArea.modelToView(dot);
+					magicPosition = new Point(r.x, r.y);
+				}
+
+				NavigationFilter filter = textArea.getNavigationFilter();
+
+				if (filter != null) {
+					dot = filter.getNextVisualPositionFrom(textArea, dot,
+									Position.Bias.Forward, direction, bias);
+				} else {
+					if (direction == SwingConstants.NORTH
+									|| direction == SwingConstants.SOUTH) {
+						dot = getNSVisualPosition((EditorPane) textArea, dot, direction);
+					} else {
+						dot = textArea.getUI().getNextVisualPositionFrom(
+										textArea, dot,
+										Position.Bias.Forward, direction, bias);
+					}
+				}
+				if (select) {
+					caret.moveDot(dot);
+				} else {
+					caret.setDot(dot);
+				}
+
+				if (magicPosition != null
+								&& (direction == SwingConstants.NORTH
+								|| direction == SwingConstants.SOUTH)) {
+					caret.setMagicCaretPosition(magicPosition);
+				}
+
+			} catch (BadLocationException ble) {
+				Debug.error(me + "Problem while trying to move caret\n%s", ble.getMessage());
+			}
+
+		}
+	}
 
 //<editor-fold defaultstate="collapsed" desc="general support functions">
-  @Override
-  public Action[] getActions() {
-    return TextAction.augmentList(super.getActions(), defaultActions);
-  }
-
-  @Override
-  public ViewFactory getViewFactory() {
-    return _viewFactory;
-  }
-
-  @Override
-  public String getContentType() {
-    //TODO other content type: ruby, DSL, ...
-    return "text/python";
-  }
-
-  @Override
-  public void read(Reader in, Document doc, int pos)
-          throws IOException, BadLocationException {
-    Debug.log(3, "SikuliEditorKit.read");
-    super.read(in, doc, pos);
-  }
-
-  @Override
-  public void write(Writer out, Document doc, int pos, int len)
-          throws IOException, BadLocationException {
-    write(out, doc, pos, len, null);
-  }
-
-  public void write(Writer out, Document doc, int pos, int len, Map<String, String> copiedImgs)
-          throws IOException, BadLocationException {
-    Debug.log(9, "SikuliEditorKit.write %d %d", pos, len);
-    DefaultStyledDocument sdoc = (DefaultStyledDocument) doc;
-    int i = pos;
-    String absPath;
-    while (i < pos + len) {
-      Element e = sdoc.getCharacterElement(i);
-      int start = e.getStartOffset(), end = e.getEndOffset();
-      if (e.getName().equals(StyleConstants.ComponentElementName)) {
-        // A image argument to be filled
-        AttributeSet attr = e.getAttributes();
-        Component com = StyleConstants.getComponent(attr);
-        out.write(com.toString());
-        if (copiedImgs != null && 
-           (com instanceof EditorPatternButton || com instanceof EditorPatternLabel)) {
-          if (com instanceof EditorPatternButton) {
-            absPath = ((EditorPatternButton) com).getFilename();
-          } else {
-            absPath = ((EditorPatternLabel) com).getFile();
-          }
-          String fname = (new File(absPath)).getName();
-          copiedImgs.put(fname, absPath);
-          Debug.log(3, "save image for copy&paste: " + fname + " -> " + absPath);
-        }
-      } else {
-        if (start < pos) {
-          start = pos;
-        }
-        if (end > pos + len) {
-          end = pos + len;
-        }
-        out.write(doc.getText(start, end - start));
-      }
-      i = end;
-    }
-    out.close();
-  }
+	@Override
+	public Action[] getActions() {
+		return TextAction.augmentList(super.getActions(), defaultActions);
+	}
+
+	@Override
+	public ViewFactory getViewFactory() {
+		return _viewFactory;
+	}
+
+	@Override
+	public String getContentType() {
+		//TODO other content type: ruby, DSL, ...
+		return "text/python";
+	}
+
+	@Override
+	public void read(Reader in, Document doc, int pos)
+					throws IOException, BadLocationException {
+		Debug.log(3, "SikuliEditorKit.read");
+		super.read(in, doc, pos);
+	}
+
+	@Override
+	public void write(Writer out, Document doc, int pos, int len)
+					throws IOException, BadLocationException {
+		write(out, doc, pos, len, null);
+	}
+
+	public void write(Writer out, Document doc, int pos, int len, Map<String, String> copiedImgs)
+					throws IOException, BadLocationException {
+		Debug.log(9, "SikuliEditorKit.write %d %d", pos, len);
+		DefaultStyledDocument sdoc = (DefaultStyledDocument) doc;
+		int i = pos;
+		String absPath;
+		while (i < pos + len) {
+			Element e = sdoc.getCharacterElement(i);
+			int start = e.getStartOffset(), end = e.getEndOffset();
+			if (e.getName().equals(StyleConstants.ComponentElementName)) {
+				// A image argument to be filled
+				AttributeSet attr = e.getAttributes();
+				Component com = StyleConstants.getComponent(attr);
+				out.write(com.toString());
+				if (copiedImgs != null
+								&& (com instanceof EditorPatternButton || com instanceof EditorPatternLabel)) {
+					if (com instanceof EditorPatternButton) {
+						absPath = ((EditorPatternButton) com).getFilename();
+					} else {
+						absPath = ((EditorPatternLabel) com).getFile();
+					}
+					String fname = (new File(absPath)).getName();
+					copiedImgs.put(fname, absPath);
+					Debug.log(3, "save image for copy&paste: " + fname + " -> " + absPath);
+				}
+			} else {
+				if (start < pos) {
+					start = pos;
+				}
+				if (end > pos + len) {
+					end = pos + len;
+				}
+				out.write(doc.getText(start, end - start));
+			}
+			i = end;
+		}
+		out.close();
+	}
 //</editor-fold>
 
 }
diff --git a/IDE/src/main/java/org/sikuli/ide/EditorPane.java b/IDE/src/main/java/org/sikuli/ide/EditorPane.java
index 2bf0a22..6023c4c 100755
--- a/IDE/src/main/java/org/sikuli/ide/EditorPane.java
+++ b/IDE/src/main/java/org/sikuli/ide/EditorPane.java
@@ -25,12 +25,14 @@ import javax.swing.event.DocumentEvent;
 import javax.swing.event.DocumentListener;
 import javax.swing.text.*;
 import org.sikuli.basics.Settings;
-import org.sikuli.jython.PythonIndentation;
+import org.sikuli.idesupport.PythonIndentation;
 import org.sikuli.basics.Debug;
 import org.sikuli.basics.FileManager;
 import org.sikuli.basics.IResourceLoader;
+import org.sikuli.basics.IndentationLogic;
 import org.sikuli.script.Location;
 import org.sikuli.basics.SikuliX;
+import org.sikuli.idesupport.JythonIDESupport;
 import org.sikuli.script.Image;
 import org.sikuli.script.ImagePath;
 
@@ -40,6 +42,7 @@ public class EditorPane extends JTextPane implements KeyListener, CaretListener
   private static TransferHandler transferHandler = null;
   private PreferencesUser pref;
   private File _editingFile;
+	private String editingType = null;
   private String _srcBundlePath = null;
   private boolean _srcBundleTemp = false;
   private boolean _dirty = false;
@@ -48,7 +51,7 @@ public class EditorPane extends JTextPane implements KeyListener, CaretListener
   private boolean hasErrorHighlight = false;
   public boolean showThumbs;
   // TODO: move to SikuliDocument ????
-  private PythonIndentation _indentationLogic;
+  private IndentationLogic _indentationLogic = null;
   static Pattern patPngStr = Pattern.compile("(\"[^\"]+?\\.(?i)(png|jpg)\")");
   static Pattern patCaptureBtn = Pattern.compile("(\"__CLICK-TO-CAPTURE__\")");
   static Pattern patPatternStr = Pattern.compile(
@@ -64,8 +67,6 @@ public class EditorPane extends JTextPane implements KeyListener, CaretListener
   public EditorPane() {
     pref = PreferencesUser.getInstance();
     showThumbs = !pref.getPrefMorePlainText();
-    setEditorKitForContentType("text/python", new EditorKit());
-    setContentType("text/python");
     initKeyMap();
     if (transferHandler == null) {
       transferHandler = new MyTransferHandler();
@@ -81,16 +82,6 @@ public class EditorPane extends JTextPane implements KeyListener, CaretListener
     }
     updateDocumentListeners();
 
-    _indentationLogic = new PythonIndentation();
-    _indentationLogic.setTabWidth(pref.getTabWidth());
-    pref.addPreferenceChangeListener(new PreferenceChangeListener() {
-      @Override
-      public void preferenceChange(PreferenceChangeEvent event) {
-        if (event.getKey().equals("TAB_WIDTH")) {
-          _indentationLogic.setTabWidth(Integer.parseInt(event.getNewValue()));
-        }
-      }
-    });
     initEditorPane();
   }
 
@@ -102,7 +93,28 @@ public class EditorPane extends JTextPane implements KeyListener, CaretListener
       popMenuImage = null;
     }
   }
-  
+
+	public void initBeforeLoad(String scriptType) {
+		//TODO ask for scripttype on new pane
+		if (scriptType == null || "py".equals(scriptType)) {
+			setEditorKitForContentType("text/python", new EditorKit());
+			setContentType("text/python");
+			_indentationLogic = JythonIDESupport.getIndentationLogic();
+			_indentationLogic.setTabWidth(pref.getTabWidth());
+			pref.addPreferenceChangeListener(new PreferenceChangeListener() {
+				@Override
+				public void preferenceChange(PreferenceChangeEvent event) {
+					if (event.getKey().equals("TAB_WIDTH")) {
+						_indentationLogic.setTabWidth(Integer.parseInt(event.getNewValue()));
+					}
+				}
+			});
+		} else if ("rb".equals(scriptType)) {
+			setEditorKitForContentType("text/ruby", new EditorKit());
+			setContentType("text/ruby");
+		}
+	}
+
   public SikuliIDEPopUpMenu getPopMenuImage() {
     return popMenuImage;
   }
@@ -119,7 +131,7 @@ public class EditorPane extends JTextPane implements KeyListener, CaretListener
     return _undo;
   }
 
-  public PythonIndentation getIndentationLogic() {
+  public IndentationLogic getIndentationLogic() {
     return _indentationLogic;
   }
 
@@ -170,6 +182,8 @@ public class EditorPane extends JTextPane implements KeyListener, CaretListener
     setSrcBundle(filename + "/");
     File script = new File(filename);
     _editingFile = FileManager.getScriptFile(script, null, null);
+		editingType = _editingFile.getAbsolutePath().substring(_editingFile.getAbsolutePath().lastIndexOf(".") + 1);
+		initBeforeLoad(editingType);
     try {
       this.read(new BufferedReader(new InputStreamReader(
               new FileInputStream(_editingFile), "UTF8")), null);
@@ -184,7 +198,7 @@ public class EditorPane extends JTextPane implements KeyListener, CaretListener
       _srcBundlePath = null;
     }
   }
-  
+
   public boolean hasEditingFile() {
     return _editingFile != null;
   }
@@ -229,7 +243,7 @@ public class EditorPane extends JTextPane implements KeyListener, CaretListener
     }
     return getCurrentShortFilename();
   }
-  
+
   private void makeBundle(String path, boolean asFile) {
     String isBundle = asFile ? "B" : "b";
     IResourceLoader loader = FileManager.getNativeLoader("basic", new String[0]);
@@ -239,7 +253,7 @@ public class EditorPane extends JTextPane implements KeyListener, CaretListener
       Debug.error("makeBundle: return: " + cmd[0]);
     }
     if (asFile) {
-      if (! FileManager.writeStringToFile("/Applications/SikuliX-IDE.app", 
+      if (! FileManager.writeStringToFile("/Applications/SikuliX-IDE.app",
               (new File(path, ".LSOverride")).getAbsolutePath())) {
         Debug.error("makeBundle: not possible: .LSOverride");
       }
@@ -247,7 +261,7 @@ public class EditorPane extends JTextPane implements KeyListener, CaretListener
       new File(path, ".LSOverride").delete();
     }
   }
-  
+
   private void saveAsBundle(String bundlePath, String current) throws IOException {
 //TODO allow other file types
     bundlePath = FileManager.slashify(bundlePath, true);
@@ -361,7 +375,7 @@ public class EditorPane extends JTextPane implements KeyListener, CaretListener
   public boolean isSourceBundleTemp() {
     return _srcBundleTemp;
   }
-  
+
   public String getCurrentSrcDir() {
     if(_srcBundlePath != null) {
       if (_editingFile == null || _srcBundleTemp) {
@@ -381,17 +395,17 @@ public class EditorPane extends JTextPane implements KeyListener, CaretListener
     }
     return "Untitled";
   }
-  
+
   public File getCurrentFile() {
-    return getCurrentFile(true);    
+    return getCurrentFile(true);
   }
-  
+
   public File getCurrentFile(boolean shouldSave) {
     if (shouldSave && _editingFile == null && isDirty()) {
       try {
         saveAsFile(Settings.isMac());
       } catch (IOException e) {
-        Debug.error(me + "getCurrentFile: Problem while trying to save %s\n%s", 
+        Debug.error(me + "getCurrentFile: Problem while trying to save %s\n%s",
                 _editingFile.getAbsolutePath(), e.getMessage());
       }
     }
@@ -426,7 +440,7 @@ public class EditorPane extends JTextPane implements KeyListener, CaretListener
         File newFile = FileManager.smartCopy(filename, bundlePath);
         return newFile;
       } catch (IOException e) {
-        Debug.error(me + "copyFileToBundle: Problem while trying to save %s\n%s", 
+        Debug.error(me + "copyFileToBundle: Problem while trying to save %s\n%s",
                 filename, e.getMessage());
         return f;
       }
@@ -441,7 +455,7 @@ public class EditorPane extends JTextPane implements KeyListener, CaretListener
       }
       return null;
   }
-  
+
   public Image getImageInBundle(String filename) {
       return Image.createThumbNail(filename);
   }
@@ -901,7 +915,7 @@ public class EditorPane extends JTextPane implements KeyListener, CaretListener
 
     private static final String me = "EditorPaneTransferHandler: ";
     Map<String, String> _copiedImgs = new HashMap<String, String>();
-    
+
     @Override
     public void exportToClipboard(JComponent comp, Clipboard clip, int action) {
       super.exportToClipboard(comp, clip, action);
diff --git a/IDE/src/main/java/org/sikuli/ide/EditorViewFactory.java b/IDE/src/main/java/org/sikuli/ide/EditorViewFactory.java
index f93ba5f..37724ff 100755
--- a/IDE/src/main/java/org/sikuli/ide/EditorViewFactory.java
+++ b/IDE/src/main/java/org/sikuli/ide/EditorViewFactory.java
@@ -20,6 +20,8 @@ import org.sikuli.basics.Debug;
 
 public class EditorViewFactory implements ViewFactory {
 
+	private EditorPane pane;
+
   @Override
   public View create(Element elem) {
     String kind = elem.getName();
@@ -40,6 +42,10 @@ public class EditorViewFactory implements ViewFactory {
     // default to text display
     return new LabelView(elem);
   }
+
+	public void setPane(EditorPane p) {
+		pane = p;
+	}
 }
 
 //<editor-fold defaultstate="collapsed" desc="Section">
diff --git a/IDE/src/main/java/org/sikuli/ide/SikuliIDE.java b/IDE/src/main/java/org/sikuli/ide/SikuliIDE.java
index 4c881bb..859211f 100755
--- a/IDE/src/main/java/org/sikuli/ide/SikuliIDE.java
+++ b/IDE/src/main/java/org/sikuli/ide/SikuliIDE.java
@@ -876,10 +876,10 @@ public class SikuliIDE extends JFrame {
     }
 
     public void doNew(ActionEvent ae) {
-      doNew(ae, -1);
+      doNew(ae, -1).initBeforeLoad(null);
     }
 
-    public void doNew(ActionEvent ae, int tabIndex) {
+    public EditorPane doNew(ActionEvent ae, int tabIndex) {
       EditorPane codePane = new EditorPane();
       JScrollPane scrPane = new JScrollPane(codePane);
       lineNumberColumn = new EditorLineNumberView(codePane);
@@ -897,6 +897,7 @@ public class SikuliIDE extends JFrame {
       }
       codePane.getSrcBundle();
       codePane.requestFocus();
+			return codePane;
     }
 
     public void doInsert(ActionEvent ae) {
diff --git a/JRuby/src/main/java/org/sikuli/idesupport/JRubyIDESupport.java b/JRuby/src/main/java/org/sikuli/idesupport/JRubyIDESupport.java
new file mode 100644
index 0000000..5ec8b15
--- /dev/null
+++ b/JRuby/src/main/java/org/sikuli/idesupport/JRubyIDESupport.java
@@ -0,0 +1,16 @@
+/*
+ * Copyright 2010-2013, Sikuli.org
+ * Released under the MIT License.
+ *
+ * added RaiMan 2013
+ */
+package org.sikuli.idesupport;
+
+import org.sikuli.basics.IDESupport;
+
+/**
+ * all methods from/for IDE, that are JRuby specific
+ */
+public class JRubyIDESupport implements IDESupport {
+
+}
diff --git a/JRuby/src/main/java/org/sikuli/jruby/IDESupport.java b/JRuby/src/main/java/org/sikuli/jruby/IDESupport.java
deleted file mode 100644
index 199a6d3..0000000
--- a/JRuby/src/main/java/org/sikuli/jruby/IDESupport.java
+++ /dev/null
@@ -1,14 +0,0 @@
-/*
- * Copyright 2010-2013, Sikuli.org
- * Released under the MIT License.
- *
- * added RaiMan 2013
- */
-package org.sikuli.jruby;
-
-/**
- * all methods from/for IDE, that are Python specific
- */
-public class IDESupport {
-  
-}
diff --git a/Jython/src/main/java/org/sikuli/idesupport/JythonIDESupport.java b/Jython/src/main/java/org/sikuli/idesupport/JythonIDESupport.java
new file mode 100644
index 0000000..50191ae
--- /dev/null
+++ b/Jython/src/main/java/org/sikuli/idesupport/JythonIDESupport.java
@@ -0,0 +1,20 @@
+/*
+ * Copyright 2010-2013, Sikuli.org
+ * Released under the MIT License.
+ *
+ * added RaiMan 2013
+ */
+package org.sikuli.idesupport;
+
+import org.sikuli.basics.IDESupport;
+import org.sikuli.basics.IndentationLogic;
+
+/**
+ * all methods from/for IDE, that are Python specific
+ */
+public class JythonIDESupport implements IDESupport {
+
+	public static IndentationLogic getIndentationLogic() {
+		return new PythonIndentation();
+	}
+}
diff --git a/Jython/src/main/java/org/sikuli/jython/PythonIndentation.java b/Jython/src/main/java/org/sikuli/idesupport/PythonIndentation.java
similarity index 99%
rename from Jython/src/main/java/org/sikuli/jython/PythonIndentation.java
rename to Jython/src/main/java/org/sikuli/idesupport/PythonIndentation.java
index e2a87b6..afcf5c4 100755
--- a/Jython/src/main/java/org/sikuli/jython/PythonIndentation.java
+++ b/Jython/src/main/java/org/sikuli/idesupport/PythonIndentation.java
@@ -5,7 +5,7 @@
  * added karlmicha 2011
  * modified RaiMan 2013
  */
-package org.sikuli.jython;
+package org.sikuli.idesupport;
 
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
@@ -15,6 +15,7 @@ import javax.swing.text.StyleConstants;
 import javax.swing.text.StyledDocument;
 import org.sikuli.basics.PreferencesUser;
 import org.sikuli.basics.Debug;
+import org.sikuli.basics.IndentationLogic;
 
 /**
  * Implements the logic for giving hints about the (correct) indentation of new
@@ -56,7 +57,7 @@ import org.sikuli.basics.Debug;
  * <li>long strings
  * </ul>
  */
-public class PythonIndentation {
+public class PythonIndentation implements IndentationLogic {
 
    public static final int PARENTHESIS_INDENTATION_TABSTOPS = 2;
    public static final int NESTED_PARENTHESIS_INDENTATION_TABSTOPS = 1;
@@ -217,6 +218,7 @@ public class PythonIndentation {
     * @param tabwidth
     *           the number of whitespace columns that equals a single tab
     */
+	 @Override
    public void setTabWidth(int tabwidth){
       pythonState.setTabSize(tabwidth);
    }
diff --git a/Jython/src/main/java/org/sikuli/jython/PythonState.java b/Jython/src/main/java/org/sikuli/idesupport/PythonState.java
similarity index 99%
rename from Jython/src/main/java/org/sikuli/jython/PythonState.java
rename to Jython/src/main/java/org/sikuli/idesupport/PythonState.java
index 9164fff..d73e68a 100755
--- a/Jython/src/main/java/org/sikuli/jython/PythonState.java
+++ b/Jython/src/main/java/org/sikuli/idesupport/PythonState.java
@@ -5,7 +5,7 @@
  * added karlmicha 2011
  * modified RaiMan 2013
  */
-package org.sikuli.jython;
+package org.sikuli.idesupport;
 
 import java.util.Stack;
 import java.util.regex.Matcher;
diff --git a/Jython/src/main/java/org/sikuli/jython/IDESupport.java b/Jython/src/main/java/org/sikuli/jython/IDESupport.java
deleted file mode 100644
index 931dc79..0000000
--- a/Jython/src/main/java/org/sikuli/jython/IDESupport.java
+++ /dev/null
@@ -1,14 +0,0 @@
-/*
- * Copyright 2010-2013, Sikuli.org
- * Released under the MIT License.
- *
- * added RaiMan 2013
- */
-package org.sikuli.jython;
-
-/**
- * all methods from/for IDE, that are Python specific
- */
-public class IDESupport {
-  
-}

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-java/sikuli.git



More information about the pkg-java-commits mailing list