blob: 5edd6e72d41725335895e99ef0ed2b7765d47c38 [file] [log] [blame]
/*=============================================================================#
# Copyright (c) 2015, 2018 Stephan Wahlbrink and others.
#
# This program and the accompanying materials are made available under the
# terms of the Eclipse Public License 2.0 which is available at
# https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0
# which is available at https://www.apache.org/licenses/LICENSE-2.0.
#
# SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
#
# Contributors:
# Stephan Wahlbrink <sw@wahlbrink.eu> - initial API and implementation
#=============================================================================*/
package org.eclipse.statet.docmlet.wikitext.commonmark.ui;
import java.util.Locale;
import org.eclipse.jface.text.BadLocationException;
import org.eclipse.jface.text.IDocument;
import org.eclipse.statet.docmlet.wikitext.commonmark.core.ParseHelper;
import org.eclipse.statet.docmlet.wikitext.core.markup.IMarkupLanguage;
import org.eclipse.statet.docmlet.wikitext.ui.sourceediting.IMarkupCompletionExtension;
import org.eclipse.statet.ltk.ui.sourceediting.assist.AssistInvocationContext;
public class CommonmarkCompletionExtension implements IMarkupCompletionExtension {
private final ParseHelper helper= new ParseHelper();
public CommonmarkCompletionExtension() {
}
@Override
public CompletionType getLinkAnchorLabel(final AssistInvocationContext context, final IMarkupLanguage markupLanguage) {
try {
final IDocument document= context.getDocument();
final int endOffset= context.getOffset();
int startOffset= endOffset;
while (startOffset > 0) {
final char c= document.getChar(--startOffset);
if (Character.isLetterOrDigit(c) || c == '-' || c == '_' || c == ':' || c == '.') {
continue;
}
if (c == '#' && startOffset > 0 && document.getChar(startOffset - 1) != '\\') {
startOffset++;
return new CompletionType(document.get(startOffset, endOffset - startOffset));
}
break;
}
}
catch (final BadLocationException e) {}
return null;
}
@Override
public CompletionType getLinkRefLabel(final AssistInvocationContext context, final IMarkupLanguage markupLanguage) {
try {
final IDocument document= context.getDocument();
final int endOffset= context.getInvocationOffset();
int startOffset= endOffset;
final int lookupBound= Math.max(startOffset - 1000, 0);
while (startOffset > lookupBound) {
final char c= document.getChar(--startOffset);
if (c == '[' && !isEscaped(document, startOffset)) {
startOffset= forwardBlank(document, ++startOffset, endOffset);
final String sourcePrefix= document.get(startOffset, endOffset - startOffset);
final String lookupPrefix= normalizeLabel(sourcePrefix);
return new CompletionType(sourcePrefix, lookupPrefix);
}
if (c != '\n' || c != '\r') {
continue;
}
break;
}
}
catch (final BadLocationException e) {}
return null;
}
private boolean isEscaped(final IDocument document, int offset) throws BadLocationException {
int count= 0;
while (offset > 0) {
if (document.getChar(--offset) == '\\') {
count++;
}
else {
break;
}
}
return (count % 2) == 1;
}
private int forwardBlank(final IDocument document, int offset, final int endOffset) throws BadLocationException {
while (offset < endOffset) {
final char c= document.getChar(offset);
if (c == ' ' || c == '\t') {
offset++;
continue;
}
break;
}
return offset;
}
private String normalizeLabel(String label) {
if (label.isEmpty()) {
return "";
}
label= this.helper.collapseWhitespace(label);
if (label.isEmpty()) {
return "";
}
return label.toLowerCase(Locale.ROOT);
}
}