func (e *Editor) RunCommand(name string, args Args) { // TODO? var ( wnd *Window v *View ) if wnd = e.ActiveWindow(); wnd != nil { v = wnd.ActiveView() } // TODO: what's the command precedence? if c := e.cmdHandler.TextCommands[name]; c != nil { if err := e.CommandHandler().RunTextCommand(v, name, args); err != nil { log.Debug("Couldn't run textcommand: %s", err) } } else if c := e.cmdHandler.WindowCommands[name]; c != nil { if err := e.CommandHandler().RunWindowCommand(wnd, name, args); err != nil { log.Debug("Couldn't run windowcommand: %s", err) } } else if c := e.cmdHandler.ApplicationCommands[name]; c != nil { if err := e.CommandHandler().RunApplicationCommand(name, args); err != nil { log.Debug("Couldn't run applicationcommand: %s", err) } } else { log.Debug("Couldn't find command to run") } }
func onInit() { l := py.NewLock() defer l.Unlock() m, err := py.Import("sublime_plugin") if err != nil { panic(err) } sys, err := py.Import("sys") if err != nil { log.Debug(err) } else { defer sys.Decref() } if watcher, err = watch.NewWatcher(); err != nil { log.Errorf("Couldn't create watcher: %s", err) } // TODO: add all plugins after supporting all commands // plugins := packages.ScanPlugins(backend.LIME_PACKAGES_PATH, ".py") // for _, p := range plugins { // newPlugin(p, m) // } newPlugin(packages.NewPlugin(path.Join(backend.LIME_PACKAGES_PATH, "Vintageous"), ".py"), m) go watcher.Observe() }
func sublime_set_timeout(tu *py.Tuple, kwargs *py.Dict) (py.Object, error) { var ( pyarg py.Object ) if tu.Size() != 2 { return nil, fmt.Errorf("Unexpected argument count: %d", tu.Size()) } if i, err := tu.GetItem(0); err != nil { return nil, err } else { pyarg = i } if i, err := tu.GetItem(1); err != nil { return nil, err } else if v, err := fromPython(i); err != nil { return nil, err } else if v2, ok := v.(int); !ok { return nil, fmt.Errorf("Expected int not %s", i.Type()) } else { pyarg.Incref() go func() { time.Sleep(time.Millisecond * time.Duration(v2)) l := py.NewLock() defer l.Unlock() defer pyarg.Decref() if ret, err := pyarg.Base().CallFunctionObjArgs(); err != nil { log.Debug("Error in callback: %v", err) } else { ret.Decref() } }() } return toPython(nil) }
func (ch *commandHandler) RunTextCommand(view *View, name string, args Args) error { lvl := log.FINE p := Prof.Enter("tc") defer p.Exit() t := time.Now() if ch.log { lvl = log.DEBUG } log.Logf(lvl, "Running text command: %s %v", name, args) if c, ok := ch.TextCommands[name].(TextCommand); c != nil && ok { if err := ch.init(c, args); err != nil && ch.verbose { log.Debug("Command initialization failed: %s", err) return err } else if err := view.runCommand(c, name); err != nil { log.Logf(lvl, "Command execution failed: %s", err) return err } } else if w := view.Window(); w != nil { if c, ok := ch.WindowCommands[name].(WindowCommand); c != nil && ok { if err := w.runCommand(c, name); err != nil { log.Logf(lvl, "Command execution failed: %s", err) return err } } } log.Logf(lvl, "Ran text command: %s %s", name, time.Since(t)) return nil }
func (ch *commandHandler) RunApplicationCommand(name string, args Args) error { p := Prof.Enter("ac") defer p.Exit() if ch.log { log.Info("Running application command: %s %v", name, args) } else { log.Fine("Running application command: %s %v", name, args) } if c, ok := ch.ApplicationCommands[name].(ApplicationCommand); c != nil && ok { if err := ch.init(c, args); err != nil && ch.verbose { log.Debug("Command initialization failed: %s", err) return err } else if err := c.Run(); err != nil && ch.verbose { log.Debug("Command execution failed: %s", err) return err } } return nil }
func (lp *LanguageParser) Parse() (*parser.Node, error) { sdata := string(lp.data) rn := parser.Node{P: lp, Name: lp.l.ScopeName} defer func() { if r := recover(); r != nil { log.Errorf("Panic during parse: %v\n", r) log.Debug("%v", rn) } }() iter := maxiter for i := 0; i < len(sdata) && iter > 0; iter-- { pat, ret := lp.l.RootPattern.Cache(sdata, i) nl := strings.IndexAny(sdata[i:], "\n\r") if nl != -1 { nl += i } if ret == nil { break } else if nl > 0 && nl <= ret[0] { i = nl for i < len(sdata) && (sdata[i] == '\n' || sdata[i] == '\r') { i++ } } else { n := pat.CreateNode(sdata, i, lp, ret) rn.Append(n) i = n.Range.B } } rn.UpdateRange() if len(sdata) != 0 { lut := make([]int, len(sdata)+1) j := 0 for i := range sdata { lut[i] = j j++ } lut[len(sdata)] = len(lp.data) lp.patch(lut, &rn) } if iter == 0 { panic("reached maximum number of iterations") } return &rn, nil }
func (c *WindowCommandGlue) Run(w *backend.Window) error { l := py.NewLock() defer l.Unlock() var ( pyw, pyargs, obj py.Object err error ) log.Debug("WindowCommand: %v", c.args) if pyw, err = toPython(w); err != nil { return pyError(err) } defer pyw.Decref() if pyargs, err = c.CreatePyArgs(c.args); err != nil { return pyError(err) } defer pyargs.Decref() // interrupt := true // defer func() { interrupt = false }() // go func() { // <-time.After(time.Second * 5) // if interrupt { // py.SetInterrupt() // } // }() if obj, err = c.inner.Base().CallFunctionObjArgs(pyw); err != nil { return pyError(err) } defer obj.Decref() if ret, err := obj.Base().CallMethodObjArgs("run_", pyargs); err != nil { return pyError(err) } else { ret.Decref() } return nil }
func (ch *commandHandler) RunWindowCommand(wnd *Window, name string, args Args) error { lvl := log.FINE p := Prof.Enter("wc") defer p.Exit() if ch.log { lvl = log.DEBUG } log.Logf(lvl, "Running window command: %s %v", name, args) t := time.Now() if c, ok := ch.WindowCommands[name].(WindowCommand); c != nil && ok { if err := ch.init(c, args); err != nil && ch.verbose { log.Debug("Command initialization failed: %s", err) return err } else if err := wnd.runCommand(c, name); err != nil { log.Logf(lvl+1, "Command execution failed: %s", err) return err } else { log.Logf(lvl, "Ran Window command: %s %s", name, time.Since(t)) } } else { log.Logf(lvl, "No such window command: %s", name) } return nil }
func (e *Editor) inputthread() { pc := 0 var lastBindings keys.KeyBindings doinput := func(kp keys.KeyPress) { defer func() { if r := recover(); r != nil { log.Errorf("Panic in inputthread: %v\n%s", r, string(debug.Stack())) if pc > 0 { panic(r) } pc++ } }() p := Prof.Enter("hi") defer p.Exit() lvl := log.FINE if e.logInput { lvl++ } log.Logf(lvl, "Key: %v", kp) if lastBindings.SeqIndex() == 0 { lastBindings = *e.KeyBindings() } try_again: possible_actions := lastBindings.Filter(kp) lastBindings = possible_actions // TODO? var ( wnd *Window v *View ) if wnd = e.ActiveWindow(); wnd != nil { v = wnd.ActiveView() } qc := func(key string, operator Op, operand interface{}, match_all bool) bool { return OnQueryContext.Call(v, key, operator, operand, match_all) == True } if action := possible_actions.Action(qc); action != nil { p2 := Prof.Enter("hi.perform") e.RunCommand(action.Command, action.Args) p2.Exit() } else if possible_actions.SeqIndex() > 1 { // TODO: this disables having keyBindings with more than 2 key sequence lastBindings = *e.KeyBindings() goto try_again } else if kp.IsCharacter() { p2 := Prof.Enter("hi.character") log.Finest("[editor.inputthread] kp: |%s|, pos: %v", kp.Text, possible_actions) if err := e.CommandHandler().RunTextCommand(v, "insert", Args{"characters": kp.Text}); err != nil { log.Debug("Couldn't run textcommand: %s", err) } p2.Exit() } } for kp := range e.keyInput { doinput(kp) } }
func TestSublime(t *testing.T) { ed := backend.GetEditor() ed.SetClipboardFuncs(func(n string) (err error) { dummyClipboard = n return nil }, func() (string, error) { return dummyClipboard, nil }) ed.Init() ed.Console().Buffer().AddObserver(&consoleObserver{T: t}) w := ed.NewWindow() l := py.NewLock() py.AddToPath("testdata") py.AddToPath("testdata/plugins") if m, err := py.Import("sublime_plugin"); err != nil { t.Fatal(err) } else { plugins := packages.ScanPlugins("testdata/", ".py") for _, p := range plugins { newPlugin(p, m) } } subl, err := py.Import("sublime") if err != nil { t.Fatal(err) } if w, err := _windowClass.Alloc(1); err != nil { t.Fatal(err) } else { (w.(*Window)).data = &backend.Window{} subl.AddObject("test_window", w) } // Testing plugin reload data := []byte(`import sublime, sublime_plugin class TestToxt(sublime_plugin.TextCommand): def run(self, edit): print("my view's id is: %d" % self.view.id()) self.view.insert(edit, 0, "Tada") `) if err := ioutil.WriteFile("testdata/plugins/reload.py", data, 0644); err != nil { t.Fatalf("Couldn't write testdata/plugins/reload.py: %s", err) } defer os.Remove("testdata/plugins/reload.py") time.Sleep(time.Millisecond * 50) if dir, err := os.Open("testdata"); err != nil { t.Error(err) } else if files, err := dir.Readdirnames(0); err != nil { t.Error(err) } else { for _, fn := range files { // FIXME: Skip reload_test.py to work around #531 on OSX. if fn == "reload_test.py" && ed.Platform() == "darwin" { continue } if filepath.Ext(fn) == ".py" { log.Debug("Running %s", fn) if _, err := py.Import(fn[:len(fn)-3]); err != nil { log.Error(err) t.Error(err) } else { log.Debug("Ran %s", fn) } } } } var f func(indent string, v py.Object, buf *bytes.Buffer) f = func(indent string, v py.Object, buf *bytes.Buffer) { b := v.Base() if dir, err := b.Dir(); err != nil { t.Error(err) } else { if l, ok := dir.(*py.List); ok { sl := l.Slice() if indent == "" { for _, v2 := range sl { if item, err := b.GetAttr(v2); err != nil { t.Error(err) } else { ty := item.Type() line := fmt.Sprintf("%s%s\n", indent, v2) buf.WriteString(line) if ty == py.TypeType { f(indent+"\t", item, buf) } item.Decref() } } } else { for _, v2 := range sl { buf.WriteString(fmt.Sprintf("%s%s\n", indent, v2)) } } } else { ty := dir.Type() t.Error("Unexpected type:", ty) } dir.Decref() } } buf := bytes.NewBuffer(nil) f("", subl, buf) l.Unlock() const expfile = "testdata/api.txt" if d, err := ioutil.ReadFile(expfile); err != nil { if err := ioutil.WriteFile(expfile, buf.Bytes(), 0644); err != nil { t.Error(err) } } else if diff := util.Diff(string(d), buf.String()); diff != "" { t.Error(diff) } ed.LogCommands(true) tests := []string{ "state", "registers", "settings", "constants", "registers", "cmd_data", "marks", } for _, test := range tests { ed.CommandHandler().RunWindowCommand(w, "vintage_ex_run_data_file_based_tests", backend.Args{"suite_name": test}) } for _, w := range ed.Windows() { for _, v := range w.Views() { if strings.HasSuffix(v.Buffer().FileName(), "sample.txt") { continue } if strings.Index(v.Buffer().Substr(text.Region{A: 0, B: v.Buffer().Size()}), "FAILED") != -1 { t.Error(v.Buffer()) } } } var v *backend.View for _, v2 := range w.Views() { if v == nil || v2.Buffer().Size() > v.Buffer().Size() { v = v2 } } }