Skip to content

Commit

Permalink
#21: highlight code blocks
Browse files Browse the repository at this point in the history
Beginning working on highlighting code blocks.
  • Loading branch information
timmhirsens committed Dec 8, 2016
1 parent 4c62be3 commit 20da5d6
Show file tree
Hide file tree
Showing 2 changed files with 87 additions and 0 deletions.
77 changes: 77 additions & 0 deletions src/elixirHighlightProvider.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
import * as vscode from 'vscode';

export class ElixirHighlightProvider implements vscode.DocumentHighlightProvider {

balancedPairs: BalancedPair[];

constructor() { }

provideDocumentHighlights(document: vscode.TextDocument, position: vscode.Position, token: vscode.CancellationToken): vscode.DocumentHighlight[] {
const result = this.balancedPairs.find(pair => (
pair.entry.start.line === position.line ||
pair.end.start.line === position.line));
if (result) {
return [new vscode.DocumentHighlight(result.entry, 2), new vscode.DocumentHighlight(result.end, 2)];
}
}

balanceEvent(event: vscode.TextEditor) {
if (event && event.document) {
this.balancePairs(event.document);
}
}

balancePairs(document: vscode.TextDocument) {
this.balancedPairs = [];
if (document.languageId !== 'elixir') {
return;
}
const waitingEntries: vscode.Range[] = [];
let entry: vscode.Range;
let end: vscode.Range;
for (let i = 0; i < document.lineCount; i++) {
if ((entry = this.getEntry(document.lineAt(i)))) {
waitingEntries.push(entry);
} else if (waitingEntries.length && (end = this.getEnd(document.lineAt(i)))) {
this.balancedPairs.push({
entry: waitingEntries.pop(),
end: end
});
}
}


}

getEntry(line: vscode.TextLine): vscode.Range {
let match = line.text.match(/^(?!.*do\:)(\s*)(def|defp|defmodule|defmacro|quote|case|cond|if|unless|try)\b.*$/);
if (match) {
return new vscode.Range(line.lineNumber, match[1].length, line.lineNumber, match[1].length + match[2].length);
} else {
match = line.text.match(/\b(do)\b\s*(\|.*\|[^;]*)?$/);
if (match) {
return new vscode.Range(line.lineNumber, match.index, line.lineNumber, match.index + 2);
} else {
match = line.text.match(/(?!.*do\:)\b(fn)\b.*$/);
if (match) {
return new vscode.Range(line.lineNumber, match.index, line.lineNumber, match.index + 2);
}
}
}
}

getEnd(line: vscode.TextLine): vscode.Range {
//end must be on a line by itself, or followed directly by a dot
const match = line.text.match(/^(\s*)end\b[\.\s#]?\s*$/);
if (match) {
return new vscode.Range(line.lineNumber, match[1].length, line.lineNumber, match[1].length + 3);
}

}

}

interface BalancedPair {
entry: vscode.Range;
end: vscode.Range;
}
10 changes: 10 additions & 0 deletions src/elixirMain.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,27 @@ import * as vscode from 'vscode';
import { ElixirAutocomplete } from './elixirAutocomplete';
import { ElixirServer } from './elixirServer';
import { ElixirDefinitionProvider } from './elixirDefinitionProvider';
import { ElixirHighlightProvider } from './elixirHighlightProvider';
import {configuration} from './elixirConfiguration';

const ELIXIR_MODE: vscode.DocumentFilter = { language: 'elixir', scheme: 'file' };
let elixirServer: ElixirServer;

export function activate(ctx: vscode.ExtensionContext) {
this.elixirServer = new ElixirServer();
const elixirHighlightProvider = new ElixirHighlightProvider();
this.elixirServer.start();
ctx.subscriptions.push(vscode.languages.registerCompletionItemProvider(ELIXIR_MODE, new ElixirAutocomplete(this.elixirServer)));
ctx.subscriptions.push(vscode.languages.registerDefinitionProvider(ELIXIR_MODE, new ElixirDefinitionProvider(this.elixirServer)));
ctx.subscriptions.push(vscode.languages.setLanguageConfiguration('elixir', configuration));
ctx.subscriptions.push(vscode.languages.registerDocumentHighlightProvider('elixir', elixirHighlightProvider));
ctx.subscriptions.push(vscode.window.onDidChangeActiveTextEditor(elixirHighlightProvider.balanceEvent.bind(elixirHighlightProvider)));
ctx.subscriptions.push(vscode.workspace.onDidChangeTextDocument(elixirHighlightProvider.balanceEvent.bind(elixirHighlightProvider)));
ctx.subscriptions.push(vscode.workspace.onDidOpenTextDocument(elixirHighlightProvider.balanceEvent.bind(elixirHighlightProvider)));
if (vscode.window && vscode.window.activeTextEditor) {
elixirHighlightProvider.balancePairs(vscode.window.activeTextEditor.document);
}

}

export function deactivate() {
Expand Down

0 comments on commit 20da5d6

Please sign in to comment.