Beispiel #1
0
func (p *plugin) loadPlugin() {
	fi := p.Get().([]os.FileInfo)
	for _, f := range fi {
		fn := f.Name()
		s, err := py.NewUnicode(path.Base(p.Name()) + "." + fn[:len(fn)-3])
		if err != nil {
			log.Error(err)
			return
		}
		if r, err := p.m.Base().CallMethodObjArgs("reload_plugin", s); err != nil {
			log.Error(err)
		} else if r != nil {
			r.Decref()
		}
	}
}
Beispiel #2
0
// Will load view settings respect to current syntax
// e.g if current syntax is Python settings order will be:
// Packages/Python/Python.sublime-settings
// Packages/User/Python.sublime-settings
// <Buffer Specific Settings>
func (v *View) loadSettings() {
	syntax := v.Settings().Get("syntax", "").(string)

	if syntax == "" {
		v.Settings().SetParent(v.window)
		return
	}

	defSettings, usrSettings := &HasSettings{}, &HasSettings{}

	defSettings.Settings().SetParent(v.window)
	usrSettings.Settings().SetParent(defSettings)
	v.Settings().SetParent(usrSettings)

	ed := GetEditor()
	if r, err := rubex.Compile(`([A-Za-z]+?)\.(?:[^.]+)$`); err != nil {
		log.Error(err)
		return
	} else if s := r.FindStringSubmatch(syntax); s != nil {
		p := path.Join(LIME_PACKAGES_PATH, s[1], s[1]+".sublime-settings")
		ed.load(packages.NewPacket(p, defSettings.Settings()))

		p = path.Join(LIME_USER_PACKAGES_PATH, s[1]+".sublime-settings")
		ed.load(packages.NewPacket(p, usrSettings.Settings()))
	}
}
Beispiel #3
0
func (c *CommandGlue) callBool(name string, args backend.Args) bool {
	gs := py.GilState_Ensure()
	defer gs.Release()

	var (
		pyargs, r py.Object
		err       error
	)
	if pyargs, err = c.CreatePyArgs(args); err != nil {
		log.Error(err)
		return false
	}
	defer pyargs.Decref()

	if r, err = c.CallMethodObjArgs(name, pyargs); err != nil {
		log.Error(err)
		return true
	}
	defer r.Decref()
	if r, ok := r.(*py.Bool); ok {
		return r.Bool()
	}
	return true
}
Beispiel #4
0
func (c *CommandGlue) Description() string {
	gs := py.GilState_Ensure()
	defer gs.Release()

	var (
		pyargs, r py.Object
		err       error
	)
	if pyargs, err = c.CreatePyArgs(c.args); err != nil {
		log.Error(err)
		return ""
	}
	defer pyargs.Decref()

	if r, err = c.CallMethodObjArgs("description", pyargs); err != nil {
		log.Error(err)
		return ""
	}
	defer r.Decref()
	if r, ok := r.(*py.Unicode); ok {
		return r.String()
	}
	return ""
}
Beispiel #5
0
func (v *View) Find(pat string, pos int, flags int) Region {
	r := Region{pos, v.buffer.Size()}
	s := v.buffer.Substr(r)

	if flags&LITERAL != 0 {
		pat = "\\Q" + pat
	}
	if flags&IGNORECASE != 0 {
		pat = "(?im)" + pat
	} else {
		pat = "(?m)" + pat
	}
	// Using regexp instead of rubex because rubex doesn't
	// support flag for treating pattern as a literal text
	if re, err := regexp.Compile(pat); err != nil {
		log.Error(err)
	} else if loc := re.FindStringIndex(s); loc != nil {
		return Region{pos + loc[0], pos + loc[1]}
	}
	return Region{-1, -1}
}
Beispiel #6
0
func (h *DummyFrontend) ErrorMessage(msg string)  { log.Error(msg) }
Beispiel #7
0
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
		}
	}
}
Beispiel #8
0
// Classifies point, returning a bitwise OR of zero or more of defined flags
func (v *View) Classify(point int) (res int) {
	var a, b string = "", ""
	ws := v.Settings().Get("word_separators", DEFAULT_SEPARATORS).(string)
	if point > 0 {
		a = v.buffer.Substr(Region{point - 1, point})
	}
	if point < v.buffer.Size() {
		b = v.buffer.Substr(Region{point, point + 1})
	}

	// Out of range
	if v.buffer.Size() == 0 || point < 0 || point > v.buffer.Size() {
		res = 3520
		return
	}

	// If before and after the point are separators return 0
	if re, err := rubex.Compile(ws); err != nil {
		log.Error(err)
	} else if a == b && re.MatchString(a) {
		res = 0
		return
	}

	// SubWord start & end
	if re, err := rubex.Compile("[A-Z]"); err != nil {
		log.Error(err)
	} else {
		if re.MatchString(b) && !re.MatchString(a) {
			res |= CLASS_SUB_WORD_START
			res |= CLASS_SUB_WORD_END
		}
	}
	if a == "_" && b != "_" {
		res |= CLASS_SUB_WORD_START
	}
	if b == "_" && a != "_" {
		res |= CLASS_SUB_WORD_END
	}

	// Punc start & end
	if re, err := rubex.Compile(ws); err != nil {
		log.Error(err)
	} else {
		// Why ws != ""? See https://github.com/gbbr/textmate/vendor/limetext/rubex/issues/2
		if ((re.MatchString(b) && ws != "") || b == "") && !(re.MatchString(a) && ws != "") {
			res |= CLASS_PUNCTUATION_START
		}
		if ((re.MatchString(a) && ws != "") || a == "") && !(re.MatchString(b) && ws != "") {
			res |= CLASS_PUNCTUATION_END
		}
		// Word start & end
		if re1, err := rubex.Compile("\\w"); err != nil {
			log.Error(err)
		} else if re2, err := rubex.Compile("\\s"); err != nil {
			log.Error(err)
		} else {
			if re1.MatchString(b) && ((re.MatchString(a) && ws != "") || re2.MatchString(a) || a == "") {
				res |= CLASS_WORD_START
			}
			if re1.MatchString(a) && ((re.MatchString(b) && ws != "") || re2.MatchString(b) || b == "") {
				res |= CLASS_WORD_END
			}
		}
	}

	// Line start & end
	if a == "\n" || a == "" {
		res |= CLASS_LINE_START
	}
	if b == "\n" || b == "" {
		res |= CLASS_LINE_END
		if ws == "" {
			res |= CLASS_WORD_END
		}
	}

	// Empty line
	if (a == "\n" && b == "\n") || (a == "" && b == "") {
		res |= CLASS_EMPTY_LINE
	}
	// Middle word
	if re, err := rubex.Compile("\\w"); err != nil {
		log.Error(err)
	} else {
		if re.MatchString(a) && re.MatchString(b) {
			res |= CLASS_MIDDLE_WORD
		}
	}

	// Word start & end with punc
	if re, err := rubex.Compile("\\s"); err != nil {
		log.Error(err)
	} else {
		if (res&CLASS_PUNCTUATION_START != 0) && (re.MatchString(a) || a == "") {
			res |= CLASS_WORD_START_WITH_PUNCTUATION
		}
		if (res&CLASS_PUNCTUATION_END != 0) && (re.MatchString(b) || b == "") {
			res |= CLASS_WORD_END_WITH_PUNCTUATION
		}
	}

	// Openning & closing parentheses
	if re, err := rubex.Compile("[(\\[{]"); err != nil {
		log.Error(err)
	} else {
		if re.MatchString(a) || re.MatchString(b) {
			res |= CLASS_OPENING_PARENTHESIS
		}
	}
	if re, err := rubex.Compile("[)\\]}]"); err != nil {
		log.Error(err)
	} else {
		if re.MatchString(a) || re.MatchString(b) {
			res |= CLASS_CLOSING_PARENTHESIS
		}
	}
	// TODO: isn't this a bug? what's the relation between
	// ',' and parentheses
	if a == "," {
		res |= CLASS_OPENING_PARENTHESIS
	}
	if b == "," {
		res |= CLASS_CLOSING_PARENTHESIS
	}

	return
}