Skip to content

Commit

Permalink
Merge 02d187f into 1f446ac
Browse files Browse the repository at this point in the history
  • Loading branch information
zoli committed Mar 18, 2016
2 parents 1f446ac + 02d187f commit fadeee7
Show file tree
Hide file tree
Showing 78 changed files with 5,264 additions and 5,353 deletions.
3 changes: 0 additions & 3 deletions .gitmodules
Original file line number Diff line number Diff line change
@@ -1,6 +1,3 @@
[submodule "packages"]
path = packages
url = https://github.com/limetext/lime-packages.git
[submodule "tasks/general"]
path = tasks/general
url = https://github.com/limetext/lime-tasks.git
157 changes: 87 additions & 70 deletions lib/editor.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,44 +6,47 @@ package backend

import (
"fmt"
"path"
"runtime"
"runtime/debug"
"sync"

"github.com/atotto/clipboard"
"github.com/limetext/lime-backend/lib/keys"
"github.com/limetext/lime-backend/lib/log"
"github.com/limetext/lime-backend/lib/packages"
. "github.com/limetext/lime-backend/lib/util"
"github.com/limetext/lime-backend/lib/watch"
. "github.com/limetext/text"
"path"
"runtime"
"runtime/debug"
"sync"
)

func init() {
runtime.GOMAXPROCS(runtime.NumCPU())
GetEditor()
OnPackagesPathAdd.Add(packages.Scan)
}

type (
Editor struct {
HasSettings
keys.HasKeyBindings
*watch.Watcher
windows []*Window
activeWindow *Window
logInput bool
cmdHandler commandHandler
console *View
frontend Frontend
keyInput chan (keys.KeyPress)
clipboardSetter func(string) error
clipboardGetter func() (string, error)
clipboard string
defaultSettings *HasSettings
platformSettings *HasSettings
defaultBindings *keys.HasKeyBindings
platformBindings *keys.HasKeyBindings
userBindings *keys.HasKeyBindings
windows []*Window
activeWindow *Window
logInput bool
cmdHandler commandHandler
console *View
frontend Frontend
keyInput chan (keys.KeyPress)
clipboardSetter func(string) error
clipboardGetter func() (string, error)
clipboard string
defaultSet *HasSettings
platformSet *HasSettings
defaultKB *keys.HasKeyBindings
platformKB *keys.HasKeyBindings
userKB *keys.HasKeyBindings
pkgsPaths map[string]string
}

// The Frontend interface defines the API
Expand Down Expand Up @@ -81,12 +84,6 @@ type (
}
)

var (
LIME_USER_PACKAGES_PATH = path.Join("..", "packages", "User")
LIME_PACKAGES_PATH = path.Join("..", "packages")
LIME_DEFAULTS_PATH = path.Join("..", "packages", "Default")
)

func (h *DummyFrontend) SetDefaultAction(action bool) {
h.m.Lock()
defer h.m.Unlock()
Expand Down Expand Up @@ -125,19 +122,22 @@ func GetEditor() *Editor {
buffer: NewBuffer(),
scratch: true,
},
keyInput: make(chan keys.KeyPress, 32),
keyInput: make(chan keys.KeyPress, 32),
defaultSet: new(HasSettings),
platformSet: new(HasSettings),
defaultKB: new(keys.HasKeyBindings),
platformKB: new(keys.HasKeyBindings),
userKB: new(keys.HasKeyBindings),
pkgsPaths: make(map[string]string),
}
var err error
if ed.Watcher, err = watch.NewWatcher(); err != nil {
log.Error("Couldn't create watcher: %s", err)
}

ed.console.Settings().Set("is_widget", true)
ed.defaultSettings = new(HasSettings)
ed.platformSettings = new(HasSettings)
ed.Settings() // Just to initialize it
ed.defaultBindings = new(keys.HasKeyBindings)
ed.platformBindings = new(keys.HasKeyBindings)
ed.userBindings = new(keys.HasKeyBindings)

