"github.com/zyedidia/micro/v2/internal/screen"
"github.com/zyedidia/micro/v2/internal/util"
"github.com/zyedidia/micro/v2/pkg/highlight"
+ "golang.org/x/text/encoding"
"golang.org/x/text/encoding/htmlindex"
"golang.org/x/text/encoding/unicode"
"golang.org/x/text/transform"
HighlightSearch bool
}
+type retabReader struct {
+ scanner *bufio.Scanner
+ buffer []byte
+ toSpaces bool
+ tabsize int
+}
+
+func newRetabReader(from io.Reader, enc encoding.Encoding, autoretab bool, toSpaces bool, tabsize int) io.Reader {
+ if !autoretab {
+ return from
+ }
+ r := new(retabReader)
+ r.scanner = bufio.NewScanner(bufio.NewReader(transform.NewReader(from, enc.NewDecoder())))
+ r.toSpaces = toSpaces
+ r.tabsize = tabsize
+ return r
+}
+
+func (r *retabReader) fillBuffer(required int) error {
+ for len(r.buffer) < required {
+ if r.scanner.Scan() {
+ line := retabLine([]byte(r.scanner.Text()), r.toSpaces, r.tabsize)
+
+ r.buffer = append(r.buffer, line...)
+ r.buffer = append(r.buffer, "\n"...)
+ } else {
+ if err := r.scanner.Err(); err != nil {
+ return err
+ } else {
+ return io.EOF
+ }
+ break
+ }
+ }
+
+ return nil
+}
+
+func (r *retabReader) Read(into []byte) (n int, err error) {
+ err = r.fillBuffer(len(into))
+ n = copy(into, r.buffer)
+
+ r.buffer = r.buffer[n:]
+ return
+}
+
+func retabLine(l []byte, toSpaces bool, tabsize int) []byte {
+ ws := util.GetLeadingWhitespace(l)
+ if len(ws) != 0 {
+ if toSpaces {
+ ws = bytes.ReplaceAll(ws, []byte{'\t'}, bytes.Repeat([]byte{' '}, tabsize))
+ } else {
+ ws = bytes.ReplaceAll(ws, bytes.Repeat([]byte{' '}, tabsize), []byte{'\t'})
+ }
+ }
+
+ l = bytes.TrimLeft(l, " \t")
+ return append(ws, l...)
+}
+
// NewBufferFromFileAtLoc opens a new buffer with a given cursor location
// If cursorLoc is {-1, -1} the location does not overwrite what the cursor location
// would otherwise be (start of file, or saved cursor position if `savecursor` is
return NewBufferFromString("", "", btype)
}
if !hasBackup {
- reader := bufio.NewReader(transform.NewReader(r, enc.NewDecoder()))
+ autoretab := b.Settings["autoretab"].(bool)
+ toSpaces := b.Settings["tabstospaces"].(bool)
+ tabsize := util.IntOpt(b.Settings["tabsize"])
+
+ reader := newRetabReader(r, enc, autoretab, toSpaces, tabsize)
var ff FileFormat = FFAuto
return err
}
- reader := bufio.NewReader(transform.NewReader(file, enc.NewDecoder()))
+ autoretab := b.Settings["autoretab"].(bool)
+ toSpaces := b.Settings["tabstospaces"].(bool)
+ tabsize := util.IntOpt(b.Settings["tabsize"])
+
+ reader := newRetabReader(file, enc, autoretab, toSpaces, tabsize)
data, err := ioutil.ReadAll(reader)
txt := string(data)
-
if err != nil {
return err
}
+
b.EventHandler.ApplyDiff(txt)
err = b.UpdateModTime()
dirty := false
for i := 0; i < b.LinesNum(); i++ {
- l := b.LineBytes(i)
-
- ws := util.GetLeadingWhitespace(l)
- if len(ws) != 0 {
- if toSpaces {
- ws = bytes.ReplaceAll(ws, []byte{'\t'}, bytes.Repeat([]byte{' '}, tabsize))
- } else {
- ws = bytes.ReplaceAll(ws, bytes.Repeat([]byte{' '}, tabsize), []byte{'\t'})
- }
- }
-
- l = bytes.TrimLeft(l, " \t")
- b.lines[i].data = append(ws, l...)
+ b.lines[i].data = retabLine(b.LineBytes(i), toSpaces, tabsize)
b.MarkModified(i, i)
dirty = true
}