]> git.lizzy.rs Git - micro.git/blob - cmd/micro/search.go
Use a buffer for help screen
[micro.git] / cmd / micro / search.go
1 package main
2
3 import (
4         "github.com/gdamore/tcell"
5         "regexp"
6 )
7
8 var (
9         // What was the last search
10         lastSearch string
11
12         // Where should we start the search down from (or up from)
13         searchStart int
14
15         // Is there currently a search in progress
16         searching bool
17 )
18
19 // BeginSearch starts a search
20 func BeginSearch() {
21         searching = true
22         messenger.hasPrompt = true
23         messenger.Message("Find: ")
24 }
25
26 // EndSearch stops the current search
27 func EndSearch() {
28         searching = false
29         messenger.hasPrompt = false
30         messenger.Clear()
31         messenger.Reset()
32 }
33
34 // HandleSearchEvent takes an event and a view and will do a real time match from the messenger's output
35 // to the current buffer. It searches down the buffer.
36 func HandleSearchEvent(event tcell.Event, v *View) {
37         switch e := event.(type) {
38         case *tcell.EventKey:
39                 switch e.Key() {
40                 case tcell.KeyCtrlQ, tcell.KeyCtrlC, tcell.KeyEscape, tcell.KeyEnter:
41                         // Done
42                         EndSearch()
43                         return
44                 }
45         }
46
47         messenger.HandleEvent(event)
48
49         if messenger.cursorx < 0 {
50                 // Done
51                 EndSearch()
52                 return
53         }
54
55         if messenger.response == "" {
56                 v.cursor.ResetSelection()
57                 // We don't end the search though
58                 return
59         }
60
61         Search(messenger.response, v, true)
62
63         return
64 }
65
66 // Search searches in the view for the given regex. The down bool
67 // specifies whether it should search down from the searchStart position
68 // or up from there
69 func Search(searchStr string, v *View, down bool) {
70         if searchStr == "" {
71                 return
72         }
73         var str string
74         var charPos int
75         if down {
76                 str = v.buf.text[searchStart:]
77                 charPos = searchStart
78         } else {
79                 str = v.buf.text[:searchStart]
80         }
81         r, err := regexp.Compile(searchStr)
82         if err != nil {
83                 return
84         }
85         matches := r.FindAllStringIndex(str, -1)
86         var match []int
87         if matches == nil {
88                 // Search the entire buffer now
89                 matches = r.FindAllStringIndex(v.buf.text, -1)
90                 charPos = 0
91                 if matches == nil {
92                         v.cursor.ResetSelection()
93                         return
94                 }
95
96                 if !down {
97                         match = matches[len(matches)-1]
98                 } else {
99                         match = matches[0]
100                 }
101         }
102
103         if !down {
104                 match = matches[len(matches)-1]
105         } else {
106                 match = matches[0]
107         }
108
109         v.cursor.curSelection[0] = charPos + match[0]
110         v.cursor.curSelection[1] = charPos + match[1]
111         v.cursor.x, v.cursor.y = FromCharPos(charPos+match[1]-1, v.buf)
112         if v.Relocate() {
113                 v.matches = Match(v)
114         }
115         lastSearch = searchStr
116 }