mirror of
https://github.com/zyedidia/micro.git
synced 2026-03-16 05:47:06 +09:00
Handle same file open in multiple buffers
This commit is contained in:
@@ -1094,7 +1094,12 @@ func (h *BufHandler) Unsplit() bool {
|
|||||||
// NextSplit changes the view to the next split
|
// NextSplit changes the view to the next split
|
||||||
func (h *BufHandler) NextSplit() bool {
|
func (h *BufHandler) NextSplit() bool {
|
||||||
a := MainTab().active
|
a := MainTab().active
|
||||||
a = util.Clamp(a+1, 0, len(MainTab().Panes))
|
if a < len(MainTab().Panes)-1 {
|
||||||
|
a++
|
||||||
|
} else {
|
||||||
|
a = 0
|
||||||
|
}
|
||||||
|
|
||||||
MainTab().SetActive(a)
|
MainTab().SetActive(a)
|
||||||
|
|
||||||
return false
|
return false
|
||||||
@@ -1103,7 +1108,11 @@ func (h *BufHandler) NextSplit() bool {
|
|||||||
// PreviousSplit changes the view to the previous split
|
// PreviousSplit changes the view to the previous split
|
||||||
func (h *BufHandler) PreviousSplit() bool {
|
func (h *BufHandler) PreviousSplit() bool {
|
||||||
a := MainTab().active
|
a := MainTab().active
|
||||||
a = util.Clamp(a-1, 0, len(MainTab().Panes))
|
if a > 0 {
|
||||||
|
a--
|
||||||
|
} else {
|
||||||
|
a = len(MainTab().Panes) - 1
|
||||||
|
}
|
||||||
MainTab().SetActive(a)
|
MainTab().SetActive(a)
|
||||||
|
|
||||||
return false
|
return false
|
||||||
|
|||||||
@@ -57,7 +57,6 @@ type BufHandler struct {
|
|||||||
|
|
||||||
Buf *buffer.Buffer
|
Buf *buffer.Buffer
|
||||||
|
|
||||||
cursors []*buffer.Cursor
|
|
||||||
Cursor *buffer.Cursor // the active cursor
|
Cursor *buffer.Cursor // the active cursor
|
||||||
|
|
||||||
StartLine int // Vertical scrolling
|
StartLine int // Vertical scrolling
|
||||||
@@ -104,11 +103,9 @@ func NewBufHandler(buf *buffer.Buffer, win display.Window) *BufHandler {
|
|||||||
h.Buf = buf
|
h.Buf = buf
|
||||||
h.Window = win
|
h.Window = win
|
||||||
|
|
||||||
h.cursors = []*buffer.Cursor{buffer.NewCursor(buf, buf.StartCursor)}
|
h.Cursor = h.Buf.GetActiveCursor()
|
||||||
h.Cursor = h.cursors[0]
|
|
||||||
h.mouseReleased = true
|
h.mouseReleased = true
|
||||||
|
|
||||||
buf.SetCursors(h.cursors)
|
|
||||||
return h
|
return h
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -60,11 +60,8 @@ type Buffer struct {
|
|||||||
// Name of the buffer on the status line
|
// Name of the buffer on the status line
|
||||||
name string
|
name string
|
||||||
|
|
||||||
// Whether or not the buffer has been modified since it was opened
|
|
||||||
isModified bool
|
|
||||||
|
|
||||||
// Stores the last modification time of the file the buffer is pointing to
|
// Stores the last modification time of the file the buffer is pointing to
|
||||||
ModTime time.Time
|
ModTime *time.Time
|
||||||
|
|
||||||
SyntaxDef *highlight.Def
|
SyntaxDef *highlight.Def
|
||||||
Highlighter *highlight.Highlighter
|
Highlighter *highlight.Highlighter
|
||||||
@@ -135,15 +132,31 @@ func NewBuffer(reader io.Reader, size int64, path string, cursorPosition []strin
|
|||||||
}
|
}
|
||||||
config.InitLocalSettings(b.Settings, b.Path)
|
config.InitLocalSettings(b.Settings, b.Path)
|
||||||
|
|
||||||
|
found := false
|
||||||
|
for _, buf := range OpenBuffers {
|
||||||
|
if buf.AbsPath == absPath {
|
||||||
|
found = true
|
||||||
|
b.LineArray = buf.LineArray
|
||||||
|
b.EventHandler = buf.EventHandler
|
||||||
|
b.ModTime = buf.ModTime
|
||||||
|
b.isModified = buf.isModified
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if !found {
|
||||||
b.LineArray = NewLineArray(uint64(size), FFAuto, reader)
|
b.LineArray = NewLineArray(uint64(size), FFAuto, reader)
|
||||||
|
b.EventHandler = NewEventHandler(b.LineArray, b.cursors)
|
||||||
|
b.ModTime = new(time.Time)
|
||||||
|
b.isModified = new(bool)
|
||||||
|
*b.isModified = false
|
||||||
|
*b.ModTime = time.Time{}
|
||||||
|
}
|
||||||
|
|
||||||
b.Path = path
|
b.Path = path
|
||||||
b.AbsPath = absPath
|
b.AbsPath = absPath
|
||||||
|
|
||||||
// The last time this file was modified
|
// The last time this file was modified
|
||||||
b.ModTime, _ = GetModTime(b.Path)
|
*b.ModTime, _ = GetModTime(b.Path)
|
||||||
|
|
||||||
b.EventHandler = NewEventHandler(b)
|
|
||||||
|
|
||||||
b.UpdateRules()
|
b.UpdateRules()
|
||||||
|
|
||||||
@@ -164,6 +177,8 @@ func NewBuffer(reader io.Reader, size int64, path string, cursorPosition []strin
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
b.AddCursor(NewCursor(b, b.StartCursor))
|
||||||
|
|
||||||
if !b.Settings["fastdirty"].(bool) {
|
if !b.Settings["fastdirty"].(bool) {
|
||||||
if size > LargeFileThreshold {
|
if size > LargeFileThreshold {
|
||||||
// If the file is larger than LargeFileThreshold fastdirty needs to be on
|
// If the file is larger than LargeFileThreshold fastdirty needs to be on
|
||||||
@@ -217,38 +232,14 @@ func (b *Buffer) ReOpen() error {
|
|||||||
}
|
}
|
||||||
b.EventHandler.ApplyDiff(txt)
|
b.EventHandler.ApplyDiff(txt)
|
||||||
|
|
||||||
b.ModTime, err = GetModTime(b.Path)
|
*b.ModTime, err = GetModTime(b.Path)
|
||||||
b.isModified = false
|
*b.isModified = false
|
||||||
for _, c := range b.cursors {
|
for _, c := range b.cursors {
|
||||||
c.Relocate()
|
c.Relocate()
|
||||||
}
|
}
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
// LineBytes returns line n as an array of bytes
|
|
||||||
func (b *Buffer) LineBytes(n int) []byte {
|
|
||||||
if n >= len(b.lines) || n < 0 {
|
|
||||||
return []byte{}
|
|
||||||
}
|
|
||||||
return b.lines[n].data
|
|
||||||
}
|
|
||||||
|
|
||||||
// LinesNum returns the number of lines in the buffer
|
|
||||||
func (b *Buffer) LinesNum() int {
|
|
||||||
return len(b.lines)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Start returns the start of the buffer
|
|
||||||
func (b *Buffer) Start() Loc {
|
|
||||||
return Loc{0, 0}
|
|
||||||
}
|
|
||||||
|
|
||||||
// End returns the location of the last character in the buffer
|
|
||||||
func (b *Buffer) End() Loc {
|
|
||||||
numlines := len(b.lines)
|
|
||||||
return Loc{utf8.RuneCount(b.lines[numlines-1].data), numlines - 1}
|
|
||||||
}
|
|
||||||
|
|
||||||
// RuneAt returns the rune at a given location in the buffer
|
// RuneAt returns the rune at a given location in the buffer
|
||||||
func (b *Buffer) RuneAt(loc Loc) rune {
|
func (b *Buffer) RuneAt(loc Loc) rune {
|
||||||
line := b.LineBytes(loc.Y)
|
line := b.LineBytes(loc.Y)
|
||||||
@@ -271,7 +262,7 @@ func (b *Buffer) RuneAt(loc Loc) rune {
|
|||||||
// being opened
|
// being opened
|
||||||
func (b *Buffer) Modified() bool {
|
func (b *Buffer) Modified() bool {
|
||||||
if b.Settings["fastdirty"].(bool) {
|
if b.Settings["fastdirty"].(bool) {
|
||||||
return b.isModified
|
return *b.isModified
|
||||||
}
|
}
|
||||||
|
|
||||||
var buff [md5.Size]byte
|
var buff [md5.Size]byte
|
||||||
@@ -314,20 +305,6 @@ func calcHash(b *Buffer, out *[md5.Size]byte) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b *Buffer) insert(pos Loc, value []byte) {
|
|
||||||
b.isModified = true
|
|
||||||
b.LineArray.insert(pos, value)
|
|
||||||
}
|
|
||||||
func (b *Buffer) remove(start, end Loc) []byte {
|
|
||||||
b.isModified = true
|
|
||||||
sub := b.LineArray.remove(start, end)
|
|
||||||
return sub
|
|
||||||
}
|
|
||||||
func (b *Buffer) deleteToEnd(start Loc) {
|
|
||||||
b.isModified = true
|
|
||||||
b.LineArray.deleteToEnd(start)
|
|
||||||
}
|
|
||||||
|
|
||||||
// UpdateRules updates the syntax rules and filetype for this buffer
|
// UpdateRules updates the syntax rules and filetype for this buffer
|
||||||
// This is called when the colorscheme changes
|
// This is called when the colorscheme changes
|
||||||
func (b *Buffer) UpdateRules() {
|
func (b *Buffer) UpdateRules() {
|
||||||
@@ -422,6 +399,7 @@ func (b *Buffer) SetCursors(c []*Cursor) {
|
|||||||
// AddCursor adds a new cursor to the list
|
// AddCursor adds a new cursor to the list
|
||||||
func (b *Buffer) AddCursor(c *Cursor) {
|
func (b *Buffer) AddCursor(c *Cursor) {
|
||||||
b.cursors = append(b.cursors, c)
|
b.cursors = append(b.cursors, c)
|
||||||
|
b.EventHandler.cursors = b.cursors
|
||||||
b.UpdateCursors()
|
b.UpdateCursors()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -37,7 +37,7 @@ type Delta struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// ExecuteTextEvent runs a text event
|
// ExecuteTextEvent runs a text event
|
||||||
func ExecuteTextEvent(t *TextEvent, buf *Buffer) {
|
func ExecuteTextEvent(t *TextEvent, buf *LineArray) {
|
||||||
if t.EventType == TextEventInsert {
|
if t.EventType == TextEventInsert {
|
||||||
for _, d := range t.Deltas {
|
for _, d := range t.Deltas {
|
||||||
buf.insert(d.Start, d.Text)
|
buf.insert(d.Start, d.Text)
|
||||||
@@ -60,24 +60,26 @@ func ExecuteTextEvent(t *TextEvent, buf *Buffer) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// UndoTextEvent undoes a text event
|
// UndoTextEvent undoes a text event
|
||||||
func UndoTextEvent(t *TextEvent, buf *Buffer) {
|
func UndoTextEvent(t *TextEvent, buf *LineArray) {
|
||||||
t.EventType = -t.EventType
|
t.EventType = -t.EventType
|
||||||
ExecuteTextEvent(t, buf)
|
ExecuteTextEvent(t, buf)
|
||||||
}
|
}
|
||||||
|
|
||||||
// EventHandler executes text manipulations and allows undoing and redoing
|
// EventHandler executes text manipulations and allows undoing and redoing
|
||||||
type EventHandler struct {
|
type EventHandler struct {
|
||||||
buf *Buffer
|
buf *LineArray
|
||||||
|
cursors []*Cursor
|
||||||
UndoStack *TEStack
|
UndoStack *TEStack
|
||||||
RedoStack *TEStack
|
RedoStack *TEStack
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewEventHandler returns a new EventHandler
|
// NewEventHandler returns a new EventHandler
|
||||||
func NewEventHandler(buf *Buffer) *EventHandler {
|
func NewEventHandler(la *LineArray, cursors []*Cursor) *EventHandler {
|
||||||
eh := new(EventHandler)
|
eh := new(EventHandler)
|
||||||
eh.UndoStack = new(TEStack)
|
eh.UndoStack = new(TEStack)
|
||||||
eh.RedoStack = new(TEStack)
|
eh.RedoStack = new(TEStack)
|
||||||
eh.buf = buf
|
eh.buf = la
|
||||||
|
eh.cursors = cursors
|
||||||
return eh
|
return eh
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -91,12 +93,12 @@ func (eh *EventHandler) ApplyDiff(new string) {
|
|||||||
loc := eh.buf.Start()
|
loc := eh.buf.Start()
|
||||||
for _, d := range diff {
|
for _, d := range diff {
|
||||||
if d.Type == dmp.DiffDelete {
|
if d.Type == dmp.DiffDelete {
|
||||||
eh.Remove(loc, loc.Move(utf8.RuneCountInString(d.Text), eh.buf))
|
eh.Remove(loc, loc.MoveLA(utf8.RuneCountInString(d.Text), eh.buf))
|
||||||
} else {
|
} else {
|
||||||
if d.Type == dmp.DiffInsert {
|
if d.Type == dmp.DiffInsert {
|
||||||
eh.Insert(loc, d.Text)
|
eh.Insert(loc, d.Text)
|
||||||
}
|
}
|
||||||
loc = loc.Move(utf8.RuneCountInString(d.Text), eh.buf)
|
loc = loc.MoveLA(utf8.RuneCountInString(d.Text), eh.buf)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -105,21 +107,21 @@ func (eh *EventHandler) ApplyDiff(new string) {
|
|||||||
func (eh *EventHandler) Insert(start Loc, textStr string) {
|
func (eh *EventHandler) Insert(start Loc, textStr string) {
|
||||||
text := []byte(textStr)
|
text := []byte(textStr)
|
||||||
e := &TextEvent{
|
e := &TextEvent{
|
||||||
C: *eh.buf.GetActiveCursor(),
|
C: *eh.cursors[0],
|
||||||
EventType: TextEventInsert,
|
EventType: TextEventInsert,
|
||||||
Deltas: []Delta{{text, start, Loc{0, 0}}},
|
Deltas: []Delta{{text, start, Loc{0, 0}}},
|
||||||
Time: time.Now(),
|
Time: time.Now(),
|
||||||
}
|
}
|
||||||
eh.Execute(e)
|
eh.Execute(e)
|
||||||
e.Deltas[0].End = start.Move(utf8.RuneCount(text), eh.buf)
|
e.Deltas[0].End = start.MoveLA(utf8.RuneCount(text), eh.buf)
|
||||||
end := e.Deltas[0].End
|
end := e.Deltas[0].End
|
||||||
|
|
||||||
for _, c := range eh.buf.GetCursors() {
|
for _, c := range eh.cursors {
|
||||||
move := func(loc Loc) Loc {
|
move := func(loc Loc) Loc {
|
||||||
if start.Y != end.Y && loc.GreaterThan(start) {
|
if start.Y != end.Y && loc.GreaterThan(start) {
|
||||||
loc.Y += end.Y - start.Y
|
loc.Y += end.Y - start.Y
|
||||||
} else if loc.Y == start.Y && loc.GreaterEqual(start) {
|
} else if loc.Y == start.Y && loc.GreaterEqual(start) {
|
||||||
loc = loc.Move(utf8.RuneCount(text), eh.buf)
|
loc = loc.MoveLA(utf8.RuneCount(text), eh.buf)
|
||||||
}
|
}
|
||||||
return loc
|
return loc
|
||||||
}
|
}
|
||||||
@@ -135,19 +137,19 @@ func (eh *EventHandler) Insert(start Loc, textStr string) {
|
|||||||
// Remove creates a remove text event and executes it
|
// Remove creates a remove text event and executes it
|
||||||
func (eh *EventHandler) Remove(start, end Loc) {
|
func (eh *EventHandler) Remove(start, end Loc) {
|
||||||
e := &TextEvent{
|
e := &TextEvent{
|
||||||
C: *eh.buf.GetActiveCursor(),
|
C: *eh.cursors[0],
|
||||||
EventType: TextEventRemove,
|
EventType: TextEventRemove,
|
||||||
Deltas: []Delta{{[]byte{}, start, end}},
|
Deltas: []Delta{{[]byte{}, start, end}},
|
||||||
Time: time.Now(),
|
Time: time.Now(),
|
||||||
}
|
}
|
||||||
eh.Execute(e)
|
eh.Execute(e)
|
||||||
|
|
||||||
for _, c := range eh.buf.GetCursors() {
|
for _, c := range eh.cursors {
|
||||||
move := func(loc Loc) Loc {
|
move := func(loc Loc) Loc {
|
||||||
if start.Y != end.Y && loc.GreaterThan(end) {
|
if start.Y != end.Y && loc.GreaterThan(end) {
|
||||||
loc.Y -= end.Y - start.Y
|
loc.Y -= end.Y - start.Y
|
||||||
} else if loc.Y == end.Y && loc.GreaterEqual(end) {
|
} else if loc.Y == end.Y && loc.GreaterEqual(end) {
|
||||||
loc = loc.Move(-Diff(start, end, eh.buf), eh.buf)
|
loc = loc.MoveLA(-DiffLA(start, end, eh.buf), eh.buf)
|
||||||
}
|
}
|
||||||
return loc
|
return loc
|
||||||
}
|
}
|
||||||
@@ -163,7 +165,7 @@ func (eh *EventHandler) Remove(start, end Loc) {
|
|||||||
// MultipleReplace creates an multiple insertions executes them
|
// MultipleReplace creates an multiple insertions executes them
|
||||||
func (eh *EventHandler) MultipleReplace(deltas []Delta) {
|
func (eh *EventHandler) MultipleReplace(deltas []Delta) {
|
||||||
e := &TextEvent{
|
e := &TextEvent{
|
||||||
C: *eh.buf.GetActiveCursor(),
|
C: *eh.cursors[0],
|
||||||
EventType: TextEventReplace,
|
EventType: TextEventReplace,
|
||||||
Deltas: deltas,
|
Deltas: deltas,
|
||||||
Time: time.Now(),
|
Time: time.Now(),
|
||||||
@@ -239,9 +241,9 @@ func (eh *EventHandler) UndoOneEvent() {
|
|||||||
|
|
||||||
// Set the cursor in the right place
|
// Set the cursor in the right place
|
||||||
teCursor := t.C
|
teCursor := t.C
|
||||||
if teCursor.Num >= 0 && teCursor.Num < eh.buf.NumCursors() {
|
if teCursor.Num >= 0 && teCursor.Num < len(eh.cursors) {
|
||||||
t.C = *eh.buf.GetCursor(teCursor.Num)
|
t.C = *eh.cursors[teCursor.Num]
|
||||||
eh.buf.GetCursor(teCursor.Num).Goto(teCursor)
|
eh.cursors[teCursor.Num].Goto(teCursor)
|
||||||
} else {
|
} else {
|
||||||
teCursor.Num = -1
|
teCursor.Num = -1
|
||||||
}
|
}
|
||||||
@@ -286,9 +288,9 @@ func (eh *EventHandler) RedoOneEvent() {
|
|||||||
UndoTextEvent(t, eh.buf)
|
UndoTextEvent(t, eh.buf)
|
||||||
|
|
||||||
teCursor := t.C
|
teCursor := t.C
|
||||||
if teCursor.Num >= 0 && teCursor.Num < eh.buf.NumCursors() {
|
if teCursor.Num >= 0 && teCursor.Num < len(eh.cursors) {
|
||||||
t.C = *eh.buf.GetCursor(teCursor.Num)
|
t.C = *eh.cursors[teCursor.Num]
|
||||||
eh.buf.GetCursor(teCursor.Num).Goto(teCursor)
|
eh.cursors[teCursor.Num].Goto(teCursor)
|
||||||
} else {
|
} else {
|
||||||
teCursor.Num = -1
|
teCursor.Num = -1
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -55,6 +55,7 @@ type LineArray struct {
|
|||||||
lines []Line
|
lines []Line
|
||||||
endings FileFormat
|
endings FileFormat
|
||||||
initsize uint64
|
initsize uint64
|
||||||
|
isModified *bool
|
||||||
}
|
}
|
||||||
|
|
||||||
// Append efficiently appends lines together
|
// Append efficiently appends lines together
|
||||||
@@ -161,6 +162,7 @@ func (la *LineArray) newlineBelow(y int) {
|
|||||||
|
|
||||||
// Inserts a byte array at a given location
|
// Inserts a byte array at a given location
|
||||||
func (la *LineArray) insert(pos Loc, value []byte) {
|
func (la *LineArray) insert(pos Loc, value []byte) {
|
||||||
|
*la.isModified = true
|
||||||
x, y := runeToByteIndex(pos.X, la.lines[pos.Y].data), pos.Y
|
x, y := runeToByteIndex(pos.X, la.lines[pos.Y].data), pos.Y
|
||||||
for i := 0; i < len(value); i++ {
|
for i := 0; i < len(value); i++ {
|
||||||
if value[i] == '\n' {
|
if value[i] == '\n' {
|
||||||
@@ -201,6 +203,7 @@ func (la *LineArray) split(pos Loc) {
|
|||||||
|
|
||||||
// removes from start to end
|
// removes from start to end
|
||||||
func (la *LineArray) remove(start, end Loc) []byte {
|
func (la *LineArray) remove(start, end Loc) []byte {
|
||||||
|
*la.isModified = true
|
||||||
sub := la.Substr(start, end)
|
sub := la.Substr(start, end)
|
||||||
startX := runeToByteIndex(start.X, la.lines[start.Y].data)
|
startX := runeToByteIndex(start.X, la.lines[start.Y].data)
|
||||||
endX := runeToByteIndex(end.X, la.lines[end.Y].data)
|
endX := runeToByteIndex(end.X, la.lines[end.Y].data)
|
||||||
@@ -219,6 +222,7 @@ func (la *LineArray) remove(start, end Loc) []byte {
|
|||||||
|
|
||||||
// deleteToEnd deletes from the end of a line to the position
|
// deleteToEnd deletes from the end of a line to the position
|
||||||
func (la *LineArray) deleteToEnd(pos Loc) {
|
func (la *LineArray) deleteToEnd(pos Loc) {
|
||||||
|
*la.isModified = true
|
||||||
la.lines[pos.Y].data = la.lines[pos.Y].data[:pos.X]
|
la.lines[pos.Y].data = la.lines[pos.Y].data[:pos.X]
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -258,6 +262,30 @@ func (la *LineArray) Substr(start, end Loc) []byte {
|
|||||||
return str
|
return str
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// LinesNum returns the number of lines in the buffer
|
||||||
|
func (la *LineArray) LinesNum() int {
|
||||||
|
return len(la.lines)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Start returns the start of the buffer
|
||||||
|
func (la *LineArray) Start() Loc {
|
||||||
|
return Loc{0, 0}
|
||||||
|
}
|
||||||
|
|
||||||
|
// End returns the location of the last character in the buffer
|
||||||
|
func (la *LineArray) End() Loc {
|
||||||
|
numlines := len(la.lines)
|
||||||
|
return Loc{utf8.RuneCount(la.lines[numlines-1].data), numlines - 1}
|
||||||
|
}
|
||||||
|
|
||||||
|
// LineBytes returns line n as an array of bytes
|
||||||
|
func (la *LineArray) LineBytes(n int) []byte {
|
||||||
|
if n >= len(la.lines) || n < 0 {
|
||||||
|
return []byte{}
|
||||||
|
}
|
||||||
|
return la.lines[n].data
|
||||||
|
}
|
||||||
|
|
||||||
// State gets the highlight state for the given line number
|
// State gets the highlight state for the given line number
|
||||||
func (la *LineArray) State(lineN int) highlight.State {
|
func (la *LineArray) State(lineN int) highlight.State {
|
||||||
return la.lines[lineN].state
|
return la.lines[lineN].state
|
||||||
|
|||||||
@@ -52,7 +52,7 @@ func (l Loc) LessEqual(b Loc) bool {
|
|||||||
// The following functions require a buffer to know where newlines are
|
// The following functions require a buffer to know where newlines are
|
||||||
|
|
||||||
// Diff returns the distance between two locations
|
// Diff returns the distance between two locations
|
||||||
func Diff(a, b Loc, buf *Buffer) int {
|
func DiffLA(a, b Loc, buf *LineArray) int {
|
||||||
if a.Y == b.Y {
|
if a.Y == b.Y {
|
||||||
if a.X > b.X {
|
if a.X > b.X {
|
||||||
return a.X - b.X
|
return a.X - b.X
|
||||||
@@ -75,7 +75,7 @@ func Diff(a, b Loc, buf *Buffer) int {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// This moves the location one character to the right
|
// This moves the location one character to the right
|
||||||
func (l Loc) right(buf *Buffer) Loc {
|
func (l Loc) right(buf *LineArray) Loc {
|
||||||
if l == buf.End() {
|
if l == buf.End() {
|
||||||
return Loc{l.X + 1, l.Y}
|
return Loc{l.X + 1, l.Y}
|
||||||
}
|
}
|
||||||
@@ -89,7 +89,7 @@ func (l Loc) right(buf *Buffer) Loc {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// This moves the given location one character to the left
|
// This moves the given location one character to the left
|
||||||
func (l Loc) left(buf *Buffer) Loc {
|
func (l Loc) left(buf *LineArray) Loc {
|
||||||
if l == buf.Start() {
|
if l == buf.Start() {
|
||||||
return Loc{l.X - 1, l.Y}
|
return Loc{l.X - 1, l.Y}
|
||||||
}
|
}
|
||||||
@@ -104,7 +104,7 @@ func (l Loc) left(buf *Buffer) Loc {
|
|||||||
|
|
||||||
// Move moves the cursor n characters to the left or right
|
// Move moves the cursor n characters to the left or right
|
||||||
// It moves the cursor left if n is negative
|
// It moves the cursor left if n is negative
|
||||||
func (l Loc) Move(n int, buf *Buffer) Loc {
|
func (l Loc) MoveLA(n int, buf *LineArray) Loc {
|
||||||
if n > 0 {
|
if n > 0 {
|
||||||
for i := 0; i < n; i++ {
|
for i := 0; i < n; i++ {
|
||||||
l = l.right(buf)
|
l = l.right(buf)
|
||||||
@@ -116,3 +116,10 @@ func (l Loc) Move(n int, buf *Buffer) Loc {
|
|||||||
}
|
}
|
||||||
return l
|
return l
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (l Loc) Diff(a, b Loc, buf *Buffer) int {
|
||||||
|
return DiffLA(a, b, buf.LineArray)
|
||||||
|
}
|
||||||
|
func (l Loc) Move(n int, buf *Buffer) Loc {
|
||||||
|
return l.MoveLA(n, buf.LineArray)
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,8 +1,6 @@
|
|||||||
package buffer
|
package buffer
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"log"
|
|
||||||
|
|
||||||
"github.com/zyedidia/micro/cmd/micro/config"
|
"github.com/zyedidia/micro/cmd/micro/config"
|
||||||
"github.com/zyedidia/tcell"
|
"github.com/zyedidia/tcell"
|
||||||
)
|
)
|
||||||
@@ -50,7 +48,6 @@ func (m *Message) Style() tcell.Style {
|
|||||||
}
|
}
|
||||||
case MTError:
|
case MTError:
|
||||||
if style, ok := config.Colorscheme["gutter-error"]; ok {
|
if style, ok := config.Colorscheme["gutter-error"]; ok {
|
||||||
log.Println("Return error")
|
|
||||||
return style
|
return style
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -73,7 +73,7 @@ func (b *Buffer) SaveAs(filename string) error {
|
|||||||
|
|
||||||
// Update the last time this file was updated after saving
|
// Update the last time this file was updated after saving
|
||||||
defer func() {
|
defer func() {
|
||||||
b.ModTime, _ = GetModTime(filename)
|
*b.ModTime, _ = GetModTime(filename)
|
||||||
}()
|
}()
|
||||||
|
|
||||||
// Removes any tilde and replaces with the absolute path to home
|
// Removes any tilde and replaces with the absolute path to home
|
||||||
@@ -146,7 +146,7 @@ func (b *Buffer) SaveAs(filename string) error {
|
|||||||
b.Path = filename
|
b.Path = filename
|
||||||
absPath, _ := filepath.Abs(filename)
|
absPath, _ := filepath.Abs(filename)
|
||||||
b.AbsPath = absPath
|
b.AbsPath = absPath
|
||||||
b.isModified = false
|
*b.isModified = false
|
||||||
return b.Serialize()
|
return b.Serialize()
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -182,8 +182,8 @@ func (b *Buffer) SaveAsWithSudo(filename string) error {
|
|||||||
err := cmd.Wait()
|
err := cmd.Wait()
|
||||||
|
|
||||||
if err == nil {
|
if err == nil {
|
||||||
b.isModified = false
|
*b.isModified = false
|
||||||
b.ModTime, _ = GetModTime(filename)
|
*b.ModTime, _ = GetModTime(filename)
|
||||||
return b.Serialize()
|
return b.Serialize()
|
||||||
}
|
}
|
||||||
return err
|
return err
|
||||||
|
|||||||
@@ -36,7 +36,7 @@ func (b *Buffer) Serialize() error {
|
|||||||
err := gob.NewEncoder(file).Encode(SerializedBuffer{
|
err := gob.NewEncoder(file).Encode(SerializedBuffer{
|
||||||
b.EventHandler,
|
b.EventHandler,
|
||||||
b.GetActiveCursor().Loc,
|
b.GetActiveCursor().Loc,
|
||||||
b.ModTime,
|
*b.ModTime,
|
||||||
})
|
})
|
||||||
return err
|
return err
|
||||||
})
|
})
|
||||||
@@ -61,9 +61,10 @@ func (b *Buffer) Unserialize() error {
|
|||||||
|
|
||||||
if b.Settings["saveundo"].(bool) {
|
if b.Settings["saveundo"].(bool) {
|
||||||
// We should only use last time's eventhandler if the file wasn't modified by someone else in the meantime
|
// We should only use last time's eventhandler if the file wasn't modified by someone else in the meantime
|
||||||
if b.ModTime == buffer.ModTime {
|
if *b.ModTime == buffer.ModTime {
|
||||||
b.EventHandler = buffer.EventHandler
|
b.EventHandler = buffer.EventHandler
|
||||||
b.EventHandler.buf = b
|
b.EventHandler.cursors = b.cursors
|
||||||
|
b.EventHandler.buf = b.LineArray
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -30,7 +30,7 @@ func (b *Buffer) SetOption(option, value string) error {
|
|||||||
} else if option == "filetype" {
|
} else if option == "filetype" {
|
||||||
b.UpdateRules()
|
b.UpdateRules()
|
||||||
} else if option == "fileformat" {
|
} else if option == "fileformat" {
|
||||||
b.isModified = true
|
*b.isModified = true
|
||||||
} else if option == "syntax" {
|
} else if option == "syntax" {
|
||||||
if !nativeValue.(bool) {
|
if !nativeValue.(bool) {
|
||||||
b.ClearMatches()
|
b.ClearMatches()
|
||||||
|
|||||||
Reference in New Issue
Block a user