dasylang / dasy

a lisp built on top of vyper
50 stars 2 forks source link

Build VS Code Extension #7

Open z80dev opened 1 year ago

z80dev commented 1 year ago

because we don't only want emacs nerds to use this

VS code extension with basic syntax highlighting as a start

z80dev commented 1 year ago

this is what GPT4 had to say

Creating a new Visual Studio Code extension for syntax highlighting of your programming language involves several steps:

1. Setting up your environment

Before you start, you'll need to have Node.js and npm installed on your machine. You'll also need to install Yeoman and VS Code Extension Generator, which will help you set up the basic structure of your extension. You can install these with the following command:

npm install -g yo generator-code

2. Generating a new extension

Once Yeoman and the VS Code Extension Generator are installed, you can generate a new extension by running the following command and answering the prompts:

yo code

You'll want to select "New Language Support" when asked what type of extension you want to create.

3. Defining the language

After generating your extension, you'll see a new directory with the same name as your extension. Inside this directory, there should be a syntaxes directory, and inside that, a .tmLanguage.json file. This file is where you'll define your language's syntax.

This file uses TextMate grammar for defining language syntax. Each rule has two parts: a regular expression pattern and a scope name. When the pattern is matched, VS Code will assign the scope name to the matched text, which is then used for coloring.

As your language is a Lisp, the syntax rules will likely be fairly simple, as Lisp syntax is generally simpler than many other languages.

4. Defining the color scheme

To actually color your syntax, you'll need to define a color scheme. This is done in a .tmTheme file, which you'll need to create in your syntaxes directory. This file should define colors for each of the scope names you used in your .tmLanguage.json file.

5. Packaging and publishing your extension

Once your syntax and color scheme are defined, you can package your extension into a .vsix file using the vsce command:

vsce package

You can then publish your extension to the VS Code marketplace using the vsce publish command, though this requires a Microsoft account and an Azure DevOps organization.

Note: This is a high-level guide. The actual implementation may be more complex and require a deeper understanding of TextMate grammars and the VS Code extension API. There is also more comprehensive documentation available from Microsoft, which I recommend you read.

This is a simplified version of the process and depending on the complexity of your lisp language and the level of support you want to provide in the plugin (like autocompletion, error checking, etc.), you might need to delve deeper into creating VS Code extensions.

Implementing autocompletion (also known as IntelliSense) for your custom language in a VS Code extension involves using the CompletionItemProvider interface. Here's a general guide on how you can do it:

1. Setting up your environment

As with the syntax highlighting, you'll need Node.js and npm installed on your machine. You'll also need to install Yeoman and VS Code Extension Generator, which you can install with the following command:

npm install -g yo generator-code

2. Generating a new extension

Once Yeoman and the VS Code Extension Generator are installed, you can generate a new extension by running the following command and answering the prompts:

yo code

You'll want to select "New Extension (TypeScript)" when asked what type of extension you want to create.

3. Implementing the CompletionItemProvider

In your extension's main TypeScript file, you'll want to register a CompletionItemProvider for your language. Here's an example of what this might look like:

import * as vscode from 'vscode';

export function activate(context: vscode.ExtensionContext) {
    context.subscriptions.push(vscode.languages.registerCompletionItemProvider('yourLanguageId', {
        provideCompletionItems(document: vscode.TextDocument, position: vscode.Position, token: vscode.CancellationToken, context: vscode.CompletionContext) {
            // a simple completion item which inserts `Hello, World!`
            const simpleCompletion = new vscode.CompletionItem('Hello, World!');

            // a completion item that inserts its text as snippet,
            // the `insertText`-property is a `SnippetString` (`Hello, ${1:World}!` in this case),
            // which allows the user to tab through the snippet's placeholders
            const snippetCompletion = new vscode.CompletionItem('Good part of the day');
            snippetCompletion.insertText = new vscode.SnippetString('Good ${1|morning,afternoon,evening|}. It is ${2|Monday,Tuesday,Wednesday,Thursday,Friday,Saturday,Sunday|}.');

            // a completion item that can be accepted by a commit character,
            // the `commitCharacters`-property is set which means that the completion will
            // be inserted and then accepting character will be typed
            const commitCharacterCompletion = new vscode.CompletionItem('console');
            commitCharacterCompletion.commitCharacters = ['.'];
            commitCharacterCompletion.insertText = 'console';
            commitCharacterCompletion.documentation = new vscode.MarkdownString('Press `.` to get `console.`');

            // a completion item that retriggers IntelliSense when being accepted,
            // the `command`-property is set which means that the `editor.action.triggerSuggest`-command is run after accepting the completion,
            // that command will retrigger IntelliSense
            const commandCompletion = new vscode.CompletionItem('new');
            commandCompletion.kind = vscode.CompletionItemKind.Keyword;
            commandCompletion.insertText = 'new ';
            commandCompletion.command = { command: 'editor.action.triggerSuggest', title: 'Re-trigger completions...' };

            // return all completion items as array
            return [
                simpleCompletion,
                snippetCompletion,
                commitCharacterCompletion,
                commandCompletion
            ];
        }
    }));
}

4. Packaging and publishing your extension

Once your autocompletion is implemented, you can package your extension into a .vsix file using the vsce command:

vsce package

You can then publish your extension to the VS Code marketplace using the vsce publish command, though this requires a Microsoft account and an Azure DevOps organization.

Note: This is a high-level guide.

The actual implementation may be more complex and require a deeper understanding of the VS Code extension API. For instance, in the provideCompletionItems function, you'll need to analyze the current document and position to determine what completion items to provide. Depending on the complexity of your language, this could be a simple or complex task.

The above example provides static completions, but in a real-world scenario, you'd likely want to provide dynamic completions based on the context of the user's code. This might involve parsing the user's code and providing completions based on the functions, variables, and other symbols they've defined.

I recommend reading the official VS Code extension documentation, specifically the Completion Item Provider section, for more detailed information.

daoio commented 8 months ago

is there a dasy major mode tho? Clojure looks like the closest Lisp in terms of syntax, but its mode still doesn't highlight a bunch of keywords