コード例 #1
0
ファイル: language.go プロジェクト: gbbr/textmate
func (p *Pattern) Cache(data string, pos int) (pat *Pattern, ret MatchObject) {
	if p.cachedData == data {
		if p.cachedMatch == nil {
			return nil, nil
		}
		if p.cachedMatch[0] >= pos && p.cachedPat.cachedMatch != nil {
			p.hits++
			return p.cachedPat, p.cachedMatch
		}
	} else {
		p.cachedPatterns = nil
	}
	if p.cachedPatterns == nil {
		p.cachedPatterns = make([]*Pattern, len(p.Patterns))
		for i := range p.cachedPatterns {
			p.cachedPatterns[i] = &p.Patterns[i]
		}
	}
	p.misses++

	if p.Match.re != nil {
		pat, ret = p, p.Match.Find(data, pos)
	} else if p.Begin.re != nil {
		pat, ret = p, p.Begin.Find(data, pos)
	} else if p.Include != "" {
		if z := p.Include[0]; z == '#' {
			key := p.Include[1:]
			if p2, ok := p.owner.Repository[key]; ok {
				pat, ret = p2.Cache(data, pos)
			} else {
				log.Fine("Not found in repository: %s", p.Include)
			}
		} else if z == '$' {
			// TODO(q): Implement tmLanguage $ include directives
			log.Warn("Unhandled include directive: %s", p.Include)
		} else if l, err := Provider.GetLanguage(p.Include); err != nil {
			if !failed[p.Include] {
				log.Warn("Include directive %s failed: %s", p.Include, err)
			}
			failed[p.Include] = true
		} else {
			return l.RootPattern.Cache(data, pos)
		}
	} else {
		pat, ret = p.FirstMatch(data, pos)
	}
	p.cachedData = data
	p.cachedMatch = ret
	p.cachedPat = pat

	return
}
コード例 #2
0
ファイル: view.go プロジェクト: gbbr/textmate
// Saves the file to the specified filename
func (v *View) SaveAs(name string) (err error) {
	log.Fine("SaveAs(%s)", name)
	v.Settings().Set("lime.saving", true)
	defer v.Settings().Erase("lime.saving")
	var atomic bool
	OnPreSave.Call(v)
	if atomic, _ = v.Settings().Get("atomic_save", true).(bool); v.buffer.FileName() == "" || !atomic {
		if err := v.nonAtomicSave(name); err != nil {
			return err
		}
	} else {
		n, err := ioutil.TempDir(path.Dir(v.buffer.FileName()), "lime")
		if err != nil {
			return err
		}
		tmpf := path.Join(n, "tmp")
		if err := v.nonAtomicSave(tmpf); err != nil {
			return err
		}
		if err := os.Rename(tmpf, name); err != nil {
			// When we want to save as a file in another directory
			// we can't go with os.Rename so we need to force
			// not atomic saving sometimes as 4th test in TestSaveAsOpenFile
			if err := v.nonAtomicSave(name); err != nil {
				return err
			}
		}
		if err := os.RemoveAll(n); err != nil {
			return err
		}
	}

	ed := GetEditor()
	if fn := v.buffer.FileName(); fn != name {
		v.buffer.SetFileName(name)
		if fn != "" {
			ed.UnWatch(fn, v)
		}
		ed.Watch(name, v)
	}

	v.Settings().Set("lime.last_save_change_count", v.buffer.ChangeCount())
	OnPostSave.Call(v)
	return nil
}
コード例 #3
0
ファイル: commandhandler.go プロジェクト: gbbr/textmate
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
}
コード例 #4
0
ファイル: view.go プロジェクト: gbbr/textmate
// Ends the given Edit object.
func (v *View) EndEdit(edit *Edit) {
	if edit.invalid {
		// This happens when nesting Edits and the child Edit ends after the parent edit.
		log.Fine("This edit has already been invalidated: %v, %v", edit, v.editstack)
		return
	}

	// Find the position of this Edit object in this View's Edit stack.
	// If plugins, commands, etc are well-behaved the ended edit should be
	// last in the stack, but shit happens and we cannot count on this being the case.
	i := len(v.editstack) - 1
	for i := len(v.editstack) - 1; i >= 0; i-- {
		if v.editstack[i] == edit {
			break
		}
	}
	if i == -1 {
		// TODO(.): Under what instances does this happen again?
		log.Errorf("This edit isn't even in the stack... where did it come from? %v, %v", edit, v.editstack)
		return
	}

	var selection_modified bool

	if l := len(v.editstack) - 1; i != l {
		// TODO(.): See TODO in BeginEdit
		log.Errorf("This edit wasn't last in the stack... %d !=  %d: %v, %v", i, l, edit, v.editstack)
	}

	// Invalidate all Edits "below" and including this Edit.
	for j := len(v.editstack) - 1; j >= i; j-- {
		current_edit := v.editstack[j]
		current_edit.invalid = true
		sel_same := reflect.DeepEqual(*v.Sel(), current_edit.savedSel)
		buf_same := v.buffer.ChangeCount() == current_edit.savedCount
		eq := (sel_same && buf_same && current_edit.composite.Len() == 0)
		if !eq && !sel_same {
			selection_modified = true
		}
		if v.IsScratch() || current_edit.bypassUndo || eq {
			continue
		}
		switch {
		case i == 0:
			// Well-behaved, no nested edits!
			fallthrough
		case j != i:
			// BOO! Someone began another Edit without finishing the first one.
			// In this instance, the parent Edit ended before the child.
			// TODO(.): What would be the correct way to handle this?
			v.undoStack.Add(edit)
		default:
			// BOO! Also poorly-behaved. This Edit object began after the parent began,
			// but was finished before the parent finished.
			//
			// Add it as a child of the parent Edit so that undoing the parent
			// will undo this edit as well.
			v.editstack[i-1].composite.Add(current_edit)
		}
	}
	// Pop this Edit and all the children off the Edit stack.
	v.editstack = v.editstack[:i]
	if selection_modified {
		OnSelectionModified.Call(v)
	}
}