summaryrefslogtreecommitdiff
path: root/internal
diff options
context:
space:
mode:
authorPaul Buetow <paul@buetow.org>2025-08-22 21:14:06 +0300
committerPaul Buetow <paul@buetow.org>2025-08-22 21:14:06 +0300
commit09ec0a091c881789a9ef79dfa47941097077dd05 (patch)
treeed6ccb07a33a80afb2572dec8e34af999082bdd6 /internal
parent0478bd470c523c8a6e07d4fa4f11ca987c38cea9 (diff)
completion: only apply leading indentation for ';;text;' prompts; not for ';text;'
Diffstat (limited to 'internal')
-rw-r--r--internal/lsp/handlers.go36
1 files changed, 36 insertions, 0 deletions
diff --git a/internal/lsp/handlers.go b/internal/lsp/handlers.go
index 8c4fd51..63b32d0 100644
--- a/internal/lsp/handlers.go
+++ b/internal/lsp/handlers.go
@@ -837,6 +837,15 @@ func (s *Server) tryLLMCompletion(p CompletionParams, above, current, below, fun
}
if cleaned != "" { cleaned = stripDuplicateAssignmentPrefix(current[:p.Position.Character], cleaned) }
if cleaned != "" { cleaned = stripDuplicateGeneralPrefix(current[:p.Position.Character], cleaned) }
+ // Preserve the current line's leading indentation only for double-semicolon
+ // inline prompts (";;text;"), since strict ";text;" replacements already
+ // occur in-place without affecting leading indentation.
+ if cleaned != "" && hasDoubleSemicolonTrigger(current) {
+ indent := leadingIndent(current)
+ if indent != "" {
+ cleaned = applyIndent(indent, cleaned)
+ }
+ }
if cleaned == "" {
return nil, false, false
}
@@ -1225,6 +1234,33 @@ func lineHasInlinePrompt(line string) bool {
return hasDoubleSemicolonTrigger(line)
}
+// leadingIndent returns the run of leading spaces/tabs from the provided line.
+func leadingIndent(line string) string {
+ i := 0
+ for i < len(line) {
+ if line[i] == ' ' || line[i] == '\t' {
+ i++
+ continue
+ }
+ break
+ }
+ if i == 0 { return "" }
+ return line[:i]
+}
+
+// applyIndent prefixes each non-empty line of suggestion with the given indent
+// unless it already starts with that indent.
+func applyIndent(indent, suggestion string) string {
+ if indent == "" || suggestion == "" { return suggestion }
+ lines := splitLines(suggestion)
+ for i, ln := range lines {
+ if strings.TrimSpace(ln) == "" { continue }
+ if strings.HasPrefix(ln, indent) { continue }
+ lines[i] = indent + ln
+ }
+ return strings.Join(lines, "\n")
+}
+
// isBareDoubleSemicolon reports whether the line contains a standalone
// double-semicolon marker with no inline content (";;" possibly with only
// whitespace after it). It explicitly excludes the valid form ";;text;".