mirror of
https://github.com/zyedidia/micro.git
synced 2026-03-31 15:17:15 +09:00
Compare commits
1 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
6f302826c8 |
@@ -62,71 +62,54 @@ func (v *View) MousePress(usePlugin bool, e *tcell.EventMouse) bool {
|
||||
return false
|
||||
}
|
||||
|
||||
rawX, rawY := e.Position()
|
||||
|
||||
x := rawX - v.lineNumOffset - v.leftCol + v.x
|
||||
y := rawY + v.Topline - v.y
|
||||
x, y := e.Position()
|
||||
x -= v.lineNumOffset - v.leftCol + v.x
|
||||
y += v.Topline - v.y
|
||||
|
||||
// This is usually bound to left click
|
||||
if !(rawX == v.x+v.Width || rawY == v.y+v.Height || v.resizeX || v.resizeY) {
|
||||
v.MoveToMouseClick(x, y)
|
||||
}
|
||||
v.MoveToMouseClick(x, y)
|
||||
if v.mouseReleased {
|
||||
if rawX == v.x+v.Width {
|
||||
v.resizeX = true
|
||||
} else if rawY == v.y+v.Height {
|
||||
v.resizeY = true
|
||||
} else {
|
||||
if len(v.Buf.cursors) > 1 {
|
||||
for i := 1; i < len(v.Buf.cursors); i++ {
|
||||
v.Buf.cursors[i] = nil
|
||||
}
|
||||
v.Buf.cursors = v.Buf.cursors[:1]
|
||||
v.Buf.UpdateCursors()
|
||||
v.Cursor.ResetSelection()
|
||||
v.Relocate()
|
||||
if len(v.Buf.cursors) > 1 {
|
||||
for i := 1; i < len(v.Buf.cursors); i++ {
|
||||
v.Buf.cursors[i] = nil
|
||||
}
|
||||
if time.Since(v.lastClickTime)/time.Millisecond < doubleClickThreshold {
|
||||
if v.doubleClick {
|
||||
// Triple click
|
||||
v.lastClickTime = time.Now()
|
||||
|
||||
v.tripleClick = true
|
||||
v.doubleClick = false
|
||||
|
||||
v.Cursor.SelectLine()
|
||||
v.Cursor.CopySelection("primary")
|
||||
} else {
|
||||
// Double click
|
||||
v.lastClickTime = time.Now()
|
||||
|
||||
v.doubleClick = true
|
||||
v.tripleClick = false
|
||||
|
||||
v.Cursor.SelectWord()
|
||||
v.Cursor.CopySelection("primary")
|
||||
}
|
||||
} else {
|
||||
v.doubleClick = false
|
||||
v.tripleClick = false
|
||||
v.Buf.cursors = v.Buf.cursors[:1]
|
||||
v.Buf.UpdateCursors()
|
||||
v.Cursor.ResetSelection()
|
||||
v.Relocate()
|
||||
}
|
||||
if time.Since(v.lastClickTime)/time.Millisecond < doubleClickThreshold {
|
||||
if v.doubleClick {
|
||||
// Triple click
|
||||
v.lastClickTime = time.Now()
|
||||
|
||||
v.Cursor.OrigSelection[0] = v.Cursor.Loc
|
||||
v.Cursor.CurSelection[0] = v.Cursor.Loc
|
||||
v.Cursor.CurSelection[1] = v.Cursor.Loc
|
||||
v.tripleClick = true
|
||||
v.doubleClick = false
|
||||
|
||||
v.Cursor.SelectLine()
|
||||
v.Cursor.CopySelection("primary")
|
||||
} else {
|
||||
// Double click
|
||||
v.lastClickTime = time.Now()
|
||||
|
||||
v.doubleClick = true
|
||||
v.tripleClick = false
|
||||
|
||||
v.Cursor.SelectWord()
|
||||
v.Cursor.CopySelection("primary")
|
||||
}
|
||||
} else {
|
||||
v.doubleClick = false
|
||||
v.tripleClick = false
|
||||
v.lastClickTime = time.Now()
|
||||
|
||||
v.Cursor.OrigSelection[0] = v.Cursor.Loc
|
||||
v.Cursor.CurSelection[0] = v.Cursor.Loc
|
||||
v.Cursor.CurSelection[1] = v.Cursor.Loc
|
||||
}
|
||||
v.mouseReleased = false
|
||||
} else if !v.mouseReleased {
|
||||
if v.resizeX {
|
||||
v.Width = rawX - v.x
|
||||
v.LockWidth = true
|
||||
v.splitNode.parent.ResizeSplits()
|
||||
} else if v.resizeY {
|
||||
v.Height = rawY - v.y
|
||||
v.LockHeight = true
|
||||
v.splitNode.parent.ResizeSplits()
|
||||
} else if v.tripleClick {
|
||||
if v.tripleClick {
|
||||
v.Cursor.AddLineToSelection()
|
||||
} else if v.doubleClick {
|
||||
v.Cursor.AddWordToSelection()
|
||||
@@ -1869,6 +1852,68 @@ func (v *View) PreviousSplit(usePlugin bool) bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func (v *View) WrapBracket(usePlugin bool) bool {
|
||||
if v.Cursor.HasSelection() {
|
||||
lockPollEvent = true
|
||||
event := screen.PollEvent()
|
||||
lockPollEvent = false
|
||||
|
||||
ev, ok := event.(*tcell.EventKey)
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
if !strings.Contains("()[]{}\"'", string(ev.Rune())) {
|
||||
return false
|
||||
}
|
||||
start := v.Cursor.CurSelection[0]
|
||||
end := v.Cursor.CurSelection[1]
|
||||
if start.Y != end.Y {
|
||||
return false
|
||||
}
|
||||
|
||||
close := map[string]string{
|
||||
")": ")",
|
||||
"]": "]",
|
||||
"}": "}",
|
||||
"(": ")",
|
||||
"[": "]",
|
||||
"{": "}",
|
||||
"\"": "\"",
|
||||
"'": "'",
|
||||
}
|
||||
|
||||
open := map[string]string{
|
||||
")": "(",
|
||||
"]": "[",
|
||||
"}": "{",
|
||||
"(": "(",
|
||||
"[": "[",
|
||||
"{": "{",
|
||||
"\"": "\"",
|
||||
"'": "'",
|
||||
}
|
||||
|
||||
if usePlugin && !PreActionCall("WrapBracket", v) {
|
||||
return false
|
||||
}
|
||||
r := string(ev.Rune())
|
||||
if start.GreaterThan(end) {
|
||||
start, end = end, start
|
||||
v.Buf.Insert(start, open[r])
|
||||
v.Buf.Insert(end.Move(1, v.Buf), close[r])
|
||||
v.Cursor.CurSelection[1] = start
|
||||
} else {
|
||||
v.Buf.Insert(start, open[r])
|
||||
v.Buf.Insert(end.Move(1, v.Buf), close[r])
|
||||
v.Cursor.CurSelection[0] = start
|
||||
}
|
||||
if usePlugin {
|
||||
return PostActionCall("WrapBracket", v)
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
var curMacro []interface{}
|
||||
var recordingMacro bool
|
||||
|
||||
|
||||
@@ -69,6 +69,7 @@ var bindingActions = map[string]func(*View, bool) bool{
|
||||
"PastePrimary": (*View).PastePrimary,
|
||||
"SelectAll": (*View).SelectAll,
|
||||
"OpenFile": (*View).OpenFile,
|
||||
"WrapBracket": (*View).WrapBracket,
|
||||
"Start": (*View).Start,
|
||||
"End": (*View).End,
|
||||
"PageUp": (*View).PageUp,
|
||||
@@ -438,6 +439,7 @@ func DefaultBindings() map[string]string {
|
||||
"Down": "CursorDown",
|
||||
"Right": "CursorRight",
|
||||
"Left": "CursorLeft",
|
||||
"Alt-j": "WrapBracket",
|
||||
"ShiftUp": "SelectUp",
|
||||
"ShiftDown": "SelectDown",
|
||||
"ShiftLeft": "SelectLeft",
|
||||
|
||||
@@ -112,9 +112,6 @@ func (c *CellView) Draw(buf *Buffer, top, height, left, width int) {
|
||||
// We'll either draw the length of the line, or the width of the screen
|
||||
// whichever is smaller
|
||||
lineLength := min(StringWidth(lineStr, tabsize), width)
|
||||
if lineLength < 0 {
|
||||
return
|
||||
}
|
||||
c.lines = append(c.lines, make([]*Char, lineLength))
|
||||
|
||||
wrap := false
|
||||
@@ -136,50 +133,38 @@ func (c *CellView) Draw(buf *Buffer, top, height, left, width int) {
|
||||
char := line[colN]
|
||||
|
||||
if viewCol >= 0 {
|
||||
if viewCol < len(c.lines[viewLine]) {
|
||||
c.lines[viewLine][viewCol] = &Char{Loc{viewCol, viewLine}, Loc{colN, lineN}, char, char, curStyle, 1}
|
||||
}
|
||||
c.lines[viewLine][viewCol] = &Char{Loc{viewCol, viewLine}, Loc{colN, lineN}, char, char, curStyle, 1}
|
||||
}
|
||||
if char == '\t' {
|
||||
charWidth := tabsize - (viewCol+left)%tabsize
|
||||
if viewCol >= 0 {
|
||||
if viewCol < len(c.lines[viewLine]) {
|
||||
c.lines[viewLine][viewCol].drawChar = indentchar
|
||||
c.lines[viewLine][viewCol].width = charWidth
|
||||
}
|
||||
c.lines[viewLine][viewCol].drawChar = indentchar
|
||||
c.lines[viewLine][viewCol].width = charWidth
|
||||
|
||||
indentStyle := curStyle
|
||||
if group, ok := colorscheme["indent-char"]; ok {
|
||||
indentStyle = group
|
||||
}
|
||||
|
||||
if viewCol < len(c.lines[viewLine]) {
|
||||
c.lines[viewLine][viewCol].style = indentStyle
|
||||
}
|
||||
c.lines[viewLine][viewCol].style = indentStyle
|
||||
}
|
||||
|
||||
for i := 1; i < charWidth; i++ {
|
||||
viewCol++
|
||||
if viewCol >= 0 && viewCol < lineLength {
|
||||
if viewCol < len(c.lines[viewLine]) {
|
||||
c.lines[viewLine][viewCol] = &Char{Loc{viewCol, viewLine}, Loc{colN, lineN}, char, ' ', curStyle, 1}
|
||||
}
|
||||
c.lines[viewLine][viewCol] = &Char{Loc{viewCol, viewLine}, Loc{colN, lineN}, char, ' ', curStyle, 1}
|
||||
}
|
||||
}
|
||||
viewCol++
|
||||
} else if runewidth.RuneWidth(char) > 1 {
|
||||
charWidth := runewidth.RuneWidth(char)
|
||||
if viewCol >= 0 {
|
||||
if viewCol < len(c.lines[viewLine]) {
|
||||
c.lines[viewLine][viewCol].width = charWidth
|
||||
}
|
||||
c.lines[viewLine][viewCol].width = charWidth
|
||||
}
|
||||
for i := 1; i < charWidth; i++ {
|
||||
viewCol++
|
||||
if viewCol >= 0 && viewCol < lineLength {
|
||||
if viewCol < len(c.lines[viewLine]) {
|
||||
c.lines[viewLine][viewCol] = &Char{Loc{viewCol, viewLine}, Loc{colN, lineN}, char, ' ', curStyle, 1}
|
||||
}
|
||||
c.lines[viewLine][viewCol] = &Char{Loc{viewCol, viewLine}, Loc{colN, lineN}, char, ' ', curStyle, 1}
|
||||
}
|
||||
}
|
||||
viewCol++
|
||||
|
||||
@@ -59,6 +59,9 @@ var (
|
||||
// Event channel
|
||||
events chan tcell.Event
|
||||
autosave chan bool
|
||||
|
||||
// Read events on another thread or wait for a temporary read
|
||||
lockPollEvent bool
|
||||
)
|
||||
|
||||
// LoadInput determines which files should be loaded into buffers
|
||||
@@ -419,8 +422,9 @@ func main() {
|
||||
// Here is the event loop which runs in a separate thread
|
||||
go func() {
|
||||
for {
|
||||
if screen != nil {
|
||||
if screen != nil && !lockPollEvent {
|
||||
events <- screen.PollEvent()
|
||||
time.Sleep(1 * time.Millisecond)
|
||||
}
|
||||
}
|
||||
}()
|
||||
@@ -476,7 +480,7 @@ func main() {
|
||||
// We loop through each view in the current tab and make sure the current view
|
||||
// is the one being clicked in
|
||||
for _, v := range tabs[curTab].views {
|
||||
if x > v.x && x <= v.x+v.Width && y > v.y && y <= v.y+v.Height {
|
||||
if x >= v.x && x < v.x+v.Width && y >= v.y && y < v.y+v.Height {
|
||||
tabs[curTab].CurView = v.Num
|
||||
}
|
||||
}
|
||||
|
||||
@@ -91,9 +91,6 @@ type View struct {
|
||||
cellview *CellView
|
||||
|
||||
splitNode *LeafNode
|
||||
|
||||
resizeX bool
|
||||
resizeY bool
|
||||
}
|
||||
|
||||
// NewView returns a new fullscreen view
|
||||
@@ -602,26 +599,21 @@ func (v *View) HandleEvent(event tcell.Event) {
|
||||
// Mouse event with no click
|
||||
if !v.mouseReleased {
|
||||
// Mouse was just released
|
||||
if v.resizeX || v.resizeY {
|
||||
v.resizeX = false
|
||||
v.resizeY = false
|
||||
} else {
|
||||
|
||||
x, y := e.Position()
|
||||
x -= v.lineNumOffset - v.leftCol + v.x
|
||||
y += v.Topline - v.y
|
||||
x, y := e.Position()
|
||||
x -= v.lineNumOffset - v.leftCol + v.x
|
||||
y += v.Topline - v.y
|
||||
|
||||
// Relocating here isn't really necessary because the cursor will
|
||||
// be in the right place from the last mouse event
|
||||
// However, if we are running in a terminal that doesn't support mouse motion
|
||||
// events, this still allows the user to make selections, except only after they
|
||||
// release the mouse
|
||||
// Relocating here isn't really necessary because the cursor will
|
||||
// be in the right place from the last mouse event
|
||||
// However, if we are running in a terminal that doesn't support mouse motion
|
||||
// events, this still allows the user to make selections, except only after they
|
||||
// release the mouse
|
||||
|
||||
if !v.doubleClick && !v.tripleClick {
|
||||
v.MoveToMouseClick(x, y)
|
||||
v.Cursor.SetSelectionEnd(v.Cursor.Loc)
|
||||
v.Cursor.CopySelection("primary")
|
||||
}
|
||||
if !v.doubleClick && !v.tripleClick {
|
||||
v.MoveToMouseClick(x, y)
|
||||
v.Cursor.SetSelectionEnd(v.Cursor.Loc)
|
||||
v.Cursor.CopySelection("primary")
|
||||
}
|
||||
v.mouseReleased = true
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user