Skip to content
Open
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
1 change: 1 addition & 0 deletions cmd/micro/initlua.go
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,7 @@ func luaImportMicroBuffer() *lua.LTable {
ulua.L.SetField(pkg, "ByteOffset", luar.New(ulua.L, buffer.ByteOffset))
ulua.L.SetField(pkg, "Log", luar.New(ulua.L, buffer.WriteLog))
ulua.L.SetField(pkg, "LogBuf", luar.New(ulua.L, buffer.GetLogBuf))
ulua.L.SetField(pkg, "NewRegexpData", luar.New(ulua.L, buffer.NewRegexpData))

return pkg
}
Expand Down
46 changes: 25 additions & 21 deletions internal/action/command.go
Original file line number Diff line number Diff line change
Expand Up @@ -1018,17 +1018,8 @@ func (h *BufPane) ReplaceCmd(args []string) {

replace := []byte(replaceStr)

var regex *regexp.Regexp
var err error
if h.Buf.Settings["ignorecase"].(bool) {
regex, err = regexp.Compile("(?im)" + search)
} else {
regex, err = regexp.Compile("(?m)" + search)
}
if err != nil {
// There was an error with the user's regex
InfoBar.Error(err)
return
search = "(?i)" + search
}

nreplaced := 0
Expand All @@ -1042,21 +1033,32 @@ func (h *BufPane) ReplaceCmd(args []string) {
searchLoc = start // otherwise me might start at the end
}
if all {
nreplaced, _ = h.Buf.ReplaceRegex(start, end, regex, replace, !noRegex)
var err error
if noRegex {
nreplaced, _, err = h.Buf.ReplaceAllLiteral(search, start, end, replace)
} else {
nreplaced, _, err = h.Buf.ReplaceAll(search, start, end, replace)
}
if err != nil {
InfoBar.Error(err)
return
}
} else {
redata, err := buffer.NewRegexpData(search)
if err != nil {
InfoBar.Error(err)
return
}

inRange := func(l buffer.Loc) bool {
return l.GreaterEqual(start) && l.LessEqual(end)
}

lastMatchEnd := buffer.Loc{-1, -1}
var doReplacement func()
doReplacement = func() {
locs, found, err := h.Buf.FindNext(search, start, end, searchLoc, true, true)
if err != nil {
InfoBar.Error(err)
return
}
if !found || !inRange(locs[0]) || !inRange(locs[1]) {
locs := h.Buf.FindRegexpDown(redata, searchLoc, end)
if locs == nil || !inRange(locs[0]) || !inRange(locs[1]) {
h.Cursor.ResetSelection()
h.Buf.RelocateCursors()

Expand Down Expand Up @@ -1084,12 +1086,14 @@ func (h *BufPane) ReplaceCmd(args []string) {

InfoBar.YNPrompt("Perform replacement (y,n,esc)", func(yes, canceled bool) {
if !canceled && yes {
_, nrunes := h.Buf.ReplaceRegex(locs[0], locs[1], regex, replace, !noRegex)
if noRegex {
_, searchLoc, _ = h.Buf.ReplaceAllLiteral(search, locs[0], locs[1], replace)
} else {
_, searchLoc, _ = h.Buf.ReplaceAll(search, locs[0], locs[1], replace)
}

searchLoc = locs[0]
searchLoc.X += nrunes + locs[0].Diff(locs[1], h.Buf)
if end.Y == locs[1].Y {
end = end.Move(nrunes, h.Buf)
end = buffer.Loc{end.X + searchLoc.X - locs[1].X, end.Y}
}
h.Cursor.Loc = searchLoc
nreplaced++
Expand Down
4 changes: 2 additions & 2 deletions internal/buffer/buffer.go
Original file line number Diff line number Diff line change
Expand Up @@ -269,13 +269,13 @@ type Buffer struct {
}

// NewBufferFromFileWithCommand opens a new buffer with a given command
// If cmd.StartCursor is {-1, -1} the location does not overwrite what the cursor location
// If cmd.StartCursor is invalid, the location does not overwrite what the cursor location
// would otherwise be (start of file, or saved cursor position if `savecursor` is
// enabled)
func NewBufferFromFileWithCommand(path string, btype BufType, cmd Command) (*Buffer, error) {
var err error
filename := path
if config.GetGlobalOption("parsecursor").(bool) && cmd.StartCursor.X == -1 && cmd.StartCursor.Y == -1 {
if config.GetGlobalOption("parsecursor").(bool) && !cmd.StartCursor.IsValid() {
var cursorPos []string
filename, cursorPos = util.GetPathAndCursorPosition(filename)
cmd.StartCursor, err = ParseCursorLocation(cursorPos)
Expand Down
26 changes: 14 additions & 12 deletions internal/buffer/eventhandler.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@ type TextEvent struct {
C Cursor

EventType int
// If there are several deltas for the same line, they must not overlap
// and be ordered by increasing start position
Deltas []Delta
Time time.Time
}
Expand Down Expand Up @@ -114,24 +116,24 @@ func (eh *EventHandler) DoTextEvent(t *TextEvent, useUndo bool) {

// ExecuteTextEvent runs a text event
func ExecuteTextEvent(t *TextEvent, buf *SharedBuffer) {
if t.EventType == TextEventInsert {
for _, d := range t.Deltas {
for i := len(t.Deltas) - 1; i >= 0; i-- {
// Processing the deltas in increasing order would require
// to recompute the positions of the later deltas
d := t.Deltas[i]
if t.EventType == TextEventInsert {
buf.insert(d.Start, d.Text)
}
} else if t.EventType == TextEventRemove {
for i, d := range t.Deltas {
} else if t.EventType == TextEventRemove {
t.Deltas[i].Text = buf.remove(d.Start, d.End)
}
} else if t.EventType == TextEventReplace {
for i, d := range t.Deltas {
} else { // TextEventReplace
t.Deltas[i].Text = buf.remove(d.Start, d.End)
buf.insert(d.Start, d.Text)
t.Deltas[i].Start = d.Start
t.Deltas[i].End = Loc{d.Start.X + util.CharacterCount(d.Text), d.Start.Y}
}
for i, j := 0, len(t.Deltas)-1; i < j; i, j = i+1, j-1 {
t.Deltas[i], t.Deltas[j] = t.Deltas[j], t.Deltas[i]
}
}

for i, j := 0, len(t.Deltas)-1; i < j; i, j = i+1, j-1 {
t.Deltas[i], t.Deltas[j] = t.Deltas[j], t.Deltas[i]
}
}

Expand Down Expand Up @@ -195,7 +197,7 @@ func (eh *EventHandler) InsertBytes(start Loc, text []byte) {
e := &TextEvent{
C: *eh.cursors[eh.active],
EventType: TextEventInsert,
Deltas: []Delta{{text, start, Loc{0, 0}}},
Deltas: []Delta{{text, start, Loc{-1, -1}}},
Time: time.Now(),
}
eh.DoTextEvent(e, true)
Expand Down
5 changes: 5 additions & 0 deletions internal/buffer/loc.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,11 @@ type Loc struct {
X, Y int
}

// IsValid returns true if the argument is an actual buffer location
func (l Loc) IsValid() bool {
return l.X >= 0 && l.Y >= 0
}

// LessThan returns true if b is smaller
func (l Loc) LessThan(b Loc) bool {
if l.Y < b.Y {
Expand Down
Loading