diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..c2658d7 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +node_modules/ diff --git a/client/extension.js b/client/extension.js new file mode 100644 index 0000000..97fa80d --- /dev/null +++ b/client/extension.js @@ -0,0 +1,100 @@ +const vscode = require('vscode'); +var fetch = require("node-fetch"); + +var urlLookup; + +function activate(context) { + + console.log('GCode hover text is active'); + + if (urlLookup == null) + { + console.debug('Fetching cache of documentation'); + urlLookup = new Object(); + fetch(`https://api.github.com/repos/MarlinFirmware/MarlinDocumentation/contents/_gcode`) + .then(res => res.json()) + .then(body => parseRepoContents(body)) + .catch((error) => console.log(error)); + } + + disposable = vscode.languages.registerHoverProvider('gcode', { + async provideHover(document, position, token) { + const range = document.getWordRangeAtPosition(position); + const word = document.getText(range); + + // format the word correctly + const regex = /\s*([A-Za-z])(\d+)\s*/ + const matches = word.match(regex); + // If the second part is a number then search the lookup for the documentation + if(!isNaN(matches[2])) + { + // Format the string correctly (i.e. with leading zeros) + const gcode = matches[1] + matches[2].padStart(3,"0"); + return new vscode.Hover(await getHoverText(gcode)); + } + } + }); + + context.subscriptions.push(disposable); +} + +function deactivate() { } + +async function getHoverText(gcode) +{ + if (urlLookup[gcode].hoverText == null) + { + // Can we generate the info? + if (urlLookup[gcode].download_url != null) + { + const rawInfoUrl = urlLookup[gcode].download_url; + if (rawInfoUrl != null) + { + try { + const response = await fetch(rawInfoUrl); + const json = await response.text(); + const docs = parseDocs(json); + urlLookup[gcode].hoverText = `**${docs.title}** \n\n ${docs.brief} \n\n <${urlLookup[gcode].docs_url}>` + } catch (error) { + console.log(error); + } + } + } + + } + return urlLookup[gcode].hoverText; +} + +function parseRepoContents(json) +{ + json.forEach(element => { + const filename = element.name.split(".")[0]; + const download_url = element.download_url; + const docs_url = `https://marlinfw.org/docs/gcode/${filename}.html`; + + const regex = /([A-Za-z])(\d+)(?:-([A-Za-z])(\d+))?/; + const matches = filename.match(regex); + + // remove the global match + matches.shift(); + + for (i = 0; i <= matches.length/2; i+=2) { + urlLookup[matches[i] + matches[i+1]] = { + download_url: download_url, + docs_url: docs_url, + }; + } + }); +} + +function parseDocs(text) +{ + return { + title:text.match(/title: ([^\n]*)/)[1], + brief:text.match(/brief: ([^\n]*)/)[1]}; +} + +module.exports = { + activate, + deactivate +} \ No newline at end of file diff --git a/package.json b/package.json index 3046b3d..6935c36 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,7 @@ "name": "nc-gcode", "displayName": "nc-gcode", "description": "G-code syntax highlighter", - "version": "0.14.1", + "version": "0.14.2", "publisher": "ML2", "author": { "name": "Milys", @@ -11,11 +11,18 @@ "maintainers": [{ "name": "scottmwyant", "url": "https://github.com/scottmwyant" + }, + { + "name": "Stevil Knevil", + "url": "https://github.com/StevilKnevil" }], "scripts": { "pack": "vsce package" }, "preview": true, + "activationEvents": [ + "onLanguage:gcode" + ], "engines": { "vscode": "^1.19.0" }, @@ -32,7 +39,11 @@ "color": "#E4F2FF", "theme": "light" }, + "main": "./client/extension.js", "contributes": { + "capabilities": { + "hoverProvider": "true" + }, "languages": [{ "id": "gcode", "aliases": [ @@ -88,5 +99,7 @@ "scopeName": "source.gcode", "path": "./gcode.tmLanguage.json" }] - } + }, + "dependencies" : + { "node-fetch" : ">2.6.0" } } \ No newline at end of file