Skip to content

Commit

Permalink
Fixes several issues and refactor codebase (#15)
Browse files Browse the repository at this point in the history
Closes #14
Closes #5
Closes #10
  • Loading branch information
jonaprieto authored Dec 14, 2022
1 parent c1ddd8a commit 250e3d0
Show file tree
Hide file tree
Showing 12 changed files with 484 additions and 311 deletions.
5 changes: 3 additions & 2 deletions .vscode/launch.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,9 @@
"name": "Run Extension",
"type": "extensionHost",
"request": "launch",
"runtimeExecutable": "${execPath}",
"args": ["--extensionDevelopmentPath=${workspaceFolder}"]
"args": ["--extensionDevelopmentPath=${workspaceFolder}"],
"outFiles": ["${workspaceFolder}/out/**/*.js"],
"preLaunchTask": "npm: build"
}
]
}
11 changes: 11 additions & 0 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
// Place your settings in this file to overwrite default and user settings.
{
"files.exclude": {
"out": false // set this to true to hide the "out" folder with the compiled JS files
},
"search.exclude": {
"out": true // set this to false to include "out" folder in search results
},
// Turn off tsc task auto detection since we have the necessary tasks as npm scripts
"typescript.tsc.autoDetect": "off"
}
28 changes: 26 additions & 2 deletions HACKING.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,39 @@
Install the Juvix syntax highlighting extension by running the following
command on your prefered shell.

```
```bash
git clone https://github.com/anoma/vscode-juvix ~/.vscode/extensions
```

## Development

You must install `npm`, `typescript` and `vsce` to build the extension.

Run the following command to publish the extension to the marketplace.
During development to get instant feedback on your changes
you can run the following command to compile the extension
and let it run in the current VSCode instance.

```bash
npm run watch
```

Now, with the `vscode-juvix` folder open in VSCode, press `F5` to start a new VSCode instance with the extension loaded. The extension will be reloaded automatically on changes. If not, you can press '`' to load the changes.

On the client side, the Juvix plugin will create an output channel called `Juvix` where you can see the output of the extension.

Once you are happy with your changes, you can run the following command to compile the extension

```bash
vsce package
```

This will create a `.vsix` file in the root directory of the project. You can install this file in VSCode by pressing `F1` and typing `Extensions: Install from VSIX...`.

## Publishing

The following steps assume that you have a publisher account.
Conntact the Juvix team to get access to the publisher account.
Assuming you have access to the publisher account, you can publish the extension by running the following commands.

