VSCode language extension with hierarchical Outline, DocumentSymbol - visual-studio-code

I'm trying to get outline working with a custom language in VScode. I have the below code but I feel like it is slow because of the way I find a range in class. Are there better ways to find the range and assign children. I've thought about just keeping track of the depth of the brackets and assigning all functions/methods/classes in higher depths into the last item of previous depth.
It was based off of this answer.
class JSLDocumentSymbolProvider implements vscode.DocumentSymbolProvider {
public provideDocumentSymbols(document: vscode.TextDocument,
token: vscode.CancellationToken): Thenable<vscode.DocumentSymbol[]> {
return new Promise((resolve, reject) => {
var symbols: vscode.DocumentSymbol[] = [];
var depth = 0;
for (var i = 0; i < document.lineCount; i++) {
var line = document.lineAt(i);
var txt = line.text;
var ltxt = txt.toLowerCase();
let open_brackets = ltxt.match(/\(/g) || [];
let close_brackets = ltxt.match(/\)/g) || [];
// console.log(ltxt)
// console.log(open_brackets, close_brackets)
//console.log(i, open_brackets.length, close_brackets.length)
depth += open_brackets.length - close_brackets.length;
//console.log(depth);
if (ltxt.includes("define class(")) {
let sname = txt.trim().substr(14, txt.trim().length - 16); //this is hard coded right now but it's kind of working
let detail = "ARGS:x, y returns z";
let start_pos = new vscode.Position(i, 0);
let n_bracket = 1;
let i_char = 0;
//let children: vscode.DocumentSymbol[] = []
let ds = new vscode.DocumentSymbol(sname, detail, vscode.SymbolKind.Class, line.range, line.range);
for(var i_line = i; n_bracket > 0; i_line++){
let class_line = document.lineAt(i_line);
let mtxt = class_line.text;
let ic;
if(i == i_line) ic = 16;
else ic = 0;
for(i_char = ic; i_char < mtxt.length; i_char++){
if(mtxt[i_char] === "(") n_bracket++;
else if(mtxt[i_char] === ")") n_bracket--;
if(n_bracket === 0) break
}
if (/(\w[\w\d\s]*)=\s*method\({((?:\s*(?:\w[\w\d\s]*)(?:=[^,]*)?,?\s*)*)},/i.test(mtxt)) {
let result = mtxt.match(/(\w[\w\d\s]*)=\s*method\({((?:\s*(?:\w[\w\d\s]*)(?:=[^,]*)?,?\s*)*)},/i)!;
let mname = result[1].trim();
let m_details = ""
if(result.length == 3){
m_details = result[2].trim();
}
ds.children.push(new vscode.DocumentSymbol(mname, m_details, vscode.SymbolKind.Method, class_line.range, class_line.range));
}
if(n_bracket === 0) break
}
let end_pos = new vscode.Position(i_line, i_char);
let rng = new vscode.Range(start_pos, end_pos);
ds.range = rng;
//ds.children = children;
symbols.push(ds);
}
else if (/(\w[\w\d\s]*)=\s*function\({((?:\s*(?:\w[\w\d\s]*)(?:=[^,]*)?,?\s*)*)},/.test(ltxt)) {
let result = txt.match(/(\w[\w\d\s]*)=\s*function\({((?:\s*(?:\w[\w\d\s]*)(?:=[^,]*)?,?\s*)*)},/i)!;
let sname = result[1].trim();
let detail = "";
if(result.length == 3){
detail = "(" + result[2].trim() + ")";
}
symbols.push(new vscode.DocumentSymbol(sname, detail, vscode.SymbolKind.Function, line.range, line.range));
}
}
resolve(symbols);
});
}
}

Related

how to replace array object in flutter

if(_list.length != 0){
var shape;
var shapeCount;
var shapeCaratCount;
var shapeTotalAmount;
var details = new Map();
var temp = [Map()];
for(int l = 0 ; l <= _list.length; l++){
var list = _list[l];
if(temp.contains(list.shape)){
shapeCount += 1;
shapeCaratCount = shapeCaratCount + list.carat;
shapeTotalAmount = shapeTotalAmount + list.totalAmount;
details['Shape'] = list.shape;
details['pcs_count'] = shapeCount;
details['Carat_Count'] = shapeCaratCount;
details['total_amount'] = shapeTotalAmount;
print(details);
temp.add(details);
}else{
shapeCount = 0;
//shapeCaratCount = shapeCaratCount + list.carat;
shapeCaratCount = list.carat;
shapeTotalAmount = list.totalAmount;
details['Shape'] = list.shape;
details['pcs_count'] = shapeCount;
details['Carat_Count'] = shapeCaratCount.toString();
details['total_amount'] = shapeTotalAmount.toString();
print(details);
temp.add(details);
}
}
}
I want to replace array object of temp dictionary array.
so if any know how to do this please help i am new at flutter
this is my code please if any difficulty. please ask.

VSC Formatter Implementation no effect

Issue Type: Bug
Launch Extension
Right click Reformat file (.items file from openhab)
VS Code version: Code 1.47.0
OS version: Darwin x64 19.5.0
Hey guys,
With the following implementation nothing happens when saving the file (format on save enabled) or when reformatting the file with a right click. I tried a lot of other solutions but none of them worked. I hope you can help me.
export function activate(context: vscode.ExtensionContext) {
vscode.languages.registerDocumentFormattingEditProvider("openhab", {
provideDocumentFormattingEdits(document: vscode.TextDocument, options: vscode.FormattingOptions): vscode.TextEdit[] {
var range = getDocumentRange(document);
var content = document.getText(range);
var result: vscode.TextEdit[] = [];
var formatted = formatItemFile();
//if (formatted) {
// result.push(new vscode.TextEdit(range, formatted));
//}
return formatted;
},
});
}
export function formatItemFile(): vscode.TextEdit[] {
var result: vscode.TextEdit[] = [];
// Get the section lengths of each line with an item in it.
// Only execute if there's an active text editor
if (!vscode.window.activeTextEditor) {
return result;
}
// Define the basic vscode variables
let doc = vscode.window.activeTextEditor.document;
let editor = vscode.window.activeTextEditor;
let currentPos = editor.selection.active;
let newPos: vscode.Position;
let itemArray: Array<Item>;
itemArray = new Array();
// Get the format configuration settings
let config = vscode.workspace.getConfiguration("oh-alignment-tool");
let preserveWhitespace = config.preserveWhitespace;
// Reset the comment tracker
isInBlockComment = false;
// Clear the file in case of line-by-line item definitions
for (let index = 0; index < doc.lineCount; index++) {
// Get Position at the beginning of the current line and start a selection
newPos = currentPos.with(index, 0);
editor.selection = new vscode.Selection(newPos, newPos);
// Get Text of current line and check if there is a comment in it
let lineText = doc.lineAt(newPos.line);
var comment = doc.getWordRangeAtPosition(newPos.with(newPos.line, 0), REGEX_COMMENT);
var blockComment = doc.getWordRangeAtPosition(newPos.with(newPos.line, 0), REGEX_START_BLOCKCOMMENT);
var endBlockComment = doc.getWordRangeAtPosition(newPos.with(newPos.line, 0), REGEX_END_BLOCKCOMMENT);
// If line is empty or contains a comment continue to the next line
if (lineText.text.length === 0 || lineText.isEmptyOrWhitespace) {
continue;
} else if (comment) {
continue;
} else if (blockComment && endBlockComment) {
isInBlockComment = false;
continue;
} else if (blockComment) {
isInBlockComment = true;
continue;
} else if (endBlockComment) {
isInBlockComment = false;
continue;
} else if (isInBlockComment) {
continue;
}
// Default these to empty. They will be changed
// if they exist in the item definition
let itemType = "";
let itemName = "";
let itemLabel = "";
let itemIcon = "";
let itemGroup = "";
let itemTag = "";
let itemChannel = "";
let itemComment = "";
// Check if there is leading Whitespace. If Yes add one in size of a tab.
let leadingWhiteSpace = lineText.firstNonWhitespaceCharacterIndex;
if (preserveWhitespace === false) {
leadingWhiteSpace = 0;
}
// Discover item Type
// Count Whitespace or tabs at the begin of the line
newPos = newPos.with(newPos.line, newPos.character + utils.countWhitespace(doc, newPos));
var wordRange = doc.getWordRangeAtPosition(newPos, REGEX_ITEM_TYPE);
if (wordRange && wordRange.isSingleLine) {
itemType = doc.getText(wordRange);
highestTypeLength = itemType.length > highestTypeLength ? itemType.length : highestTypeLength;
newPos = newPos.with(newPos.line, newPos.character + itemType.length);
newPos = newPos.with(newPos.line, newPos.character + utils.countWhitespace(doc, newPos));
// Discover item Name
var itemNameRange = doc.getWordRangeAtPosition(newPos, REGEX_ITEM_NAME);
if (itemNameRange && itemNameRange.isSingleLine) {
itemName = doc.getText(itemNameRange);
highestNameLength = itemName.length > highestNameLength ? itemName.length : highestNameLength;
newPos = newPos.with(newPos.line, newPos.character + itemName.length);
newPos = newPos.with(newPos.line, newPos.character + utils.countWhitespace(doc, newPos));
}
}
// Must have a type and name to continue
if (itemType.length === 0 || itemName.length === 0) {
continue;
}
// Discover item Label
let itemLabelRange = doc.getWordRangeAtPosition(newPos, REGEX_ITEM_LABEL);
if (itemLabelRange && itemLabelRange.isSingleLine) {
itemLabel = doc.getText(itemLabelRange);
highestLabelLength = itemLabel.length > highestLabelLength ? itemLabel.length : highestLabelLength;
newPos = newPos.with(newPos.line, newPos.character + itemLabel.length);
newPos = newPos.with(newPos.line, newPos.character + utils.countWhitespace(doc, newPos));
}
// Discover item Icon
let itemIconRange = doc.getWordRangeAtPosition(newPos, REGEX_ITEM_ICON);
if (itemIconRange && itemIconRange.isSingleLine) {
itemIcon = doc.getText(itemIconRange);
highestIconLength = itemIcon.length > highestIconLength ? itemIcon.length : highestIconLength;
newPos = newPos.with(newPos.line, newPos.character + itemIcon.length);
newPos = newPos.with(newPos.line, newPos.character + utils.countWhitespace(doc, newPos));
}
// Discover item Group
let itemGroupRange = doc.getWordRangeAtPosition(newPos, REGEX_ITEM_GROUP);
if (itemGroupRange && itemGroupRange.isSingleLine) {
itemGroup = doc.getText(itemGroupRange);
highestGroupLength = itemGroup.length > highestGroupLength ? itemGroup.length : highestGroupLength;
newPos = newPos.with(newPos.line, newPos.character + itemGroup.length);
newPos = newPos.with(newPos.line, newPos.character + utils.countWhitespace(doc, newPos));
}
// Discover item Tag
let itemTagRange = doc.getWordRangeAtPosition(newPos, REGEX_ITEM_TAG);
if (itemTagRange && itemTagRange.isSingleLine) {
itemTag = doc.getText(itemTagRange);
highestTagLength = itemTag.length > highestTagLength ? itemTag.length : highestTagLength;
//console.log("Tag: " + itemTag);
newPos = newPos.with(newPos.line, newPos.character + itemTag.length);
newPos = newPos.with(newPos.line, newPos.character + utils.countWhitespace(doc, newPos));
}
// Discover item Channel
let itemChannelRange = doc.getWordRangeAtPosition(newPos, REGEX_ITEM_CHANNEL);
if (itemChannelRange && itemChannelRange.isSingleLine) {
itemChannel = doc.getText(itemChannelRange);
highestChannelLength = itemChannel.length > highestChannelLength ? itemChannel.length : highestChannelLength;
newPos = newPos.with(newPos.line, newPos.character + itemChannel.length);
newPos = newPos.with(newPos.line, newPos.character + utils.countWhitespace(doc, newPos));
}
// Discover comment at end of line
let itemCommentRange = doc.getWordRangeAtPosition(newPos, REGEX_EOL_COMMENT);
if (itemCommentRange && itemCommentRange.isSingleLine) {
itemComment = doc.getText(itemCommentRange);
newPos = newPos.with(newPos.line, newPos.character + itemComment.length);
newPos = newPos.with(newPos.line, newPos.character + utils.countWhitespace(doc, newPos));
}
// Add the new item to the itemArray
itemArray.push(new Item(index, leadingWhiteSpace, itemType, itemName, itemLabel, itemIcon, itemGroup, itemTag, itemChannel, itemComment));
}
// Convert the column lengths to tabs
highestTypeLength = utils.generateTabFromSpaces(highestTypeLength);
highestNameLength = utils.generateTabFromSpaces(highestNameLength);
highestLabelLength = utils.generateTabFromSpaces(highestLabelLength);
highestIconLength = utils.generateTabFromSpaces(highestIconLength);
highestGroupLength = utils.generateTabFromSpaces(highestGroupLength);
highestTagLength = utils.generateTabFromSpaces(highestTagLength);
highestChannelLength = utils.generateTabFromSpaces(highestChannelLength);
// Insert the newly formatted items
itemArray.forEach(function (item) {
newPos = currentPos.with(item.line, 0);
editor.selection = new vscode.Selection(newPos, newPos);
let reformattedItem = formatItem(item);
if (reformattedItem !== "") {
let selection = new vscode.Range(newPos, newPos.with(newPos.line, doc.lineAt(newPos.line).text.length));
result.push(new vscode.TextEdit(selection, reformattedItem));
}
});
// Apply all clean and formatting Edits
//textWorkEdit.set(doc.uri, textTextEdits);
//await vscode.workspace.applyEdit(textWorkEdit);
return result;
}

Arcobjects: set measures based on the polyline length

I am currently linear referencing a set of roads. Using IMSegmatation2.SetMsAsDistance2 works fine for single-part polylines but for multi-part polylines I want to set the M values as the length along the polyline to the point, not the shortest distance between the point and the start point of the polyline. The SetMsAsDistance2 function sets the Measures on parallel lines as equal. I want them to be different.
Apart from setting an M value for each polyline vertex does anyone know of a method that sets the M as the length along the polyline?
The solution is to use the IMSegmentation3.SetAndInterpolateMsBetween function.
Note that the solution assumes that the geometries that make up the feature are in the right order. It assigns measures geometry-by-geometry.
The code for this is:
public static void measuresAdd_NonDuplicating(ref IFeature pFeat, bool bHasZ, bool bIgnoreGaps, out string sError)
{
// Add non-duplicating measures to the feature
sError = "";
IMSegmentation3 pSeg;
IGeometryCollection pGeomColl;
//IGeometryCollection pNewGeomColl; // Use if geometries are to be re-ordered.
IGeometry pGeom;
IPolyline4 pPoly;
IQueryFilter pQ;
IMAware pMAware;
IZAware pZAware;
double dStartMeasure;
double dToMeasure;
double dMeasure;
double dLen;
try
{
if (pFeat.ShapeCopy.IsEmpty == false)
{
pGeomColl = (IGeometryCollection)new PolylineClass();
pGeomColl = (IGeometryCollection)pFeat.ShapeCopy;
if (pGeomColl.GeometryCount == 1)
{
// Single line geometry. Duplication not an issue.
pMAware = (IMAware)pFeat.ShapeCopy;
pMAware.MAware = true;
pSeg = (IMSegmentation3)pMAware;
pPoly = geometryToPolyline((IGeometry)pFeat.ShapeCopy, out sError);
if (sError.Length > 0)
{
sError = "measuresAdd_NonDuplicating\r\n" + sError;
return;
}
pSeg.SetMsAsDistance2(pPoly.FromPoint, 1, 0, bIgnoreGaps);
pFeat.Shape = (IGeometry)pSeg;
pFeat.Store();
}
else
{
// For re-ordering geometries. Not currently used.
//pNewGeomColl = (IGeometryCollection)new Polyline();
//IZAware pZawareNew = (IZAware)pNewGeomColl;
//pZawareNew.ZAware = bHasZ;
//IMAware pMAwareNew = (IMAware)pNewGeomColl;
//pMAwareNew.MAware = true;
dStartMeasure = 0;
dMeasure = 0;
// MultiGeometry. Place them in order and set the measures on each part increasing.
// Currently assumes the existing order is correct.
for (int i = 0; i < pGeomColl.GeometryCount; i++)
{
pGeom = pGeomColl.Geometry[i];
pPoly = geometryToPolyline(pGeom, out sError);
if (sError.Length > 0)
{
sError = "measuresAdd_NonDuplicating\r\n" + sError;
return;
}
// Measure Values
dStartMeasure = dMeasure;
if (i > 0) dStartMeasure += 0.01;
dLen = pPoly.Length;
dToMeasure = dMeasure + dLen;
// Set Measures
pMAware = (IMAware)pPoly;
pMAware.MAware = true;
pZAware = (IZAware)pPoly;
pZAware.ZAware = bHasZ;
pSeg = (IMSegmentation3)pPoly;
pSeg.SetAndInterpolateMsBetween(dStartMeasure, dToMeasure);
// If geometries are re-ordered into a connecting network
//IGeometryCollection pXGeomColl = new PolylineClass();
//pMAware = (IMAware)pXGeomColl;
//pMAware.MAware = true;
//pZAware = (IZAware)pXGeomColl;
//pZAware.ZAware = bHasZ;
//pXGeomColl = (IGeometryCollection)pPoly;
//for (int j = 0; j < pXGeomColl.GeometryCount; j++)
// pNewGeomColl.AddGeometry(pXGeomColl.Geometry[j]);
dMeasure += dLen;
}
pFeat.Shape = (IGeometry)pGeomColl;
}
}
}
catch (Exception ex)
{
System.Diagnostics.StackTrace pStack = new System.Diagnostics.StackTrace(ex, true);
System.Diagnostics.StackFrame pFrame = pStack.GetFrame(pStack.FrameCount - 1);
int iLineNo = pFrame.GetFileLineNumber();
sError = "ERROR: measuresAdd_NonDuplicating; Line: " + iLineNo + "\n" + ex.ToString();
}
}

Calling a function from onEdit() trigger doesn't work

I want to run a function that updates some values when I edit one cell of a column. This line of the trigger works well: dataCell0.setValue(today_date(new Date())[2]);. But this other line updatePercent(); doesn't. But if I call this updatePercent() function from a time based trigger (in Resources), it works well. What is going wrong with this updatePercent() call?
function onEdit(){
var s = SpreadsheetApp.getActiveSheet();
if( ( s.getName() == "mySheet1" ) || (s.getName() == "mySheet2") ) { //checks that we're on the correct sheet
var r = s.getActiveCell();
if( s.getRange(1, r.getColumn()).getValue() == "PORCENT_TIME") { // If you type a porcent, it adds its date.
var dataCell0 = r.offset(0, 1);
dataCell0.setValue(today_date(new Date())[2]);
updatePercent();
}
}
}
Here the updatePercent function code:
/**
* A function to update percent values accoding to input date.
**/
function updatePercent() {
var sheet = SpreadsheetApp.getActiveSheet();
var column = getColumnNrByName(sheet, "PORCENT_TIME");
var input = sheet.getRange(2, column+1, sheet.getLastRow(), 4).getValues();
var output = [];
for (var i = 0; i < input.length; i++) {
var fulfilledPercent = input[i][0];
Logger.log("fulfilledPercent = " + fulfilledPercent);
var finalDate = input[i][3];
Logger.log("finalDate = " + input[i][3]);
if ( (typeof fulfilledPercent == "number") && (finalDate instanceof Date) ) {
var inputDate = input[i][1]; // Date when input was added.
var restPorcentPen = 100 - fulfilledPercent;
var restantDays = dataDiff(inputDate, finalDate);
var percentDay = restPorcentPen/restantDays;
Logger.log("percentDay = " + percentDay);
var passedTime = dataDiff(inputDate, new Date());
Logger.log("passedTime = " + passedTime);
var passedPorcent = passedTime * percentDay; // How much percent this passed time is?
Logger.log("passedPorcent = " + passedPorcent);
var newPorcent = (fulfilledPercent + passedPorcent);
newPorcent = Math.round(newPorcent * 100) / 100;
Logger.log("newPorcent = " + newPorcent);
var newInputDate = hoje_data(new Date())[2]; // Now update the new input date
// newPorcent = newPorcent.toFixed(2);
output.push([newPorcent, newInputDate]);
sheet.getRange(2, column+1, output.length, 2).setValues(output);
Logger.log(" ");
var column25Dec = getColumnNrByName(sheet, "PORCENT_25DEZ");
var passedTimeSince25Dec = dataDiff(new Date(2013,11,25), new Date()); // Months: January is 0;
var decPercent = (newPorcent - (passedTimeSince25Dec * percentDay)); // .toFixed(2).replace(".", ",");
decPercent = Math.round(decPercent * 100) / 100;
// if (sheet.getRange(output.length+1, column25Dec+1).getValues() == ''){
sheet.getRange(output.length+1, column25Dec+1).setValue(decPercent );
// }
var remainingYears = dataDiffYears(new Date(), finalDate);
sheet.getRange(output.length+1, column).setValue(remainingYears);
}
else {
newPorcent = "Put a final date"
output.push([newPorcent, inputDate]);
sheet.getRange(2, column+1, output.length, 2).setValues(output);
}
if (finalDate instanceof Date){
var remainingYears = dataDiffYears(new Date(), finalDate);
// Logger.log("remainingYears = " + remainingYears);
}
else {
remainingYears = "insert a valid date";
}
sheet.getRange(output.length+1, column).setValue(remainingYears);
}
}
I will guess you're using the new gSheets. Check if it will work in the old-style sheets. The new sheets' onEdit trigger has problems, particularly with getActive.
My problem was in the updatePercent() funciton. Thank you, guys!

I'm trying to re-write this in CoffeeScript. Coming unstuck

function getElementsByClassName(className)
{
// get all elements in the document
if (document.all)
{
var allElements = document.all;
}
else
{
var allElements = document.getElementsByTagName("*");
}
var foundElements = [];
for (var i = 0, ii = allElements.length; i < ii; i++)
{
if (allElements[i].className == className)
{
foundElements[foundElements.length] = allElements[i];
}
}
return foundElements;
}
var listItems = document.getElementsByClassName("quirky");
for (var i = 0, ii = listItems.length; i < ii; i++)
{
alert(listItems[i].nodeName);
}
getElementsByClassName = (className) ->
# get all elements in the document
if document.all
allElements = document.all
else
allElements = document.getElementsByTagName "*"
el for el in allElements when el.className == className
# NOTE: getElementsByClassName was never assigned as a member
# of document. So this call will likely fail, unless you are
# using a latest-version browser.
listItems = document.getElementsByClassName "quirky"
for i in listItems
alert i.nodeName