Skip to content

Commit

Permalink
Merge pull request #28 from williamthome/refactor/lint
Browse files Browse the repository at this point in the history
refactor: lint
  • Loading branch information
williamthome authored Jun 13, 2022
2 parents 8f6d103 + fc96e54 commit 80af2a2
Show file tree
Hide file tree
Showing 10 changed files with 136 additions and 150 deletions.
11 changes: 8 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"name": "zotonic-ls",
"displayName": "Zotonic",
"description": "Syntax highlight for Zotonic templates (.tpl).",
"version": "0.4.0",
"version": "0.4.1",
"publisher": "williamthome",
"license": "Apache-2.0",
"icon": "images/z_logo.png",
Expand Down Expand Up @@ -36,7 +36,12 @@
"definitionProvider": "true",
"hoverProvider": "true",
"completionProvider": {
"triggerCharacters": [ ".", "[", "{", "|" ]
"triggerCharacters": [
".",
"[",
"{",
"|"
]
}
},
"main": "./out/extension.js",
Expand Down Expand Up @@ -141,4 +146,4 @@
"dependencies": {
"axios": "^0.27.2"
}
}
}
8 changes: 4 additions & 4 deletions src/config/docs.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import { Docs } from "../utils/docs"
import { Docs } from "../utils/docs";

export type DocsConfig = {
docs: Docs,
language: string,
version: string,
branch: string,
}
};

const docsConfig: DocsConfig = {
docs: {
Expand Down Expand Up @@ -464,6 +464,6 @@ const docsConfig: DocsConfig = {
language: "en",
version: "latest",
branch: "master",
}
};

export default docsConfig
export default docsConfig;
10 changes: 5 additions & 5 deletions src/config/index.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
import getDoc from "../utils/docs"
import docsConfig, { DocsConfig } from "./docs"
import getDoc from "../utils/docs";
import docsConfig, { DocsConfig } from "./docs";

type Config = {
docs: DocsConfig,
}
};

const config: Config = {
docs: docsConfig
}
};

export default {
defaults: config,
Expand All @@ -17,4 +17,4 @@ export default {
docsConfig.version,
docsConfig.branch
)
}
};
149 changes: 74 additions & 75 deletions src/extension.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
import * as vscode from 'vscode';
import axios from "axios";
import config from "./config";
import { m_get, Expression, FindFile } from './utils/snippets';
import { mGetExpressions, Expression, FindFile } from './utils/snippets';

// this method is called when your extension is activated
// your extension is activated the very first time the command is executed
Expand All @@ -21,54 +21,54 @@ export function activate(context: vscode.ExtensionContext) {
// @see this question in StackOverflow here https://stackoverflow.com/questions/72554515/go-to-definition-highlight-in-vscode-lsp
const definitionProvider = vscode.languages.registerDefinitionProvider('tpl', {
async provideDefinition(document, position, _token) {
const wordRange = document.getWordRangeAtPosition(position, /(?<=").*?(?=")/)
if (!wordRange || wordRange.isEmpty) return
const wordRange = document.getWordRangeAtPosition(position, /(?<=").*?(?=")/);
if (!wordRange || wordRange.isEmpty) { return; };

const text = document.getText(wordRange)
const lastDotIndex = text.lastIndexOf(".")
if (lastDotIndex <= 0) return
const text = document.getText(wordRange);
const lastDotIndex = text.lastIndexOf(".");
if (lastDotIndex <= 0) { return; };

const ext = text.substring(lastDotIndex)
if (!ext) return
const ext = text.substring(lastDotIndex + 1);
if (!ext) { return; };

const lastSlashIndex = text.lastIndexOf("/")
const fileName = text.substring(lastSlashIndex).replace("/", "")
if (!fileName) return
const lastSlashIndex = text.lastIndexOf("/");
const fileName = text.substring(lastSlashIndex).replace("/", "");
if (!fileName) { return; };

const tplLocationPattern = "**/priv/templates/**/"
const jsLocationPattern = "**/priv/lib/**/"
const cssLocationPattern = "**/priv/lib/**/"
const imageLocationPattern = "**/priv/lib/images/**/"
const tplLocationPattern = "**/priv/templates/**/";
const jsLocationPattern = "**/priv/lib/**/";
const cssLocationPattern = "**/priv/lib/**/";
const imageLocationPattern = "**/priv/lib/images/**/";

const extLocationPattern = {
".tpl": tplLocationPattern,
".js": jsLocationPattern,
".css": cssLocationPattern,
".apng": imageLocationPattern,
".gif": imageLocationPattern,
".ico": imageLocationPattern,
".cur": imageLocationPattern,
".jpg": imageLocationPattern,
".jpeg": imageLocationPattern,
".jfif": imageLocationPattern,
".pjpeg": imageLocationPattern,
".pjp": imageLocationPattern,
".png": imageLocationPattern,
".svg": imageLocationPattern,
}

const locationPattern = extLocationPattern[ext as keyof typeof extLocationPattern]
if (!locationPattern) return
tpl: tplLocationPattern,
js: jsLocationPattern,
css: cssLocationPattern,
apng: imageLocationPattern,
gif: imageLocationPattern,
ico: imageLocationPattern,
cur: imageLocationPattern,
jpg: imageLocationPattern,
jpeg: imageLocationPattern,
jfif: imageLocationPattern,
pjpeg: imageLocationPattern,
pjp: imageLocationPattern,
png: imageLocationPattern,
svg: imageLocationPattern,
};

const locationPattern = extLocationPattern[ext as keyof typeof extLocationPattern];
if (!locationPattern) { return; };

const filePattern = `${locationPattern}${fileName}`;
const ignorePattern = "**/_build/**"
const ignorePattern = "**/_build/**";

const files = await vscode.workspace.findFiles(filePattern, ignorePattern);
if (!files) return;
if (!files) { return; }

return files.map(uri => new vscode.Location(
uri, new vscode.Position(0, 0)
))
));
}
});

