下面列出了org.eclipse.jface.text.IDocument#getChar ( ) 实例代码,或者点击链接到github查看源代码,也可以在右侧发表评论。
protected IRegion performMatch(IDocument doc, int caretOffset) throws BadLocationException {
final int charOffset= caretOffset - 1;
final char prevChar= doc.getChar(Math.max(charOffset, 0));
if (!fPairs.contains(prevChar)) return null;
final boolean isForward= fPairs.isStartCharacter(prevChar);
fAnchor= isForward ? ICharacterPairMatcher.LEFT : ICharacterPairMatcher.RIGHT;
final int searchStartPosition= isForward ? caretOffset : caretOffset - 2;
final int adjustedOffset= isForward ? charOffset : caretOffset;
final String partition= TextUtilities.getContentType(doc, fPartitioning, charOffset, false);
final DocumentPartitionAccessor partDoc= new DocumentPartitionAccessor(doc, fPartitioning, partition);
int endOffset= findMatchingPeer(partDoc, prevChar, fPairs.getMatching(prevChar),
isForward, isForward ? doc.getLength() : -1,
searchStartPosition);
if (endOffset == -1) return null;
final int adjustedEndOffset= isForward ? endOffset + 1: endOffset;
if (adjustedEndOffset == adjustedOffset) return null;
return new Region(Math.min(adjustedOffset, adjustedEndOffset),
Math.abs(adjustedEndOffset - adjustedOffset));
}
public ExitFlags doExit(LinkedModeModel model, VerifyEvent event, int offset, int length) {
if (fSize == fStack.size() && !isMasked(offset)) {
if (event.character == fExitCharacter) {
BracketLevel level = (BracketLevel) fStack.peek();
if (level.fFirstPosition.offset > offset || level.fSecondPosition.offset < offset)
return null;
if (level.fSecondPosition.offset == offset && length == 0)
// don't enter the character if if its the closing peer
return new ExitFlags(ILinkedModeListener.UPDATE_CARET, false);
}
// when entering an anonymous class between the parenthesis', we
// don't want
// to jump after the closing parenthesis when return is pressed
if (event.character == SWT.CR && offset > 0) {
IDocument document = getSourceViewer().getDocument();
try {
if (document.getChar(offset - 1) == '{')
return new ExitFlags(ILinkedModeListener.EXIT_ALL, true);
} catch (BadLocationException e) {
}
}
}
return null;
}
/**
* If a _ is not a word break character, see if the BreakIterator stopped on one
*
* @param doc
* @param pos
* @return new offset if word moves past any _'s, else pos
*/
int checkUnder(IDocument doc, int pos) {
int result = pos;
try {
if (!isUnder()) {
char c = doc.getChar(pos);
if (!isDot() || c != '.') {
IRegion lineInfo = doc.getLineInformationOfOffset(pos);
int p = pos;
// if we're at or just moved over an _
if (c == '_' || (--p >= lineInfo.getOffset() && doc.getChar(p) == '_')) {
int end = (lineInfo.getOffset() + lineInfo.getLength());
if (end > p) {
Matcher matcher = getUnderMatcher();
matcher.reset(doc.get(p, end - p));
if (matcher.matches()) {
result = p + matcher.end(1);
}
}
}
}
}
} catch (BadLocationException e) {
}
return result;
}
/**
* Count the whitespace to the left and right of offset, potentially counting over EOLs.
* @param document
* @param offset
* @param dir
* @param ignoreCR - count over EOLs if true
* @return the whitespace count
* @throws BadLocationException
*/
protected int countWS(IDocument document, int offset, int dir, boolean ignoreCR) throws BadLocationException {
String eol = getLineDelimiter();
int lineOff = offset;
int off = offset;
int lastOff = document.getLength(); // -1; // n
char c;
while ((-1 < off && off < lastOff) && (c = document.getChar(off)) <= ' ') {
if (eol.indexOf(c) != -1) {
if (!ignoreCR) {
break;
}
// preserve the position past the last EOL
lineOff = off + dir;
}
off = off + dir;
}
// if ignoreCR == true, then we're interested in complete blank lines only
return Math.abs(offset - (ignoreCR ? lineOff : off));
}
/**
*
* This leaves a bit of a mess e.g. "import " or "from " for some later process to clean up.
*
*/
private void deleteImport(PySelection ps, MarkerAnnotationAndPosition markerInfo)
throws BadLocationException, CoreException {
IMarker marker = markerInfo.markerAnnotation.getMarker();
Integer start = (Integer) marker.getAttribute(IMarker.CHAR_START);
Integer end = (Integer) marker.getAttribute(IMarker.CHAR_END);
IDocument doc = ps.getDoc();
while (start > 0) {
char c;
try {
c = doc.getChar(start - 1);
} catch (Exception e) {
break;
}
if (c == '\r' || c == '\n') {
break;
}
if (Character.isWhitespace(c) || c == ',') {
start--;
continue;
}
break;
}
ps.setSelection(start, end);
ps.deleteSelection();
}
/**
* Checks whether a character to be inserted is already present at the insert location (perhaps
* separated by some whitespace from <code>position</code>.
*
* @param document the document we are working on
* @param position the insert position of <code>ch</code>
* @param ch the character to be inserted
* @return <code>true</code> if <code>ch</code> is already present at <code>location</code>, <code>false</code> otherwise
*/
private boolean alreadyPresent(IDocument document, char ch, int position) {
int pos= firstNonWhitespaceForward(document, position, fPartitioning, document.getLength());
try {
if (pos != -1 && document.getChar(pos) == ch)
return true;
} catch (BadLocationException e) {
}
return false;
}
public String updateReplacementString(IDocument document, int offset, ImportRewrite impRewrite) throws CoreException, BadLocationException {
// Construct empty body for performance concern
// See https://github.com/microsoft/language-server-protocol/issues/1032#issuecomment-648748013
String newBody = fSnippetSupport ? "{\n\t${0}\n}" : "{\n\n}";
StringBuilder buf = new StringBuilder("new A()"); //$NON-NLS-1$
buf.append(newBody);
// use the code formatter
String lineDelim = TextUtilities.getDefaultLineDelimiter(document);
final IJavaProject project = fCompilationUnit.getJavaProject();
IRegion lineInfo = document.getLineInformationOfOffset(fReplacementOffset);
Map<String, String> options = project != null ? project.getOptions(true) : JavaCore.getOptions();
String replacementString = CodeFormatterUtil.format(CodeFormatter.K_EXPRESSION, buf.toString(), 0, lineDelim, options);
int lineEndOffset = lineInfo.getOffset() + lineInfo.getLength();
int p = offset;
if (p < document.getLength()) {
char ch = document.getChar(p);
while (p < lineEndOffset) {
if (ch == '(' || ch == ')' || ch == ';' || ch == ',') {
break;
}
ch = document.getChar(++p);
}
if (ch != ';' && ch != ',' && ch != ')') {
replacementString = replacementString + ';';
}
}
int beginIndex = replacementString.indexOf('(');
replacementString = replacementString.substring(beginIndex);
return replacementString;
}
/**
* @see com.mulgasoft.emacsplus.commands.EmacsPlusNoEditHandler#transform(org.eclipse.ui.texteditor.ITextEditor, org.eclipse.jface.text.IDocument, org.eclipse.jface.text.ITextSelection, org.eclipse.core.commands.ExecutionEvent)
*/
@Override
protected int transform(ITextEditor editor, IDocument document, ITextSelection currentSelection,
ExecutionEvent event) throws BadLocationException {
String msg = null;
int offset = getCursorOffset(editor,currentSelection);
int docLen = document.getLength();
IRegion line = document.getLineInformationOfOffset(offset);
if (offset >= docLen) {
msg = String.format(EOB_POSITION, offset,docLen);
} else {
char curChar = document.getChar(offset);
String sChar = ""; //$NON-NLS-1$
int percent = new Float(((offset * 100) / docLen) + .5).intValue();
if (offset == line.getOffset() + line.getLength()){
String ld = document.getLineDelimiter(document.getLineOfOffset(offset));
char[] points = ld.toCharArray();
for (int i=0; i<points.length; i++) {
sChar += normalizeChar(points[i]);
}
msg = String.format(EOL_POSITION, sChar,offset,docLen,percent);
} else {
int curCode = (int) curChar;
sChar = (curChar <= ' ' ? normalizeChar(curChar) : String.valueOf(curChar));
msg = String.format(CURSOR_POSITION, sChar, curCode, curCode, curCode, offset, docLen, percent);
}
}
EmacsPlusUtils.showMessage(editor, msg, false);
setCmdResult(new Integer(offset));
return super.transform(editor, document, currentSelection, event);
}
protected int getCommentEnd(IDocument d, int pos, int end) throws BadLocationException {
while (pos < end) {
char curr= d.getChar(pos);
pos++;
if (curr == '*') {
if (pos < end && d.getChar(pos) == '/') {
return pos + 1;
}
}
}
return end;
}
/**
* Computes an insert position for an opening brace if <code>offset</code> maps to a position in
* <code>document</code> that looks like being the RHS of an assignment or like an array definition.
*
* @param document the document being modified
* @param line the current line under investigation
* @param offset the offset of the caret position, relative to the line start.
* @param partitioning the document partitioning
* @return an insert position relative to the line start if <code>line</code> looks like being an array initialization at <code>offset</code>, -1 otherwise
*/
private static int computeArrayInitializationPos(IDocument document, ITextSelection line, int offset, String partitioning) {
// search backward while WS, find = (not != <= >= ==) in default partition
int pos= offset + line.getOffset();
if (pos == 0)
return -1;
int p= firstNonWhitespaceBackward(document, pos - 1, partitioning, -1);
if (p == -1)
return -1;
try {
char ch= document.getChar(p);
if (ch != '=' && ch != ']')
return -1;
if (p == 0)
return offset;
p= firstNonWhitespaceBackward(document, p - 1, partitioning, -1);
if (p == -1)
return -1;
ch= document.getChar(p);
if (Character.isJavaIdentifierPart(ch) || ch == ']' || ch == '[')
return offset;
} catch (BadLocationException e) {
}
return -1;
}
public int getIndentationLevelAtOffset(int offset, IDocument document, XtextResource resource) {
try {
if (offset <= 0)
return 0;
int currentOffset = offset - 1;
char currentChr = document.getChar(currentOffset);
int indentationOffset = 0;
if(currentChr == '\n' || currentChr == '\r') {
-- currentOffset;
if(currentOffset < 0)
return 0;
currentChr = document.getChar(currentOffset);
}
while (currentChr != '\n' && currentChr != '\r' && currentOffset > 0) {
if (Character.isWhitespace(currentChr))
++indentationOffset;
else
indentationOffset = 0;
--currentOffset;
currentChr = document.getChar(currentOffset);
}
return indentationOffset / getIndentString(resource).length();
} catch (BadLocationException e) {
LOG.error("Error calculating indentation at offset", e);
}
return 0;
}
private int getCommentEnd(IDocument d, int offset, int endOffset) throws BadLocationException {
while (offset < endOffset) {
char curr= d.getChar(offset);
offset++;
if (curr == '*') {
if (offset < endOffset && d.getChar(offset) == '/') {
return offset + 1;
}
}
}
return endOffset;
}
/**
* From <code>position</code> to the left, eats any whitespace and then a pair of brackets
* as used to declare an array return type like <pre>String [ ]</pre>.
* The return value is either the position of the opening bracket or <code>position</code> if no
* pair of brackets can be parsed.
*
* @param document the document being modified
* @param position the first character position in <code>document</code> to be considered
* @param partitioning the document partitioning
* @return the smallest character position of bracket pair or <code>position</code>
*/
private static int eatBrackets(IDocument document, int position, String partitioning) {
// accept array return type
int pos= firstNonWhitespaceBackward(document, position, partitioning, -1);
try {
if (pos > 1 && document.getChar(pos) == ']') {
pos= firstNonWhitespaceBackward(document, pos - 1, partitioning, -1);
if (pos > 0 && document.getChar(pos) == '[')
return pos;
}
} catch (BadLocationException e) {
// won't happen
}
return position;
}
/**
* At a given position in text retrieves the region marking the word, starting at and ending after the current position
* @param document document
* @param documentOffset offset (position of the cursor)
* @param detector for identification of words
* @return a region expanded forward
*/
public static IRegion getRegionExpandedForwards(IDocument document, int documentOffset, IWordDetector detector)
{
// Use string buffer to collect characters
int charCounter = 0;
while (true)
{
try
{
// Read character forward
char c = document.getChar(++documentOffset);
// This was the start of a word
if (!detector.isWordPart(c))
break;
// Count character
charCounter++;
} catch (BadLocationException e)
{
// Document end reached, no word
break;
}
}
return new Region(documentOffset - charCounter, charCounter + 1);
}
private boolean hasEndJavadoc(IDocument document, int offset) throws BadLocationException {
int pos = -1;
while (offset < document.getLength()) {
char c = document.getChar(offset);
if (!Character.isWhitespace(c) && !(c == '*')) {
pos = offset;
break;
}
offset++;
}
if (document.getLength() >= pos + 2 && document.get(pos - 1, 2).equals("*/")) {
return true;
}
return false;
}
/**
* Computes and returns the indentation for a javadoc line. The line
* must be inside a javadoc comment.
*
* @param document the document
* @param line the line in document
* @param scanner the scanner
* @param partition the comment partition
* @return the indent, or <code>null</code> if not computable
* @throws BadLocationException
*/
private static String computeJavadocIndent(IDocument document, int line, JavaHeuristicScanner scanner, ITypedRegion partition) throws BadLocationException {
if (line == 0) // impossible - the first line is never inside a javadoc comment
return null;
// don't make any assumptions if the line does not start with \s*\* - it might be
// commented out code, for which we don't want to change the indent
final IRegion lineInfo= document.getLineInformation(line);
final int lineStart= lineInfo.getOffset();
final int lineLength= lineInfo.getLength();
final int lineEnd= lineStart + lineLength;
int nonWS= scanner.findNonWhitespaceForwardInAnyPartition(lineStart, lineEnd);
if (nonWS == JavaHeuristicScanner.NOT_FOUND || document.getChar(nonWS) != '*') {
if (nonWS == JavaHeuristicScanner.NOT_FOUND)
return document.get(lineStart, lineLength);
return document.get(lineStart, nonWS - lineStart);
}
// take the indent from the previous line and reuse
IRegion previousLine= document.getLineInformation(line - 1);
int previousLineStart= previousLine.getOffset();
int previousLineLength= previousLine.getLength();
int previousLineEnd= previousLineStart + previousLineLength;
StringBuffer buf= new StringBuffer();
int previousLineNonWS= scanner.findNonWhitespaceForwardInAnyPartition(previousLineStart, previousLineEnd);
if (previousLineNonWS == JavaHeuristicScanner.NOT_FOUND || document.getChar(previousLineNonWS) != '*') {
// align with the comment start if the previous line is not an asterix line
previousLine= document.getLineInformationOfOffset(partition.getOffset());
previousLineStart= previousLine.getOffset();
previousLineLength= previousLine.getLength();
previousLineEnd= previousLineStart + previousLineLength;
previousLineNonWS= scanner.findNonWhitespaceForwardInAnyPartition(previousLineStart, previousLineEnd);
if (previousLineNonWS == JavaHeuristicScanner.NOT_FOUND)
previousLineNonWS= previousLineEnd;
// add the initial space
// TODO this may be controlled by a formatter preference in the future
buf.append(' ');
}
String indentation= document.get(previousLineStart, previousLineNonWS - previousLineStart);
buf.insert(0, indentation);
return buf.toString();
}
/**
* Computes quick assists for the console.
*/
@Override
public ICompletionProposal[] computeQuickAssistProposals(IQuickAssistInvocationContext invocationContext) {
ISourceViewer sourceViewer = invocationContext.getSourceViewer();
List<ICompletionProposalHandle> props = new ArrayList<ICompletionProposalHandle>();
if (sourceViewer instanceof ScriptConsoleViewer) {
ScriptConsoleViewer viewer = (ScriptConsoleViewer) sourceViewer;
//currently, only the assign quick assist is used
AssistAssign assistAssign = new AssistAssign();
ISelection selection = sourceViewer.getSelectionProvider().getSelection();
if (selection instanceof ITextSelection) {
PySelection ps = PySelectionFromEditor.createPySelectionFromEditor(sourceViewer,
(ITextSelection) selection);
int offset = viewer.getCaretOffset();
String commandLine = viewer.getCommandLine();
//let's calculate the 1st line that is not a whitespace.
if (assistAssign.isValid(ps.getSelLength(), commandLine, offset)) {
int commandLineOffset = viewer.getCommandLineOffset();
try {
IDocument doc = sourceViewer.getDocument();
while (true) {
if (commandLineOffset == doc.getLength() - 1) {
break;
}
char c = doc.getChar(commandLineOffset);
if (Character.isWhitespace(c)) {
commandLineOffset++;
} else {
break;
}
}
props.addAll(assistAssign.getProps(ps, SharedUiPlugin.getImageCache(), sourceViewer, offset,
commandLine, commandLineOffset));
} catch (BadLocationException e) {
Log.log(e);
}
}
}
}
return ConvertCompletionProposals
.convertHandlesToProposals(props.toArray(new ICompletionProposalHandle[props.size()]));
}
/**
*
* @param ps
* @throws BadLocationException
*/
private void eraseSingleChar(PySelection ps) throws BadLocationException {
ICoreTextSelection textSelection = ps.getTextSelection();
int replaceLength = 1;
int replaceOffset = textSelection.getOffset() - replaceLength;
IDocument doc = ps.getDoc();
if (replaceOffset >= 0 && replaceOffset + replaceLength < doc.getLength()) {
char c = doc.getChar(replaceOffset);
if (c == '(' || c == '[' || c == '{') {
//When removing a (, check if we have to delete the corresponding ) too.
char peer = StringUtils.getPeer(c);
if (replaceOffset + replaceLength < doc.getLength()) {
char c2 = doc.getChar(replaceOffset + 1);
if (c2 == peer) {
//Ok, there's a closing one right next to it, now, what we have to do is
//check if the user was actually removing that one because there's an opening
//one without a match.
//To do that, we go backwards in the document searching for an opening match and then
//search its match. If it's found, it means we can delete both, otherwise, this
//delete will make things correct.
//Create a matcher only matching this char
PythonPairMatcher pythonPairMatcher = new PythonPairMatcher(new char[] { c, peer });
int openingPeerOffset = pythonPairMatcher.searchForAnyOpeningPeer(replaceOffset, doc);
if (openingPeerOffset == -1) {
replaceLength += 1;
} else {
int closingPeerOffset = pythonPairMatcher.searchForClosingPeer(openingPeerOffset, c, peer,
doc);
if (closingPeerOffset != -1) {
//we have a match, so, things are balanced and we can delete the next
replaceLength += 1;
}
}
}
}
} else if (c == '\'' || c == '"') {
//when removing a ' or ", check if we have to delete another ' or " too.
Tuple<String, String> beforeAndAfterMatchingChars = ps.getBeforeAndAfterMatchingChars(c);
int matchesBefore = beforeAndAfterMatchingChars.o1.length();
int matchesAfter = beforeAndAfterMatchingChars.o2.length();
if (matchesBefore == 1 && matchesBefore == matchesAfter) {
replaceLength += 1;
}
}
}
makeDelete(doc, replaceOffset, replaceLength);
}
private ICompletionProposal[] standardMethod(ITextViewer viewer, int offset, List<String> keywords, List<ICompletionProposal> autoCompProposals) {
int index = offset - 1;
StringBuffer prefix = new StringBuffer();
IDocument document = viewer.getDocument();
while (index > 0) {
try {
char prev = document.getChar(index);
if (Character.isWhitespace(prev)) {
break;
}
prefix.insert(0, prev);
index--;
}
catch (BadLocationException ble) {
Activator.getDefault().log("could not get char", ble);
}
}
if (prefix.length() > 0) {
String word = prefix.toString();
// limit to attributes
if (containsOpenBracket(word)) {
autoCompProposals.addAll(addHeaderAttributes(word, offset));
}
for (String keyword : keywords) {
if (keyword.toUpperCase(Locale.ENGLISH).startsWith(word.toUpperCase(Locale.ENGLISH)) && word.length() < keyword.length()) {
autoCompProposals.add(new CompletionProposal(keyword + " ", index + 1, offset - (index + 1), keyword.length() + 1));
}
}
}
else {
// propose header keywords
proposeHeaderOperands(offset, document, autoCompProposals);
}
if (!autoCompProposals.isEmpty()) {
return (ICompletionProposal[]) autoCompProposals.toArray(new ICompletionProposal[autoCompProposals.size()]);
}
return null;
}
/**
* Returns the first offset greater than <code>offset</code> and smaller than
* <code>end</code> whose character is not a space or tab character. If no such
* offset is found, <code>end</code> is returned.
*
* @param document the document to search in
* @param offset the offset at which searching start
* @param end the offset at which searching stops
* @return the offset in the specified range whose character is not a space or tab
* @exception BadLocationException if position is an invalid range in the given document
*/
private int findEndOfWhiteSpace(IDocument document, int offset, int end) throws BadLocationException {
while (offset < end) {
char c = document.getChar(offset);
if (c != ' ' && c != '\t') {
return offset;
}
offset++;
}
return end;
}