diff --git a/.vscode/settings.json b/.vscode/settings.json index 2f6b47a..21c910f 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -9,5 +9,8 @@ "[typescript]": { "editor.defaultFormatter": "esbenp.prettier-vscode", "editor.formatOnSave": true, + }, + "[json]": { + "editor.defaultFormatter": "esbenp.prettier-vscode" } } diff --git a/CHANGELOG.md b/CHANGELOG.md index 5bf59ef..f64c94f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,18 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [2.3.0] - 2021-05-27 + +### Added + +- feat(py): add config option processing.py.isEnabled +- feat(search): directly search processing reference if possible +- feat(search): add py.processing.org search + +### Changed + +- fix: add extra restrictions to commands + ## [2.2.0] - 2021-05-21 ### Added diff --git a/README.md b/README.md index 6471c04..bf1a408 100644 --- a/README.md +++ b/README.md @@ -103,6 +103,7 @@ This extension attempts to make Processing with Python easier to use. Follow the - Change the following configuration options - `processing.py.jarPath`: the path to your `processing-py.jar` file. Preferably, this is an absolute path. In this example, it will be `~/processing.py-linux64/processing.py-3056-linux64/processing-py.jar` - `processing.py.javaPath`: the path to your `java` executable. For example, `/usr/bin/java` + - Make sure `processing.py.isEnabled` is set to `true` (true by default) 4. Downloads stub definitions (optional) - Definitions can be found [here](https://github.com/Abdulla060/Processing.py-intellisense/blob/master/lib/Processing3.pyi) - After than, follow the imports in [this example](https://github.com/Abdulla060/Processing.py-intellisense/blob/master/Example.py) diff --git a/package.json b/package.json index 49aca9e..aa73db8 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,7 @@ "name": "processing-vscode", "displayName": "Processing VSCode", "description": "Processing Language Support for VSCode", - "version": "2.2.0", + "version": "2.3.0", "publisher": "Luke-zhang-04", "engines": { "vscode": "^1.48.0" @@ -33,6 +33,8 @@ "onCommand:processing.OpenDocs", "onCommand:processing.SearchWebsite", "onCommand:processing.Run", + "onCommand:processing.RunJava", + "onCommand:processing.RunPy", "onLanguage:pde", "onLanguage:python" ], @@ -41,29 +43,35 @@ "commands": [ { "command": "processing.Run", - "title": "Processing: Run Open Processing Project" + "title": "Processing: Run Open Processing Project", + "enablement": "resourceLangId == python || resourceLangId == pde" }, { "command": "processing.RunPy", "title": "Processing: Run Open Processing Python Project", - "icon": "./images/play-arrow-with-logo.svg" + "icon": "./images/play-arrow-with-logo.svg", + "enablement": "resourceLangId == python && config.processing.py.isEnabled" }, { "command": "processing.RunJava", - "title": "Processing: Run Open Processing Project", - "icon": "./images/play-arrow.svg" + "title": "Processing: Run Open Processing Java Project", + "icon": "./images/play-arrow.svg", + "enablement": "resourceLangId == pde" }, { "command": "processing.OpenExtensionDocumentation", - "title": "Processing: Open Extension Documentation" + "title": "Processing: Open Extension Documentation", + "enablement": "resourceLangId == pde" }, { "command": "processing.OpenDocs", - "title": "Processing: Open Documentation for Selection" + "title": "Processing: Open Documentation for Selection", + "enablement": "resourceLangId == pde || resourceLangId == python && config.processing.py.isEnabled" }, { "command": "processing.SearchWebsite", - "title": "Processing: Search Processing Website" + "title": "Processing: Search Processing Website", + "enablement": "resourceLangId == pde || resourceLangId == python && config.processing.py.isEnabled" } ], "languages": [ @@ -105,7 +113,7 @@ "group": "navigation" }, { - "when": "resourceLangId == python", + "when": "resourceLangId == python && config.processing.py.isEnabled", "command": "processing.RunPy", "group": "navigation" } @@ -117,7 +125,7 @@ "group": "navigation" }, { - "when": "resourceLangId == python", + "when": "resourceLangId == python && config.processing.py.isEnabled", "command": "processing.RunPy", "group": "navigation" } @@ -134,16 +142,20 @@ }, "processing.docs": { "type": "string", - "default": "processing.org", + "default": "auto", "enum": [ "processing.org", - "p5js.org" + "p5js.org", + "py.processing.org", + "auto" ], "enumDescriptions": [ "Use processing.org for documentation", - "Use p5js for documentation" + "Use p5js for documentation", + "Use py.processing.org for documentation", + "Automatically determine either processing.org or py.processing.org (never p5js) depending on the current file" ], - "description": "Which documentation should this extension use?" + "description": "Which documentation this extension should use" }, "processing.search": { "type": "string", @@ -181,6 +193,11 @@ "type": "string", "default": "java", "description": "Path to Java. Leave default if you've added java to your path, otherwise enter the path to `java` here. Example: `/usr/bin/java` for Unix, or `C:\\Program Files\\Java\\jdk1.8.0_202\\bin\\javac.exe` for Windows." + }, + "processing.py.isEnabled": { + "type": "boolean", + "default": true, + "description": "If processing.py features should be enabled or not." } } } diff --git a/rollup.config.js b/rollup.config.js index 2100bed..2951559 100644 --- a/rollup.config.js +++ b/rollup.config.js @@ -5,10 +5,21 @@ import {terser} from "rollup-plugin-terser" import typescript from "@rollup/plugin-typescript" const banner = `/** - * processing-vscode - Processing Language Support for VSCode - * @version 2.2.0 - * @copyright (C) 2016 - 2020 Tobiah Zarlez, 2021 Luke Zhang + * Processing-vscode - Processing Language Support for VSCode + * https://github.com/Luke-zhang-04/processing-vscode + * + * @license MIT + * @version 2.3.0 * @preserve + * @copyright (C) 2016 - 2020 Tobiah Zarlez, 2021 Luke Zhang + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. */ ` @@ -28,7 +39,9 @@ const config = { progress(), typescript(), yaml(), - resolve(), + resolve({ + resolveOnly: [/^(?!vscode)$/], + }), process.env.NODE_ENV === "dev" ? undefined : terser({ diff --git a/scripts/fetchDocs.mjs b/scripts/fetchDocs.mjs index 2c5bc24..49534bd 100755 --- a/scripts/fetchDocs.mjs +++ b/scripts/fetchDocs.mjs @@ -115,7 +115,7 @@ const escapeHTML = (html) => * Gets the documentation for a single link * * @param {string} link - Link to get doc from - * @returns {Promise} + * @returns {Promise} */ const documentVariable = async (link) => { const documentation = { @@ -177,7 +177,7 @@ const documentVariable = async (link) => { * Gets the documentation for a single link * * @param {string} link - Link to get doc from - * @returns {Promise} + * @returns {Promise} */ const documentFunction = async (link) => { const documentation = { @@ -246,7 +246,7 @@ const documentFunction = async (link) => { * Gets the documentation for a single link * * @param {string} link - Link to get doc from - * @returns {Promise} + * @returns {Promise} */ const documentClass = async (link) => { const documentation = { @@ -328,7 +328,7 @@ const documentLinks = async ({classLinks, functionLinks, variableLinks}) => { /** * All documentation (final object dumped to JSON) * - * @type {import("./src/documentation").Documentation} + * @type {import("../src/types").Documentation} */ const documentation = {} diff --git a/src/commands/index.ts b/src/commands/index.ts index 888e2ae..4904fb3 100644 --- a/src/commands/index.ts +++ b/src/commands/index.ts @@ -6,13 +6,18 @@ import {openDocumentation, openProcessingDocs, searchUnityDocs} from "./search" import {run as runProject} from "./run" +import {shouldEnablePython} from "../config" import vscode from "vscode" export const subscribeCommands = (context: vscode.ExtensionContext): void => { context.subscriptions.push(vscode.commands.registerCommand("processing.Run", runProject)) - context.subscriptions.push( - vscode.commands.registerCommand("processing.RunPy", () => runProject("py")), - ) + + if (shouldEnablePython) { + context.subscriptions.push( + vscode.commands.registerCommand("processing.RunPy", () => runProject("py")), + ) + } + context.subscriptions.push( vscode.commands.registerCommand("processing.RunJava", () => runProject("java")), ) diff --git a/src/commands/run.ts b/src/commands/run.ts index 01225e2..2c97e10 100644 --- a/src/commands/run.ts +++ b/src/commands/run.ts @@ -4,28 +4,20 @@ * @copyright (C) 2021 Luke Zhang */ -import { - getJarPath, - getJavaCommand, - getProcessingCommand, - shouldAlwaysQuotePath, -} from "../getConfig" +import {jarPath, javaCommand, processingCommand, shouldAlwaysQuotePath} from "../config" import path, {dirname} from "path" import {isValidProcessingProject} from "../utils" import vscode from "vscode" -class RunManager { - private static _pythonUtils = { - getProjectFilename: ({fileName}: vscode.TextDocument): string => - shouldAlwaysQuotePath() || / |\\/u.test(fileName) ? `"${fileName}"` : fileName, - - getJarFilename: (): string => { - const jarPath = getJarPath() +const pythonUtils = { + getProjectFilename: ({fileName}: vscode.TextDocument): string => + shouldAlwaysQuotePath || / |\\/u.test(fileName) ? `"${fileName}"` : fileName, - return shouldAlwaysQuotePath() || / |\\/u.test(jarPath) ? `"${jarPath}"` : jarPath - }, - } + getJarFilename: (): string => + shouldAlwaysQuotePath || / |\\/u.test(jarPath) ? `"${jarPath}"` : jarPath, +} +class RunManager { private _terminal?: vscode.Terminal = undefined private _pythonTerminal?: vscode.Terminal = undefined @@ -88,7 +80,7 @@ class RunManager { let sketchName = dirname(editor.document.fileName) const isValidProjectName = isValidProcessingProject(sketchName.split(path.sep).pop()) - const shouldQuotePath = shouldAlwaysQuotePath() || / |\\/u.test(sketchName) + const shouldQuotePath = shouldAlwaysQuotePath || / |\\/u.test(sketchName) if (shouldQuotePath) { sketchName = `"${sketchName}"` @@ -103,7 +95,7 @@ class RunManager { } // If file is a processing project file - const cmd = `${getProcessingCommand()} --sketch=${sketchName} --run` + const cmd = `${processingCommand} --sketch=${sketchName} --run` currentTerminal.sendText(cmd) } @@ -119,7 +111,7 @@ class RunManager { currentTerminal.show() // If file is a processing project file - const cmd = `${getJavaCommand()} -jar ${RunManager._pythonUtils.getJarFilename()} ${RunManager._pythonUtils.getProjectFilename( + const cmd = `${javaCommand} -jar ${pythonUtils.getJarFilename()} ${pythonUtils.getProjectFilename( editor.document, )}` diff --git a/src/commands/search.ts b/src/commands/search.ts index a32f9d9..5ac3359 100644 --- a/src/commands/search.ts +++ b/src/commands/search.ts @@ -4,7 +4,7 @@ * @copyright (C) 2016 - 2020 Tobiah Zarlez, 2021 Luke Zhang */ -import * as search from "../search" +import {search} from "../utils" import vscode from "vscode" const openDocErrorMessage = async (str: string) => { diff --git a/src/config.ts b/src/config.ts new file mode 100644 index 0000000..863f393 --- /dev/null +++ b/src/config.ts @@ -0,0 +1,150 @@ +/** + * Processing-vscode - Processing Language Support for VSCode + * + * @copyright (C) 2021 Luke Zhang + */ + +import vscode from "vscode" + +const getProcessingCommand = (): string => { + const config = vscode.workspace + .getConfiguration() + .get("processing.processingPath", "processing-java") + + if (typeof config !== "string") { + const msg = "Config option processing.processingPath must be of type string" + + vscode.window.showErrorMessage(msg) + + throw new Error(msg) + } + + return config +} + +const getJavaCommand = (): string => { + const config = vscode.workspace + .getConfiguration() + .get("processing.py.javaPath", "java") + + if (typeof config !== "string") { + const msg = "Config option processing.py.javaPath must be of type string" + + vscode.window.showErrorMessage(msg) + + throw new Error(msg) + } + + return config +} + +const getJarPath = (): string => { + const config = vscode.workspace + .getConfiguration() + .get("processing.py.jarPath", "processing-py.jar") + + if (typeof config !== "string") { + const msg = "Config option processing.py.jarPath must be of type string" + + vscode.window.showErrorMessage(msg) + + throw new Error(msg) + } + + return config +} + +const getPythonEnablement = (): boolean => { + const isEnabled = vscode.workspace + .getConfiguration() + .get("processing.py.isEnabled", true) + + if (typeof isEnabled !== "boolean") { + const msg = "Config option processing.py.isEnabled should be a boolean" + + vscode.window.showErrorMessage(msg) + + throw new Error(msg) + } + + return isEnabled +} + +type DocOptions = "processing.org" | "p5js.org" | "py.processing.org" | "auto" +type SearchEngines = "Google" | "DuckDuckGo" + +const getSearchConfig = (): {searchEngine: SearchEngines; processingDocs: DocOptions} => { + const config = vscode.workspace.getConfiguration("processing") + const processingDocs = config.get("docs", "auto") + const searchEngine = config.get("search", "Google") + + if (!["processing.org", "p5js.org", "py.processing.org", "auto"].includes(processingDocs)) { + const msg = + 'Config option processing.docs must be "processing.org" | "p5js.org" | "py.processing.org" | "auto"' + + vscode.window.showErrorMessage(msg) + + throw new Error(msg) + } else if (!["Google", "DuckDuckGo"].includes(searchEngine)) { + const msg = 'Config option processing.search must be "Google" | "DuckDuckGo"' + + vscode.window.showErrorMessage(msg) + + throw new Error(msg) + } + + return { + searchEngine, + processingDocs, + } +} + +const getshouldEnableDiagnostics = (): boolean => { + const shouldGiveDiagnostics = vscode.workspace + .getConfiguration() + .get("processing.shouldGiveDiagnostics", true) + + if (typeof shouldGiveDiagnostics !== "boolean") { + const msg = "Config option processing.shouldGiveDiagnostics must be of type string" + + vscode.window.showErrorMessage(msg) + + throw new Error(msg) + } + + return shouldGiveDiagnostics +} + +const getQuoteEnablement = (): boolean => { + const shouldQuotePath = vscode.workspace + .getConfiguration() + .get<"always" | "auto">("processing.runPathQuotes", "auto") + + if (shouldQuotePath !== "always" && shouldQuotePath !== "auto") { + const msg = 'Config option processing.runPathQuotes should be "auto" or "always"' + + vscode.window.showErrorMessage(msg) + + throw new Error(msg) + } + + return shouldQuotePath === "always" +} + +export const processingCommand = getProcessingCommand() +export const javaCommand = getJavaCommand() +export const jarPath = getJarPath() +export const shouldEnablePython = getPythonEnablement() +export const searchConfig = getSearchConfig() +export const shouldEnableDiagnostics = getshouldEnableDiagnostics() +export const shouldAlwaysQuotePath = getQuoteEnablement() + +export default { + processingCommand, + javaCommand, + jarPath, + shouldEnablePython, + searchConfig, + shouldEnableDiagnostics, + shouldAlwaysQuotePath, +} diff --git a/src/diagnostics.ts b/src/diagnostics.ts index 0e3d0cb..94346bd 100644 --- a/src/diagnostics.ts +++ b/src/diagnostics.ts @@ -7,8 +7,8 @@ import path, {dirname} from "path" import childProcess from "child_process" import crypto from "crypto" -import {getProcessingCommand} from "./getConfig" import {isValidProcessingProject} from "./utils" +import {processingCommand} from "./config" import vscode from "vscode" let oldHash = "" @@ -53,7 +53,7 @@ const refreshDiagnostics = async ( console.log({sketchName}) const diagnostic = await new Promise((resolve) => { - const processingProcess = childProcess.spawn(getProcessingCommand(), [ + const processingProcess = childProcess.spawn(processingCommand, [ `--sketch=${sketchName}`, "--build", ]) diff --git a/src/documentation.ts b/src/documentation.ts index e0c01e9..e1dd649 100644 --- a/src/documentation.ts +++ b/src/documentation.ts @@ -4,6 +4,12 @@ * @copyright (C) 2021 Luke Zhang */ +import type { + Documentation, + DocumentationClass, + DocumentationFunction, + DocumentationVariable, +} from "./types" import documentation from "./documentation-data.yml" import vscode from "vscode" @@ -22,7 +28,7 @@ const getHoveredItem = (line: string, position: number): string | undefined => { let index = position for (; index >= 0 && index < line.length; index--) { - if (!/[a-z]|[0-9]|_/iu.test(line[index])) { + if (!/[a-z]|[0-9]|_/iu.test(line[index]!)) { break } } @@ -34,7 +40,7 @@ const getHoveredItem = (line: string, position: number): string | undefined => { let index = position for (; index >= 0 && index < line.length; index++) { - if (!/[a-z]|[0-9]|_/iu.test(line[index])) { + if (!/[a-z]|[0-9]|_/iu.test(line[index]!)) { break } } @@ -45,35 +51,6 @@ const getHoveredItem = (line: string, position: number): string | undefined => { return line.slice(itemStart, itemEnd) } -interface DocumentationVariable { - description: string - examples?: string - docUrl: string - type: "var" | "const" -} - -interface DocumentationClass { - description: string - syntax: string - parameters: {[key: string]: string} - docUrl: string - type: "class" -} - -interface DocumentationFunction { - description: string - syntax: string - parameters: {[key: string]: string} - returns: string - docUrl: string - type: "function" -} - -/* prettier-ignore */ -export type Documentation = { - [key: string]: DocumentationFunction | DocumentationVariable | DocumentationClass -}; - const documentVariable = ( info: DocumentationVariable, item: keyof typeof documentation, diff --git a/src/env.d.ts b/src/env.d.ts index 6e75d9d..37dfd8c 100644 --- a/src/env.d.ts +++ b/src/env.d.ts @@ -1,5 +1,5 @@ declare module "*.yml" { - declare const content: {[key: string]: unknown} + const content: {[key: string]: unknown} export default content } diff --git a/src/getConfig.ts b/src/getConfig.ts deleted file mode 100644 index e983bd6..0000000 --- a/src/getConfig.ts +++ /dev/null @@ -1,96 +0,0 @@ -/** - * Processing-vscode - Processing Language Support for VSCode - * - * @copyright (C) 2021 Luke Zhang - */ - -import vscode from "vscode" - -export const getProcessingCommand = (): string => { - const config = vscode.workspace - .getConfiguration() - .get("processing.processingPath", "processing-java") - - if (typeof config !== "string") { - throw new Error("Config option processing.processingPath must be of type string") - } - - return config -} - -export const getJavaCommand = (): string => { - const config = vscode.workspace - .getConfiguration() - .get("processing.py.javaPath", "java") - - if (typeof config !== "string") { - throw new Error("Config option processing.py.javaPath must be of type string") - } - - return config -} - -export const getJarPath = (): string => { - const config = vscode.workspace - .getConfiguration() - .get("processing.py.jarPath", "processing-py.jar") - - if (typeof config !== "string") { - throw new Error("Config option processing.py.jarPath must be of type string") - } - - return config -} - -export const isPythonEnabled = (): boolean => { - const config = vscode.workspace - .getConfiguration() - .get("processing.py.isEnabled", true) - - if (typeof config !== "boolean") { - throw new Error("Config option processing.py.javaPath must be of type string") - } - - return config -} - -export const getSearchConfig = (): {searchEngine: string; processingDocs: string} => { - const config = vscode.workspace.getConfiguration("processing") - const processingDocs = config.get("docs", "processing.org") - const searchEngine = config.get("search", "Google") - - if (typeof processingDocs !== "string" || typeof searchEngine !== "string") { - throw new Error( - "Config options processing.processingDocs and processing.searchEngine must be of type string", - ) - } - - return { - searchEngine, - processingDocs, - } -} - -export const getDiagnosticConfig = (): boolean => { - const shouldGiveDiagnostics = vscode.workspace - .getConfiguration() - .get("processing.shouldGiveDiagnostics", true) - - if (typeof shouldGiveDiagnostics !== "boolean") { - throw new Error("Config option processing.shouldGiveDiagnostics must be of type string") - } - - return shouldGiveDiagnostics -} - -export const shouldAlwaysQuotePath = (): boolean => { - const shouldQuotePath = vscode.workspace - .getConfiguration() - .get<"always" | "auto">("processing.runPathQuotes", "auto") - - if (shouldQuotePath !== "always" && shouldQuotePath !== "auto") { - throw new Error("processing.runPathQuotes should be auto or always") - } - - return shouldQuotePath === "always" -} diff --git a/src/index.ts b/src/index.ts index 04b781b..3fcb3f2 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,11 +1,11 @@ /** * Processing-vscode - Processing Language Support for VSCode * - * @version 2.2.0 + * @version 2.3.0 * @copyright (C) 2016 - 2020 Tobiah Zarlez, 2021 Luke Zhang */ -import {getDiagnosticConfig, getProcessingCommand} from "./getConfig" +import {processingCommand, shouldEnableDiagnostics} from "./config" import isValidProcessingCommand from "./validateCommand" import subscribeCommands from "./commands" import subscribeDiagnostics from "./diagnostics" @@ -18,15 +18,15 @@ export const activate = async (context: vscode.ExtensionContext) => { subscribeCommands(context) - if (getDiagnosticConfig()) { - if (await isValidProcessingCommand(getProcessingCommand())) { + if (shouldEnableDiagnostics) { + if (await isValidProcessingCommand(processingCommand)) { const pdeDiagnostics = vscode.languages.createDiagnosticCollection("processing") context.subscriptions.push(pdeDiagnostics) subscribeDiagnostics(pdeDiagnostics, context, log) } else { log.appendLine( - `ERROR! The configured processing command ${getProcessingCommand()} could not be executed.`, + `ERROR! The configured processing command ${processingCommand} could not be executed.`, ) log.show() } diff --git a/src/search.ts b/src/search.ts deleted file mode 100644 index bf0c97c..0000000 --- a/src/search.ts +++ /dev/null @@ -1,72 +0,0 @@ -/** - * Processing-vscode - Processing Language Support for VSCode - * - * @copyright (C) 2016 - 2020 Tobiah Zarlez, 2021 Luke Zhang - */ - -import {getSearchConfig} from "./getConfig" -import vscode from "vscode" - -const enum Urls { - ProcessingorgDocs = "https://processing.org/reference/", - ProcessingorgSearchGoogle = "https://www.google.com/search?as_sitesearch=processing.org&as_q=", - ProcessingorgSearchDuckDuckGo = "https://duckduckgo.com/?q=!processing+%5C", - P5jsDocs = "https://p5js.org/reference/", - P5jsSearchGoogle = "https://www.google.com/search?as_sitesearch=p5js.org&as_q=", - P5jsSearchDuckDuckGo = "https://duckduckgo.com/?q=!p5+", -} - -export const openURL = async (searchBase?: string, url?: string) => { - if (searchBase === "open") { - await vscode.env.openExternal(vscode.Uri.parse(url as string)) - } else { - const {processingDocs, searchEngine} = getSearchConfig() - const searchUrl = ((): string => { - if (searchBase === "docs") { - if (!url) { - return processingDocs === "p5js.org" ? Urls.P5jsDocs : Urls.ProcessingorgDocs - } else if (searchEngine === "DuckDuckGo") { - return processingDocs === "p5js.org" - ? `${Urls.P5jsSearchDuckDuckGo}${url}` - : `${Urls.ProcessingorgSearchDuckDuckGo}${url}` - } - - return processingDocs === "p5js.org" - ? `${Urls.P5jsSearchGoogle}${url}` - : `${Urls.ProcessingorgSearchGoogle}${url}` - } - - return searchBase ?? "" - })() - - await vscode.env.openExternal(vscode.Uri.parse(searchUrl)) - } - - return true -} - -// Slice and Trim -export const prepareInput = (input: string, start: number, end: number) => { - // input is the whole line, part of which is selected by the user (defined by star/end) - - if (start >= end) { - return "" - } - - // Slice to the selection - input = input.slice(start, end) - - // Trim white space - input = input.trim() - - // Possible future addition: - // Check right here if valid variable/function name to search? - - // Everything looks good by this point, so time to open a web browser! - return input -} - -export const openProcessingDocs = (input: string, start: number, end: number) => { - // Use the node module "opn" to open a web browser - openURL("docs", prepareInput(input, start, end)) -} diff --git a/src/types.d.ts b/src/types.d.ts new file mode 100644 index 0000000..d20f160 --- /dev/null +++ b/src/types.d.ts @@ -0,0 +1,27 @@ +export interface DocumentationClass { + description: string + syntax: string + parameters: {[key: string]: string} + docUrl: string + type: "class" +} + +export interface DocumentationFunction { + description: string + syntax: string + parameters: {[key: string]: string} + returns: string + docUrl: string + type: "function" +} + +export interface DocumentationVariable { + description: string + examples?: string + docUrl: string + type: "var" | "const" +} + +export type Documentation = { + [key: string]: DocumentationFunction | DocumentationVariable | DocumentationClass +} diff --git a/src/utils.ts b/src/utils/index.ts similarity index 86% rename from src/utils.ts rename to src/utils/index.ts index 5355332..a53a93e 100644 --- a/src/utils.ts +++ b/src/utils/index.ts @@ -4,5 +4,7 @@ * @copyright (C) 2021 Luke Zhang */ +export * as search from "./search" + export const isValidProcessingProject = (path?: string): boolean => path !== undefined && /^[/_$a-z][/\w$]*$/iu.test(path) diff --git a/src/utils/search.ts b/src/utils/search.ts new file mode 100644 index 0000000..c4f4f10 --- /dev/null +++ b/src/utils/search.ts @@ -0,0 +1,113 @@ +/** + * Processing-vscode - Processing Language Support for VSCode + * + * @copyright (C) 2016 - 2020 Tobiah Zarlez, 2021 Luke Zhang + */ + +import type {Documentation} from "../types" +import documentation from "../documentation-data.yml" +import {searchConfig} from "../config" +import vscode from "vscode" + +const enum Urls { + ProcessingorgDocs = "https://processing.org/reference/", + ProcessingorgSearchGoogle = "https://www.google.com/search?as_sitesearch=processing.org&as_q=", + ProcessingorgSearchDuckDuckGo = "https://duckduckgo.com/?q=!processing+%5C", + P5jsDocs = "https://p5js.org/reference/", + P5jsSearchGoogle = "https://www.google.com/search?as_sitesearch=p5js.org&as_q=", + P5jsSearchDuckDuckGo = "https://duckduckgo.com/?q=!p5+", + PyDocs = "https://py.processing.org/reference/", + PySearchGoogle = "https://www.google.com/search?as_sitesearch=py.processing.org&as_q=", + PySearchDuckDuckGo = "https://duckduckgo.com/?q=%5Csite%3Apy.processing.org+", +} + +export const openURL = async (searchBase?: string, url?: string): Promise => { + if (searchBase === "open") { + await vscode.env.openExternal(vscode.Uri.parse(url as string)) + } else { + const {processingDocs, searchEngine} = searchConfig + const searchUrl = ((): string => { + let directDocUrl: string | undefined + + if (searchBase === "docs") { + const { + window: {activeTextEditor}, + } = vscode + const languageId = activeTextEditor?.document.languageId + + if (!url) { + if (processingDocs === "p5js.org") { + return Urls.P5jsDocs + } else if ( + (processingDocs === "auto" && languageId === "pyton") || + processingDocs === "py.processing.org" + ) { + return Urls.PyDocs + } + + // (processingDocs === "auto" && languageId === "pde") + // || processingDocs === "processing.org" + return Urls.ProcessingorgDocs + } else if ( + // Look for entry directly in documentation data + (processingDocs === "auto" || processingDocs === "processing.org") && + languageId === "pde" && + (directDocUrl = (documentation as Documentation)[url]?.docUrl) !== undefined + ) { + return directDocUrl + } else if (searchEngine === "DuckDuckGo") { + // Search Engine == "google" + if (processingDocs === "p5js.org") { + return `${Urls.P5jsSearchDuckDuckGo}${url}` + } else if ( + (processingDocs === "auto" && languageId === "pyton") || + processingDocs === "py.processing.org" + ) { + return `${Urls.PySearchDuckDuckGo}${url}` + } + + // (processingDocs === "auto" && languageId === "pde") + // || processingDocs === "processing.org" + return `${Urls.ProcessingorgSearchDuckDuckGo}${url}` + } + + // Search Engine == "google" + if (processingDocs === "p5js.org") { + return `${Urls.P5jsSearchGoogle}${url}` + } else if ( + (processingDocs === "auto" && languageId === "pyton") || + processingDocs === "py.processing.org" + ) { + return `${Urls.PySearchGoogle}${url}` + } + + // (processingDocs === "auto" && languageId === "pde") + // || processingDocs === "processing.org" + return `${Urls.ProcessingorgSearchGoogle}${url}` + } + + return searchBase ?? "" + })() + + await vscode.env.openExternal(vscode.Uri.parse(searchUrl)) + } + + return +} + +// Slice and Trim +export const prepareInput = (input: string, start: number, end: number) => { + // input is the whole line, part of which is selected by the user (defined by star/end) + + if (start >= end) { + return "" + } + + // Everything looks good by this point, so time to open a web browser! + return input.slice(start, end).trim() +} + +export const openProcessingDocs = (input: string, start: number, end: number) => { + // Use the node module "opn" to open a web browser + openURL("docs", prepareInput(input, start, end)) +} diff --git a/tsconfig.json b/tsconfig.json index d5de5ae..8008b68 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -4,7 +4,7 @@ /* Basic Options */ // "incremental": true, /* Enable incremental compilation */ - "target": "ES2018", /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', 'ES2018', 'ES2019', 'ES2020', or 'ESNEXT'. */ + "target": "ES2019", /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', 'ES2018', 'ES2019', 'ES2020', or 'ESNEXT'. */ "module": "ESNext", /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', 'es2020', or 'ESNext'. */ // "lib": [], /* Specify library files to be included in the compilation. */ "allowJs": true, /* Allow javascript files to be compiled. */ @@ -63,9 +63,11 @@ // "emitDecoratorMetadata": true, /* Enables experimental support for emitting type metadata for decorators. */ /* Advanced Options */ - "skipLibCheck": true, /* Skip type checking of declaration files. */ + "skipLibCheck": false, /* Skip type checking of declaration files. */ + "skipDefaultLibCheck": true, "forceConsistentCasingInFileNames": true, /* Disallow inconsistently-cased references to the same file. */ "resolveJsonModule": true, + "noUncheckedIndexedAccess": true, }, "include": [ "src"