Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

We’re showing branches in this repository, but you can also compare across forks.

base fork: romuloceccon/jedit
base: master
...
head fork: romuloceccon/jedit
compare: electric_line
  • 1 commit
  • 4 files changed
  • 0 commit comments
  • 1 contributor
Commits on May 12, 2013
Romulo A. Ceccon implemented "electric line" behaviour, an improved way to handle the …
…statement delimiters (end, else, rescue etc.) in Ruby
fe1331f
4 modes/ruby.xml
View
@@ -11,8 +11,6 @@
<MODE NAME="ruby" FILE="ruby.xml" FILE_NAME_GLOB="*.{rb,rbw}" FIRST_LINE_GLOB="#!*/*ruby*" /> -->
<MODE>
<PROPS>
- <PROPERTY NAME="indentOpenBrackets" VALUE="{"/>
- <PROPERTY NAME="indentCloseBrackets" VALUE="}"/>
<PROPERTY NAME="unalignedOpenBrackets" VALUE="("/>
<PROPERTY NAME="unalignedCloseBrackets" VALUE=")"/>
<PROPERTY NAME="lineUpClosingBracket" VALUE="true"/>
@@ -25,7 +23,7 @@
<PROPERTY NAME="unindentNextLines" VALUE="^\s*(end\s*|else.*|rescue.*|elsif.*|when.*|ensure.*)$"/>
<PROPERTY NAME="indentNextLine"
VALUE="^[^#]*([^$](:|\+|~|\*|-|%|&lt;|&gt;|&amp;|\^|\.|=)|\s(/|\!|\?|\|)|\b(not|and|or)|\\)\s*$"/>
- <PROPERTY NAME="electricKeys" VALUE="edfn"/>
+ <PROPERTY NAME="electricLine" VALUE="^\s*(end\s*|(else|elsif|rescue|when|ensure)\s?.*)$" />
</PROPS>
<RULES IGNORE_CASE="FALSE" HIGHLIGHT_DIGITS="TRUE"
DIGIT_RE="(0b[01]([01_]*[01])?)|(0x[\p{XDigit}]([\p{XDigit}_]*[\p{XDigit}])?)|(0([0-7_]*[0-7])?)|(0d[0-9]([0-9_]*[0-9])?)|([1-9]([0-9_]*[0-9])?)|([0-9]([0-9_]*[0-9])?[Ee]([0-9]([0-9_]*[0-9])?)?)">
34 org/gjt/sp/jedit/Mode.java
View
@@ -407,6 +407,38 @@ public synchronized boolean isElectricKey(char ch)
return (electricKeys.indexOf(ch) >= 0);
} //}}}
+ //{{{ getElectricLinePattern() method
+ public Pattern getElectricLinePattern()
+ {
+ if (electricLine == null)
+ compileElectricLinePattern();
+
+ return electricLineRE;
+ } //}}}
+
+ //{{{ compileElectricLinePattern() method
+ private synchronized void compileElectricLinePattern()
+ {
+ if (electricLine == null)
+ {
+ if ((electricLine = (String) getProperty("electricLine")) == null)
+ electricLine = "";
+ else
+ {
+ try
+ {
+ electricLineRE = Pattern.compile(electricLine);
+ }
+ catch(PatternSyntaxException e)
+ {
+ Log.log(Log.ERROR,this,
+ "Bad electricLine rule: " + electricLine);
+ Log.log(Log.ERROR, this, e);
+ }
+ }
+ }
+ } //}}}
+
//{{{ initIndentRules() method
private void initIndentRules()
{
@@ -532,5 +564,7 @@ private void createBracketIndentRules(String prop,
private List<IndentRule> indentRules;
private String electricKeys;
private boolean ignoreWhitespace;
+ private String electricLine;
+ private Pattern electricLineRE;
//}}}
}
15 org/gjt/sp/jedit/buffer/JEditBuffer.java
View
@@ -1314,8 +1314,7 @@ public int insertIndented(int offset, String text)
*/
public boolean isElectricKey(char ch, int line)
{
- TokenMarker.LineContext ctx = lineMgr.getLineContext(line);
- Mode mode = ModeProvider.instance.getMode(ctx.rules.getModeName());
+ Mode mode = getMode(line);
// mode can be null, though that's probably an error "further up":
if (mode == null)
@@ -1323,6 +1322,18 @@ public boolean isElectricKey(char ch, int line)
return mode.isElectricKey(ch);
} //}}}
+ public Pattern getElectricLinePattern(int line)
+ {
+ Mode mode = getMode(line);
+ return mode != null ? mode.getElectricLinePattern() : null;
+ }
+
+ private Mode getMode(int line)
+ {
+ TokenMarker.LineContext ctx = lineMgr.getLineContext(line);
+ return ModeProvider.instance.getMode(ctx.rules.getModeName());
+ }
+
//}}}
//{{{ Syntax highlighting
99 org/gjt/sp/jedit/textarea/TextArea.java
View
@@ -31,6 +31,8 @@
import java.text.BreakIterator;
import java.text.CharacterIterator;
+import java.util.regex.Pattern;
+
import javax.annotation.Nonnull;
import javax.swing.*;
import javax.swing.event.*;
@@ -2277,6 +2279,8 @@ public void moveCaretPosition(int newCaret, int scrollMode)
{
caret = getCharacterBoundaryAt(newCaret);
caretLine = getLineOfOffset(caret);
+ if (caretLine != oldCaretLine)
+ previousIndent = null;
magicCaret = -1;
@@ -3406,12 +3410,8 @@ public void userInput(char ch)
{
if(!doWordWrap(ch == ' '))
{
- boolean indent = buffer.isElectricKey(ch, caretLine) &&
- "full".equals(buffer.getStringProperty("autoIndent")) &&
- /* if the line is not manually indented */
- (buffer.getCurrentIndentForLine(caretLine, null) ==
- buffer.getIdealIndentForLine(caretLine));
- insert(str,indent);
+ int indentAction = getIndentAction(ch);
+ insert(str,indentAction);
}
}
else
@@ -5442,14 +5442,20 @@ private boolean lineContainsSpaceAndTabs(int lineIndex)
return true;
} //}}}
+ private static final int NO_INDENT = 0;
+ private static final int DO_INDENT = 1;
+ private static final int UNDO_INDENT = 2;
+
//{{{ insert() method
- protected void insert(String str, boolean indent)
+ protected void insert(String str, int indentAction)
{
+ boolean compoundEdit = overwrite || indentAction != NO_INDENT;
+
try
{
// Don't overstrike if we're on the end of
// the line
- if(overwrite || indent)
+ if(compoundEdit)
buffer.beginCompoundEdit();
if(overwrite)
@@ -5461,16 +5467,89 @@ protected void insert(String str, boolean indent)
buffer.insert(caret,str);
- if(indent)
+ if(indentAction == DO_INDENT)
+ {
+ saveIndent();
buffer.indentLine(caretLine,true);
+ }
+ else if(indentAction == UNDO_INDENT)
+ undoIndent();
}
finally
{
- if(overwrite || indent)
+ if(compoundEdit)
buffer.endCompoundEdit();
}
} //}}}
+ private String previousIndent;
+
+ private String getLeadingWhitespaceChars(int line)
+ {
+ StringBuffer strBuf = new StringBuffer();
+ String lineText = getLineText(line);
+
+ for (int i = 0; i < lineText.length(); i++)
+ {
+ char c = lineText.charAt(i);
+ if (c == ' ' || c == '\t')
+ strBuf.append(c);
+ else
+ break;
+ }
+
+ return strBuf.toString();
+ }
+
+ private void saveIndent()
+ {
+ previousIndent = getLeadingWhitespaceChars(caretLine);
+ }
+
+ private void undoIndent()
+ {
+ if (previousIndent == null)
+ return;
+
+ int start = buffer.getLineStartOffset(caretLine);
+ String whitespace = getLeadingWhitespaceChars(caretLine);
+ buffer.remove(start, whitespace.length());
+ buffer.insert(start, previousIndent);
+
+ previousIndent = null;
+ }
+
+ private int getIndentAction(char c)
+ {
+ Pattern pattern = buffer.getElectricLinePattern(caretLine);
+
+ if (pattern == null)
+ {
+ boolean indent = buffer.isElectricKey(c, caretLine) &&
+ "full".equals(buffer.getStringProperty("autoIndent")) &&
+ /* if the line is not manually indented */
+ (buffer.getCurrentIndentForLine(caretLine, null) ==
+ buffer.getIdealIndentForLine(caretLine));
+ return indent ? DO_INDENT : NO_INDENT;
+ }
+
+ StringBuffer strBuf = new StringBuffer();
+ int start = buffer.getLineStartOffset(caretLine);
+ int end = buffer.getLineEndOffset(caretLine);
+ strBuf.append(buffer.getText(start,caret - start));
+ strBuf.append(c);
+ strBuf.append(buffer.getText(caret,end - caret - 1));
+
+ boolean matched = pattern.matcher(strBuf.toString()).matches();
+
+ if (matched && previousIndent == null)
+ return DO_INDENT;
+ else if (!matched && previousIndent != null)
+ return UNDO_INDENT;
+ else
+ return NO_INDENT;
+ }
+
//{{{ insertTab() method
private void insertTab()
{

No commit comments for this range

Something went wrong with that request. Please try again.