mirror of
https://github.com/zyedidia/micro.git
synced 2026-03-18 06:47:14 +09:00
Add support for user-created commands
Plugins can now create their own commands using the `MakeCommand` function. Plugins can also now create their own keybindings with the `BindKey` function. See the go plugin for an example of `MakeCommand`.
This commit is contained in:
@@ -16,6 +16,209 @@ import (
|
||||
var bindings map[Key]func(*View) bool
|
||||
var helpBinding string
|
||||
|
||||
var bindingActions = map[string]func(*View) bool{
|
||||
"CursorUp": (*View).CursorUp,
|
||||
"CursorDown": (*View).CursorDown,
|
||||
"CursorLeft": (*View).CursorLeft,
|
||||
"CursorRight": (*View).CursorRight,
|
||||
"CursorStart": (*View).CursorStart,
|
||||
"CursorEnd": (*View).CursorEnd,
|
||||
"SelectToStart": (*View).SelectToStart,
|
||||
"SelectToEnd": (*View).SelectToEnd,
|
||||
"SelectUp": (*View).SelectUp,
|
||||
"SelectDown": (*View).SelectDown,
|
||||
"SelectLeft": (*View).SelectLeft,
|
||||
"SelectRight": (*View).SelectRight,
|
||||
"WordRight": (*View).WordRight,
|
||||
"WordLeft": (*View).WordLeft,
|
||||
"SelectWordRight": (*View).SelectWordRight,
|
||||
"SelectWordLeft": (*View).SelectWordLeft,
|
||||
"DeleteWordRight": (*View).DeleteWordRight,
|
||||
"DeleteWordLeft": (*View).DeleteWordLeft,
|
||||
"SelectToStartOfLine": (*View).SelectToStartOfLine,
|
||||
"SelectToEndOfLine": (*View).SelectToEndOfLine,
|
||||
"InsertEnter": (*View).InsertEnter,
|
||||
"InsertSpace": (*View).InsertSpace,
|
||||
"Backspace": (*View).Backspace,
|
||||
"Delete": (*View).Delete,
|
||||
"InsertTab": (*View).InsertTab,
|
||||
"Save": (*View).Save,
|
||||
"Find": (*View).Find,
|
||||
"FindNext": (*View).FindNext,
|
||||
"FindPrevious": (*View).FindPrevious,
|
||||
"Undo": (*View).Undo,
|
||||
"Redo": (*View).Redo,
|
||||
"Copy": (*View).Copy,
|
||||
"Cut": (*View).Cut,
|
||||
"CutLine": (*View).CutLine,
|
||||
"DuplicateLine": (*View).DuplicateLine,
|
||||
"Paste": (*View).Paste,
|
||||
"SelectAll": (*View).SelectAll,
|
||||
"OpenFile": (*View).OpenFile,
|
||||
"Start": (*View).Start,
|
||||
"End": (*View).End,
|
||||
"PageUp": (*View).PageUp,
|
||||
"PageDown": (*View).PageDown,
|
||||
"HalfPageUp": (*View).HalfPageUp,
|
||||
"HalfPageDown": (*View).HalfPageDown,
|
||||
"StartOfLine": (*View).StartOfLine,
|
||||
"EndOfLine": (*View).EndOfLine,
|
||||
"ToggleHelp": (*View).ToggleHelp,
|
||||
"ToggleRuler": (*View).ToggleRuler,
|
||||
"JumpLine": (*View).JumpLine,
|
||||
"ClearStatus": (*View).ClearStatus,
|
||||
"ShellMode": (*View).ShellMode,
|
||||
"CommandMode": (*View).CommandMode,
|
||||
"Quit": (*View).Quit,
|
||||
}
|
||||
|
||||
var bindingKeys = map[string]Key{
|
||||
"Up": Key{tcell.KeyUp, tcell.ModNone, 0},
|
||||
"Down": Key{tcell.KeyDown, tcell.ModNone, 0},
|
||||
"Right": Key{tcell.KeyRight, tcell.ModNone, 0},
|
||||
"Left": Key{tcell.KeyLeft, tcell.ModNone, 0},
|
||||
"AltUp": Key{tcell.KeyUp, tcell.ModAlt, 0},
|
||||
"AltDown": Key{tcell.KeyDown, tcell.ModAlt, 0},
|
||||
"AltLeft": Key{tcell.KeyLeft, tcell.ModAlt, 0},
|
||||
"AltRight": Key{tcell.KeyRight, tcell.ModAlt, 0},
|
||||
"CtrlUp": Key{tcell.KeyUp, tcell.ModCtrl, 0},
|
||||
"CtrlDown": Key{tcell.KeyDown, tcell.ModCtrl, 0},
|
||||
"CtrlLeft": Key{tcell.KeyLeft, tcell.ModCtrl, 0},
|
||||
"CtrlRight": Key{tcell.KeyRight, tcell.ModCtrl, 0},
|
||||
"ShiftUp": Key{tcell.KeyUp, tcell.ModShift, 0},
|
||||
"ShiftDown": Key{tcell.KeyDown, tcell.ModShift, 0},
|
||||
"ShiftLeft": Key{tcell.KeyLeft, tcell.ModShift, 0},
|
||||
"ShiftRight": Key{tcell.KeyRight, tcell.ModShift, 0},
|
||||
"AltShiftUp": Key{tcell.KeyUp, tcell.ModShift | tcell.ModAlt, 0},
|
||||
"AltShiftDown": Key{tcell.KeyDown, tcell.ModShift | tcell.ModAlt, 0},
|
||||
"AltShiftLeft": Key{tcell.KeyLeft, tcell.ModShift | tcell.ModAlt, 0},
|
||||
"AltShiftRight": Key{tcell.KeyRight, tcell.ModShift | tcell.ModAlt, 0},
|
||||
"CtrlShiftUp": Key{tcell.KeyUp, tcell.ModShift | tcell.ModCtrl, 0},
|
||||
"CtrlShiftDown": Key{tcell.KeyDown, tcell.ModShift | tcell.ModCtrl, 0},
|
||||
"CtrlShiftLeft": Key{tcell.KeyLeft, tcell.ModShift | tcell.ModCtrl, 0},
|
||||
"CtrlShiftRight": Key{tcell.KeyRight, tcell.ModShift | tcell.ModCtrl, 0},
|
||||
"UpLeft": Key{tcell.KeyUpLeft, tcell.ModNone, 0},
|
||||
"UpRight": Key{tcell.KeyUpRight, tcell.ModNone, 0},
|
||||
"DownLeft": Key{tcell.KeyDownLeft, tcell.ModNone, 0},
|
||||
"DownRight": Key{tcell.KeyDownRight, tcell.ModNone, 0},
|
||||
"Center": Key{tcell.KeyCenter, tcell.ModNone, 0},
|
||||
"PgUp": Key{tcell.KeyPgUp, tcell.ModNone, 0},
|
||||
"PgDn": Key{tcell.KeyPgDn, tcell.ModNone, 0},
|
||||
"Home": Key{tcell.KeyHome, tcell.ModNone, 0},
|
||||
"End": Key{tcell.KeyEnd, tcell.ModNone, 0},
|
||||
"Insert": Key{tcell.KeyInsert, tcell.ModNone, 0},
|
||||
"Delete": Key{tcell.KeyDelete, tcell.ModNone, 0},
|
||||
"Help": Key{tcell.KeyHelp, tcell.ModNone, 0},
|
||||
"Exit": Key{tcell.KeyExit, tcell.ModNone, 0},
|
||||
"Clear": Key{tcell.KeyClear, tcell.ModNone, 0},
|
||||
"Cancel": Key{tcell.KeyCancel, tcell.ModNone, 0},
|
||||
"Print": Key{tcell.KeyPrint, tcell.ModNone, 0},
|
||||
"Pause": Key{tcell.KeyPause, tcell.ModNone, 0},
|
||||
"Backtab": Key{tcell.KeyBacktab, tcell.ModNone, 0},
|
||||
"F1": Key{tcell.KeyF1, tcell.ModNone, 0},
|
||||
"F2": Key{tcell.KeyF2, tcell.ModNone, 0},
|
||||
"F3": Key{tcell.KeyF3, tcell.ModNone, 0},
|
||||
"F4": Key{tcell.KeyF4, tcell.ModNone, 0},
|
||||
"F5": Key{tcell.KeyF5, tcell.ModNone, 0},
|
||||
"F6": Key{tcell.KeyF6, tcell.ModNone, 0},
|
||||
"F7": Key{tcell.KeyF7, tcell.ModNone, 0},
|
||||
"F8": Key{tcell.KeyF8, tcell.ModNone, 0},
|
||||
"F9": Key{tcell.KeyF9, tcell.ModNone, 0},
|
||||
"F10": Key{tcell.KeyF10, tcell.ModNone, 0},
|
||||
"F11": Key{tcell.KeyF11, tcell.ModNone, 0},
|
||||
"F12": Key{tcell.KeyF12, tcell.ModNone, 0},
|
||||
"F13": Key{tcell.KeyF13, tcell.ModNone, 0},
|
||||
"F14": Key{tcell.KeyF14, tcell.ModNone, 0},
|
||||
"F15": Key{tcell.KeyF15, tcell.ModNone, 0},
|
||||
"F16": Key{tcell.KeyF16, tcell.ModNone, 0},
|
||||
"F17": Key{tcell.KeyF17, tcell.ModNone, 0},
|
||||
"F18": Key{tcell.KeyF18, tcell.ModNone, 0},
|
||||
"F19": Key{tcell.KeyF19, tcell.ModNone, 0},
|
||||
"F20": Key{tcell.KeyF20, tcell.ModNone, 0},
|
||||
"F21": Key{tcell.KeyF21, tcell.ModNone, 0},
|
||||
"F22": Key{tcell.KeyF22, tcell.ModNone, 0},
|
||||
"F23": Key{tcell.KeyF23, tcell.ModNone, 0},
|
||||
"F24": Key{tcell.KeyF24, tcell.ModNone, 0},
|
||||
"F25": Key{tcell.KeyF25, tcell.ModNone, 0},
|
||||
"F26": Key{tcell.KeyF26, tcell.ModNone, 0},
|
||||
"F27": Key{tcell.KeyF27, tcell.ModNone, 0},
|
||||
"F28": Key{tcell.KeyF28, tcell.ModNone, 0},
|
||||
"F29": Key{tcell.KeyF29, tcell.ModNone, 0},
|
||||
"F30": Key{tcell.KeyF30, tcell.ModNone, 0},
|
||||
"F31": Key{tcell.KeyF31, tcell.ModNone, 0},
|
||||
"F32": Key{tcell.KeyF32, tcell.ModNone, 0},
|
||||
"F33": Key{tcell.KeyF33, tcell.ModNone, 0},
|
||||
"F34": Key{tcell.KeyF34, tcell.ModNone, 0},
|
||||
"F35": Key{tcell.KeyF35, tcell.ModNone, 0},
|
||||
"F36": Key{tcell.KeyF36, tcell.ModNone, 0},
|
||||
"F37": Key{tcell.KeyF37, tcell.ModNone, 0},
|
||||
"F38": Key{tcell.KeyF38, tcell.ModNone, 0},
|
||||
"F39": Key{tcell.KeyF39, tcell.ModNone, 0},
|
||||
"F40": Key{tcell.KeyF40, tcell.ModNone, 0},
|
||||
"F41": Key{tcell.KeyF41, tcell.ModNone, 0},
|
||||
"F42": Key{tcell.KeyF42, tcell.ModNone, 0},
|
||||
"F43": Key{tcell.KeyF43, tcell.ModNone, 0},
|
||||
"F44": Key{tcell.KeyF44, tcell.ModNone, 0},
|
||||
"F45": Key{tcell.KeyF45, tcell.ModNone, 0},
|
||||
"F46": Key{tcell.KeyF46, tcell.ModNone, 0},
|
||||
"F47": Key{tcell.KeyF47, tcell.ModNone, 0},
|
||||
"F48": Key{tcell.KeyF48, tcell.ModNone, 0},
|
||||
"F49": Key{tcell.KeyF49, tcell.ModNone, 0},
|
||||
"F50": Key{tcell.KeyF50, tcell.ModNone, 0},
|
||||
"F51": Key{tcell.KeyF51, tcell.ModNone, 0},
|
||||
"F52": Key{tcell.KeyF52, tcell.ModNone, 0},
|
||||
"F53": Key{tcell.KeyF53, tcell.ModNone, 0},
|
||||
"F54": Key{tcell.KeyF54, tcell.ModNone, 0},
|
||||
"F55": Key{tcell.KeyF55, tcell.ModNone, 0},
|
||||
"F56": Key{tcell.KeyF56, tcell.ModNone, 0},
|
||||
"F57": Key{tcell.KeyF57, tcell.ModNone, 0},
|
||||
"F58": Key{tcell.KeyF58, tcell.ModNone, 0},
|
||||
"F59": Key{tcell.KeyF59, tcell.ModNone, 0},
|
||||
"F60": Key{tcell.KeyF60, tcell.ModNone, 0},
|
||||
"F61": Key{tcell.KeyF61, tcell.ModNone, 0},
|
||||
"F62": Key{tcell.KeyF62, tcell.ModNone, 0},
|
||||
"F63": Key{tcell.KeyF63, tcell.ModNone, 0},
|
||||
"F64": Key{tcell.KeyF64, tcell.ModNone, 0},
|
||||
"CtrlSpace": Key{tcell.KeyCtrlSpace, tcell.ModCtrl, 0},
|
||||
"CtrlA": Key{tcell.KeyCtrlA, tcell.ModCtrl, 0},
|
||||
"CtrlB": Key{tcell.KeyCtrlB, tcell.ModCtrl, 0},
|
||||
"CtrlC": Key{tcell.KeyCtrlC, tcell.ModCtrl, 0},
|
||||
"CtrlD": Key{tcell.KeyCtrlD, tcell.ModCtrl, 0},
|
||||
"CtrlE": Key{tcell.KeyCtrlE, tcell.ModCtrl, 0},
|
||||
"CtrlF": Key{tcell.KeyCtrlF, tcell.ModCtrl, 0},
|
||||
"CtrlG": Key{tcell.KeyCtrlG, tcell.ModCtrl, 0},
|
||||
"CtrlH": Key{tcell.KeyCtrlH, tcell.ModCtrl, 0},
|
||||
"CtrlI": Key{tcell.KeyCtrlI, tcell.ModCtrl, 0},
|
||||
"CtrlJ": Key{tcell.KeyCtrlJ, tcell.ModCtrl, 0},
|
||||
"CtrlK": Key{tcell.KeyCtrlK, tcell.ModCtrl, 0},
|
||||
"CtrlL": Key{tcell.KeyCtrlL, tcell.ModCtrl, 0},
|
||||
"CtrlM": Key{tcell.KeyCtrlM, tcell.ModCtrl, 0},
|
||||
"CtrlN": Key{tcell.KeyCtrlN, tcell.ModCtrl, 0},
|
||||
"CtrlO": Key{tcell.KeyCtrlO, tcell.ModCtrl, 0},
|
||||
"CtrlP": Key{tcell.KeyCtrlP, tcell.ModCtrl, 0},
|
||||
"CtrlQ": Key{tcell.KeyCtrlQ, tcell.ModCtrl, 0},
|
||||
"CtrlR": Key{tcell.KeyCtrlR, tcell.ModCtrl, 0},
|
||||
"CtrlS": Key{tcell.KeyCtrlS, tcell.ModCtrl, 0},
|
||||
"CtrlT": Key{tcell.KeyCtrlT, tcell.ModCtrl, 0},
|
||||
"CtrlU": Key{tcell.KeyCtrlU, tcell.ModCtrl, 0},
|
||||
"CtrlV": Key{tcell.KeyCtrlV, tcell.ModCtrl, 0},
|
||||
"CtrlW": Key{tcell.KeyCtrlW, tcell.ModCtrl, 0},
|
||||
"CtrlX": Key{tcell.KeyCtrlX, tcell.ModCtrl, 0},
|
||||
"CtrlY": Key{tcell.KeyCtrlY, tcell.ModCtrl, 0},
|
||||
"CtrlZ": Key{tcell.KeyCtrlZ, tcell.ModCtrl, 0},
|
||||
"CtrlLeftSq": Key{tcell.KeyCtrlLeftSq, tcell.ModCtrl, 0},
|
||||
"CtrlBackslash": Key{tcell.KeyCtrlBackslash, tcell.ModCtrl, 0},
|
||||
"CtrlRightSq": Key{tcell.KeyCtrlRightSq, tcell.ModCtrl, 0},
|
||||
"CtrlCarat": Key{tcell.KeyCtrlCarat, tcell.ModCtrl, 0},
|
||||
"CtrlUnderscore": Key{tcell.KeyCtrlUnderscore, tcell.ModCtrl, 0},
|
||||
"Backspace": Key{tcell.KeyBackspace, tcell.ModNone, 0},
|
||||
"Tab": Key{tcell.KeyTab, tcell.ModNone, 0},
|
||||
"Esc": Key{tcell.KeyEsc, tcell.ModNone, 0},
|
||||
"Escape": Key{tcell.KeyEscape, tcell.ModNone, 0},
|
||||
"Enter": Key{tcell.KeyEnter, tcell.ModNone, 0},
|
||||
"Backspace2": Key{tcell.KeyBackspace2, tcell.ModNone, 0},
|
||||
}
|
||||
|
||||
// The Key struct holds the data for a keypress (keycode + modifiers)
|
||||
type Key struct {
|
||||
keyCode tcell.Key
|
||||
@@ -27,209 +230,6 @@ type Key struct {
|
||||
func InitBindings() {
|
||||
bindings = make(map[Key]func(*View) bool)
|
||||
|
||||
actions := map[string]func(*View) bool{
|
||||
"CursorUp": (*View).CursorUp,
|
||||
"CursorDown": (*View).CursorDown,
|
||||
"CursorLeft": (*View).CursorLeft,
|
||||
"CursorRight": (*View).CursorRight,
|
||||
"CursorStart": (*View).CursorStart,
|
||||
"CursorEnd": (*View).CursorEnd,
|
||||
"SelectToStart": (*View).SelectToStart,
|
||||
"SelectToEnd": (*View).SelectToEnd,
|
||||
"SelectUp": (*View).SelectUp,
|
||||
"SelectDown": (*View).SelectDown,
|
||||
"SelectLeft": (*View).SelectLeft,
|
||||
"SelectRight": (*View).SelectRight,
|
||||
"WordRight": (*View).WordRight,
|
||||
"WordLeft": (*View).WordLeft,
|
||||
"SelectWordRight": (*View).SelectWordRight,
|
||||
"SelectWordLeft": (*View).SelectWordLeft,
|
||||
"DeleteWordRight": (*View).DeleteWordRight,
|
||||
"DeleteWordLeft": (*View).DeleteWordLeft,
|
||||
"SelectToStartOfLine": (*View).SelectToStartOfLine,
|
||||
"SelectToEndOfLine": (*View).SelectToEndOfLine,
|
||||
"InsertEnter": (*View).InsertEnter,
|
||||
"InsertSpace": (*View).InsertSpace,
|
||||
"Backspace": (*View).Backspace,
|
||||
"Delete": (*View).Delete,
|
||||
"InsertTab": (*View).InsertTab,
|
||||
"Save": (*View).Save,
|
||||
"Find": (*View).Find,
|
||||
"FindNext": (*View).FindNext,
|
||||
"FindPrevious": (*View).FindPrevious,
|
||||
"Undo": (*View).Undo,
|
||||
"Redo": (*View).Redo,
|
||||
"Copy": (*View).Copy,
|
||||
"Cut": (*View).Cut,
|
||||
"CutLine": (*View).CutLine,
|
||||
"DuplicateLine": (*View).DuplicateLine,
|
||||
"Paste": (*View).Paste,
|
||||
"SelectAll": (*View).SelectAll,
|
||||
"OpenFile": (*View).OpenFile,
|
||||
"Start": (*View).Start,
|
||||
"End": (*View).End,
|
||||
"PageUp": (*View).PageUp,
|
||||
"PageDown": (*View).PageDown,
|
||||
"HalfPageUp": (*View).HalfPageUp,
|
||||
"HalfPageDown": (*View).HalfPageDown,
|
||||
"StartOfLine": (*View).StartOfLine,
|
||||
"EndOfLine": (*View).EndOfLine,
|
||||
"ToggleHelp": (*View).ToggleHelp,
|
||||
"ToggleRuler": (*View).ToggleRuler,
|
||||
"JumpLine": (*View).JumpLine,
|
||||
"ClearStatus": (*View).ClearStatus,
|
||||
"ShellMode": (*View).ShellMode,
|
||||
"CommandMode": (*View).CommandMode,
|
||||
"Quit": (*View).Quit,
|
||||
}
|
||||
|
||||
keys := map[string]Key{
|
||||
"Up": Key{tcell.KeyUp, tcell.ModNone, 0},
|
||||
"Down": Key{tcell.KeyDown, tcell.ModNone, 0},
|
||||
"Right": Key{tcell.KeyRight, tcell.ModNone, 0},
|
||||
"Left": Key{tcell.KeyLeft, tcell.ModNone, 0},
|
||||
"AltUp": Key{tcell.KeyUp, tcell.ModAlt, 0},
|
||||
"AltDown": Key{tcell.KeyDown, tcell.ModAlt, 0},
|
||||
"AltLeft": Key{tcell.KeyLeft, tcell.ModAlt, 0},
|
||||
"AltRight": Key{tcell.KeyRight, tcell.ModAlt, 0},
|
||||
"CtrlUp": Key{tcell.KeyUp, tcell.ModCtrl, 0},
|
||||
"CtrlDown": Key{tcell.KeyDown, tcell.ModCtrl, 0},
|
||||
"CtrlLeft": Key{tcell.KeyLeft, tcell.ModCtrl, 0},
|
||||
"CtrlRight": Key{tcell.KeyRight, tcell.ModCtrl, 0},
|
||||
"ShiftUp": Key{tcell.KeyUp, tcell.ModShift, 0},
|
||||
"ShiftDown": Key{tcell.KeyDown, tcell.ModShift, 0},
|
||||
"ShiftLeft": Key{tcell.KeyLeft, tcell.ModShift, 0},
|
||||
"ShiftRight": Key{tcell.KeyRight, tcell.ModShift, 0},
|
||||
"AltShiftUp": Key{tcell.KeyUp, tcell.ModShift | tcell.ModAlt, 0},
|
||||
"AltShiftDown": Key{tcell.KeyDown, tcell.ModShift | tcell.ModAlt, 0},
|
||||
"AltShiftLeft": Key{tcell.KeyLeft, tcell.ModShift | tcell.ModAlt, 0},
|
||||
"AltShiftRight": Key{tcell.KeyRight, tcell.ModShift | tcell.ModAlt, 0},
|
||||
"CtrlShiftUp": Key{tcell.KeyUp, tcell.ModShift | tcell.ModCtrl, 0},
|
||||
"CtrlShiftDown": Key{tcell.KeyDown, tcell.ModShift | tcell.ModCtrl, 0},
|
||||
"CtrlShiftLeft": Key{tcell.KeyLeft, tcell.ModShift | tcell.ModCtrl, 0},
|
||||
"CtrlShiftRight": Key{tcell.KeyRight, tcell.ModShift | tcell.ModCtrl, 0},
|
||||
"UpLeft": Key{tcell.KeyUpLeft, tcell.ModNone, 0},
|
||||
"UpRight": Key{tcell.KeyUpRight, tcell.ModNone, 0},
|
||||
"DownLeft": Key{tcell.KeyDownLeft, tcell.ModNone, 0},
|
||||
"DownRight": Key{tcell.KeyDownRight, tcell.ModNone, 0},
|
||||
"Center": Key{tcell.KeyCenter, tcell.ModNone, 0},
|
||||
"PgUp": Key{tcell.KeyPgUp, tcell.ModNone, 0},
|
||||
"PgDn": Key{tcell.KeyPgDn, tcell.ModNone, 0},
|
||||
"Home": Key{tcell.KeyHome, tcell.ModNone, 0},
|
||||
"End": Key{tcell.KeyEnd, tcell.ModNone, 0},
|
||||
"Insert": Key{tcell.KeyInsert, tcell.ModNone, 0},
|
||||
"Delete": Key{tcell.KeyDelete, tcell.ModNone, 0},
|
||||
"Help": Key{tcell.KeyHelp, tcell.ModNone, 0},
|
||||
"Exit": Key{tcell.KeyExit, tcell.ModNone, 0},
|
||||
"Clear": Key{tcell.KeyClear, tcell.ModNone, 0},
|
||||
"Cancel": Key{tcell.KeyCancel, tcell.ModNone, 0},
|
||||
"Print": Key{tcell.KeyPrint, tcell.ModNone, 0},
|
||||
"Pause": Key{tcell.KeyPause, tcell.ModNone, 0},
|
||||
"Backtab": Key{tcell.KeyBacktab, tcell.ModNone, 0},
|
||||
"F1": Key{tcell.KeyF1, tcell.ModNone, 0},
|
||||
"F2": Key{tcell.KeyF2, tcell.ModNone, 0},
|
||||
"F3": Key{tcell.KeyF3, tcell.ModNone, 0},
|
||||
"F4": Key{tcell.KeyF4, tcell.ModNone, 0},
|
||||
"F5": Key{tcell.KeyF5, tcell.ModNone, 0},
|
||||
"F6": Key{tcell.KeyF6, tcell.ModNone, 0},
|
||||
"F7": Key{tcell.KeyF7, tcell.ModNone, 0},
|
||||
"F8": Key{tcell.KeyF8, tcell.ModNone, 0},
|
||||
"F9": Key{tcell.KeyF9, tcell.ModNone, 0},
|
||||
"F10": Key{tcell.KeyF10, tcell.ModNone, 0},
|
||||
"F11": Key{tcell.KeyF11, tcell.ModNone, 0},
|
||||
"F12": Key{tcell.KeyF12, tcell.ModNone, 0},
|
||||
"F13": Key{tcell.KeyF13, tcell.ModNone, 0},
|
||||
"F14": Key{tcell.KeyF14, tcell.ModNone, 0},
|
||||
"F15": Key{tcell.KeyF15, tcell.ModNone, 0},
|
||||
"F16": Key{tcell.KeyF16, tcell.ModNone, 0},
|
||||
"F17": Key{tcell.KeyF17, tcell.ModNone, 0},
|
||||
"F18": Key{tcell.KeyF18, tcell.ModNone, 0},
|
||||
"F19": Key{tcell.KeyF19, tcell.ModNone, 0},
|
||||
"F20": Key{tcell.KeyF20, tcell.ModNone, 0},
|
||||
"F21": Key{tcell.KeyF21, tcell.ModNone, 0},
|
||||
"F22": Key{tcell.KeyF22, tcell.ModNone, 0},
|
||||
"F23": Key{tcell.KeyF23, tcell.ModNone, 0},
|
||||
"F24": Key{tcell.KeyF24, tcell.ModNone, 0},
|
||||
"F25": Key{tcell.KeyF25, tcell.ModNone, 0},
|
||||
"F26": Key{tcell.KeyF26, tcell.ModNone, 0},
|
||||
"F27": Key{tcell.KeyF27, tcell.ModNone, 0},
|
||||
"F28": Key{tcell.KeyF28, tcell.ModNone, 0},
|
||||
"F29": Key{tcell.KeyF29, tcell.ModNone, 0},
|
||||
"F30": Key{tcell.KeyF30, tcell.ModNone, 0},
|
||||
"F31": Key{tcell.KeyF31, tcell.ModNone, 0},
|
||||
"F32": Key{tcell.KeyF32, tcell.ModNone, 0},
|
||||
"F33": Key{tcell.KeyF33, tcell.ModNone, 0},
|
||||
"F34": Key{tcell.KeyF34, tcell.ModNone, 0},
|
||||
"F35": Key{tcell.KeyF35, tcell.ModNone, 0},
|
||||
"F36": Key{tcell.KeyF36, tcell.ModNone, 0},
|
||||
"F37": Key{tcell.KeyF37, tcell.ModNone, 0},
|
||||
"F38": Key{tcell.KeyF38, tcell.ModNone, 0},
|
||||
"F39": Key{tcell.KeyF39, tcell.ModNone, 0},
|
||||
"F40": Key{tcell.KeyF40, tcell.ModNone, 0},
|
||||
"F41": Key{tcell.KeyF41, tcell.ModNone, 0},
|
||||
"F42": Key{tcell.KeyF42, tcell.ModNone, 0},
|
||||
"F43": Key{tcell.KeyF43, tcell.ModNone, 0},
|
||||
"F44": Key{tcell.KeyF44, tcell.ModNone, 0},
|
||||
"F45": Key{tcell.KeyF45, tcell.ModNone, 0},
|
||||
"F46": Key{tcell.KeyF46, tcell.ModNone, 0},
|
||||
"F47": Key{tcell.KeyF47, tcell.ModNone, 0},
|
||||
"F48": Key{tcell.KeyF48, tcell.ModNone, 0},
|
||||
"F49": Key{tcell.KeyF49, tcell.ModNone, 0},
|
||||
"F50": Key{tcell.KeyF50, tcell.ModNone, 0},
|
||||
"F51": Key{tcell.KeyF51, tcell.ModNone, 0},
|
||||
"F52": Key{tcell.KeyF52, tcell.ModNone, 0},
|
||||
"F53": Key{tcell.KeyF53, tcell.ModNone, 0},
|
||||
"F54": Key{tcell.KeyF54, tcell.ModNone, 0},
|
||||
"F55": Key{tcell.KeyF55, tcell.ModNone, 0},
|
||||
"F56": Key{tcell.KeyF56, tcell.ModNone, 0},
|
||||
"F57": Key{tcell.KeyF57, tcell.ModNone, 0},
|
||||
"F58": Key{tcell.KeyF58, tcell.ModNone, 0},
|
||||
"F59": Key{tcell.KeyF59, tcell.ModNone, 0},
|
||||
"F60": Key{tcell.KeyF60, tcell.ModNone, 0},
|
||||
"F61": Key{tcell.KeyF61, tcell.ModNone, 0},
|
||||
"F62": Key{tcell.KeyF62, tcell.ModNone, 0},
|
||||
"F63": Key{tcell.KeyF63, tcell.ModNone, 0},
|
||||
"F64": Key{tcell.KeyF64, tcell.ModNone, 0},
|
||||
"CtrlSpace": Key{tcell.KeyCtrlSpace, tcell.ModCtrl, 0},
|
||||
"CtrlA": Key{tcell.KeyCtrlA, tcell.ModCtrl, 0},
|
||||
"CtrlB": Key{tcell.KeyCtrlB, tcell.ModCtrl, 0},
|
||||
"CtrlC": Key{tcell.KeyCtrlC, tcell.ModCtrl, 0},
|
||||
"CtrlD": Key{tcell.KeyCtrlD, tcell.ModCtrl, 0},
|
||||
"CtrlE": Key{tcell.KeyCtrlE, tcell.ModCtrl, 0},
|
||||
"CtrlF": Key{tcell.KeyCtrlF, tcell.ModCtrl, 0},
|
||||
"CtrlG": Key{tcell.KeyCtrlG, tcell.ModCtrl, 0},
|
||||
"CtrlH": Key{tcell.KeyCtrlH, tcell.ModCtrl, 0},
|
||||
"CtrlI": Key{tcell.KeyCtrlI, tcell.ModCtrl, 0},
|
||||
"CtrlJ": Key{tcell.KeyCtrlJ, tcell.ModCtrl, 0},
|
||||
"CtrlK": Key{tcell.KeyCtrlK, tcell.ModCtrl, 0},
|
||||
"CtrlL": Key{tcell.KeyCtrlL, tcell.ModCtrl, 0},
|
||||
"CtrlM": Key{tcell.KeyCtrlM, tcell.ModCtrl, 0},
|
||||
"CtrlN": Key{tcell.KeyCtrlN, tcell.ModCtrl, 0},
|
||||
"CtrlO": Key{tcell.KeyCtrlO, tcell.ModCtrl, 0},
|
||||
"CtrlP": Key{tcell.KeyCtrlP, tcell.ModCtrl, 0},
|
||||
"CtrlQ": Key{tcell.KeyCtrlQ, tcell.ModCtrl, 0},
|
||||
"CtrlR": Key{tcell.KeyCtrlR, tcell.ModCtrl, 0},
|
||||
"CtrlS": Key{tcell.KeyCtrlS, tcell.ModCtrl, 0},
|
||||
"CtrlT": Key{tcell.KeyCtrlT, tcell.ModCtrl, 0},
|
||||
"CtrlU": Key{tcell.KeyCtrlU, tcell.ModCtrl, 0},
|
||||
"CtrlV": Key{tcell.KeyCtrlV, tcell.ModCtrl, 0},
|
||||
"CtrlW": Key{tcell.KeyCtrlW, tcell.ModCtrl, 0},
|
||||
"CtrlX": Key{tcell.KeyCtrlX, tcell.ModCtrl, 0},
|
||||
"CtrlY": Key{tcell.KeyCtrlY, tcell.ModCtrl, 0},
|
||||
"CtrlZ": Key{tcell.KeyCtrlZ, tcell.ModCtrl, 0},
|
||||
"CtrlLeftSq": Key{tcell.KeyCtrlLeftSq, tcell.ModCtrl, 0},
|
||||
"CtrlBackslash": Key{tcell.KeyCtrlBackslash, tcell.ModCtrl, 0},
|
||||
"CtrlRightSq": Key{tcell.KeyCtrlRightSq, tcell.ModCtrl, 0},
|
||||
"CtrlCarat": Key{tcell.KeyCtrlCarat, tcell.ModCtrl, 0},
|
||||
"CtrlUnderscore": Key{tcell.KeyCtrlUnderscore, tcell.ModCtrl, 0},
|
||||
"Backspace": Key{tcell.KeyBackspace, tcell.ModNone, 0},
|
||||
"Tab": Key{tcell.KeyTab, tcell.ModNone, 0},
|
||||
"Esc": Key{tcell.KeyEsc, tcell.ModNone, 0},
|
||||
"Escape": Key{tcell.KeyEscape, tcell.ModNone, 0},
|
||||
"Enter": Key{tcell.KeyEnter, tcell.ModNone, 0},
|
||||
"Backspace2": Key{tcell.KeyBackspace2, tcell.ModNone, 0},
|
||||
}
|
||||
|
||||
var parsed map[string]string
|
||||
defaults := DefaultBindings()
|
||||
|
||||
@@ -247,35 +247,40 @@ func InitBindings() {
|
||||
}
|
||||
}
|
||||
|
||||
parse(defaults, actions, keys)
|
||||
parse(parsed, actions, keys)
|
||||
parseBindings(defaults)
|
||||
parseBindings(parsed)
|
||||
}
|
||||
|
||||
func parse(userBindings map[string]string, actions map[string]func(*View) bool, keys map[string]Key) {
|
||||
func parseBindings(userBindings map[string]string) {
|
||||
for k, v := range userBindings {
|
||||
var key Key
|
||||
if strings.Contains(k, "Alt-") {
|
||||
split := strings.Split(k, "-")
|
||||
if len(split[1]) > 1 {
|
||||
key = Key{keys[split[1]].keyCode, keys[k].modifiers | tcell.ModAlt, 0}
|
||||
} else {
|
||||
key = Key{tcell.KeyRune, tcell.ModAlt, rune(k[len(k)-1])}
|
||||
}
|
||||
BindKey(k, v)
|
||||
}
|
||||
}
|
||||
|
||||
// BindKey takes a key and an action and binds the two together
|
||||
func BindKey(k, v string) {
|
||||
var key Key
|
||||
if strings.Contains(k, "Alt-") {
|
||||
split := strings.Split(k, "-")
|
||||
if len(split[1]) > 1 {
|
||||
key = Key{bindingKeys[split[1]].keyCode, bindingKeys[k].modifiers | tcell.ModAlt, 0}
|
||||
} else {
|
||||
key = keys[k]
|
||||
key = Key{tcell.KeyRune, tcell.ModAlt, rune(k[len(k)-1])}
|
||||
}
|
||||
} else {
|
||||
key = bindingKeys[k]
|
||||
}
|
||||
|
||||
action := actions[v]
|
||||
if _, ok := actions[v]; !ok {
|
||||
// If the user seems to be binding a function that doesn't exist
|
||||
// We hope that it's a lua function that exists and bind it to that
|
||||
action = LuaFunctionBinding(v)
|
||||
}
|
||||
action := bindingActions[v]
|
||||
if _, ok := bindingActions[v]; !ok {
|
||||
// If the user seems to be binding a function that doesn't exist
|
||||
// We hope that it's a lua function that exists and bind it to that
|
||||
action = LuaFunctionBinding(v)
|
||||
}
|
||||
|
||||
bindings[key] = action
|
||||
if v == "ToggleHelp" {
|
||||
helpBinding = k
|
||||
}
|
||||
bindings[key] = action
|
||||
if v == "ToggleHelp" {
|
||||
helpBinding = k
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -9,6 +9,183 @@ import (
|
||||
"strings"
|
||||
)
|
||||
|
||||
var commands map[string]func([]string)
|
||||
|
||||
var commandActions = map[string]func([]string){
|
||||
"Set": Set,
|
||||
"Run": Run,
|
||||
"Bind": Bind,
|
||||
"Quit": Quit,
|
||||
"Save": Save,
|
||||
"Replace": Replace,
|
||||
}
|
||||
|
||||
// InitCommands initializes the default commands
|
||||
func InitCommands() {
|
||||
commands = make(map[string]func([]string))
|
||||
|
||||
defaults := DefaultCommands()
|
||||
parseCommands(defaults)
|
||||
}
|
||||
|
||||
func parseCommands(userCommands map[string]string) {
|
||||
for k, v := range userCommands {
|
||||
MakeCommand(k, v)
|
||||
}
|
||||
}
|
||||
|
||||
// MakeCommand is a function to easily create new commands
|
||||
// This can be called by plugins in Lua so that plugins can define their own commands
|
||||
func MakeCommand(name, function string) {
|
||||
action := commandActions[function]
|
||||
if _, ok := commandActions[function]; !ok {
|
||||
// If the user seems to be binding a function that doesn't exist
|
||||
// We hope that it's a lua function that exists and bind it to that
|
||||
action = LuaFunctionCommand(function)
|
||||
}
|
||||
|
||||
commands[name] = action
|
||||
}
|
||||
|
||||
// DefaultCommands returns a map containing micro's default commands
|
||||
func DefaultCommands() map[string]string {
|
||||
return map[string]string{
|
||||
"set": "Set",
|
||||
"bind": "Bind",
|
||||
"run": "Run",
|
||||
"quit": "Quit",
|
||||
"save": "Save",
|
||||
"replace": "Replace",
|
||||
}
|
||||
}
|
||||
|
||||
// Set sets an option
|
||||
func Set(args []string) {
|
||||
// Set an option and we have to set it for every view
|
||||
for _, view := range views {
|
||||
SetOption(view, args)
|
||||
}
|
||||
}
|
||||
|
||||
// Bind creates a new keybinding
|
||||
func Bind(args []string) {
|
||||
if len(args) != 2 {
|
||||
messenger.Error("Incorrect number of arguments")
|
||||
return
|
||||
}
|
||||
BindKey(args[0], args[1])
|
||||
}
|
||||
|
||||
// Run runs a shell command in the background
|
||||
func Run(args []string) {
|
||||
// Run a shell command in the background (openTerm is false)
|
||||
HandleShellCommand(strings.Join(args, " "), false)
|
||||
}
|
||||
|
||||
// Quit closes the main view
|
||||
func Quit(args []string) {
|
||||
// Close the main view
|
||||
views[mainView].Quit()
|
||||
}
|
||||
|
||||
// Save saves the buffer in the main view
|
||||
func Save(args []string) {
|
||||
// Save the main view
|
||||
views[mainView].Save()
|
||||
}
|
||||
|
||||
// Replace runs search and replace
|
||||
func Replace(args []string) {
|
||||
// This is a regex to parse the replace expression
|
||||
// We allow no quotes if there are no spaces, but if you want to search
|
||||
// for or replace an expression with spaces, you can add double quotes
|
||||
r := regexp.MustCompile(`"[^"\\]*(?:\\.[^"\\]*)*"|[^\s]*`)
|
||||
replaceCmd := r.FindAllString(strings.Join(args, " "), -1)
|
||||
if len(replaceCmd) < 2 {
|
||||
// We need to find both a search and replace expression
|
||||
messenger.Error("Invalid replace statement: " + strings.Join(args, " "))
|
||||
return
|
||||
}
|
||||
|
||||
var flags string
|
||||
if len(replaceCmd) == 3 {
|
||||
// The user included some flags
|
||||
flags = replaceCmd[2]
|
||||
}
|
||||
|
||||
search := string(replaceCmd[0])
|
||||
replace := string(replaceCmd[1])
|
||||
|
||||
// If the search and replace expressions have quotes, we need to remove those
|
||||
if strings.HasPrefix(search, `"`) && strings.HasSuffix(search, `"`) {
|
||||
search = search[1 : len(search)-1]
|
||||
}
|
||||
if strings.HasPrefix(replace, `"`) && strings.HasSuffix(replace, `"`) {
|
||||
replace = replace[1 : len(replace)-1]
|
||||
}
|
||||
|
||||
// We replace all escaped double quotes to real double quotes
|
||||
search = strings.Replace(search, `\"`, `"`, -1)
|
||||
replace = strings.Replace(replace, `\"`, `"`, -1)
|
||||
// Replace some things so users can actually insert newlines and tabs in replacements
|
||||
replace = strings.Replace(replace, "\\n", "\n", -1)
|
||||
replace = strings.Replace(replace, "\\t", "\t", -1)
|
||||
|
||||
regex, err := regexp.Compile(search)
|
||||
if err != nil {
|
||||
// There was an error with the user's regex
|
||||
messenger.Error(err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
view := views[mainView]
|
||||
|
||||
found := false
|
||||
for {
|
||||
match := regex.FindStringIndex(view.Buf.String())
|
||||
if match == nil {
|
||||
break
|
||||
}
|
||||
found = true
|
||||
if strings.Contains(flags, "c") {
|
||||
// The 'check' flag was used
|
||||
Search(search, view, true)
|
||||
view.Relocate()
|
||||
if settings["syntax"].(bool) {
|
||||
view.matches = Match(view)
|
||||
}
|
||||
RedrawAll()
|
||||
choice, canceled := messenger.YesNoPrompt("Perform replacement? (y,n)")
|
||||
if canceled {
|
||||
if view.Cursor.HasSelection() {
|
||||
view.Cursor.SetLoc(view.Cursor.CurSelection[0])
|
||||
view.Cursor.ResetSelection()
|
||||
}
|
||||
messenger.Reset()
|
||||
return
|
||||
}
|
||||
if choice {
|
||||
view.Cursor.DeleteSelection()
|
||||
view.Buf.Insert(match[0], replace)
|
||||
view.Cursor.ResetSelection()
|
||||
messenger.Reset()
|
||||
} else {
|
||||
if view.Cursor.HasSelection() {
|
||||
searchStart = view.Cursor.CurSelection[1]
|
||||
} else {
|
||||
searchStart = ToCharPos(view.Cursor.X, view.Cursor.Y, view.Buf)
|
||||
}
|
||||
continue
|
||||
}
|
||||
} else {
|
||||
view.Buf.Replace(match[0], match[1], replace)
|
||||
}
|
||||
}
|
||||
if !found {
|
||||
messenger.Message("Nothing matched " + search)
|
||||
}
|
||||
}
|
||||
|
||||
// RunShellCommand executes a shell command and returns the output/error
|
||||
func RunShellCommand(input string) (string, error) {
|
||||
inputCmd := strings.Split(input, " ")[0]
|
||||
@@ -88,117 +265,9 @@ func HandleCommand(input string) {
|
||||
inputCmd := strings.Split(input, " ")[0]
|
||||
args := strings.Split(input, " ")[1:]
|
||||
|
||||
switch inputCmd {
|
||||
case "set":
|
||||
// Set an option and we have to set it for every view
|
||||
for _, view := range views {
|
||||
SetOption(view, args)
|
||||
}
|
||||
case "run":
|
||||
// Run a shell command in the background (openTerm is false)
|
||||
HandleShellCommand(strings.Join(args, " "), false)
|
||||
case "quit":
|
||||
// This is a bit weird because micro only has one view for now so there is no way to close
|
||||
// a single view
|
||||
// Currently if multiple views were open, it would close all of them, and not check the non-mainviews
|
||||
// for unsaved changes. This, and the behavior of Ctrl-Q need to be changed when splits are implemented
|
||||
if views[mainView].CanClose("Quit anyway? (yes, no, save) ") {
|
||||
screen.Fini()
|
||||
os.Exit(0)
|
||||
}
|
||||
case "save":
|
||||
// Save the main view
|
||||
views[mainView].Save()
|
||||
case "replace":
|
||||
// This is a regex to parse the replace expression
|
||||
// We allow no quotes if there are no spaces, but if you want to search
|
||||
// for or replace an expression with spaces, you can add double quotes
|
||||
r := regexp.MustCompile(`"[^"\\]*(?:\\.[^"\\]*)*"|[^\s]*`)
|
||||
replaceCmd := r.FindAllString(strings.Join(args, " "), -1)
|
||||
if len(replaceCmd) < 2 {
|
||||
// We need to find both a search and replace expression
|
||||
messenger.Error("Invalid replace statement: " + strings.Join(args, " "))
|
||||
return
|
||||
}
|
||||
|
||||
var flags string
|
||||
if len(replaceCmd) == 3 {
|
||||
// The user included some flags
|
||||
flags = replaceCmd[2]
|
||||
}
|
||||
|
||||
search := string(replaceCmd[0])
|
||||
replace := string(replaceCmd[1])
|
||||
|
||||
// If the search and replace expressions have quotes, we need to remove those
|
||||
if strings.HasPrefix(search, `"`) && strings.HasSuffix(search, `"`) {
|
||||
search = search[1 : len(search)-1]
|
||||
}
|
||||
if strings.HasPrefix(replace, `"`) && strings.HasSuffix(replace, `"`) {
|
||||
replace = replace[1 : len(replace)-1]
|
||||
}
|
||||
|
||||
// We replace all escaped double quotes to real double quotes
|
||||
search = strings.Replace(search, `\"`, `"`, -1)
|
||||
replace = strings.Replace(replace, `\"`, `"`, -1)
|
||||
// Replace some things so users can actually insert newlines and tabs in replacements
|
||||
replace = strings.Replace(replace, "\\n", "\n", -1)
|
||||
replace = strings.Replace(replace, "\\t", "\t", -1)
|
||||
|
||||
regex, err := regexp.Compile(search)
|
||||
if err != nil {
|
||||
// There was an error with the user's regex
|
||||
messenger.Error(err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
view := views[mainView]
|
||||
|
||||
found := false
|
||||
for {
|
||||
match := regex.FindStringIndex(view.Buf.String())
|
||||
if match == nil {
|
||||
break
|
||||
}
|
||||
found = true
|
||||
if strings.Contains(flags, "c") {
|
||||
// The 'check' flag was used
|
||||
Search(search, view, true)
|
||||
view.Relocate()
|
||||
if settings["syntax"].(bool) {
|
||||
view.matches = Match(view)
|
||||
}
|
||||
RedrawAll()
|
||||
choice, canceled := messenger.YesNoPrompt("Perform replacement? (y,n)")
|
||||
if canceled {
|
||||
if view.Cursor.HasSelection() {
|
||||
view.Cursor.SetLoc(view.Cursor.CurSelection[0])
|
||||
view.Cursor.ResetSelection()
|
||||
}
|
||||
messenger.Reset()
|
||||
return
|
||||
}
|
||||
if choice {
|
||||
view.Cursor.DeleteSelection()
|
||||
view.Buf.Insert(match[0], replace)
|
||||
view.Cursor.ResetSelection()
|
||||
messenger.Reset()
|
||||
} else {
|
||||
if view.Cursor.HasSelection() {
|
||||
searchStart = view.Cursor.CurSelection[1]
|
||||
} else {
|
||||
searchStart = ToCharPos(view.Cursor.X, view.Cursor.Y, view.Buf)
|
||||
}
|
||||
continue
|
||||
}
|
||||
} else {
|
||||
view.Buf.Replace(match[0], match[1], replace)
|
||||
}
|
||||
}
|
||||
if !found {
|
||||
messenger.Message("Nothing matched " + search)
|
||||
}
|
||||
default:
|
||||
messenger.Error("Unknown command: " + inputCmd)
|
||||
if _, ok := commands[inputCmd]; !ok {
|
||||
messenger.Error("Unkown command ", inputCmd)
|
||||
} else {
|
||||
commands[inputCmd](args)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -203,6 +203,7 @@ func main() {
|
||||
InitConfigDir()
|
||||
// Load the user's settings
|
||||
InitSettings()
|
||||
InitCommands()
|
||||
InitBindings()
|
||||
// Load the syntax files, including the colorscheme
|
||||
LoadSyntaxFiles()
|
||||
@@ -237,6 +238,8 @@ func main() {
|
||||
L.SetGlobal("messenger", luar.New(L, messenger))
|
||||
L.SetGlobal("GetOption", luar.New(L, GetOption))
|
||||
L.SetGlobal("AddOption", luar.New(L, AddOption))
|
||||
L.SetGlobal("BindKey", luar.New(L, BindKey))
|
||||
L.SetGlobal("MakeCommand", luar.New(L, MakeCommand))
|
||||
|
||||
LoadPlugins()
|
||||
|
||||
|
||||
@@ -4,6 +4,7 @@ import (
|
||||
"errors"
|
||||
"io/ioutil"
|
||||
|
||||
"github.com/layeh/gopher-luar"
|
||||
"github.com/yuin/gopher-lua"
|
||||
)
|
||||
|
||||
@@ -17,16 +18,17 @@ var preInstalledPlugins = []string{
|
||||
// Call calls the lua function 'function'
|
||||
// If it does not exist nothing happens, if there is an error,
|
||||
// the error is returned
|
||||
func Call(function string) error {
|
||||
func Call(function string, args []string) error {
|
||||
luaFunc := L.GetGlobal(function)
|
||||
if luaFunc.String() == "nil" {
|
||||
return errors.New("function does not exist: " + function)
|
||||
}
|
||||
luaArgs := luar.New(L, args)
|
||||
err := L.CallByParam(lua.P{
|
||||
Fn: luaFunc,
|
||||
NRet: 0,
|
||||
Protect: true,
|
||||
})
|
||||
}, luaArgs)
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -36,7 +38,7 @@ func Call(function string) error {
|
||||
// to bind keys to lua functions
|
||||
func LuaFunctionBinding(function string) func(*View) bool {
|
||||
return func(v *View) bool {
|
||||
err := Call(function)
|
||||
err := Call(function, nil)
|
||||
if err != nil {
|
||||
TermMessage(err)
|
||||
}
|
||||
@@ -46,9 +48,9 @@ func LuaFunctionBinding(function string) func(*View) bool {
|
||||
|
||||
// LuaFunctionCommand is the same as LuaFunctionBinding except it returns a normal function
|
||||
// so that a command can be bound to a lua function
|
||||
func LuaFunctionCommand(function string) func() {
|
||||
return func() {
|
||||
err := Call(function)
|
||||
func LuaFunctionCommand(function string) func([]string) {
|
||||
return func(args []string) {
|
||||
err := Call(function, args)
|
||||
if err != nil {
|
||||
TermMessage(err)
|
||||
}
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -301,7 +301,7 @@ func (v *View) HandleEvent(event tcell.Event) {
|
||||
relocate = action(v)
|
||||
for _, pl := range loadedPlugins {
|
||||
funcName := strings.Split(runtime.FuncForPC(reflect.ValueOf(action).Pointer()).Name(), ".")
|
||||
err := Call(pl + "_on" + funcName[len(funcName)-1])
|
||||
err := Call(pl+"_on"+funcName[len(funcName)-1], nil)
|
||||
if err != nil && !strings.HasPrefix(err.Error(), "function does not exist") {
|
||||
TermMessage(err)
|
||||
}
|
||||
|
||||
@@ -152,6 +152,9 @@ Here are the possible commands that you can use.
|
||||
* `run sh-command`: runs the given shell command in the background. The
|
||||
command's output will be displayed in one line when it finishes running.
|
||||
|
||||
* `bind key action`: creates a keybinding from key to action. See the sections on
|
||||
keybindings above for more info about what keys and actions are available.
|
||||
|
||||
### Options
|
||||
|
||||
Micro stores all of the user configuration in its configuration directory.
|
||||
|
||||
@@ -5,6 +5,9 @@ if GetOption("gofmt") == nil then
|
||||
AddOption("gofmt", true)
|
||||
end
|
||||
|
||||
MakeCommand("goimports", "go_goimports")
|
||||
MakeCommand("gofmt", "go_gofmt")
|
||||
|
||||
function go_onSave()
|
||||
if views[mainView+1].Buf.FileType == "Go" then
|
||||
if GetOption("goimports") then
|
||||
@@ -12,21 +15,25 @@ function go_onSave()
|
||||
elseif GetOption("gofmt") then
|
||||
go_gofmt()
|
||||
end
|
||||
|
||||
views[mainView+1]:ReOpen()
|
||||
end
|
||||
end
|
||||
|
||||
function go_gofmt()
|
||||
views[mainView+1]:Save()
|
||||
local handle = io.popen("gofmt -w " .. views[mainView+1].Buf.Path)
|
||||
local result = handle:read("*a")
|
||||
handle:close()
|
||||
|
||||
views[mainView+1]:ReOpen()
|
||||
end
|
||||
|
||||
function go_goimports()
|
||||
views[mainView+1]:Save()
|
||||
local handle = io.popen("goimports -w " .. views[mainView+1].Buf.Path)
|
||||
local result = go_split(handle:read("*a"), ":")
|
||||
handle:close()
|
||||
|
||||
views[mainView+1]:ReOpen()
|
||||
end
|
||||
|
||||
function go_split(str, sep)
|
||||
|
||||
Reference in New Issue
Block a user