Skip to content

Commit

Permalink
v0.1.2 (#3)
Browse files Browse the repository at this point in the history
* update lock file

* remove unnecessary err log

* update `launch.json` and `package.json` for debugging

* add a configuration option to set the futhark executable path

* ignore futhark files

* longer line break in prettier
  • Loading branch information
haoranpb authored Oct 16, 2022
1 parent b871d3a commit 29336fa
Show file tree
Hide file tree
Showing 7 changed files with 101 additions and 76 deletions.
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -13,3 +13,6 @@ futhark-language-server

# ignore personal configurations
.vscode/settings.json

# test files
*.fut
3 changes: 2 additions & 1 deletion .prettierrc.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,6 @@
"semi": false,
"singleQuote": true,
"trailingComma": "es5",
"arrowParens": "always"
"arrowParens": "always",
"printWidth": 100
}
16 changes: 6 additions & 10 deletions .vscode/launch.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,20 +2,16 @@
"version": "0.2.0",
"configurations": [
{
"name": "Launch Extension",
"name": "Dev Futhark Extension",
"request": "launch",
"type": "pwa-extensionHost",
"type": "extensionHost",
"runtimeExecutable": "${execPath}",
"args": [
"--extensionDevelopmentPath=${workspaceFolder}"
],
"outFiles": [
"${workspaceFolder}/out/**/*.js"
],
"args": ["--disable-extensions", "--extensionDevelopmentPath=${workspaceFolder}"],
"outFiles": ["${workspaceFolder}/out/**/*.js"],
"preLaunchTask": {
"type": "npm",
"script": "esbuild"
},
"script": "esbuild:dev"
}
}
]
}
4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