log.AddFilter("console", log.DEBUG, log.NewLogWriter(ed.handleLog))
go ed.inputthread()
go ed.Observe()
Expand All @@ -163,69 +163,67 @@ func getClipboard() (string, error) {

func (e *Editor) Init() {
log.Info("Initializing")
// TODO: shouldn't we move SetClipboardFuncs to frontends?
e.SetClipboardFuncs(setClipboard, getClipboard)
e.loadKeyBindings()
e.loadSettings()

OnInit.call()

// There should be usable window and view on startup
w := e.NewWindow()
w.NewFile()
}

func (e *Editor) SetClipboardFuncs(setter func(string) error, getter func() (string, error)) {
e.clipboardSetter = setter
e.clipboardGetter = getter
}

func (e *Editor) load(pkg *packages.Packet) {
if err := pkg.Load(); err != nil {
log.Error("Failed to load packet %s: %s", pkg.Name(), err)
} else {
log.Info("Loaded %s", pkg.Name())
if err := e.Watch(pkg.Name(), pkg); err != nil {
log.Warn("Couldn't watch %s: %s", pkg.Name(), err)
}
}
}

func (e *Editor) loadKeyBindings() {
e.KeyBindings().SetParent(e.userBindings)
e.userBindings.KeyBindings().SetParent(e.platformBindings)
e.platformBindings.KeyBindings().SetParent(e.defaultBindings)
// Prevent running loadKeyBindings func more than once
if e.KeyBindings().Parent() != nil {
return
}
log.Fine("Loading editor keybindings")
e.KeyBindings().SetParent(e.userKB)
e.userKB.KeyBindings().SetParent(e.platformKB)
e.platformKB.KeyBindings().SetParent(e.defaultKB)

p := path.Join(LIME_DEFAULTS_PATH, "Default.sublime-keymap")
defPckt := packages.NewPacket(p, e.defaultBindings.KeyBindings())
e.load(defPckt)
p := path.Join(e.PackagesPath("default"), "Default.sublime-keymap")
packages.NewJSONL(p, e.defaultKB.KeyBindings())

p = path.Join(LIME_DEFAULTS_PATH, "Default ("+e.Plat()+").sublime-keymap")
platPckt := packages.NewPacket(p, e.platformBindings.KeyBindings())
e.load(platPckt)
p = path.Join(e.PackagesPath("default"), "Default ("+e.Plat()+").sublime-keymap")
packages.NewJSONL(p, e.platformKB.KeyBindings())

p = path.Join(LIME_USER_PACKAGES_PATH, "Default.sublime-keymap")
usrPckt := packages.NewPacket(p, e.userBindings.KeyBindings())
e.load(usrPckt)
p = path.Join(e.PackagesPath("user"), "Default.sublime-keymap")
packages.NewJSONL(p, e.userKB.KeyBindings())

p = path.Join(LIME_USER_PACKAGES_PATH, "Default ("+e.Plat()+").sublime-keymap")
usrPlatPckt := packages.NewPacket(p, e.KeyBindings())
e.load(usrPlatPckt)
p = path.Join(e.PackagesPath("user"), "Default ("+e.Plat()+").sublime-keymap")
packages.NewJSONL(p, e.KeyBindings())
}

func (e *Editor) loadSettings() {
e.platformSettings.Settings().SetParent(e.defaultSettings)
e.Settings().SetParent(e.platformSettings)
// Prevent running loadSettings func more than once
if e.Settings().Parent() != nil {
return
}
log.Fine("Loading editor settings")
e.platformSet.Settings().SetParent(e.defaultSet)
e.Settings().SetParent(e.platformSet)

p := path.Join(LIME_DEFAULTS_PATH, "Preferences.sublime-settings")
defPckt := packages.NewPacket(p, e.defaultSettings.Settings())
e.load(defPckt)
p := path.Join(e.PackagesPath("default"), "Preferences.sublime-settings")
packages.NewJSONL(p, e.defaultSet.Settings())

p = path.Join(LIME_DEFAULTS_PATH, "Preferences ("+e.Plat()+").sublime-settings")
platPckt := packages.NewPacket(p, e.platformSettings.Settings())
e.load(platPckt)
p = path.Join(e.PackagesPath("default"), "Preferences ("+e.Plat()+").sublime-settings")
packages.NewJSONL(p, e.platformSet.Settings())

p = path.Join(LIME_USER_PACKAGES_PATH, "Preferences.sublime-settings")
usrPckt := packages.NewPacket(p, e.Settings())
e.load(usrPckt)
p = path.Join(e.PackagesPath("user"), "Preferences.sublime-settings")
packages.NewJSONL(p, e.Settings())
}

func (e *Editor) PackagesPath() string {
return LIME_PACKAGES_PATH
func (e *Editor) PackagesPath(key string) string {
return e.pkgsPaths[key]
}

func (e *Editor) Console() *View {
Expand Down Expand Up @@ -430,3 +428,22 @@ func (e *Editor) handleLog(s string) {
c.Insert(edit, c.Buffer().Size(), f)
c.EndEdit(edit)
}

func (e *Editor) AddPackagesPath(key, p string) {
if p0, ok := e.pkgsPaths[key]; ok {
log.Debug("Changing package path %s: %s to %s", key, p0, p)
e.RemovePackagesPath(key)
} else {
log.Debug("Adding package path %s: %s", key, p)
}
e.pkgsPaths[key] = p
OnPackagesPathAdd.call(p)
}

func (e *Editor) RemovePackagesPath(key string) {
if p, ok := e.pkgsPaths[key]; ok {
log.Debug("Removing package path %s: %s", key, p)
OnPackagesPathRemove.call(p)
}
delete(e.pkgsPaths, key)
}
29 changes: 16 additions & 13 deletions lib/editor_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,12 @@
package backend

import (
"github.com/limetext/lime-backend/lib/keys"
"github.com/limetext/lime-backend/lib/packages"
"path"
"testing"
)

func init() {
LIME_PACKAGES_PATH = path.Join("..", "packages")
LIME_USER_PACKAGES_PATH = path.Join("..", "packages", "User")
LIME_DEFAULTS_PATH = path.Join("..", "packages", "Default")
}
"github.com/limetext/lime-backend/lib/keys"
"github.com/limetext/lime-backend/lib/packages"
)

func TestGetEditor(t *testing.T) {
editor := GetEditor()
Expand All @@ -26,8 +21,7 @@ func TestGetEditor(t *testing.T) {

func TestLoadKeyBinding(t *testing.T) {
editor := GetEditor()
pkg := packages.NewPacket("testdata/Default.sublime-keymap", editor.KeyBindings())
editor.load(pkg)
packages.NewJSONL("testdata/Default.sublime-keymap", editor.KeyBindings())

kb := editor.KeyBindings().Filter(keys.KeyPress{Key: 'i'})
if expectedLen := 3; kb.Len() != expectedLen {
Expand All @@ -39,14 +33,14 @@ func TestLoadKeyBindings(t *testing.T) {
editor := GetEditor()
editor.loadKeyBindings()

if editor.defaultBindings.KeyBindings().Len() <= 0 {
if editor.defaultKB.KeyBindings().Len() <= 0 {
t.Errorf("Expected editor to have some keys bound, but it didn't")
}
}

func TestLoadSetting(t *testing.T) {
editor := GetEditor()
editor.load(packages.NewPacket("testdata/Default.sublime-settings", editor.Settings()))
packages.NewJSONL("testdata/Default.sublime-settings", editor.Settings())

if editor.Settings().Has("tab_size") != true {
t.Error("Expected editor settings to have tab_size, but it didn't")
Expand Down Expand Up @@ -87,7 +81,7 @@ func TestInit(t *testing.T) {
editor := GetEditor()
editor.Init()

if editor.defaultBindings.KeyBindings().Len() <= 0 {
if editor.defaultKB.KeyBindings().Len() <= 0 {
t.Errorf("Expected editor to have some keys bound, but it didn't")
}

Expand Down Expand Up @@ -189,6 +183,7 @@ func TestClipboard(t *testing.T) {
}
}

/* TODO: causing panic
func TestHandleInput(t *testing.T) {
editor := GetEditor()
kp := keys.KeyPress{Key: 'i'}
Expand All @@ -199,3 +194,11 @@ func TestHandleInput(t *testing.T) {
t.Errorf("Expected %s to be on the input buffer, but got %s", kp, ki)
}
}
*/

func init() {
ed := GetEditor()
ed.AddPackagesPath("shipped", path.Join("testdata", "shipped"))
ed.AddPackagesPath("default", path.Join("testdata", "default"))
ed.AddPackagesPath("user", path.Join("testdata", "user"))
}
27 changes: 27 additions & 0 deletions lib/events.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,12 @@ type (
// is typically used by feature modules to defer heavy initialization work
// such as scanning for plugins, loading key bindings, macros etc.
InitEvent []InitCallback

// Dealing with package events
PackagesPathEventCallback func(string)

// A PackagesPathEvent is simply a bunch of PackagesPathEventCallbacks.
PackagesPathEvent []PackagesPathEventCallback
)

const (
Expand Down Expand Up @@ -80,6 +86,7 @@ func (ve *ViewEvent) Add(cb ViewEventCallback) {
}

// Trigger this ViewEvent by calling all the registered callbacks in order of registration.
// TODO: should calling be exported?
func (ve *ViewEvent) Call(v *View) {
log.Finest("%s(%v)", evNames[ve], v.Id())
for _, ev := range *ve {
Expand All @@ -95,6 +102,7 @@ func (qe *QueryContextEvent) Add(cb QueryContextCallback) {

// Searches for a QueryContextCallback and returns the result of the first callback being able to deal with this
// context, or Unknown if no such callback was found.
// TODO: should calling be exported?
func (qe QueryContextEvent) Call(v *View, key string, operator util.Op, operand interface{}, match_all bool) QueryContextReturn {
log.Fine("Query context: %s, %v, %v, %v", key, operator, operand, match_all)
for i := range qe {
Expand All @@ -114,13 +122,25 @@ func (we *WindowEvent) Add(cb WindowEventCallback) {
}

// Trigger this WindowEvent by calling all the registered callbacks in order of registration.
// TODO: should calling be exported?
func (we *WindowEvent) Call(w *Window) {
log.Finest("%s(%v)", wevNames[we], w.Id())
for _, ev := range *we {
ev(w)
}
}

func (pe *PackagesPathEvent) Add(cb PackagesPathEventCallback) {
*pe = append(*pe, cb)
}

func (pe *PackagesPathEvent) call(p string) {
log.Finest("%s(%v)", pkgPathevNames[pe], p)
for _, ev := range *pe {
ev(p)
}
}

var (
OnNew ViewEvent //< Called when a new view is created
OnLoad ViewEvent //< Called when loading a view's buffer has finished
Expand All @@ -136,6 +156,9 @@ var (
OnNewWindow WindowEvent //< Called when a new window has been created.
OnQueryContext QueryContextEvent //< Called when context is being queried.
OnInit InitEvent //< Called once at program startup

OnPackagesPathAdd PackagesPathEvent
OnPackagesPathRemove PackagesPathEvent
)

var (
Expand All @@ -154,6 +177,10 @@ var (
wevNames = map[*WindowEvent]string{
&OnNewWindow: "OnNewWindow",
}
pkgPathevNames = map[*PackagesPathEvent]string{
&OnPackagesPathAdd: "OnPackagesPathAdd",
&OnPackagesPathRemove: "OnPackagesPathRemove",
}
)

func init() {
Expand Down
Loading

0 comments on commit fadeee7

Please sign in to comment.