diff --git a/.version b/.version index 5158f20d0..a27b075aa 100644 --- a/.version +++ b/.version @@ -1 +1 @@ -0.2.808 \ No newline at end of file +0.2.810 \ No newline at end of file diff --git a/benchmarks/templ/template_templ.go b/benchmarks/templ/template_templ.go index eb129170d..6fb43e211 100644 --- a/benchmarks/templ/template_templ.go +++ b/benchmarks/templ/template_templ.go @@ -28,7 +28,7 @@ func Render(p Person) templ.Component { templ_7745c5c3_Var1 = templ.NopComponent } ctx = templ.ClearChildren(ctx) - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("

") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 1, "

") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } @@ -41,7 +41,7 @@ func Render(p Person) templ.Component { if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("




") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 11, ">
") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } diff --git a/cmd/templ/generatecmd/cmd.go b/cmd/templ/generatecmd/cmd.go index 3f1707481..77afe19b9 100644 --- a/cmd/templ/generatecmd/cmd.go +++ b/cmd/templ/generatecmd/cmd.go @@ -7,6 +7,7 @@ import ( "log/slog" "net/http" "net/url" + "os" "path" "path/filepath" "regexp" @@ -54,6 +55,7 @@ type Generate struct { type GenerationEvent struct { Event fsnotify.Event + Updated bool GoUpdated bool TextUpdated bool } @@ -114,7 +116,7 @@ func (cmd Generate) Run(ctx context.Context) (err error) { // If we're processing a single file, don't bother setting up the channels/multithreaing. if cmd.Args.FileName != "" { - _, _, err = fseh.HandleEvent(ctx, fsnotify.Event{ + _, err = fseh.HandleEvent(ctx, fsnotify.Event{ Name: cmd.Args.FileName, Op: fsnotify.Create, }) @@ -219,15 +221,16 @@ func (cmd Generate) Run(ctx context.Context) (err error) { cmd.Log.Debug("Processing file", slog.String("file", event.Name)) defer eventsWG.Done() defer func() { <-sem }() - goUpdated, textUpdated, err := fseh.HandleEvent(ctx, event) + r, err := fseh.HandleEvent(ctx, event) if err != nil { errs <- err } - if goUpdated || textUpdated { + if r.GoUpdated || r.TextUpdated { postGeneration <- &GenerationEvent{ Event: event, - GoUpdated: goUpdated, - TextUpdated: textUpdated, + Updated: r.Updated, + GoUpdated: r.GoUpdated, + TextUpdated: r.TextUpdated, } } }(event) @@ -273,6 +276,9 @@ func (cmd Generate) Run(ctx context.Context) (err error) { postGenerationEventsWG.Add(1) if cmd.Args.Command != "" && goUpdated { cmd.Log.Debug("Executing command", slog.String("command", cmd.Args.Command)) + if cmd.Args.Watch { + os.Setenv("TEMPL_DEV_MODE", "true") + } if _, err := run.Run(ctx, cmd.Args.Path, cmd.Args.Command); err != nil { cmd.Log.Error("Error executing command", slog.Any("error", err)) } diff --git a/cmd/templ/generatecmd/eventhandler.go b/cmd/templ/generatecmd/eventhandler.go index 841670a09..82224eb43 100644 --- a/cmd/templ/generatecmd/eventhandler.go +++ b/cmd/templ/generatecmd/eventhandler.go @@ -57,18 +57,17 @@ func NewFSEventHandler( fileNameToLastModTimeMutex: &sync.Mutex{}, fileNameToError: make(map[string]struct{}), fileNameToErrorMutex: &sync.Mutex{}, + fileNameToOutput: make(map[string]generator.GeneratorOutput), + fileNameToOutputMutex: &sync.Mutex{}, + devMode: devMode, hashes: make(map[string][sha256.Size]byte), hashesMutex: &sync.Mutex{}, genOpts: genOpts, genSourceMapVis: genSourceMapVis, - DevMode: devMode, keepOrphanedFiles: keepOrphanedFiles, writer: fileWriter, lazy: lazy, } - if devMode { - fseh.genOpts = append(fseh.genOpts, generator.WithExtractStrings()) - } return fseh } @@ -80,71 +79,84 @@ type FSEventHandler struct { fileNameToLastModTimeMutex *sync.Mutex fileNameToError map[string]struct{} fileNameToErrorMutex *sync.Mutex + fileNameToOutput map[string]generator.GeneratorOutput + fileNameToOutputMutex *sync.Mutex + devMode bool hashes map[string][sha256.Size]byte hashesMutex *sync.Mutex genOpts []generator.GenerateOpt genSourceMapVis bool - DevMode bool Errors []error keepOrphanedFiles bool writer func(string, []byte) error lazy bool } -func (h *FSEventHandler) HandleEvent(ctx context.Context, event fsnotify.Event) (goUpdated, textUpdated bool, err error) { +type GenerateResult struct { + // Updated indicates that the file was updated. + Updated bool + // GoUpdated indicates that Go expressions were updated. + GoUpdated bool + // TextUpdated indicates that text literals were updated. + TextUpdated bool +} + +func (h *FSEventHandler) HandleEvent(ctx context.Context, event fsnotify.Event) (result GenerateResult, err error) { // Handle _templ.go files. if !event.Has(fsnotify.Remove) && strings.HasSuffix(event.Name, "_templ.go") { _, err = os.Stat(strings.TrimSuffix(event.Name, "_templ.go") + ".templ") if !os.IsNotExist(err) { - return false, false, err + return GenerateResult{}, err } // File is orphaned. if h.keepOrphanedFiles { - return false, false, nil + return GenerateResult{}, nil } h.Log.Debug("Deleting orphaned Go file", slog.String("file", event.Name)) if err = os.Remove(event.Name); err != nil { h.Log.Warn("Failed to remove orphaned file", slog.Any("error", err)) } - return true, false, nil + return GenerateResult{Updated: true, GoUpdated: true, TextUpdated: false}, nil } // Handle _templ.txt files. if !event.Has(fsnotify.Remove) && strings.HasSuffix(event.Name, "_templ.txt") { - if h.DevMode { - // Don't delete the file if we're in dev mode, but mark that text was updated. - return false, true, nil + if h.devMode { + // Don't delete the file in dev mode, ignore changes to it, since the .templ file + // must have been updated in order to trigger a change in the _templ.txt file. + return GenerateResult{Updated: false, GoUpdated: false, TextUpdated: false}, nil } h.Log.Debug("Deleting watch mode file", slog.String("file", event.Name)) if err = os.Remove(event.Name); err != nil { h.Log.Warn("Failed to remove watch mode text file", slog.Any("error", err)) - return false, false, nil + return GenerateResult{}, nil } - return false, false, nil + return GenerateResult{}, nil } // Handle .templ files. if !strings.HasSuffix(event.Name, ".templ") { - return false, false, nil + return GenerateResult{}, nil } // If the file hasn't been updated since the last time we processed it, ignore it. lastModTime, updatedModTime := h.UpsertLastModTime(event.Name) if !updatedModTime { h.Log.Debug("Skipping file because it wasn't updated", slog.String("file", event.Name)) - return false, false, nil + return GenerateResult{}, nil } // If the go file is newer than the templ file, skip generation, because it's up-to-date. if h.lazy && goFileIsUpToDate(event.Name, lastModTime) { h.Log.Debug("Skipping file because the Go file is up-to-date", slog.String("file", event.Name)) - return false, false, nil + return GenerateResult{}, nil } // Start a processor. start := time.Now() - goUpdated, textUpdated, diag, err := h.generate(ctx, event.Name) + var diag []parser.Diagnostic + result, diag, err = h.generate(ctx, event.Name) if err != nil { h.SetError(event.Name, true) - return goUpdated, textUpdated, fmt.Errorf("failed to generate code for %q: %w", event.Name, err) + return result, fmt.Errorf("failed to generate code for %q: %w", event.Name, err) } if len(diag) > 0 { for _, d := range diag { @@ -153,14 +165,14 @@ func (h *FSEventHandler) HandleEvent(ctx context.Context, event fsnotify.Event) slog.String("to", fmt.Sprintf("%d:%d", d.Range.To.Line, d.Range.To.Col)), ) } - return + return result, nil } if errorCleared, errorCount := h.SetError(event.Name, false); errorCleared { h.Log.Info("Error cleared", slog.String("file", event.Name), slog.Int("errors", errorCount)) } h.Log.Debug("Generated code", slog.String("file", event.Name), slog.Duration("in", time.Since(start))) - return goUpdated, textUpdated, nil + return result, nil } func goFileIsUpToDate(templFileName string, templFileLastMod time.Time) (upToDate bool) { @@ -212,68 +224,78 @@ func (h *FSEventHandler) UpsertHash(fileName string, hash [sha256.Size]byte) (up // generate Go code for a single template. // If a basePath is provided, the filename included in error messages is relative to it. -func (h *FSEventHandler) generate(ctx context.Context, fileName string) (goUpdated, textUpdated bool, diagnostics []parser.Diagnostic, err error) { +func (h *FSEventHandler) generate(ctx context.Context, fileName string) (result GenerateResult, diagnostics []parser.Diagnostic, err error) { t, err := parser.Parse(fileName) if err != nil { - return false, false, nil, fmt.Errorf("%s parsing error: %w", fileName, err) + return GenerateResult{}, nil, fmt.Errorf("%s parsing error: %w", fileName, err) } targetFileName := strings.TrimSuffix(fileName, ".templ") + "_templ.go" // Only use relative filenames to the basepath for filenames in runtime error messages. absFilePath, err := filepath.Abs(fileName) if err != nil { - return false, false, nil, fmt.Errorf("failed to get absolute path for %q: %w", fileName, err) + return GenerateResult{}, nil, fmt.Errorf("failed to get absolute path for %q: %w", fileName, err) } relFilePath, err := filepath.Rel(h.dir, absFilePath) if err != nil { - return false, false, nil, fmt.Errorf("failed to get relative path for %q: %w", fileName, err) + return GenerateResult{}, nil, fmt.Errorf("failed to get relative path for %q: %w", fileName, err) } // Convert Windows file paths to Unix-style for consistency. relFilePath = filepath.ToSlash(relFilePath) var b bytes.Buffer - sourceMap, literals, err := generator.Generate(t, &b, append(h.genOpts, generator.WithFileName(relFilePath))...) + generatorOutput, err := generator.Generate(t, &b, append(h.genOpts, generator.WithFileName(relFilePath))...) if err != nil { - return false, false, nil, fmt.Errorf("%s generation error: %w", fileName, err) + return GenerateResult{}, nil, fmt.Errorf("%s generation error: %w", fileName, err) } formattedGoCode, err := format.Source(b.Bytes()) if err != nil { - err = remapErrorList(err, sourceMap, fileName) - return false, false, nil, fmt.Errorf("% source formatting error %w", fileName, err) + err = remapErrorList(err, generatorOutput.SourceMap, fileName) + return GenerateResult{}, nil, fmt.Errorf("%s source formatting error %w", fileName, err) } // Hash output, and write out the file if the goCodeHash has changed. goCodeHash := sha256.Sum256(formattedGoCode) if h.UpsertHash(targetFileName, goCodeHash) { - goUpdated = true + result.Updated = true if err = h.writer(targetFileName, formattedGoCode); err != nil { - return false, false, nil, fmt.Errorf("failed to write target file %q: %w", targetFileName, err) + return result, nil, fmt.Errorf("failed to write target file %q: %w", targetFileName, err) } } // Add the txt file if it has changed. - if len(literals) > 0 { + if h.devMode { txtFileName := strings.TrimSuffix(fileName, ".templ") + "_templ.txt" - txtHash := sha256.Sum256([]byte(literals)) + joined := strings.Join(generatorOutput.Literals, "\n") + txtHash := sha256.Sum256([]byte(joined)) if h.UpsertHash(txtFileName, txtHash) { - textUpdated = true - if err = os.WriteFile(txtFileName, []byte(literals), 0o644); err != nil { - return false, false, nil, fmt.Errorf("failed to write string literal file %q: %w", txtFileName, err) + result.TextUpdated = true + if err = os.WriteFile(txtFileName, []byte(joined), 0o644); err != nil { + return result, nil, fmt.Errorf("failed to write string literal file %q: %w", txtFileName, err) + } + + // Check whether the change would require a recompilation to take effect. + h.fileNameToOutputMutex.Lock() + defer h.fileNameToOutputMutex.Unlock() + previous := h.fileNameToOutput[fileName] + if generator.HasChanged(previous, generatorOutput) { + result.GoUpdated = true } + h.fileNameToOutput[fileName] = generatorOutput } } parsedDiagnostics, err := parser.Diagnose(t) if err != nil { - return goUpdated, textUpdated, nil, fmt.Errorf("%s diagnostics error: %w", fileName, err) + return result, nil, fmt.Errorf("%s diagnostics error: %w", fileName, err) } if h.genSourceMapVis { - err = generateSourceMapVisualisation(ctx, fileName, targetFileName, sourceMap) + err = generateSourceMapVisualisation(ctx, fileName, targetFileName, generatorOutput.SourceMap) } - return goUpdated, textUpdated, parsedDiagnostics, err + return result, parsedDiagnostics, err } // Takes an error from the formatter and attempts to convert the positions reported in the target file to their positions diff --git a/cmd/templ/generatecmd/run/run_unix.go b/cmd/templ/generatecmd/run/run_unix.go index 68f8d6724..f2f4bfbce 100644 --- a/cmd/templ/generatecmd/run/run_unix.go +++ b/cmd/templ/generatecmd/run/run_unix.go @@ -52,7 +52,7 @@ func ignoreExited(err error) error { return err } -func Run(ctx context.Context, workingDir, input string) (cmd *exec.Cmd, err error) { +func Run(ctx context.Context, workingDir string, input string) (cmd *exec.Cmd, err error) { m.Lock() defer m.Unlock() cmd, ok := running[input] diff --git a/cmd/templ/generatecmd/run/run_windows.go b/cmd/templ/generatecmd/run/run_windows.go index f96a06c70..0a79032b1 100644 --- a/cmd/templ/generatecmd/run/run_windows.go +++ b/cmd/templ/generatecmd/run/run_windows.go @@ -37,7 +37,7 @@ func Stop(cmd *exec.Cmd) (err error) { return kill.Run() } -func Run(ctx context.Context, workingDir, input string) (cmd *exec.Cmd, err error) { +func Run(ctx context.Context, workingDir string, input string) (cmd *exec.Cmd, err error) { m.Lock() defer m.Unlock() cmd, ok := running[input] diff --git a/cmd/templ/generatecmd/test-eventhandler/eventhandler_test.go b/cmd/templ/generatecmd/test-eventhandler/eventhandler_test.go index 5e3e2d335..8c1319921 100644 --- a/cmd/templ/generatecmd/test-eventhandler/eventhandler_test.go +++ b/cmd/templ/generatecmd/test-eventhandler/eventhandler_test.go @@ -63,7 +63,7 @@ func TestErrorLocationMapping(t *testing.T) { } event := fsnotify.Event{Name: file.Name(), Op: fsnotify.Write} - _, _, err = fseh.HandleEvent(context.Background(), event) + _, err = fseh.HandleEvent(context.Background(), event) if err == nil { t.Errorf("%s: no error was thrown", test.name) break diff --git a/cmd/templ/generatecmd/testwatch/generate_test.go b/cmd/templ/generatecmd/testwatch/generate_test.go index b97437767..70f4bd550 100644 --- a/cmd/templ/generatecmd/testwatch/generate_test.go +++ b/cmd/templ/generatecmd/testwatch/generate_test.go @@ -394,12 +394,12 @@ func Setup(gzipEncoding bool) (args TestArgs, teardown func(t *testing.T), err e if err = waitForURL(args.AppURL); err != nil { cancel() wg.Wait() - return args, teardown, fmt.Errorf("failed to start app server: %v", err) + return args, teardown, fmt.Errorf("failed to start app server, command error %v: %w", cmdErr, err) } if err = waitForURL(args.ProxyURL); err != nil { cancel() wg.Wait() - return args, teardown, fmt.Errorf("failed to start proxy server: %v", err) + return args, teardown, fmt.Errorf("failed to start proxy server, command error %v: %w", cmdErr, err) } // Wait for exit. diff --git a/cmd/templ/generatecmd/testwatch/testdata/main.go b/cmd/templ/generatecmd/testwatch/testdata/main.go index 8b4d150bf..8ffd85d71 100644 --- a/cmd/templ/generatecmd/testwatch/testdata/main.go +++ b/cmd/templ/generatecmd/testwatch/testdata/main.go @@ -5,6 +5,7 @@ import ( "compress/gzip" "flag" "fmt" + "log/slog" "net/http" "os" "strconv" @@ -63,7 +64,14 @@ func main() { count++ c := Page(count) - templ.Handler(c).ServeHTTP(w, r) + h := templ.Handler(c) + h.ErrorHandler = func(r *http.Request, err error) http.Handler { + slog.Error("failed to render template", slog.Any("error", err)) + return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + http.Error(w, err.Error(), http.StatusInternalServerError) + }) + } + h.ServeHTTP(w, r) }) err := http.ListenAndServe(fmt.Sprintf("localhost:%d", *flagPort), nil) if err != nil { diff --git a/cmd/templ/generatecmd/testwatch/testdata/templates_templ.go b/cmd/templ/generatecmd/testwatch/testdata/templates_templ.go index 938618f6f..508897f35 100644 --- a/cmd/templ/generatecmd/testwatch/testdata/templates_templ.go +++ b/cmd/templ/generatecmd/testwatch/testdata/templates_templ.go @@ -30,7 +30,7 @@ func Page(count int) templ.Component { templ_7745c5c3_Var1 = templ.NopComponent } ctx = templ.ClearChildren(ctx) - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("templ test page

Count

") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 1, "templ test page

Count

") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } @@ -43,7 +43,7 @@ func Page(count int) templ.Component { if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("
Original
") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 2, "
Original
") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } diff --git a/cmd/templ/imports/process.go b/cmd/templ/imports/process.go index d3ccbe770..7ceb57863 100644 --- a/cmd/templ/imports/process.go +++ b/cmd/templ/imports/process.go @@ -79,7 +79,7 @@ func Process(t parser.TemplateFile) (parser.TemplateFile, error) { var updatedImports []*ast.ImportSpec var eg errgroup.Group eg.Go(func() (err error) { - if _, _, err := generator.Generate(t, gw); err != nil { + if _, err := generator.Generate(t, gw); err != nil { return fmt.Errorf("failed to generate go code: %w", err) } updatedImports, err = updateImports(fileName, gw.String()) diff --git a/cmd/templ/lspcmd/httpdebug/list_templ.go b/cmd/templ/lspcmd/httpdebug/list_templ.go index 49b64413c..5ee3ede5f 100644 --- a/cmd/templ/lspcmd/httpdebug/list_templ.go +++ b/cmd/templ/lspcmd/httpdebug/list_templ.go @@ -28,12 +28,12 @@ func list(uris []string) templ.Component { templ_7745c5c3_Var1 = templ.NopComponent } ctx = templ.ClearChildren(ctx) - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 1, "
File
") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } for _, uri := range uris { - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 7, "\">Go") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } } - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("
File
") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 2, "
") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } @@ -46,7 +46,7 @@ func list(uris []string) templ.Component { if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("MappingMappingSource MapSource MapTemplTemplGo
") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 8, "") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } diff --git a/cmd/templ/lspcmd/proxy/server.go b/cmd/templ/lspcmd/proxy/server.go index 6599e17ce..d7a1d36bf 100644 --- a/cmd/templ/lspcmd/proxy/server.go +++ b/cmd/templ/lspcmd/proxy/server.go @@ -111,16 +111,19 @@ func (p *Server) convertGoRangeToTemplRange(templURI lsp.DocumentURI, input lsp. return } // Map from the source position to target Go position. - start, ok := sourceMap.SourcePositionFromTarget(input.Start.Line, input.Start.Character) - if ok { + start, startPositionMapped := sourceMap.SourcePositionFromTarget(input.Start.Line, input.Start.Character) + if startPositionMapped { output.Start.Line = start.Line output.Start.Character = start.Col } - end, ok := sourceMap.SourcePositionFromTarget(input.End.Line, input.End.Character) - if ok { + end, endPositionMapped := sourceMap.SourcePositionFromTarget(input.End.Line, input.End.Character) + if endPositionMapped { output.End.Line = end.Line output.End.Character = end.Col } + if !startPositionMapped || !endPositionMapped { + p.Log.Warn("go->templ: range not found in sourcemap", zap.Any("range", input)) + } return } @@ -265,12 +268,12 @@ func (p *Server) Initialize(ctx context.Context, params *lsp.InitializeParams) ( return nil } w := new(strings.Builder) - sm, _, err := generator.Generate(template, w) + generatorOutput, err := generator.Generate(template, w) if err != nil { return fmt.Errorf("generate failure: %w", err) } p.Log.Info("setting source map cache contents", zap.String("uri", string(uri))) - p.SourceMapCache.Set(string(uri), sm) + p.SourceMapCache.Set(string(uri), generatorOutput.SourceMap) // Set the Go contents. p.GoSource[string(uri)] = w.String() @@ -667,14 +670,14 @@ func (p *Server) DidChange(ctx context.Context, params *lsp.DidChangeTextDocumen // // This change would increase the surface area of gopls that we use, so may surface a number of issues // if enabled. - sm, _, err := generator.Generate(template, w) + generatorOutput, err := generator.Generate(template, w) if err != nil { p.Log.Error("generate failure", zap.Error(err)) return } // Cache the sourcemap. p.Log.Info("setting cache", zap.String("uri", string(params.TextDocument.URI))) - p.SourceMapCache.Set(string(params.TextDocument.URI), sm) + p.SourceMapCache.Set(string(params.TextDocument.URI), generatorOutput.SourceMap) p.GoSource[string(params.TextDocument.URI)] = w.String() // Change the path. params.TextDocument.URI = goURI @@ -740,12 +743,12 @@ func (p *Server) DidOpen(ctx context.Context, params *lsp.DidOpenTextDocumentPar // Generate the output code and cache the source map and Go contents to use during completion // requests. w := new(strings.Builder) - sm, _, err := generator.Generate(template, w) + generatorOutput, err := generator.Generate(template, w) if err != nil { return } p.Log.Info("setting source map cache contents", zap.String("uri", string(params.TextDocument.URI))) - p.SourceMapCache.Set(string(params.TextDocument.URI), sm) + p.SourceMapCache.Set(string(params.TextDocument.URI), generatorOutput.SourceMap) // Set the Go contents. params.TextDocument.Text = w.String() p.GoSource[string(params.TextDocument.URI)] = params.TextDocument.Text @@ -837,16 +840,6 @@ func (p *Server) DocumentSymbol(ctx context.Context, params *lsp.DocumentSymbolP return nil, err } - // recursively convert the ranges of the symbols and their children - var convertRange func(s *lsp.DocumentSymbol) - convertRange = func(s *lsp.DocumentSymbol) { - s.Range = p.convertGoRangeToTemplRange(templURI, s.Range) - s.SelectionRange = p.convertGoRangeToTemplRange(templURI, s.SelectionRange) - for i := 0; i < len(s.Children); i++ { - convertRange(&s.Children[i]) - } - } - for _, s := range symbols { if m, ok := s.(map[string]interface{}); ok { s, err = mapToSymbol(m) @@ -856,7 +849,7 @@ func (p *Server) DocumentSymbol(ctx context.Context, params *lsp.DocumentSymbolP } switch s := s.(type) { case lsp.DocumentSymbol: - convertRange(&s) + p.convertSymbolRange(templURI, &s) result = append(result, s) case lsp.SymbolInformation: s.Location.URI = templURI @@ -868,6 +861,54 @@ func (p *Server) DocumentSymbol(ctx context.Context, params *lsp.DocumentSymbolP return result, err } +func (p *Server) convertSymbolRange(templURI lsp.DocumentURI, s *lsp.DocumentSymbol) { + sourceMap, ok := p.SourceMapCache.Get(string(templURI)) + if !ok { + p.Log.Warn("go->templ: sourcemap not found in cache") + return + } + src, ok := sourceMap.SymbolSourceRangeFromTarget(s.Range.Start.Line, s.Range.Start.Character) + if !ok { + p.Log.Warn("go->templ: symbol range not found", zap.Any("symbol", s), zap.Any("choices", sourceMap.TargetSymbolRangeToSource)) + return + } + s.Range = lsp.Range{ + Start: lsp.Position{ + Line: uint32(src.From.Line), + Character: uint32(src.From.Col), + }, + End: lsp.Position{ + Line: uint32(src.To.Line), + Character: uint32(src.To.Col), + }, + } + // Within the symbol, we can select sub-sections. + // These are Go expressions, in the standard source map. + s.SelectionRange = p.convertGoRangeToTemplRange(templURI, s.SelectionRange) + for i := 0; i < len(s.Children); i++ { + p.convertSymbolRange(templURI, &s.Children[i]) + if !isRangeWithin(s.Range, s.Children[i].Range) { + p.Log.Error("child symbol range not within parent range", zap.Any("symbol", s.Children[i]), zap.Int("index", i)) + } + } + if !isRangeWithin(s.Range, s.SelectionRange) { + p.Log.Error("selection range not within range", zap.Any("symbol", s)) + } +} + +func isRangeWithin(parent, child lsp.Range) bool { + if child.Start.Line < parent.Start.Line || child.End.Line > parent.End.Line { + return false + } + if child.Start.Line == parent.Start.Line && child.Start.Character < parent.Start.Character { + return false + } + if child.End.Line == parent.End.Line && child.End.Character > parent.End.Character { + return false + } + return true +} + func (p *Server) ExecuteCommand(ctx context.Context, params *lsp.ExecuteCommandParams) (result interface{}, err error) { p.Log.Info("client -> server: ExecuteCommand") defer p.Log.Info("client -> server: ExecuteCommand end") diff --git a/cmd/templ/testproject/testdata/remotechild_templ.go b/cmd/templ/testproject/testdata/remotechild_templ.go index 2544e0425..26448c999 100644 --- a/cmd/templ/testproject/testdata/remotechild_templ.go +++ b/cmd/templ/testproject/testdata/remotechild_templ.go @@ -28,7 +28,7 @@ func Remote() templ.Component { templ_7745c5c3_Var1 = templ.NopComponent } ctx = templ.ClearChildren(ctx) - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("

This is remote content

") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 1, "

This is remote content

") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } diff --git a/cmd/templ/testproject/testdata/templates_templ.go b/cmd/templ/testproject/testdata/templates_templ.go index 2bffb2427..176ba6055 100644 --- a/cmd/templ/testproject/testdata/templates_templ.go +++ b/cmd/templ/testproject/testdata/templates_templ.go @@ -30,7 +30,7 @@ func Page(count int) templ.Component { templ_7745c5c3_Var1 = templ.NopComponent } ctx = templ.ClearChildren(ctx) - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("templ test page

Count

") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 1, "templ test page

Count

") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } @@ -43,7 +43,7 @@ func Page(count int) templ.Component { if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("
Original
") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 2, "
Original
") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } diff --git a/cmd/templ/visualize/sourcemapvisualisation_templ.go b/cmd/templ/visualize/sourcemapvisualisation_templ.go index 1793a8be8..35b25ebfd 100644 --- a/cmd/templ/visualize/sourcemapvisualisation_templ.go +++ b/cmd/templ/visualize/sourcemapvisualisation_templ.go @@ -60,7 +60,7 @@ func combine(templFileName string, left, right templ.Component) templ.Component templ_7745c5c3_Var1 = templ.NopComponent } ctx = templ.ClearChildren(ctx) - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 1, "<html><head><title>") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } @@ -73,7 +73,7 @@ func combine(templFileName string, left, right templ.Component) templ.Component if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("- Source Map Visualisation

") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 2, "- Source Map Visualisation

") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } @@ -86,7 +86,7 @@ func combine(templFileName string, left, right templ.Component) templ.Component if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("

") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 3, "") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } @@ -95,7 +95,7 @@ func combine(templFileName string, left, right templ.Component) templ.Component if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("
") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 5, "\">") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } @@ -117,7 +117,7 @@ func combine(templFileName string, left, right templ.Component) templ.Component if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("
") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 7, "\">") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } @@ -138,7 +138,7 @@ func combine(templFileName string, left, right templ.Component) templ.Component if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("
") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 8, "
") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } @@ -147,7 +147,7 @@ func combine(templFileName string, left, right templ.Component) templ.Component if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("
") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 10, "\">") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } @@ -168,7 +168,7 @@ func combine(templFileName string, left, right templ.Component) templ.Component if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("
") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 11, "") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } @@ -240,7 +240,7 @@ func mappedCharacter(s string, sourceID, targetID string) templ.Component { if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 15, "\">") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } @@ -284,7 +284,7 @@ func mappedCharacter(s string, sourceID, targetID string) templ.Component { if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 16, "") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } diff --git a/examples/blog/posts_templ.go b/examples/blog/posts_templ.go index 29c560b64..b93352d57 100644 --- a/examples/blog/posts_templ.go +++ b/examples/blog/posts_templ.go @@ -33,7 +33,7 @@ func headerTemplate(name string) templ.Component { templ_7745c5c3_Var1 = templ.NopComponent } ctx = templ.ClearChildren(ctx) - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("

") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 1, "

") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } @@ -46,7 +46,7 @@ func headerTemplate(name string) templ.Component { if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("

") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 2, "

") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } @@ -75,7 +75,7 @@ func footerTemplate() templ.Component { templ_7745c5c3_Var3 = templ.NopComponent } ctx = templ.ClearChildren(ctx) - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } @@ -117,7 +117,7 @@ func navTemplate() templ.Component { templ_7745c5c3_Var5 = templ.NopComponent } ctx = templ.ClearChildren(ctx) - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 5, "") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } @@ -146,7 +146,7 @@ func layout(name string) templ.Component { templ_7745c5c3_Var6 = templ.NopComponent } ctx = templ.ClearChildren(ctx) - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 6, "<html><head><title>") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } @@ -159,7 +159,7 @@ func layout(name string) templ.Component { if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 7, "") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } @@ -171,7 +171,7 @@ func layout(name string) templ.Component { if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("
") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 8, "
") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } @@ -179,7 +179,7 @@ func layout(name string) templ.Component { if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("
") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 9, "
") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } @@ -187,7 +187,7 @@ func layout(name string) templ.Component { if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 10, "") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } @@ -216,12 +216,12 @@ func postsTemplate(posts []Post) templ.Component { templ_7745c5c3_Var8 = templ.NopComponent } ctx = templ.ClearChildren(ctx) - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("
") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 11, "
") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } for _, p := range posts { - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("
") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 12, "
") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } @@ -234,7 +234,7 @@ func postsTemplate(posts []Post) templ.Component { if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("
") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 13, "
") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } @@ -247,12 +247,12 @@ func postsTemplate(posts []Post) templ.Component { if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("
") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 14, "
") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } } - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("
") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 15, "
") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } @@ -293,7 +293,7 @@ func home() templ.Component { }() } ctx = templ.InitializeContext(ctx) - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("
Welcome to my website.
") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 16, "
Welcome to my website.
") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } diff --git a/examples/counter-basic/components_templ.go b/examples/counter-basic/components_templ.go index 38234dcb1..2a961d7f4 100644 --- a/examples/counter-basic/components_templ.go +++ b/examples/counter-basic/components_templ.go @@ -30,7 +30,7 @@ func counts(global, user int) templ.Component { templ_7745c5c3_Var1 = templ.NopComponent } ctx = templ.ClearChildren(ctx) - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("
Global: ") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 1, "
Global: ") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } @@ -43,7 +43,7 @@ func counts(global, user int) templ.Component { if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("
User: ") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 2, "
User: ") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } @@ -56,7 +56,7 @@ func counts(global, user int) templ.Component { if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("
") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 3, "
") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } @@ -85,7 +85,7 @@ func form() templ.Component { templ_7745c5c3_Var4 = templ.NopComponent } ctx = templ.ClearChildren(ctx) - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("
") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 4, "
") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } @@ -114,7 +114,7 @@ func page(global, user int) templ.Component { templ_7745c5c3_Var5 = templ.NopComponent } ctx = templ.ClearChildren(ctx) - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("Counts

Counts

") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 5, "Counts

Counts

") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } @@ -126,7 +126,7 @@ func page(global, user int) templ.Component { if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("
") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 6, "
") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } diff --git a/examples/counter/components/components_templ.go b/examples/counter/components/components_templ.go index e2f134159..e1c3d6c65 100644 --- a/examples/counter/components/components_templ.go +++ b/examples/counter/components/components_templ.go @@ -44,7 +44,7 @@ func counts(global, session int) templ.Component { templ_7745c5c3_Var1 = templ.NopComponent } ctx = templ.ClearChildren(ctx) - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("
") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 1, "
") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } @@ -53,7 +53,7 @@ func counts(global, session int) templ.Component { if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("

") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 3, "\">

") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } @@ -79,7 +79,7 @@ func counts(global, session int) templ.Component { if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("

Global

") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 4, "

Global

") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } @@ -88,7 +88,7 @@ func counts(global, session int) templ.Component { if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("

") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 6, "\">

") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } @@ -114,7 +114,7 @@ func counts(global, session int) templ.Component { if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("

Session

") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 7, "

Session

") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } @@ -143,7 +143,7 @@ func Page(global, session int) templ.Component { templ_7745c5c3_Var8 = templ.NopComponent } ctx = templ.ClearChildren(ctx) - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("Counts

Counts

") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 8, "Counts

Counts

") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } @@ -151,7 +151,7 @@ func Page(global, session int) templ.Component { if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("
") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 9, "
") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } diff --git a/examples/counter/go.mod b/examples/counter/go.mod index a143c45e5..a371da342 100644 --- a/examples/counter/go.mod +++ b/examples/counter/go.mod @@ -44,9 +44,10 @@ require ( github.com/mattn/go-isatty v0.0.20 // indirect github.com/yuin/goldmark v1.7.4 // indirect golang.org/x/lint v0.0.0-20210508222113-6edffad5e616 // indirect - golang.org/x/mod v0.18.0 // indirect - golang.org/x/sys v0.21.0 // indirect - golang.org/x/tools v0.22.0 // indirect + golang.org/x/mod v0.20.0 // indirect + golang.org/x/sync v0.8.0 // indirect + golang.org/x/sys v0.23.0 // indirect + golang.org/x/tools v0.24.0 // indirect ) replace github.com/a-h/templ => ../../ diff --git a/examples/counter/go.sum b/examples/counter/go.sum index feac4512b..3e574d8f4 100644 --- a/examples/counter/go.sum +++ b/examples/counter/go.sum @@ -84,23 +84,23 @@ golang.org/x/exp v0.0.0-20240613232115-7f521ea00fb8/go.mod h1:jj3sYF3dwk5D+ghuXy golang.org/x/lint v0.0.0-20210508222113-6edffad5e616 h1:VLliZ0d+/avPrXXH+OakdXhpJuEoBZuwh1m2j7U6Iug= golang.org/x/lint v0.0.0-20210508222113-6edffad5e616/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= -golang.org/x/mod v0.18.0 h1:5+9lSbEzPSdWkH32vYPBwEpX8KwDbM52Ud9xBUvNlb0= -golang.org/x/mod v0.18.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= +golang.org/x/mod v0.20.0 h1:utOm6MM3R3dnawAiJgn0y+xvuYRsm1RKM/4giyfDgV0= +golang.org/x/mod v0.20.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M= -golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sync v0.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ= +golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.21.0 h1:rF+pYz3DAGSQAxAu1CbC7catZg4ebC4UIeIhKxBZvws= -golang.org/x/sys v0.21.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.23.0 h1:YfKFowiIMvtgl1UERQoTPPToxltDeZfbj4H7dVUCwmM= +golang.org/x/sys v0.23.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.22.0 h1:gqSGLZqv+AI9lIQzniJ0nZDRG5GBPsSi+DRNHWNz6yA= -golang.org/x/tools v0.22.0/go.mod h1:aCwcsjqvq7Yqt6TNyX7QMU2enbQ/Gt0bo6krSeEri+c= +golang.org/x/tools v0.24.0 h1:J1shsA93PJUEVaUSaay7UXAyE8aimq3GW0pjlolpa24= +golang.org/x/tools v0.24.0/go.mod h1:YhNqVBIfWHdzvTLs0d8LCuMhkKUgSUKldakyV7W/WDQ= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/yaml.v2 v2.2.8 h1:obN1ZagJSUGI0Ek/LBmuj4SNLPfIny3KsKFopxRdj10= diff --git a/examples/counter/lambda/main.go b/examples/counter/lambda/main.go index 861f5a37b..91cdc16d3 100644 --- a/examples/counter/lambda/main.go +++ b/examples/counter/lambda/main.go @@ -13,7 +13,7 @@ import ( func main() { // Create handlers. - log := slog.New(slog.NewJSONHandler(os.Stderr)) + log := slog.New(slog.NewJSONHandler(os.Stderr, nil)) s, err := db.NewCountStore(os.Getenv("TABLE_NAME"), os.Getenv("AWS_REGION")) if err != nil { log.Error("failed to create store", slog.Any("error", err)) diff --git a/examples/external-libraries/components_templ.go b/examples/external-libraries/components_templ.go index c2d9108f1..a5597cd66 100644 --- a/examples/external-libraries/components_templ.go +++ b/examples/external-libraries/components_templ.go @@ -40,7 +40,7 @@ func page(data []TimeValue) templ.Component { templ_7745c5c3_Var1 = templ.NopComponent } ctx = templ.ClearChildren(ctx) - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("Graphs") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 1, "Graphs") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } @@ -48,7 +48,7 @@ func page(data []TimeValue) templ.Component { if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 3, "\">") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } diff --git a/examples/hello-world-ssr/hello_templ.go b/examples/hello-world-ssr/hello_templ.go index e35e08da8..aee8689a4 100644 --- a/examples/hello-world-ssr/hello_templ.go +++ b/examples/hello-world-ssr/hello_templ.go @@ -28,7 +28,7 @@ func hello(name string) templ.Component { templ_7745c5c3_Var1 = templ.NopComponent } ctx = templ.ClearChildren(ctx) - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("
Hello, ") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 1, "
Hello, ") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } @@ -41,7 +41,7 @@ func hello(name string) templ.Component { if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("
") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 2, "
") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } diff --git a/examples/hello-world-static/hello_templ.go b/examples/hello-world-static/hello_templ.go index c3816cb5c..a42dfa6e7 100644 --- a/examples/hello-world-static/hello_templ.go +++ b/examples/hello-world-static/hello_templ.go @@ -28,7 +28,7 @@ func hello(name string) templ.Component { templ_7745c5c3_Var1 = templ.NopComponent } ctx = templ.ClearChildren(ctx) - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("
Hello, ") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 1, "
Hello, ") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } @@ -41,7 +41,7 @@ func hello(name string) templ.Component { if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("
") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 2, "
") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } diff --git a/examples/integration-chi/home_templ.go b/examples/integration-chi/home_templ.go index dff7eefe8..91f6e428d 100644 --- a/examples/integration-chi/home_templ.go +++ b/examples/integration-chi/home_templ.go @@ -28,7 +28,7 @@ func Home() templ.Component { templ_7745c5c3_Var1 = templ.NopComponent } ctx = templ.ClearChildren(ctx) - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("
Hello World
") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 1, "
Hello World
") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } diff --git a/examples/integration-echo/home_templ.go b/examples/integration-echo/home_templ.go index dff7eefe8..91f6e428d 100644 --- a/examples/integration-echo/home_templ.go +++ b/examples/integration-echo/home_templ.go @@ -28,7 +28,7 @@ func Home() templ.Component { templ_7745c5c3_Var1 = templ.NopComponent } ctx = templ.ClearChildren(ctx) - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("
Hello World
") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 1, "
Hello World
") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } diff --git a/examples/integration-gin/home_templ.go b/examples/integration-gin/home_templ.go index 13985a671..de404802b 100644 --- a/examples/integration-gin/home_templ.go +++ b/examples/integration-gin/home_templ.go @@ -28,7 +28,7 @@ func Home() templ.Component { templ_7745c5c3_Var1 = templ.NopComponent } ctx = templ.ClearChildren(ctx) - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("
Hello world
") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 1, "
Hello world
") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } diff --git a/examples/integration-go-echarts/components_templ.go b/examples/integration-go-echarts/components_templ.go index 859a9cacf..391c6acba 100644 --- a/examples/integration-go-echarts/components_templ.go +++ b/examples/integration-go-echarts/components_templ.go @@ -30,7 +30,7 @@ func Home(chart *charts.Bar) templ.Component { templ_7745c5c3_Var1 = templ.NopComponent } ctx = templ.ClearChildren(ctx) - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("Bar chart") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 1, "Bar chart") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } @@ -38,7 +38,7 @@ func Home(chart *charts.Bar) templ.Component { if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 2, "") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } diff --git a/examples/integration-gofiber/home_templ.go b/examples/integration-gofiber/home_templ.go index 3bc5794a1..88b1bde8b 100644 --- a/examples/integration-gofiber/home_templ.go +++ b/examples/integration-gofiber/home_templ.go @@ -37,7 +37,7 @@ func Home(name string) templ.Component { templ_7745c5c3_Var1 = templ.NopComponent } ctx = templ.ClearChildren(ctx) - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("
Hello ") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 1, "
Hello ") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } @@ -50,7 +50,7 @@ func Home(name string) templ.Component { if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("
Hello ") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 2, "
Hello ") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } @@ -63,7 +63,7 @@ func Home(name string) templ.Component { if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(" (from context)
") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 3, " (from context)
") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } @@ -92,7 +92,7 @@ func NotFound() templ.Component { templ_7745c5c3_Var4 = templ.NopComponent } ctx = templ.ClearChildren(ctx) - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("
404
") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 4, "
404
") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } diff --git a/examples/integration-react/components_templ.go b/examples/integration-react/components_templ.go index 52276999c..ee38da50f 100644 --- a/examples/integration-react/components_templ.go +++ b/examples/integration-react/components_templ.go @@ -28,7 +28,7 @@ func Hello(name string) templ.Component { templ_7745c5c3_Var1 = templ.NopComponent } ctx = templ.ClearChildren(ctx) - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("
") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 2, "\">") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } @@ -70,7 +70,7 @@ func page() templ.Component { templ_7745c5c3_Var3 = templ.NopComponent } ctx = templ.ClearChildren(ctx) - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("React integration
This is server-side content from templ.
") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 3, "React integration
This is server-side content from templ.
") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } @@ -80,7 +80,7 @@ func page() templ.Component { return templ_7745c5c3_Err } } - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 4, "") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } diff --git a/examples/internationalization/components_templ.go b/examples/internationalization/components_templ.go index 2ccfa47f6..33a0fe3f6 100644 --- a/examples/internationalization/components_templ.go +++ b/examples/internationalization/components_templ.go @@ -30,7 +30,7 @@ func page() templ.Component { templ_7745c5c3_Var1 = templ.NopComponent } ctx = templ.ClearChildren(ctx) - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 1, "<html><head><meta charset=\"UTF-8\"><meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\"><title>") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } @@ -43,7 +43,7 @@ func page() templ.Component { if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("

") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 2, "

") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } @@ -56,7 +56,7 @@ func page() templ.Component { if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("

") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 3, "

") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } @@ -69,7 +69,7 @@ func page() templ.Component { if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("

") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 4, "") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } diff --git a/examples/static-generator/blog_templ.go b/examples/static-generator/blog_templ.go index eff4a463a..122fb22e8 100644 --- a/examples/static-generator/blog_templ.go +++ b/examples/static-generator/blog_templ.go @@ -33,7 +33,7 @@ func headerComponent(title string) templ.Component { templ_7745c5c3_Var1 = templ.NopComponent } ctx = templ.ClearChildren(ctx) - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 1, "<head><title>") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } @@ -46,7 +46,7 @@ func headerComponent(title string) templ.Component { if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 2, "") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } @@ -75,7 +75,7 @@ func contentComponent(title string, body templ.Component) templ.Component { templ_7745c5c3_Var3 = templ.NopComponent } ctx = templ.ClearChildren(ctx) - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("

") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 3, "

") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } @@ -88,7 +88,7 @@ func contentComponent(title string, body templ.Component) templ.Component { if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("

") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 4, "
") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } @@ -96,7 +96,7 @@ func contentComponent(title string, body templ.Component) templ.Component { if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("
") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 5, "
") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } @@ -125,7 +125,7 @@ func contentPage(title string, body templ.Component) templ.Component { templ_7745c5c3_Var5 = templ.NopComponent } ctx = templ.ClearChildren(ctx) - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 6, "") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } @@ -137,7 +137,7 @@ func contentPage(title string, body templ.Component) templ.Component { if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 7, "") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } @@ -166,7 +166,7 @@ func indexPage(posts []Post) templ.Component { templ_7745c5c3_Var6 = templ.NopComponent } ctx = templ.ClearChildren(ctx) - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 8, "") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } @@ -174,12 +174,12 @@ func indexPage(posts []Post) templ.Component { if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("

My Blog

") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 9, "

My Blog

") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } for _, post := range posts { - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("
") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 11, "\">") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } @@ -201,12 +201,12 @@ func indexPage(posts []Post) templ.Component { if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("
") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 12, "") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } } - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 13, "") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } diff --git a/examples/streaming/main_templ.go b/examples/streaming/main_templ.go index c94756a1e..98213ef78 100644 --- a/examples/streaming/main_templ.go +++ b/examples/streaming/main_templ.go @@ -63,7 +63,7 @@ func Page(data chan string) templ.Component { templ_7745c5c3_Var1 = templ.NopComponent } ctx = templ.ClearChildren(ctx) - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("Page

Page

") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 1, "Page

Page

") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } @@ -80,7 +80,7 @@ func Page(data chan string) templ.Component { }() } ctx = templ.InitializeContext(ctx) - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("
") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 2, "
") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } @@ -93,7 +93,7 @@ func Page(data chan string) templ.Component { if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("
") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 3, "
") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } @@ -104,7 +104,7 @@ func Page(data chan string) templ.Component { return templ_7745c5c3_Err } } - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 4, "") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } diff --git a/examples/suspense/main_templ.go b/examples/suspense/main_templ.go index 78777645a..7b054d453 100644 --- a/examples/suspense/main_templ.go +++ b/examples/suspense/main_templ.go @@ -94,7 +94,7 @@ func Slot(name string) templ.Component { templ_7745c5c3_Var1 = templ.NopComponent } ctx = templ.ClearChildren(ctx) - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("
Loading ") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 2, "\">
Loading ") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } @@ -120,7 +120,7 @@ func Slot(name string) templ.Component { if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("...
") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 3, "...
") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } @@ -149,7 +149,7 @@ func A() templ.Component { templ_7745c5c3_Var4 = templ.NopComponent } ctx = templ.ClearChildren(ctx) - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("
Component A.
") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 4, "
Component A.
") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } @@ -178,7 +178,7 @@ func B() templ.Component { templ_7745c5c3_Var5 = templ.NopComponent } ctx = templ.ClearChildren(ctx) - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("
Component B.
") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 5, "
Component B.
") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } @@ -207,7 +207,7 @@ func C() templ.Component { templ_7745c5c3_Var6 = templ.NopComponent } ctx = templ.ClearChildren(ctx) - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("
Component C.
") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 6, "
Component C.
") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } @@ -236,7 +236,7 @@ func Page(data chan SlotContents) templ.Component { templ_7745c5c3_Var7 = templ.NopComponent } ctx = templ.ClearChildren(ctx) - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("Page

Page

") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 7, "Page

Page

") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } @@ -252,7 +252,7 @@ func Page(data chan SlotContents) templ.Component { }() } ctx = templ.InitializeContext(ctx) - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } @@ -291,7 +291,7 @@ func Page(data chan SlotContents) templ.Component { }() } ctx = templ.InitializeContext(ctx) - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("
") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 11, "\">") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } @@ -312,7 +312,7 @@ func Page(data chan SlotContents) templ.Component { if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("
") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 12, "") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } @@ -323,7 +323,7 @@ func Page(data chan SlotContents) templ.Component { return templ_7745c5c3_Err } } - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 13, "") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } diff --git a/examples/syntax-and-usage/components/templsyntax_templ.go b/examples/syntax-and-usage/components/templsyntax_templ.go index cd939634f..a2e9291bf 100644 --- a/examples/syntax-and-usage/components/templsyntax_templ.go +++ b/examples/syntax-and-usage/components/templsyntax_templ.go @@ -28,12 +28,12 @@ func list(items []string) templ.Component { templ_7745c5c3_Var1 = templ.NopComponent } ctx = templ.ClearChildren(ctx) - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("
    ") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 1, "
      ") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } for _, item := range items { - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("
    1. ") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 2, "
    2. ") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } @@ -46,12 +46,12 @@ func list(items []string) templ.Component { if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("
    3. ") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 3, "") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } } - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("
    ") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 4, "
") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } diff --git a/examples/typescript/components/index_templ.go b/examples/typescript/components/index_templ.go index 8eea7da77..d9f1ab648 100644 --- a/examples/typescript/components/index_templ.go +++ b/examples/typescript/components/index_templ.go @@ -32,7 +32,7 @@ func Page(attributeData Data, scriptData Data) templ.Component { templ_7745c5c3_Var1 = templ.NopComponent } ctx = templ.ClearChildren(ctx) - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("Script usage") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 2, "\">Show alert from data in alert-data attribute") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } @@ -53,7 +53,7 @@ func Page(attributeData Data, scriptData Data) templ.Component { if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 3, "") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } diff --git a/generator/generator.go b/generator/generator.go index af3eda69b..3b8e316a6 100644 --- a/generator/generator.go +++ b/generator/generator.go @@ -23,7 +23,7 @@ type GenerateOpt func(g *generator) error // WithVersion enables the version to be included in the generated code. func WithVersion(v string) GenerateOpt { return func(g *generator) error { - g.version = v + g.options.Version = v return nil } } @@ -31,7 +31,7 @@ func WithVersion(v string) GenerateOpt { // WithTimestamp enables the generated date to be included in the generated code. func WithTimestamp(d time.Time) GenerateOpt { return func(g *generator) error { - g.generatedDate = d.Format(time.RFC3339) + g.options.GeneratedDate = d.Format(time.RFC3339) return nil } } @@ -40,19 +40,10 @@ func WithTimestamp(d time.Time) GenerateOpt { func WithFileName(name string) GenerateOpt { return func(g *generator) error { if filepath.IsAbs(name) { - _, g.fileName = filepath.Split(name) + _, g.options.FileName = filepath.Split(name) return nil } - g.fileName = name - return nil - } -} - -func WithExtractStrings() GenerateOpt { - return func(g *generator) error { - g.w.literalWriter = &watchLiteralWriter{ - builder: &strings.Builder{}, - } + g.options.FileName = name return nil } } @@ -62,14 +53,61 @@ func WithExtractStrings() GenerateOpt { // wish to skip generation of this comment so that gopls provides expected results. func WithSkipCodeGeneratedComment() GenerateOpt { return func(g *generator) error { - g.skipCodeGeneratedComment = true + g.options.SkipCodeGeneratedComment = true return nil } } +type GeneratorOutput struct { + Options GeneratorOptions `json:"meta"` + SourceMap *parser.SourceMap `json:"sourceMap"` + Literals []string `json:"literals"` +} + +type GeneratorOptions struct { + // Version of templ. + Version string + // FileName to include in error messages if string expressions return an error. + FileName string + // SkipCodeGeneratedComment skips the code generated comment at the top of the file. + SkipCodeGeneratedComment bool + // GeneratedDate to include as a comment. + GeneratedDate string +} + +// HasChanged returns true if the generated file should be written to disk, and therefore, also +// requires a recompilation. +func HasChanged(previous, updated GeneratorOutput) bool { + // If generator options have changed, we need to recompile. + if previous.Options.Version != updated.Options.Version { + return true + } + if previous.Options.FileName != updated.Options.FileName { + return true + } + if previous.Options.SkipCodeGeneratedComment != updated.Options.SkipCodeGeneratedComment { + return true + } + // We don't check the generated date as it's not used for determining if the file has changed. + // If the number of literals has changed, we need to recompile. + if len(previous.Literals) != len(updated.Literals) { + return true + } + // If the Go code has changed, we need to recompile. + if len(previous.SourceMap.Expressions) != len(updated.SourceMap.Expressions) { + return true + } + for i, prev := range previous.SourceMap.Expressions { + if prev != updated.SourceMap.Expressions[i] { + return true + } + } + return false +} + // Generate generates Go code from the input template file to w, and returns a map of the location of Go expressions in the template // to the location of the generated Go code in the output. -func Generate(template parser.TemplateFile, w io.Writer, opts ...GenerateOpt) (sm *parser.SourceMap, literals string, err error) { +func Generate(template parser.TemplateFile, w io.Writer, opts ...GenerateOpt) (op GeneratorOutput, err error) { g := &generator{ tf: template, w: NewRangeWriter(w), @@ -81,9 +119,13 @@ func Generate(template parser.TemplateFile, w io.Writer, opts ...GenerateOpt) (s } } err = g.generate() - sm = g.sourceMap - literals = g.w.literalWriter.literals() - return + if err != nil { + return op, err + } + op.Options = g.options + op.SourceMap = g.sourceMap + op.Literals = g.w.Literals + return op, nil } type generator struct { @@ -93,14 +135,7 @@ type generator struct { variableID int childrenVar string - // version of templ. - version string - // generatedDate to include as a comment. - generatedDate string - // fileName to include in error messages if string expressions return an error. - fileName string - // skipCodeGeneratedComment skips the code generated comment at the top of the file. - skipCodeGeneratedComment bool + options GeneratorOptions } func (g *generator) generate() (err error) { @@ -135,7 +170,7 @@ func (g *generator) generate() (err error) { // Automatically generated files have a comment in the header that instructs the LSP // to stop operating. func (g *generator) writeCodeGeneratedComment() (err error) { - if g.skipCodeGeneratedComment { + if g.options.SkipCodeGeneratedComment { // Write an empty comment so that the file is the same shape. _, err = g.w.Write("//\n\n") return err @@ -145,15 +180,15 @@ func (g *generator) writeCodeGeneratedComment() (err error) { } func (g *generator) writeVersionComment() (err error) { - if g.version != "" { - _, err = g.w.Write("// templ: version: " + g.version + "\n") + if g.options.Version != "" { + _, err = g.w.Write("// templ: version: " + g.options.Version + "\n") } return err } func (g *generator) writeGeneratedDateComment() (err error) { - if g.generatedDate != "" { - _, err = g.w.Write("// templ: generated: " + g.generatedDate + "\n") + if g.options.GeneratedDate != "" { + _, err = g.w.Write("// templ: generated: " + g.options.GeneratedDate + "\n") } return err } @@ -227,13 +262,15 @@ func (g *generator) writeTemplateNodes() error { func (g *generator) writeCSS(n parser.CSSTemplate) error { var r parser.Range + var tgtSymbolRange parser.Range var err error var indentLevel int // func - if _, err = g.w.Write("func "); err != nil { + if r, err = g.w.Write("func "); err != nil { return err } + tgtSymbolRange.From = r.From if r, err = g.w.Write(n.Expression.Value); err != nil { return err } @@ -296,17 +333,25 @@ func (g *generator) writeCSS(n parser.CSSTemplate) error { indentLevel-- } // } - if _, err = g.w.WriteIndent(indentLevel, "}\n\n"); err != nil { + if r, err = g.w.WriteIndent(indentLevel, "}\n\n"); err != nil { return err } + + // Keep a track of symbol ranges for the LSP. + tgtSymbolRange.To = r.To + g.sourceMap.AddSymbolRange(n.Range, tgtSymbolRange) + return nil } func (g *generator) writeGoExpression(n parser.TemplateFileGoExpression) (err error) { + var tgtSymbolRange parser.Range + r, err := g.w.Write(n.Expression.Value) if err != nil { return err } + tgtSymbolRange.From = r.From g.sourceMap.Add(n.Expression, r) v := n.Expression.Value lineSlice := strings.Split(v, "\n") @@ -317,9 +362,14 @@ func (g *generator) writeGoExpression(n parser.TemplateFileGoExpression) (err er } return err } - if _, err = g.w.WriteIndent(0, "\n\n"); err != nil { + if r, err = g.w.WriteIndent(0, "\n\n"); err != nil { return err } + + // Keep a track of symbol ranges for the LSP. + tgtSymbolRange.To = r.To + g.sourceMap.AddSymbolRange(n.Expression.Range, tgtSymbolRange) + return err } @@ -377,13 +427,15 @@ func (g *generator) writeTemplBuffer(indentLevel int) (err error) { func (g *generator) writeTemplate(nodeIdx int, t parser.HTMLTemplate) error { var r parser.Range + var tgtSymbolRange parser.Range var err error var indentLevel int // func - if _, err = g.w.Write("func "); err != nil { + if r, err = g.w.Write("func "); err != nil { return err } + tgtSymbolRange.From = r.From // (r *Receiver) Name(params []string) if r, err = g.w.Write(t.Expression.Value); err != nil { return err @@ -472,9 +524,14 @@ func (g *generator) writeTemplate(nodeIdx int, t parser.HTMLTemplate) error { closingBrace = "}\n" } - if _, err = g.w.WriteIndent(indentLevel, closingBrace); err != nil { + if r, err = g.w.WriteIndent(indentLevel, closingBrace); err != nil { return err } + + // Keep a track of symbol ranges for the LSP. + tgtSymbolRange.To = r.To + g.sourceMap.AddSymbolRange(t.Range, tgtSymbolRange) + return nil } @@ -878,7 +935,7 @@ func (g *generator) writeExpressionErrorHandler(indentLevel int, expression pars indentLevel++ line := int(expression.Range.To.Line + 1) col := int(expression.Range.To.Col) - _, err = g.w.WriteIndent(indentLevel, "return templ.Error{Err: templ_7745c5c3_Err, FileName: "+createGoString(g.fileName)+", Line: "+strconv.Itoa(line)+", Col: "+strconv.Itoa(col)+"}\n") + _, err = g.w.WriteIndent(indentLevel, "return templ.Error{Err: templ_7745c5c3_Err, FileName: "+createGoString(g.options.FileName)+", Line: "+strconv.Itoa(line)+", Col: "+strconv.Itoa(col)+"}\n") if err != nil { return err } @@ -1432,13 +1489,15 @@ func createGoString(s string) string { func (g *generator) writeScript(t parser.ScriptTemplate) error { var r parser.Range + var tgtSymbolRange parser.Range var err error var indentLevel int // func - if _, err = g.w.Write("func "); err != nil { + if r, err = g.w.Write("func "); err != nil { return err } + tgtSymbolRange.From = r.From if r, err = g.w.Write(t.Name.Value); err != nil { return err } @@ -1492,9 +1551,14 @@ func (g *generator) writeScript(t parser.ScriptTemplate) error { } indentLevel-- // } - if _, err = g.w.WriteIndent(indentLevel, "}\n\n"); err != nil { + if r, err = g.w.WriteIndent(indentLevel, "}\n\n"); err != nil { return err } + + // Keep track of the symbol range for the LSP. + tgtSymbolRange.To = r.To + g.sourceMap.AddSymbolRange(t.Range, tgtSymbolRange) + return nil } diff --git a/generator/rangewriter.go b/generator/rangewriter.go index d028251c9..5c286159d 100644 --- a/generator/rangewriter.go +++ b/generator/rangewriter.go @@ -11,8 +11,8 @@ import ( func NewRangeWriter(w io.Writer) *RangeWriter { return &RangeWriter{ - w: w, - literalWriter: prodLiteralWriter{}, + w: w, + builder: &strings.Builder{}, } } @@ -22,59 +22,28 @@ type RangeWriter struct { w io.Writer // Extract strings. - literalWriter literalWriter -} - -type literalWriter interface { - writeLiteral(inLiteral bool, s string) string - closeLiteral(indent int) string - literals() string -} - -type watchLiteralWriter struct { - index int - builder *strings.Builder -} - -func (w *watchLiteralWriter) closeLiteral(indent int) string { - w.index++ - w.builder.WriteString("\n") - return "" -} - -func (w *watchLiteralWriter) writeLiteral(inLiteral bool, s string) string { - w.builder.WriteString(s) - if inLiteral { - return "" - } - - return "templ_7745c5c3_Err = templ.WriteWatchModeString(templ_7745c5c3_Buffer, " + strconv.Itoa(w.index+1) + ")\n" -} - -func (w *watchLiteralWriter) literals() string { - return w.builder.String() -} - -type prodLiteralWriter struct{} - -func (prodLiteralWriter) closeLiteral(indent int) string { - return "\")\n" -} - -func (prodLiteralWriter) writeLiteral(inLiteral bool, s string) string { - if inLiteral { - return s - } - return `_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("` + s -} - -func (prodLiteralWriter) literals() string { - return "" + index int + builder *strings.Builder + Literals []string } func (rw *RangeWriter) closeLiteral(indent int) (r parser.Range, err error) { rw.inLiteral = false - if _, err := rw.write(rw.literalWriter.closeLiteral(indent)); err != nil { + rw.index++ + + var sb strings.Builder + sb.WriteString(strings.Repeat("\t", indent)) + sb.WriteString(`templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, `) + sb.WriteString(strconv.Itoa(rw.index)) + sb.WriteString(`, "`) + literal := rw.builder.String() + rw.Literals = append(rw.Literals, literal) + sb.WriteString(literal) + rw.builder.Reset() + sb.WriteString(`")`) + sb.WriteString("\n") + + if _, err := rw.write(sb.String()); err != nil { return r, err } @@ -96,19 +65,8 @@ func (rw *RangeWriter) WriteIndent(level int, s string) (r parser.Range, err err } func (rw *RangeWriter) WriteStringLiteral(level int, s string) (r parser.Range, err error) { - if !rw.inLiteral { - _, err = rw.write(strings.Repeat("\t", level)) - if err != nil { - return - } - } - - if _, err := rw.write(rw.literalWriter.writeLiteral(rw.inLiteral, s)); err != nil { - return r, err - } - rw.inLiteral = true - + rw.builder.WriteString(s) return } diff --git a/generator/test-a-href/template_templ.go b/generator/test-a-href/template_templ.go index 2b15189e7..35d777a18 100644 --- a/generator/test-a-href/template_templ.go +++ b/generator/test-a-href/template_templ.go @@ -28,7 +28,7 @@ func render() templ.Component { templ_7745c5c3_Var1 = templ.NopComponent } ctx = templ.ClearChildren(ctx) - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("Ignored Ignored Sanitized Sanitized Unsanitized") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 3, "\">Unsanitized") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } diff --git a/generator/test-attribute-errors/template_templ.go b/generator/test-attribute-errors/template_templ.go index 78edec11d..0c44eba42 100644 --- a/generator/test-attribute-errors/template_templ.go +++ b/generator/test-attribute-errors/template_templ.go @@ -39,7 +39,7 @@ func TestComponent(err error) templ.Component { templ_7745c5c3_Var1 = templ.NopComponent } ctx = templ.ClearChildren(ctx) - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 4, "\">") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } diff --git a/generator/test-attribute-escaping/template_templ.go b/generator/test-attribute-escaping/template_templ.go index 706243702..3afabebf6 100644 --- a/generator/test-attribute-escaping/template_templ.go +++ b/generator/test-attribute-escaping/template_templ.go @@ -28,7 +28,7 @@ func BasicTemplate(url string) templ.Component { templ_7745c5c3_Var1 = templ.NopComponent } ctx = templ.ClearChildren(ctx) - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("
text
") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 2, "\">text
") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } diff --git a/generator/test-call/template_templ.go b/generator/test-call/template_templ.go index d8634e619..d54059892 100644 --- a/generator/test-call/template_templ.go +++ b/generator/test-call/template_templ.go @@ -56,7 +56,7 @@ func showAll() templ.Component { }() } ctx = templ.InitializeContext(ctx) - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("
Child content
") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 1, "
Child content
") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } @@ -91,7 +91,7 @@ func a() templ.Component { templ_7745c5c3_Var3 = templ.NopComponent } ctx = templ.ClearChildren(ctx) - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("
A
") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 2, "
A
") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } @@ -120,7 +120,7 @@ func b(child templ.Component) templ.Component { templ_7745c5c3_Var4 = templ.NopComponent } ctx = templ.ClearChildren(ctx) - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("
B
") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 3, "
B
") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } @@ -153,7 +153,7 @@ func c(text string) templ.Component { templ_7745c5c3_Var5 = templ.NopComponent } ctx = templ.ClearChildren(ctx) - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("
") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 4, "
") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } @@ -166,7 +166,7 @@ func c(text string) templ.Component { if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("
") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 5, "
") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } @@ -195,7 +195,7 @@ func d() templ.Component { templ_7745c5c3_Var7 = templ.NopComponent } ctx = templ.ClearChildren(ctx) - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("
Legacy call style
") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 6, "
Legacy call style
") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } @@ -224,7 +224,7 @@ func e() templ.Component { templ_7745c5c3_Var8 = templ.NopComponent } ctx = templ.ClearChildren(ctx) - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("e") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 7, "e") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } @@ -253,7 +253,7 @@ func showOne(component templ.Component) templ.Component { templ_7745c5c3_Var9 = templ.NopComponent } ctx = templ.ClearChildren(ctx) - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("
") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 8, "
") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } @@ -261,7 +261,7 @@ func showOne(component templ.Component) templ.Component { if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("
") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 9, "
") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } @@ -290,7 +290,7 @@ func wrapChildren() templ.Component { templ_7745c5c3_Var10 = templ.NopComponent } ctx = templ.ClearChildren(ctx) - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("
") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 10, "
") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } @@ -298,7 +298,7 @@ func wrapChildren() templ.Component { if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("
") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 11, "
") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } diff --git a/generator/test-complex-attributes/template_templ.go b/generator/test-complex-attributes/template_templ.go index 90536e470..7e4419ac5 100644 --- a/generator/test-complex-attributes/template_templ.go +++ b/generator/test-complex-attributes/template_templ.go @@ -28,7 +28,7 @@ func ComplexAttributes() templ.Component { templ_7745c5c3_Var1 = templ.NopComponent } ctx = templ.ClearChildren(ctx) - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("
") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 1, "
") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } diff --git a/generator/test-constant-attribute-escaping/template_templ.go b/generator/test-constant-attribute-escaping/template_templ.go index af9e39e29..e1e1b2675 100644 --- a/generator/test-constant-attribute-escaping/template_templ.go +++ b/generator/test-constant-attribute-escaping/template_templ.go @@ -28,7 +28,7 @@ func BasicTemplate() templ.Component { templ_7745c5c3_Var1 = templ.NopComponent } ctx = templ.ClearChildren(ctx) - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("
") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 1, "
") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } diff --git a/generator/test-context/template_templ.go b/generator/test-context/template_templ.go index a62b4bfe3..840c83298 100644 --- a/generator/test-context/template_templ.go +++ b/generator/test-context/template_templ.go @@ -32,7 +32,7 @@ func render() templ.Component { templ_7745c5c3_Var1 = templ.NopComponent } ctx = templ.ClearChildren(ctx) - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } diff --git a/generator/test-css-middleware/template_templ.go b/generator/test-css-middleware/template_templ.go index 89546249b..24fd21041 100644 --- a/generator/test-css-middleware/template_templ.go +++ b/generator/test-css-middleware/template_templ.go @@ -43,7 +43,7 @@ func render(s string) templ.Component { if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("
") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 2, "\">") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } @@ -69,7 +69,7 @@ func render(s string) templ.Component { if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("
") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 3, "") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } diff --git a/generator/test-css-usage/template_templ.go b/generator/test-css-usage/template_templ.go index 1d45e658f..47cd7496b 100644 --- a/generator/test-css-usage/template_templ.go +++ b/generator/test-css-usage/template_templ.go @@ -33,7 +33,7 @@ func StyleTagsAreSupported() templ.Component { templ_7745c5c3_Var1 = templ.NopComponent } ctx = templ.ClearChildren(ctx) - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("
Style tags are supported
") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 1, "
Style tags are supported
") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } @@ -81,7 +81,7 @@ func CSSComponentsAreSupported() templ.Component { if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("
CSS components are supported
") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 3, "\">CSS components are supported") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } @@ -130,7 +130,7 @@ func CSSComponentsAndConstantsAreSupported() templ.Component { if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("
Both CSS components and constants are supported
") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 5, "\" type=\"button\">Both CSS components and constants are supported") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } @@ -152,7 +152,7 @@ func CSSComponentsAndConstantsAreSupported() templ.Component { if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("
Both CSS components and constants are supported
") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 7, "\" type=\"button\">Both CSS components and constants are supported") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } @@ -200,7 +200,7 @@ func MapsCanBeUsedToConditionallySetClasses() templ.Component { if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("
Maps can be used to determine if a class should be added or not.
") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 9, "\">Maps can be used to determine if a class should be added or not.") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } @@ -268,7 +268,7 @@ func KVCanBeUsedToConditionallySetClasses() templ.Component { if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("
KV can be used to conditionally set classes.
") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 11, "\">KV can be used to conditionally set classes.") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } @@ -316,7 +316,7 @@ func PsuedoAttributesAndComplexClassNamesAreSupported() templ.Component { if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("
Psuedo attributes and complex class names are supported.
") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 13, "\">Psuedo attributes and complex class names are supported.") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } @@ -364,7 +364,7 @@ func ClassNamesAreHTMLEscaped() templ.Component { if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("
Class names are HTML escaped.
") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 15, "\">Class names are HTML escaped.") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } @@ -422,7 +422,7 @@ func CSSComponentsCanBeUsedWithArguments() templ.Component { if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("
CSS components can be used with arguments.
") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 17, "\">CSS components can be used with arguments.") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } @@ -444,7 +444,7 @@ func CSSComponentsCanBeUsedWithArguments() templ.Component { if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("
CSS components can be used with arguments.
") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 19, "\">CSS components can be used with arguments.") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } @@ -501,7 +501,7 @@ func Rotate(degrees float64) templ.Component { if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("
Rotate
") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 21, "\">Rotate") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } diff --git a/generator/test-doctype/template_templ.go b/generator/test-doctype/template_templ.go index baefd8873..6da16edce 100644 --- a/generator/test-doctype/template_templ.go +++ b/generator/test-doctype/template_templ.go @@ -28,7 +28,7 @@ func Layout(title, content string) templ.Component { templ_7745c5c3_Var1 = templ.NopComponent } ctx = templ.ClearChildren(ctx) - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 1, "<!doctype html><html lang=\"en\"><head><meta charset=\"UTF-8\"><meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\"><meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\"><title>") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } @@ -41,7 +41,7 @@ func Layout(title, content string) templ.Component { if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 2, "") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } @@ -54,7 +54,7 @@ func Layout(title, content string) templ.Component { if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 3, "") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } diff --git a/generator/test-element-attributes/template_templ.go b/generator/test-element-attributes/template_templ.go index 9ff771827..62b1576e4 100644 --- a/generator/test-element-attributes/template_templ.go +++ b/generator/test-element-attributes/template_templ.go @@ -53,12 +53,12 @@ func render(p person) templ.Component { if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("
Important
") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 4, ">Important") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } @@ -85,12 +85,12 @@ func render(p person) templ.Component { if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("
Unimportant
") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 8, ">Unimportant") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } @@ -122,12 +122,12 @@ func render(p person) templ.Component { if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("
Else

HTMX Wildcard attribute

") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 14, ">Else

HTMX Wildcard attribute

") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } diff --git a/generator/test-elseif/template_templ.go b/generator/test-elseif/template_templ.go index 49af560b7..2b0e5ad31 100644 --- a/generator/test-elseif/template_templ.go +++ b/generator/test-elseif/template_templ.go @@ -28,7 +28,7 @@ func render(d data) templ.Component { templ_7745c5c3_Var1 = templ.NopComponent } ctx = templ.ClearChildren(ctx) - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("
") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 1, "
") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } @@ -63,7 +63,7 @@ func render(d data) templ.Component { return templ_7745c5c3_Err } } - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("
") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 2, "
") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } @@ -88,7 +88,7 @@ func render(d data) templ.Component { return templ_7745c5c3_Err } } - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("
") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 3, "
") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } @@ -133,7 +133,7 @@ func render(d data) templ.Component { return templ_7745c5c3_Err } } - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("
") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 4, "
") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } diff --git a/generator/test-for/template_templ.go b/generator/test-for/template_templ.go index f5234bd6a..50b059a5f 100644 --- a/generator/test-for/template_templ.go +++ b/generator/test-for/template_templ.go @@ -29,7 +29,7 @@ func render(items []string) templ.Component { } ctx = templ.ClearChildren(ctx) for _, item := range items { - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("
") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 1, "
") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } @@ -42,7 +42,7 @@ func render(items []string) templ.Component { if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("
") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 2, "
") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } diff --git a/generator/test-form-action/template_templ.go b/generator/test-form-action/template_templ.go index 400666352..98fc64eea 100644 --- a/generator/test-form-action/template_templ.go +++ b/generator/test-form-action/template_templ.go @@ -28,7 +28,7 @@ func render() templ.Component { templ_7745c5c3_Var1 = templ.NopComponent } ctx = templ.ClearChildren(ctx) - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("
Ignored
Ignored
Sanitized
Sanitized
Unsanitized
") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 3, "\">Unsanitized") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } diff --git a/generator/test-go-comments/template_templ.go b/generator/test-go-comments/template_templ.go index 9b0778d7d..ba66c7492 100644 --- a/generator/test-go-comments/template_templ.go +++ b/generator/test-go-comments/template_templ.go @@ -28,7 +28,7 @@ func render(content string) templ.Component { templ_7745c5c3_Var1 = templ.NopComponent } ctx = templ.ClearChildren(ctx) - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("

") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 1, "

") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } @@ -41,7 +41,7 @@ func render(content string) templ.Component { if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("

") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 2, "

") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } diff --git a/generator/test-go-template-in-templ/template_templ.go b/generator/test-go-template-in-templ/template_templ.go index a750e14ec..4e699b554 100644 --- a/generator/test-go-template-in-templ/template_templ.go +++ b/generator/test-go-template-in-templ/template_templ.go @@ -32,7 +32,7 @@ func Example() templ.Component { templ_7745c5c3_Var1 = templ.NopComponent } ctx = templ.ClearChildren(ctx) - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 1, "") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } @@ -40,7 +40,7 @@ func Example() templ.Component { if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 2, "") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } diff --git a/generator/test-html-comment/template_templ.go b/generator/test-html-comment/template_templ.go index ca38a5c28..bf755633a 100644 --- a/generator/test-html-comment/template_templ.go +++ b/generator/test-html-comment/template_templ.go @@ -28,7 +28,7 @@ func render(content string) templ.Component { templ_7745c5c3_Var1 = templ.NopComponent } ctx = templ.ClearChildren(ctx) - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 1, "") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } @@ -36,7 +36,7 @@ func render(content string) templ.Component { if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 2, "") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } @@ -44,7 +44,7 @@ func render(content string) templ.Component { if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 3, "") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } @@ -52,7 +52,7 @@ func render(content string) templ.Component { if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 4, "") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } @@ -65,7 +65,7 @@ func render(content string) templ.Component { if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 5, "") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } @@ -94,7 +94,7 @@ func paragraph(content string) templ.Component { templ_7745c5c3_Var3 = templ.NopComponent } ctx = templ.ClearChildren(ctx) - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("

") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 6, "

") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } @@ -107,7 +107,7 @@ func paragraph(content string) templ.Component { if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("

") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 7, "

") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } diff --git a/generator/test-html/template_templ.go b/generator/test-html/template_templ.go index afeddcfa9..a939a6516 100644 --- a/generator/test-html/template_templ.go +++ b/generator/test-html/template_templ.go @@ -28,7 +28,7 @@ func render(p person) templ.Component { templ_7745c5c3_Var1 = templ.NopComponent } ctx = templ.ClearChildren(ctx) - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("

") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 1, "

") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } @@ -41,7 +41,7 @@ func render(p person) templ.Component { if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("




Text") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 11, ">
Text") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } diff --git a/generator/test-import/template_templ.go b/generator/test-import/template_templ.go index 1ce0dd8d2..164a9532e 100644 --- a/generator/test-import/template_templ.go +++ b/generator/test-import/template_templ.go @@ -28,7 +28,7 @@ func listItem() templ.Component { templ_7745c5c3_Var1 = templ.NopComponent } ctx = templ.ClearChildren(ctx) - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("
  • ") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 1, "
  • ") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } @@ -36,7 +36,7 @@ func listItem() templ.Component { if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("
  • ") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 2, "") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } @@ -65,7 +65,7 @@ func list() templ.Component { templ_7745c5c3_Var2 = templ.NopComponent } ctx = templ.ClearChildren(ctx) - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } @@ -126,7 +126,7 @@ func main() templ.Component { }() } ctx = templ.InitializeContext(ctx) - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("Item 1") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 5, "Item 1") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } @@ -136,7 +136,7 @@ func main() templ.Component { if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(" ") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 6, " ") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } @@ -152,7 +152,7 @@ func main() templ.Component { }() } ctx = templ.InitializeContext(ctx) - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("Item 2") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 7, "Item 2") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } @@ -162,7 +162,7 @@ func main() templ.Component { if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(" ") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 8, " ") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } @@ -178,7 +178,7 @@ func main() templ.Component { }() } ctx = templ.InitializeContext(ctx) - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("Item 3") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 9, "Item 3") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } diff --git a/generator/test-method/template_templ.go b/generator/test-method/template_templ.go index b1c6b7ddc..51ba91801 100644 --- a/generator/test-method/template_templ.go +++ b/generator/test-method/template_templ.go @@ -32,7 +32,7 @@ func (d Data) Method() templ.Component { templ_7745c5c3_Var1 = templ.NopComponent } ctx = templ.ClearChildren(ctx) - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("
    ") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 1, "
    ") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } @@ -45,7 +45,7 @@ func (d Data) Method() templ.Component { if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("
    ") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 2, "
    ") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } diff --git a/generator/test-once/template_templ.go b/generator/test-once/template_templ.go index 282306ada..930687dc6 100644 --- a/generator/test-once/template_templ.go +++ b/generator/test-once/template_templ.go @@ -42,7 +42,7 @@ func hello(label, name string) templ.Component { }() } ctx = templ.InitializeContext(ctx) - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 1, "") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } @@ -52,7 +52,7 @@ func hello(label, name string) templ.Component { if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 4, "\" onclick=\"hello(this.getAttribute('data-name'))\">") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } diff --git a/generator/test-raw-elements/template_templ.go b/generator/test-raw-elements/template_templ.go index 4f6f25b3e..f91e7dbad 100644 --- a/generator/test-raw-elements/template_templ.go +++ b/generator/test-raw-elements/template_templ.go @@ -28,7 +28,7 @@ func Example() templ.Component { templ_7745c5c3_Var1 = templ.NopComponent } ctx = templ.ClearChildren(ctx) - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("

    Hello

    ") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 1, "

    Hello

    ") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } @@ -36,7 +36,7 @@ func Example() templ.Component { if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 2, "") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } diff --git a/generator/test-script-usage-nonce/template_templ.go b/generator/test-script-usage-nonce/template_templ.go index c73474d7f..1e5c41b21 100644 --- a/generator/test-script-usage-nonce/template_templ.go +++ b/generator/test-script-usage-nonce/template_templ.go @@ -62,7 +62,7 @@ func Button(text string) templ.Component { if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 4, "") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } @@ -140,7 +140,7 @@ func ThreeButtons() templ.Component { if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(" ") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 5, " ") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } @@ -148,7 +148,7 @@ func ThreeButtons() templ.Component { if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 7, "\" type=\"button\">Button E") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } @@ -204,12 +204,12 @@ func Conditional(show bool) templ.Component { if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 11, ">") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } diff --git a/generator/test-script-usage/template_templ.go b/generator/test-script-usage/template_templ.go index 938451d39..66bfba4ac 100644 --- a/generator/test-script-usage/template_templ.go +++ b/generator/test-script-usage/template_templ.go @@ -62,7 +62,7 @@ func Button(text string) templ.Component { if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 4, "") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } @@ -150,7 +150,7 @@ func ThreeButtons() templ.Component { if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(" ") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 5, " ") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } @@ -158,7 +158,7 @@ func ThreeButtons() templ.Component { if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(" ") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 7, "\" type=\"button\">Button E ") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } @@ -175,7 +175,7 @@ func ThreeButtons() templ.Component { if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 9, "\">Button F") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } @@ -235,12 +235,12 @@ func Conditional(show bool) templ.Component { if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 13, ">") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } @@ -297,7 +297,7 @@ func ScriptOnLoad() templ.Component { if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 15, "\" src=\"url.to.some.script\">") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } diff --git a/generator/test-spread-attributes/template_templ.go b/generator/test-spread-attributes/template_templ.go index 6bd9d5b10..17b5741b0 100644 --- a/generator/test-spread-attributes/template_templ.go +++ b/generator/test-spread-attributes/template_templ.go @@ -28,7 +28,7 @@ func BasicTemplate(spread templ.Attributes) templ.Component { templ_7745c5c3_Var1 = templ.NopComponent } ctx = templ.ClearChildren(ctx) - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("
    texttexttext2
    text2text3") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 4, ">text3") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } diff --git a/generator/test-string-errors/template_templ.go b/generator/test-string-errors/template_templ.go index 1995127de..f4a172e09 100644 --- a/generator/test-string-errors/template_templ.go +++ b/generator/test-string-errors/template_templ.go @@ -39,7 +39,7 @@ func TestComponent(err error) templ.Component { templ_7745c5c3_Var1 = templ.NopComponent } ctx = templ.ClearChildren(ctx) - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("
    • ") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 1, "
      • ") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } @@ -52,7 +52,7 @@ func TestComponent(err error) templ.Component { if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("
      • ") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 2, "
      • ") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } @@ -65,7 +65,7 @@ func TestComponent(err error) templ.Component { if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("
      • ") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 3, "
      • ") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } @@ -78,7 +78,7 @@ func TestComponent(err error) templ.Component { if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("
      ") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 4, "
    ") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } diff --git a/generator/test-string/template_templ.go b/generator/test-string/template_templ.go index b2de39d4c..8468472ea 100644 --- a/generator/test-string/template_templ.go +++ b/generator/test-string/template_templ.go @@ -28,7 +28,7 @@ func render(s string) templ.Component { templ_7745c5c3_Var1 = templ.NopComponent } ctx = templ.ClearChildren(ctx) - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("
    • ") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 1, "
      • ") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } @@ -41,7 +41,7 @@ func render(s string) templ.Component { if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("
      • ") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 2, "
      • ") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } @@ -54,7 +54,7 @@ func render(s string) templ.Component { if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(" ") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 3, " ") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } @@ -67,7 +67,7 @@ func render(s string) templ.Component { if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(" ") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 4, " ") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } @@ -80,7 +80,7 @@ func render(s string) templ.Component { if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("
      ") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 5, "
    ") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } diff --git a/generator/test-templ-element/template_templ.go b/generator/test-templ-element/template_templ.go index bd7f0bf11..4468053b5 100644 --- a/generator/test-templ-element/template_templ.go +++ b/generator/test-templ-element/template_templ.go @@ -30,7 +30,7 @@ func wrapper(index int) templ.Component { templ_7745c5c3_Var1 = templ.NopComponent } ctx = templ.ClearChildren(ctx) - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("
    ") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 2, "\">") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } @@ -51,7 +51,7 @@ func wrapper(index int) templ.Component { if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("
    ") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 3, "") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } @@ -92,7 +92,7 @@ func template() templ.Component { }() } ctx = templ.InitializeContext(ctx) - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("child1") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 4, "child1") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } @@ -108,7 +108,7 @@ func template() templ.Component { }() } ctx = templ.InitializeContext(ctx) - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("child2") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 5, "child2") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } @@ -124,7 +124,7 @@ func template() templ.Component { }() } ctx = templ.InitializeContext(ctx) - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("child3") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 6, "child3") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } diff --git a/generator/test-templ-in-go-template/template_templ.go b/generator/test-templ-in-go-template/template_templ.go index c62699478..2a87ce770 100644 --- a/generator/test-templ-in-go-template/template_templ.go +++ b/generator/test-templ-in-go-template/template_templ.go @@ -38,7 +38,7 @@ func greeting() templ.Component { templ_7745c5c3_Var1 = templ.NopComponent } ctx = templ.ClearChildren(ctx) - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("
    Hello, World!
    ") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 1, "
    Hello, World!
    ") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } diff --git a/generator/test-text-whitespace/template_templ.go b/generator/test-text-whitespace/template_templ.go index 26fc6447e..80dafa3df 100644 --- a/generator/test-text-whitespace/template_templ.go +++ b/generator/test-text-whitespace/template_templ.go @@ -28,17 +28,17 @@ func WhitespaceIsAddedWithinTemplStatements() templ.Component { templ_7745c5c3_Var1 = templ.NopComponent } ctx = templ.ClearChildren(ctx) - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("

    This is some text. ") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 1, "

    This is some text. ") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } if true { - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("So is this.") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 2, "So is this.") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } } - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("

    ") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 3, "

    ") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } @@ -69,7 +69,7 @@ func InlineElementsAreNotPadded() templ.Component { templ_7745c5c3_Var2 = templ.NopComponent } ctx = templ.ClearChildren(ctx) - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("

    Inline text is spaced properly without adding extra spaces.

    ") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 4, "

    Inline text is spaced properly without adding extra spaces.

    ") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } @@ -100,7 +100,7 @@ func WhiteSpaceInHTMLIsNormalised() templ.Component { templ_7745c5c3_Var3 = templ.NopComponent } ctx = templ.ClearChildren(ctx) - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("

    newlines and other whitespace are stripped but it is normalised like HTML.

    ") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 5, "

    newlines and other whitespace are stripped but it is normalised like HTML.

    ") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } @@ -131,7 +131,7 @@ func WhiteSpaceAroundValues() templ.Component { templ_7745c5c3_Var4 = templ.NopComponent } ctx = templ.ClearChildren(ctx) - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("

    templ allows ") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 6, "

    templ allows ") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } @@ -144,7 +144,7 @@ func WhiteSpaceAroundValues() templ.Component { if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(" to be included in sentences.

    ") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 7, " to be included in sentences.

    ") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } @@ -177,7 +177,7 @@ func WhiteSpaceAroundTemplatedValues(prefix, statement string) templ.Component { templ_7745c5c3_Var6 = templ.NopComponent } ctx = templ.ClearChildren(ctx) - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("
    ") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 8, "
    ") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } @@ -190,7 +190,7 @@ func WhiteSpaceAroundTemplatedValues(prefix, statement string) templ.Component { if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(" ") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 9, " ") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } @@ -203,7 +203,7 @@ func WhiteSpaceAroundTemplatedValues(prefix, statement string) templ.Component { if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("
    ") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 10, "
    ") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } diff --git a/generator/test-text/template_templ.go b/generator/test-text/template_templ.go index 60dafec9a..4307dab42 100644 --- a/generator/test-text/template_templ.go +++ b/generator/test-text/template_templ.go @@ -28,7 +28,7 @@ func BasicTemplate(name string) templ.Component { templ_7745c5c3_Var1 = templ.NopComponent } ctx = templ.ClearChildren(ctx) - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("
    Name: ") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 1, "
    Name: ") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } @@ -41,7 +41,7 @@ func BasicTemplate(name string) templ.Component { if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("
    Text `with backticks`
    Text `with backtick
    Text `with backtick alongside variable: ") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 2, "
    Text `with backticks`
    Text `with backtick
    Text `with backtick alongside variable: ") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } @@ -54,7 +54,7 @@ func BasicTemplate(name string) templ.Component { if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("
    ") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 3, "
    ") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } diff --git a/generator/test-void/template_templ.go b/generator/test-void/template_templ.go index 5479e7b17..a2552cc81 100644 --- a/generator/test-void/template_templ.go +++ b/generator/test-void/template_templ.go @@ -28,7 +28,7 @@ func render() templ.Component { templ_7745c5c3_Var1 = templ.NopComponent } ctx = templ.ClearChildren(ctx) - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("


    ") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 1, "


    ") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } diff --git a/generator/test-whitespace-around-go-keywords/template_templ.go b/generator/test-whitespace-around-go-keywords/template_templ.go index 7e49af087..0df8f0c0c 100644 --- a/generator/test-whitespace-around-go-keywords/template_templ.go +++ b/generator/test-whitespace-around-go-keywords/template_templ.go @@ -30,27 +30,27 @@ func WhitespaceIsConsistentInIf(firstIf, secondIf bool) templ.Component { templ_7745c5c3_Var1 = templ.NopComponent } ctx = templ.ClearChildren(ctx) - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(" ") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 1, " ") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } if firstIf { - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(" ") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 2, " ") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } } else if secondIf { - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(" ") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 3, " ") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } } else { - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(" ") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 4, " ") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } } - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 5, "") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } @@ -83,17 +83,17 @@ func WhitespaceIsConsistentInFalseIf() templ.Component { templ_7745c5c3_Var2 = templ.NopComponent } ctx = templ.ClearChildren(ctx) - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(" ") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 6, " ") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } if false { - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(" ") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 7, " ") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } } - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 8, "") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } @@ -124,23 +124,23 @@ func WhitespaceIsConsistentInSwitch(i int) templ.Component { templ_7745c5c3_Var3 = templ.NopComponent } ctx = templ.ClearChildren(ctx) - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(" ") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 9, " ") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } switch i { case 1: - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(" ") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 10, " ") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } default: - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(" ") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 11, " ") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } } - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 12, "") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } @@ -172,18 +172,18 @@ func WhitespaceIsConsistentInSwitchNoDefault() templ.Component { templ_7745c5c3_Var4 = templ.NopComponent } ctx = templ.ClearChildren(ctx) - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(" ") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 13, " ") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } switch false { case true: - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(" ") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 14, " ") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } } - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 15, "") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } @@ -214,12 +214,12 @@ func WhitespaceIsConsistentInFor(i int) templ.Component { templ_7745c5c3_Var5 = templ.NopComponent } ctx = templ.ClearChildren(ctx) - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(" ") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 16, " ") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } for j := 0; j < i; j++ { - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(" ") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 18, " ") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } } - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 19, "") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } diff --git a/parser/v2/calltemplateparser_test.go b/parser/v2/calltemplateparser_test.go index 765d91500..5f9db107e 100644 --- a/parser/v2/calltemplateparser_test.go +++ b/parser/v2/calltemplateparser_test.go @@ -96,5 +96,5 @@ func TestCallTemplateExpressionParser(t *testing.T) { } func TestCallTemplateParserAllocsSkip(t *testing.T) { - RunParserAllocTest[Node](t, callTemplateExpression, false, 0, ``) + RunParserAllocTest(t, callTemplateExpression, false, 0, ``) } diff --git a/parser/v2/childrenparser_test.go b/parser/v2/childrenparser_test.go index 7ee5b4cd8..2422884ff 100644 --- a/parser/v2/childrenparser_test.go +++ b/parser/v2/childrenparser_test.go @@ -48,9 +48,9 @@ func TestChildrenExpressionParser(t *testing.T) { } func TestChildrenExpressionParserAllocsOK(t *testing.T) { - RunParserAllocTest[Node](t, childrenExpression, true, 2, `{ children... }`) + RunParserAllocTest(t, childrenExpression, true, 2, `{ children... }`) } func TestChildrenExpressionParserAllocsSkip(t *testing.T) { - RunParserAllocTest[Node](t, childrenExpression, false, 2, ``) + RunParserAllocTest(t, childrenExpression, false, 2, ``) } diff --git a/parser/v2/elementparser_test.go b/parser/v2/elementparser_test.go index 19050c18a..2bab6fcff 100644 --- a/parser/v2/elementparser_test.go +++ b/parser/v2/elementparser_test.go @@ -283,7 +283,7 @@ if test { { name: "attribute parsing handles boolean expression attributes", input: ` noshade?={ true }`, - parser: StripType[Attribute](attributeParser{}), + parser: StripType(attributeParser{}), expected: BoolExpressionAttribute{ Name: "noshade", NameRange: Range{ @@ -464,7 +464,7 @@ if test { { name: "bool constant attributes can end with a Unix newline", input: "", - parser: StripType[Node](element), + parser: StripType(element), expected: Element{ Name: "input", IndentAttrs: true, @@ -486,7 +486,7 @@ if test { { name: "bool constant attributes can end with a Windows newline", input: "", - parser: StripType[Node](element), + parser: StripType(element), expected: Element{ Name: "input", IndentAttrs: true, diff --git a/parser/v2/expressionparser.go b/parser/v2/expressionparser.go index c8474a2e5..cde2dfd28 100644 --- a/parser/v2/expressionparser.go +++ b/parser/v2/expressionparser.go @@ -45,7 +45,7 @@ var dblCloseBraceWithOptionalPadding = parse.StringFrom(optionalSpaces, dblClose var openBracket = parse.String("(") var closeBracket = parse.String(")") -var stringUntilNewLine = parse.StringUntil[string](parse.NewLine) +var stringUntilNewLine = parse.StringUntil(parse.NewLine) var newLineOrEOF = parse.Or(parse.NewLine, parse.EOF[string]()) var stringUntilNewLineOrEOF = parse.StringUntil(newLineOrEOF) diff --git a/parser/v2/gocommentparser.go b/parser/v2/gocommentparser.go index 6555d99b1..469264842 100644 --- a/parser/v2/gocommentparser.go +++ b/parser/v2/gocommentparser.go @@ -60,4 +60,4 @@ func (p goMultiLineCommentParser) Parse(pi *parse.Input) (n Node, ok bool, err e return c, true, nil } -var goComment = parse.Any[Node](goSingleLineComment, goMultiLineComment) +var goComment = parse.Any(goSingleLineComment, goMultiLineComment) diff --git a/parser/v2/sourcemap.go b/parser/v2/sourcemap.go index d342e31e6..ef259ccbd 100644 --- a/parser/v2/sourcemap.go +++ b/parser/v2/sourcemap.go @@ -9,18 +9,49 @@ import ( // parsed template. func NewSourceMap() *SourceMap { return &SourceMap{ - SourceLinesToTarget: make(map[uint32]map[uint32]Position), - TargetLinesToSource: make(map[uint32]map[uint32]Position), + SourceLinesToTarget: make(map[uint32]map[uint32]Position), + TargetLinesToSource: make(map[uint32]map[uint32]Position), + SourceSymbolRangeToTarget: make(map[uint32]map[uint32]Range), + TargetSymbolRangeToSource: make(map[uint32]map[uint32]Range), } } type SourceMap struct { - SourceLinesToTarget map[uint32]map[uint32]Position - TargetLinesToSource map[uint32]map[uint32]Position + Expressions []string + SourceLinesToTarget map[uint32]map[uint32]Position + TargetLinesToSource map[uint32]map[uint32]Position + SourceSymbolRangeToTarget map[uint32]map[uint32]Range + TargetSymbolRangeToSource map[uint32]map[uint32]Range +} + +func (sm *SourceMap) AddSymbolRange(src Range, tgt Range) { + sm.SourceSymbolRangeToTarget[src.From.Line] = make(map[uint32]Range) + sm.SourceSymbolRangeToTarget[src.From.Line][src.From.Col] = tgt + sm.TargetSymbolRangeToSource[tgt.From.Line] = make(map[uint32]Range) + sm.TargetSymbolRangeToSource[tgt.From.Line][tgt.From.Col] = src +} + +func (sm *SourceMap) SymbolTargetRangeFromSource(line, col uint32) (tgt Range, ok bool) { + lm, ok := sm.SourceSymbolRangeToTarget[line] + if !ok { + return + } + tgt, ok = lm[col] + return +} + +func (sm *SourceMap) SymbolSourceRangeFromTarget(line, col uint32) (src Range, ok bool) { + lm, ok := sm.TargetSymbolRangeToSource[line] + if !ok { + return + } + src, ok = lm[col] + return } // Add an item to the lookup. func (sm *SourceMap) Add(src Expression, tgt Range) (updatedFrom Position) { + sm.Expressions = append(sm.Expressions, src.Value) srcIndex := src.Range.From.Index tgtIndex := tgt.From.Index diff --git a/runtime.go b/runtime.go index 7ed9db99c..b55459b63 100644 --- a/runtime.go +++ b/runtime.go @@ -11,14 +11,10 @@ import ( "html/template" "io" "net/http" - "os" "reflect" - "runtime" "sort" - "strconv" "strings" "sync" - "time" "github.com/a-h/templ/safehtml" ) @@ -640,91 +636,3 @@ func ToGoHTML(ctx context.Context, c Component) (s template.HTML, err error) { s = template.HTML(b.String()) return } - -// WriteWatchModeString is used when rendering templates in development mode. -// the generator would have written non-go code to the _templ.txt file, which -// is then read by this function and written to the output. -func WriteWatchModeString(w io.Writer, lineNum int) error { - _, path, _, _ := runtime.Caller(1) - if !strings.HasSuffix(path, "_templ.go") { - return errors.New("templ: WriteWatchModeString can only be called from _templ.go") - } - txtFilePath := strings.Replace(path, "_templ.go", "_templ.txt", 1) - - literals, err := getWatchedStrings(txtFilePath) - if err != nil { - return fmt.Errorf("templ: failed to cache strings: %w", err) - } - - if lineNum > len(literals) { - return errors.New("templ: failed to find line " + strconv.Itoa(lineNum) + " in " + txtFilePath) - } - - unquoted, err := strconv.Unquote(`"` + literals[lineNum-1] + `"`) - if err != nil { - return err - } - _, err = io.WriteString(w, unquoted) - return err -} - -var ( - watchModeCache = map[string]watchState{} - watchStateMutex sync.Mutex -) - -type watchState struct { - modTime time.Time - strings []string -} - -func getWatchedStrings(txtFilePath string) ([]string, error) { - watchStateMutex.Lock() - defer watchStateMutex.Unlock() - - state, cached := watchModeCache[txtFilePath] - if !cached { - return cacheStrings(txtFilePath) - } - - if time.Since(state.modTime) < time.Millisecond*100 { - return state.strings, nil - } - - info, err := os.Stat(txtFilePath) - if err != nil { - return nil, fmt.Errorf("templ: failed to stat %s: %w", txtFilePath, err) - } - - if !info.ModTime().After(state.modTime) { - return state.strings, nil - } - - return cacheStrings(txtFilePath) -} - -func cacheStrings(txtFilePath string) ([]string, error) { - txtFile, err := os.Open(txtFilePath) - if err != nil { - return nil, fmt.Errorf("templ: failed to open %s: %w", txtFilePath, err) - } - defer txtFile.Close() - - info, err := txtFile.Stat() - if err != nil { - return nil, fmt.Errorf("templ: failed to stat %s: %w", txtFilePath, err) - } - - all, err := io.ReadAll(txtFile) - if err != nil { - return nil, fmt.Errorf("templ: failed to read %s: %w", txtFilePath, err) - } - - literals := strings.Split(string(all), "\n") - watchModeCache[txtFilePath] = watchState{ - modTime: info.ModTime(), - strings: literals, - } - - return literals, nil -} diff --git a/runtime/watchmode.go b/runtime/watchmode.go new file mode 100644 index 000000000..26e3c063c --- /dev/null +++ b/runtime/watchmode.go @@ -0,0 +1,104 @@ +package runtime + +import ( + "errors" + "fmt" + "io" + "os" + "runtime" + "strconv" + "strings" + "sync" + "time" +) + +var developmentMode = os.Getenv("TEMPL_DEV_MODE") == "true" + +// WriteString writes the string to the writer. If development mode is enabled +// s is replaced with the string at the index in the _templ.txt file. +func WriteString(w io.Writer, index int, s string) (err error) { + if developmentMode { + _, path, _, _ := runtime.Caller(1) + if !strings.HasSuffix(path, "_templ.go") { + return errors.New("templ: attempt to use WriteString from a non templ file") + } + txtFilePath := strings.Replace(path, "_templ.go", "_templ.txt", 1) + + literals, err := getWatchedStrings(txtFilePath) + if err != nil { + return fmt.Errorf("templ: failed to cache strings: %w", err) + } + + if index > len(literals) { + return fmt.Errorf("templ: failed to find line %d in %s", index, txtFilePath) + } + + s, err = strconv.Unquote(`"` + literals[index-1] + `"`) + if err != nil { + return err + } + } + _, err = io.WriteString(w, s) + return err +} + +var ( + watchModeCache = map[string]watchState{} + watchStateMutex sync.Mutex +) + +type watchState struct { + modTime time.Time + strings []string +} + +func getWatchedStrings(txtFilePath string) ([]string, error) { + watchStateMutex.Lock() + defer watchStateMutex.Unlock() + + state, cached := watchModeCache[txtFilePath] + if !cached { + return cacheStrings(txtFilePath) + } + + if time.Since(state.modTime) < time.Millisecond*100 { + return state.strings, nil + } + + info, err := os.Stat(txtFilePath) + if err != nil { + return nil, fmt.Errorf("templ: failed to stat %s: %w", txtFilePath, err) + } + + if !info.ModTime().After(state.modTime) { + return state.strings, nil + } + + return cacheStrings(txtFilePath) +} + +func cacheStrings(txtFilePath string) ([]string, error) { + txtFile, err := os.Open(txtFilePath) + if err != nil { + return nil, fmt.Errorf("templ: failed to open %s: %w", txtFilePath, err) + } + defer txtFile.Close() + + info, err := txtFile.Stat() + if err != nil { + return nil, fmt.Errorf("templ: failed to stat %s: %w", txtFilePath, err) + } + + all, err := io.ReadAll(txtFile) + if err != nil { + return nil, fmt.Errorf("templ: failed to read %s: %w", txtFilePath, err) + } + + literals := strings.Split(string(all), "\n") + watchModeCache[txtFilePath] = watchState{ + modTime: info.ModTime(), + strings: literals, + } + + return literals, nil +} diff --git a/turbo/stream_templ.go b/turbo/stream_templ.go index b453b7624..dfca728f2 100644 --- a/turbo/stream_templ.go +++ b/turbo/stream_templ.go @@ -28,7 +28,7 @@ func actionTemplate(action string, target string) templ.Component { templ_7745c5c3_Var1 = templ.NopComponent } ctx = templ.ClearChildren(ctx) - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } @@ -91,7 +91,7 @@ func removeTemplate(action string, target string) templ.Component { templ_7745c5c3_Var4 = templ.NopComponent } ctx = templ.ClearChildren(ctx) - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 7, "\">") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } diff --git a/watchmode.go b/watchmode.go new file mode 100644 index 000000000..1e4df7f88 --- /dev/null +++ b/watchmode.go @@ -0,0 +1,103 @@ +package templ + +import ( + "errors" + "fmt" + "io" + "os" + "runtime" + "strconv" + "strings" + "sync" + "time" +) + +// WriteWatchModeString is used when rendering templates in development mode. +// the generator would have written non-go code to the _templ.txt file, which +// is then read by this function and written to the output. +// +// Deprecated: since templ v0.3.x generated code uses WriteString. +func WriteWatchModeString(w io.Writer, lineNum int) error { + _, path, _, _ := runtime.Caller(1) + if !strings.HasSuffix(path, "_templ.go") { + return errors.New("templ: WriteWatchModeString can only be called from _templ.go") + } + txtFilePath := strings.Replace(path, "_templ.go", "_templ.txt", 1) + + literals, err := getWatchedStrings(txtFilePath) + if err != nil { + return fmt.Errorf("templ: failed to cache strings: %w", err) + } + + if lineNum > len(literals) { + return fmt.Errorf("templ: failed to find line %d in %s", lineNum, txtFilePath) + } + + s, err := strconv.Unquote(`"` + literals[lineNum-1] + `"`) + if err != nil { + return err + } + _, err = io.WriteString(w, s) + return err +} + +var ( + watchModeCache = map[string]watchState{} + watchStateMutex sync.Mutex +) + +type watchState struct { + modTime time.Time + strings []string +} + +func getWatchedStrings(txtFilePath string) ([]string, error) { + watchStateMutex.Lock() + defer watchStateMutex.Unlock() + + state, cached := watchModeCache[txtFilePath] + if !cached { + return cacheStrings(txtFilePath) + } + + if time.Since(state.modTime) < time.Millisecond*100 { + return state.strings, nil + } + + info, err := os.Stat(txtFilePath) + if err != nil { + return nil, fmt.Errorf("templ: failed to stat %s: %w", txtFilePath, err) + } + + if !info.ModTime().After(state.modTime) { + return state.strings, nil + } + + return cacheStrings(txtFilePath) +} + +func cacheStrings(txtFilePath string) ([]string, error) { + txtFile, err := os.Open(txtFilePath) + if err != nil { + return nil, fmt.Errorf("templ: failed to open %s: %w", txtFilePath, err) + } + defer txtFile.Close() + + info, err := txtFile.Stat() + if err != nil { + return nil, fmt.Errorf("templ: failed to stat %s: %w", txtFilePath, err) + } + + all, err := io.ReadAll(txtFile) + if err != nil { + return nil, fmt.Errorf("templ: failed to read %s: %w", txtFilePath, err) + } + + literals := strings.Split(string(all), "\n") + watchModeCache[txtFilePath] = watchState{ + modTime: info.ModTime(), + strings: literals, + } + + return literals, nil +}