```
npm run vscode:prepublish
Expand Down
2 changes: 1 addition & 1 deletion checklist.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
- [x] semantic syntax highlighting
- [x] snippets
- [x] go to definition (not for stdlib symbols)
- [ ] user configuration
- [x] user configuration
- [ ] go to implementation
- [ ] find all references
- [ ] types on hover
Expand Down
21 changes: 8 additions & 13 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "juvix-mode",
"version": "0.1.1",
"version": "0.1.2",
"license": "GPL-3.0",
"description": "Juvix IDE support for VSCode",
"displayName": "Juvix",
Expand Down Expand Up @@ -91,8 +91,7 @@
"fontStyle": "italic"
},
"constructor": {
"foreground": "#a37acc",
"fontStyle": "italic"
"foreground": "#a37acc"
},
"error": {
"foreground": "#bd3744",
Expand All @@ -102,23 +101,19 @@
"foreground": "#f2ae49"
},
"inductive": {
"foreground": "#86b300",
"fontStyle": "italic"
"foreground": "#86b300"
},
"keyword": {
"foreground": "#399ee6",
"fontStyle": "italic"
"foreground": "#399ee6"
},
"module": {
"foreground": "#4e5e78"
},
"number": {
"foreground": "#8c48d0",
"fontStyle": "italic"
"foreground": "#8c48d0"
},
"string": {
"foreground": "#f07171",
"fontStyle": "italic"
"foreground": "#f07171"
}
}
}
Expand All @@ -136,7 +131,7 @@
".juvix"
],
"aliases": [
"juvix"
"Juvix"
],
"configuration": "./language-configuration.json"
},
Expand Down Expand Up @@ -342,7 +337,7 @@
"properties": {
"juvix-mode.statusBarIcons": {
"type": "boolean",
"default": true,
"default": false,
"scope": "machine-overridable",
"description": "Show icons on the status bar to run Juvix commands"
},
Expand Down
99 changes: 67 additions & 32 deletions src/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,41 +5,58 @@
'use strict';
import * as vscode from 'vscode';

export class JuvixConfig {
private uc = vscode.workspace.getConfiguration(
'extension',
vscode.window.activeTextEditor?.document.uri
);
export let config: JuvixConfig;

export function getConfig() {
config = new JuvixConfig();
return config;
}

private binaryName: string;
public revealPanel: string;
public statusBarIcons: boolean;
public noColors: boolean;
public showNameIds: boolean;
public onlyErrors: boolean;
public noTermination: boolean;
public noPositivity: boolean;
public noStdlib: boolean;
export class JuvixConfig {
public uc: vscode.WorkspaceConfiguration;

constructor() {
this.uc = vscode.workspace.getConfiguration();
this.binaryName = this.getBinaryName();
this.statusBarIcons = this.uc.get('juvix-mode.statusBarIcons') ?? true;
this.revealPanel = this.uc.get('juvix-mode.revealPanel') ?? 'always';
this.noColors = this.uc.get('juvix-mode.opts.noColors') ?? false;
this.showNameIds = this.uc.get('juvix-mode.opts.showNameIds') ?? false;
this.onlyErrors = this.uc.get('juvix-mode.opts.onlyErrors') ?? false;
this.noTermination = this.uc.get('juvix-mode.opts.noTermination') ?? false;
this.noPositivity = this.uc.get('juvix-mode.opts.noPositivity') ?? false;
this.noStdlib = this.uc.get('juvix-mode.opts.noStdlib') ?? false;
this.uc = vscode.workspace.getConfiguration(
'extension',
vscode.window.activeTextEditor?.document.uri
);
}

public getBinaryName(): string {
public binaryName(): string {
return this.uc.get('juvix-mode.bin.name') ?? 'juvix';
}

public binaryPath(): string {
return this.uc.get('juvix-mode.bin.path') ?? '';
}

public getJuvixExec(): string {
return this.uc.get('juvix-mode.bin.path') + this.getBinaryName();
return this.binaryPath() + this.binaryName();
}

public statusBarIcons(): boolean {
return this.uc.get('juvix-mode.statusBarIcons') ?? false;
}
public revealPanel(): string {
return this.uc.get('juvix-mode.revealPanel') ?? 'always';
}
public noColors(): boolean {
return this.uc.get('juvix-mode.opts.noColors') ?? false;
}
public showNameIds(): boolean {
return this.uc.get('juvix-mode.opts.showNameIds') ?? false;
}
public onlyErrors(): boolean {
return this.uc.get('juvix-mode.opts.onlyErrors') ?? false;
}
public noTermination(): boolean {
return this.uc.get('juvix-mode.opts.noTermination') ?? false;
}
public noPositivity(): boolean {
return this.uc.get('juvix-mode.opts.noPositivity') ?? false;
}
public noStdlib(): boolean {
return this.uc.get('juvix-mode.opts.noStdlib') ?? false;
}

public getCompilationFlags(): string {
Expand All @@ -58,24 +75,42 @@ export class JuvixConfig {
}
public getGlobalFlags(): string {
const flags = [];
if (this.noColors) {
if (this.noColors()) {
flags.push('--no-colors');
}
if (this.showNameIds) {
if (this.showNameIds()) {
flags.push('--show-name-ids');
}
if (this.onlyErrors) {
if (this.onlyErrors()) {
flags.push('--only-errors');
}
if (this.noTermination) {
if (this.noTermination()) {
flags.push('--no-termination');
}
if (this.noPositivity) {
if (this.noPositivity()) {
flags.push('--no-positivity');
}
if (this.noStdlib) {
if (this.noStdlib()) {
flags.push('--no-stdlib');
}
return flags.join(' ');
}

public toString = (): string => {
return `JuvixConfig {
binaryName: ${this.binaryName()},
binaryPath: ${this.binaryPath()},
juvixExec: ${this.getJuvixExec()},
statusBarIcons: ${this.statusBarIcons()},
revealPanel: ${this.revealPanel()},
noColors: ${this.noColors()},
showNameIds: ${this.showNameIds()},
onlyErrors: ${this.onlyErrors()},
noTermination: ${this.noTermination()},
noPositivity: ${this.noPositivity()},
noStdlib: ${this.noStdlib()},
compilationFlags: ${this.getCompilationFlags()},
globalFlags: ${this.getGlobalFlags()}
}`;
};
}
109 changes: 109 additions & 0 deletions src/definitions.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
/*---------------------------------------------------------
* Copyright (C) Microsoft Corporation. All rights reserved.
*--------------------------------------------------------*/
'use strict';

import * as vscode from 'vscode';
import * as debug from './utils/debug';

export let definitionProvider: vscode.DefinitionProvider;
export const locationMap = new Map<string, Map<number, TargetLocation[]>>();

export interface ColInterval {
start: number;
end: number;
}

export interface TargetLocation {
interval: ColInterval;
targetFile: string;
targetLine: number;
targetStartCharacter: number;
}

export function activate(context: vscode.ExtensionContext) {
/* Go to definition */
try {
definitionProvider = new JuvixDefinitionProvider();
context.subscriptions.push(
vscode.languages.registerDefinitionProvider(
{ language: 'Juvix', scheme: 'file' },
definitionProvider
)
);
debug.log('info', 'Go to definition registered');
} catch (error) {
debug.log('error', 'No definition provider', error);
}
}

export class JuvixDefinitionProvider implements vscode.DefinitionProvider {
async provideDefinition(
document: vscode.TextDocument,
position: vscode.Position,
token: vscode.CancellationToken
): Promise<vscode.Location | vscode.Location[] | undefined> {
const filePath: string = document.fileName;
const line: number = position.line;
const col: number = position.character;
debug.log('info', 'Find def. requested ------------------------');
debug.log(
'info',
'Looking for definition of the symbol at: ' + (line + 1) + ':' + (col + 1)
);
debug.log('info', 'Active file: ' + filePath);

if (!locationMap.has(filePath)) {
debug.log(
'info',
'There is no definitions registered in file: ' + filePath
);
return undefined;
} else {
if (!locationMap.get(filePath)!.has(line)) {
debug.log(
'info',
'There is no defnition registered at line: ' + (line + 1)
);
return undefined;
} else {
const locsByLine: TargetLocation[] = locationMap
.get(filePath)!
.get(line)!;
debug.log(
'info',
'> Found ' + locsByLine.length + ' definitions at line: ' + (line + 1)
);
for (let i = 0; i < locsByLine.length; i++) {
const info: TargetLocation = locsByLine[i];
// debug.log(
// 'info',
// '+ Checking if symbol is between colummns: ' +
// (info.interval.start + 1) +
// ' and ' +
// (info.interval.end + 1)
// );

if (info.interval.start <= col && info.interval.end >= col) {
debug.log(
'info',
'[!] Found definition at: ' +
info.targetFile +
':' +
(info.targetLine + 1) +
':' +
(info.targetStartCharacter + 1)
);
const definitionFound = new vscode.Location(
vscode.Uri.file(info.targetFile),
new vscode.Position(info.targetLine, info.targetStartCharacter)
);
return definitionFound;
}
}
}
}
debug.log('info', 'No definition found');
return undefined;
}
}
Loading

0 comments on commit 250e3d0

Please sign in to comment.