[UPDATED] mojo.el to 0.9.9 (bug fix for mojo-switch-file-dwim)

This commit is contained in:
Sami Samhuri 2009-12-04 16:35:33 -08:00
parent c5772f07dc
commit af79c9ef71
2 changed files with 546 additions and 153 deletions

4
emacs
View file

@ -140,6 +140,10 @@
(require 'mojo)
;; enable Mojo for CSS, HTML, JS, and JSON files within a Mojo project
;; root. Did I forget anything?
(mojo-setup-mode-hooks 'css-mode-hook 'js2-mode-hook 'espresso-mode-hook 'html-mode-hook)
;;;;;;;;;;;;;;;;
;; javascript ;;

View file

@ -1,6 +1,6 @@
;;; mojo.el --- Interactive functions to aid the development of webOS apps
;; 2009-12-01 08:29:25
(defconst mojo-version "0.9.6")
;;; mojo.el --- Interactive functions for webOS development
;; 2009-12-04 15:44:24
(defconst mojo-version "0.9.9")
(require 'json)
@ -13,87 +13,213 @@
;; Latest version is available on github:
;; http://github.com/samsonjs/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.
"Interactive functions for webOS development.
This package is in early beta. I am open to any contributions or
This package is in 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.)
;;
;; => http://github.com/samsonjs/mojo.el -- mojo.el and json.el
;; => http://edward.oconnor.cx/2006/03/json.el -- official json.el
;;
;; 2. Add this to your Emacs init file: (require 'mojo)
;;
;; 3. Make sure you customize the variables:
;; 3. Enable mojo-mode for modes that you use for webOS, e.g.:
;;
;; (mojo-setup-mode-hooks 'css-mode-hook 'js2-mode-hook
;; 'espresso-mode-hook 'html-mode-hook)
;;
;; * Note that this does not simply enable mojo-mode for these types
;; wholesale, but instead only enables mojo-mode when it finds that
;; the file is also under a Mojo project root (using mojo-project-p).
;;
;; 4. 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)
;; (optional but recommended)
;;
;; 4. I recommend that you define a few keyboard shortcuts in your Emacs init
;; file. Maybe something like this:
;; 5. js2-mode for JavaScript and espresso-mode for JSON.
;;
;; (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)
;; => http://code.google.com/p/js2-mode/
;; => http://www.nongnu.org/espresso/
;;
;;
;; That's it! You've got the most powerful Mojo development environment.
;;
;; Check COMMANDS for a list of all interactive commands and key bindings.
;;; Commands:
;;
;; Below are complete command list:
;; Default key bindings:
;;
;; `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'
;; * C-c C-c a -- mojo-switch-to-assistant
;; * C-c C-c i -- mojo-switch-to-appinfo
;; * C-c C-c I -- mojo-switch-to-index
;; * C-c C-c n -- mojo-switch-to-next-view
;; * C-c C-c s -- mojo-switch-to-sources
;; * C-c C-c S -- mojo-switch-to-stylesheet
;; * C-c C-c v -- mojo-switch-to-view
;; * C-c C-c SPC -- mojo-switch-file-dwim
;; * C-c C-c C-e -- mojo-emulate
;; * C-c C-c C-p -- mojo-package
;; * C-c C-c C-r -- mojo-package-install-and-inspect
;; * C-c C-c C-s -- mojo-generate-scene
;; * C-c C-c C-t -- mojo-toggle-target
;;
;;
;; The complete command list:
;;
;; Code generation
;; ---------------
;;
;; mojo-generate
;; Generate a new Mojo application in the mojo-project-directory.
;;
;; mojo-generate-scene
;; Generate a new Mojo scene for the application found by mojo-root.
;; (a.k.a. the current application)
;;
;;
;; Packaging and device/emulator interactions
;; ------------------------------------------
;;
;; mojo-emulate
;; Launch the palm emulator.
;; `mojo-package'
;; Package the current application.
;; `mojo-install'
;; Install the specified package for the current application.
;;
;; mojo-package
;; Package the specified application (defaults to current app id).
;;
;; mojo-install
;; Install the specified package (defaults to current app id).
;; The emulator needs to be running.
;; `mojo-list'
;;
;; 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'
;;
;; mojo-delete
;; Remove the specified application. (defaults to current app id)
;;
;; mojo-launch
;; Launch the specified application in the emulator. (defaults to
;; current app id)
;;
;; mojo-close
;; Close specified application. (defaults to current app id)
;;
;; mojo-inspect
;; Run the dom inspector on the specified application. (defaults to
;; current app id)
;;
;; mojo-hard-reset
;; Perform a hard reset, clearing all data.
;; `mojo-package-install-and-launch'
;;
;; mojo-package-install-and-launch
;; Package, install, and launch the current app.
;; `mojo-package-install-and-inspect'
;;
;; 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.
;;
;; mojo-target-device
;; Set the target device to USB.
;;
;; mojo-target-emulator
;; Set the target device to the emulator.
;;
;; mojo-toggle-target
;; Automatically change the target device from 'usb' to 'tcp' and vice
;; versa.
;;
;;
;; Quickly switch buffers
;; ----------------------
;;
;; mojo-switch-to-assistant
;; Switch to the corresponding assistant from any view file.
;;
;; mojo-switch-to-view
;; Switch to the main view from an assistant.
;;
;; mojo-switch-to-next-view
;; Switch to the next view file, alphabetically. Wraps around at the
;; end.
;;
;; mojo-switch-to-appinfo
;; Switch to the appinfo.json file.
;;
;; mojo-switch-to-sources
;; Switch to the sources.json file.
;;
;; mojo-switch-to-index
;; Switch to the root index.html file.
;;
;; mojo-switch-to-stylesheet
;; Switch to the main stylesheet.
;;
;;
;; Manage framework_config.json
;; ----------------------------
;;
;; mojo-debugging-enabled-p
;; See if debugging is enabled.
;;
;; mojo-log-events-p
;; See if event logging is enabled.
;;
;; mojo-timing-enabled-p
;; See if timing is enabled.
;;
;; mojo-use-native-json-parser-p
;; See if the native JSON parser is used (if available).
;;
;; mojo-log-level
;; See the log level.
;;
;; mojo-html-escaped-in-templates-p
;; See if HTML is escaped in templates.
;;
;; mojo-set-debugging-enabled
;; Enable or disable debugging.
;;
;; mojo-set-log-events
;; Enable or disable event logging.
;;
;; mojo-set-timing-enabled
;; Enable or disable timing.
;;
;; mojo-set-use-native-json-parser
;; Enable or disable use of the native JSON parser.
;;
;; mojo-set-log-level
;; Set the log level.
;;
;; mojo-set-escape-html-in-templates
;; Enable or disable escaping of HTML in templates.
;;; Customizable Options:
;;
@ -114,6 +240,103 @@ 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-12-04
;; v 0.9.9 (bug fix)
;;
;; - Fixed the value of *mojo-switch-suffixes*, which was confusing
;; mojo-switch-file-dwim.
;;
;; sjs 2009-12-04
;; v 0.9.8 (framework_config.json support)
;;
;; - Implemented support for framework_config.json. Functions for
;; both reading and writing all known values.
;;
;; sjs 2009-12-03
;; v 0.9.7 (hooks)
;;
;; - Added mojo-setup-mode-hooks which adds
;; mojo-maybe-enable-minor-mode to the specified mode hooks.
;; When the hooked modes are activated on files under a Mojo
;; project root also activate mojo-mode.
;;
;; sjs 2009-12-01
;; v 0.9.6 (minor mode)
;;
;; - Created mojo-mode, a minor mode with keybindings.
;;
;; - Prefixed *all* functions with "mojo-".
;;
;; sjs 2009-11-24
;; v 0.9.5 (bug fix)
;;
;; - Now that I have a real Palm Pre device I was able to test
;; device support. Turns out I couldn't (easily) target the
;; device because mojo-target-device was not interactive.
;; Whoops.
;;
;; 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:
@ -133,19 +356,19 @@ ideas. Send me a pull request on github if you hack on mojo.el.")
Keybindings are:
* C-c a -- \\[mojo-switch-to-assistant]
* C-c i -- \\[mojo-switch-to-appinfo]
* C-c I -- \\[mojo-switch-to-index]
* C-c n -- \\[mojo-switch-to-next-view]
* C-c s -- \\[mojo-switch-to-sources]
* C-c S -- \\[mojo-switch-to-stylesheet]
* C-c v -- \\[mojo-switch-to-view]
* C-c SPC -- \\[mojo-switch-file-dwim]
* C-c C-e -- \\[mojo-emulate]
* C-c C-p -- \\[mojo-package]
* C-c C-r -- \\[mojo-package-install-and-inspect]
* C-c C-s -- \\[mojo-generate-scene]
* C-c C-t -- \\[mojo-toggle-target]
* C-c C-c a -- \\[mojo-switch-to-assistant]
* C-c C-c i -- \\[mojo-switch-to-appinfo]
* C-c C-c I -- \\[mojo-switch-to-index]
* C-c C-c n -- \\[mojo-switch-to-next-view]
* C-c C-c s -- \\[mojo-switch-to-sources]
* C-c C-c S -- \\[mojo-switch-to-stylesheet]
* C-c C-c v -- \\[mojo-switch-to-view]
* C-c C-c SPC -- \\[mojo-switch-file-dwim]
* C-c C-c C-e -- \\[mojo-emulate]
* C-c C-c C-p -- \\[mojo-package]
* C-c C-c C-r -- \\[mojo-package-install-and-inspect]
* C-c C-c C-s -- \\[mojo-generate-scene]
* C-c C-c C-t -- \\[mojo-toggle-target]
See the source code mojo.el or the README file for a list of
all of the interactive commands."
@ -155,19 +378,19 @@ ideas. Send me a pull request on github if you hack on mojo.el.")
:lighter "-Mojo"
;; The minor mode bindings.
:keymap
'(("\C-ca" . mojo-switch-to-assistant)
("\C-ci" . mojo-switch-to-appinfo)
("\C-cI" . mojo-switch-to-index)
("\C-cn" . mojo-switch-to-next-view)
("\C-cs" . mojo-switch-to-sources)
("\C-cS" . mojo-switch-to-stylesheet)
("\C-cv" . mojo-switch-to-view)
("\C-c " . mojo-switch-file-dwim)
("\C-c\C-e" . mojo-emulate)
("\C-c\C-p" . mojo-package)
("\C-c\C-r" . mojo-package-install-and-inspect)
("\C-c\C-s" . mojo-generate-scene)
("\C-c\C-t" . mojo-toggle-target))
'(("\C-c\C-ca" . mojo-switch-to-assistant)
("\C-c\C-ci" . mojo-switch-to-appinfo)
("\C-c\C-cI" . mojo-switch-to-index)
("\C-c\C-cn" . mojo-switch-to-next-view)
("\C-c\C-cs" . mojo-switch-to-sources)
("\C-c\C-cS" . mojo-switch-to-stylesheet)
("\C-c\C-cv" . mojo-switch-to-view)
("\C-c\C-c " . mojo-switch-file-dwim)
("\C-c\C-c\C-e" . mojo-emulate)
("\C-c\C-c\C-p" . mojo-package)
("\C-c\C-c\C-r" . mojo-package-install-and-inspect)
("\C-c\C-c\C-s" . mojo-generate-scene)
("\C-c\C-c\C-t" . mojo-toggle-target))
:group 'mojo)
(defcustom mojo-sdk-directory
@ -198,6 +421,16 @@ this work."
:type 'boolean
:group 'mojo)
;; Call this from your emacs config file with the modes you want to hook.
(defun mojo-setup-mode-hooks (&rest hooks)
"Add `mojo-maybe-enable-minor-mode' to the specified mode hooks."
(dolist (hook hooks)
(add-hook hook 'mojo-maybe-enable-minor-mode)))
(defun mojo-maybe-enable-minor-mode ()
"Enable `mojo-mode' when the current buffer belongs to a Mojo project."
(when (mojo-project-p)
(mojo-mode)))
;;* interactive generate
(defun mojo-generate (title directory)
@ -221,7 +454,7 @@ DIRECTORY is the directory where the files are stored."
NAME is the name of the scene."
(interactive "sScene Name: \n")
(let ((mojo-dir (mojo-root)))
(let ((mojo-dir (mojo-root t)))
(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))
@ -239,11 +472,11 @@ NAME is the name of the scene."
"Package the current application into `MOJO-BUILD-DIRECTORY'."
(interactive)
(mojo-cmd "palm-package" (list "-o" (expand-file-name mojo-build-directory)
(mojo-root))))
(mojo-root t))))
;;* interactive
(defun mojo-install ()
"Install the package named by `MOJO-PACKAGE-FILENAME'. The emulator needs to be running."
"Install the package named by `MOJO-PACKAGE-FILENAME'. The emulator is started if needed."
(interactive)
(mojo-ensure-emulator-is-running)
(mojo-cmd-with-target "palm-install" (list (expand-file-name (mojo-read-package-filename))))
@ -258,7 +491,7 @@ NAME is the name of the scene."
;;* interactive
(defun mojo-delete ()
"Remove the current application using `MOJO-APP-ID'."
"Remove an application."
(interactive)
(mojo-ensure-emulator-is-running)
(mojo-cmd-with-target "palm-install" (list "-r" (mojo-read-app-id)))
@ -280,14 +513,14 @@ NAME is the name of the scene."
;;* interactive
(defun mojo-launch ()
"Launch the current application in the emulator."
"Launch the current application in the emulator, and the emulator if necessary.."
(interactive)
(mojo-ensure-emulator-is-running)
(mojo-cmd-with-target "palm-launch" (list (mojo-read-app-id))))
;;* interactive
(defun mojo-close ()
"Close launched application."
"Close an application."
(interactive)
(mojo-ensure-emulator-is-running)
(mojo-cmd-with-target "palm-launch" (list "-c" (mojo-read-app-id))))
@ -348,8 +581,7 @@ Sets `*mojo-target*' to \"tcp\"."
;;* interactive
(defun mojo-toggle-target ()
"Automatically change the target device from 'usb' to 'tcp' and
vice versa."
"Automatically change the target device from 'usb' to 'tcp' and vice versa."
(interactive)
(if (string= "usb" *mojo-target*)
(mojo-target-emulator)
@ -359,16 +591,16 @@ vice versa."
;; Some support functions that grok the basics of a Mojo project. ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(defun mojo-drop-last-path-component (path)
"Get the head of a path by dropping the last component."
(defun mojo-parent-directory (path)
"Get the parent directory, i.e. the head of a path by dropping the last component."
(if (< (length path) 2)
path
(substring path 0 (- (length path)
(length (mojo-last-path-component path))
(length (mojo-filename path))
1)))) ;; subtract one more for the trailing slash
(defun mojo-last-path-component (path)
"Get the tail of a path, i.e. the last component."
(defun mojo-filename (path)
"Get the filename from a path, i.e. the last component, or tail."
(if (< (length path) 2)
path
(let ((start -2))
@ -379,32 +611,34 @@ vice versa."
(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 (mojo-last-path-component default-directory))
(defun mojo-root (&optional ask)
"Find a Mojo project's root directory starting with `DEFAULT-DIRECTORY'.
If ASK is non-nil and no root was found, ask the user for a directory."
(let ((last-component (mojo-filename 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 (mojo-last-path-component dir-prefix))
(setq dir-prefix (mojo-drop-last-path-component dir-prefix)))
(setq last-component (mojo-filename dir-prefix))
(setq dir-prefix (mojo-parent-directory dir-prefix)))
;; If no Mojo root found, ask for a directory.
(if (< (length dir-prefix) 2)
(when (and ask (< (length dir-prefix) 2))
(setq dir-prefix (mojo-read-root)))
;; Invalidate cached values when changing projects.
(if (or (mojo-blank *mojo-last-root*)
(when (or (mojo-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)))
(setq *mojo-app-id* nil)
(setq *mojo-appinfo* nil))
dir-prefix))
;; foolproof?
;; foolproof enough? don't want false positives.
(defun mojo-project-p ()
"Return T if the current buffer belongs to a Mojo project, otherwise NIL."
(and (file-exists-p (concat (mojo-root) "/appinfo.json"))
(file-exists-p (concat (mojo-root) "/sources.json"))
(file-exists-p (concat (mojo-root) "/app"))
@ -413,34 +647,52 @@ vice versa."
(defun mojo-read-json-file (filename)
"Parse the JSON in FILENAME and return the result."
(save-excursion
(let ((origbuffer (current-buffer))
(filebuffer (find-file-noselect filename)))
(let* ((origbuffer (current-buffer))
(path (concat (mojo-root) "/" filename))
(filebuffer (find-file-noselect path)))
(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'."
(defun mojo-write-json-file (filename content)
"Convert CONTENT to JSON and write to FILENAME in `mojo-root'."
(save-excursion
(let* ((origbuffer (current-buffer))
(path (concat (mojo-root) "/" filename))
(filebuffer (find-file-noselect path)))
(set-buffer filebuffer)
(erase-buffer)
(insert (json-encode content) "\n")
(save-buffer)
(switch-to-buffer origbuffer))))
(defvar *mojo-appinfo* nil
"Last structure read from appinfo.json.")
(defun mojo-appinfo ()
"Get the contents of appinfo.json. Last read appinfo is cached."
(when (mojo-project-p)
(let ((appinfo (mojo-read-json-file (concat (mojo-root) "/appinfo.json"))))
(cdr (assoc 'version appinfo)))))
(or *mojo-appinfo*
(setq *mojo-appinfo* (mojo-read-json-file "appinfo.json")))))
(defun mojo-app-version ()
"Parse the project version from appinfo.json."
(when (mojo-project-p)
(cdr (assoc 'version (mojo-appinfo)))))
(defun mojo-app-id ()
"Parse the project id from the appinfo.json file in `MOJO-ROOT'."
"Parse the project id from appinfo.json."
(when (mojo-project-p)
(let ((appinfo (mojo-read-json-file (concat (mojo-root) "/appinfo.json"))))
(cdr (assoc 'id appinfo)))))
(cdr (assoc 'id (mojo-appinfo)))))
(defun mojo-app-title ()
"Parse the project title from appinfo.json."
(when (mojo-project-p)
(let ((appinfo (mojo-read-json-file (concat (mojo-root) "/appinfo.json"))))
(cdr (assoc 'title appinfo)))))
(cdr (assoc 'title (mojo-appinfo)))))
(defun mojo-informal-app-id ()
"Parse the project title from appinfo.json and remove all non alphanumeric
characters."
"Parse the project title from appinfo.json and remove all non alphanumeric characters."
(let ((title (downcase (mojo-app-title))))
(replace-regexp-in-string "[^a-z0-9]" "" title)))
@ -450,6 +702,123 @@ vice versa."
(mojo-app-id) (mojo-app-version)))
(defun mojo-framework-config ()
"Get the contents of framework_config.json."
(when (mojo-project-p)
(and (file-exists-p (concat (mojo-root) "/framework_config.json"))
(mojo-read-json-file "framework_config.json"))))
(defun mojo-write-framework-config (config)
"Set the contents of framework_config.json to the JSON representation of CONFIG."
(when (mojo-project-p)
(mojo-write-json-file "framework_config.json" config)))
(defun mojo-framework-config-value (key)
"Retrieve a value from framework_config.json."
(when (and (mojo-project-p)
(mojo-framework-config))
(cdr (assoc key (mojo-framework-config)))))
(defun mojo-framework-config-boolean (key)
"Retrieve the value of a boolean in framework_config.json."
(string= t (mojo-framework-config-value key)))
;;* interactive
(defun mojo-debugging-enabled-p ()
(interactive)
"Determine if debugging is enabled for the current Mojo project."
(print (mojo-framework-config-boolean 'debuggingEnabled)))
;;* interactive
(defun mojo-log-events-p ()
(interactive)
"Determine if event logging is enabled for the current Mojo project."
(print (mojo-framework-config-boolean 'logEvents)))
;;* interactive
(defun mojo-timing-enabled-p ()
(interactive)
"Determine if timing is enabled for the current Mojo project."
(print (mojo-framework-config-boolean 'timingEnabled)))
;;* interactive
(defun mojo-use-native-json-parser-p ()
(interactive)
"Determine if the native JSON parser is enabled for the current Mojo project."
(print (mojo-framework-config-boolean 'useNativeJSONParser)))
;;* interactive
(defun mojo-log-level ()
"The log level for the current Mojo project."
(interactive)
(when (and (mojo-project-p)
(mojo-framework-config))
(print (cdr (assoc 'logLevel (mojo-framework-config))))))
;;* interactive
(defun mojo-escape-html-in-templates-p ()
"Return T if HTML is escaped in templates, NIL otherwise."
(interactive)
(print (mojo-framework-config-boolean 'escapeHTMLInTemplates)))
(defun mojo-change-framework-config-value (key value)
"Set the value for a key in framework_config.json."
(interactive)
(when (mojo-project-p)
(let ((config (mojo-framework-config)))
(unless config (setq config (list)))
(setq config (assq-delete-all key config))
(mojo-write-framework-config (cons (cons key (or value :json-false))
config)))))
;;* interactive
(defun mojo-set-debugging-enabled (enabled)
"Enable debugging if ENABLED is t, or disable if it is nil or :json-false."
(interactive "XEnable debugging? (t or nil) ")
(mojo-change-framework-config-value 'debuggingEnabled enabled))
;;* interactive
(defun mojo-toggle-debugging ()
"If debugging is enabled then disable it, and vice versa."
(interactive)
(mojo-change-framework-config-value 'debuggingEnabled (not (mojo-debugging-enabled-p))))
;;* interactive
(defun mojo-set-log-level (level)
"Set the log level to the integer LEVEL.
Mojo.Log.LOG_LEVEL_INFO is 10
Mojo.Log.LOG_LEVEL_ERROR is 30"
(interactive "nLog level: ")
(mojo-change-framework-config-value 'logLevel level))
;;* interactive
(defun mojo-set-escape-html-in-templates (enabled)
"Escape HTML if ENABLED is t, don't escape HTML if it is nil or :json-false."
(interactive "XEscape HTML in templates? (t or nil) ")
(mojo-change-framework-config-value 'escapeHTMLInTemplates enabled))
;;* interactive
(defun mojo-set-log-events (enabled)
"Turn event logging on if ENABLED is t, or off if it is nil or :json-false."
(interactive "XLog events? (t or nil) ")
(mojo-change-framework-config-value 'debuggingEnabled enabled))
;;* interactive
(defun mojo-set-timing-enabled (enabled)
"Enable timing if ENABLED is t, or disable timing if it is nil or :json-false."
(interactive "XEnable timing? (t or nil) ")
(mojo-change-framework-config-value 'timingEnabled enabled))
;;* interactive
(defun mojo-set-use-native-json-parser (enabled)
"Use the native JSON parser if ENABLED is t, or not if it is nil or :json-false."
(interactive "XUse native JSON parser? (t or nil) ")
(mojo-change-framework-config-value 'useNativeJSONParser enabled))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;; app listing and completion ;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
@ -497,25 +866,22 @@ vice versa."
(= 0 (length thing)))))
(defun mojo-read-root ()
"Get the path to a Mojo application, prompting with completion and
history."
"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.
"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* (mojo-last-path-component package))
(setq *mojo-package-filename* (mojo-filename package))
(expand-file-name package)))
(defun mojo-read-app-id (&optional prompt)
"Get the id of an existing application, prompting with completion and
history.
"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)))
@ -562,8 +928,7 @@ The app id is stored in *mojo-app-id* unless it was blank."
(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.
"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)))
@ -589,47 +954,64 @@ If the cache file does not exist then it is considered stale."
'(("-assistant.js" . mojo-switch-to-view)
("-scene.html" . mojo-switch-to-assistant)
(".html" . mojo-switch-to-next-view)
("" . mojo-switch-to-appinfo)))
("" . mojo-switch-to-appinfo))
"Suffixes of files that we can guess where to switch.")
;;* interactive
(defun mojo-switch-to-appinfo ()
"Switch to appinfo.json."
(interactive)
(find-file (concat (mojo-root) "/appinfo.json")))
(when (mojo-project-p)
(find-file (concat (mojo-root) "/appinfo.json"))))
;;* interactive
(defun mojo-switch-to-index ()
"Switch to index.html."
(interactive)
(find-file (concat (mojo-root) "/index.html")))
(when (mojo-project-p)
(find-file (concat (mojo-root) "/index.html"))))
;;* interactive
(defun mojo-switch-to-sources ()
"Switch to sources.json."
(interactive)
(find-file (concat (mojo-root) "/sources.json")))
(when (mojo-project-p)
(find-file (concat (mojo-root) "/sources.json"))))
;;* interactive
(defun mojo-switch-to-stylesheet ()
"Switch to the main CSS stylesheet, or the first one."
(interactive)
(when (mojo-project-p)
(let* ((stylesheet-dir (concat (mojo-root) "/stylesheets"))
(path (concat stylesheet-dir "/"
(mojo-informal-app-id) ".css")))
(when (not (file-exists-p path))
(setq path (car (mojo-filter-paths (directory-files stylesheet-dir t)))))
(find-file path)))
(find-file path))))
(defun mojo-parent-directory-name (path)
"The parent directory's basename."
(mojo-filename (mojo-parent-directory path)))
(defun mojo-scene-name-from-assistant ()
"The scene name of the assistant being edited."
(let ((path (buffer-file-name)))
(substring (mojo-last-path-component path) 0 (- 0 (length "-assistant.js")))))
(and (string= "assistants" (mojo-parent-directory-name path))
(substring (mojo-filename path) 0 (- 0 (length "-assistant.js"))))))
(defun mojo-scene-name-from-view ()
(mojo-last-path-component (mojo-drop-last-path-component (buffer-file-name))))
"The scene name of the view being edited."
(let ((path (buffer-file-name)))
(and (string= "views" (mojo-parent-directory-name (mojo-parent-directory path)))
(mojo-parent-directory-name path))))
;;* interactive
(defun mojo-switch-file-dwim ()
"Determine if the current buffer is visiting a file with known
relationships. Try to find the 'best' choice and switch to it.
"Attempt to intelligently find a related file and switch to it.
This does what I (sjs) mean by default, so change
*mojo-switch-suffixes* if you want different behaviour."
This does what I (sjs) mean by default, so change *mojo-switch-suffixes*
if you want different behaviour."
(interactive)
(let* ((path (buffer-file-name))
(suffixes (copy-list *mojo-switch-suffixes*))
@ -645,6 +1027,7 @@ If the cache file does not exist then it is considered stale."
;;* interactive
(defun mojo-switch-to-view ()
"Switch to the corresponding main view from an assistant."
(interactive)
(when (mojo-project-p)
(let ((scene-name (mojo-scene-name-from-assistant)))
@ -653,12 +1036,14 @@ If the cache file does not exist then it is considered stale."
scene-name "-scene.html")))))
(defun mojo-ignored-path (path)
(let ((filename (mojo-last-path-component path)))
(or (string= (substring filename 0 1) ".")
(and (string= (substring filename 0 1) "#")
"Paths that we don't want to look at when walking directories."
(let ((filename (mojo-filename path)))
(or (string= (substring filename 0 1) ".") ;; "." and ".." and hidden files
(and (string= (substring filename 0 1) "#") ;; emacs recovery files
(string= (substring filename -1) "#")))))
(defun mojo-filter-paths (all-paths)
"Filter out unimportant paths from a list of paths."
(let ((wanted-paths (list)))
(dolist (path all-paths wanted-paths)
(unless (mojo-ignored-path path)
@ -666,6 +1051,7 @@ If the cache file does not exist then it is considered stale."
(reverse wanted-paths)))
(defun mojo-index (elem list)
"Return the position of ELEM in LIST."
(catch 'break
(let ((index 0))
(dolist (path list index)
@ -675,6 +1061,7 @@ If the cache file does not exist then it is considered stale."
;;* interactive
(defun mojo-switch-to-next-view ()
"Switch to the next view in this scene, alphabetically. Wrap around at the end."
(interactive)
(when (mojo-project-p)
(let* ((scene-name (mojo-scene-name-from-view))
@ -687,6 +1074,7 @@ If the cache file does not exist then it is considered stale."
;;* interactive
(defun mojo-switch-to-assistant ()
"Swtich to the corresponding assistant from a view."
(interactive)
(let ((scene-name (mojo-scene-name-from-view)))
(when (and (mojo-project-p)
@ -710,8 +1098,8 @@ 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\".")
"Used to specify the target platform, \"usb\" for the device and \"tcp\"
for the emulator. Deaults to \"tcp\".")
(defun mojo-emulator-running-p ()
"Determine if the webOS emulator is running or not.
@ -720,7 +1108,8 @@ 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
"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")))