Comments (11)
Thanks for that.
I can match up the message at 8 seconds, when it says u declared but not used
. This comes from gopls
. templ
"rewrites" it to update the position of the error message to be correct within the templ file (i.e. not the generated Go file that gopls
sees).
{"level":"info","ts":"2023-04-17T14:35:32+01:00","caller":"proxy/client.go:50","msg":"client <- server: PublishDiagnostics"}
{"level":"info","ts":"2023-04-17T14:35:32+01:00","caller":"proxy/client.go:52","msg":"client <- server: PublishDiagnostics: [0]","diagnostic":{"range":{"start":{"line":181,"character":9},"end":{"line":181,"character":10}},"severity":1,"code":"UnusedVar","codeDescription":{"href":"https://pkg.go.dev/golang.org/x/tools/internal/typesinternal?utm_source=gopls#UnusedVar"},"source":"compiler","message":"u declared but not used"}}
{"level":"info","ts":"2023-04-17T14:35:32+01:00","caller":"proxy/client.go:75","msg":"diagnostic [0] rewritten","diagnostic":{"range":{"start":{"line":21,"character":9},"end":{"line":21,"character":10}},"severity":1,"code":"UnusedVar","codeDescription":{"href":"https://pkg.go.dev/golang.org/x/tools/internal/typesinternal?utm_source=gopls#UnusedVar"},"source":"compiler","message":"u declared but not used"}}
{"level":"info","ts":"2023-04-17T14:35:32+01:00","caller":"proxy/client.go:50","msg":"client <- server: PublishDiagnostics"}
I then see the message from the client to the server that a newline was added:
{"level":"info","ts":"2023-04-17T14:35:33+01:00","caller":"proxy/server.go:394","msg":"client -> server: DidChange","params":{"textDocument":{"uri":"file:///Users/joe.davidson/src/joerdav/go-htmx-examples/bulkupdate/templates.templ","version":5},"contentChanges":[{"range":{"start":{"line":22,"character":7},"end":{"line":23,"character":0}},"rangeLength":1,"text":"\n\t\t\t\n"},{"range":{"start":{"line":23,"character":3},"end":{"line":23,"character":3}},"text":"\t"}]}}
Then the <
char:
{"level":"info","ts":"2023-04-17T14:35:33+01:00","caller":"proxy/server.go:394","msg":"client -> server: DidChange","params":{"textDocument":{"uri":"file:///Users/joe.davidson/src/joerdav/go-htmx-examples/bulkupdate/templates.templ","version":6},"contentChanges":[{"range":{"start":{"line":23,"character":4},"end":{"line":23,"character":4}},"text":"<"}]}}
Then the >
char which I think is auto-inserted by the editor:
{"level":"info","ts":"2023-04-17T14:35:35+01:00","caller":"proxy/server.go:394","msg":"client -> server: DidChange","params":{"textDocument":{"uri":"file:///Users/joe.davidson/src/joerdav/go-htmx-examples/bulkupdate/templates.templ","version":7},"contentChanges":[{"range":{"start":{"line":23,"character":5},"end":{"line":23,"character":5}},"text":">"}]}}
The client then deletes a character at line 23, character 5, then inserts an >
and \n\t\t\t\t</
. It's slightly odd that the client passes some pointless changes, but it's OK. This is probably the snippet auto-inserting the end tag.
{
"level": "info",
"ts": "2023-04-17T14:35:35+01:00",
"caller": "proxy/server.go:394",
"msg": "client -> server: DidChange",
"params": {
"textDocument": {
"uri": "file:///Users/joe.davidson/src/joerdav/go-htmx-examples/bulkupdate/templates.templ",
"version": 15
},
"contentChanges": [
{
"range": {
"start": {
"line": 23,
"character": 5
},
"end": {
"line": 23,
"character": 6
}
},
"rangeLength": 1,
"text": ""
},
{
"range": {
"start": {
"line": 23,
"character": 5
},
"end": {
"line": 23,
"character": 5
}
},
"text": ""
},
{
"range": {
"start": {
"line": 23,
"character": 5
},
"end": {
"line": 23,
"character": 5
}
},
"text": ""
},
{
"range": {
"start": {
"line": 23,
"character": 5
},
"end": {
"line": 23,
"character": 5
}
},
"text": ">\n\t\t\t\t\t"
},
{
"range": {
"start": {
"line": 24,
"character": 5
},
"end": {
"line": 24,
"character": 5
}
},
"text": ""
},
{
"range": {
"start": {
"line": 24,
"character": 5
},
"end": {
"line": 24,
"character": 5
}
},
"text": "\n\t\t\t\t</"
},
{
"range": {
"start": {
"line": 25,
"character": 6
},
"end": {
"line": 25,
"character": 6
}
},
"text": ">"
},
{
"range": {
"start": {
"line": 25,
"character": 7
},
"end": {
"line": 25,
"character": 7
}
},
"text": ""
}
]
}
}
Next, you can see the insertion of the t
char:
{
"level": "info",
"ts": "2023-04-17T14:35:36+01:00",
"caller": "proxy/server.go:394",
"msg": "client -> server: DidChange",
"params": {
"textDocument": {
"uri": "file:///Users/joe.davidson/src/joerdav/go-htmx-examples/bulkupdate/templates.templ",
"version": 16
},
"contentChanges": [
{
"range": {
"start": {
"line": 23,
"character": 5
},
"end": {
"line": 23,
"character": 5
}
},
"text": "t"
}
]
}
}
The insertion of the d
character is basically the same, then the snippet inserts td
in the end tag space:
{"level":"info","ts":"2023-04-17T14:35:38+01:00","caller":"proxy/server.go:394","msg":"client -> server: DidChange","params":{"textDocument":{"uri":"file:///Users/joe.davidson/src/joerdav/go-htmx-examples/bulkupdate/templates.templ","version":18},"contentChanges":[{"range":{"start":{"line":25,"character":6},"end":{"line":25,"character":6}},"text":"td"}]}}
The client then formats everything.
{"level":"info","ts":"2023-04-17T14:35:42+01:00","caller":"proxy/server.go:394","msg":"client -> server: DidChange","params":{"textDocument":{"uri":"file:///Users/joe.davidson/src/joerdav/go-htmx-examples/bulkupdate/templates.templ","version":19},"contentChanges":[{"range":{"start":{"line":25,"character":9},"end":{"line":26,"character":0}},"rangeLength":1,"text":"\n\t\t\t\t<td>\n\t\t\t\t\t\n\t\t\t\t</td>\n"}]}}
A few seconds later (16 secs in the video), the yanked <td></td>
pair gets pasted into line 26:
{"level":"info","ts":"2023-04-17T14:35:42+01:00","caller":"proxy/server.go:394","msg":"client -> server: DidChange","params":{"textDocument":{"uri":"file:///Users/joe.davidson/src/joerdav/go-htmx-examples/bulkupdate/templates.templ","version":20},"contentChanges":[{"range":{"start":{"line":26,"character":8},"end":{"line":27,"character":0}},"rangeLength":1,"text":"\n\t\t\t\t<td>\n\t\t\t\t\t\n\t\t\t\t</td>\n"}]}}
It then looks like you pasted it again by accident, then did undo. In the LSP, this is shown as a delete of 25 chars:
{
"level": "info",
"ts": "2023-04-17T14:35:43+01:00",
"caller": "proxy/server.go:394",
"msg": "client -> server: DidChange",
"params": {
"textDocument": {
"uri": "file:///Users/joe.davidson/src/joerdav/go-htmx-examples/bulkupdate/templates.templ",
"version": 21
},
"contentChanges": [
{
"range": {
"start": {
"line": 27,
"character": 0
},
"end": {
"line": 30,
"character": 0
}
},
"rangeLength": 25,
"text": ""
}
]
}
}
There's some formatting... then you type P{
at 23 secs:
{"level":"info","ts":"2023-04-17T14:35:49+01:00","caller":"proxy/server.go:394","msg":"client -> server: DidChange","params":{"textDocument":{"uri":"file:///Users/joe.davidson/src/joerdav/go-htmx-examples/bulkupdate/templates.templ","version":28},"contentChanges":[{"range":{"start":{"line":27,"character":5},"end":{"line":27,"character":5}},"text":"P"}]}}
{"level":"info","ts":"2023-04-17T14:35:49+01:00","caller":"proxy/server.go:394","msg":"client -> server: DidChange","params":{"textDocument":{"uri":"file:///Users/joe.davidson/src/joerdav/go-htmx-examples/bulkupdate/templates.templ","version":29},"contentChanges":[{"range":{"start":{"line":27,"character":6},"end":{"line":27,"character":6}},"text":"{"}]}}
This triggers autocompletion, but you're not in a known Go code bit of the template, so templ can't map from the Go code position back to templ (normal behaviour), so it's ignored.
You get rid of the P{
and start again with {
.
Then hit { u
at 25 seconds:
{"level":"info","ts":"2023-04-17T14:35:51+01:00","caller":"proxy/server.go:394","msg":"client -> server: DidChange","params":{"textDocument":{"uri":"file:///Users/joe.davidson/src/joerdav/go-htmx-examples/bulkupdate/templates.templ","version":33},"contentChanges":[{"range":{"start":{"line":27,"character":6},"end":{"line":27,"character":6}},"text":"u"}]}}
Followed by the period:
{"level":"info","ts":"2023-04-17T14:35:51+01:00","caller":"proxy/server.go:394","msg":"client -> server: DidChange","params":{"textDocument":{"uri":"file:///Users/joe.davidson/src/joerdav/go-htmx-examples/bulkupdate/templates.templ","version":34},"contentChanges":[{"range":{"start":{"line":27,"character":7},"end":{"line":27,"character":7}},"text":"."}]}}
Then, the n
, followed by a
:
{"level":"info","ts":"2023-04-17T14:35:52+01:00","caller":"proxy/server.go:394","msg":"client -> server: DidChange","params":{"textDocument":{"uri":"file:///Users/joe.davidson/src/joerdav/go-htmx-examples/bulkupdate/templates.templ","version":36},"contentChanges":[{"range":{"start":{"line":27,"character":9},"end":{"line":27,"character":9}},"text":"a"}]}}
At this point, this is what's in the editor.
I can't see what was in templ's understanding of the file (you can see that via the web view), but it's probably OK. We're working on line index 27, which is shown as line 28 in the editor.
Next, you can see the deletion of the a
:
{"level":"info","ts":"2023-04-17T14:35:53+01:00","caller":"proxy/server.go:394","msg":"client -> server: DidChange","params":{"textDocument":{"uri":"file:///Users/joe.davidson/src/joerdav/go-htmx-examples/bulkupdate/templates.templ","version":37},"contentChanges":[{"range":{"start":{"line":27,"character":9},"end":{"line":27,"character":10}},"rangeLength":1,"text":""}]}}
Followed by the deletion of the n
:
{"level":"info","ts":"2023-04-17T14:35:53+01:00","caller":"proxy/server.go:394","msg":"client -> server: DidChange","params":{"textDocument":{"uri":"file:///Users/joe.davidson/src/joerdav/go-htmx-examples/bulkupdate/templates.templ","version":38},"contentChanges":[{"range":{"start":{"line":27,"character":8},"end":{"line":27,"character":9}},"rangeLength":1,"text":""}]}}
Period:
{"level":"info","ts":"2023-04-17T14:35:53+01:00","caller":"proxy/server.go:394","msg":"client -> server: DidChange","params":{"textDocument":{"uri":"file:///Users/joe.davidson/src/joerdav/go-htmx-examples/bulkupdate/templates.templ","version":39},"contentChanges":[{"range":{"start":{"line":27,"character":7},"end":{"line":27,"character":8}},"rangeLength":1,"text":""}]}}
Deletion of the u
:
{"level":"info","ts":"2023-04-17T14:35:54+01:00","caller":"proxy/server.go:394","msg":"client -> server: DidChange","params":{"textDocument":{"uri":"file:///Users/joe.davidson/src/joerdav/go-htmx-examples/bulkupdate/templates.templ","version":40},"contentChanges":[{"range":{"start":{"line":27,"character":6},"end":{"line":27,"character":7}},"rangeLength":1,"text":""}]}}
Deletion of char 6, which is the brace.
{"level":"info","ts":"2023-04-17T14:35:54+01:00","caller":"proxy/server.go:394","msg":"client -> server: DidChange","params":{"textDocument":{"uri":"file:///Users/joe.davidson/src/joerdav/go-htmx-examples/bulkupdate/templates.templ","version":41},"contentChanges":[{"range":{"start":{"line":27,"character":5},"end":{"line":27,"character":6}},"rangeLength":1,"text":""}]}}
Then the whole of that line (to clear out the whitespace).
{"level":"info","ts":"2023-04-17T14:35:54+01:00","caller":"proxy/server.go:394","msg":"client -> server: DidChange","params":{"textDocument":{"uri":"file:///Users/joe.davidson/src/joerdav/go-htmx-examples/bulkupdate/templates.templ","version":42},"contentChanges":[{"range":{"start":{"line":27,"character":0},"end":{"line":28,"character":0}},"rangeLength":6,"text":""}]}}
When you save the file, the client rewrites everything from the end of the import statement.
{"level":"info","ts":"2023-04-17T14:35:55+01:00","caller":"proxy/server.go:505","msg":"client -> server: DidSave"}
{
"level": "info",
"ts": "2023-04-17T14:35:55+01:00",
"caller": "proxy/server.go:394",
"msg": "client -> server: DidChange",
"params": {
"textDocument": {
"uri": "file:///Users/joe.davidson/src/joerdav/go-htmx-examples/bulkupdate/templates.templ",
"version": 44
},
"contentChanges": [
{
"range": {
"start": {
"line": 0,
"character": 18
},
"end": {
"line": 53,
"character": 0
}
},
"rangeLength": 1078,
"text": "\n\nimport \"examples/shared\"\n\ntempl demo(users map[int]user) {\n\t<h3 class=\"subtitle\">Select Rows And Activate Or Deactivate Below</h3>\n\t<table class=\"table\">\n\t\t<thead>\n\t\t\t<tr>\n\t\t\t\t<td></td>\n\t\t\t\t<td>Name</td>\n\t\t\t\t<td>Email</td>\n\t\t\t\t<td>Status</td>\n\t\t\t</tr>\n\t\t</thead>\n\t\t@tbody(users)\n\t</table>\n}\n\ntempl tbody(users map[int]user) {\n\t<tbody id=\"tbody\">\n\t\tfor _, u := range users {\n\t\t\t<tr>\n\t\t\t\t<td></td>\n\t\t\t\t<td></td>\n\t\t\t\t<td></td>\n\t\t\t\t<td></td>\n\t\t\t</tr>\n\t\t}\n\t</tbody>\n}\n\ntempl Index(users map[int]user) {\n\[email protected](\"Bulk Update\") {\n\t\t<h2 class=\"title\">Bulk Update</h2>\n\t\t<p>This demo shows how to implement a common pattern where rows are selected and then bulk updated. This is accomplished by putting a form around a table, with checkboxes in the table, and then including the checked values in <code>PUT</code>’s to two different endpoints: <code>activate</code>and <code>deactivate</code>:</p>\n\t\t<pre><code class=\"language-html\">\n\[email protected]() {\n\t\t@demo(users)\n\t}\n</code></pre>\n\t\t<h2 class=\"title\">Demo</h2>\n\t\t@demo(users)\n\t}\n}\n"
}
]
}
}
The content looks OK.
import "examples/shared"
templ demo(users map[int]user) {
<h3 class="subtitle">Select Rows And Activate Or Deactivate Below</h3>
<table class="table">
<thead>
<tr>
<td></td>
<td>Name</td>
<td>Email</td>
<td>Status</td>
</tr>
</thead>
@tbody(users)
</table>
}
templ tbody(users map[int]user) {
<tbody id="tbody">
for _, u := range users {
<tr>
<td></td>
<td></td>
<td></td>
<td></td>
</tr>
}
</tbody>
}
templ Index(users map[int]user) {
@shared.Layout("Bulk Update") {
<h2 class="title">Bulk Update</h2>
<p>This demo shows how to implement a common pattern where rows are selected and then bulk updated. This is accomplished by putting a form around a table, with checkboxes in the table, and then including the checked values in <code>PUT</code>’s to two different endpoints: <code>activate</code>and <code>deactivate</code>:</p>
<pre><code class="language-html">
@shared.Raw() {
@demo(users)
}
</code></pre>
<h2 class="title">Demo</h2>
@demo(users)
}
}
from templ.
We see u
get inserted at 31 seconds:
{"level":"info","ts":"2023-04-17T14:35:57+01:00","caller":"proxy/server.go:394","msg":"client -> server: DidChange","params":{"textDocument":{"uri":"file:///Users/joe.davidson/src/joerdav/go-htmx-examples/bulkupdate/templates.templ","version":46},"contentChanges":[{"range":{"start":{"line":24,"character":8},"end":{"line":24,"character":8}},"text":"u"}]}}
Then get deleted.
{"level":"info","ts":"2023-04-17T14:35:58+01:00","caller":"proxy/server.go:394","msg":"client -> server: DidChange","params":{"textDocument":{"uri":"file:///Users/joe.davidson/src/joerdav/go-htmx-examples/bulkupdate/templates.templ","version":47},"contentChanges":[{"range":{"start":{"line":24,"character":8},"end":{"line":24,"character":9}},"rangeLength":1,"text":""}]}}
Then the open brace and close brace get inserted.
{"level":"info","ts":"2023-04-17T14:35:58+01:00","caller":"proxy/server.go:394","msg":"client -> server: DidChange","params":{"textDocument":{"uri":"file:///Users/joe.davidson/src/joerdav/go-htmx-examples/bulkupdate/templates.templ","version":48},"contentChanges":[{"range":{"start":{"line":24,"character":8},"end":{"line":24,"character":8}},"text":"{"}]}}
{"level":"info","ts":"2023-04-17T14:35:59+01:00","caller":"proxy/server.go:394","msg":"client -> server: DidChange","params":{"textDocument":{"uri":"file:///Users/joe.davidson/src/joerdav/go-htmx-examples/bulkupdate/templates.templ","version":49},"contentChanges":[{"range":{"start":{"line":24,"character":9},"end":{"line":24,"character":9}},"text":"}"}]}}
At this point, whatever was in the Go code wasn't liked. Perhaps if there's empty braces, it results in a syntax error in the generated Go code. I expect the generator could be improved to simply ignore empty braces.
{"level":"info","ts":"2023-04-17T14:35:59+01:00","caller":"proxy/client.go:50","msg":"client <- server: PublishDiagnostics"}
{"level":"info","ts":"2023-04-17T14:35:59+01:00","caller":"proxy/client.go:52","msg":"client <- server: PublishDiagnostics: [0]","diagnostic":{"range":{"start":{"line":203,"character":10},"end":{"line":203,"character":10}},"severity":1,"source":"syntax","message":"expected '==', found '='"}}
Next, u
and .
are added (33 seconds), and this triggers completion. Chopping out the irrelevant lines, you can see it's working fine and returns 3 items.
{"level":"info","ts":"2023-04-17T14:36:00+01:00","caller":"proxy/server.go:309","msg":"client -> server: Completion"}
{"level":"info","ts":"2023-04-17T14:36:00+01:00","caller":"proxy/server.go:70","msg":"updatePosition: found","uri":"file:///Users/joe.davidson/src/joerdav/go-htmx-examples/bulkupdate/templates.templ","fromTempl":"24:11","toGo":"202:24"}
{"level":"info","ts":"2023-04-17T14:36:00+01:00","caller":"proxy/server.go:330","msg":"completion: received items","count":3}
{"level":"info","ts":"2023-04-17T14:36:00+01:00","caller":"proxy/server.go:338","msg":"client -> server: Completion end"}
Next, we see n
being added, presumably with a view to select name
from the list.
{"level":"info","ts":"2023-04-17T14:36:01+01:00","caller":"proxy/server.go:394","msg":"client -> server: DidChange","params":{"textDocument":{"uri":"file:///Users/joe.davidson/src/joerdav/go-htmx-examples/bulkupdate/templates.templ","version":52},"contentChanges":[{"range":{"start":{"line":24,"character":11},"end":{"line":24,"character":11}},"text":"n"}]}}
A diagnostic comes back, because there's no field called n
.
{"level":"info","ts":"2023-04-17T14:36:01+01:00","caller":"proxy/client.go:52","msg":"client <- server: PublishDiagnostics: [0]","diagnostic":{"range":{"start":{"line":202,"character":24},"end":{"line":202,"character":25}},"severity":1,"code":"MissingFieldOrMethod","codeDescription":{"href":"https://pkg.go.dev/golang.org/x/tools/internal/typesinternal?utm_source=gopls#MissingFieldOrMethod"},"source":"compiler","message":"u.n undefined (type user has no field or method n)"}}
Then we see the selection get made. The Neovim client does something a bit weird! It writes it character at a time (a
, m
, e
), then deletes it, then inserts name
{
"level": "info",
"ts": "2023-04-17T14:36:01+01:00",
"caller": "proxy/server.go:394",
"msg": "client -> server: DidChange",
"params": {
"textDocument": {
"uri": "file:///Users/joe.davidson/src/joerdav/go-htmx-examples/bulkupdate/templates.templ",
"version": 57
},
"contentChanges": [
{
"range": {
"start": {
"line": 24,
"character": 12
},
"end": {
"line": 24,
"character": 12
}
},
"text": "a"
},
{
"range": {
"start": {
"line": 24,
"character": 13
},
"end": {
"line": 24,
"character": 13
}
},
"text": "m"
},
{
"range": {
"start": {
"line": 24,
"character": 14
},
"end": {
"line": 24,
"character": 14
}
},
"text": "e"
},
{
"range": {
"start": {
"line": 24,
"character": 11
},
"end": {
"line": 24,
"character": 15
}
},
"rangeLength": 4,
"text": ""
},
{
"range": {
"start": {
"line": 24,
"character": 11
},
"end": {
"line": 24,
"character": 11
}
},
"text": "name"
}
]
}
}
from templ.
The client then does something very weird. It inserts a copy of everything at line index 0, col index 18.
{
"level": "info",
"ts": "2023-04-17T14:36:01+01:00",
"caller": "proxy/server.go:394",
"msg": "client -> server: DidChange",
"params": {
"textDocument": {
"uri": "file:///Users/joe.davidson/src/joerdav/go-htmx-examples/bulkupdate/templates.templ",
"version": 58
},
"contentChanges": [
{
"range": {
"start": {
"line": 0,
"character": 18
},
"end": {
"line": 0,
"character": 18
}
},
"text": "\n\n\t\t\t\timport \"examples/shared\"\n\n\t\t\t\ttempl demo(users map[int]user) {\n\t\t\t\t\t<h3 class=\"subtitle\">Select Rows And Activate Or Deactivate Below</h3>\n\t\t\t\t\t<table class=\"table\">\n\t\t\t\t\t\t<thead>\n\t\t\t\t\t\t\t<tr>\n\t\t\t\t\t\t\t\t<td></td>\n\t\t\t\t\t\t\t\t<td>Name</td>\n\t\t\t\t\t\t\t\t<td>Email</td>\n\t\t\t\t\t\t\t\t<td>Status</td>\n\t\t\t\t\t\t\t</tr>\n\t\t\t\t\t\t</thead>\n\t\t\t\t\t\t@tbody(users)\n\t\t\t\t\t</table>\n\t\t\t\t}\n\n\t\t\t\ttempl tbody(users map[int]user) {\n\t\t\t\t\t<tbody id=\"tbody\">\n\t\t\t\t\t\tfor _, u := range users {\n\t\t\t\t\t\t\t<tr>\n\t\t\t\t\t\t\t\t<td></td>\n\t\t\t\t\t\t\t\t<td>{u.name}</td>\n\t\t\t\t\t\t\t\t<td></td>\n\t\t\t\t\t\t\t\t<td></td>\n\t\t\t\t\t\t\t</tr>\n\t\t\t\t\t\t}\n\t\t\t\t\t</tbody>\n\t\t\t\t}\n\n\t\t\t\ttempl Index(users map[int]user) {\n\t\t\t\t\[email protected](\"Bulk Update\") {\n\t\t\t\t\t\t<h2 class=\"title\">Bulk Update</h2>\n\t\t\t\t\t\t<p>This demo shows how to implement a common pattern where rows are selected and then bulk updated. This is accomplished by putting a form around a table, with checkboxes in the table, and then including the checked values in <code>PUT</code>’s to two different endpoints: <code>activate</code>and <code>deactivate</code>:</p>\n\t\t\t\t\t\t<pre><code class=\"language-html\">\n\t\t\t\t\[email protected]() {\n\t\t\t\t\t\t@demo(users)\n\t\t\t\t\t}\n\t\t\t\t</code></pre>\n\t\t\t\t\t\t<h2 class=\"title\">Demo</h2>\n\t\t\t\t\t\t@demo(users)\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tpackage bulkupdate"
}
]
}
}
That's clearly the wrong thing for the client to do, since it's doing an insert instead of an overwrite. I'd want to check that it's definitely the LSP client that's doing the wrong thing, but the code that handles this process at
templ/cmd/templ/lspcmd/proxy/server.go
Lines 393 to 434 in 6f8e254
Definitely worth checking what the templ LSP web view thinks it has internally, to check that it's the same as what you're seeing in your editor.
from templ.
Awesome thanks for the breakdown of that! I'll gather some more evidence, and try avoid making mistakes in the recording, to save some time!
from templ.
Interestingly this stops happening when I disable my format on save plugin. Maybe rather than the lsp this is related to templ fmt (or my usage of it). Or at the very least it's related to templ lsp not playing well with formatters.
from templ.
Here's the log file of my most recent example, with fewer random mistakes!
https://gist.github.com/joerdav/be6178059b52ab55cd79098700fdcdab
from templ.
To help debug this (and other LSP related issues), I've started creating a Nix flake in the root of the project that includes all of the development dependencies (Go, gopls, xc etc.) and sets up a Neovim environment with the LSP configuration all included.
You can use it with xc nix-develop
, which runs nix develop --impure
if you have Nix installed, or you can use the Docker build script to build it inside a Docker container (xc docker-build
) which uses the Nix Docker image and builds all the Nix stuff inside there.
Docker is useful to make sure that none of your system's existing programs are being used. It's relatively slow (2 mins) to build a Docker container from my Mac using Docker and Nix, because it rebuilds all of the Nix stuff from scratch each run. I need to set up a Linux remote builder at some point, then I can generate a Docker image directly from Nix itself.
Then you can use the Docker image in your examples directory to test.
docker run -it --rm -v `pwd`:/go-htmx-examples templ:latest
At the moment, the LSP config was borrowed from my personal configuration, so it's a bit heavyweight. I've been cutting it down.
The branch is here:
https://github.com/a-h/templ/tree/neovim_docker
from templ.
To rule out issues with the plugins, I've updated everything to the latest version, and also upgraded to Neovim 0.9.0 in the Docker container to make sure that it's not an issue with Neovim 0.8.0.
from templ.
Looks like the problem is with Luasnip, or cmp-luasnip. I ripped everything out except the bare minimum LSP config and it was still a problem, so I swapped out to vsnip and... the problems went away.
There's a config here, with a Docker build etc.
https://github.com/a-h/templ/tree/minimal_neovim
You need to use :set filetype = templ
to get the LSP to take effect (I ripped out everything I could!).
from templ.
Ah yep, I'm on luaSnip too so that adds up!
from templ.
Going to close this, I don't think there's a clear issue or reproduction. Feel free to re-open though.
from templ.
Related Issues (20)
- Templ config for passsing additional variables to component HOT 1
- Proxy not ready, retrying infinitely HOT 2
- Improved dev flow HOT 1
- Proposal: Introduce JsGenericVar for Event and Element Access in element event handlers HOT 5
- `templ generate` takes a long time for unformatted files HOT 6
- `templ generate` doesn't work if pwd is a symlink HOT 3
- Templ formatting breaks imports at v0.2.747 HOT 7
- Composable templates do not render properly in tests HOT 1
- App freeze using air proxy HOT 1
- templ-vscode "Request textDocument/codeAction failed" HOT 2
- Streaming Not Working
- [Proposal] Improve embedding components HOT 2
- proposal: Go comments within HTML tags HOT 1
- Raw go errors if block ends with a comment
- LSP crashes after being started by kakoune-lsp HOT 4
- How to prevent cache HOT 1
- .templ file with only script elements leads to unused import HOT 1
- Anyway to instantiate a templ once per rendering context? HOT 4
- performance: templ parse takes a long time and uses high CPU when unclosed void elements are used HOT 8
- Little typo in streaming documentation
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from templ.