14 changes: 11 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"name": "futhark-vscode",
"displayName": "Futhark",
"description": "Futhark language support powered by the Futhark Language Server",
"version": "0.1.1",
"version": "0.1.2",
"publisher": "DIKU",
"repository": "github:diku-dk/futhark-vscode",
"engines": {
Expand Down Expand Up @@ -51,7 +51,14 @@
"configuration": {
"type": "object",
"title": "Futhark",
"properties": {}
"properties": {
"futhark.futharkExecutablePath": {
"scope": "resource",
"type": "string",
"default": "",
"markdownDescription": "Manually set a futhark executable, the path must ends `futhark` (e,g, `~/.local/bin/futhark`), supports `~` and `${HOME}`. Reload Window after change to take effect."
}
}
},
"commands": [
{
Expand All @@ -63,7 +70,8 @@
},
"scripts": {
"vscode:prepublish": "rm -rf ./out && npm run esbuild -- --minify",
"esbuild": "esbuild ./src/extension.ts --bundle --outfile=out/main.js --external:vscode --format=cjs --platform=node"
"esbuild": "esbuild ./src/extension.ts --bundle --outfile=out/main.js --external:vscode --format=cjs --platform=node",
"esbuild:dev": "npm run esbuild -- --sourcemap"
},
"devDependencies": {
"@types/node": "^17.0.14",
Expand Down
129 changes: 69 additions & 60 deletions src/extension.ts
Original file line number Diff line number Diff line change
@@ -1,87 +1,60 @@
import which from 'which'
import { execSync } from 'child_process'
import semver from 'semver'
import { window, commands, ExtensionContext } from 'vscode'
import { window, workspace, commands, ExtensionContext } from 'vscode'
import {
LanguageClient,
LanguageClientOptions,
ServerOptions,
TransportKind,
} from 'vscode-languageclient/node'
import { resolveHOMEPlaceHolders } from './utils'

let client: LanguageClient
const minFutharkVersion = '0.21.9'
const langName = 'futhark'

// entry point of the extension
export async function activate(context: ExtensionContext) {
which('futhark')
.then((resolvedPath) => {
const futharkVersion = execSync('futhark --version', {
encoding: 'utf-8',
})
.split(/\r?\n/)[0]
.match(/\d+\.\d+\.\d+/)
const futharkConfig = workspace.getConfiguration(langName)
const futharkExecutable = findFutharkExecutable(futharkConfig.get('futharkExecutablePath'))

// check if futhark's version is compatible
// lsp included since futhark 0.21.9
if (futharkVersion && semver.gte(futharkVersion[0], minFutharkVersion)) {
window.onDidChangeActiveTextEditor((editor) => {
// fire custom event "custom/onFocusTextDocument"
// so that the language server can re-compile on focus
if (editor) {
const focusedURI = editor.document.uri.toString()
if (futharkExecutable) {
window.onDidChangeActiveTextEditor((editor) => {
// fire custom event "custom/onFocusTextDocument"
// so that the language server can re-compile on focus
if (editor) {
const focusedURI = editor.document.uri.toString()

if (focusedURI.endsWith('.fut')) {
client.sendNotification('custom/onFocusTextDocument', focusedURI)
}
}
})

const clientOptions: LanguageClientOptions = {
documentSelector: [{ scheme: 'file', language: 'futhark' }],
if (focusedURI.endsWith('.fut')) {
client.sendNotification('custom/onFocusTextDocument', focusedURI)
}
}
})

const serverOptions: ServerOptions = {
command: resolvedPath,
// not sure why stdio over ipc (copied from vscode-haskell)
transport: TransportKind.stdio,
args: ['lsp'], // run `futhark lsp` to fire up the language server
}
const clientOptions: LanguageClientOptions = {
documentSelector: [{ scheme: 'file', language: langName }],
}

client = new LanguageClient(
langName,
langName,
serverOptions,
clientOptions
)
const serverOptions: ServerOptions = {
command: futharkExecutable,
// not sure why stdio over ipc (copied from vscode-haskell)
transport: TransportKind.stdio,
args: ['lsp'], // run `futhark lsp` to fire up the language server
}

const restartCommand = commands.registerCommand(
'futhark.commands.restartServer',
async () => {
client.info('Restarting server...')
await client.stop()
client.info('Starting server...')
client.start()
}
)
context.subscriptions.push(restartCommand)
client = new LanguageClient(langName, langName, serverOptions, clientOptions)

client.start()
} else {
window.showErrorMessage(
`Futhark version is too low, the version you are using is ${futharkVersion},
but Futhark Language Server is available as part of futhark from version ${minFutharkVersion}
please follow [Installation](https://futhark.readthedocs.io/en/stable/installation.html) guide to upgrade.`
)
}
})
.catch((err) => {
window.showErrorMessage(
"Can't find futhark executable, please follow [Installation](https://futhark.readthedocs.io/en/stable/installation.html) guide."
)
console.error(err)
const restartCommand = commands.registerCommand('futhark.commands.restartServer', async () => {
client.info('Restarting server...')
await client.stop()
client.info('Starting server...')
client.start()
})
context.subscriptions.push(restartCommand)

client.start()
}
}

export function deactivate(): Thenable<void> | undefined {
Expand All @@ -90,3 +63,39 @@ export function deactivate(): Thenable<void> | undefined {
}
return client.stop()
}

function findFutharkExecutable(userDefinedPath: string | undefined): string | null {
const potentialExecutablePath = userDefinedPath ? userDefinedPath : langName
const executablePath = which.sync(resolveHOMEPlaceHolders(potentialExecutablePath), {
nothrow: true,
})

if (executablePath && executablePath.endsWith(langName)) {
const futharkVersion = execSync(`${executablePath} --version`, {
encoding: 'utf-8',
})
.split(/\r?\n/)[0]
.match(/\d+\.\d+\.\d+/)

if (futharkVersion && semver.gte(futharkVersion[0], minFutharkVersion)) {
return executablePath
} else {
window.showErrorMessage(
`Futhark version is too low, the version you are using is ${futharkVersion},
but Futhark Language Server is available as part of futhark from version ${minFutharkVersion}
please follow [Installation](https://futhark.readthedocs.io/en/stable/installation.html) guide to upgrade.`
)
return null
}
} else {
if (userDefinedPath) {
window.showErrorMessage(
`The path defined ("${userDefinedPath}") is not a valid futhark executable.`
)
}
window.showErrorMessage(
"Can't find futhark executable, please follow [Installation](https://futhark.readthedocs.io/en/stable/installation.html) guide."
)
return null
}
}
8 changes: 8 additions & 0 deletions src/utils.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import os from 'os'

/**
* Resolve placeholders `${HOME}` and `~`.
*/
export function resolveHOMEPlaceHolders(path: string): string {
return path.replace('${HOME}', os.homedir).replace(/^~/, os.homedir)
}

0 comments on commit 29336fa

Please sign in to comment.