X-Git-Url: https://git.lizzy.rs/?a=blobdiff_plain;f=cmd%2Fmicro%2Fcursor.go;h=15b01010eec9879ba45dbaf8fda1b5c8c1e41c10;hb=aaf098bb472207352c5b67c7d8f30b9c28763df3;hp=2682dee4640e3531eeccd431b82547cf4166eac1;hpb=7ccec0e3f7af8751921d9324125055ec6b4413f7;p=micro.git diff --git a/cmd/micro/cursor.go b/cmd/micro/cursor.go index 2682dee4..15b01010 100644 --- a/cmd/micro/cursor.go +++ b/cmd/micro/cursor.go @@ -1,6 +1,8 @@ package main -import "github.com/zyedidia/clipboard" +import ( + "github.com/zyedidia/clipboard" +) // The Cursor struct stores the location of the cursor in the view // The complicated part about the cursor is storing its location. @@ -26,13 +28,22 @@ type Cursor struct { Num int } -// Goto puts the cursor at the given cursor's location and gives the current cursor its selection too +// Goto puts the cursor at the given cursor's location and gives +// the current cursor its selection too func (c *Cursor) Goto(b Cursor) { c.X, c.Y, c.LastVisualX = b.X, b.Y, b.LastVisualX c.OrigSelection, c.CurSelection = b.OrigSelection, b.CurSelection } -// CopySelection copies the user's selection to either "primary" or "clipboard" +// GotoLoc puts the cursor at the given cursor's location and gives +// the current cursor its selection too +func (c *Cursor) GotoLoc(l Loc) { + c.X, c.Y = l.X, l.Y + c.LastVisualX = c.GetVisualX() +} + +// CopySelection copies the user's selection to either "primary" +// or "clipboard" func (c *Cursor) CopySelection(target string) { if c.HasSelection() { if target != "primary" || c.buf.Settings["useprimary"].(bool) { @@ -149,7 +160,8 @@ func (c *Cursor) SelectWord() { c.Loc = c.CurSelection[1] } -// AddWordToSelection adds the word the cursor is currently on to the selection +// AddWordToSelection adds the word the cursor is currently on +// to the selection func (c *Cursor) AddWordToSelection() { if c.Loc.GreaterThan(c.OrigSelection[0]) && c.Loc.LessThan(c.OrigSelection[1]) { c.CurSelection = c.OrigSelection @@ -181,7 +193,8 @@ func (c *Cursor) AddWordToSelection() { c.Loc = c.CurSelection[1] } -// SelectTo selects from the current cursor location to the given location +// SelectTo selects from the current cursor location to the given +// location func (c *Cursor) SelectTo(loc Loc) { if loc.GreaterThan(c.OrigSelection[0]) { c.SetSelectionStart(c.OrigSelection[0]) @@ -248,19 +261,19 @@ func (c *Cursor) UpN(amount int) { proposedY := c.Y - amount if proposedY < 0 { proposedY = 0 + c.LastVisualX = 0 } else if proposedY >= c.buf.NumLines { proposedY = c.buf.NumLines - 1 } - if proposedY == c.Y { - return - } - c.Y = proposedY runes := []rune(c.buf.Line(c.Y)) - c.X = c.GetCharPosInLine(c.Y, c.LastVisualX) - if c.X > len(runes) { + c.X = c.GetCharPosInLine(proposedY, c.LastVisualX) + + if c.X > len(runes) || (amount < 0 && proposedY == c.Y) { c.X = len(runes) } + + c.Y = proposedY } // DownN moves the cursor down N lines (if possible) @@ -278,7 +291,8 @@ func (c *Cursor) Down() { c.DownN(1) } -// Left moves the cursor left one cell (if possible) or to the last line if it is at the beginning +// Left moves the cursor left one cell (if possible) or to +// the previous line if it is at the beginning func (c *Cursor) Left() { if c.Loc == c.buf.Start() { return @@ -292,7 +306,8 @@ func (c *Cursor) Left() { c.LastVisualX = c.GetVisualX() } -// Right moves the cursor right one cell (if possible) or to the next line if it is at the end +// Right moves the cursor right one cell (if possible) or +// to the next line if it is at the end func (c *Cursor) Right() { if c.Loc == c.buf.End() { return @@ -318,7 +333,9 @@ func (c *Cursor) Start() { c.LastVisualX = c.GetVisualX() } -// GetCharPosInLine gets the char position of a visual x y coordinate (this is necessary because tabs are 1 char but 4 visual spaces) +// GetCharPosInLine gets the char position of a visual x y +// coordinate (this is necessary because tabs are 1 char but +// 4 visual spaces) func (c *Cursor) GetCharPosInLine(lineNum, visualPos int) int { // Get the tab size tabSize := int(c.buf.Settings["tabsize"].(float64)) @@ -337,11 +354,25 @@ func (c *Cursor) GetCharPosInLine(lineNum, visualPos int) int { func (c *Cursor) GetVisualX() int { runes := []rune(c.buf.Line(c.Y)) tabSize := int(c.buf.Settings["tabsize"].(float64)) + if c.X > len(runes) { + c.X = len(runes) - 1 + } + + if c.X < 0 { + c.X = 0 + } + return StringWidth(string(runes[:c.X]), tabSize) } -// Relocate makes sure that the cursor is inside the bounds of the buffer -// If it isn't, it moves it to be within the buffer's lines +// StoreVisualX stores the current visual x value in the cursor +func (c *Cursor) StoreVisualX() { + c.LastVisualX = c.GetVisualX() +} + +// Relocate makes sure that the cursor is inside the bounds +// of the buffer If it isn't, it moves it to be within the +// buffer's lines func (c *Cursor) Relocate() { if c.Y < 0 { c.Y = 0