[CHANGED] Key bindings now conform to Emacs' minor mode convention.

Added and updated docstrings and comments.
This commit is contained in:
Sami Samhuri 2009-12-04 00:46:05 -08:00
parent ae5335fef2
commit 9c8d1cc5a4

View file

@ -13,19 +13,19 @@
Keybindings are: Keybindings are:
* C-c a -- \\[mojo-switch-to-assistant] * C-c C-c a -- \\[mojo-switch-to-assistant]
* C-c i -- \\[mojo-switch-to-appinfo] * C-c C-c i -- \\[mojo-switch-to-appinfo]
* C-c I -- \\[mojo-switch-to-index] * C-c C-c I -- \\[mojo-switch-to-index]
* C-c n -- \\[mojo-switch-to-next-view] * C-c C-c n -- \\[mojo-switch-to-next-view]
* C-c s -- \\[mojo-switch-to-sources] * C-c C-c s -- \\[mojo-switch-to-sources]
* C-c S -- \\[mojo-switch-to-stylesheet] * C-c C-c S -- \\[mojo-switch-to-stylesheet]
* C-c v -- \\[mojo-switch-to-view] * C-c C-c v -- \\[mojo-switch-to-view]
* C-c SPC -- \\[mojo-switch-file-dwim] * C-c C-c SPC -- \\[mojo-switch-file-dwim]
* C-c C-e -- \\[mojo-emulate] * C-c C-c C-e -- \\[mojo-emulate]
* C-c C-p -- \\[mojo-package] * C-c C-c C-p -- \\[mojo-package]
* C-c C-r -- \\[mojo-package-install-and-inspect] * C-c C-c C-r -- \\[mojo-package-install-and-inspect]
* C-c C-s -- \\[mojo-generate-scene] * C-c C-c C-s -- \\[mojo-generate-scene]
* C-c C-t -- \\[mojo-toggle-target] * C-c C-c C-t -- \\[mojo-toggle-target]
See the source code mojo.el or the README file for a list of See the source code mojo.el or the README file for a list of
all of the interactive commands." all of the interactive commands."
@ -35,19 +35,19 @@
:lighter "-Mojo" :lighter "-Mojo"
;; The minor mode bindings. ;; The minor mode bindings.
:keymap :keymap
'(("\C-ca" . mojo-switch-to-assistant) '(("\C-c\C-ca" . mojo-switch-to-assistant)
("\C-ci" . mojo-switch-to-appinfo) ("\C-c\C-ci" . mojo-switch-to-appinfo)
("\C-cI" . mojo-switch-to-index) ("\C-c\C-cI" . mojo-switch-to-index)
("\C-cn" . mojo-switch-to-next-view) ("\C-c\C-cn" . mojo-switch-to-next-view)
("\C-cs" . mojo-switch-to-sources) ("\C-c\C-cs" . mojo-switch-to-sources)
("\C-cS" . mojo-switch-to-stylesheet) ("\C-c\C-cS" . mojo-switch-to-stylesheet)
("\C-cv" . mojo-switch-to-view) ("\C-c\C-cv" . mojo-switch-to-view)
("\C-c " . mojo-switch-file-dwim) ("\C-c\C-c " . mojo-switch-file-dwim)
("\C-c\C-e" . mojo-emulate) ("\C-c\C-c\C-e" . mojo-emulate)
("\C-c\C-p" . mojo-package) ("\C-c\C-c\C-p" . mojo-package)
("\C-c\C-r" . mojo-package-install-and-inspect) ("\C-c\C-c\C-r" . mojo-package-install-and-inspect)
("\C-c\C-s" . mojo-generate-scene) ("\C-c\C-c\C-s" . mojo-generate-scene)
("\C-c\C-t" . mojo-toggle-target)) ("\C-c\C-c\C-t" . mojo-toggle-target))
:group 'mojo) :group 'mojo)
(defcustom mojo-sdk-directory (defcustom mojo-sdk-directory
@ -80,11 +80,12 @@ this work."
;; Call this from your emacs config file with the modes you want to hook. ;; Call this from your emacs config file with the modes you want to hook.
(defun mojo-setup-mode-hooks (&rest hooks) (defun mojo-setup-mode-hooks (&rest hooks)
"Add `MOJO-MAYBE-ENABLE-MINOR-MODE' to the specified mode hooks." "Add `mojo-maybe-enable-minor-mode' to the specified mode hooks."
(dolist (hook hooks) (dolist (hook hooks)
(add-hook hook 'mojo-maybe-enable-minor-mode))) (add-hook hook 'mojo-maybe-enable-minor-mode)))
(defun 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) (when (mojo-project-p)
(mojo-mode))) (mojo-mode)))
@ -132,7 +133,7 @@ NAME is the name of the scene."
;;* interactive ;;* interactive
(defun mojo-install () (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) (interactive)
(mojo-ensure-emulator-is-running) (mojo-ensure-emulator-is-running)
(mojo-cmd-with-target "palm-install" (list (expand-file-name (mojo-read-package-filename)))) (mojo-cmd-with-target "palm-install" (list (expand-file-name (mojo-read-package-filename))))
@ -147,7 +148,7 @@ NAME is the name of the scene."
;;* interactive ;;* interactive
(defun mojo-delete () (defun mojo-delete ()
"Remove the current application using `MOJO-APP-ID'." "Remove an application."
(interactive) (interactive)
(mojo-ensure-emulator-is-running) (mojo-ensure-emulator-is-running)
(mojo-cmd-with-target "palm-install" (list "-r" (mojo-read-app-id))) (mojo-cmd-with-target "palm-install" (list "-r" (mojo-read-app-id)))
@ -169,14 +170,14 @@ NAME is the name of the scene."
;;* interactive ;;* interactive
(defun mojo-launch () (defun mojo-launch ()
"Launch the current application in the emulator." "Launch the current application in the emulator, and the emulator if necessary.."
(interactive) (interactive)
(mojo-ensure-emulator-is-running) (mojo-ensure-emulator-is-running)
(mojo-cmd-with-target "palm-launch" (list (mojo-read-app-id)))) (mojo-cmd-with-target "palm-launch" (list (mojo-read-app-id))))
;;* interactive ;;* interactive
(defun mojo-close () (defun mojo-close ()
"Close launched application." "Close an application."
(interactive) (interactive)
(mojo-ensure-emulator-is-running) (mojo-ensure-emulator-is-running)
(mojo-cmd-with-target "palm-launch" (list "-c" (mojo-read-app-id)))) (mojo-cmd-with-target "palm-launch" (list "-c" (mojo-read-app-id))))
@ -237,8 +238,7 @@ Sets `*mojo-target*' to \"tcp\"."
;;* interactive ;;* interactive
(defun mojo-toggle-target () (defun mojo-toggle-target ()
"Automatically change the target device from 'usb' to 'tcp' and "Automatically change the target device from 'usb' to 'tcp' and vice versa."
vice versa."
(interactive) (interactive)
(if (string= "usb" *mojo-target*) (if (string= "usb" *mojo-target*)
(mojo-target-emulator) (mojo-target-emulator)
@ -284,17 +284,18 @@ vice versa."
(setq dir-prefix (mojo-read-root))) (setq dir-prefix (mojo-read-root)))
;; Invalidate cached values when changing projects. ;; 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*))) (not (string= dir-prefix *mojo-last-root*)))
(progn (setq *mojo-last-root* dir-prefix)
(setq *mojo-last-root* dir-prefix) (setq *mojo-package-filename* nil)
(setq *mojo-package-filename* nil) (setq *mojo-app-id* nil)
(setq *mojo-app-id* nil))) (setq *mojo-appinfo* nil))
dir-prefix)) dir-prefix))
;; foolproof? ;; foolproof enough? don't want false positives.
(defun mojo-project-p () (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")) (and (file-exists-p (concat (mojo-root) "/appinfo.json"))
(file-exists-p (concat (mojo-root) "/sources.json")) (file-exists-p (concat (mojo-root) "/sources.json"))
(file-exists-p (concat (mojo-root) "/app")) (file-exists-p (concat (mojo-root) "/app"))
@ -303,34 +304,40 @@ vice versa."
(defun mojo-read-json-file (filename) (defun mojo-read-json-file (filename)
"Parse the JSON in FILENAME and return the result." "Parse the JSON in FILENAME and return the result."
(save-excursion (save-excursion
(let ((origbuffer (current-buffer)) (let* ((origbuffer (current-buffer))
(filebuffer (find-file-noselect filename))) (path (concat (mojo-root) "/" filename))
(filebuffer (find-file-noselect path)))
(set-buffer filebuffer) (set-buffer filebuffer)
(let ((text (buffer-string))) (let ((text (buffer-string)))
(switch-to-buffer origbuffer) (switch-to-buffer origbuffer)
(json-read-from-string text))))) (json-read-from-string text)))))
(defvar *mojo-appinfo* nil
"Last structure read from appinfo.json.")
(defun mojo-appinfo ()
"Get the contents of the appinfo.json file. Last read appinfo is cached."
(when (mojo-project-p)
(or *mojo-appinfo*
(setq *mojo-appinfo* (mojo-read-json-file "appinfo.json")))))
(defun mojo-app-version () (defun mojo-app-version ()
"Parse the project version from the appinfo.json file in `MOJO-ROOT'." "Parse the project version from the appinfo.json file in `MOJO-ROOT'."
(when (mojo-project-p) (when (mojo-project-p)
(let ((appinfo (mojo-read-json-file (concat (mojo-root) "/appinfo.json")))) (cdr (assoc 'version (mojo-appinfo)))))
(cdr (assoc 'version appinfo)))))
(defun mojo-app-id () (defun mojo-app-id ()
"Parse the project id from the appinfo.json file in `MOJO-ROOT'." "Parse the project id from the appinfo.json file in `MOJO-ROOT'."
(when (mojo-project-p) (when (mojo-project-p)
(let ((appinfo (mojo-read-json-file (concat (mojo-root) "/appinfo.json")))) (cdr (assoc 'id (mojo-appinfo)))))
(cdr (assoc 'id appinfo)))))
(defun mojo-app-title () (defun mojo-app-title ()
"Parse the project title from appinfo.json." "Parse the project title from appinfo.json."
(when (mojo-project-p) (when (mojo-project-p)
(let ((appinfo (mojo-read-json-file (concat (mojo-root) "/appinfo.json")))) (cdr (assoc 'title (mojo-appinfo)))))
(cdr (assoc 'title appinfo)))))
(defun mojo-informal-app-id () (defun mojo-informal-app-id ()
"Parse the project title from appinfo.json and remove all non alphanumeric "Parse the project title from appinfo.json and remove all non alphanumeric characters."
characters."
(let ((title (downcase (mojo-app-title)))) (let ((title (downcase (mojo-app-title))))
(replace-regexp-in-string "[^a-z0-9]" "" title))) (replace-regexp-in-string "[^a-z0-9]" "" title)))
@ -387,13 +394,11 @@ vice versa."
(= 0 (length thing))))) (= 0 (length thing)))))
(defun mojo-read-root () (defun mojo-read-root ()
"Get the path to a Mojo application, prompting with completion and "Get the path to a Mojo application, prompting with completion and history."
history."
(read-file-name "Mojo project: " (expand-file-name (concat mojo-project-directory "/")))) (read-file-name "Mojo project: " (expand-file-name (concat mojo-project-directory "/"))))
(defun mojo-read-package-filename () (defun mojo-read-package-filename ()
"Get the filename of a packaged application, prompting with completion and "Get the filename of a packaged application, prompting with completion and history.
history.
The app id is stored in *mojo-package-filename* unless it was blank." The app id is stored in *mojo-package-filename* unless it was blank."
(let* ((default (or *mojo-package-filename* (let* ((default (or *mojo-package-filename*
@ -404,8 +409,7 @@ The app id is stored in *mojo-package-filename* unless it was blank."
(expand-file-name package))) (expand-file-name package)))
(defun mojo-read-app-id (&optional prompt) (defun mojo-read-app-id (&optional prompt)
"Get the id of an existing application, prompting with completion and "Get the id of an existing application, prompting with completion and history.
history.
The app id is stored in *mojo-app-id* unless it was blank." The app id is stored in *mojo-app-id* unless it was blank."
(let* ((default (or *mojo-app-id* (mojo-app-id))) (let* ((default (or *mojo-app-id* (mojo-app-id)))
@ -452,8 +456,7 @@ The app id is stored in *mojo-app-id* unless it was blank."
(nreverse apps))) (nreverse apps)))
(defun mojo-app-cache-stale-p () (defun mojo-app-cache-stale-p ()
"Non-nil if the cache in `MOJO-APP-CACHE-FILE' is more than "Non-nil if the cache in `MOJO-APP-CACHE-FILE' is more than *mojo-app-cache-ttl* seconds old.
*mojo-app-cache-ttl* seconds old.
If the cache file does not exist then it is considered stale." If the cache file does not exist then it is considered stale."
(or (null (file-exists-p (mojo-app-cache-file))) (or (null (file-exists-p (mojo-app-cache-file)))
@ -476,6 +479,7 @@ If the cache file does not exist then it is considered stale."
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(defvar *mojo-switch-suffixes* (defvar *mojo-switch-suffixes*
"Suffixes of files that we can guess where to switch."
'(("-assistant.js" . mojo-switch-to-view) '(("-assistant.js" . mojo-switch-to-view)
("-scene.html" . mojo-switch-to-assistant) ("-scene.html" . mojo-switch-to-assistant)
(".html" . mojo-switch-to-next-view) (".html" . mojo-switch-to-next-view)
@ -483,49 +487,59 @@ If the cache file does not exist then it is considered stale."
;;* interactive ;;* interactive
(defun mojo-switch-to-appinfo () (defun mojo-switch-to-appinfo ()
"Switch to appinfo.json."
(interactive) (interactive)
(find-file (concat (mojo-root) "/appinfo.json"))) (when (mojo-project-p)
(find-file (concat (mojo-root) "/appinfo.json"))))
;;* interactive ;;* interactive
(defun mojo-switch-to-index () (defun mojo-switch-to-index ()
"Switch to index.html."
(interactive) (interactive)
(find-file (concat (mojo-root) "/index.html"))) (when (mojo-project-p)
(find-file (concat (mojo-root) "/index.html"))))
;;* interactive ;;* interactive
(defun mojo-switch-to-sources () (defun mojo-switch-to-sources ()
"Switch to sources.json."
(interactive) (interactive)
(find-file (concat (mojo-root) "/sources.json"))) (when (mojo-project-p)
(find-file (concat (mojo-root) "/sources.json"))))
;;* interactive ;;* interactive
(defun mojo-switch-to-stylesheet () (defun mojo-switch-to-stylesheet ()
"Switch to the main CSS stylesheet, or the first one."
(interactive) (interactive)
(let* ((stylesheet-dir (concat (mojo-root) "/stylesheets")) (when (mojo-project-p)
(path (concat stylesheet-dir "/" (let* ((stylesheet-dir (concat (mojo-root) "/stylesheets"))
(mojo-informal-app-id) ".css"))) (path (concat stylesheet-dir "/"
(when (not (file-exists-p path)) (mojo-informal-app-id) ".css")))
(setq path (car (mojo-filter-paths (directory-files stylesheet-dir t))))) (when (not (file-exists-p path))
(find-file path))) (setq path (car (mojo-filter-paths (directory-files stylesheet-dir t)))))
(find-file path))))
(defun mojo-parent-directory-name (path) (defun mojo-parent-directory-name (path)
"The parent directory's basename."
(mojo-filename (mojo-parent-directory path))) (mojo-filename (mojo-parent-directory path)))
(defun mojo-scene-name-from-assistant () (defun mojo-scene-name-from-assistant ()
"The scene name of the assistant being edited."
(let ((path (buffer-file-name))) (let ((path (buffer-file-name)))
(and (string= "assistants" (mojo-parent-directory-name path)) (and (string= "assistants" (mojo-parent-directory-name path))
(substring (mojo-filename path) 0 (- 0 (length "-assistant.js")))))) (substring (mojo-filename path) 0 (- 0 (length "-assistant.js"))))))
(defun mojo-scene-name-from-view () (defun mojo-scene-name-from-view ()
"The scene name of the view being edited."
(let ((path (buffer-file-name))) (let ((path (buffer-file-name)))
(and (string= "views" (mojo-parent-directory-name (mojo-parent-directory path))) (and (string= "views" (mojo-parent-directory-name (mojo-parent-directory path)))
(mojo-parent-directory-name path)))) (mojo-parent-directory-name path))))
;;* interactive ;;* interactive
(defun mojo-switch-file-dwim () (defun mojo-switch-file-dwim ()
"Determine if the current buffer is visiting a file with known "Attempt to intelligently find a related file and switch to it.
relationships. Try to find the 'best' choice and switch to it.
This does what I (sjs) mean by default, so change This does what I (sjs) mean by default, so change *mojo-switch-suffixes*
*mojo-switch-suffixes* if you want different behaviour." if you want different behaviour."
(interactive) (interactive)
(let* ((path (buffer-file-name)) (let* ((path (buffer-file-name))
(suffixes (copy-list *mojo-switch-suffixes*)) (suffixes (copy-list *mojo-switch-suffixes*))
@ -541,6 +555,7 @@ If the cache file does not exist then it is considered stale."
;;* interactive ;;* interactive
(defun mojo-switch-to-view () (defun mojo-switch-to-view ()
"Switch to the corresponding main view from an assistant."
(interactive) (interactive)
(when (mojo-project-p) (when (mojo-project-p)
(let ((scene-name (mojo-scene-name-from-assistant))) (let ((scene-name (mojo-scene-name-from-assistant)))
@ -549,12 +564,14 @@ If the cache file does not exist then it is considered stale."
scene-name "-scene.html"))))) scene-name "-scene.html")))))
(defun mojo-ignored-path (path) (defun mojo-ignored-path (path)
"Paths that we don't want to look at when walking directories."
(let ((filename (mojo-filename path))) (let ((filename (mojo-filename path)))
(or (string= (substring filename 0 1) ".") (or (string= (substring filename 0 1) ".") ;; "." and ".." and hidden files
(and (string= (substring filename 0 1) "#") (and (string= (substring filename 0 1) "#") ;; emacs recovery files
(string= (substring filename -1) "#"))))) (string= (substring filename -1) "#")))))
(defun mojo-filter-paths (all-paths) (defun mojo-filter-paths (all-paths)
"Filter out unimportant paths from a list of paths."
(let ((wanted-paths (list))) (let ((wanted-paths (list)))
(dolist (path all-paths wanted-paths) (dolist (path all-paths wanted-paths)
(unless (mojo-ignored-path path) (unless (mojo-ignored-path path)
@ -562,6 +579,7 @@ If the cache file does not exist then it is considered stale."
(reverse wanted-paths))) (reverse wanted-paths)))
(defun mojo-index (elem list) (defun mojo-index (elem list)
"Return the position of ELEM in LIST."
(catch 'break (catch 'break
(let ((index 0)) (let ((index 0))
(dolist (path list index) (dolist (path list index)
@ -571,6 +589,7 @@ If the cache file does not exist then it is considered stale."
;;* interactive ;;* interactive
(defun mojo-switch-to-next-view () (defun mojo-switch-to-next-view ()
"Switch to the next view in this scene, alphabetically. Wrap around at the end."
(interactive) (interactive)
(when (mojo-project-p) (when (mojo-project-p)
(let* ((scene-name (mojo-scene-name-from-view)) (let* ((scene-name (mojo-scene-name-from-view))
@ -583,6 +602,7 @@ If the cache file does not exist then it is considered stale."
;;* interactive ;;* interactive
(defun mojo-switch-to-assistant () (defun mojo-switch-to-assistant ()
"Swtich to the corresponding assistant from a view."
(interactive) (interactive)
(let ((scene-name (mojo-scene-name-from-view))) (let ((scene-name (mojo-scene-name-from-view)))
(when (and (mojo-project-p) (when (and (mojo-project-p)
@ -616,8 +636,9 @@ This command only works on Unix-like systems."
(= 0 (shell-command "ps x | fgrep 'Palm SDK' | fgrep -v fgrep >/dev/null 2>&1"))) (= 0 (shell-command "ps x | fgrep 'Palm SDK' | fgrep -v fgrep >/dev/null 2>&1")))
(defun mojo-emulator-responsive-p () (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)."
(i.e. if it's done booting)."
(= 0 (shell-command "palm-install -d tcp --list >/dev/null 2>&1"))) (= 0 (shell-command "palm-install -d tcp --list >/dev/null 2>&1")))
(defun mojo-path-to-cmd (cmd) (defun mojo-path-to-cmd (cmd)