Expand All @@ -77,17 +77,17 @@ export function activate(context: vscode.ExtensionContext) {
const hoverProvider = vscode.languages.registerHoverProvider('tpl', {
async provideHover(document, position, _token) {
const patternMatch = (pattern: RegExp) => {
const wordRange = document.getWordRangeAtPosition(position, pattern)
const wordRange = document.getWordRangeAtPosition(position, pattern);
return !!wordRange && !wordRange.isEmpty
? document.getText(wordRange)
: undefined
}
: undefined;
};

const doc = config.getDoc(patternMatch)
if (!doc || !doc.raw) return
const doc = config.getDoc(patternMatch);
if (!doc || !doc.raw) { return; };

const response = await axios.get(doc.raw);
if (response.status !== 200) return
if (response.status !== 200) { return; };

const markdown = new vscode.MarkdownString(response.data);
markdown.supportHtml = true;
Expand All @@ -107,78 +107,77 @@ export function activate(context: vscode.ExtensionContext) {
_token: vscode.CancellationToken,
_context: vscode.CompletionContext
) {
const modelNameRe = /\bm\.(\w+)?/
const modelNameRange = document.getWordRangeAtPosition(position, modelNameRe)
const modelNameRe = /\bm\.(\w+)?/;
const modelNameRange = document.getWordRangeAtPosition(position, modelNameRe);
if (!!modelNameRange && !modelNameRange.isEmpty) {
const modelsPattern = "{apps,apps_user}/**/src/models/**/m_*.erl"
const modelsPattern = "{apps,apps_user}/**/src/models/**/m_*.erl";
const models = await vscode.workspace.findFiles(modelsPattern);
return models.reduce((arr, file) => {
const modelRe = /(?<=\bm_).*?(?=.erl)/
const modelMatch = modelRe.exec(file.fsPath)
const modelRe = /(?<=\bm_).*?(?=.erl)/;
const modelMatch = modelRe.exec(file.fsPath);
if (!modelMatch || !modelMatch.length) {
return arr
return arr;
}

const model = modelMatch[0]
const modelExpressionsFinder = (m: string) => m_get(findFile, m)
const snippet = new vscode.CompletionItem(model)
snippet.insertText = new vscode.SnippetString(model)
const model = modelMatch[0];
const modelExpressionsFinder = (m: string) => mGetExpressions(findFile, m);
const snippet = new vscode.CompletionItem(model);
snippet.insertText = new vscode.SnippetString(model);
snippet.command = {
command: "tpl.snippet.pick",
title: "m_get",
arguments: [model, modelExpressionsFinder]
}
arr.push(snippet)
return arr
}, new Array<vscode.CompletionItem>())
};
arr.push(snippet);
return arr;
}, new Array<vscode.CompletionItem>());
}

const variableRe = /(?<=\[).*?(?=\])|(?<={).*?(?=})|(?<=:).*?(?=}|,)|(?<==).*?(?=(}|,|%}))/
const variableRange = document.getWordRangeAtPosition(position, variableRe)
const variableRe = /(?<=\[).*?(?=\])|(?<={).*?(?=})|(?<=:).*?(?=}|,)|(?<==).*?(?=(}|,|%}))/;
const variableRange = document.getWordRangeAtPosition(position, variableRe);
if (!!variableRange) {
// TODO: Variables snippets.
// It will be awesome if variables can pop up as suggestion.
return
return;
}

