mirror of
https://github.com/go-sylixos/elvish.git
synced 2024-12-15 11:57:55 +08:00
99921ea222
Elvish strings are now simply Go strings. \o/ This addresses #573.
92 lines
2.2 KiB
Go
92 lines
2.2 KiB
Go
package edit
|
|
|
|
import (
|
|
"errors"
|
|
"io"
|
|
"os"
|
|
"strings"
|
|
"unicode/utf8"
|
|
|
|
"github.com/elves/elvish/edit/ui"
|
|
"github.com/elves/elvish/util"
|
|
)
|
|
|
|
// PreviewBytes is the maximum number of bytes to preview a file.
|
|
const PreviewBytes = 64 * 1024
|
|
|
|
// Errors displayed in the preview area of navigation mode.
|
|
var (
|
|
ErrNotRegular = errors.New("no preview for non-regular file")
|
|
ErrNotValidUTF8 = errors.New("no preview for non-utf8 file")
|
|
)
|
|
|
|
type navFilePreview struct {
|
|
lines []ui.Styled
|
|
fullWidth int
|
|
beginLine int
|
|
}
|
|
|
|
func newNavFilePreview(lines []string) *navFilePreview {
|
|
width := 0
|
|
convertedLines := make([]ui.Styled, len(lines))
|
|
for i, line := range lines {
|
|
// BUG: Handle tabstops correctly
|
|
convertedLine := strings.Replace(line, "\t", " ", -1)
|
|
convertedLines[i] = ui.Unstyled(convertedLine)
|
|
width = max(width, util.Wcswidth(convertedLine))
|
|
}
|
|
return &navFilePreview{convertedLines, width, 0}
|
|
}
|
|
|
|
func (fp *navFilePreview) FullWidth(h int) int {
|
|
width := fp.fullWidth
|
|
if h < len(fp.lines) {
|
|
return width + 1
|
|
}
|
|
return width
|
|
}
|
|
|
|
func (fp *navFilePreview) List(h int) ui.Renderer {
|
|
if len(fp.lines) <= h {
|
|
logger.Printf("Height %d fit all lines", h)
|
|
return listingRenderer{fp.lines}
|
|
}
|
|
shown := fp.lines[fp.beginLine:]
|
|
if len(shown) > h {
|
|
shown = shown[:h]
|
|
}
|
|
logger.Printf("Showing lines %d to %d", fp.beginLine, fp.beginLine+len(shown))
|
|
return listingWithScrollBarRenderer{
|
|
listingRenderer{shown}, len(fp.lines),
|
|
fp.beginLine, fp.beginLine + len(shown), h}
|
|
}
|
|
|
|
func makeNavFilePreview(fname string) navPreview {
|
|
file, err := os.Open(fname)
|
|
if err != nil {
|
|
return newErrNavColumn(err)
|
|
}
|
|
|
|
info, err := file.Stat()
|
|
if err != nil {
|
|
return newErrNavColumn(err)
|
|
}
|
|
if (info.Mode() & (os.ModeDevice | os.ModeNamedPipe | os.ModeSocket | os.ModeCharDevice)) != 0 {
|
|
return newErrNavColumn(ErrNotRegular)
|
|
}
|
|
|
|
// BUG: when the file is bigger than the buffer, the scrollbar is wrong.
|
|
var buf [PreviewBytes]byte
|
|
nr, err := file.Read(buf[:])
|
|
if err != nil && err != io.EOF {
|
|
return newErrNavColumn(err)
|
|
}
|
|
|
|
content := buf[:nr]
|
|
if !utf8.Valid(content) {
|
|
return newErrNavColumn(ErrNotValidUTF8)
|
|
}
|
|
|
|
return newNavFilePreview(strings.Split(string(content), "\n"))
|
|
}
|