Welcome, and thank you for your interest in this project!
Hoping this guide will be helpful to you whether you would like to contribute, fork, or learn this repository :)
Please note that we will discuss the implementation of programmatic-language-features in the folder
./srcfirst. If you are interested in declarative language features, see the part declarative-language-features.
Let us first take a brief look at the design of this project.
The image above shows the layers of the source code. entry initializes the extension and applies the vscode workspace configuration to the extension. provider_interface registers the providers in vscode. builders prepare the data structures from the raw text string/processed semantic information for vscode language features. collect_info collects the semantic information from the raw text string. common includes some constants and algorithms. doc is the interface for getting documentation.
If you are interested in a more detailed dependency graph, you can find the dependency graph in ./images/doc/dependency_graph.svg. Also, you can generate the dependency graph by running
You may need to run
sudo apt install graphvizfirst
npx depcruise src --no-config --include-only "^src" --output-type dot | dot -T svg > ./images/doc/dependency_graph.svgPlease do not trust the correspondence between naming in the data flow diagram and naming in the source code since the naming in the source code is subject to change.
This part is above the dashed line in the Data Flow diagram. entry includes this part.
The config listener will listen to the config change from vscode. Then, the config listener will call other functions to register the correct providers and pass the building config to structuredInfo. If you are interested in the configuration of this extension, see
Configuration.
Also, the dirty listener will set the dirty flag to true in structuredInfo when a text/editor change event is received.
This part is below the dashed line in the Data Flow diagram. The core functionality is in this part. First, if you are not familiar with vscode extension, please just check patterns-and-principles and programmatic-language-features.
When vscode requests language information from a provider, the provider will call updateResultByDoc to get updated semantic information. Then, the provider will return the information to vscode. If you are interested in how the provider works, you can check the samples in vscode-extension-samples samples which used API languages.
Run npm install
-
How to add a vscode provider?
- add a pair (k, v) in
TraceableDisposables.disposables - add a pair (k, v) in
TraceableDisposables.cfgMapDisposable - add a case in
TraceableDisposables.registerProviderByName - add a config (k, v) in
WorkspaceConfig.config - add a config in
contributes.configuration.propertiesinpackage.json
- add a pair (k, v) in
-
How to change the parsing process?
The parsing process is incollect_from_text, and the symbol information is stored inMap{name: SymbolInfo} -
How to change the vscode-formated language information?
buildersprepare the vscode-formated language information. Seeexport{}to understand what information the builder is building.
Run npm run esbuildc for compiling once;
Run npm run esbuildw for watch mode;
Run npm run esbuildp for production.
Please remember to run
npm run tsccfor TypeScript type checking separately.
For more commands, check them in "scripts" in package.json.
Note that we are trying to use esbuild as the bundler since it is faster than webpack. However, we still keep webpack for vsce package.
See debugging-the-extension. Note that "preLaunchTask": "npm: esbuildc" in launch.json is disabled in this project so you need to run npm run esbuildc (or just enable "preLaunchTask") before launching the debugger.
Run npm run lint for linting.
Most errors and warnings can be fixed automatically by running npm run lint -- --fix.
Run npx knip to check if there are any dangling files.
There are no tests now. The features of this project are still changing. Most of the time needs to be allocated for polishing the features.
Run npm i -g @vscode/vsce to install vsce globally since vsce is not in the package.json.
Run vsce package.
Then, you will get a common-lisp-x.x.x.vsix in your ./ .
.vscodeignoreuses whitelist mode. Runnpx vsce lsto check what has been packaged.
If you would like to use the packaged .vsix extension, you can load the .vsix extension to vscode by referring to extension-marketplace install-from-a-vsix.
The version number is in the format MAJOR.MINOR.PATCH. We do not comply with the Semantic Versioning strictly. We save x.x.0 for the alpha version and x.x.1 for the beta version.
We are trying to write dumb code. TypeScript has many fancy syntax features, however, we would not like to use them too much. We are trying to maintain the best readability while utilizing some useful syntax features.
We do not use prettier in the linter, and the reason is basically Why I don't use Prettier_antfu.
According to The Art of Unix Programming, Chapter 4. Modularity, Encapsulation and Optimal Module Size,
we are trying to keep <200 logical lines of code and <400 physical lines of code per file for maintainability.
Run find ./src -name '*.ts' | xargs wc -l to check the physical lines of code of ./src.
We have two syntax files in ./syntaxes, and we use ./syntaxes/scripts/build_grammar.mjs to convert them into json format:
commonlisp.yamlis the main syntax of Common Lisp.cl_codeblock.yamlis the injection grammar for Markdown.
If you need to modify the syntax, here are some helpful materials:
Syntax Highlight Guide,
TextMate grammars,
making_language_grammar,
textmatebundle,
regex101,
Common Lisp HyperSpec.
Mastering the TextMate grammars is very difficult. If you are a beginner, you can try to start with a small work sample and then work on it incrementally.
The recommended workflow is:
git add- construct a regex and verify the regex in regex101
- add the regex to the syntax
- convert the syntax into
jsonand test the syntax in real world
npm run bg # After you modified the grammar, you need to rebuild the grammar.
npm run testg # Then, test the grammar with the fixtures in `syntaxes/fixtures/baselines`.
npm run diff # Check if it is the test result you expected. Find the differences between the baselines and generated.
npm run accept # If the changes are what you expect, accept the new baselines.You may need to run
npx tsc -p syntaxes/scripts/tsconfig.emit.jsonto generategen_record.mjsbeforenpm run testg.
In ./declaratives/commonlisp_snippets.json.
See Snippet Guide and creating-your-own-snippets.
In ./declaratives/language-configuration.json.
See Language Configuration Guide.
