Feature/edit stack command (#23)

* add edit feature
* bump version
This commit is contained in:
T.v.Dein
2023-12-04 13:53:18 +01:00
committed by GitHub
parent 416c163d94
commit 252e7eb8d9
4 changed files with 104 additions and 2 deletions

View File

@@ -18,8 +18,12 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
package main
import (
"bufio"
"fmt"
"os"
"os/exec"
"strconv"
"strings"
)
type CommandFunction func(*Calc)
@@ -184,6 +188,102 @@ func (c *Calc) SetCommands() {
}
},
),
"edit": NewCommand(
"edit the stack interactively",
func(c *Calc) {
if c.stack.Len() == 0 {
fmt.Println("empty stack")
return
}
c.stack.Backup()
// put the stack contents into a tmp file
tmp, err := os.CreateTemp("", "stack")
if err != nil {
fmt.Println(err)
return
}
defer os.Remove(tmp.Name())
comment := `# add or remove numbers as you wish.
# each number must be on its own line.
# numbers must be floating point formatted.
`
_, err = tmp.WriteString(comment)
if err != nil {
fmt.Println(err)
return
}
for _, item := range c.stack.All() {
_, err = fmt.Fprintf(tmp, "%f\n", item)
if err != nil {
fmt.Println(err)
return
}
}
tmp.Close()
// determine which editor to use
editor := "vi"
enveditor, present := os.LookupEnv("EDITOR")
if present {
if editor != "" {
if _, err := os.Stat(editor); err == nil {
editor = enveditor
}
}
}
// execute editor with our tmp file containing current stack
cmd := exec.Command(editor, tmp.Name())
cmd.Stdin = os.Stdin
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr
err = cmd.Run()
if err != nil {
fmt.Println("could not run editor command: ", err)
return
}
// read the file back in
modified, err := os.Open(tmp.Name())
if err != nil {
fmt.Println("Error opening file:", err)
return
}
defer modified.Close()
// reset the stack
c.stack.Clear()
// and put the new contents (if legit) back onto the stack
scanner := bufio.NewScanner(modified)
for scanner.Scan() {
line := strings.TrimSpace(c.Comment.ReplaceAllString(scanner.Text(), ""))
if line == "" {
continue
}
num, err := strconv.ParseFloat(line, 64)
if err != nil {
fmt.Printf("%s is not a floating point number!\n", line)
continue
}
c.stack.Push(num)
}
if err := scanner.Err(); err != nil {
fmt.Println("Error reading from file:", err)
}
},
),
}
// general commands