Thanks to visit codestin.com
Credit goes to github.com

Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 3 additions & 20 deletions oviewer/action.go
Original file line number Diff line number Diff line change
Expand Up @@ -409,18 +409,15 @@ func (root *Root) subShell(shell string) error {
if shell == "" {
shell = getShell()
}

stdin := os.Stdin
if !term.IsTerminal(int(os.Stdin.Fd())) {
// Use TTY as stdin when the current stdin is not a terminal.
tty, err := getTty()
if !term.IsTerminal(int(stdin.Fd())) {
tty, err := getTTY()
if err != nil {
return fmt.Errorf("failed to open tty: %w", err)
return fmt.Errorf("failed to get stdin: %w", err)
}
defer tty.Close()
stdin = tty
}

c := exec.Command(shell, "-l")
c.Stdin = stdin
c.Stdout = os.Stdout
Expand All @@ -432,20 +429,6 @@ func (root *Root) subShell(shell string) error {
return nil
}

func getShell() string {
if runtime.GOOS == "windows" {
return "CMD.EXE"
}
return "/bin/sh"
}

func getTty() (*os.File, error) {
if runtime.GOOS == "windows" {
return os.Open("CONIN$")
}
return os.Open("/dev/tty")
}

// setViewMode switches to the preset display mode.
func (root *Root) setViewMode(ctx context.Context, modeName string) {
if modeName == "" {
Expand Down
14 changes: 13 additions & 1 deletion oviewer/document.go
Original file line number Diff line number Diff line change
Expand Up @@ -422,6 +422,18 @@ func (m *Document) CurrentLN() int {

// Export exports the document in the specified range.
func (m *Document) Export(w io.Writer, start int, end int) error {
return m.export(w, start, end, m.store.export)
}

// ExportPlain exports the document in the specified range without ANSI escape sequences.
func (m *Document) ExportPlain(w io.Writer, start int, end int) error {
return m.export(w, start, end, m.store.exportPlain)
}

// storeExportFunc is a function type for exporting lines from a chunk.
type storeExportFunc func(w io.Writer, chunk *chunk, start int, end int) error

func (m *Document) export(w io.Writer, start int, end int, exportFunc storeExportFunc) error {
end = min(end, m.BufEndNum()-1)
startChunk, startCn := chunkLineNum(start)
endChunk, endCn := chunkLineNum(end)
Expand All @@ -433,7 +445,7 @@ func (m *Document) Export(w io.Writer, start int, end int) error {
ecn = endCn + 1
}
chunk := m.store.chunks[chunkNum]
if err := m.store.export(w, chunk, scn, ecn); err != nil {
if err := exportFunc(w, chunk, scn, ecn); err != nil {
return err
}
scn = 0
Expand Down
39 changes: 31 additions & 8 deletions oviewer/edit.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import (
"strings"

"github.com/google/shlex"
"golang.org/x/term"
)

// DefaultEditor is the fallback editor to use if no other editor is specified.
Expand All @@ -18,8 +19,11 @@ const DefaultEditor = "vim +%d %f"
// edit suspends the current screen display and runs the edit.
// It will return when you exit the edit.
func (root *Root) edit(context.Context) {
isTemp := !root.Doc.seekable
fileName := root.Doc.FileName
isTemp := false
if root.Doc.PlainMode || !root.Doc.seekable {
isTemp = true
}

if isTemp {
var err error
Expand All @@ -30,6 +34,18 @@ func (root *Root) edit(context.Context) {
}
}

stdin := os.Stdin
if !term.IsTerminal(int(stdin.Fd())) {
tty, err := getTTY()
if err != nil {
err = fmt.Errorf("failed to open tty: %w", err)
root.setMessageLog(err.Error())
return
}
defer tty.Close()
stdin = tty
}

if err := root.Screen.Suspend(); err != nil {
root.setMessageLog(err.Error())
return
Expand All @@ -48,7 +64,9 @@ func (root *Root) edit(context.Context) {
}
// Reload the document after editing.
if isTemp {
os.Remove(fileName) // Clean up the temporary file.
if err := os.Remove(fileName); err != nil {
log.Printf("Failed to remove temporary file %s: %v", fileName, err)
}
} else {
root.reload(root.Doc)
root.sendGoto(num + 1)
Expand All @@ -61,7 +79,7 @@ func (root *Root) edit(context.Context) {

log.Println("Editing with command:", command, "and args:", args)
c := exec.Command(command, args...)
c.Stdin = os.Stdout
c.Stdin = stdin
c.Stdout = os.Stdout
c.Stderr = os.Stderr
if err := c.Run(); err != nil {
Expand All @@ -78,7 +96,7 @@ func (root *Root) saveTempFile() (string, error) {
}
defer tempFile.Close()

if err := root.Doc.Export(tempFile, root.Doc.BufStartNum(), root.Doc.BufEndNum()); err != nil {
if err := root.tempExport(tempFile); err != nil {
log.Printf("Failed to export document to temporary file: %v", err)
return "", err
}
Expand All @@ -88,6 +106,15 @@ func (root *Root) saveTempFile() (string, error) {
return fileName, nil
}

// tempExport exports the current document to a temporary file.
func (root *Root) tempExport(tempFile *os.File) error {
if root.Doc.PlainMode {
// If the document is in plain mode, export it as plain text.
return root.Doc.ExportPlain(tempFile, root.Doc.BufStartNum(), root.Doc.BufEndNum())
}
return root.Doc.Export(tempFile, root.Doc.BufStartNum(), root.Doc.BufEndNum())
}

// identifyEditor determines the editor to use based on environment variables and configuration.
func (root *Root) identifyEditor() string {
if ovedit := os.Getenv("OVEDIT"); ovedit != "" {
Expand All @@ -98,10 +125,6 @@ func (root *Root) identifyEditor() string {
return editor
}

if visual := os.Getenv("VISUAL"); visual != "" {
return visual
}

if editor := os.Getenv("EDITOR"); editor != "" {
return editor
}
Expand Down
16 changes: 16 additions & 0 deletions oviewer/store.go
Original file line number Diff line number Diff line change
Expand Up @@ -373,3 +373,19 @@ func (s *store) export(w io.Writer, chunk *chunk, start int, end int) error {
}
return nil
}

// exportPlain exports the plain text without ANSI escape sequences.
func (s *store) exportPlain(w io.Writer, chunk *chunk, start int, end int) error {
s.mu.RLock()
defer s.mu.RUnlock()

start = max(0, start)
end = min(len(chunk.lines), end)
for i := start; i < end; i++ {
plain := stripEscapeSequenceBytes(chunk.lines[i])
if _, err := w.Write(plain); err != nil {
return err
}
}
return nil
}
18 changes: 18 additions & 0 deletions oviewer/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,9 @@ import (
"bytes"
"io"
"log"
"os"
"regexp"
"runtime"
"slices"
"strings"
)
Expand Down Expand Up @@ -116,3 +118,19 @@ func stripEscapeSequenceBytes(src []byte) []byte {
// Remove EscapeSequence.
return stripRegexpES.ReplaceAll(src, []byte(""))
}

// getShell returns the shell name based on the operating system.
func getShell() string {
if runtime.GOOS == "windows" {
return "CMD.EXE"
}
return "/bin/sh"
}

// getTTY returns the TTY file based on the operating system.
func getTTY() (*os.File, error) {
if runtime.GOOS == "windows" {
return os.Open("CONIN$")
}
return os.Open("/dev/tty")
}
Loading