Skip to content

Commit 362e10b

Browse files
committed
modified search and replace methods
process `Deltas` in `ExecuteTextEvent` in reverse order added `util.RangeMap` changed `util.isMark` to public `IsMark` added `Loc.IsValid` added `(*Buffer).Expand`
1 parent fa68314 commit 362e10b

9 files changed

Lines changed: 362 additions & 186 deletions

File tree

cmd/micro/initlua.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -141,6 +141,7 @@ func luaImportMicroBuffer() *lua.LTable {
141141
ulua.L.SetField(pkg, "ByteOffset", luar.New(ulua.L, buffer.ByteOffset))
142142
ulua.L.SetField(pkg, "Log", luar.New(ulua.L, buffer.WriteLog))
143143
ulua.L.SetField(pkg, "LogBuf", luar.New(ulua.L, buffer.GetLogBuf))
144+
ulua.L.SetField(pkg, "NewRegexpData", luar.New(ulua.L, buffer.NewRegexpData))
144145

145146
return pkg
146147
}

internal/action/command.go

Lines changed: 25 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1006,17 +1006,8 @@ func (h *BufPane) ReplaceCmd(args []string) {
10061006

10071007
replace := []byte(replaceStr)
10081008

1009-
var regex *regexp.Regexp
1010-
var err error
10111009
if h.Buf.Settings["ignorecase"].(bool) {
1012-
regex, err = regexp.Compile("(?im)" + search)
1013-
} else {
1014-
regex, err = regexp.Compile("(?m)" + search)
1015-
}
1016-
if err != nil {
1017-
// There was an error with the user's regex
1018-
InfoBar.Error(err)
1019-
return
1010+
search = "(?i)" + search
10201011
}
10211012

10221013
nreplaced := 0
@@ -1030,21 +1021,32 @@ func (h *BufPane) ReplaceCmd(args []string) {
10301021
searchLoc = start // otherwise me might start at the end
10311022
}
10321023
if all {
1033-
nreplaced, _ = h.Buf.ReplaceRegex(start, end, regex, replace, !noRegex)
1024+
var err error
1025+
if noRegex {
1026+
nreplaced, _, err = h.Buf.ReplaceAllLiteral(search, start, end, replace)
1027+
} else {
1028+
nreplaced, _, err = h.Buf.ReplaceAll(search, start, end, replace)
1029+
}
1030+
if err != nil {
1031+
InfoBar.Error(err)
1032+
return
1033+
}
10341034
} else {
1035+
redata, err := buffer.NewRegexpData(search)
1036+
if err != nil {
1037+
InfoBar.Error(err)
1038+
return
1039+
}
1040+
10351041
inRange := func(l buffer.Loc) bool {
10361042
return l.GreaterEqual(start) && l.LessEqual(end)
10371043
}
10381044

10391045
lastMatchEnd := buffer.Loc{-1, -1}
10401046
var doReplacement func()
10411047
doReplacement = func() {
1042-
locs, found, err := h.Buf.FindNext(search, start, end, searchLoc, true, true)
1043-
if err != nil {
1044-
InfoBar.Error(err)
1045-
return
1046-
}
1047-
if !found || !inRange(locs[0]) || !inRange(locs[1]) {
1048+
locs := h.Buf.FindRegexpDown(redata, searchLoc, end)
1049+
if locs == nil || !inRange(locs[0]) || !inRange(locs[1]) {
10481050
h.Cursor.ResetSelection()
10491051
h.Buf.RelocateCursors()
10501052

@@ -1072,12 +1074,14 @@ func (h *BufPane) ReplaceCmd(args []string) {
10721074

10731075
InfoBar.YNPrompt("Perform replacement (y,n,esc)", func(yes, canceled bool) {
10741076
if !canceled && yes {
1075-
_, nrunes := h.Buf.ReplaceRegex(locs[0], locs[1], regex, replace, !noRegex)
1077+
if noRegex {
1078+
_, searchLoc, _ = h.Buf.ReplaceAllLiteral(search, locs[0], locs[1], replace)
1079+
} else {
1080+
_, searchLoc, _ = h.Buf.ReplaceAll(search, locs[0], locs[1], replace)
1081+
}
10761082

1077-
searchLoc = locs[0]
1078-
searchLoc.X += nrunes + locs[0].Diff(locs[1], h.Buf)
10791083
if end.Y == locs[1].Y {
1080-
end = end.Move(nrunes, h.Buf)
1084+
end = buffer.Loc{end.X + searchLoc.X - locs[1].X, end.Y}
10811085
}
10821086
h.Cursor.Loc = searchLoc
10831087
nreplaced++

internal/buffer/buffer.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -269,13 +269,13 @@ type Buffer struct {
269269
}
270270

271271
// NewBufferFromFileWithCommand opens a new buffer with a given command
272-
// If cmd.StartCursor is {-1, -1} the location does not overwrite what the cursor location
272+
// If cmd.StartCursor is invalid, the location does not overwrite what the cursor location
273273
// would otherwise be (start of file, or saved cursor position if `savecursor` is
274274
// enabled)
275275
func NewBufferFromFileWithCommand(path string, btype BufType, cmd Command) (*Buffer, error) {
276276
var err error
277277
filename := path
278-
if config.GetGlobalOption("parsecursor").(bool) && cmd.StartCursor.X == -1 && cmd.StartCursor.Y == -1 {
278+
if config.GetGlobalOption("parsecursor").(bool) && !cmd.StartCursor.IsValid() {
279279
var cursorPos []string
280280
filename, cursorPos = util.GetPathAndCursorPosition(filename)
281281
cmd.StartCursor, err = ParseCursorLocation(cursorPos)

internal/buffer/eventhandler.go

Lines changed: 14 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,8 @@ type TextEvent struct {
3030
C Cursor
3131

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

115117
// ExecuteTextEvent runs a text event
116118
func ExecuteTextEvent(t *TextEvent, buf *SharedBuffer) {
117-
if t.EventType == TextEventInsert {
118-
for _, d := range t.Deltas {
119+
for i := len(t.Deltas) - 1; i >= 0; i-- {
120+
// Processing the deltas in increasing order would require
121+
// to recompute the positions of the later deltas
122+
d := t.Deltas[i]
123+
if t.EventType == TextEventInsert {
119124
buf.insert(d.Start, d.Text)
120-
}
121-
} else if t.EventType == TextEventRemove {
122-
for i, d := range t.Deltas {
125+
} else if t.EventType == TextEventRemove {
123126
t.Deltas[i].Text = buf.remove(d.Start, d.End)
124-
}
125-
} else if t.EventType == TextEventReplace {
126-
for i, d := range t.Deltas {
127+
} else { // TextEventReplace
127128
t.Deltas[i].Text = buf.remove(d.Start, d.End)
128129
buf.insert(d.Start, d.Text)
129130
t.Deltas[i].Start = d.Start
130131
t.Deltas[i].End = Loc{d.Start.X + util.CharacterCount(d.Text), d.Start.Y}
131132
}
132-
for i, j := 0, len(t.Deltas)-1; i < j; i, j = i+1, j-1 {
133-
t.Deltas[i], t.Deltas[j] = t.Deltas[j], t.Deltas[i]
134-
}
133+
}
134+
135+
for i, j := 0, len(t.Deltas)-1; i < j; i, j = i+1, j-1 {
136+
t.Deltas[i], t.Deltas[j] = t.Deltas[j], t.Deltas[i]
135137
}
136138
}
137139

@@ -195,7 +197,7 @@ func (eh *EventHandler) InsertBytes(start Loc, text []byte) {
195197
e := &TextEvent{
196198
C: *eh.cursors[eh.active],
197199
EventType: TextEventInsert,
198-
Deltas: []Delta{{text, start, Loc{0, 0}}},
200+
Deltas: []Delta{{text, start, Loc{-1, -1}}},
199201
Time: time.Now(),
200202
}
201203
eh.DoTextEvent(e, true)

internal/buffer/loc.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,11 @@ type Loc struct {
99
X, Y int
1010
}
1111

12+
// IsValid returns true if the argument is an actual buffer location
13+
func (l Loc) IsValid() bool {
14+
return l.X >= 0 && l.Y >= 0
15+
}
16+
1217
// LessThan returns true if b is smaller
1318
func (l Loc) LessThan(b Loc) bool {
1419
if l.Y < b.Y {

0 commit comments

Comments
 (0)