const mSnippet = new vscode.CompletionItem("m")
mSnippet.insertText = new vscode.SnippetString("m")
const mSnippet = new vscode.CompletionItem("m");
mSnippet.insertText = new vscode.SnippetString("m");

return [
mSnippet
]
];
}
// })
}, ".", "[", "{", "|")
}, ".", "[", "{", "|");

context.subscriptions.push(completionProvider)
context.subscriptions.push(completionProvider);

vscode.commands.registerCommand('tpl.snippet.pick', async (model, modelExpressionsFinder) => {
const expressions: Array<Expression> = await modelExpressionsFinder(model)
const expressions: Array<Expression> = await modelExpressionsFinder(model);
if (expressions instanceof Error) {
await vscode.window.showErrorMessage(expressions.message)
return undefined
await vscode.window.showErrorMessage(expressions.message);
return undefined;
}

const quickPick = vscode.window.createQuickPick();
quickPick.items = expressions.map(({ expression: label }) => ({ label }));
quickPick.onDidChangeSelection(async ([{ label }]) => {
const token = expressions.find(token => token.expression === label)
const token = expressions.find(token => token.expression === label);
if (!token) {
throw (new Error(`Unexpected no token match in quick pick with label '${label}'`))
throw (new Error(`Unexpected no token match in quick pick with label '${label}'`));
}

await vscode.commands.executeCommand("tpl.snippet.insert", token.snippet)
await vscode.commands.executeCommand("tpl.snippet.insert", token.snippet);
quickPick.hide();
});
quickPick.show();
})
});

vscode.commands.registerTextEditorCommand('tpl.snippet.insert', (editor, _edit, snippet) => {
return editor.insertSnippet(
new vscode.SnippetString(snippet),
);
})
});
}

// this method is called when your extension is deactivated
Expand All @@ -190,5 +189,5 @@ const findFile: FindFile = async (pattern, ignorePattern = null) => {
const files = await vscode.workspace.findFiles(pattern, ignorePattern, 1);
return files.length
? files[0].fsPath
: undefined
}
: undefined;
};
File renamed without changes.
20 changes: 10 additions & 10 deletions src/utils/docs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,40 +4,40 @@ export type Doc = {
pattern: RegExp,
genUri: (token: string) => string,
tokens?: string[]
}
};

export type Docs = { [key: string]: Doc }
export type Docs = { [key: string]: Doc };

// API

export default function (docs: Docs, language: string, version: string, branch: string) {
return function (patternMatch: (pattern: RegExp) => string | undefined) {
const uri = maybeGenDocUri(docs, patternMatch)
const uri = maybeGenDocUri(docs, patternMatch);
return {
uri: maybeGenDocUri(docs, patternMatch),
url: uri ? genDocUrl(language, version, uri) : undefined,
raw: uri ? genDocRawUrl(branch, uri) : undefined,
}
}
};
};
}

// Internal functions

function genDocUrl(language: string, version: string, uri = "/") {
return `http://docs.zotonic.com/${language}/${version}${uri}`
return `http://docs.zotonic.com/${language}/${version}${uri}`;
}

function genDocRawUrl(branch: string, uri: string) {
return `https://raw.githubusercontent.com/zotonic/zotonic/${branch}/doc${uri}.rst`
return `https://raw.githubusercontent.com/zotonic/zotonic/${branch}/doc${uri}.rst`;
}

function maybeGenDocUri(
docs: Docs,
patternMatch: (pattern: RegExp) => string | undefined
) {
for (const doc of Object.values(docs)) {
const token = patternMatch(doc.pattern)
if (!token || (doc.tokens?.length && !doc.tokens.includes(token))) continue
return doc.genUri(token)
const token = patternMatch(doc.pattern);
if (!token || (doc.tokens?.length && !doc.tokens.includes(token))) { continue; };
return doc.genUri(token);
}
}
Loading

0 comments on commit 80af2a2

Please sign in to comment.