feat: start sops edit on the key's line
CI / Checks (pull_request) Successful in 25s
PR title / Conventional title (pull_request) Successful in 1s

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
kebandClaude Opus 5.5 committed 2026-10-11 00:25:01 +02:00
1 parent c29319b821
commit 10c2362482
3 files changed
+49 -5

No files matched your search

+27 -4
View File
@@ -1,6 +1,7 @@
package app
import (
"cmp"
"errors"
"os"
"os/exec"
@@ -71,6 +72,12 @@ func (m *Model) edit() tea.Cmd {
if f.Sops != "" {
cmd := exec.Command(f.Sops, "edit", f.Path)
cmd.Dir = filepath.Dir(f.Path) // sops looks for .sops.yaml from here
// sops starts SOPS_EDITOR (else EDITOR, else vim) on the decrypted
// copy, which keeps the file's lines: start it on the key.
editor := cmp.Or(m.getenv("SOPS_EDITOR"), m.getenv("EDITOR"), "vim")
if at, ok := editorAtLine(editor, f.Line); ok {
cmd.Env = append(os.Environ(), "SOPS_EDITOR="+at)
}
m.flash = flash{}
return tea.ExecProcess(cmd, finished)
}
@@ -100,6 +107,22 @@ func (m *Model) edit() tea.Cmd {
return nil
}
// plusLine are editors that open at a line with +N before the file.
var plusLine = map[string]bool{
"vi": true, "vim": true, "nvim": true, "nano": true, "emacs": true, "emacsclient": true,
"micro": true, "kak": true, "mg": true, "ne": true, "joe": true, "vis": true,
}
// editorAtLine is editor starting at line, for editors that take +N:
// sops adds the file after it.
func editorAtLine(editor string, line int) (string, bool) {
fields := strings.Fields(editor)
if line == 0 || len(fields) == 0 || !plusLine[filepath.Base(fields[0])] {
return "", false
}
return editor + " +" + strconv.Itoa(line), true
}
// editorArgs opens f at its line, for editors known to take one.
func editorArgs(editor string, f provider.File) []string {
fields := strings.Fields(editor)
@@ -107,12 +130,12 @@ func editorArgs(editor string, f provider.File) []string {
return []string{f.Path}
}
at := f.Path + ":" + strconv.Itoa(f.Line)
switch filepath.Base(fields[0]) {
case "vi", "vim", "nvim", "nano", "emacs", "emacsclient", "micro", "kak", "mg", "ne", "joe", "vis":
switch base := filepath.Base(fields[0]); {
case plusLine[base]:
return []string{"+" + strconv.Itoa(f.Line), f.Path}
case "hx", "helix", "subl", "zed":
case base == "hx" || base == "helix" || base == "subl" || base == "zed":
return []string{at}
case "code", "codium", "cursor", "windsurf":
case base == "code" || base == "codium" || base == "cursor" || base == "windsurf":
return []string{"-g", at}
}
return []string{f.Path}