Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
47 commits
Select commit Hold shift + click to select a range
1103e6e
Add scope tracking to Walker for LSP support
Tasty-Kiwi Feb 7, 2026
4f55cfc
Implement LSP analysis pipeline, state management, and scope-based co…
Tasty-Kiwi Feb 7, 2026
36211d4
Walker scope tracking pt 2
Tasty-Kiwi Feb 7, 2026
e44f5a2
Revert "disable the LSP command (the LSP is not ready yet)"
Tasty-Kiwi Feb 7, 2026
0e3852c
Implement LSP features including hover, signature help, and enhanced …
Tasty-Kiwi Feb 7, 2026
0042278
format code, clean up certain code
Tasty-Kiwi Feb 11, 2026
bdb9099
fix hover and function signature bugs
Tasty-Kiwi Feb 11, 2026
ecb8376
implement `--debug` flag for lsp
Tasty-Kiwi Feb 11, 2026
dc339b0
Update copyright year to 2026 and other touch-ups
Tasty-Kiwi Feb 12, 2026
05c17bd
add enum, entity, class support and primitive custom namespace support
Tasty-Kiwi Feb 12, 2026
a4d4fce
Use evaluator instead of own namespace mechanism in LSP
Tasty-Kiwi Feb 12, 2026
38d08a1
Progress on autocomplete from other files
Tasty-Kiwi Feb 12, 2026
d0eeece
little progress on custom namespace autocomplete
Tasty-Kiwi Feb 13, 2026
b898765
fix custom namespace autocomplete
Tasty-Kiwi Feb 13, 2026
6efce36
fix namespace bugs and implement go-to-definition
Tasty-Kiwi Feb 14, 2026
7d17619
implement go-to-reference and improve go-to-definition
Tasty-Kiwi Feb 14, 2026
2ab1ac7
got-to reference fixes and QoL for numeric literals
Tasty-Kiwi Feb 15, 2026
6c7fac3
add lsp builtin documentation and update API
Tasty-Kiwi Feb 15, 2026
b65ec0c
add better function signatures but diagnostics are broken
Tasty-Kiwi Feb 15, 2026
18cf037
fix broken error diagnostics, improve missing paren errors, fix evalu…
Tasty-Kiwi Feb 18, 2026
212db6a
implement symbol rename, fix enum problems
Tasty-Kiwi Feb 20, 2026
26a797b
Add rename feature, stray file fixes, other changes
Tasty-Kiwi Feb 20, 2026
10d025e
update agent context
Tasty-Kiwi Feb 20, 2026
77845fa
Codex: Fix nil env handling in LSP and alias unused token source
Tasty-Kiwi Feb 25, 2026
865ec10
Codex: Add evaluator locking and fix path handling in LSP
Tasty-Kiwi Feb 25, 2026
5868029
Codex: Deduplicate LSP word helpers and streamline comment scan
Tasty-Kiwi Feb 25, 2026
e90bb98
Codex: Fix LSP analysis crashes, races, and stale diagnostics
Tasty-Kiwi Feb 25, 2026
b912373
Update .gitignore to include .DS_Store and ensure proper formatting
Tasty-Kiwi Jun 2, 2026
a7b6009
Codex: Enhance LSP functionality with improved handling and new submo…
Tasty-Kiwi Jun 2, 2026
2f62425
Enhance LSP logging mechanism to support configurable log file paths …
Tasty-Kiwi Jun 2, 2026
7b00596
fix lsp crash and rename GEMINI.md to AGENTS.md
Tasty-Kiwi Jun 4, 2026
ec7085d
add single file opening support
Tasty-Kiwi Jun 4, 2026
dee09c5
update vscode-ext submodule
Tasty-Kiwi Jun 4, 2026
45fbc1b
test impl phase 1
Tasty-Kiwi Jun 4, 2026
c0322bf
test impl phase 2
Tasty-Kiwi Jun 4, 2026
2b6758d
test impl phase 3, memory leak found
Tasty-Kiwi Jun 4, 2026
5488355
fix memory leak in evaluator
Tasty-Kiwi Jun 4, 2026
51cd6af
add LSP logging configuration and tests; update VS Code extension setup
Tasty-Kiwi Jun 4, 2026
5b97bbc
fix CI
Tasty-Kiwi Jun 4, 2026
530bc94
delete binary file
Tasty-Kiwi Jun 4, 2026
e4985f8
restore the nuked tests
Tasty-Kiwi Jun 5, 2026
5cee6cf
fix deviated expression and statement tests
Tasty-Kiwi Jun 5, 2026
5cb8bd2
revert removal of AST identifier mutations.
Tasty-Kiwi Jun 5, 2026
95078b3
Potential fix for pull request finding
SKPG-Tech Jun 5, 2026
2c22f06
Apply suggestions from code review
SKPG-Tech Jun 5, 2026
afe904a
PR Cleanup, review for merge
SKPG-Tech Jun 6, 2026
1f8660d
Upgrade to go 1.26.4. Upgrade dependencies
SKPG-Tech Jun 6, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -26,4 +26,8 @@ __pycache__

