Skip to content

Commit 6ad0719

Browse files
authored
fix: preserve trailing blank lines when adding SSH config fields (#66)
1 parent 1c21618 commit 6ad0719

File tree

1 file changed

+45
-6
lines changed
  • internal/adapters/data/ssh_config_file

1 file changed

+45
-6
lines changed

internal/adapters/data/ssh_config_file/crud.go

Lines changed: 45 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,6 @@ func (r *Repository) createHostFromServer(server domain.Server) *ssh_config.Host
9898
{Str: server.Alias},
9999
},
100100
Nodes: make([]ssh_config.Node, 0),
101-
LeadingSpace: 4,
102101
EOLComment: "Added by lazyssh",
103102
SpaceBeforeComment: strings.Repeat(" ", 4),
104103
}
@@ -200,7 +199,49 @@ func (r *Repository) addKVNodeIfNotEmpty(host *ssh_config.Host, key, value strin
200199
Value: value,
201200
LeadingSpace: 4,
202201
}
203-
host.Nodes = append(host.Nodes, kvNode)
202+
r.insertKVNodeAfterLastKV(host, kvNode)
203+
}
204+
205+
// insertKVNodeAfterLastKV inserts a KV node immediately after the last existing KV node in the host.
206+
// This preserves any trailing non-KV nodes (blank lines, comments) that may exist after the host's
207+
// configuration block, preventing formatting shifts when adding new fields to a host entry.
208+
//
209+
// Example: If a host block has trailing blank lines separating it from the next host entry,
210+
// this function ensures new fields are inserted before those blank lines, maintaining the
211+
// visual separation between host blocks.
212+
func (r *Repository) insertKVNodeAfterLastKV(host *ssh_config.Host, kvNode *ssh_config.KV) {
213+
// STEP 1: Find the last KV node (search backwards)
214+
lastKVIndex := -1
215+
for i := len(host.Nodes) - 1; i >= 0; i-- {
216+
if _, ok := host.Nodes[i].(*ssh_config.KV); ok {
217+
lastKVIndex = i
218+
break
219+
}
220+
}
221+
222+
// STEP 2: Handle case where no KV nodes exist
223+
if lastKVIndex == -1 {
224+
if len(host.Nodes) == 0 {
225+
// Case A: Empty host - just append
226+
host.Nodes = append(host.Nodes, kvNode)
227+
} else {
228+
// Case B: Only comments/blanks exist - prepend before them
229+
host.Nodes = append([]ssh_config.Node{kvNode}, host.Nodes...)
230+
}
231+
return
232+
}
233+
234+
// STEP 3: We found KV nodes - insert after the last one
235+
insertAt := lastKVIndex + 1
236+
237+
if insertAt == len(host.Nodes) {
238+
// Case C: Last KV is at the end - just append
239+
host.Nodes = append(host.Nodes, kvNode)
240+
return
241+
}
242+
243+
// Case D: Last KV has trailing nodes (blanks/comments) - insert between them
244+
host.Nodes = append(host.Nodes[:insertAt], append([]ssh_config.Node{kvNode}, host.Nodes[insertAt:]...)...)
204245
}
205246

206247
// removeNodesByKey removes all nodes with the specified key from the nodes slice
@@ -337,12 +378,10 @@ func (r *Repository) updateHostNodes(host *ssh_config.Host, newServer domain.Ser
337378

338379
// updateOrAddKVNode updates an existing key-value node or adds a new one if it doesn't exist.
339380
func (r *Repository) updateOrAddKVNode(host *ssh_config.Host, key, newValue string) {
340-
keyLower := strings.ToLower(key)
341-
342381
// Try to update existing node
343382
for _, node := range host.Nodes {
344383
kvNode, ok := node.(*ssh_config.KV)
345-
if ok && strings.EqualFold(kvNode.Key, keyLower) {
384+
if ok && strings.EqualFold(kvNode.Key, key) {
346385
kvNode.Value = newValue
347386
return
348387
}
@@ -354,7 +393,7 @@ func (r *Repository) updateOrAddKVNode(host *ssh_config.Host, key, newValue stri
354393
Value: newValue,
355394
LeadingSpace: 4,
356395
}
357-
host.Nodes = append(host.Nodes, kvNode)
396+
r.insertKVNodeAfterLastKV(host, kvNode)
358397
}
359398

360399
// removeKVNode removes a key-value node from the host if it exists.

0 commit comments

Comments
 (0)