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

View File

@@ -30,7 +30,7 @@ import (
lua "github.com/yuin/gopher-lua"
)
const VERSION string = "2.0.10"
const VERSION string = "2.0.11"
const Usage string = `This is rpn, a reverse polish notation calculator cli.

3
rpn.go
View File

@@ -185,7 +185,8 @@ DESCRIPTION
Stack manipulation commands: clear clear the whole stack shift remove
the last element of the stack reverse reverse the stack elements swap
exchange the last two stack elements dup duplicate last stack item undo
undo last operation
undo last operation edit edit the stack interactively using vi or
$EDITOR
Other commands: help|? show this message manual show manual
quit|exit|c-d|c-c exit program

View File

@@ -198,6 +198,7 @@ Stack manipulation commands:
swap exchange the last two stack elements
dup duplicate last stack item
undo undo last operation
edit edit the stack interactively using vi or $EDITOR
Other commands:
help|? show this message