mirror of
https://github.com/samsonjs/mojo.el.git
synced 2026-03-25 09:25:49 +00:00
[NEW] Added build script and Rakefile to project.
This commit is contained in:
parent
30a2a3d4d2
commit
95c0f355ab
7 changed files with 788 additions and 64 deletions
17
Rakefile
Normal file
17
Rakefile
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
require 'rubygems'
|
||||
|
||||
desc "Default task (builds mojo.el)"
|
||||
task :default => [:build]
|
||||
|
||||
desc "Build mojo.el"
|
||||
task :build do
|
||||
Dir.chdir 'src'
|
||||
require 'assemble'
|
||||
begin
|
||||
Assembler.go!
|
||||
puts "XD"
|
||||
rescue RuntimeError => e
|
||||
puts ":("
|
||||
raise e.inspect
|
||||
end
|
||||
end
|
||||
66
mojo.el
66
mojo.el
|
|
@ -1,5 +1,5 @@
|
|||
;;; mojo.el --- Interactive functions to aid the development of webOS apps
|
||||
;; 2009-11-22 22:23:26
|
||||
;;; ../mojo.el --- Interactive functions to aid the development of webOS apps
|
||||
;; 2009-11-24 09:51:16
|
||||
(defconst mojo-version "0.9.4")
|
||||
|
||||
(require 'json)
|
||||
|
|
@ -114,68 +114,6 @@ ideas. Send me a pull request on github if you hack on mojo.el.")
|
|||
;; Run Mojo in debug mode. Assumed true while in such an early version.
|
||||
;; default = t
|
||||
|
||||
;; CHANGELOG
|
||||
;; =========
|
||||
;;
|
||||
;; sjs 2009-11-22
|
||||
;; v 0.9.4 launch emulator if needed
|
||||
;;
|
||||
;; - Commands that use the emulator launch it if necessary and wait till
|
||||
;; it is fully booted before running commands.
|
||||
;;
|
||||
;; sjs 2009-11-21
|
||||
;; v 0.9.3 (one more bug fix for today)
|
||||
;;
|
||||
;; - Don't pass -d switch to commands that don't accept it.
|
||||
;;
|
||||
;; sjs 2009-11-21
|
||||
;; v 0.9.2 (bug fixes)
|
||||
;;
|
||||
;; - reading json files no longer messes up your buffer history.
|
||||
;;
|
||||
;; - app list completion works now (caching bug)
|
||||
;;
|
||||
;; sjs 2009-11-21
|
||||
;; v 0.9.1
|
||||
;;
|
||||
;; - Added mojo-package-install-and-launch.
|
||||
;;
|
||||
;; - New variable for specifying whether commands target the
|
||||
;; device or emulator, *mojo-target*. Set it to 'usb' for a
|
||||
;; real device and 'tcp' for the emulator. Defaults to 'tcp'.
|
||||
;; To set the default target you can use the convenience
|
||||
;; functions mojo-target-device and mojo-target-emulator.
|
||||
;;
|
||||
;; sjs 2009-11-20
|
||||
;; v 0.9
|
||||
;;
|
||||
;; - Automatically find Mojo project root by searching upwards
|
||||
;; for appinfo.json.
|
||||
;;
|
||||
;; - Added command for generating new scenes,
|
||||
;; mojo-generate-scene.
|
||||
;;
|
||||
;; - mojo-package now operates only on the current project.
|
||||
;;
|
||||
;; - Parse appinfo.json to get version, used for installing &
|
||||
;; launching with less interaction.
|
||||
;;
|
||||
;; - mojo-install, mojo-launch, mojo-inspect, and mojo-delete
|
||||
;; still read in arguments but have the current project/app as
|
||||
;; the default values.
|
||||
;;
|
||||
;; - New convenience method: mojo-package-install-and-inspect
|
||||
;; This function only operates on the active app and does not
|
||||
;; read in any input.
|
||||
;;
|
||||
;; - Remembered filenames and app ids are cleared when the Mojo
|
||||
;; project root changes. (DWIM)
|
||||
;;
|
||||
;; - Parse output of `palm-install --list` for app id
|
||||
;; completion. App id completion was ported from cheat.el.
|
||||
;;
|
||||
;; v 0.2 - Fixed some minor bugs
|
||||
;; v 0.1 - Initial release
|
||||
|
||||
|
||||
;;; Code:
|
||||
|
|
|
|||
79
src/assemble.rb
Executable file
79
src/assemble.rb
Executable file
|
|
@ -0,0 +1,79 @@
|
|||
#!/usr/bin/env ruby
|
||||
|
||||
require 'rubygems'
|
||||
require 'json'
|
||||
require 'blankslate'
|
||||
|
||||
class Assembler
|
||||
|
||||
# When you insert lambdas into a LazyHash they are automatically executed
|
||||
# when the value is retrieved, and the result is cached in place of the
|
||||
# original lambda value.
|
||||
class LazyHash < Hash
|
||||
alias_method :original_get, :[]
|
||||
def [](key)
|
||||
if value = original_get(key)
|
||||
if value.respond_to?(:call)
|
||||
self[key] = value.call
|
||||
original_get(key)
|
||||
else
|
||||
value
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
class AssemblerDelegate < BlankSlate
|
||||
attr_reader :app, :files
|
||||
def initialize(app, files)
|
||||
@app = app
|
||||
@files = files
|
||||
end
|
||||
def timestamp
|
||||
Time.now.strftime('%Y-%m-%d %H:%M:%S')
|
||||
end
|
||||
def process(string)
|
||||
eval(string)
|
||||
end
|
||||
end
|
||||
|
||||
attr_reader :app, :files, :delegate
|
||||
|
||||
def self.go!
|
||||
new.write_output!
|
||||
end
|
||||
|
||||
def initialize
|
||||
@app = JSON.parse(File.read('info.json'))
|
||||
@files = Dir['*'].select {|f| File.file?(f)}.
|
||||
inject(LazyHash.new) {|h,f|
|
||||
h[f] = lambda { read_file(f) };h
|
||||
}
|
||||
@delegate = AssemblerDelegate.new(@app, @files)
|
||||
end
|
||||
|
||||
def read_file(f)
|
||||
if f[-3,3] == '.el'
|
||||
File.read(f)
|
||||
else
|
||||
File.readlines(f).map{|l| ";; #{l}"}.join
|
||||
end
|
||||
end
|
||||
|
||||
def write_output!
|
||||
output = File.read(app['template']).
|
||||
gsub(/#\{[^}]+\}/) {|m| @delegate.process(m[2..-2])}
|
||||
File.open(app['filename'], 'w') {|f| f.puts(output)}
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
if __FILE__ == $0
|
||||
begin
|
||||
Assembler.go!
|
||||
puts "XD"
|
||||
rescue RuntimeError => e
|
||||
puts e.inspect
|
||||
puts ":("
|
||||
end
|
||||
end
|
||||
113
src/blankslate.rb
Normal file
113
src/blankslate.rb
Normal file
|
|
@ -0,0 +1,113 @@
|
|||
#!/usr/bin/env ruby
|
||||
#--
|
||||
# Copyright 2004, 2006 by Jim Weirich (jim@weirichhouse.org).
|
||||
# All rights reserved.
|
||||
|
||||
# Permission is granted for use, copying, modification, distribution,
|
||||
# and distribution of modified versions of this work as long as the
|
||||
# above copyright notice is included.
|
||||
#++
|
||||
|
||||
######################################################################
|
||||
# BlankSlate provides an abstract base class with no predefined
|
||||
# methods (except for <tt>\_\_send__</tt> and <tt>\_\_id__</tt>).
|
||||
# BlankSlate is useful as a base class when writing classes that
|
||||
# depend upon <tt>method_missing</tt> (e.g. dynamic proxies).
|
||||
#
|
||||
class BlankSlate
|
||||
class << self
|
||||
|
||||
# Hide the method named +name+ in the BlankSlate class. Don't
|
||||
# hide +instance_eval+ or any method beginning with "__".
|
||||
def hide(name)
|
||||
if instance_methods.include?(name.to_s) and
|
||||
name !~ /^(__|instance_eval)/
|
||||
@hidden_methods ||= {}
|
||||
@hidden_methods[name.to_sym] = instance_method(name)
|
||||
undef_method name
|
||||
end
|
||||
end
|
||||
|
||||
def find_hidden_method(name)
|
||||
@hidden_methods ||= {}
|
||||
@hidden_methods[name] || superclass.find_hidden_method(name)
|
||||
end
|
||||
|
||||
# Redefine a previously hidden method so that it may be called on a blank
|
||||
# slate object.
|
||||
def reveal(name)
|
||||
bound_method = nil
|
||||
unbound_method = find_hidden_method(name)
|
||||
fail "Don't know how to reveal method '#{name}'" unless unbound_method
|
||||
define_method(name) do |*args|
|
||||
bound_method ||= unbound_method.bind(self)
|
||||
bound_method.call(*args)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
instance_methods.each { |m| hide(m) }
|
||||
end
|
||||
|
||||
######################################################################
|
||||
# Since Ruby is very dynamic, methods added to the ancestors of
|
||||
# BlankSlate <em>after BlankSlate is defined</em> will show up in the
|
||||
# list of available BlankSlate methods. We handle this by defining a
|
||||
# hook in the Object and Kernel classes that will hide any method
|
||||
# defined after BlankSlate has been loaded.
|
||||
#
|
||||
module Kernel
|
||||
class << self
|
||||
alias_method :blank_slate_method_added, :method_added
|
||||
|
||||
# Detect method additions to Kernel and remove them in the
|
||||
# BlankSlate class.
|
||||
def method_added(name)
|
||||
result = blank_slate_method_added(name)
|
||||
return result if self != Kernel
|
||||
BlankSlate.hide(name)
|
||||
result
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
######################################################################
|
||||
# Same as above, except in Object.
|
||||
#
|
||||
class Object
|
||||
class << self
|
||||
alias_method :blank_slate_method_added, :method_added
|
||||
|
||||
# Detect method additions to Object and remove them in the
|
||||
# BlankSlate class.
|
||||
def method_added(name)
|
||||
result = blank_slate_method_added(name)
|
||||
return result if self != Object
|
||||
BlankSlate.hide(name)
|
||||
result
|
||||
end
|
||||
|
||||
def find_hidden_method(name)
|
||||
nil
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
######################################################################
|
||||
# Also, modules included into Object need to be scanned and have their
|
||||
# instance methods removed from blank slate. In theory, modules
|
||||
# included into Kernel would have to be removed as well, but a
|
||||
# "feature" of Ruby prevents late includes into modules from being
|
||||
# exposed in the first place.
|
||||
#
|
||||
class Module
|
||||
alias blankslate_original_append_features append_features
|
||||
def append_features(mod)
|
||||
result = blankslate_original_append_features(mod)
|
||||
return result if mod != Object
|
||||
instance_methods.each do |name|
|
||||
BlankSlate.hide(name)
|
||||
end
|
||||
result
|
||||
end
|
||||
end
|
||||
448
src/code.el
Normal file
448
src/code.el
Normal file
|
|
@ -0,0 +1,448 @@
|
|||
|
||||
(defcustom mojo-sdk-directory
|
||||
(case system-type
|
||||
((windows-nt) "c:/progra~1/palm/sdk")
|
||||
((darwin) "/opt/PalmSDK/Current")
|
||||
(t ""))
|
||||
"Path to where the mojo SDK is.
|
||||
|
||||
Note, using the old-school dos name of progra~1 was the only way i could make
|
||||
this work."
|
||||
:type 'directory
|
||||
:group 'mojo)
|
||||
|
||||
(defcustom mojo-project-directory ""
|
||||
"Directory where all your Mojo projects are located."
|
||||
:type 'directory
|
||||
:group 'mojo)
|
||||
|
||||
(defcustom mojo-build-directory ""
|
||||
"Directory where built projects are saved."
|
||||
:type 'directory
|
||||
:group 'mojo)
|
||||
|
||||
;;* debug
|
||||
(defcustom mojo-debug t
|
||||
"Run Mojo in debug mode. Assumed true while in such an early version."
|
||||
:type 'boolean
|
||||
:group 'mojo)
|
||||
|
||||
|
||||
;;* interactive generate
|
||||
(defun mojo-generate (title directory)
|
||||
"Generate a new Mojo application in the `mojo-project-directory'.
|
||||
|
||||
TITLE is the name of the application.
|
||||
DIRECTORY is the directory where the files are stored."
|
||||
;;TODO handle existing directories (use --overwrite)
|
||||
(interactive "sTitle: \nsDirectory Name (inside of mojo-project-directory): \n")
|
||||
(let ((mojo-dir (expand-file-name (concat mojo-project-directory "/" directory))))
|
||||
(when (file-exists-p mojo-dir)
|
||||
(error "Cannot mojo-generate onto an existing directory! (%s)" mojo-dir))
|
||||
(make-directory mojo-dir)
|
||||
(mojo-cmd "palm-generate" (list "-p" (format "\"{'title':'%s'}\"" title)
|
||||
mojo-dir))
|
||||
(find-file (concat mojo-dir "/appinfo.json"))))
|
||||
|
||||
;;* interactive
|
||||
(defun mojo-generate-scene (name)
|
||||
"Generate a new Mojo scene for the current application.
|
||||
|
||||
NAME is the name of the scene."
|
||||
(interactive "sScene Name: \n")
|
||||
(let ((mojo-dir (mojo-root)))
|
||||
(mojo-cmd "palm-generate" (list "-t" "new_scene"
|
||||
"-p" (format "name=%s" name) mojo-dir))
|
||||
(find-file (format "%s/app/assistants/%s-assistant.js" mojo-dir name))
|
||||
(find-file (format "%s/app/views/%s/%s-scene.html" mojo-dir name name))))
|
||||
|
||||
;;* interactive
|
||||
(defun mojo-emulate ()
|
||||
"Launch the palm emulator."
|
||||
(interactive)
|
||||
(unless (mojo-emulator-running-p)
|
||||
(mojo-cmd "palm-emulator" nil)))
|
||||
|
||||
;;* interactive
|
||||
(defun mojo-package ()
|
||||
"Package the current application into `MOJO-BUILD-DIRECTORY'."
|
||||
(interactive)
|
||||
(mojo-cmd "palm-package" (list "-o" (expand-file-name mojo-build-directory)
|
||||
(mojo-root))))
|
||||
|
||||
;;* interactive
|
||||
(defun mojo-install ()
|
||||
"Install the package named by `MOJO-PACKAGE-FILENAME'. The emulator needs to be running."
|
||||
(interactive)
|
||||
(mojo-ensure-emulator-is-running)
|
||||
(mojo-cmd-with-target "palm-install" (list (expand-file-name (mojo-read-package-filename))))
|
||||
(mojo-invalidate-app-cache))
|
||||
|
||||
;;* interactive
|
||||
(defun mojo-list ()
|
||||
"List all installed packages."
|
||||
(interactive)
|
||||
(mojo-ensure-emulator-is-running)
|
||||
(mojo-cmd-with-target "palm-install" (list "--list")))
|
||||
|
||||
;;* interactive
|
||||
(defun mojo-delete ()
|
||||
"Remove the current application using `MOJO-APP-ID'."
|
||||
(interactive)
|
||||
(mojo-ensure-emulator-is-running)
|
||||
(mojo-cmd-with-target "palm-install" (list "-r" (mojo-read-app-id)))
|
||||
(mojo-invalidate-app-cache))
|
||||
|
||||
;;* interactive
|
||||
(defun mojo-ensure-emulator-is-running ()
|
||||
"Launch the current application, and the emulator if necessary."
|
||||
(interactive)
|
||||
(if (string= "tcp" *mojo-target*)
|
||||
(progn
|
||||
(when (not (mojo-emulator-running-p))
|
||||
(mojo-emulate)
|
||||
(print "Launching the emulator, this will take a minute..."))
|
||||
(while (not (mojo-emulator-responsive-p))
|
||||
(sleep-for 3))
|
||||
(print "Emulator has booted!"))
|
||||
(print "Connect your device if necessary.")))
|
||||
|
||||
;;* interactive
|
||||
(defun mojo-launch ()
|
||||
"Launch the current application in the emulator."
|
||||
(interactive)
|
||||
(mojo-ensure-emulator-is-running)
|
||||
(mojo-cmd-with-target "palm-launch" (list (mojo-read-app-id))))
|
||||
|
||||
;;* interactive
|
||||
(defun mojo-close ()
|
||||
"Close launched application."
|
||||
(interactive)
|
||||
(mojo-ensure-emulator-is-running)
|
||||
(mojo-cmd-with-target "palm-launch" (list "-c" (mojo-read-app-id))))
|
||||
|
||||
;;* launch interactive
|
||||
(defun mojo-inspect ()
|
||||
"Run the DOM inspector on the current application."
|
||||
(interactive)
|
||||
(mojo-ensure-emulator-is-running)
|
||||
(mojo-cmd-with-target "palm-launch" (list "-i" (mojo-read-app-id))))
|
||||
|
||||
;;* emulator interactive
|
||||
(defun mojo-hard-reset ()
|
||||
"Perform a hard reset, clearing all data."
|
||||
(interactive)
|
||||
(mojo-cmd "palm-emulator" (list "--reset")))
|
||||
|
||||
(defun mojo-browse ()
|
||||
"Use `browse-url' to visit your application with Palm Host."
|
||||
(browse-url "http://localhost:8888"))
|
||||
|
||||
|
||||
;;* interactive
|
||||
(defun mojo-package-install-and-inspect ()
|
||||
"Package, install, and launch the current application for inspection."
|
||||
(interactive)
|
||||
(mojo-package)
|
||||
(mojo-ensure-emulator-is-running)
|
||||
(mojo-cmd-with-target "palm-install" (list (expand-file-name (mojo-package-filename))))
|
||||
(mojo-cmd-with-target "palm-launch" (list "-i" (mojo-app-id))))
|
||||
|
||||
;;* interactive
|
||||
(defun mojo-package-install-and-launch ()
|
||||
"Package, install, and launch the current application."
|
||||
(interactive)
|
||||
(mojo-package)
|
||||
(mojo-ensure-emulator-is-running)
|
||||
(mojo-cmd-with-target "palm-install" (list (expand-file-name (mojo-package-filename))))
|
||||
(mojo-cmd-with-target "palm-launch" (list (mojo-app-id))))
|
||||
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; Some support functions that grok the basics of a Mojo project. ;;
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
(defun drop-last-path-component (path)
|
||||
"Get the head of a path by dropping the last component."
|
||||
(if (< (length path) 2)
|
||||
path
|
||||
(substring path 0 (- (length path)
|
||||
(length (last-path-component path))
|
||||
1)))) ;; subtract one more for the trailing slash
|
||||
|
||||
(defun last-path-component (path)
|
||||
"Get the tail of a path, i.e. the last component."
|
||||
(if (< (length path) 2)
|
||||
path
|
||||
(let ((start -2))
|
||||
(while (not (string= "/" (substring path start (+ start 1))))
|
||||
(setq start (- start 1)))
|
||||
(substring path (+ start 1)))))
|
||||
|
||||
(defvar *mojo-last-root* ""
|
||||
"Last Mojo root found by `MOJO-ROOT'.")
|
||||
|
||||
(defun mojo-root ()
|
||||
"Find a Mojo project's root directory starting with `DEFAULT-DIRECTORY'."
|
||||
(let ((last-component (last-path-component default-directory))
|
||||
(dir-prefix default-directory))
|
||||
;; remove last path element until we find appinfo.json
|
||||
(while (and (not (file-exists-p (concat dir-prefix "/appinfo.json")))
|
||||
(not (< (length dir-prefix) 2)))
|
||||
(setq last-component (last-path-component dir-prefix))
|
||||
(setq dir-prefix (drop-last-path-component dir-prefix)))
|
||||
|
||||
;; If no Mojo root found, ask for a directory.
|
||||
(if (< (length dir-prefix) 2)
|
||||
(setq dir-prefix (mojo-read-root)))
|
||||
|
||||
;; Invalidate cached values when changing projects.
|
||||
(if (or (blank *mojo-last-root*)
|
||||
(not (string= dir-prefix *mojo-last-root*)))
|
||||
(progn
|
||||
(setq *mojo-last-root* dir-prefix)
|
||||
(setq *mojo-package-filename* nil)
|
||||
(setq *mojo-app-id* nil)))
|
||||
|
||||
dir-prefix))
|
||||
|
||||
(defun read-json-file (filename)
|
||||
"Parse the JSON in FILENAME and return the result."
|
||||
(save-excursion
|
||||
(let ((origbuffer (current-buffer))
|
||||
(filebuffer (find-file-noselect filename)))
|
||||
(set-buffer filebuffer)
|
||||
(let ((text (buffer-string)))
|
||||
(switch-to-buffer origbuffer)
|
||||
(json-read-from-string text)))))
|
||||
|
||||
(defun mojo-app-version ()
|
||||
"Parse the project version from the appinfo.json file in `MOJO-ROOT'."
|
||||
(let ((appinfo (read-json-file (concat (mojo-root) "/appinfo.json"))))
|
||||
(cdr (assoc 'version appinfo))))
|
||||
|
||||
(defun mojo-app-id ()
|
||||
"Parse the project id from the appinfo.json file in `MOJO-ROOT'."
|
||||
(let ((appinfo (read-json-file (concat (mojo-root) "/appinfo.json"))))
|
||||
(cdr (assoc 'id appinfo))))
|
||||
|
||||
(defun mojo-package-filename ()
|
||||
"Get the package filename for the specified application."
|
||||
(format "%s/%s_%s_all.ipk" (expand-file-name mojo-build-directory)
|
||||
(mojo-app-id) (mojo-app-version)))
|
||||
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;;; app listing and completion ;;;
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
(defvar *mojo-app-cache-filename* nil)
|
||||
(defun mojo-app-cache-file (&optional force-reload)
|
||||
"Cache the list of applications in a temporary file. Return the filename."
|
||||
(when (or force-reload
|
||||
(not *mojo-app-cache-filename*))
|
||||
(setq *mojo-app-cache-filename* (make-temp-file "mojo-app-list-cache"))
|
||||
(save-excursion
|
||||
(let ((buffer (find-file-noselect *mojo-app-cache-filename*))
|
||||
(apps (mojo-fetch-app-list)))
|
||||
(set-buffer buffer)
|
||||
(insert (string-join "\n" apps))
|
||||
(basic-save-buffer)
|
||||
(kill-buffer buffer))))
|
||||
*mojo-app-cache-filename*)
|
||||
|
||||
(defvar *mojo-app-id* nil
|
||||
"Most recently used application id.")
|
||||
|
||||
(defvar *mojo-package-filename* nil
|
||||
"Most recently used package file.")
|
||||
|
||||
(defvar *mojo-app-history* nil
|
||||
"List of the most recently used application ids.")
|
||||
|
||||
;; cache expires hourly by default
|
||||
(defvar *mojo-app-cache-ttl* 3600
|
||||
"The minimum age of a stale cache file, in seconds.")
|
||||
|
||||
(defvar *mojo-package-history* nil
|
||||
"List of the most recently used package filenames.")
|
||||
|
||||
;; this is from rails-lib.el in the emacs-rails package
|
||||
(defun string-join (separator strings)
|
||||
"Join all STRINGS using SEPARATOR."
|
||||
(mapconcat 'identity strings separator))
|
||||
|
||||
(defun blank (thing)
|
||||
"Return T if THING is nil or an empty string, otherwise nil."
|
||||
(or (null thing)
|
||||
(and (stringp thing)
|
||||
(= 0 (length thing)))))
|
||||
|
||||
(defun mojo-read-root ()
|
||||
"Get the path to a Mojo application, prompting with completion and
|
||||
history."
|
||||
(read-file-name "Mojo project: " (expand-file-name (concat mojo-project-directory "/"))))
|
||||
|
||||
(defun mojo-read-package-filename ()
|
||||
"Get the filename of a packaged application, prompting with completion and
|
||||
history.
|
||||
|
||||
The app id is stored in *mojo-package-filename* unless it was blank."
|
||||
(let* ((default (or *mojo-package-filename*
|
||||
(mojo-package-filename)))
|
||||
(package (read-file-name (format "Package file (default: %s): " default)
|
||||
(concat mojo-build-directory "/") default t)))
|
||||
(setq *mojo-package-filename* (last-path-component package))
|
||||
(expand-file-name package)))
|
||||
|
||||
(defun mojo-read-app-id (&optional prompt)
|
||||
"Get the id of an existing application, prompting with completion and
|
||||
history.
|
||||
|
||||
The app id is stored in *mojo-app-id* unless it was blank."
|
||||
(let* ((default (or *mojo-app-id* (mojo-app-id)))
|
||||
(prompt (or prompt
|
||||
(format "App id (default: %s): " default)))
|
||||
(app-id (completing-read prompt
|
||||
(mojo-app-list t)
|
||||
nil
|
||||
t
|
||||
nil
|
||||
'*mojo-app-history*
|
||||
default)))
|
||||
(when (blank app-id)
|
||||
(setq app-id (mojo-app-id)))
|
||||
(setq *mojo-app-id* app-id)
|
||||
app-id))
|
||||
|
||||
(defun mojo-app-list (&optional fetch-if-missing-or-stale)
|
||||
"Get a list of installed Mojo applications."
|
||||
(cond ((and (file-readable-p (mojo-app-cache-file))
|
||||
(not (mojo-app-cache-stale-p)))
|
||||
(save-excursion
|
||||
(let* ((buffer (find-file (mojo-app-cache-file)))
|
||||
(apps (split-string (buffer-string))))
|
||||
(kill-buffer buffer)
|
||||
apps)))
|
||||
(fetch-if-missing-or-stale
|
||||
(mojo-app-cache-file t) ;; force reload
|
||||
(mojo-app-list)) ;; guaranteed cache hit this time
|
||||
(t nil)))
|
||||
|
||||
(defun mojo-fetch-app-list ()
|
||||
"Fetch a fresh list of all applications."
|
||||
(mojo-ensure-emulator-is-running)
|
||||
(let* ((raw-list (nthcdr 7 (split-string (mojo-cmd-to-string "palm-install" (list "--list")))))
|
||||
(apps (list))
|
||||
(appname-regex "^[^0-9][^.]+\\(\\.[^.]+\\)+$")
|
||||
(item (pop raw-list)))
|
||||
(while item
|
||||
(if (string-match appname-regex item) ;; liberal regex for simplicity
|
||||
(push item apps)
|
||||
(print (concat "discarding " item)))
|
||||
(setq item (pop raw-list)))
|
||||
(nreverse apps)))
|
||||
|
||||
(defun mojo-app-cache-stale-p ()
|
||||
"Non-nil if the cache in `MOJO-APP-CACHE-FILE' is more than
|
||||
*mojo-app-cache-ttl* seconds old.
|
||||
|
||||
If the cache file does not exist then it is considered stale."
|
||||
(or (null (file-exists-p (mojo-app-cache-file)))
|
||||
(let* ((now (float-time (current-time)))
|
||||
(last-mod (float-time (sixth (file-attributes
|
||||
(mojo-app-cache-file)))))
|
||||
(age (- now last-mod)))
|
||||
(> age *mojo-app-cache-ttl*))))
|
||||
|
||||
(defun mojo-invalidate-app-cache ()
|
||||
"Delete the app list cache."
|
||||
(delete-file (mojo-app-cache-file)))
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
;;* lowlevel luna
|
||||
(defun mojo-luna-send (url data)
|
||||
"Send something through luna.
|
||||
|
||||
Luna-send is a program to send things like incoming calls, GPS status, SMS,
|
||||
etc. to your emulator.
|
||||
|
||||
This is a low level Emacs interface to luna-send.
|
||||
URL is the luna url, and DATA is the data."
|
||||
(mojo-cmd "luna-send" (list "-n" "1" url data)))
|
||||
|
||||
(defvar *mojo-target* "tcp"
|
||||
"Used to specify the target platform, \"usb\" for the device
|
||||
and \"tcp\" for the emulator. Deaults to \"tcp\".")
|
||||
|
||||
(defun mojo-target-device ()
|
||||
"Specify that Mojo commands should target a real device.
|
||||
|
||||
Sets `*mojo-target*' to \"usb\"."
|
||||
(setq *mojo-target* "usb"))
|
||||
|
||||
(defun mojo-target-emulator ()
|
||||
"Specify that Mojo commands should target a real device.
|
||||
|
||||
Sets `*mojo-target*' to \"tcp\"."
|
||||
(setq *mojo-target* "tcp"))
|
||||
|
||||
(defun mojo-emulator-running-p ()
|
||||
"Determine if the webOS emulator is running or not.
|
||||
|
||||
This command only works on Unix-like systems."
|
||||
(= 0 (shell-command "ps x | fgrep 'Palm SDK' | fgrep -v fgrep >/dev/null 2>&1")))
|
||||
|
||||
(defun mojo-emulator-responsive-p ()
|
||||
"Determine if the webOS emulator is able to respond to commands yet
|
||||
(i.e. if it's done booting)."
|
||||
(= 0 (shell-command "palm-install -d tcp --list >/dev/null 2>&1")))
|
||||
|
||||
(defun mojo-path-to-cmd (cmd)
|
||||
"Return the absolute path to a Mojo SDK command line program."
|
||||
(case system-type
|
||||
((windows-nt) (concat mojo-sdk-directory "/bin/" cmd ".bat"))
|
||||
(t (concat mojo-sdk-directory "/bin/" cmd))))
|
||||
|
||||
;;* lowlevel cmd
|
||||
(defun mojo-cmd (cmd args)
|
||||
"General interface for running mojo-sdk commands.
|
||||
|
||||
CMD is the name of the command (without path or extension) to execute.
|
||||
Automagically shell quoted.
|
||||
ARGS is a list of all arguments to the command.
|
||||
These arguments are NOT shell quoted."
|
||||
(let ((cmd (mojo-path-to-cmd cmd))
|
||||
(args (string-join " " args)))
|
||||
(if mojo-debug (message "running %s with args %s " cmd args))
|
||||
(shell-command (concat cmd " " args))))
|
||||
|
||||
;;* lowlevel cmd
|
||||
(defun mojo-cmd-with-target (cmd args &optional target)
|
||||
"General interface for running mojo-sdk commands that accept a target device.
|
||||
|
||||
CMD is the name of the command (without path or extension) to
|
||||
execute. Automagically shell quoted. ARGS is a list of all
|
||||
arguments to the command. These arguments are NOT shell quoted.
|
||||
TARGET specifies the target device, \"tcp\" or \"usb\"."
|
||||
(let ((args (cons "-d" (cons (or target *mojo-target*) args))))
|
||||
(mojo-cmd cmd args)))
|
||||
|
||||
;;* lowlevel cmd
|
||||
(defun mojo-cmd-to-string (cmd args &optional target)
|
||||
"General interface for running mojo-sdk commands and capturing the output
|
||||
to a string.
|
||||
|
||||
CMD is the name of the command (without path or extension) to execute.
|
||||
Automatically shell quoted.
|
||||
ARGS is a list of all arguments to the command.
|
||||
These arguments are NOT shell quoted."
|
||||
(let ((cmd (mojo-path-to-cmd cmd))
|
||||
(args (concat "-d " (or target *mojo-target*) " "
|
||||
(string-join " " args))))
|
||||
(if mojo-debug (message "running %s with args %s " cmd args))
|
||||
(shell-command-to-string (concat cmd " " args))))
|
||||
|
||||
(provide 'mojo)
|
||||
6
src/info.json
Normal file
6
src/info.json
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
{
|
||||
"title": "mojo.el",
|
||||
"filename": "../mojo.el",
|
||||
"version": "0.9.4",
|
||||
"template": "template.el"
|
||||
}
|
||||
123
src/template.el
Normal file
123
src/template.el
Normal file
|
|
@ -0,0 +1,123 @@
|
|||
;;; #{app['filename']} --- Interactive functions to aid the development of webOS apps
|
||||
;; #{timestamp}
|
||||
(defconst mojo-version "#{app['version']}")
|
||||
|
||||
(require 'json)
|
||||
|
||||
;; Copyright (c)2008 Jonathan Arkell. (by)(nc)(sa) Some rights reserved.
|
||||
;; 2009 Sami Samhuri
|
||||
;;
|
||||
;; Authors: Jonathan Arkell <jonnay@jonnay.net>
|
||||
;; Sami Samhuri <sami.samhuri@gmail.com>
|
||||
;;
|
||||
;; Latest version is available on github:
|
||||
;; http://github.com/samsonjs/config/blob/master/emacs.d/mojo.el
|
||||
;;
|
||||
;; With sufficient interest mojo.el will get its own repo.
|
||||
|
||||
;; This file is not part of GNU Emacs.
|
||||
|
||||
;; This program is free software; you can redistribute it and/or
|
||||
;; modify it under the terms of the GNU General Public License as
|
||||
;; published by the Free Software Foundation version 2.
|
||||
|
||||
;; This program is distributed in the hope that it will be useful, but
|
||||
;; WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
;; General Public License for more details.
|
||||
|
||||
;; For a copy of the GNU General Public License, search the Internet,
|
||||
;; or write to the Free Software Foundation, Inc., 59 Temple Place,
|
||||
;; Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
;;; Commentary:
|
||||
(defgroup mojo '()
|
||||
"Interactive functions to aid the development of webOS apps.
|
||||
|
||||
This package is in early beta. I am open to any contributions or
|
||||
ideas. Send me a pull request on github if you hack on mojo.el.")
|
||||
|
||||
;;; Installation:
|
||||
;;
|
||||
;; 1. Put json.el and mojo.el somewhere in your load-path.
|
||||
;; (Use M-x show-variable RET load-path to see what your load path is.)
|
||||
;;
|
||||
;; 2. Add this to your Emacs init file: (require 'mojo)
|
||||
;;
|
||||
;; 3. Make sure you customize the variables:
|
||||
;; mojo-project-directory, mojo-sdk-directory and mojo-build-directory
|
||||
;; (Use M-x customize-group RET mojo RET)
|
||||
;;
|
||||
;; (optional)
|
||||
;;
|
||||
;; 4. I recommend that you define a few keyboard shortcuts in your Emacs init
|
||||
;; file. Maybe something like this:
|
||||
;;
|
||||
;; (global-set-key [f2] mojo-generate-scene)
|
||||
;; (global-set-key [f3] mojo-emulate)
|
||||
;; (global-set-key [f4] mojo-package)
|
||||
;; (global-set-key [f5] mojo-package-install-and-inspect)
|
||||
;;
|
||||
|
||||
;;; Commands:
|
||||
;;
|
||||
;; Below are complete command list:
|
||||
;;
|
||||
;; `mojo-generate'
|
||||
;; Generate a new Mojo application in the `mojo-project-directory'.
|
||||
;; `mojo-generate-scene'
|
||||
;; Generate a new Mojo scene for the application in `mojo-root'.
|
||||
;; `mojo-emulate'
|
||||
;; Launch the palm emulator.
|
||||
;; `mojo-package'
|
||||
;; Package the current application.
|
||||
;; `mojo-install'
|
||||
;; Install the specified package for the current application.
|
||||
;; The emulator needs to be running.
|
||||
;; `mojo-list'
|
||||
;; List all installed packages.
|
||||
;; `mojo-delete'
|
||||
;; Remove application named APP-NAME.
|
||||
;; `mojo-launch'
|
||||
;; Launch the current application in an emulator.
|
||||
;; `mojo-close'
|
||||
;; Close launched application.
|
||||
;; `mojo-inspect'
|
||||
;; Run the dom inspector on the current application.
|
||||
;; `mojo-hard-reset'
|
||||
;; Perform a hard reset, clearing all data.
|
||||
;; `mojo-package-install-and-launch'
|
||||
;; Package, install, and launch the current app.
|
||||
;; `mojo-package-install-and-inspect'
|
||||
;; Package, install, and launch the current app for inspection.
|
||||
;; `mojo-target-device'
|
||||
;; Set the target to a USB device.
|
||||
;; `mojo-target-emulator'
|
||||
;; Set the target to the emulator.
|
||||
|
||||
;;; Customizable Options:
|
||||
;;
|
||||
;; Below are customizable option list:
|
||||
;;
|
||||
;; `mojo-sdk-directory'
|
||||
;; Path to where the mojo SDK is.
|
||||
;; default = (case system-type
|
||||
;; ((windows-nt) "c:/progra~1/palm/sdk")
|
||||
;; ((darwin) "/opt/PalmSDK/Current")
|
||||
;; (t ""))
|
||||
;; `mojo-project-directory'
|
||||
;; Directory where all your Mojo projects are located.
|
||||
;; default = ""
|
||||
;; `mojo-build-directory'
|
||||
;; Directory to build Mojo applications in.
|
||||
;; `mojo-debug'
|
||||
;; Run Mojo in debug mode. Assumed true while in such an early version.
|
||||
;; default = t
|
||||
|
||||
#{files['CHANGELOG']}
|
||||
|
||||
;;; Code:
|
||||
|
||||
#{files['code.el']}
|
||||
|
||||
;;; mojo ends here
|
||||
Loading…
Reference in a new issue