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.
// This is used for line and word selection where it is necessary
// to know what the original selection was
OrigSelection [2]Loc
+
+ // Which cursor index is this (for multiple cursors)
+ Num int
}
// Goto puts the cursor at the given cursor's location and gives the current cursor its selection too
c.OrigSelection, c.CurSelection = b.OrigSelection, b.CurSelection
}
+// 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) {
+ clipboard.WriteAll(c.GetSelection(), target)
+ }
+ }
+}
+
// ResetSelection resets the user's selection
func (c *Cursor) ResetSelection() {
c.CurSelection[0] = c.buf.Start()
// SetSelectionStart sets the start of the selection
func (c *Cursor) SetSelectionStart(pos Loc) {
c.CurSelection[0] = pos
- // Copy to primary clipboard for linux
- if c.HasSelection() {
- clipboard.WriteAll(c.GetSelection(), "primary")
- }
}
// SetSelectionEnd sets the end of the selection
func (c *Cursor) SetSelectionEnd(pos Loc) {
c.CurSelection[1] = pos
- // Copy to primary clipboard for linux
- if c.HasSelection() {
- clipboard.WriteAll(c.GetSelection(), "primary")
- }
}
// HasSelection returns whether or not the user has selected anything
// GetSelection returns the cursor's selection
func (c *Cursor) GetSelection() string {
- if c.CurSelection[0].GreaterThan(c.CurSelection[1]) {
- return c.buf.Substr(c.CurSelection[1], c.CurSelection[0])
+ if InBounds(c.CurSelection[0], c.buf) && InBounds(c.CurSelection[1], c.buf) {
+ if c.CurSelection[0].GreaterThan(c.CurSelection[1]) {
+ return c.buf.Substr(c.CurSelection[1], c.CurSelection[0])
+ }
+ return c.buf.Substr(c.CurSelection[0], c.CurSelection[1])
}
- return c.buf.Substr(c.CurSelection[0], c.CurSelection[1])
+ return ""
}
// SelectLine selects the current line
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)
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)
}
+// 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() {