Skip to content

Commit

Permalink
🐛 fix #31 Format Document
Browse files Browse the repository at this point in the history
  • Loading branch information
xsro committed Dec 2, 2021
1 parent d608127 commit 5006d0b
Show file tree
Hide file tree
Showing 3 changed files with 45 additions and 21 deletions.
50 changes: 32 additions & 18 deletions src/language/AsmDocumentFormattingEdit.ts
Original file line number Diff line number Diff line change
@@ -1,35 +1,52 @@
import * as vscode from 'vscode';
import { eolString } from '../utils/eol';
import { DocInfo, linetype, Asmline } from "./scanDoc";

//TODO: offer different operation for different vscode.FormattingOptions
export class AsmDocFormat implements vscode.DocumentFormattingEditProvider {
provideDocumentFormattingEdits(document: vscode.TextDocument): vscode.TextEdit[] {
provideDocumentFormattingEdits(document: vscode.TextDocument, options: vscode.FormattingOptions, token: vscode.CancellationToken): vscode.TextEdit[] {
const textedits: vscode.TextEdit[] = [];
const tabString = options.insertSpaces ? new Array(options.tabSize).fill(" ").join("") : "\t";
const docinfo = DocInfo.getDocInfo(document);
if (docinfo.tree) {
docinfo.tree.forEach(
(item) => {
formateline(item.range.start.line, item.range.end.line, docinfo.lines, document, textedits);
for (const item of docinfo.tree) {
if (token.isCancellationRequested) {
return textedits;
}
);
const newText = formateline(item.range, docinfo.lines, tabString);
const range = document.validateRange(item.range);
textedits.push(new vscode.TextEdit(range, newText.join(eolString(document.eol))));
}
}
return textedits;
}
}
function formateline(beg: number, end: number, asmline: Asmline[], document: vscode.TextDocument, formator: vscode.TextEdit[]): vscode.TextEdit[] {

/**
* format a segment of assembly code
* @param range the range of the code
* @param asmline the array of lines information
* @param tabString the string to used as tab
* @returns
*/
function formateline(range: vscode.Range, asmline: Asmline[], tabString = "\t"): string[] {
let namesize = 0, optsize = 0, oprsize = 0,
str: string | undefined = undefined, r: vscode.Range, i: number;
str: string | undefined = undefined;
const output: string[] = [];

//scan the asmlines for information
for (i = beg; i < end; i++) {
for (let i = range.start.line; i <= range.end.line; i++) {
const item = asmline[i];
if (item.name) { namesize = item.name.length > namesize ? item.name.length : namesize; }//find the maxlength of label name or variabel name
if (item.operator) { optsize = item.operator.length > optsize ? item.operator.length : optsize; }//find the maxlength of operator
if (item.operand) { oprsize = item.operand.length > oprsize ? item.operand.length : oprsize; }//find the maxlength of operand
}
for (i = beg; i < end; i++) {

for (let i = range.start.line; i <= range.end.line; i++) {
str = undefined;
const item = asmline[i];
if (item.type === linetype.label || item.type === linetype.variable) {
str = "\t";
str = tabString;
let length = 0;
if (item.name?.length) { length = item.name.length; }
if (item.type === linetype.label && item.name) { str += item.name + ":"; }
Expand All @@ -47,25 +64,22 @@ function formateline(beg: number, end: number, asmline: Asmline[], document: vsc
if (item.operand?.length) { length = item.operand.length; }
else { length = 0; }
for (let i = 0; i < oprsize - length; i++) { str += " "; }//操作数后补充空格
str += "\t" + item.comment;
str += tabString + item.comment;
}
}
else if (item.type === linetype.onlycomment) {
str = "\t" + item.comment;
str = tabString + item.comment;
}
else if (item.main) {
str = item.main.replace(/\s+/, " ");
const length: number = namesize + 1 + optsize + 1 + oprsize - str.length;
if (item.comment) {
for (let i = 0; i < length; i++) { str += " "; }//后补充空格
str += "\t\t" + item.comment;
str += tabString + tabString + item.comment;
}
}
if (str && str !== item.str) {
r = new vscode.Range(item.line, 0, item.line, item.str.length);
formator.push(vscode.TextEdit.replace(document.validateRange(r), str));
}
output.push(str && str !== item.str ? str : item.str);
}
return formator;
return output;
}

6 changes: 3 additions & 3 deletions src/language/scanDoc.ts
Original file line number Diff line number Diff line change
Expand Up @@ -276,7 +276,7 @@ function lines2tree(asmlines: Asmline[]): SYMBOLINFO {
}
//finded the end of macro
if (line.name && lineEndmacro?.line) {
const macrorange = new vscode.Range(line.line, line.index, lineEndmacro?.line, lineEndmacro?.index);
const macrorange = new vscode.Range(line.line, line.index, lineEndmacro?.line, lineEndmacro.str.length);
symbols.push(new AsmSymbol(KeywordType.Macro, line.name, macrorange));
const symbol1 = new vscode.DocumentSymbol(line.name, getType(KeywordType.Macro), SymbolVSCfy(KeywordType.Macro), macrorange, new vscode.Range(line.line, line.index, line.line, line.index + line.name.length));
VSCsymbols.push(symbol1);
Expand All @@ -296,7 +296,7 @@ function lines2tree(asmlines: Asmline[]): SYMBOLINFO {
if (array[i].type === linetype.endp && proc?.name === array[i].name) {
const _name = array[i].name;
if (proc?.name && _name) {
const range: vscode.Range = new vscode.Range(proc?.line, proc?.index, array[i].line, array[i].index + _name.length);
const range: vscode.Range = new vscode.Range(proc?.line, proc?.index, array[i].line, array[i].str.length);
const srange: vscode.Range = new vscode.Range(proc.line, proc.index, proc?.line, proc?.index + proc?.name?.length);
procschild.push(new vscode.DocumentSymbol(proc?.name, getType(KeywordType.Procedure), SymbolVSCfy(KeywordType.Procedure), range, srange));
symbols.push(new AsmSymbol(KeywordType.Procedure, _name, range));
Expand All @@ -315,7 +315,7 @@ function lines2tree(asmlines: Asmline[]): SYMBOLINFO {
}
//finded the end of segment
if (line.name && lineEndSegment?.line) {
const range = new vscode.Range(line.line, line.index, lineEndSegment?.line, lineEndSegment?.index);
const range = new vscode.Range(line.line, line.index, lineEndSegment?.line, lineEndSegment.str.length);
symbols.push(new AsmSymbol(KeywordType.Segment, line.name, range));
const symbol1 = new vscode.DocumentSymbol(line.name, getType(KeywordType.Segment), SymbolVSCfy(KeywordType.Segment), range, new vscode.Range(line.line, line.line, line.line, line.line + line.name.length));
symbol1.children = procschild;
Expand Down
10 changes: 10 additions & 0 deletions src/utils/eol.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import { EndOfLine } from "vscode";

export function eolString(eol: EndOfLine) {
switch (eol) {
case EndOfLine.CRLF:
return "\r\n";
case EndOfLine.LF:
return "\n";
}
}

0 comments on commit 5006d0b

Please sign in to comment.