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.
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) {
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
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])
}
return line[x]
}
-
// UpN moves the cursor up N lines (if possible)
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) {
+ runes := []rune(c.buf.Line(proposedY))
+ 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)
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
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
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)
+// StartOfText moves the cursor to the first non-whitespace rune of
+// the line it is on
+func (c *Cursor) StartOfText() {
+ c.Start()
+ for IsWhitespace(c.RuneUnder(c.X)) {
+ if c.X == Count(c.buf.Line(c.Y)) {
+ break
+ }
+ c.Right()
+ }
+}
+
+// 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))
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