From: Robert M. <rob...@us...> - 2005-11-06 00:26:04
|
Update of /cvsroot/jedit/plugins/RubyPlugin/src/org/jedit/ruby/structure In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv7860/org/jedit/ruby/structure Modified Files: ProgressiveSelector.java RubySideKickParser.java Added Files: RubyToken.java RubyTokenHandler.java Log Message: Fixed progressive selection of literals --- NEW FILE: RubyTokenHandler.java --- /* * RubyPlugin.java - Ruby editor plugin for jEdit * * Copyright 2005 Robert McKinnon * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ package org.jedit.ruby.structure; import org.gjt.sp.jedit.Buffer; import org.gjt.sp.jedit.TextUtilities; import org.gjt.sp.jedit.syntax.DefaultTokenHandler; import org.gjt.sp.jedit.syntax.Token; /** * @author robmckinnon at users,sourceforge,net */ public final class RubyTokenHandler extends DefaultTokenHandler { public RubyToken getTokenAtCaret(Buffer buffer, int caret) { init(); // reset int line = buffer.getLineOfOffset(caret); buffer.markTokens(line, this); int offset = caret; offset -= buffer.getLineStartOffset(line); if (offset != 0) { offset--; } Token token = TextUtilities.getTokenAtOffset(firstToken, offset); return new RubyToken(token, firstToken); } } Index: ProgressiveSelector.java =================================================================== RCS file: /cvsroot/jedit/plugins/RubyPlugin/src/org/jedit/ruby/structure/ProgressiveSelector.java,v retrieving revision 1.3 retrieving revision 1.4 diff -u -d -r1.3 -r1.4 --- ProgressiveSelector.java 29 Oct 2005 19:07:19 -0000 1.3 +++ ProgressiveSelector.java 6 Nov 2005 00:25:45 -0000 1.4 @@ -19,23 +19,23 @@ */ package org.jedit.ruby.structure; -import org.gjt.sp.jedit.View; import org.gjt.sp.jedit.Buffer; import org.gjt.sp.jedit.TextUtilities; -import org.gjt.sp.jedit.syntax.Token; -import org.gjt.sp.jedit.syntax.DefaultTokenHandler; +import org.gjt.sp.jedit.View; import org.gjt.sp.jedit.textarea.JEditTextArea; import org.gjt.sp.jedit.textarea.Selection; import org.jedit.ruby.RubyPlugin; -import org.jedit.ruby.parser.RubyParser; import org.jedit.ruby.ast.Member; import org.jedit.ruby.ast.RubyMembers; +import org.jedit.ruby.parser.RubyParser; /** * @author robmckinnon at users.sourceforge.net */ public final class ProgressiveSelector { + private static RubyTokenHandler tokenHandler = new RubyTokenHandler(); + public static void doProgressiveSelection(View view) { JEditTextArea textArea = view.getTextArea(); String text = textArea.getText(); @@ -50,7 +50,7 @@ boolean needToSelectMoreDefault = true; if (!matchesLiteralChar(text.charAt(caretPosition))) { - if(!(caretPosition > 0 && matchesLiteralChar(text.charAt(caretPosition - 1)))) { + if (!(caretPosition > 0 && matchesLiteralChar(text.charAt(caretPosition - 1)))) { needToSelectMoreDefault = false; selectWord(textArea); @@ -86,66 +86,78 @@ } private static void handleLiteral(Buffer buffer, int caretPosition, JEditTextArea textArea, Selection selection) { - DefaultTokenHandler tokens = RubyPlugin.getTokens(buffer, caretPosition); - Token priorToken = RubyPlugin.getToken(buffer, caretPosition, tokens); - Token currentToken = priorToken.next; - Token nextToken = currentToken.next; + RubyToken first = tokenHandler.getTokenAtCaret(buffer, caretPosition); + RubyToken second = first.getNextToken(); - boolean priorLiteral = isLiteral(priorToken); - boolean currentLiteral = isLiteral(currentToken); - boolean nextLiteral = isLiteral(nextToken); + RubyToken prior = first; + RubyToken current = second; - if (priorLiteral && currentLiteral && nextLiteral) { - selectLiteral(priorToken, currentToken, nextToken, textArea, selection); + if (prior.isLiteral() || current.isLiteral()) { + if (current.isLiteral() && (selection != null || !prior.isLiteral())) { + while (current.isNextLiteral()) { + current = current.getNextToken(); + } + } - } else if(currentLiteral && nextLiteral && isLiteral(nextToken.next)) { - selectLiteral(currentToken, nextToken, nextToken.next, textArea, selection, false); + if (prior.isLiteral() && (selection != null || !current.isLiteral())) { + while (prior.isPreviousLiteral()) { + prior = prior.getPreviousToken(); + } + } - } else { - Token previousToken = RubyPlugin.getPreviousToken(tokens, priorToken); - boolean previousLiteral = isLiteral(previousToken); + int lineStartOffset = textArea.getLineStartOffset(textArea.getCaretLine()); - if (previousLiteral && priorLiteral && currentLiteral) { - selectLiteral(previousToken, priorToken, currentToken, textArea, selection); + int start = lineStartOffset; + int end = lineStartOffset; + if (prior.isLiteral()) { + start += prior.offset; } else { - Token earlierToken = RubyPlugin.getPreviousToken(tokens, previousToken); + start += second.offset; + } - if (isLiteral(earlierToken) && previousLiteral && priorLiteral) { - selectLiteral(earlierToken, previousToken, priorToken, textArea, selection, false); + if (current.isLiteral()) { + end += current.offset + current.length; + } else { + end += first.offset + first.length; + } - } else if (previousLiteral && priorLiteral) { - selectLiteral(previousToken, null, priorToken, textArea, selection); + RubyPlugin.log("prior " + prior + " current " + current, ProgressiveSelector.class); + RubyPlugin.log("start " + start + " end " + end, ProgressiveSelector.class); + if (selection != null) { + RubyPlugin.log("sstart " + selection.getStart() + " send " + selection.getEnd(), ProgressiveSelector.class); + } - } else if (priorLiteral && currentLiteral) { - selectLiteral(priorToken, null, currentToken, textArea, selection); + boolean unselectQuotes = true; + boolean emptyString = start == (end - 2); - } else if (currentLiteral && nextLiteral) { - selectLiteral(currentToken, null, nextToken, textArea, selection); + if (selection != null) { + if (selection.getStart() == start) { + unselectQuotes = false; + } else if ((start + 1) == selection.getStart() && (end - 1) == selection.getEnd()) { + unselectQuotes = false; } - } - } - } - - private static void selectLiteral(Token literalStart, Token literal, Token literalEnd, JEditTextArea textArea, Selection selection) { - selectLiteral(literalStart, literal, literalEnd, textArea, selection, true); - } + } else { + unselectQuotes = false; - private static void selectLiteral(Token literalStart, Token literal, Token literalEnd, JEditTextArea textArea, Selection selection, boolean inside) { - int lineStartOffset = textArea.getLineStartOffset(textArea.getCaretLine()); + if(!emptyString) { + if (first.length == 1 && first.isLiteral() && !first.isPreviousLiteral()) { + start++; + } else if(second.length == 1 && second.isLiteral() && !second.isNextLiteral()) { + end--; + } + } + } - if (literal != null) { - int offset = literal.offset + lineStartOffset; - int end = offset + literal.length; - setSelection(offset, end, textArea); - if (!inside || needToSelectMore(textArea, selection)) { - setSelection(offset - literalStart.length, end + literalEnd.length, textArea); + if (!current.isLiteral() || !prior.isLiteral()) { + unselectQuotes = false; } - } else { - int offset = literalStart.offset + lineStartOffset; - int end = offset + literalStart.length + literalEnd.length; - setSelection(offset, end, textArea); + if (unselectQuotes && !emptyString) { + start++; + end--; + } + setSelection(start, end, textArea); } } @@ -161,22 +173,6 @@ } } - private static boolean isLiteral(Token token) { - if (token == null) { - return false; - } else { - switch (token.id) { - case Token.LITERAL1: - case Token.LITERAL2: - case Token.LITERAL3: - case Token.LITERAL4: - return true; - default: - return false; - } - } - } - private static void selectBeyondLine(View view, JEditTextArea textArea, Selection selection) { if (RubyPlugin.isRubyFile(view.getBuffer())) { try { @@ -226,11 +222,11 @@ if (!(hitMemberStart && hitMemberEnd)) { if (hitMemberStart) { int line = textArea.getLineOfOffset(member.getStartOffset()); - int offset = textArea.getLineStartOffset(line+1); + int offset = textArea.getLineStartOffset(line + 1); setSelection(offset, paragraphSelection.getEnd(), textArea); - } else if(hitMemberEnd) { + } else if (hitMemberEnd) { int line = textArea.getLineOfOffset(member.getEndOffset()); - int offset = textArea.getLineEndOffset(line-1); + int offset = textArea.getLineEndOffset(line - 1); setSelection(paragraphSelection.getStart(), offset, textArea); } } @@ -251,7 +247,7 @@ } private static void selectMemberOrParent(Member member, JEditTextArea textArea, Selection selection) { - if(insideMember(textArea, member)) { + if (insideMember(textArea, member)) { selectMemberContents(member, textArea); } @@ -322,6 +318,7 @@ /** * Selects the word at the caret position. + * * @since jEdit 2.7pre2 */ private static void selectWord(JEditTextArea textArea) { @@ -329,17 +326,17 @@ int lineStart = textArea.getLineStartOffset(line); int offset = textArea.getCaretPosition() - lineStart; - if(textArea.getLineLength(line) == 0) + if (textArea.getLineLength(line) == 0) return; String lineText = textArea.getLineText(line); String noWordSep = textArea.getBuffer().getStringProperty("noWordSep"); - if(offset == textArea.getLineLength(line)) + if (offset == textArea.getLineLength(line)) offset--; - int wordStart = TextUtilities.findWordStart(lineText,offset,noWordSep); - int wordEnd = TextUtilities.findWordEnd(lineText,offset+1,noWordSep); + int wordStart = TextUtilities.findWordStart(lineText, offset, noWordSep); + int wordEnd = TextUtilities.findWordEnd(lineText, offset + 1, noWordSep); Selection s = new Selection.Range(lineStart + wordStart, lineStart + wordEnd); addToSelection(textArea, s); @@ -347,12 +344,13 @@ /** * Selects the paragraph at the caret position. + * * @since jEdit 2.7pre2 */ private static void selectParagraph(JEditTextArea textArea) { int caretLine = textArea.getCaretLine(); - if(textArea.getLineLength(caretLine) == 0) { + if (textArea.getLineLength(caretLine) == 0) { textArea.getToolkit().beep(); return; } @@ -360,15 +358,15 @@ int start = caretLine; int end = caretLine; - while(start >= 0) { - if(textArea.getLineLength(start) == 0 || textArea.getLineText(start).trim().length() == 0) + while (start >= 0) { + if (textArea.getLineLength(start) == 0 || textArea.getLineText(start).trim().length() == 0) break; else start--; } - while(end < textArea.getLineCount()) { - if(textArea.getLineLength(end) == 0 || textArea.getLineText(end).trim().length() == 0) + while (end < textArea.getLineCount()) { + if (textArea.getLineLength(end) == 0 || textArea.getLineText(end).trim().length() == 0) break; else end++; @@ -377,20 +375,21 @@ int selectionStart = textArea.getLineStartOffset(start + 1); int selectionEnd = textArea.getLineEndOffset(end - 1) - 1; if (selectionEnd > selectionStart) { - Selection s = new Selection.Range(selectionStart,selectionEnd); + Selection s = new Selection.Range(selectionStart, selectionEnd); addToSelection(textArea, s); } } /** * Selects the current line. + * * @since jEdit 2.7pre2 */ private static void selectLine(JEditTextArea textArea) { int caretLine = textArea.getCaretLine(); int start = textArea.getLineStartOffset(caretLine); int end = textArea.getLineEndOffset(caretLine) - 1; - Selection s = new Selection.Range(start,end); + Selection s = new Selection.Range(start, end); addToSelection(textArea, s); } @@ -409,7 +408,7 @@ } private static void addToSelection(JEditTextArea textArea, Selection s) { - if(textArea.isMultipleSelectionEnabled()) { + if (textArea.isMultipleSelectionEnabled()) { textArea.addToSelection(s); } else { textArea.setSelection(s); --- NEW FILE: RubyToken.java --- package org.jedit.ruby.structure; import org.gjt.sp.jedit.syntax.Token; /** * @author robmckinnon at users,sourceforge,net */ public class RubyToken extends Token { private Token firstToken; private RubyToken previousToken; private RubyToken nextToken; public RubyToken(Token token, Token firstToken) { super(token.id, token.offset, token.length, token.rules); this.next = token.next; this.firstToken = firstToken; } public RubyToken getPreviousToken() { if (previousToken == null) { Token token = firstToken; Token previous = null; while (token != null && token.next != null) { if (isEqual(token.next)) { previous = token; break; } token = token.next; } previousToken = previous == null ? null : new RubyToken(previous, firstToken); } return previousToken; } public RubyToken getNextToken() { if (nextToken == null) { nextToken = next == null ? null : new RubyToken(next, firstToken); } return nextToken; } public boolean isNextLiteral() { return getNextToken() != null && getNextToken().isLiteral(); } public boolean isPreviousLiteral() { return getPreviousToken() != null && getPreviousToken().isLiteral(); } public boolean isLiteral() { switch (id) { case Token.LITERAL1: case Token.LITERAL2: case Token.LITERAL3: case Token.LITERAL4: return true; default: return false; } } public boolean isComment() { switch(id) { case Token.COMMENT1: case Token.COMMENT2: case Token.COMMENT3: case Token.COMMENT4: return true; default: return false; } } public String toString() { String id = this.id < Token.TOKEN_TYPES.length ? Token.TOKEN_TYPES[this.id] : String.valueOf(this.id); return id + '['+offset+','+(offset+length)+']'; } private boolean isEqual(Token token) { return token != null && token.id == id && token.offset == offset && token.length == length; } } Index: RubySideKickParser.java =================================================================== RCS file: /cvsroot/jedit/plugins/RubyPlugin/src/org/jedit/ruby/structure/RubySideKickParser.java,v retrieving revision 1.9 retrieving revision 1.10 diff -u -d -r1.9 -r1.10 --- RubySideKickParser.java 29 Oct 2005 19:07:19 -0000 1.9 +++ RubySideKickParser.java 6 Nov 2005 00:25:45 -0000 1.10 @@ -24,7 +24,6 @@ import sidekick.SideKickCompletion; import org.gjt.sp.jedit.Buffer; import org.gjt.sp.jedit.EditPane; -import org.gjt.sp.jedit.syntax.Token; import org.jruby.lexer.yacc.ISourcePosition; import org.jedit.ruby.ast.Member; import org.jedit.ruby.parser.RubyParser; @@ -45,9 +44,11 @@ private static DefaultErrorSource errorSource; private static final ErrorSource.Error[] EMPTY_ERROR_LIST = new ErrorSource.Error[0]; + private RubyTokenHandler tokenHandler; public RubySideKickParser() { super("ruby"); + tokenHandler = new RubyTokenHandler(); } public final boolean supportsCompletion() { @@ -60,7 +61,7 @@ public static ErrorSource.Error[] getErrors() { ErrorSource.Error[] errors = errorSource.getAllErrors(); - if(errors != null) { + if (errors != null) { return errors; } else { return EMPTY_ERROR_LIST; @@ -78,7 +79,7 @@ if (!members.containsErrors()) { addNodes(parentNode, members.getMembers(), buffer); - } else if(RubyParser.hasLastGoodMembers(buffer)) { + } else if (RubyParser.hasLastGoodMembers(buffer)) { members = RubyParser.getLastGoodMembers(buffer); addNodes(parentNode, members.combineMembersAndProblems(0), buffer); } else { @@ -96,7 +97,7 @@ public final SideKickCompletion complete(EditPane editPane, int caret) { RubyCompletion completion = null; - Token syntaxType = RubyPlugin.getToken(editPane.getBuffer(), caret); + RubyToken syntaxType = tokenHandler.getTokenAtCaret(editPane.getBuffer(), caret); if (!ignore(syntaxType)) { RubyPlugin.log("completing", getClass()); @@ -115,22 +116,13 @@ return completion; } - private boolean ignore(Token token) { - switch(token.id) { - case Token.COMMENT1: - case Token.COMMENT2: - case Token.COMMENT3: - case Token.COMMENT4: - case Token.LITERAL1: - case Token.LITERAL2: - case Token.LITERAL3: - case Token.LITERAL4: - RubyPlugin.log("ignoring: " + Token.TOKEN_TYPES[token.id], getClass()); - return true; - default: - String tokenType = token.id < Token.TOKEN_TYPES.length ? Token.TOKEN_TYPES[token.id] : String.valueOf(token.id); - RubyPlugin.log("not ignoring: " + tokenType, getClass()); - return false; + private boolean ignore(RubyToken token) { + if (token.isComment() || token.isLiteral()) { + RubyPlugin.log("ignoring: " + token, getClass()); + return true; + } else { + RubyPlugin.log("not ignoring: " + token, getClass()); + return false; } } @@ -158,8 +150,8 @@ } private void addNodes(DefaultMutableTreeNode parentNode, Member[] members, Buffer buffer) { - if(members != null) { - for(Member member : members) { + if (members != null) { + for (Member member : members) { MemberNode node = new org.jedit.ruby.structure.MemberNode(member); node.start = buffer.createPosition(Math.min(buffer.getLength(), member.getStartOffset())); node.end = buffer.createPosition(Math.min(buffer.getLength(), member.getEndOffset())); |