package main
+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.
// The cursor must be displayed at an x, y location, but since the buffer
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()
c.CurSelection[1] = c.buf.Start()
}
+// SetSelectionStart sets the start of the selection
+func (c *Cursor) SetSelectionStart(pos Loc) {
+ c.CurSelection[0] = pos
+}
+
+// SetSelectionEnd sets the end of the selection
+func (c *Cursor) SetSelectionEnd(pos Loc) {
+ c.CurSelection[1] = pos
+}
+
// HasSelection returns whether or not the user has selected anything
func (c *Cursor) HasSelection() bool {
return c.CurSelection[0] != c.CurSelection[1]
if c.CurSelection[0].GreaterThan(c.CurSelection[1]) {
c.buf.Remove(c.CurSelection[1], c.CurSelection[0])
c.Loc = c.CurSelection[1]
- } else if c.GetSelection() == "" {
+ } else if !c.HasSelection() {
return
} else {
c.buf.Remove(c.CurSelection[0], c.CurSelection[1])
// 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
func (c *Cursor) SelectLine() {
c.Start()
- c.CurSelection[0] = c.Loc
+ c.SetSelectionStart(c.Loc)
c.End()
if c.buf.NumLines-1 > c.Y {
- c.CurSelection[1] = c.Loc.Move(1, c.buf)
+ c.SetSelectionEnd(c.Loc.Move(1, c.buf))
} else {
- c.CurSelection[1] = c.Loc
+ c.SetSelectionEnd(c.Loc)
}
c.OrigSelection = c.CurSelection
func (c *Cursor) AddLineToSelection() {
if c.Loc.LessThan(c.OrigSelection[0]) {
c.Start()
- c.CurSelection[0] = c.Loc
- c.CurSelection[1] = c.OrigSelection[1]
+ c.SetSelectionStart(c.Loc)
+ c.SetSelectionEnd(c.OrigSelection[1])
}
if c.Loc.GreaterThan(c.OrigSelection[1]) {
c.End()
- c.CurSelection[1] = c.Loc.Move(1, c.buf)
- c.CurSelection[0] = c.OrigSelection[0]
+ c.SetSelectionEnd(c.Loc.Move(1, c.buf))
+ c.SetSelectionStart(c.OrigSelection[0])
}
if c.Loc.LessThan(c.OrigSelection[1]) && c.Loc.GreaterThan(c.OrigSelection[0]) {
}
if !IsWordChar(string(c.RuneUnder(c.X))) {
- c.CurSelection[0] = c.Loc
- c.CurSelection[1] = c.Loc.Move(1, c.buf)
+ c.SetSelectionStart(c.Loc)
+ c.SetSelectionEnd(c.Loc.Move(1, c.buf))
c.OrigSelection = c.CurSelection
return
}
backward--
}
- c.CurSelection[0] = Loc{backward, c.Y}
+ c.SetSelectionStart(Loc{backward, c.Y})
c.OrigSelection[0] = c.CurSelection[0]
for forward < Count(c.buf.Line(c.Y))-1 && IsWordChar(string(c.RuneUnder(forward+1))) {
forward++
}
- c.CurSelection[1] = Loc{forward, c.Y}.Move(1, c.buf)
+ c.SetSelectionEnd(Loc{forward, c.Y}.Move(1, c.buf))
c.OrigSelection[1] = c.CurSelection[1]
c.Loc = c.CurSelection[1]
}
backward--
}
- c.CurSelection[0] = Loc{backward, c.Y}
- c.CurSelection[1] = c.OrigSelection[1]
+ c.SetSelectionStart(Loc{backward, c.Y})
+ c.SetSelectionEnd(c.OrigSelection[1])
}
if c.Loc.GreaterThan(c.OrigSelection[1]) {
forward++
}
- c.CurSelection[1] = Loc{forward, c.Y}.Move(1, c.buf)
- c.CurSelection[0] = c.OrigSelection[0]
+ c.SetSelectionEnd(Loc{forward, c.Y}.Move(1, c.buf))
+ c.SetSelectionStart(c.OrigSelection[0])
}
c.Loc = c.CurSelection[1]
// SelectTo selects from the current cursor location to the given location
func (c *Cursor) SelectTo(loc Loc) {
if loc.GreaterThan(c.OrigSelection[0]) {
- c.CurSelection[0] = c.OrigSelection[0]
- c.CurSelection[1] = loc
+ c.SetSelectionStart(c.OrigSelection[0])
+ c.SetSelectionEnd(loc)
} else {
- c.CurSelection[0] = loc
- c.CurSelection[1] = c.OrigSelection[0]
+ c.SetSelectionStart(loc)
+ c.SetSelectionEnd(c.OrigSelection[0])
}
}
// WordRight moves the cursor one word to the right
func (c *Cursor) WordRight() {
- c.Right()
for IsWhitespace(c.RuneUnder(c.X)) {
if c.X == Count(c.buf.Line(c.Y)) {
+ c.Right()
return
}
c.Right()
}
- for !IsWhitespace(c.RuneUnder(c.X)) {
+ c.Right()
+ for IsWordChar(string(c.RuneUnder(c.X))) {
if c.X == Count(c.buf.Line(c.Y)) {
return
}
}
c.Left()
}
- for !IsWhitespace(c.RuneUnder(c.X)) {
+ c.Left()
+ for IsWordChar(string(c.RuneUnder(c.X))) {
if c.X == 0 {
return
}
// 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(settings["tabsize"].(float64))
- // This is the visual line -- every \t replaced with the correct number of spaces
- visualLineLen := StringWidth(c.buf.Line(lineNum))
+ tabSize := int(c.buf.Settings["tabsize"].(float64))
+ visualLineLen := StringWidth(c.buf.Line(lineNum), tabSize)
if visualPos > visualLineLen {
visualPos = visualLineLen
}
- width := WidthOfLargeRunes(c.buf.Line(lineNum))
+ width := WidthOfLargeRunes(c.buf.Line(lineNum), tabSize)
if visualPos >= width {
return visualPos - width
}
// GetVisualX returns the x value of the cursor in visual spaces
func (c *Cursor) GetVisualX() int {
runes := []rune(c.buf.Line(c.Y))
- return StringWidth(string(runes[:c.X]))
+ tabSize := int(c.buf.Settings["tabsize"].(float64))
+ return StringWidth(string(runes[:c.X]), tabSize)
}
// Relocate makes sure that the cursor is inside the bounds of the buffer