diff --git a/cmd/micro/bindings.go b/cmd/micro/bindings.go index 613b80fb..c3af4cb9 100644 --- a/cmd/micro/bindings.go +++ b/cmd/micro/bindings.go @@ -915,11 +915,13 @@ func (v *View) OpenFile() bool { filename = strings.Replace(filename, "~", home, 1) file, err := ioutil.ReadFile(filename) + var buf *Buffer if err != nil { - messenger.Error(err.Error()) - return false + // File does not exist -- create an empty buffer with that name + buf = NewBuffer([]byte{}, filename) + } else { + buf = NewBuffer(file, filename) } - buf := NewBuffer(file, filename) v.OpenBuffer(buf) return true } @@ -1090,7 +1092,27 @@ func (v *View) Quit() bool { // Make sure not to quit if there are unsaved changes if v.CanClose("Quit anyway? (yes, no, save) ") { v.CloseBuffer() - if len(tabs) > 1 { + if len(tabs[curTab].views) > 1 { + var view *View + if v.splitChild != nil { + view = v.splitChild + view.splitParent = v.splitParent + } else if v.splitParent != nil { + view = v.splitParent + v.splitParent.splitChild = nil + } + view.x, view.y = view.splitOrigPos[0], view.splitOrigPos[1] + view.widthPercent, view.heightPercent = view.splitOrigDimensions[0], view.splitOrigDimensions[1] + view.Resize(screen.Size()) + if settings["syntax"].(bool) { + view.matches = Match(view) + } + tabs[curTab].views = tabs[curTab].views[:v.Num+copy(tabs[curTab].views[v.Num:], tabs[curTab].views[v.Num+1:])] + for i, v := range tabs[curTab].views { + v.Num = i + } + tabs[curTab].curView = view.Num + } else if len(tabs) > 1 { if len(tabs[v.TabNum].views) == 1 { tabs = tabs[:v.TabNum+copy(tabs[v.TabNum:], tabs[v.TabNum+1:])] for i, t := range tabs { diff --git a/cmd/micro/command.go b/cmd/micro/command.go index 05dd7645..54c2aa3d 100644 --- a/cmd/micro/command.go +++ b/cmd/micro/command.go @@ -2,11 +2,14 @@ package main import ( "bytes" + "io/ioutil" "os" "os/exec" "os/signal" "regexp" "strings" + + "github.com/mitchellh/go-homedir" ) var commands map[string]func([]string) @@ -63,11 +66,48 @@ func DefaultCommands() map[string]string { } } +// VSplit opens a vertical split with file given in the first argument +// If no file is given, it opens an empty buffer in a new split func VSplit(args []string) { - CurView().VSplit() + if len(args) == 0 { + CurView().VSplit(NewBuffer([]byte{}, "")) + } else { + filename := args[0] + home, _ := homedir.Dir() + filename = strings.Replace(filename, "~", home, 1) + file, err := ioutil.ReadFile(filename) + + var buf *Buffer + if err != nil { + // File does not exist -- create an empty buffer with that name + buf = NewBuffer([]byte{}, filename) + } else { + buf = NewBuffer(file, filename) + } + CurView().VSplit(buf) + } } + +// HSplit opens a horizontal split with file given in the first argument +// If no file is given, it opens an empty buffer in a new split func HSplit(args []string) { - CurView().HSplit() + if len(args) == 0 { + CurView().HSplit(NewBuffer([]byte{}, "")) + } else { + filename := args[0] + home, _ := homedir.Dir() + filename = strings.Replace(filename, "~", home, 1) + file, err := ioutil.ReadFile(filename) + + var buf *Buffer + if err != nil { + // File does not exist -- create an empty buffer with that name + buf = NewBuffer([]byte{}, filename) + } else { + buf = NewBuffer(file, filename) + } + CurView().HSplit(buf) + } } // Set sets an option diff --git a/cmd/micro/micro.go b/cmd/micro/micro.go index 859277ab..e62c93fa 100644 --- a/cmd/micro/micro.go +++ b/cmd/micro/micro.go @@ -281,11 +281,17 @@ func main() { case *tcell.EventMouse: if e.Buttons() == tcell.Button1 { _, h := screen.Size() - _, y := e.Position() + x, y := e.Position() if y == h-1 && messenger.message != "" { clipboard.WriteAll(messenger.message) continue } + + for _, v := range tabs[curTab].views { + if x >= v.x && x < v.x+v.width && y >= v.y && y < v.y+v.height { + tabs[curTab].curView = v.Num + } + } } } diff --git a/cmd/micro/view.go b/cmd/micro/view.go index ff004fb9..79d1dfa3 100644 --- a/cmd/micro/view.go +++ b/cmd/micro/view.go @@ -87,6 +87,11 @@ type View struct { matches SyntaxMatches // The matches from the last frame lastMatches SyntaxMatches + + splitParent *View + splitChild *View + splitOrigDimensions [2]int + splitOrigPos [2]int } // NewView returns a new fullscreen view @@ -222,32 +227,56 @@ func (v *View) ReOpen() { } } -func (v *View) HSplit() bool { +// HSplit opens a horizontal split with the given buffer +func (v *View) HSplit(buf *Buffer) bool { + origDimensions := [2]int{v.widthPercent, v.heightPercent} + origPos := [2]int{v.x, v.y} + v.heightPercent /= 2 v.Resize(screen.Size()) - newView := NewViewWidthHeight(NewBuffer([]byte{}, ""), v.widthPercent, v.heightPercent) + newView := NewViewWidthHeight(buf, v.widthPercent, v.heightPercent) + + v.splitOrigDimensions = origDimensions + v.splitOrigPos = origPos + newView.splitOrigDimensions = origDimensions + newView.splitOrigPos = origPos + newView.TabNum = v.TabNum newView.y = v.y + v.height + 1 newView.x = v.x tab := tabs[v.TabNum] tab.curView++ newView.Num = len(tab.views) + newView.splitParent = v + v.splitChild = newView tab.views = append(tab.views, newView) return false } -func (v *View) VSplit() bool { +// VSplit opens a vertical split with the given buffer +func (v *View) VSplit(buf *Buffer) bool { + origDimensions := [2]int{v.widthPercent, v.heightPercent} + origPos := [2]int{v.x, v.y} + v.widthPercent /= 2 v.Resize(screen.Size()) - newView := NewViewWidthHeight(NewBuffer([]byte{}, ""), v.widthPercent, v.heightPercent) + newView := NewViewWidthHeight(buf, v.widthPercent, v.heightPercent) + + v.splitOrigDimensions = origDimensions + v.splitOrigPos = origPos + newView.splitOrigDimensions = origDimensions + newView.splitOrigPos = origPos + newView.TabNum = v.TabNum newView.y = v.y newView.x = v.x + v.width tab := tabs[v.TabNum] tab.curView++ newView.Num = len(tab.views) + newView.splitParent = v + v.splitChild = newView tab.views = append(tab.views, newView) return false } @@ -638,7 +667,7 @@ func (v *View) DisplayView() { lineStyle = highlightStyle } - if settings["cursorline"].(bool) && !v.Cursor.HasSelection() && v.Cursor.Y == lineN+v.Topline { + if settings["cursorline"].(bool) && tabs[curTab].curView == v.Num && !v.Cursor.HasSelection() && v.Cursor.Y == lineN+v.Topline { if style, ok := colorscheme["cursor-line"]; ok { fg, _, _ := style.Decompose() lineStyle = lineStyle.Background(fg) @@ -742,7 +771,9 @@ func (v *View) DisplayCursor() { // Display renders the view, the cursor, and statusline func (v *View) Display() { v.DisplayView() - v.DisplayCursor() + if v.Num == tabs[curTab].curView { + v.DisplayCursor() + } if settings["statusline"].(bool) { v.sline.Display() }