Skip to content

Commit 398f710

Browse files
committed
update nvim configuration
1 parent 1b5a83e commit 398f710

File tree

9 files changed

+251
-44
lines changed

9 files changed

+251
-44
lines changed

tools/.claude/settings.local.json

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
{
2+
"permissions": {
3+
"allow": [
4+
"Bash(mkdir:*)",
5+
"Bash(cp:*)",
6+
"Bash(npx tree-sitter parse:*)",
7+
"Bash(npx tree-sitter:*)",
8+
"Bash(tree:*)",
9+
"Bash(lua:*)",
10+
"Bash(npm run build-parser:*)"
11+
],
12+
"deny": [],
13+
"ask": []
14+
}
15+
}

tools/treesitter/README.md

Lines changed: 205 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ The most significant design decision was resolving parse ambiguity between three
5959
**Problem:**
6060
```filament
6161
x := new Component[32]; // Instance creation
62-
y := Component<'G>(ports); // Invocation
62+
y := Component<'G>(ports); // Invocation
6363
z := expr; // Existential binding
6464
```
6565

@@ -84,7 +84,7 @@ assignment: $ => seq(
8484
```
8585

8686
This approach:
87-
- ✅ Leverages unique tokens (`new`, `<`) for disambiguation
87+
- ✅ Leverages unique tokens (`new`, `<`) for disambiguation
8888
- ✅ Maintains identical AST structure for downstream tools
8989
- ✅ Eliminates all parse conflicts
9090
- ✅ Handles 100% of test cases correctly
@@ -94,7 +94,7 @@ This approach:
9494
The grammar is specifically designed for LSP functionality with careful attention to:
9595

9696
**Definition Providers:**
97-
- Component names: `comp MyComponent`
97+
- Component names: `comp MyComponent`
9898
- Parameter names: `[WIDTH, HEIGHT]`, `with { some PARAM; }`
9999
- Instance names: `adder := new Add[32]`
100100
- Port names: `input: ['G, 'G+1] 32`
@@ -117,7 +117,7 @@ tools/tree-sitter/
117117
├── package.json # NPM package configuration
118118
├── queries/ # LSP query files
119119
│ ├── highlights.scm # Syntax highlighting rules
120-
│ ├── locals.scm # Local scope definitions
120+
│ ├── locals.scm # Local scope definitions
121121
│ └── tags.scm # Symbol extraction for navigation
122122
├── src/ # Generated parser (auto-generated)
123123
├── bindings/ # Language bindings (auto-generated)
@@ -128,17 +128,126 @@ tools/tree-sitter/
128128

129129
### Building the Parser
130130

131+
The parser build process involves several steps that transform the grammar definition into a usable shared library:
132+
133+
#### Automated Build (Recommended)
134+
```bash
135+
# Install dependencies and build parser in one step
136+
npm install # Runs postinstall hook automatically
137+
138+
# Or build explicitly
139+
npm run build-parser
140+
```
141+
142+
#### Manual Build Steps
131143
```bash
132-
# Install dependencies
144+
# 1. Install tree-sitter CLI and dependencies
133145
npm install
134146

135-
# Generate the parser
147+
# 2. Generate C code from grammar.js
136148
npx tree-sitter generate
137149

138-
# Test the grammar
150+
# 3. Compile shared library for Neovim
151+
gcc -o src/parser.so -shared -fPIC -I src src/parser.c
152+
153+
# 4. Test the grammar
139154
npx tree-sitter test
140155
```
141156

157+
#### What Each Step Does
158+
159+
1. **`npm install`**:
160+
- Installs `tree-sitter-cli` and Node.js dependencies
161+
- Runs `postinstall` hook → automatically builds parser
162+
- Creates `node_modules/` directory
163+
164+
2. **`tree-sitter generate`**:
165+
- Reads `grammar.js` (source grammar definition)
166+
- Generates `src/parser.c` (C implementation)
167+
- Generates `src/grammar.json` (grammar metadata)
168+
- Generates `src/node-types.json` (AST node types)
169+
- Creates `src/tree_sitter/parser.h` (header file)
170+
171+
3. **`gcc` compilation**:
172+
- Compiles `src/parser.c` to `src/parser.so`
173+
- Creates position-independent code (`-fPIC`)
174+
- Links as shared library (`-shared`)
175+
- Includes headers from `src/` directory (`-I src`)
176+
177+
4. **Result**: `src/parser.so` - ready for Neovim integration
178+
179+
#### Build Artifacts
180+
181+
**Generated files (git-ignored):**
182+
```
183+
src/
184+
├── parser.c # Generated C parser implementation
185+
├── parser.so # Compiled shared library (for Neovim)
186+
├── grammar.json # Grammar metadata
187+
├── node-types.json # AST node type definitions
188+
└── tree_sitter/
189+
└── parser.h # C header file
190+
```
191+
192+
**Source files (version controlled):**
193+
```
194+
grammar.js # Grammar definition (source of truth)
195+
package.json # Build configuration with npm scripts
196+
queries/ # Syntax highlighting and query rules
197+
├── highlights.scm
198+
├── locals.scm
199+
└── tags.scm
200+
```
201+
202+
The `package.json` defines several build scripts for different purposes:
203+
204+
```json
205+
{
206+
"scripts": {
207+
"build": "tree-sitter generate && node-gyp build",
208+
"build-parser": "tree-sitter generate && gcc -o src/parser.so -shared -fPIC -I src src/parser.c",
209+
"postinstall": "npm run build-parser",
210+
"test": "tree-sitter test"
211+
}
212+
}
213+
```
214+
215+
#### Script Breakdown
216+
217+
- **`npm run build`**: Full Node.js binding build
218+
- Generates parser C code
219+
- Builds Node.js native module using `node-gyp`
220+
- Creates `build/Release/tree_sitter_filament_binding.node`
221+
- Used for Node.js applications and tree-sitter CLI tools
222+
223+
- **`npm run build-parser`**: Neovim-specific build
224+
- Generates parser C code
225+
- Compiles directly to shared library (`parser.so`)
226+
- Optimized for Neovim tree-sitter integration
227+
- **This is what editor plugins use**
228+
229+
- **`postinstall`**: Automatic build hook
230+
- Runs after `npm install`
231+
- Calls `build-parser` to create `src/parser.so`
232+
- Enables zero-config installation for users
233+
234+
- **`npm test`**: Grammar validation
235+
- Runs tree-sitter test suite
236+
- Validates grammar against test files
237+
- Checks parsing correctness
238+
239+
#### Build Requirements
240+
241+
**System Dependencies:**
242+
- **Node.js & npm**: For running build scripts
243+
- **GCC**: For compiling C code to shared library
244+
- **tree-sitter CLI**: Installed via npm dependencies
245+
246+
**Platform Notes:**
247+
- **Linux/macOS**: Uses GCC directly
248+
- **Windows**: May require MinGW or MSYS2 for GCC
249+
- **Cross-platform**: Node.js parts work everywhere
250+
142251
### Testing with Filament Files
143252

144253
```bash
@@ -170,7 +279,7 @@ Defines syntax highlighting rules:
170279
- Types: component names, parameter names
171280
- Functions: builtin functions like `pow2`, `log2`
172281

173-
### locals.scm
282+
### locals.scm
174283
Defines local scope rules for variable resolution:
175284
- Component scopes for parameter visibility
176285
- With-block scopes for existential parameters
@@ -188,14 +297,99 @@ Defines symbol extraction for "jump to definition":
188297

189298
The grammar includes comprehensive tests covering:
190299
- ✅ Simple component definitions
191-
- ✅ Complex signatures with with-blocks
300+
- ✅ Complex signatures with with-blocks
192301
- ✅ External declarations
193302
- ✅ All three assignment types (instance, invocation, existential)
194303
- ✅ Nested expressions and time arithmetic
195304
- ✅ Error recovery and partial parsing
196305

197306
Test files demonstrate parsing of real Filament programs from the repository.
198307

308+
## Build Troubleshooting
309+
310+
### Common Build Issues
311+
312+
#### Missing GCC Compiler
313+
```
314+
Error: gcc: command not found
315+
```
316+
**Solutions:**
317+
- **macOS**: Install Xcode command line tools: `xcode-select --install`
318+
- **Linux**: Install build-essential: `sudo apt install build-essential` (Ubuntu/Debian) or `sudo yum groupinstall "Development Tools"` (RHEL/CentOS)
319+
- **Windows**: Install MinGW-w64 or use WSL with Linux tools
320+
321+
#### Node.js/NPM Missing
322+
```
323+
Error: npm: command not found
324+
```
325+
**Solutions:**
326+
- Install Node.js from https://nodejs.org/
327+
- Use package manager: `brew install node` (macOS), `sudo apt install nodejs npm` (Linux)
328+
- Use version manager: `nvm install node`
329+
330+
#### Parser Generation Fails
331+
```
332+
Error during tree-sitter generate
333+
```
334+
**Solutions:**
335+
- Check `grammar.js` syntax for JavaScript errors
336+
- Verify tree-sitter CLI installation: `npx tree-sitter --version`
337+
- Clean and rebuild: `rm -rf src/ && npm run build-parser`
338+
339+
#### Compilation Errors
340+
```
341+
Error: src/parser.c: No such file or directory
342+
```
343+
**Solutions:**
344+
- Ensure `tree-sitter generate` ran successfully first
345+
- Check that `src/parser.c` exists after generation
346+
- Run full build: `npm install && npm run build-parser`
347+
348+
#### Permission Issues
349+
```
350+
Error: EACCES: permission denied
351+
```
352+
**Solutions:**
353+
- Don't use `sudo` with npm (security risk)
354+
- Fix npm permissions: https://docs.npmjs.com/resolving-eacces-permissions-errors-when-installing-packages-globally
355+
- Use node version manager (nvm) instead of system Node.js
356+
357+
#### Windows-Specific Issues
358+
```
359+
Error: 'gcc' is not recognized as an internal or external command
360+
```
361+
**Solutions:**
362+
- Install MinGW-w64: https://www.mingw-w64.org/
363+
- Add GCC to PATH environment variable
364+
- Use WSL (Windows Subsystem for Linux) with Ubuntu
365+
- Consider using Visual Studio Build Tools with node-gyp
366+
367+
### Verification Steps
368+
369+
After successful build, verify:
370+
```bash
371+
# Check generated files exist
372+
ls -la src/
373+
# Should show: parser.c, parser.so, grammar.json, node-types.json
374+
375+
# Test the parser works
376+
npx tree-sitter parse test_simple.fil
377+
378+
# Verify shared library
379+
file src/parser.so
380+
# Should show: shared library, dynamically linked
381+
```
382+
383+
### Clean Rebuild
384+
385+
If experiencing persistent issues:
386+
```bash
387+
# Full clean and rebuild
388+
rm -rf src/ node_modules/ build/
389+
npm install
390+
npm run build-parser
391+
```
392+
199393
## Implementation Notes
200394

201395
### Grammar Conflicts Resolved
@@ -228,7 +422,7 @@ Test files demonstrate parsing of real Filament programs from the repository.
228422
The grammar foundation supports adding:
229423
- **Error diagnostics** with precise source locations
230424
- **Semantic highlighting** based on symbol types
231-
- **Auto-completion** using partial parse trees
425+
- **Auto-completion** using partial parse trees
232426
- **Refactoring tools** via AST transformations
233427
- **Documentation generation** from parsed structures
234428

@@ -242,4 +436,4 @@ When modifying the grammar:
242436
4. **Document design decisions** for complex changes
243437
5. **Preserve LSP compatibility** by maintaining field names
244438

245-
The grammar is designed to evolve with the Filament language while maintaining backward compatibility for existing LSP tooling.
439+
The grammar is designed to evolve with the Filament language while maintaining backward compatibility for existing LSP tooling.

tools/vim/README.md

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ Plug 'filament-hdl/filament', {'rtp': 'treesitter/tools/vim/filament', 'do': 'cd
4040
}
4141
```
4242

43-
**That's it!** The parser builds automatically and syntax highlighting works immediately.
43+
**That's it!** The `do`/`build` hook builds the parser during plugin installation, then syntax highlighting works immediately.
4444

4545
### Requirements
4646
- **Neovim 0.8+** (for tree-sitter support)
@@ -73,7 +73,7 @@ Add to your lazy configuration:
7373
dependencies = { 'nvim-treesitter/nvim-treesitter' },
7474
config = function()
7575
require('filament').setup({
76-
auto_install = false, -- Parser is built automatically
76+
-- Parser is built by 'build' hook above
7777
})
7878
end,
7979
}
@@ -89,7 +89,7 @@ use {
8989
run = 'cd treesitter/tools/treesitter && npm install && npm run build-parser',
9090
config = function()
9191
require('filament').setup({
92-
auto_install = false, -- Parser is built automatically
92+
-- Parser is built by 'run' hook above
9393
})
9494
end
9595
}
@@ -366,9 +366,9 @@ The tree-sitter grammar provides comprehensive highlighting for:
366366
Error: no parser for 'filament' language
367367
```
368368
**Solutions**:
369-
1. Run `:TSInstall filament` in Neovim
370-
2. Use `require('filament').setup({ auto_install = true })`
371-
3. Build parser manually from `treesitter/tools/treesitter/`
369+
1. **Most likely**: Plugin manager didn't run the build hook. Reinstall with `:PlugClean` then `:PlugInstall`
370+
2. **Manual build**: Run `:FilamentBuildParser` in Neovim
371+
3. **Command line**: `cd treesitter/tools/treesitter && npm run build-parser`
372372

373373
### Plugin Not Loading
374374
1. Check runtimepath: `:set rtp?` should include filament plugin path

tools/vim/examples/lazy.lua

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -43,9 +43,8 @@ return {
4343
dependencies = { 'nvim-treesitter/nvim-treesitter' },
4444
config = function()
4545
require('filament').setup({
46-
auto_install = true,
46+
-- Parser built by 'build' hook above, no auto_install needed
4747
treesitter = {
48-
-- Additional tree-sitter configuration specific to filament
4948
highlight = { enable = true },
5049
indent = { enable = true },
5150
fold = { enable = true },

tools/vim/examples/packer.lua

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ return require('packer').startup(function(use)
3636
run = 'cd treesitter/tools/treesitter && npm install && npm run build-parser',
3737
config = function()
3838
require('filament').setup({
39-
auto_install = true,
39+
-- Parser built by 'run' hook above, no auto_install needed
4040
treesitter = {
4141
highlight = { enable = true },
4242
indent = { enable = true },

tools/vim/examples/vim-plug.vim

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,10 +29,11 @@ require('nvim-treesitter.configs').setup {
2929
},
3030
}
3131

32-
-- Setup filament with auto-install
32+
-- Setup filament (parser built by 'do' hook above)
3333
require('filament').setup({
34-
auto_install = true,
3534
treesitter = {
35+
highlight = { enable = true },
36+
indent = { enable = true },
3637
fold = { enable = true },
3738
incremental_selection = { enable = true },
3839
}

tools/vim/filament/lua/filament/init.lua

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,11 +19,12 @@ function M.setup(opts)
1919
}, opts.treesitter or {}))
2020
end
2121

22-
-- Auto-install parser if requested
22+
-- Auto-install parser if explicitly requested (not recommended)
2323
if opts.auto_install then
2424
vim.schedule(function()
2525
local status = treesitter.status()
2626
if status.available and not status.parser_installed then
27+
vim.notify('Auto-installing Filament parser...', vim.log.levels.INFO)
2728
treesitter.install_parser()
2829
end
2930
end)

0 commit comments

Comments
 (0)