mirror of
https://github.com/zyedidia/micro.git
synced 2026-02-07 07:30:20 +09:00
More actions
This commit is contained in:
@@ -2,8 +2,10 @@ package action
|
||||
|
||||
import (
|
||||
"os"
|
||||
"unicode/utf8"
|
||||
|
||||
"github.com/zyedidia/micro/cmd/micro/screen"
|
||||
"github.com/zyedidia/micro/cmd/micro/util"
|
||||
"github.com/zyedidia/tcell"
|
||||
)
|
||||
|
||||
@@ -262,6 +264,11 @@ func (h *BufHandler) SelectToEnd() bool {
|
||||
|
||||
// InsertSpace inserts a space
|
||||
func (h *BufHandler) InsertSpace() bool {
|
||||
if h.Cursor.HasSelection() {
|
||||
h.Cursor.DeleteSelection()
|
||||
h.Cursor.ResetSelection()
|
||||
}
|
||||
h.Buf.Insert(h.Cursor.Loc, " ")
|
||||
return true
|
||||
}
|
||||
|
||||
@@ -272,6 +279,30 @@ func (h *BufHandler) InsertNewline() bool {
|
||||
|
||||
// Backspace deletes the previous character
|
||||
func (h *BufHandler) Backspace() bool {
|
||||
if h.Cursor.HasSelection() {
|
||||
h.Cursor.DeleteSelection()
|
||||
h.Cursor.ResetSelection()
|
||||
} else if h.Cursor.Loc.GreaterThan(h.Buf.Start()) {
|
||||
// We have to do something a bit hacky here because we want to
|
||||
// delete the line by first moving left and then deleting backwards
|
||||
// but the undo redo would place the cursor in the wrong place
|
||||
// So instead we move left, save the position, move back, delete
|
||||
// and restore the position
|
||||
|
||||
// If the user is using spaces instead of tabs and they are deleting
|
||||
// whitespace at the start of the line, we should delete as if it's a
|
||||
// tab (tabSize number of spaces)
|
||||
lineStart := util.SliceStart(h.Buf.LineBytes(h.Cursor.Y), h.Cursor.X)
|
||||
tabSize := int(h.Buf.Settings["tabsize"].(float64))
|
||||
if h.Buf.Settings["tabstospaces"].(bool) && util.IsSpaces(lineStart) && len(lineStart) != 0 && utf8.RuneCount(lineStart)%tabSize == 0 {
|
||||
loc := h.Cursor.Loc
|
||||
h.Buf.Remove(loc.Move(-tabSize, h.Buf), loc)
|
||||
} else {
|
||||
loc := h.Cursor.Loc
|
||||
h.Buf.Remove(loc.Move(-1, h.Buf), loc)
|
||||
}
|
||||
}
|
||||
h.Cursor.LastVisualX = h.Cursor.GetVisualX()
|
||||
return true
|
||||
}
|
||||
|
||||
|
||||
@@ -102,21 +102,29 @@ modSearch:
|
||||
// see if the key is in bindingKeys with the Ctrl prefix.
|
||||
k = string(unicode.ToUpper(rune(k[0]))) + k[1:]
|
||||
if code, ok := keyEvents["Ctrl"+k]; ok {
|
||||
var r tcell.Key
|
||||
if code < 256 {
|
||||
r = code
|
||||
}
|
||||
// It is, we're done.
|
||||
return KeyEvent{
|
||||
code: code,
|
||||
mod: modifiers,
|
||||
r: rune(code),
|
||||
r: rune(r),
|
||||
}, true
|
||||
}
|
||||
}
|
||||
|
||||
// See if we can find the key in bindingKeys
|
||||
if code, ok := keyEvents[k]; ok {
|
||||
var r tcell.Key
|
||||
if code < 256 {
|
||||
r = code
|
||||
}
|
||||
return KeyEvent{
|
||||
code: code,
|
||||
mod: modifiers,
|
||||
r: 0,
|
||||
r: rune(r),
|
||||
}, true
|
||||
}
|
||||
|
||||
|
||||
@@ -4,6 +4,7 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/zyedidia/micro/cmd/micro/buffer"
|
||||
"github.com/zyedidia/micro/cmd/micro/util"
|
||||
"github.com/zyedidia/tcell"
|
||||
)
|
||||
|
||||
@@ -19,10 +20,23 @@ func init() {
|
||||
}
|
||||
|
||||
func BufMapKey(k KeyEvent, action string) {
|
||||
BufKeyBindings[k] = BufKeyActions[action]
|
||||
if f, ok := BufKeyActions[action]; ok {
|
||||
BufKeyBindings[k] = f
|
||||
} else {
|
||||
util.TermMessage("Error:", action, "does not exist")
|
||||
}
|
||||
}
|
||||
func BufMapMouse(k MouseEvent, action string) {
|
||||
BufMouseBindings[k] = BufMouseActions[action]
|
||||
if f, ok := BufMouseActions[action]; ok {
|
||||
BufMouseBindings[k] = f
|
||||
} else if f, ok := BufKeyActions[action]; ok {
|
||||
// allowed to map mouse buttons to key actions
|
||||
BufMouseBindings[k] = func(h *BufHandler, e *tcell.EventMouse) bool {
|
||||
return f(h)
|
||||
}
|
||||
} else {
|
||||
util.TermMessage("Error:", action, "does not exist")
|
||||
}
|
||||
}
|
||||
|
||||
// The BufHandler connects the buffer and the window
|
||||
@@ -91,7 +105,10 @@ func (h *BufHandler) HandleEvent(event tcell.Event) {
|
||||
mod: e.Modifiers(),
|
||||
r: e.Rune(),
|
||||
}
|
||||
h.DoKeyEvent(ke)
|
||||
done := h.DoKeyEvent(ke)
|
||||
if !done && e.Key() == tcell.KeyRune {
|
||||
h.DoRuneInsert(e.Rune())
|
||||
}
|
||||
case *tcell.EventMouse:
|
||||
me := MouseEvent{
|
||||
btn: e.Buttons(),
|
||||
@@ -117,6 +134,22 @@ func (h *BufHandler) DoMouseEvent(e MouseEvent, te *tcell.EventMouse) bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func (h *BufHandler) DoRuneInsert(r rune) {
|
||||
// Insert a character
|
||||
if h.Cursor.HasSelection() {
|
||||
h.Cursor.DeleteSelection()
|
||||
h.Cursor.ResetSelection()
|
||||
}
|
||||
|
||||
if h.isOverwriteMode {
|
||||
next := h.Cursor.Loc
|
||||
next.X++
|
||||
h.Buf.Replace(h.Cursor.Loc, next, string(r))
|
||||
} else {
|
||||
h.Buf.Insert(h.Cursor.Loc, string(r))
|
||||
}
|
||||
}
|
||||
|
||||
var BufKeyActions = map[string]BufKeyAction{
|
||||
"CursorUp": (*BufHandler).CursorUp,
|
||||
"CursorDown": (*BufHandler).CursorDown,
|
||||
|
||||
@@ -320,6 +320,20 @@ func calcHash(b *Buffer, out *[md5.Size]byte) {
|
||||
h.Sum((*out)[:0])
|
||||
}
|
||||
|
||||
func (b *Buffer) insert(pos Loc, value []byte) {
|
||||
b.isModified = true
|
||||
b.LineArray.insert(pos, value)
|
||||
}
|
||||
func (b *Buffer) remove(start, end Loc) []byte {
|
||||
b.isModified = true
|
||||
sub := b.LineArray.remove(start, end)
|
||||
return sub
|
||||
}
|
||||
func (b *Buffer) deleteToEnd(start Loc) {
|
||||
b.isModified = true
|
||||
b.LineArray.deleteToEnd(start)
|
||||
}
|
||||
|
||||
// UpdateRules updates the syntax rules and filetype for this buffer
|
||||
// This is called when the colorscheme changes
|
||||
func (b *Buffer) UpdateRules() {
|
||||
|
||||
@@ -24,7 +24,7 @@ func Unlock() {
|
||||
var screenWasNil bool
|
||||
|
||||
func TempFini() {
|
||||
screenWasNil := Screen == nil
|
||||
screenWasNil = Screen == nil
|
||||
|
||||
if !screenWasNil {
|
||||
Lock()
|
||||
|
||||
@@ -139,6 +139,17 @@ func IsWordChar(r rune) bool {
|
||||
return (r >= '0' && r <= '9') || (r >= 'A' && r <= 'Z') || (r >= 'a' && r <= 'z') || (r == '_')
|
||||
}
|
||||
|
||||
// IsSpaces checks if a given string is only spaces
|
||||
func IsSpaces(str []byte) bool {
|
||||
for _, c := range str {
|
||||
if c != ' ' {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
// IsWhitespace returns true if the given rune is a space, tab, or newline
|
||||
func IsWhitespace(c rune) bool {
|
||||
return c == ' ' || c == '\t' || c == '\n'
|
||||
|
||||
Reference in New Issue
Block a user