diff --git a/emacs.d/js-comint.el b/emacs.d/js-comint.el new file mode 100644 index 0000000..1f93ce3 --- /dev/null +++ b/emacs.d/js-comint.el @@ -0,0 +1,209 @@ +;;; js-comint.el --- Run javascript in an inferior process window. + +;;; Copyright (C) 2008 Paul Huff + +;;; Author: Paul Huff +;;; Maintainer: Paul Huff +;;; Created: 26 May 2008 +;;; Version: 0.0.1 +;;; Package-Requires: () +;;; Keywords: javascript, inferior-mode, convenience + + +;; js-comint.el 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; either version 2, or +;; {at your option} any later version. + +;; js-comint.el 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. + +;; You should have received a copy of the GNU General Public License +;; along with GNU Emacs; see the file COPYING, or type `C-h C-c'. If +;; not, write to the Free Software Foundation at this address: + +;; Free Software Foundation +;; 51 Franklin Street, Fifth Floor +;; Boston, MA 02110-1301 +;; USA + +;;; Commentary: +;;; js-comint.el let's you run an inferior javascript process in emacs, +;;; and defines a few functions for sending javascript input to it quickly. + +;; Usage: +;; Put js-comint.el in your load path +;; Add (require 'js-comint) to your .emacs +;; Set inferior-js-program-command to the execution command for running your javascript REPL +;; (setq inferior-js-program-command "/path/to/executable ") +;; Do: M-x run-js +;; Away you go. + +;; I've added the following couple of lines to my .emacs to take advantage of +;; cool keybindings for sending things to the javascript interpreter inside +;; of Steve Yegge's most excellent js2-mode. + +;; (add-hook 'js2-mode-hook '(lambda () +;; (local-set-key "\C-x\C-e" 'js-send-last-sexp) +;; (local-set-key "\C-\M-x" 'js-send-last-sexp-and-go) +;; (local-set-key "\C-cb" 'js-send-buffer) +;; (local-set-key "\C-c\C-b" 'js-send-buffer-and-go) +;; (local-set-key "\C-cl" 'js-load-file-and-go) +;; )) + +;; This is version 0.0.1, so I've only tested it on my own version of emacs which is currently: +;; GNU Emacs 22.0.90.1 (i386-apple-darwin8.8.1, Carbon Version 1.6.0) of 2006-10-28 +;; Not sure if it'll work anywhere else, but it doesn't require anything apple-ish, just emacs-ish. + +;; Additionally, I've only tested this with rhino. I'm sure it'll probably work with spidermonkey, +;; though if it barfs let me know, and I'll update it. + +;; I'm a newbie elisper, so please let me know if I'm a. doing things the wrong way, b. +;; making things work they way they shouldn't in the elisp world. + +;;; History: +;; + +;;; Code: + +(require 'comint) + +(provide 'js-comint) + +(defcustom inferior-js-program-command "/usr/bin/java org.mozilla.javascript.tools.shell.Main" "Path to the javascript interpreter") + +(defgroup inferior-js nil + "Run a javascript process in a buffer." + :group 'inferior-js) + +(defcustom inferior-js-mode-hook nil + "*Hook for customizing inferior-js mode." + :type 'hook + :group 'inferior-js) + +;;;###autoload +(defun run-js (cmd &optional dont-switch-p) + "Run an inferior Javascript process, input and output via buffer `*js*'. +If there is a process already running in `*js*', switch to that buffer. +With argument, allows you to edit the command line (default is value +of `inferior-js-program-command'). +Runs the hook `inferior-js-mode-hook' \(after the `comint-mode-hook' +is run). +\(Type \\[describe-mode] in the process buffer for a list of commands.)" + + (interactive (list (if current-prefix-arg + (read-string "Run js: " inferior-js-program-command) + inferior-js-program-command))) + (if (not (comint-check-proc "*js*")) + (save-excursion (let ((cmdlist (split-string cmd))) + (set-buffer (apply 'make-comint "js" (car cmdlist) + nil (cdr cmdlist))) + (inferior-js-mode)))) + (setq inferior-js-program-command cmd) + (setq inferior-js-buffer "*js*") + (if (not dont-switch-p) + (pop-to-buffer "*js*"))) + +;;;###autoload +(defun js-send-region (start end) + "Send the current region to the inferior Javascript process." + (interactive "r") + (run-js inferior-js-program-command t) + (comint-send-region inferior-js-buffer start end) + (comint-send-string inferior-js-buffer "\n")) + +;;;###autoload +(defun js-send-region-and-go (start end) + "Send the current region to the inferior Javascript process." + (interactive "r") + (run-js inferior-js-program-command t) + (comint-send-region inferior-js-buffer start end) + (comint-send-string inferior-js-buffer "\n") + (switch-to-js inferior-js-buffer)) + +;;;###autoload +(defun js-send-last-sexp-and-go () + "Send the previous sexp to the inferior Js process." + (interactive) + (js-send-region-and-go (save-excursion (backward-sexp) (point)) (point))) + +;;;###autoload +(defun js-send-last-sexp () + "Send the previous sexp to the inferior Javascript process." + (interactive) + (js-send-region (save-excursion (backward-sexp) (point)) (point))) + +;;;###autoload +(defun js-send-buffer () + "Send the buffer to the inferior Javascript process." + (interactive) + (js-send-region (point-min) (point-max))) + + +;;;###autoload +(defun js-send-buffer-and-go () + "Send the buffer to the inferior Javascript process." + (interactive) + (js-send-region-and-go (point-min) (point-max))) + +;;;###autoload +(defun js-load-file (filename) + "Load a file in the javascript interpreter." + (interactive "f") + (let ((filename (expand-file-name filename))) + (run-js inferior-js-program-command t) + (comint-send-string inferior-js-buffer (concat "load(\"" filename "\")\n")))) + +;;;###autoload +(defun js-load-file-and-go (filename) + "Load a file in the javascript interpreter." + (interactive "f") + (let ((filename (expand-file-name filename))) + (run-js inferior-js-program-command t) + (comint-send-string inferior-js-buffer (concat "load(\"" filename "\")\n")) + (switch-to-js inferior-js-buffer))) + +;;;###autoload +(defun switch-to-js (eob-p) + "Switch to the javascript process buffer. +With argument, position cursor at end of buffer." + (interactive "P") + (if (or (and inferior-js-buffer (get-buffer inferior-js-buffer)) + (js-interactively-start-process)) + (pop-to-buffer inferior-js-buffer) + (error "No current process buffer. See variable `inferior-js-buffer'")) + (when eob-p + (push-mark) + (goto-char (point-max)))) + +(defvar inferior-js-buffer) + +(defvar inferior-js-mode-map + (let ((m (make-sparse-keymap))) + (define-key m "\C-x\C-e" 'js-send-last-sexp) + (define-key m "\C-cl" 'js-load-file) + m)) + +;;;###autoload +(define-derived-mode inferior-js-mode comint-mode "Inferior Javascript" + "Major mode for interacting with an inferior javascript process. + +The following commands are available: +\\{inferior-js-mode-map} + +A javascript process can be fired up with M-x run-js. + +Customization: Entry to this mode runs the hooks on comint-mode-hook and +inferior-js-mode-hook (in that order). + +You can send text to the inferior Javascript process from othber buffers containing +Javascript source. + switch-to-js switches the current buffer to the Javascript process buffer. + js-send-region sends the current region to the Javascript process. + + +" +(use-local-map inferior-js-mode-map) +) \ No newline at end of file diff --git a/emacs.d/mojo.el b/emacs.d/mojo.el index 7af7839..919db10 100644 --- a/emacs.d/mojo.el +++ b/emacs.d/mojo.el @@ -1,6 +1,6 @@ ;;; mojo.el --- Interactive functions for webOS development -;; 2009-12-07 14:28:52 -(defconst mojo-version "0.9.10") +;; 2009-12-08 22:12:37 +(defconst mojo-version "1.0.0b") (require 'json) @@ -84,7 +84,7 @@ ideas. Send me a pull request on github if you hack on mojo.el.") ;; * 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 v -- mojo-switch-to-last-view ;; * C-c C-c SPC -- mojo-switch-file-dwim ;; * C-c C-c C-d -- mojo-target-device ;; * C-c C-c C-e -- mojo-emulate @@ -163,13 +163,17 @@ ideas. Send me a pull request on github if you hack on mojo.el.") ;; mojo-switch-to-assistant ;; Switch to the corresponding assistant from any view file. ;; -;; mojo-switch-to-view +;; mojo-switch-to-main-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-last-view +;; Switch to the last visited view buffer (excluding the current +;; buffer). +;; ;; mojo-switch-to-appinfo ;; Switch to the appinfo.json file. ;; @@ -182,6 +186,10 @@ ideas. Send me a pull request on github if you hack on mojo.el.") ;; mojo-switch-to-stylesheet ;; Switch to the main stylesheet. ;; +;; mojo-switch-file-dwim +;; Switch to the next view from a view, and to the main view from an +;; assistant. From any other file switch to appinfo.json. +;; ;; ;; Manage framework_config.json ;; ---------------------------- @@ -201,12 +209,15 @@ ideas. Send me a pull request on github if you hack on mojo.el.") ;; mojo-log-level ;; See the log level. ;; -;; mojo-html-escaped-in-templates-p +;; mojo-escape-html-in-templates-p ;; See if HTML is escaped in templates. ;; ;; mojo-set-debugging-enabled ;; Enable or disable debugging. ;; +;; mojo-toggle-debugging +;; Toggle debugging in framework_config.json. +;; ;; mojo-set-log-events ;; Enable or disable event logging. ;; @@ -374,7 +385,7 @@ ideas. Send me a pull request on github if you hack on mojo.el.") * 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 v -- \\[mojo-switch-to-last-view] * C-c C-c SPC -- \\[mojo-switch-file-dwim] * C-c C-c C-d -- \\[mojo-target-device] * C-c C-c C-e -- \\[mojo-emulate] @@ -397,7 +408,7 @@ ideas. Send me a pull request on github if you hack on mojo.el.") ("\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-cv" . mojo-switch-to-last-view) ("\C-c\C-c " . mojo-switch-file-dwim) ("\C-c\C-c\C-d" . mojo-target-device) ("\C-c\C-c\C-e" . mojo-emulate) @@ -512,10 +523,8 @@ NAME is the name of the scene." (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) + "Launch the emulator unless it is already running." (if (string= "tcp" *mojo-target*) (progn (when (not (mojo-emulator-running-p)) @@ -540,14 +549,15 @@ NAME is the name of the scene." (mojo-ensure-emulator-is-running) (mojo-cmd-with-target "palm-launch" (list "-c" (mojo-read-app-id)))) -;;* launch interactive +;;* interactive (defun mojo-inspect () "Run the DOM inspector on the current application." (interactive) (mojo-ensure-emulator-is-running) + (mojo-set-log-level-for-debugging) (mojo-cmd-with-target "palm-launch" (list "-i" (mojo-read-app-id)))) -;;* emulator interactive +;;* interactive (defun mojo-hard-reset () "Perform a hard reset, clearing all data." (interactive) @@ -966,11 +976,13 @@ If the cache file does not exist then it is considered stale." ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; (defvar *mojo-switch-suffixes* - '(("-assistant.js" . mojo-switch-to-view) - ("-scene.html" . mojo-switch-to-assistant) + '(("-assistant.js" . mojo-switch-to-last-view) (".html" . mojo-switch-to-next-view) ("" . mojo-switch-to-appinfo)) - "Suffixes of files that we can guess where to switch.") + "Suffixes of files that we can switch from and where to switch, with catch-all to appinfo.json by default.") + +(defvar *mojo-last-visited-view* nil + "Path of the last visited view file.") ;;* interactive (defun mojo-switch-to-appinfo () @@ -1009,17 +1021,37 @@ If the cache file does not exist then it is considered stale." "The parent directory's basename." (mojo-filename (mojo-parent-directory path))) +(defun mojo-current-filename () + "Return the filename part of the current buffer's path." + (mojo-filename (buffer-file-name))) + +(defun mojo-buffer-is-assistant-p () + "Determine if the current buffer is a scene assistant." + (string= "assistants" (mojo-parent-directory-name (buffer-file-name)))) + (defun mojo-scene-name-from-assistant () "The scene name of the assistant being edited." - (let ((path (buffer-file-name))) - (and (string= "assistants" (mojo-parent-directory-name path)) - (substring (mojo-filename path) 0 (- 0 (length "-assistant.js")))))) + (and (mojo-buffer-is-assistant-p) + (substring (mojo-current-filename) 0 (- 0 (length "-assistant.js"))))) + +(defun mojo-path-is-view-p (path) + "Determine if the given path is a Mojo view." + (string= "views" (mojo-parent-directory-name (mojo-parent-directory path)))) + +(defun mojo-buffer-is-view-p () + "Determine if the current buffer is a view." + (mojo-path-is-view-p (buffer-file-name))) + +(defun mojo-buffer-is-main-view-p () + "Determine if the current buffer is the main view of a scene." + (and (mojo-buffer-is-view-p) + (string= (concat (mojo-scene-name-from-view) "-scene.html") + (mojo-current-filename)))) (defun mojo-scene-name-from-view () "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)))) + (and (mojo-buffer-is-view-p) + (mojo-parent-directory-name (buffer-file-name)))) ;;* interactive (defun mojo-switch-file-dwim () @@ -1040,28 +1072,56 @@ if you want different behaviour." (when switch-function (call-interactively switch-function)))) -;;* 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))) - (find-file (concat (mojo-root) - "/app/views/" scene-name "/" - scene-name "-scene.html"))))) +(defun mojo-buffer-is-scene-file-p () + "Determine if the current buffer belongs to a Mojo scene." + (or (mojo-buffer-is-view-p) + (mojo-buffer-is-assistant-p))) -(defun mojo-ignored-path (path) +;;* interactive +(defun mojo-switch-to-main-view () + "Switch to the corresponding main view from an assistant or any other view in the scene." + (interactive) + (when (and (mojo-project-p) (mojo-buffer-is-scene-file-p)) + (let* ((scene-name (mojo-scene-name))) + (setq *mojo-last-visited-view* (concat (mojo-root) + "/app/views/" scene-name "/" + scene-name "-scene.html"))) + (find-file *mojo-last-visited-view*))) + +(defun mojo-visited-view-paths () + "Return a list of all visited view paths, most recently visited first." + (mojo-filter-paths (mapcar (function buffer-file-name) (buffer-list)) + (lambda (path) (or (null path) (not (mojo-path-is-view-p path)))))) + +;;* interactive +(defun mojo-switch-to-last-view () + "Switch to the last visited view from another view or assistant. + +If there no view can be found then the action depends on the +current buffer. From an assistant you are taken to the main +view, from the main view you go to the next view, and from any +other view you go to the main view. Any other file is a no op." + (interactive) + (let* ((view-paths (mojo-visited-view-paths)) + (last-view-path (if (string= (buffer-file-name) (car view-paths)) + (cadr view-paths) + (car view-paths)))) + (when last-view-path (find-file last-view-path)))) + +(defun mojo-ignored-path-p (path) "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 + (or (null filename) + (string= (substring filename 0 1) ".") ;; "." and ".." and hidden files (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 &optional filter) "Filter out unimportant paths from a list of paths." - (let ((wanted-paths (list))) + (let ((wanted-paths (list)) + (filter (or filter 'mojo-ignored-path-p))) (dolist (path all-paths wanted-paths) - (unless (mojo-ignored-path path) + (unless (funcall filter path) (setq wanted-paths (cons path wanted-paths)))) (reverse wanted-paths))) @@ -1074,15 +1134,20 @@ if you want different behaviour." (when (string= path elem) (throw 'break index)))))) +(defun mojo-scene-name () + "Get the name of the current Mojo scene, or nil if not a scene file." + (or (mojo-scene-name-from-view) + (mojo-scene-name-from-assistant))) + ;;* 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)) + (when (and (mojo-project-p) (mojo-buffer-is-scene-file-p)) + (let* ((scene-name (mojo-scene-name)) (view-dir (concat (mojo-root) "/app/views/" scene-name)) (view-files (mojo-filter-paths (directory-files view-dir t))) -(mojo-filter-paths (directory-files (concat (mojo-root) "/app/views/" (mojo-scene-name-from-view)) t)) + (mojo-filter-paths (directory-files (concat (mojo-root) "/app/views/" scene-name) t)) (index (mojo-index (buffer-file-name) view-files)) (filename (nth (mod index (length view-files)) view-files))) (find-file filename))))