Skip to content

Commit

Permalink
Merge pull request #23 from mkslanc/fixes
Browse files Browse the repository at this point in the history
Unified named constructor for LanguageProvider to improve API
  • Loading branch information
anijanyan authored Jan 17, 2023
2 parents 06d5ce3 + 5b5515e commit f7cb87b
Show file tree
Hide file tree
Showing 10 changed files with 118 additions and 124 deletions.
75 changes: 36 additions & 39 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
# Ace Linters (Ace Language Client)

Ace linters is a library that brings language-aware features to the Ace editor. It includes a number of language services, each of which provides support for a specific language, such as JSON, HTML, CSS, and Typescript.
Ace linters is a library that brings language-aware features to the Ace editor. It includes a number of language
services, each of which provides support for a specific language, such as JSON, HTML, CSS, and Typescript.

Ace linters works in two modes: **WebSockets** and **WebWorkers**.
Ace linters works in two modes: **WebSockets** and **WebWorkers**.

## Features

With Ace linters, you can easily add the following language-aware features to your Ace editor:

- Error checking
- Code completion
- Type checking
Expand All @@ -16,13 +18,15 @@ With Ace linters, you can easily add the following language-aware features to yo
## Supported languages

Ace linters supports the following languages by default with webworkers approach:

- JSON, JSON5 (with JsonService)
- HTML (with HtmlService)
- CSS, SCSS, LESS (with CssService)
- Typescript, Javascript, JSX, TSX (with TypescriptService)
- Lua (with LuaService)

For WebSockets you could connect any of your Language Server folowing LSP

## Installation

To install Ace linters, you can use the following command:
Expand All @@ -33,53 +37,50 @@ npm install ace-linters

## Usage with WebWorker

To use Ace linters with WebWorker, you will first need to include it in your project and create an instance of the Ace
editor
and
an instance of LanguageProvider. Then, LanguageProvider will use the appropriate language service based on the mode being used:
To use Ace linters with WebWorker, you will first need to include it in your project and create an instance of the Ace
editor and an instance of LanguageProvider.

*client.js*:

