cat / 012
clone

a spreadsheet for the terminal: lotus 1-2-3 looks, google sheets keys and formulas, one go binary

Route :w and :e through the File menu's save, open and download paths

Dami committed 6f25f2b
Save as, Open and Download's prompts and the command line now share
saveAsFile, openFile and downloadFile, so files are resolved, checked
and replaced one way whichever reached them.
commit
6f25f2ba07950e4efe8e89fc1c1ef2deda6e887d
parent
af4eda8871d0d584342d0bfd8e11584dfdbe0608
author
Dami <dami.etoile@gmail.com>
4 files changed, +55 -52
Mdocs/keys.md2+-
Minternal/ui/cmdline.go46++++++++++++------------------
Minternal/ui/download.go34+++++++++++++---------
Minternal/ui/file.go25++++++++++------
M docs/keys.md +1 -1
M internal/ui/cmdline.go +18 -28
@@ -2,7 +2,6 @@ package ui
22 33 import (44 "cmp"5- "path/filepath"65 "slices"76 "strconv"87 "strings"
@@ -181,7 +180,7 @@ func (m *Model) runCmdLine(text string) (tea.Cmd, bool) {
181180 bang := strings.HasSuffix(word, "!")182181 switch strings.TrimSuffix(word, "!") {183182 case "w":184- return m.writeTo(arg, bang), true183+ return m.writeTo(arg), true185184 case "q":186185 if bang {187186 return m.exit(), true
@@ -192,7 +191,7 @@ func (m *Model) runCmdLine(text string) (tea.Cmd, bool) {
192191 return m.exit(), true193192 }194193 m.quitAfterSave = true195- return m.writeTo(arg, bang), true194+ return m.writeTo(arg), true196195 case "e":197196 return m.editFile(arg, bang), true198197 }
@@ -231,31 +230,25 @@ func commandNamed(text string) (string, bool) {
231230 return "", false232231 }233232 234-// writeTo is :w. Without a name it saves; with one it saves under that235-// name, or downloads when the name is another format's (:w out.csv).236-// An existing file is replaced only after asking, or with :w!.237-func (m *Model) writeTo(name string, force bool) tea.Cmd {233+// writeTo is :w. Without a name it saves, as File > Save; with one it234+// saves as that name, as File > Save as, or downloads when the name is235+// another format's (:w out.csv), as File > Download. It goes the menus'236+// ways, so files are named, checked and replaced the same.237+func (m *Model) writeTo(name string) tea.Cmd {238238 if name == "" {239239 return m.runCommand("file.save")240240 }241- if k, ok := fileio.KindOf(name); ok {242- if !k.CanExport() {243- m.quitAfterSave = false244- m.fail("012 can't write " + k.String() + " files")245- return nil246- }247- if k.HasTables() {248- m.openTableName(name, k, sheet.Rect{})249- return nil250- }251- return m.confirmReplace(filepath.Base(name)+" exists.", func(m *Model) tea.Cmd {252- return m.download(name, k, sheet.Rect{}, "")253- }, exists(name) && !force)241+ k, ok := fileio.KindOf(name)242+ switch {243+ case !ok:244+ return m.saveAsFile(name)245+ case !k.CanExport():246+ m.quitAfterSave = false247+ m.fail("012 can't write " + k.String() + " files")248+ return nil254249 }255- name = withExt(name)256- return m.confirmReplace(filepath.Base(name)+" exists.", func(m *Model) tea.Cmd {257- return saveCmd(m.sheet, name)258- }, exists(name) && !force && name != m.filename)250+ m.quitAfterSave = false // a download isn't the sheet's file251+ return m.downloadFile(k, sheet.Rect{}, name)259252 }260253 261254 // editFile is :e name: open a sheet or import a file, refusing to drop
@@ -268,10 +261,7 @@ func (m *Model) editFile(name string, force bool) tea.Cmd {
268261 m.fail("Unsaved changes: :w saves them, :e! " + name + " discards them")269262 return nil270263 }271- if _, ok := fileio.KindOf(name); ok {272- return m.confirmImport(name, fileio.Options{})273- }274- return loadCmd(withExt(name))264+ return m.openFile(name)275265 }276266 277267 func (c *cmdLine) contextLine(m *Model) (string, string) {
M internal/ui/download.go +20 -14
M internal/ui/file.go +16 -9