# Hybroid Live generated files
examples/*/out

# DS_Store
.DS_Store

hybroid
3 changes: 3 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
[submodule "docs"]
path = docs
url = https://github.com/pewpewlive/hybroid-docs.git
[submodule "vscode-ext"]
path = vscode-ext
url = https://github.com/pewpewlive/hybroid-vscode.git
21 changes: 21 additions & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,10 @@ The project is written in **Go** and follows a standard compiler architecture:
4. **Generator (`generator/`)**: Transpiles the AST into Lua code.
5. **LSP (`lsp/`)**: Provides Language Server Protocol support for editors (VS Code).

### LSP single-file fallback

When the editor opens a `.hyb` file without a containing folder (no `rootUri` in the `initialize` request), the LSP walks the parent directories looking for `hybconfig.toml` — the same pattern that `tsserver` uses to discover a `tsconfig.json` for loose files. If a project root is found, full workspace analysis runs as if the folder had been opened. If no marker is found, the file is analyzed in isolation and a single Information diagnostic is published at the top of the buffer: *"This file is open without its Hybroid project. Open the folder containing `hybconfig.toml` to resolve all `use` references."* See `lsp/find_project_root.go` and `lsp/handle_text_document_did_change.go`.

## Development Environments

Hybroid supports distinct "environments" that dictate available standard libraries and compilation behavior:
Expand Down Expand Up @@ -61,6 +65,23 @@ Run standard Go tests:
go test ./...
```

### Releasing the LSP alpha

1. Tag the merge commit on `master` as `v0.1.0-lsp-alpha`.
2. Run `python utils/build_hybroid.py` to produce binaries for all platforms in `./build/`. Upload each to the GitHub Release with the name `hybroid-<platform><.exe>`.
3. The `install.sh` / `install.ps1` scripts at hybroid.pewpew.live fetch the matching asset and copy it to `~/.hybroid/hybroid`.
4. The VS Code extension is packaged and published separately in the `hybroid-vscode` repo. Bump its `version` in `package.json` to `0.1.0` and run `vsce package`.
5. No new CI workflow is added in this repo — the existing `.github/workflows/go.yml` validates builds and tests on push to master, which is sufficient for the alpha.

### Install location and logs

The Hybroid CLI/LSP binary and the LSP debug log both live under `~/.hybroid/`:

* Binary: `~/.hybroid/hybroid` (or `~/.hybroid/hybroid.exe` on Windows)
* LSP log (debug mode only): `~/.hybroid/logs/lsp.log`

The `HYBROID_LS_LOG` environment variable overrides the log path. On macOS, VS Code has a sanitized PATH that does not include `~/.hybroid`, so the extension searches there explicitly. The `hybroid.languageServerPath` user setting is the override if both mechanisms fail. See `lsp/logpath.go` for the resolution contract and `vscode-ext/src/path-resolver.ts` (in the submodule) for the binary search chain.

## Directory Structure

* `alerts/`: Error reporting system (diagnostics, pretty printing).
Expand Down
2 changes: 1 addition & 1 deletion LICENSE
Original file line number Diff line number Diff line change
Expand Up @@ -186,7 +186,7 @@
same "printed page" as the copyright notice for easier
identification within third-party archives.

Copyright 2025 Hybroid Team
Copyright 2026 Hybroid Team

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
Expand Down
4 changes: 4 additions & 0 deletions alerts/printer.go
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,10 @@ func (p *Printer) GetAlerts(sourcePath string) []Alert {
return p.alertsByFile[sourcePath]
}

func (p *Printer) AllAlerts() map[string][]Alert {
return p.alertsByFile
}

func (p *Printer) StageAlerts(sourcePath string, alerts []Alert) {
fileAlerts, existed := p.alertsByFile[sourcePath]
if !existed {
Expand Down
17 changes: 17 additions & 0 deletions alerts/snippet.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,23 @@ func writeTruncatedLine(snippet *strings.Builder, loc tokens.Location, line []by
start, end := loc.Column.Start, loc.Column.End
lineSize := len(line)

// Clamp column values into the valid range for this line. A bad or
// stale column (e.g. from a multi-line token whose End points past the
// current line, or a single-line token whose End > line length) would
// otherwise cause slice-out-of-range panics below.
if start < 1 {
start = 1
}
if end < start {
end = start
}
if start-1 > lineSize {
start = lineSize + 1
}
if end-1 > lineSize {
end = lineSize + 1
}

leadingSpace := start - 1
markerSize := end - start

Expand Down
5 changes: 3 additions & 2 deletions ast/expressions.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,8 +50,9 @@ func (pe *EntityAccessExpr) GetType() NodeType { return EntityAccessExpress
func (pe *EntityAccessExpr) GetToken() tokens.Token { return pe.Expr.GetToken() }

type LiteralExpr struct {
Value string
Token tokens.Token
Value string
Token tokens.Token
IsEnvPath bool // Set when this literal was generated from an environment identifier
}

func (le *LiteralExpr) GetType() NodeType { return LiteralExpression }
Expand Down
7 changes: 3 additions & 4 deletions cli/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,15 +12,14 @@ func RunApp() {
app := &cli.App{
Name: "hybroid-live",
Usage: "The Hybroid Live transpiler CLI",
Version: "0.1.0",
Copyright: "Copyright (C) Hybroid Team, 2025\nLicensed under Apache-2.0",
Version: "0.2.0-alpha",
Copyright: "Copyright (C) Hybroid Team, 2026\nLicensed under Apache-2.0",
Commands: []*cli.Command{
commands.Add(),
commands.Build(),
commands.Initialize(),
commands.Watch(),
// LSP is not yet implemented
// commands.Lsp(),
commands.Lsp(),
},
}

Expand Down
4 changes: 2 additions & 2 deletions cli/commands/build.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ func Build() *cli.Command {
}
}

func runEvaluator(config core.HybroidConfig, filesToBuild []core.FileInformation, cwd string) error {
func runEvaluator(config core.HybroidConfig, filesToBuild []core.File, cwd string) error {
outputDir := config.Project.OutputDirectory

if outputDir != "" {
Expand Down Expand Up @@ -87,7 +87,7 @@ func runEvaluator(config core.HybroidConfig, filesToBuild []core.FileInformation
return nil
}

func Build_(filesToBuild ...core.FileInformation) error {
func Build_(filesToBuild ...core.File) error {
cwd, err := os.Getwd()
if err != nil {
return fmt.Errorf("failed getting current working directory: %v", err)
Expand Down
29 changes: 29 additions & 0 deletions cli/commands/lsp.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package commands

import (
"hybroid/lsp"

"github.com/urfave/cli/v2"
)

func Lsp() *cli.Command {
return &cli.Command{
Name: "language-server",
Aliases: []string{"server", "lsp"},
Usage: "Starts HybroidLS, an integrated Language Server for Hybroid Live",
Flags: []cli.Flag{
&cli.BoolFlag{
Name: "debug",
Usage: "Enable verbose debug logging",
},
},
Action: func(ctx *cli.Context) error {
return languageServer(ctx)
},
}
}

func languageServer(ctx *cli.Context) error {
lsp.Init(ctx.Bool("debug"))
return nil
}
2 changes: 1 addition & 1 deletion cli/commands/watch.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ func watch(ctx *cli.Context) error {
fileName := strings.Split(filepath.Base(event.Name), ".")[0]
fileExtension := filepath.Ext(event.Name)

Build_(core.FileInformation{DirectoryPath: directoryPath, FileName: fileName, FileExtension: fileExtension})
Build_(core.File{DirectoryPath: directoryPath, FileName: fileName, FileExtension: fileExtension})
}
case err, ok := <-watcher.Errors:
if !ok {
Expand Down
38 changes: 38 additions & 0 deletions core/files.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
package core

import (
"io/fs"
"os"
"path/filepath"
"strings"
)

func CollectFiles(dir string) ([]File, error) {
files := make([]File, 0)
err := fs.WalkDir(os.DirFS(dir), ".", func(path string, d fs.DirEntry, err error) error {
if d != nil && !d.IsDir() {
ext := filepath.Ext(path)
if ext != ".hyb" {
return nil
}

directoryPath, err := filepath.Rel(dir, filepath.Dir(dir+"/"+path))
if err != nil {
return err
}

files = append(files, File{
DirectoryPath: filepath.ToSlash(directoryPath),
FileName: strings.ReplaceAll(d.Name(), ".hyb", ""),
FileExtension: ext,
})
}

return nil
})
if err != nil {
return files, err
}

return files, nil
}
79 changes: 0 additions & 79 deletions core/helpers.go

This file was deleted.

6 changes: 3 additions & 3 deletions core/hybroid.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,21 +22,21 @@ type HybroidConfig struct {
//Packages []PackageConfig `toml:"packages"`
}

type FileInformation struct {
type File struct {
DirectoryPath string // The directory the file is located at (relative)
FileName string // The name of the file (without an extension)
FileExtension string // The extension of the file
}

func (fi *FileInformation) Path() string {
func (fi *File) Path() string {
if fi.DirectoryPath == "." {
return fmt.Sprintf("%s%s", fi.FileName, fi.FileExtension)
}

return fmt.Sprintf("%s/%s%s", fi.DirectoryPath, fi.FileName, fi.FileExtension)
}

func (fi *FileInformation) NewPath(start string, end string) string {
func (fi *File) NewPath(start string, end string) string {
if fi.DirectoryPath == "." {
return fmt.Sprintf("%s/%s%s", start, fi.FileName, end)
}
Expand Down
13 changes: 13 additions & 0 deletions core/logging.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package core

import (
"log"
)

var IsDebug bool

func DebugLog(format string, v ...any) {
if IsDebug {
log.Printf(format, v...)
}
}
Loading