```javascript
import * as ace from "ace-code";
import {Mode as TypescriptMode} from "ace-code/src/mode/typescript";
import {registerStyles, LanguageProvider, MessageController} from "ace-linters";
import { ScriptTarget, JsxEmit } from "ace-linters/type-converters/typescript-converters";

// Register custom styles for the hover tooltip
registerStyles();
import {registerStyles, LanguageProvider} from "ace-linters";
import {ScriptTarget, JsxEmit} from "ace-linters/type-converters/typescript-converters";

// Create a web worker and a message controller
// Create a web worker
let worker = new Worker(new URL('./webworker.js', import.meta.url));
let messageController = new MessageController(worker);

// Create an Ace editor
let editor = ace.edit("container", {
mode: new TypescriptMode() // Set the mode of the editor to Typescript
});

// Create a language provider for web worker
let languageProvider = LanguageProvider.for(worker);

// Set global options for the Typescript service
messageController.setGlobalOptions("typescript", {
languageProvider.setGlobalOptions("typescript", {
compilerOptions: {
allowJs: true,
target: ScriptTarget.ESNext,
jsx: JsxEmit.Preserve
}
});

// Create an Ace editor
let editor = ace.edit("container");

// Set the mode of the editor to Typescript
editor.session.setMode(new TypescriptMode());

// Create a language provider
let languageProvider = new LanguageProvider(messageController);

// Register the editor with the language provider
languageProvider.registerEditor(editor);

```
In WebWorkers mode, you need to register
services on the webworker side. Like this:
*webworker.js*
```javascript
import {ServiceManager} from "ace-linters/services/service-manager";

let manager = new ServiceManager(self);
manager.registerService("typescript", {
module: () => import("ace-linters/services/typescript/typescript-service"),
Expand All @@ -88,37 +89,31 @@ manager.registerService("typescript", {
});
```
[Example client](https://github.com/mkslanc/ace-linters/blob/main/packages/demo/webworker-lsp/demo.ts).
[Example client](https://github.com/mkslanc/ace-linters/blob/main/packages/demo/webworker-lsp/demo.ts)
[Example web worker](https://github.com/mkslanc/ace-linters/blob/main/packages/demo/webworker-lsp/webworker.ts)
## Usage with WebSocket
In WebSockets mode, you need to start a language server on any port and connect to it.
Here's an example client:
```javascript
import * as ace from "ace-code";
import {Mode as JSONMode} from "ace-code/src/mode/json"; //any mode you want
import {registerStyles, LanguageProvider, MessageControllerWS} from "ace-linters";
import { ScriptTarget, JsxEmit } from "ace-linters/type-converters/typescript-converters";
import {LanguageProvider} from "ace-linters";

// Register custom styles for the hover tooltip
registerStyles();

// Create a web socket and a message controller
// Create a web socket
const webSocket = new WebSocket("ws://localhost:3000/exampleServer"); // adress of your websocket server

//Message controller for web sockets
let messageController = new MessageControllerWS(webSocket);

// Create an Ace editor
let editor = ace.edit("container");

// Set the mode of the editor to JSON
editor.session.setMode(new JSONMode());
let editor = ace.edit("container", {
mode: new JSONMode() // Set the mode of the editor to JSON
});

// Create a language provider
let languageProvider = new LanguageProvider(messageController);
// Create a language provider for web socket
let languageProvider = LanguageProvider.for(webSocket);

// Register the editor with the language provider
languageProvider.registerEditor(editor);
Expand All @@ -127,5 +122,7 @@ languageProvider.registerEditor(editor);
[Example client](https://github.com/mkslanc/ace-linters/blob/main/packages/demo/websockets-lsp/client.ts)
[Example server](https://github.com/mkslanc/ace-linters/tree/main/packages/demo/websockets-lsp/server)
## License
Ace linters is released under the [MIT License](https://opensource.org/licenses/MIT).
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "ace-linters-root",
"version": "0.0.4",
"version": "0.1.1",
"scripts": {
"build": "webpack",
"start": "webpack-dev-server"
Expand Down
71 changes: 34 additions & 37 deletions packages/ace-linters/README.md
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
# Ace Linters (Ace Language Client)

Ace linters is a library that brings language-aware features to the Ace editor. It includes a number of language services, each of which provides support for a specific language, such as JSON, HTML, CSS, and Typescript.
Ace linters is a library that brings language-aware features to the Ace editor. It includes a number of language
services, each of which provides support for a specific language, such as JSON, HTML, CSS, and Typescript.

Ace linters works in two modes: **WebSockets** and **WebWorkers**.

## Features

With Ace linters, you can easily add the following language-aware features to your Ace editor:

- Error checking
- Code completion
- Type checking
Expand All @@ -16,13 +18,15 @@ With Ace linters, you can easily add the following language-aware features to yo
## Supported languages

Ace linters supports the following languages by default with webworkers approach:

- JSON, JSON5 (with JsonService)
- HTML (with HtmlService)
- CSS, SCSS, LESS (with CssService)
- Typescript, Javascript, JSX, TSX (with TypescriptService)
- Lua (with LuaService)

For WebSockets you could connect any of your Language Server folowing LSP

## Installation

To install Ace linters, you can use the following command:
Expand All @@ -34,52 +38,49 @@ npm install ace-linters
## Usage with WebWorker

To use Ace linters with WebWorker, you will first need to include it in your project and create an instance of the Ace
editor
and
an instance of LanguageProvider. Then, LanguageProvider will use the appropriate language service based on the mode being used:
editor and an instance of LanguageProvider.

*client.js*:

```javascript
import * as ace from "ace-code";
import {Mode as TypescriptMode} from "ace-code/src/mode/typescript";
import {registerStyles, LanguageProvider, MessageController} from "ace-linters";
import { ScriptTarget, JsxEmit } from "ace-linters/type-converters/typescript-converters";

// Register custom styles for the hover tooltip
registerStyles();
import {registerStyles, LanguageProvider} from "ace-linters";
import {ScriptTarget, JsxEmit} from "ace-linters/type-converters/typescript-converters";

// Create a web worker and a message controller
// Create a web worker
let worker = new Worker(new URL('./webworker.js', import.meta.url));
let messageController = new MessageController(worker);

// Create an Ace editor
let editor = ace.edit("container", {
mode: new TypescriptMode() // Set the mode of the editor to Typescript
});

// Create a language provider for web worker
let languageProvider = LanguageProvider.for(worker);

// Set global options for the Typescript service
messageController.setGlobalOptions("typescript", {
languageProvider.setGlobalOptions("typescript", {
compilerOptions: {
allowJs: true,
target: ScriptTarget.ESNext,
jsx: JsxEmit.Preserve
}
});

// Create an Ace editor
let editor = ace.edit("container");

// Set the mode of the editor to Typescript
editor.session.setMode(new TypescriptMode());

// Create a language provider
let languageProvider = new LanguageProvider(messageController);

// Register the editor with the language provider
languageProvider.registerEditor(editor);

```
In WebWorkers mode, you need to register
services on the webworker side. Like this:
*webworker.js*
```javascript
import {ServiceManager} from "ace-linters/services/service-manager";

let manager = new ServiceManager(self);
manager.registerService("typescript", {
module: () => import("ace-linters/services/typescript/typescript-service"),
Expand All @@ -88,37 +89,31 @@ manager.registerService("typescript", {
});
```
[Example client](https://github.com/mkslanc/ace-linters/blob/main/packages/demo/webworker-lsp/demo.ts).
[Example client](https://github.com/mkslanc/ace-linters/blob/main/packages/demo/webworker-lsp/demo.ts)
[Example web worker](https://github.com/mkslanc/ace-linters/blob/main/packages/demo/webworker-lsp/webworker.ts)
## Usage with WebSocket
In WebSockets mode, you need to start a language server on any port and connect to it.
Here's an example client:
```javascript
import * as ace from "ace-code";
import {Mode as JSONMode} from "ace-code/src/mode/json"; //any mode you want
import {registerStyles, LanguageProvider, MessageControllerWS} from "ace-linters";
import { ScriptTarget, JsxEmit } from "ace-linters/type-converters/typescript-converters";
import {LanguageProvider} from "ace-linters";

// Register custom styles for the hover tooltip
registerStyles();

// Create a web socket and a message controller
// Create a web socket
const webSocket = new WebSocket("ws://localhost:3000/exampleServer"); // adress of your websocket server

//Message controller for web sockets
let messageController = new MessageControllerWS(webSocket);

// Create an Ace editor
let editor = ace.edit("container");

// Set the mode of the editor to JSON
editor.session.setMode(new JSONMode());
let editor = ace.edit("container", {
mode: new JSONMode() // Set the mode of the editor to JSON
});

// Create a language provider
let languageProvider = new LanguageProvider(messageController);
// Create a language provider for web socket
let languageProvider = LanguageProvider.for(webSocket);

// Register the editor with the language provider
languageProvider.registerEditor(editor);
Expand All @@ -127,5 +122,7 @@ languageProvider.registerEditor(editor);
[Example client](https://github.com/mkslanc/ace-linters/blob/main/packages/demo/websockets-lsp/client.ts)
[Example server](https://github.com/mkslanc/ace-linters/tree/main/packages/demo/websockets-lsp/server)
## License
Ace linters is released under the [MIT License](https://opensource.org/licenses/MIT).
4 changes: 1 addition & 3 deletions packages/ace-linters/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,7 @@ import {MessageController} from "./message-controller";
import * as lintersCSS from "./css/linters.css";
import * as dom from "ace-code/src/lib/dom";

export function registerStyles() {
dom.importCssString(lintersCSS, "linters.css");
}
dom.importCssString(lintersCSS, "linters.css");

export {LanguageProvider} from "./language-provider";
export {MessageController} from "./message-controller";
21 changes: 19 additions & 2 deletions packages/ace-linters/language-provider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,9 @@ import Editor = Ace.Editor;
import EditSession = Ace.EditSession;
import Completion = Ace.Completion;
import Annotation = Ace.Annotation;
import {MessageControllerWS} from "./message-controller-ws";
import ServiceOptionsMap = AceLinters.ServiceOptionsMap;
import {MessageController} from "./message-controller";

let showdown = require('showdown');

Expand All @@ -23,12 +26,22 @@ export class LanguageProvider {
private $sessionLanguageProviders: {[sessionID: string]: SessionLanguageProvider} = {};
private $editors: Editor[] = [];

constructor(messageController: IMessageController, markdownConverter?: MarkDownConverter) {
private constructor(messageController: IMessageController, markdownConverter?: MarkDownConverter) {
this.$messageController = messageController;
this.$markdownConverter = markdownConverter ?? new showdown.Converter();
this.$descriptionTooltip = new DescriptionTooltip(this);
}

static for(mode: Worker | WebSocket, markdownConverter?: MarkDownConverter) {
let messageController: IMessageController;
if (mode instanceof Worker) {
messageController = new MessageController(mode);
} else {
messageController = new MessageControllerWS(mode);
}
return new LanguageProvider(messageController, markdownConverter);
}

private $registerSession = (session?: EditSession, options?: ServiceOptions) => {
if (!session)
return;
Expand Down Expand Up @@ -66,6 +79,10 @@ export class LanguageProvider {
sessionLanguageProvider.setOptions(options);
}

setGlobalOptions<T extends keyof ServiceOptionsMap>(serviceName: T, options: ServiceOptionsMap[T], merge = false) {
this.$messageController.setGlobalOptions(serviceName, options, merge);
}

doHover(session: EditSession, position: Ace.Point, callback?: (hover: Tooltip) => void) {
this.$messageController.doHover(this.$getFileName(session), position, callback);
}
Expand Down Expand Up @@ -247,4 +264,4 @@ class SessionLanguageProvider {
let cursor = editor.getCursorPosition();
this.$messageController.doComplete(this.fileName, cursor, callback);
}
}
}
2 changes: 1 addition & 1 deletion packages/ace-linters/package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "ace-linters",
"author": "Azat Alimov <[email protected]>",
"version": "0.1.0",
"version": "0.1.1",
"scripts": {
"clean": "rimraf build",
"build": "npm run clean && webpack --mode=production",
Expand Down
Loading

0 comments on commit f7cb87b

Please sign in to comment.