-
-
Save mseddon/bb8b50f04604e186aeed491749079db7 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import * as vscode from "vscode"; | |
class ClojureSourceLine { | |
constructor(public text: string) {} | |
get length() { | |
return this.text.length; | |
} | |
} | |
let debugValidation = false | |
class DocumentMirror { | |
lines: ClojureSourceLine[] = []; | |
constructor(public doc: vscode.TextDocument) { | |
for(let i=0; i<doc.lineCount; i++) { | |
let line = doc.lineAt(i); | |
this.lines.push(new ClojureSourceLine(line.text)); | |
} | |
} | |
changeRange(e: vscode.TextDocumentContentChangeEvent) { | |
let replaceLines = e.text.split(this.doc.eol == vscode.EndOfLine.LF ? /\n/ : /\r\n/); | |
let left = this.lines[e.range.start.line].text.substr(0, e.range.start.character); | |
let right = this.lines[e.range.end.line].text.substr(e.range.end.character); | |
let items: ClojureSourceLine[] = []; | |
if(replaceLines.length == 1) { | |
items.push(new ClojureSourceLine(left + replaceLines[0] + right)); | |
} else { | |
items.push(new ClojureSourceLine(left + replaceLines[0])); | |
for(let i=1; i<replaceLines.length-1; i++) { | |
items.push(new ClojureSourceLine(replaceLines[i])); | |
} | |
items.push(new ClojureSourceLine(replaceLines[replaceLines.length-1] + right)) | |
} | |
this.lines.splice(e.range.start.line, e.range.end.line-e.range.start.line+1, ...items); | |
} | |
processChanges(e: vscode.TextDocumentContentChangeEvent[]) { | |
for(let change of e) { | |
this.changeRange(change); | |
} | |
if(debugValidation && this.doc.getText() != this.text) { | |
vscode.window.showErrorMessage("DocumentMirror failed"); | |
} | |
} | |
get text() { | |
return this.lines.map(x => x.text).join(this.doc.eol == vscode.EndOfLine.LF ? "\n" : "\r\n"); | |
} | |
} | |
let documents = new Map<vscode.TextDocument, DocumentMirror>(); | |
let registered = false; | |
export function activate() { | |
// the last thing we want is to register twice and receive double events... | |
if(registered) | |
return; | |
registered = true; | |
vscode.workspace.onDidCloseTextDocument(e => { | |
if(e.languageId == "clojure") { | |
documents.delete(e); | |
} | |
}) | |
vscode.workspace.onDidChangeTextDocument(e => { | |
if(e.document.languageId == "clojure") { | |
if(!documents.get(e.document)) | |
documents.set(e.document, new DocumentMirror(e.document)); | |
else | |
documents.get(e.document).processChanges(e.contentChanges) | |
} | |
}) | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment