]> git.lizzy.rs Git - micro.git/blobdiff - cmd/micro/view.go
Add scrollmargin option, rename scrollSpeed to scrollspeed for consistency, make...
[micro.git] / cmd / micro / view.go
index be7ff115b9aea069240c94f9da8685a9fd81ff89..22a304c31c111b6d44e324bfaa23863fedb6581f 100644 (file)
@@ -110,7 +110,11 @@ func (v *View) Resize(w, h int) {
        h--
        v.width = int(float32(w) * float32(v.widthPercent) / 100)
        // We subtract 1 for the statusline
-       v.height = int(float32(h)*float32(v.heightPercent)/100) - 1
+       v.height = int(float32(h) * float32(v.heightPercent) / 100)
+       if settings["statusline"].(bool) {
+               // Make room for the status line if it is enabled
+               v.height--
+       }
 }
 
 // ScrollUp scrolls the view up n lines (if possible)
@@ -138,7 +142,7 @@ func (v *View) ScrollDown(n int) {
 // causing them to lose the unsaved changes
 // The message is what to print after saying "You have unsaved changes. "
 func (v *View) CanClose(msg string) bool {
-       if v.Buf.IsDirty() {
+       if v.Buf.IsModified {
                quit, canceled := messenger.Prompt("You have unsaved changes. " + msg)
                if !canceled {
                        if strings.ToLower(quit) == "yes" || strings.ToLower(quit) == "y" {
@@ -192,21 +196,24 @@ func (v *View) ReOpen() {
                v.Buf = buf
                v.matches = Match(v)
                v.Cursor.Relocate()
-               v.Relocate()
+               v.Relocate(0)
        }
 }
 
 // Relocate moves the view window so that the cursor is in view
 // This is useful if the user has scrolled far away, and then starts typing
-func (v *View) Relocate() bool {
+func (v *View) Relocate(x int) bool {
        ret := false
        cy := v.Cursor.y
-       if cy < v.Topline {
+       if cy < v.Topline+x && cy > x-1 {
+               v.Topline = cy - x
+               ret = true
+       } else if cy < v.Topline {
                v.Topline = cy
                ret = true
        }
-       if cy > v.Topline+v.height-1 {
-               v.Topline = cy - v.height + 1
+       if cy > v.Topline+v.height-1-x {
+               v.Topline = cy - v.height + 1 + x
                ret = true
        }
 
@@ -253,6 +260,7 @@ func (v *View) HandleEvent(event tcell.Event) {
        // This bool determines whether the view is relocated at the end of the function
        // By default it's true because most events should cause a relocate
        relocate := true
+       scrollmargin := int(settings["scrollmargin"].(float64))
 
        switch e := event.(type) {
        case *tcell.EventResize:
@@ -269,13 +277,15 @@ func (v *View) HandleEvent(event tcell.Event) {
                        v.Cursor.Right()
                } else {
                        for key, action := range bindings {
-                               if e.Key() == key {
-                                       relocate = action(v)
-                                       for _, pl := range loadedPlugins {
-                                               funcName := strings.Split(runtime.FuncForPC(reflect.ValueOf(action).Pointer()).Name(), ".")
-                                               err := Call(pl + "_on" + funcName[len(funcName)-1])
-                                               if err != nil {
-                                                       TermMessage(err)
+                               if e.Key() == key.keyCode {
+                                       if e.Modifiers() == key.modifiers {
+                                               relocate = action(v)
+                                               for _, pl := range loadedPlugins {
+                                                       funcName := strings.Split(runtime.FuncForPC(reflect.ValueOf(action).Pointer()).Name(), ".")
+                                                       err := Call(pl + "_on" + funcName[len(funcName)-1])
+                                                       if err != nil {
+                                                               TermMessage(err)
+                                                       }
                                                }
                                        }
                                }
@@ -294,13 +304,15 @@ func (v *View) HandleEvent(event tcell.Event) {
                x, y := e.Position()
                x -= v.lineNumOffset - v.leftCol
                y += v.Topline
+               // Don't relocate for mouse events
+               relocate = false
 
                button := e.Buttons()
 
                switch button {
                case tcell.Button1:
                        // Left click
-                       if v.mouseReleased && !e.HasMotion() {
+                       if v.mouseReleased {
                                v.MoveToMouseClick(x, y)
                                if time.Since(v.lastClickTime)/time.Millisecond < doubleClickThreshold {
                                        if v.doubleClick {
@@ -358,24 +370,19 @@ func (v *View) HandleEvent(event tcell.Event) {
                                }
                                v.mouseReleased = true
                        }
-                       // We don't want to relocate because otherwise the view will be relocated
-                       // every time the user moves the cursor
-                       relocate = false
                case tcell.WheelUp:
-                       // Scroll up two lines
-                       v.ScrollUp(2)
-                       // We don't want to relocate if the user is scrolling
-                       relocate = false
+                       // Scroll up
+                       scrollspeed := int(settings["scrollspeed"].(float64))
+                       v.ScrollUp(scrollspeed)
                case tcell.WheelDown:
-                       // Scroll down two lines
-                       v.ScrollDown(2)
-                       // We don't want to relocate if the user is scrolling
-                       relocate = false
+                       // Scroll down
+                       scrollspeed := int(settings["scrollspeed"].(float64))
+                       v.ScrollDown(scrollspeed)
                }
        }
 
        if relocate {
-               v.Relocate()
+               v.Relocate(scrollmargin)
        }
        if settings["syntax"].(bool) {
                v.matches = Match(v)
@@ -401,10 +408,18 @@ func (v *View) GutterMessage(section string, lineN int, msg string, kind int) {
        v.messages[section] = append(messages, gutterMsg)
 }
 
+// ClearGutterMessages clears all gutter messages from a given section
 func (v *View) ClearGutterMessages(section string) {
        v.messages[section] = []GutterMessage{}
 }
 
+// ClearAllGutterMessages clears all the gutter messages
+func (v *View) ClearAllGutterMessages() {
+       for k := range v.messages {
+               v.messages[k] = []GutterMessage{}
+       }
+}
+
 // DisplayView renders the view to the screen
 func (v *View) DisplayView() {
        // The character number of the character in the top left of the screen
@@ -533,7 +548,22 @@ func (v *View) DisplayView() {
                        }
 
                        if ch == '\t' {
-                               screen.SetContent(x+tabchars, lineN, ' ', nil, lineStyle)
+                               lineIndentStyle := defStyle
+                               if style, ok := colorscheme["indent-char"]; ok {
+                                       lineIndentStyle = style
+                               }
+                               if v.Cursor.HasSelection() &&
+                                       (charNum >= v.Cursor.curSelection[0] && charNum < v.Cursor.curSelection[1] ||
+                                               charNum < v.Cursor.curSelection[0] && charNum >= v.Cursor.curSelection[1]) {
+
+                                       lineIndentStyle = tcell.StyleDefault.Reverse(true)
+
+                                       if style, ok := colorscheme["selection"]; ok {
+                                               lineIndentStyle = style
+                                       }
+                               }
+                               indentChar := []rune(settings["indentchar"].(string))
+                               screen.SetContent(x-v.leftCol+tabchars, lineN, indentChar[0], nil, lineIndentStyle)
                                tabSize := int(settings["tabsize"].(float64))
                                for i := 0; i < tabSize-1; i++ {
                                        tabchars++
@@ -573,5 +603,7 @@ func (v *View) DisplayView() {
 func (v *View) Display() {
        v.DisplayView()
        v.Cursor.Display()
-       v.sline.Display()
+       if settings["statusline"].(bool) {
+               v.sline.Display()
+       }
 }