Giter Club home page Giter Club logo

Comments (11)

a-h avatar a-h commented on August 25, 2024

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.

Screenshot 2023-04-20 at 09 01 06

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.

a-h avatar a-h commented on August 25, 2024

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.

a-h avatar a-h commented on August 25, 2024

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

func (p *Server) DidChange(ctx context.Context, params *lsp.DidChangeTextDocumentParams) (err error) {
p.Log.Info("client -> server: DidChange", zap.Any("params", params))
defer p.Log.Info("client -> server: DidChange end")
isTemplFile, goURI := convertTemplToGoURI(params.TextDocument.URI)
if !isTemplFile {
p.Log.Error("not a templ file")
return
}
// Apply content changes to the cached template.
d, err := p.TemplSource.Apply(string(params.TextDocument.URI), params.ContentChanges)
if err != nil {
p.Log.Error("error applying changes", zap.Error(err))
return
}
// Update the Go code.
p.Log.Info("parsing template")
template, ok, err := p.parseTemplate(ctx, params.TextDocument.URI, d.String())
if err != nil {
p.Log.Error("parseTemplate failure", zap.Error(err))
}
if !ok {
return
}
w := new(strings.Builder)
sm, 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.GoSource[string(params.TextDocument.URI)] = w.String()
// Change the path.
params.TextDocument.URI = goURI
params.TextDocument.TextDocumentIdentifier.URI = goURI
// Overwrite all the Go contents.
params.ContentChanges = []lsp.TextDocumentContentChangeEvent{{
Text: w.String(),
}}
return p.Target.DidChange(ctx, params)
}
logs the input params before doing any modifications to the range, so I think it's correct.

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.

joerdav avatar joerdav commented on August 25, 2024

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.

joerdav avatar joerdav commented on August 25, 2024

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.

joerdav avatar joerdav commented on August 25, 2024

Here's the log file of my most recent example, with fewer random mistakes!
https://gist.github.com/joerdav/be6178059b52ab55cd79098700fdcdab

from templ.

a-h avatar a-h commented on August 25, 2024

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.

a-h avatar a-h commented on August 25, 2024

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.

a-h avatar a-h commented on August 25, 2024

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.

joerdav avatar joerdav commented on August 25, 2024

Ah yep, I'm on luaSnip too so that adds up!

from templ.

a-h avatar a-h commented on August 25, 2024

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)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo 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.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.