From 90d53b15df1206bb0c2739e525c2ba89c557882c Mon Sep 17 00:00:00 2001 From: David Maus Date: Sun, 16 Jan 2011 17:28:19 +0100 Subject: [PATCH 01/30] Don't try to merge abbrev tables if `php-mode-abbrev-table' is unbound * php-repl.el: Don't try to merge abbrev tables if `php-mode-abbrev-table' is unbound. --- data/php-repl.el | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/data/php-repl.el b/data/php-repl.el index 08d6ad4..ebc0b20 100644 --- a/data/php-repl.el +++ b/data/php-repl.el @@ -81,8 +81,9 @@ (define-derived-mode inferior-php-mode comint-mode "Inferior PHP") (defvar inferior-php-mode-abbrev-table (make-abbrev-table)) -(derived-mode-merge-abbrev-tables php-mode-abbrev-table - inferior-php-mode-abbrev-table) +(if (boundp php-mode-abbrev-table) + (derived-mode-merge-abbrev-tables php-mode-abbrev-table + inferior-php-mode-abbrev-table)) (derived-mode-set-abbrev-table 'inferior-php-mode) (defvar eval-php-mode-map From 1bb8763c6e8eda0b07d11c39a866855f1ca262b1 Mon Sep 17 00:00:00 2001 From: David Maus Date: Sun, 16 Jan 2011 17:31:42 +0100 Subject: [PATCH 02/30] Move point to inferior php buffer * php-repl.el (run-php): Move point to inferior php buffer. Otherwise major mode of current buffer is set to `inferior-php-mode'. --- data/php-repl.el | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/data/php-repl.el b/data/php-repl.el index ebc0b20..d8d77c6 100644 --- a/data/php-repl.el +++ b/data/php-repl.el @@ -75,7 +75,7 @@ (mapconcat 'identity php-repl-program-arguments " ")) (setq inferior-php-buffer buf) (display-buffer buf t) - ;; (pop-to-buffer buf t) + (pop-to-buffer buf t) (inferior-php-mode))) (define-derived-mode inferior-php-mode comint-mode "Inferior PHP") From 9e57494b3d2bda5e37321713c99119384190521e Mon Sep 17 00:00:00 2001 From: David Maus Date: Sun, 16 Jan 2011 18:15:39 +0100 Subject: [PATCH 03/30] Fix missing quote * php-repl.el: Fix missing quote. --- data/php-repl.el | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/data/php-repl.el b/data/php-repl.el index d8d77c6..c1d1968 100644 --- a/data/php-repl.el +++ b/data/php-repl.el @@ -81,7 +81,7 @@ (define-derived-mode inferior-php-mode comint-mode "Inferior PHP") (defvar inferior-php-mode-abbrev-table (make-abbrev-table)) -(if (boundp php-mode-abbrev-table) +(if (boundp 'php-mode-abbrev-table) (derived-mode-merge-abbrev-tables php-mode-abbrev-table inferior-php-mode-abbrev-table)) (derived-mode-set-abbrev-table 'inferior-php-mode) From 7bd5ecf7601358aab2fd9c396074aa3ff2bfd13b Mon Sep 17 00:00:00 2001 From: David Maus Date: Sun, 16 Jan 2011 18:26:49 +0100 Subject: [PATCH 04/30] Use `apply' to pass php repl program arguments * php-repl.el (run-php): Use `apply' to pass php repl program arguments. Otherwise if `php-repl-program-arguments' is the empty, the empty string is passed as argument for `php-repl-program' which causes the process to terminate. --- data/php-repl.el | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/data/php-repl.el b/data/php-repl.el index c1d1968..43798de 100644 --- a/data/php-repl.el +++ b/data/php-repl.el @@ -70,9 +70,7 @@ (interactive "p") (let ((buf (cond ((buffer-live-p inferior-php-buffer) inferior-php-buffer) (t (generate-new-buffer "*inferior-php*"))))) - (make-comint-in-buffer - "PHP" buf php-repl-program nil - (mapconcat 'identity php-repl-program-arguments " ")) + (apply 'make-comint-in-buffer "PHP" buf php-repl-program nil php-repl-program-arguments) (setq inferior-php-buffer buf) (display-buffer buf t) (pop-to-buffer buf t) From 6a501ad8d0c3efdd14a3e5b1ea7ff122baaddbb6 Mon Sep 17 00:00:00 2001 From: Justin Hileman Date: Wed, 17 Mar 2010 04:50:35 +0800 Subject: [PATCH 05/30] Removed need to explicitly end lines with backslashes inside matched parens or curlies. --- PHP/Repl.php | 38 ++++++++++++++++++++++++++++++++------ 1 file changed, 32 insertions(+), 6 deletions(-) diff --git a/PHP/Repl.php b/PHP/Repl.php index fe5faaf..76c93a4 100755 --- a/PHP/Repl.php +++ b/PHP/Repl.php @@ -154,9 +154,11 @@ public function run(array $scope = array()) */ private function read() { - $code = ''; - $done = false; - $lines = 0; + $code = ''; + $done = false; + $lines = 0; + $curleys = 0; + $parens = 0; static $shifted; if (!$shifted) { // throw away argv[0] @@ -179,13 +181,37 @@ private function read() return false; } + $done = true; $line = trim($line); // If the last char is a backslash, remove it and // accumulate more lines. if (substr($line, -1) == '\\') { - $line = substr($line, 0, strlen($line) - 1); - } else { - $done = true; + $line = trim(substr($line, 0, strlen($line) - 1)); + $done = false; + } + + // check for curleys and parens, keep accumulating lines. + $tokens = token_get_all(" 0) { + $done = false; + } else if ($parens > 0) { + $done = false; } $code .= $line; $lines++; From 0c9ab045dc7c8a1ae23aa68988dd3e94f048da1e Mon Sep 17 00:00:00 2001 From: Justin Hileman Date: Wed, 17 Mar 2010 05:38:33 +0800 Subject: [PATCH 06/30] Combined curleys and parens logic into a token stack, allows matching token pairs instead of naive counters. > If an unmatched token is incountered, in input, the read function will throw a generic exception. > Semicolons are only implicitly added inside curlies, not inside parens. --- PHP/Repl.php | 35 +++++++++++++++++++++-------------- 1 file changed, 21 insertions(+), 14 deletions(-) diff --git a/PHP/Repl.php b/PHP/Repl.php index 76c93a4..4c80d90 100755 --- a/PHP/Repl.php +++ b/PHP/Repl.php @@ -154,11 +154,10 @@ public function run(array $scope = array()) */ private function read() { - $code = ''; - $done = false; - $lines = 0; - $curleys = 0; - $parens = 0; + $code = ''; + $done = false; + $lines = 0; + $stack = array(); static $shifted; if (!$shifted) { // throw away argv[0] @@ -195,22 +194,30 @@ private function read() foreach ($tokens as $t) { switch ($t) { case '{': - ++$curleys; + case '(': + array_push($stack, $t); break; + case '}': - --$curleys; - break; - case '(': - ++$parens; + if ('{' !== array_pop($stack)) { + throw new Exception('Unmatched closing brace.'); + } break; case ')': - --$parens; + if ('(' !== array_pop($stack)) { + throw new Exception('Unmatched closing paren.'); + } break; } } - if ($curleys > 0) { - $done = false; - } else if ($parens > 0) { + if (count($stack) > 0) { + $last_t = array_pop($tokens); + if (is_array($last_t) && $last_t[0] == T_OPEN_TAG) { + // if the last token was an open tag, this is nothing. + } else if ($stack[count($stack) - 1] === '{' && !in_array($last_t, array('{', '}', ';'))) { + // allow implied semicolons inside curlies + $line .= ';'; + } $done = false; } $code .= $line; From 251080355c511ce70ce0995988df041764a6f5cd Mon Sep 17 00:00:00 2001 From: Justin Hileman Date: Wed, 17 Mar 2010 06:47:39 +0800 Subject: [PATCH 07/30] Continue when user enters a blank line (rather than exiting). User may still exit by typing Ctrl+X, 'die' or 'exit' --- PHP/Repl.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/PHP/Repl.php b/PHP/Repl.php index 4c80d90..9af9f62 100755 --- a/PHP/Repl.php +++ b/PHP/Repl.php @@ -124,13 +124,13 @@ public function run(array $scope = array()) while (true) { // inner loop is to escape from stacked output buffers while ($__ob__ = ob_get_clean() ) { - echo $__ob__; + echo $this->ob_cleanup($__ob__); unset($__ob__); } try { if (((boolean) $__code__ = $this->read()) === false) { - break; + continue; } ob_start(array($this, 'ob_cleanup')); ob_implicit_flush(true); From 73d0d12ed84459eff2cdd991816b0a24683ce021 Mon Sep 17 00:00:00 2001 From: David Maus Date: Fri, 29 Apr 2011 06:10:39 +0200 Subject: [PATCH 08/30] Restart PHP process after abnormal exit * php-repl.el (run-php-process-sentinel): New function. Process sentinel, restart PHP process after abnormal exit. (run-php): Use process sentinel. --- data/php-repl.el | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/data/php-repl.el b/data/php-repl.el index 43798de..cf4f858 100644 --- a/data/php-repl.el +++ b/data/php-repl.el @@ -71,11 +71,19 @@ (let ((buf (cond ((buffer-live-p inferior-php-buffer) inferior-php-buffer) (t (generate-new-buffer "*inferior-php*"))))) (apply 'make-comint-in-buffer "PHP" buf php-repl-program nil php-repl-program-arguments) + (set-process-sentinel + (get-buffer-process inferior-php-buffer) 'run-php-process-sentinel) (setq inferior-php-buffer buf) (display-buffer buf t) (pop-to-buffer buf t) (inferior-php-mode))) +(defun run-php-process-sentinel (process event) + "*Restart PHP process after abnormal exit." + (when (string-match-p "^exited abnormally with code" event) + (message "Restarting PHP process") + (run-php))) + (define-derived-mode inferior-php-mode comint-mode "Inferior PHP") (defvar inferior-php-mode-abbrev-table (make-abbrev-table)) From b9fc57a272ac5da3f4c21ccb69049698f3783960 Mon Sep 17 00:00:00 2001 From: David Maus Date: Fri, 29 Apr 2011 06:17:39 +0200 Subject: [PATCH 09/30] Setq symbol before using it * php-repl.el (run-php): Setq symbol before using it. --- data/php-repl.el | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/data/php-repl.el b/data/php-repl.el index cf4f858..1c625da 100644 --- a/data/php-repl.el +++ b/data/php-repl.el @@ -71,9 +71,9 @@ (let ((buf (cond ((buffer-live-p inferior-php-buffer) inferior-php-buffer) (t (generate-new-buffer "*inferior-php*"))))) (apply 'make-comint-in-buffer "PHP" buf php-repl-program nil php-repl-program-arguments) + (setq inferior-php-buffer buf) (set-process-sentinel (get-buffer-process inferior-php-buffer) 'run-php-process-sentinel) - (setq inferior-php-buffer buf) (display-buffer buf t) (pop-to-buffer buf t) (inferior-php-mode))) From ebbb46c51be228ce51184562bc9443e14a65c0fc Mon Sep 17 00:00:00 2001 From: David Maus Date: Fri, 29 Apr 2011 06:19:24 +0200 Subject: [PATCH 10/30] Don't change buffer and window when visiting inferior-php-buffer * php-repl.el (run-php): Don't change buffer and window when already visiting inferior-php-buffer. --- data/php-repl.el | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/data/php-repl.el b/data/php-repl.el index 1c625da..6aa84db 100644 --- a/data/php-repl.el +++ b/data/php-repl.el @@ -74,8 +74,9 @@ (setq inferior-php-buffer buf) (set-process-sentinel (get-buffer-process inferior-php-buffer) 'run-php-process-sentinel) - (display-buffer buf t) - (pop-to-buffer buf t) + (unless (eq (current-buffer) inferior-php-buffer) + (display-buffer buf t) + (pop-to-buffer buf t)) (inferior-php-mode))) (defun run-php-process-sentinel (process event) From 95a9dfeb8a42eaeb338953d8863142b5eed73345 Mon Sep 17 00:00:00 2001 From: David Maus Date: Sun, 10 Jul 2011 06:25:23 +0200 Subject: [PATCH 11/30] Fix typo in defgroup prefix * php-repl.el (php-repl): Fix typo in defgroup prefix. --- data/php-repl.el | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/data/php-repl.el b/data/php-repl.el index 6aa84db..531918d 100644 --- a/data/php-repl.el +++ b/data/php-repl.el @@ -43,7 +43,7 @@ (defgroup php-repl nil "Major mode for interacting with an inferior PHP interpreter." - :prefix "ph-repl-" + :prefix "php-repl-" :group 'php) (defcustom php-repl-program From b2cb9361a099a944ae5278a0030415361fbaec5c Mon Sep 17 00:00:00 2001 From: David Maus Date: Sun, 10 Jul 2011 06:32:33 +0200 Subject: [PATCH 12/30] Use inferior php buffer, not sql buffer * php-repl.el (php-send-region): Use inferior php buffer, not sql buffer. --- data/php-repl.el | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/data/php-repl.el b/data/php-repl.el index 531918d..3939d2f 100644 --- a/data/php-repl.el +++ b/data/php-repl.el @@ -120,7 +120,7 @@ (save-excursion (comint-send-region inferior-php-buffer start end) (if (not (string-match "\n$" (buffer-substring start end))) - (comint-send-string sql-buffer "\n")) + (comint-send-string inferior-php-buffer "\n")) (display-buffer inferior-php-buffer)))) (defun php-eval-sexp ()) From ce52384e033af0793290981882dc1cc66f4a150d Mon Sep 17 00:00:00 2001 From: Niclas Hoyer Date: Mon, 5 Mar 2012 20:14:03 +0100 Subject: [PATCH 13/30] Added check for PHP_INCLUDE_PATH environment variable. The binary wrapper /scripts/php-repl will now if the environment variable PHP_INCLUDE_PATH is set and add it to the include_path php.ini directive. --- scripts/php-repl | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/scripts/php-repl b/scripts/php-repl index 909effc..8ef4d6a 100755 --- a/scripts/php-repl +++ b/scripts/php-repl @@ -16,6 +16,12 @@ * @filesource */ +// Add environment variable PHP_INCLUDE_PATH to include_path if it exists. +$includePath = getenv('PHP_INCLUDE_PATH'); +if ($includePath !== false) { + set_include_path(get_include_path().':'.getenv('PHP_INCLUDE_PATH')); +} + require_once 'PHP/Repl.php'; $__repl__ = new PHP_Repl(); $__repl__->run(); From 646c51d2204aa6bd8e1c94870e0f5768a43565e2 Mon Sep 17 00:00:00 2001 From: Michael Dwyer Date: Tue, 17 Jul 2012 14:57:27 -0500 Subject: [PATCH 14/30] Fixed bug in run-php that occured when php-repl-program-arguments is nil. --- data/php-repl.el | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/data/php-repl.el b/data/php-repl.el index 08d6ad4..19cd67d 100644 --- a/data/php-repl.el +++ b/data/php-repl.el @@ -70,9 +70,10 @@ (interactive "p") (let ((buf (cond ((buffer-live-p inferior-php-buffer) inferior-php-buffer) (t (generate-new-buffer "*inferior-php*"))))) - (make-comint-in-buffer - "PHP" buf php-repl-program nil - (mapconcat 'identity php-repl-program-arguments " ")) + (apply 'make-comint-in-buffer + (append `("PHP" ,buf ,php-repl-program ,nil) + (when php-repl-program-arguments + `(,(mapconcat 'identity php-repl-program-arguments " "))))) (setq inferior-php-buffer buf) (display-buffer buf t) ;; (pop-to-buffer buf t) From 0bcb8b7cbfa08b003fd1bac43b4548731181fa17 Mon Sep 17 00:00:00 2001 From: Michael Dwyer Date: Tue, 17 Jul 2012 17:23:42 -0500 Subject: [PATCH 15/30] Set local comint-related variables. Added a new function and corresponding defcustom php-repl-echo-add-newline. This will cause php-send-region to make the prompt reappear on its own line. Fixed misplaced defcustom. --- data/php-repl.el | 36 +++++++++++++++++++++++++++++------- 1 file changed, 29 insertions(+), 7 deletions(-) diff --git a/data/php-repl.el b/data/php-repl.el index 3939d2f..f89cf6e 100644 --- a/data/php-repl.el +++ b/data/php-repl.el @@ -56,6 +56,11 @@ "Arguments for the PHP program." :type '(repeat string)) +(defcustom php-repl-echo-add-newline nil + "Whether tp have an extra newline added after echo/print +statments so that the prompt will reappear on its own line." + :type 'boolean) + (defcustom php-use-eval-php-mode nil "Whether to enable php-eval-mode for PHP buffers." :type 'boolean @@ -77,7 +82,10 @@ (unless (eq (current-buffer) inferior-php-buffer) (display-buffer buf t) (pop-to-buffer buf t)) - (inferior-php-mode))) + (inferior-php-mode) + (set (make-local-variable 'comint-prompt-regexp) "^php> ") + (set (make-local-variable 'comint-use-prompt-regexp) t) + (set (make-local-variable 'comint-eol-on-send) t))) (defun run-php-process-sentinel (process event) "*Restart PHP process after abnormal exit." @@ -115,17 +123,31 @@ (defun php-send-region (start end) "Send a region to the inferior PHP process." (interactive "r") - (if (not (buffer-live-p inferior-php-buffer)) - (run-php)) + (unless (and (buffer-live-p inferior-php-buffer) + (get-buffer-process inferior-php-buffer)) + (save-excursion (run-php))) (save-excursion - (comint-send-region inferior-php-buffer start end) - (if (not (string-match "\n$" (buffer-substring start end))) - (comint-send-string inferior-php-buffer "\n")) - (display-buffer inferior-php-buffer)))) + (let ((cmd-string (replace-regexp-in-string + "\n" "" + (buffer-substring-no-properties start end)))) + (comint-simple-send inferior-php-buffer cmd-string) + (when php-repl-echo-add-newline (php-repl-echo-add-newline)) + (display-buffer inferior-php-buffer)))) (defun php-eval-sexp ()) (defun php-eval-expression ()) (defun php-eval-buffer ()) (defun php-eval-line ()) +(defun php-repl-echo-add-newline () + (with-current-buffer inferior-php-buffer + (sit-for .01) + (comint-next-prompt 1) + (save-match-data + (when (and (not (looking-back-p comint-prompt-regexp)) + (looking-back (substring comint-prompt-regexp 1))) + (goto-char (match-beginning 0)) + (newline) + (end-of-line))))) + (provide 'php-repl) From a7167afe906ac41a1d368193edf6fe806b21b177 Mon Sep 17 00:00:00 2001 From: Peter Meth Date: Wed, 7 Nov 2012 10:54:22 -0500 Subject: [PATCH 16/30] adding setter for options --- PHP/Repl.php | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/PHP/Repl.php b/PHP/Repl.php index fe5faaf..932173b 100755 --- a/PHP/Repl.php +++ b/PHP/Repl.php @@ -87,6 +87,17 @@ private function defaultOptions() return $defaults; } + /** + * Set options + * + * @param array $options An array of options for use in the REPL + * + */ + private function setOptions(array $options) + { + $this->options = array_merge($this->options, $options); + } + /** * Destructor * From cc5d2e0a03ae3294b2f1659350028b962ab02cc0 Mon Sep 17 00:00:00 2001 From: Peter Meth Date: Wed, 7 Nov 2012 11:44:24 -0500 Subject: [PATCH 17/30] making setOptions public --- PHP/Repl.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/PHP/Repl.php b/PHP/Repl.php index befab32..41a4653 100755 --- a/PHP/Repl.php +++ b/PHP/Repl.php @@ -93,7 +93,7 @@ private function defaultOptions() * @param array $options An array of options for use in the REPL * */ - private function setOptions(array $options) + public function setOptions(array $options) { $this->options = array_merge($this->options, $options); } From f0eec4e009fed70c9cdb062125c334db2486ee77 Mon Sep 17 00:00:00 2001 From: Peter Meth Date: Thu, 21 Feb 2013 13:49:22 -0500 Subject: [PATCH 18/30] changing output of an array to print_r and adding a showtime option to the prompt --- PHP/Repl.php | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/PHP/Repl.php b/PHP/Repl.php index 41a4653..d4f9f9c 100755 --- a/PHP/Repl.php +++ b/PHP/Repl.php @@ -73,6 +73,7 @@ public function __construct($options = array()) private function defaultOptions() { $defaults = array('prompt' => 'php> ', + 'showtime' => false, 'readline' => true, 'readline_hist' => getenv('HOME') . '/.phprepl_history'); @@ -176,7 +177,7 @@ private function read() $shifted = true; } do { - $prompt = $lines > 0 ? '> ' : $this->options['prompt']; + $prompt = $lines > 0 ? '> ' : ($this->options['showtime'] ? date('G:i:s ') : '') . $this->options['prompt']; if (count($_SERVER['argv'])) { $line = array_shift($_SERVER['argv']); } elseif ($this->options['readline']) { @@ -208,7 +209,7 @@ private function read() case '(': array_push($stack, $t); break; - + case '}': if ('{' !== array_pop($stack)) { throw new Exception('Unmatched closing brace.'); @@ -359,9 +360,11 @@ private function _print($out) break; case 'string': + var_export($out); + echo "\n"; + break; case 'array': - var_export($out); - echo "\n"; + print_r($out); break; default: From 3dac45538e5195fc7b6d2e929143e99e52589022 Mon Sep 17 00:00:00 2001 From: Peter Meth Date: Wed, 26 Jun 2013 10:13:55 -0400 Subject: [PATCH 19/30] taking readline out of options and making it part of the class --- PHP/Repl.php | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/PHP/Repl.php b/PHP/Repl.php index d4f9f9c..69a918a 100755 --- a/PHP/Repl.php +++ b/PHP/Repl.php @@ -59,7 +59,12 @@ public function __construct($options = array()) $defaults = $this->defaultOptions(); $this->options = array_merge($defaults, $options); - if ($this->options['readline'] && + $this->readline_support = true; + if (!function_exists('readline') || getenv('TERM') == 'dumb') { + $this->readline_support = false; + } + + if ($this->readline_support && is_readable($this->options['readline_hist'])) { readline_read_history($this->options['readline_hist']); } @@ -74,14 +79,9 @@ private function defaultOptions() { $defaults = array('prompt' => 'php> ', 'showtime' => false, - 'readline' => true, 'readline_hist' => getenv('HOME') . '/.phprepl_history'); - if (!function_exists('readline') || getenv('TERM') == 'dumb') { - $defaults['readline'] = false; - } - if (is_readable($this->rc_file)) { $defaults = array_merge($defaults, parse_ini_file($this->rc_file)); } @@ -107,7 +107,7 @@ public function setOptions(array $options) public function __destruct() { fclose($this->input); - if ($this->options['readline']) { + if ($this->readline_support) { readline_write_history($this->options['readline_hist']); } @@ -180,7 +180,7 @@ private function read() $prompt = $lines > 0 ? '> ' : ($this->options['showtime'] ? date('G:i:s ') : '') . $this->options['prompt']; if (count($_SERVER['argv'])) { $line = array_shift($_SERVER['argv']); - } elseif ($this->options['readline']) { + } elseif ($this->readline_support) { $line = readline($prompt); } else { echo $prompt; @@ -237,7 +237,7 @@ private function read() } while (!$done); // Add the whole block to the readline history. - if ($this->options['readline']) { + if ($this->readline_support) { readline_add_history($code); } return $code; From 1917d5b2595b458301fa8dfff5a8f21395d4e03b Mon Sep 17 00:00:00 2001 From: Peter Meth Date: Fri, 5 Jul 2013 22:27:56 -0400 Subject: [PATCH 20/30] reorganizing files for use with composer --- .gitignore | 1 + composer.json | 25 ++++ data/php-repl.el | 153 ---------------------- scripts/php-repl => examples/php-repl.sh | 4 +- package.xml | 76 ----------- PHP/Repl.php => src/PHP_Repl/PHP_Repl.php | 1 + 6 files changed, 29 insertions(+), 231 deletions(-) create mode 100644 .gitignore create mode 100644 composer.json delete mode 100644 data/php-repl.el rename scripts/php-repl => examples/php-repl.sh (86%) delete mode 100644 package.xml rename PHP/Repl.php => src/PHP_Repl/PHP_Repl.php (99%) diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..57872d0 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +/vendor/ diff --git a/composer.json b/composer.json new file mode 100644 index 0000000..f8f6a90 --- /dev/null +++ b/composer.json @@ -0,0 +1,25 @@ +{ + "name": "pmeth/php_repl", + "description": "A command line REPL (Read-Evaluate-Print-Loop) for PHP written in PHP.", + "license": "BSD-2-Clause", + "authors": [ + { + "name": "Ian Eure", + "email": "ieure@php.net" + }, + { + "name": "Peter Meth", + "homepage": "http://softersoftware.com" + } + ], + + "require": { + "php": ">=5.3.0" + }, + + "autoload": { + "psr-0": { + "PHP_Repl": "src/" + } + } +} diff --git a/data/php-repl.el b/data/php-repl.el deleted file mode 100644 index f89cf6e..0000000 --- a/data/php-repl.el +++ /dev/null @@ -1,153 +0,0 @@ -;;; php-repl.el --- Interact with PHP - -;; Copyright © 2009 Ian Eure - -;; Maintainer: Ian Eure -;; Author: Ian Eure -;; Keywords: php repl -;; Created: 2009-03-27 -;; Modified: 2009-03-27 -;; X-URL: http://atomized.org - -;;; License - -;; This file 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 3 -;; of the License, or (at your option) any later version. - -;; This file 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 this file; if not, write to the Free Software -;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA -;; 02110-1301, USA. - -;;; Usage - -;; Put this file in your Emacs lisp path (eg. site-lisp) and add to -;; your .emacs file: -;; -;; (require 'php-repl) -;; -;; You can run an inferior PHP by invoking run-php. -;; - -(defconst php-repl-version-number "0.8.2" - "PHP_Repl Mode version number.") - -(require 'comint) - -(defgroup php-repl nil - "Major mode for interacting with an inferior PHP interpreter." - :prefix "php-repl-" - :group 'php) - -(defcustom php-repl-program - "php-repl" - "Path to the PHP interpreter" - :type '(file)) - -(defcustom php-repl-program-arguments - '() - "Arguments for the PHP program." - :type '(repeat string)) - -(defcustom php-repl-echo-add-newline nil - "Whether tp have an extra newline added after echo/print -statments so that the prompt will reappear on its own line." - :type 'boolean) - -(defcustom php-use-eval-php-mode nil - "Whether to enable php-eval-mode for PHP buffers." - :type 'boolean - :group 'php) - -(defvar inferior-php-buffer nil - "The buffer of the current inferior PHP processs") - -;;;###autoload -(defun run-php (&optional arg) - "Run an inferior PHP interpreter." - (interactive "p") - (let ((buf (cond ((buffer-live-p inferior-php-buffer) inferior-php-buffer) - (t (generate-new-buffer "*inferior-php*"))))) - (apply 'make-comint-in-buffer "PHP" buf php-repl-program nil php-repl-program-arguments) - (setq inferior-php-buffer buf) - (set-process-sentinel - (get-buffer-process inferior-php-buffer) 'run-php-process-sentinel) - (unless (eq (current-buffer) inferior-php-buffer) - (display-buffer buf t) - (pop-to-buffer buf t)) - (inferior-php-mode) - (set (make-local-variable 'comint-prompt-regexp) "^php> ") - (set (make-local-variable 'comint-use-prompt-regexp) t) - (set (make-local-variable 'comint-eol-on-send) t))) - -(defun run-php-process-sentinel (process event) - "*Restart PHP process after abnormal exit." - (when (string-match-p "^exited abnormally with code" event) - (message "Restarting PHP process") - (run-php))) - -(define-derived-mode inferior-php-mode comint-mode "Inferior PHP") -(defvar inferior-php-mode-abbrev-table - (make-abbrev-table)) -(if (boundp 'php-mode-abbrev-table) - (derived-mode-merge-abbrev-tables php-mode-abbrev-table - inferior-php-mode-abbrev-table)) -(derived-mode-set-abbrev-table 'inferior-php-mode) - -(defvar eval-php-mode-map - (let ((map (make-sparse-keymap))) - (define-key map "\C-c\C-r" 'php-send-region) - ;; (define-key map "\C-\M-x" 'php-send-defun) - (define-key map "\C-x\C-e" 'php-send-sexp) - ;; (define-key map "\C-x\C-:" 'php-send-expression) - map) - "Keymap for eval-php-mode.") - -(define-minor-mode eval-php-mode - "Minor mode for evaluating PHP code in an inferior process." nil "eval" - :keymap eval-php-mode-map - :group 'php-repl - :global nil) - -(add-hook 'php-mode-hook - '(lambda () - (when php-use-eval-php-mode (eval-php-mode t))) - -(defun php-send-region (start end) - "Send a region to the inferior PHP process." - (interactive "r") - (unless (and (buffer-live-p inferior-php-buffer) - (get-buffer-process inferior-php-buffer)) - (save-excursion (run-php))) - (save-excursion - (let ((cmd-string (replace-regexp-in-string - "\n" "" - (buffer-substring-no-properties start end)))) - (comint-simple-send inferior-php-buffer cmd-string) - (when php-repl-echo-add-newline (php-repl-echo-add-newline)) - (display-buffer inferior-php-buffer)))) - -(defun php-eval-sexp ()) -(defun php-eval-expression ()) -(defun php-eval-buffer ()) -(defun php-eval-line ()) - -(defun php-repl-echo-add-newline () - (with-current-buffer inferior-php-buffer - (sit-for .01) - (comint-next-prompt 1) - (save-match-data - (when (and (not (looking-back-p comint-prompt-regexp)) - (looking-back (substring comint-prompt-regexp 1))) - (goto-char (match-beginning 0)) - (newline) - (end-of-line))))) - -(provide 'php-repl) diff --git a/scripts/php-repl b/examples/php-repl.sh similarity index 86% rename from scripts/php-repl rename to examples/php-repl.sh index 8ef4d6a..e1bafd1 100755 --- a/scripts/php-repl +++ b/examples/php-repl.sh @@ -22,8 +22,8 @@ if ($includePath !== false) { set_include_path(get_include_path().':'.getenv('PHP_INCLUDE_PATH')); } -require_once 'PHP/Repl.php'; -$__repl__ = new PHP_Repl(); +require_once __DIR__ . '/../src/PHP_Repl/PHP_Repl.php'; +$__repl__ = new \PHP_Repl\PHP_Repl(); $__repl__->run(); ?> diff --git a/package.xml b/package.xml deleted file mode 100644 index 40146b2..0000000 --- a/package.xml +++ /dev/null @@ -1,76 +0,0 @@ - - - PHP_Repl - pear.php.net - An interactive read-eval-print loop for PHP - PHP_Repl is a read-eval-print loop for PHP, written in PHP. It aims to be light, clean, modern, object-oriented, and to leverage the existing features of PHP wherever possible. - - Ian Eure - ieure - ieure@php.net - yes - - 2009-04-21 - - 0.8.6dev3 - 0.8.6 - - - beta - alpha - - New BSD License - - - Allow multiline input. - - Basic dissection and sugar. - - Save last-evaluated code in $__exp__. - - Start output buffering at the top of run(). - - - - - - - - - - - - - - - - - - - - - - - - - 5.2.0 - - - 1.7.0 - - - - - pcntl - - - - - diff --git a/PHP/Repl.php b/src/PHP_Repl/PHP_Repl.php similarity index 99% rename from PHP/Repl.php rename to src/PHP_Repl/PHP_Repl.php index 69a918a..5e8bdf5 100755 --- a/PHP/Repl.php +++ b/src/PHP_Repl/PHP_Repl.php @@ -1,5 +1,6 @@ Date: Fri, 5 Jul 2013 22:42:54 -0400 Subject: [PATCH 21/30] adding another example --- examples/example.php | 9 +++++++++ 1 file changed, 9 insertions(+) create mode 100644 examples/example.php diff --git a/examples/example.php b/examples/example.php new file mode 100644 index 0000000..55c3312 --- /dev/null +++ b/examples/example.php @@ -0,0 +1,9 @@ +run(); From e25103c5f6a230f4728b8f34a8f41668e788c6e8 Mon Sep 17 00:00:00 2001 From: Peter Meth Date: Fri, 5 Jul 2013 23:00:00 -0400 Subject: [PATCH 22/30] renaming PHP_Repl to PHPRepl --- composer.json | 2 +- examples/example.php | 2 +- examples/php-repl.sh | 4 ++-- src/{PHP_Repl/PHP_Repl.php => PHPRepl/PHPRepl.php} | 4 ++-- 4 files changed, 6 insertions(+), 6 deletions(-) rename src/{PHP_Repl/PHP_Repl.php => PHPRepl/PHPRepl.php} (99%) diff --git a/composer.json b/composer.json index f8f6a90..3f509e7 100644 --- a/composer.json +++ b/composer.json @@ -19,7 +19,7 @@ "autoload": { "psr-0": { - "PHP_Repl": "src/" + "PHPRepl": "src/" } } } diff --git a/examples/example.php b/examples/example.php index 55c3312..c4ea3c5 100644 --- a/examples/example.php +++ b/examples/example.php @@ -1,6 +1,6 @@ run(); ?> diff --git a/src/PHP_Repl/PHP_Repl.php b/src/PHPRepl/PHPRepl.php similarity index 99% rename from src/PHP_Repl/PHP_Repl.php rename to src/PHPRepl/PHPRepl.php index 5e8bdf5..82f027d 100755 --- a/src/PHP_Repl/PHP_Repl.php +++ b/src/PHPRepl/PHPRepl.php @@ -1,6 +1,6 @@ * @version @package_version@ */ -class PHP_Repl +class PHPRepl { /** * Where we're reading input from From 4eb839862704ea77c38557e198bff01aed156693 Mon Sep 17 00:00:00 2001 From: Peter Meth Date: Fri, 5 Jul 2013 23:10:50 -0400 Subject: [PATCH 23/30] changes to readme to support the composer installation method --- README.mkd | 41 +++++++++++++---------------------------- 1 file changed, 13 insertions(+), 28 deletions(-) diff --git a/README.mkd b/README.mkd index bc4f2df..e74b01c 100644 --- a/README.mkd +++ b/README.mkd @@ -5,14 +5,17 @@ PHP_Repl is a read-eval-print loop for PHP, written in PHP. It aims to be light, Installation ============ - $ git clone git://github.com/ieure/php_repl.git - $ cd php_repl - $ pear package - $ pear install PHP_Repl*tgz +The library is available through Composer, so its easy to get it. Simply add this to your `composer.json` file: + + "require": { + "pmeth/php_repl": "dev-master" + } + +And run `composer install` Usage ===== -When you fire up PHP_Repl, you’re greeted with a prompt: +When you fire up PHPRepl, you’re greeted with a prompt: php> @@ -129,9 +132,9 @@ As mentioned, input is slightly altered before it is evaluated. Since this may p Reuse ===== -You can reuse PHP_Repl in your own projects. +You can reuse PHPRepl in your own projects. - require_once 'PHP/Repl.php'; + require_once 'PHPRepl.php'; function do_stuff() { @@ -141,7 +144,7 @@ You can reuse PHP_Repl in your own projects. } } -The REPL will have access to whatever scope your function does. If you invoke it from an object method, be aware that `$this` is always the PHP_Repl instance, not your object. +The REPL will have access to whatever scope your function does. If you invoke it from an object method, be aware that `$this` is always the PHPRepl instance, not your object. Passing Scope @@ -149,7 +152,7 @@ Passing Scope If you would like to pass additional variables into the REPL’s scope, you may include them in an array passed to run(). - require_once 'PHP/Repl.php'; + require_once 'PHPRepl.php'; class StuffDoer { function do_stuff() @@ -164,7 +167,7 @@ If you would like to pass additional variables into the REPL’s scope, you may Configuration ============= -PHP_Repl stores its configuration in `$HOME/.phpreplrc`. A default file will be created for you if none exists. Any options you set while the REPL is running will be written out when you quit it. +PHPRepl stores its configuration in `$HOME/.phpreplrc`. A default file will be created for you if none exists. Any options you set while the REPL is running will be written out when you quit it. The following options are recognized: @@ -187,24 +190,6 @@ Dangers 6. The output buffer’s callback method. -Emacs Integration -================= -Because I really like Emacs, and enjoy the integration other languages (e.g. Common Lisp, Python, etc) have with it, I put together `phprepl.el`. It’s incomplete and may be buggy. - -It provides `run-php`, which will fire up the PHP REPL of your choice (not just PHP_Repl, it should work with any interactive PHP tool). It has the beginnings of a minor-mode to send regions, buffers, etc to the REPL for evaluation, but this isn’t finished yet. - -Installation ------------- -Drop `php-repl.el` somewhere in your `load-path` and `(require 'php-repl)`. - -Configuration -------------- -It’s customizable; `M-x customize-group RET phprepl RET`. Point `php-repl-program` at `PHP/Repl.php`. - -Usage ------ -`M-x run-php` will fire PHP_Repl up in a `*php*` buffer. Type and be happy. - Alternatives ============ From 6ca1da8d0261bbeefeaffc7f44efeeff855da051 Mon Sep 17 00:00:00 2001 From: Peter Meth Date: Fri, 5 Jul 2013 23:14:49 -0400 Subject: [PATCH 24/30] changing references of PHP_Repl to PHPRepl --- README.mkd | 24 ++++++++++++------------ examples/example.php | 2 +- examples/php-repl.sh | 2 +- 3 files changed, 14 insertions(+), 14 deletions(-) diff --git a/README.mkd b/README.mkd index e74b01c..3c3ed5b 100644 --- a/README.mkd +++ b/README.mkd @@ -1,6 +1,6 @@ -What is PHP_Repl? +What is PHPRepl? ================= -PHP_Repl is a read-eval-print loop for PHP, written in PHP. It aims to be light, clean, modern, object-oriented, and to leverage the existing features of PHP wherever possible. +PHPRepl is a read-eval-print loop for PHP, written in PHP. It aims to be light, clean, modern, object-oriented, and to leverage the existing features of PHP wherever possible. Installation ============ @@ -51,8 +51,8 @@ Uncaught Exceptions are caught and dumped: exception 'Exception' with message 'Test 123' in /Users/ieure/Projects/php_repl/PHP/Repl.php(143) : eval()'d code:1 Stack trace: #0 /Users/ieure/Projects/php_repl/PHP/Repl.php(143): eval() - #1 /Users/ieure/Projects/php_repl/PHP/Repl.php(62): PHP_Repl->run() - #2 /Users/ieure/Projects/php_repl/testrepl(20): PHP_Repl->__construct(Array) + #1 /Users/ieure/Projects/php_repl/PHP/Repl.php(62): PHPRepl->run() + #2 /Users/ieure/Projects/php_repl/testrepl(20): PHPRepl->__construct(Array) #3 {main} php> @@ -82,16 +82,16 @@ Documentation ------------- Doc blocks can be accessed with `,d`: - php> ,d PHP_Repl + php> ,d PHPRepl /** - * PHP_Repl + * PHPRepl * - * @package PHP_Repl + * @package PHPRepl * @author Ian Eure * @version @package_version@ */ '---' - php> ,d PHP_Repl::read + php> ,d PHPRepl::read /** * Read input * @@ -139,7 +139,7 @@ You can reuse PHPRepl in your own projects. function do_stuff() { if ($debug_condition) { - $repl = new PHP_Repl(); + $repl = new PHPRepl(); $repl->run(); } } @@ -158,7 +158,7 @@ If you would like to pass additional variables into the REPL’s scope, you may function do_stuff() { if ($debug_condition) { - $repl = new PHP_Repl(); + $repl = new PHPRepl(); $repl->run(array('_caller' => $this)); } } @@ -179,9 +179,9 @@ The following options are recognized: Dangers ======= - 1. The evaluated code is run in the same process as PHP_Repl, so if you evaluate something which causes a fatal error, PHP_Repl will terminate. Sorry. + 1. The evaluated code is run in the same process as PHPRepl, so if you evaluate something which causes a fatal error, PHPRepl will terminate. Sorry. 2. Output buffering is used to capture anything printed by eval’d code. If you have code which produces output over a long period of time, you may not see the results right away. Use `flush()`. - 3. Certain settings are enforced by PHP_Repl. You can’t change the values of: + 3. Certain settings are enforced by PHPRepl. You can’t change the values of: 1. `display_errors`. It’s always on. 2. `html_errors`. Always off. 3. `error_reporting`. Always `E_ALL | E_STRICT`. diff --git a/examples/example.php b/examples/example.php index c4ea3c5..e28809a 100644 --- a/examples/example.php +++ b/examples/example.php @@ -5,5 +5,5 @@ require __DIR__ . '/../vendor/autoload.php'; -$repl = new PHP_Repl(); +$repl = new PHPRepl(); $repl->run(); diff --git a/examples/php-repl.sh b/examples/php-repl.sh index 66045d6..7166205 100755 --- a/examples/php-repl.sh +++ b/examples/php-repl.sh @@ -4,7 +4,7 @@ /* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */ /** - * Wrapper script for invoking PHP_Repl + * Wrapper script for invoking PHPRepl * * PHP version 5 * From 750078864d520f3d77d566b76740fbc8a9957465 Mon Sep 17 00:00:00 2001 From: Peter Meth Date: Sun, 7 Jul 2013 17:35:40 -0400 Subject: [PATCH 25/30] fixing some bugs that may have been added by namespaces --- src/PHPRepl/PHPRepl.php | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/src/PHPRepl/PHPRepl.php b/src/PHPRepl/PHPRepl.php index 82f027d..333cc20 100755 --- a/src/PHPRepl/PHPRepl.php +++ b/src/PHPRepl/PHPRepl.php @@ -213,12 +213,12 @@ private function read() case '}': if ('{' !== array_pop($stack)) { - throw new Exception('Unmatched closing brace.'); + throw new \Exception('Unmatched closing brace.'); } break; case ')': if ('(' !== array_pop($stack)) { - throw new Exception('Unmatched closing paren.'); + throw new \Exception('Unmatched closing paren.'); } break; } @@ -275,6 +275,8 @@ private function cleanup($input) $input = $last; } + $tokens = token_get_all("getName()}\n"; } foreach ($rc->getMethods() as $meth) { - echo "\{$meth->getName()}()\n"; + echo "{$meth->getName()}()\n"; } + return "---"; } From 0e3dfd79b0d6bde5c9e8a254bed4352d9fb5cc22 Mon Sep 17 00:00:00 2001 From: Peter Meth Date: Sun, 7 Jul 2013 17:56:47 -0400 Subject: [PATCH 26/30] fixing bug in sugar method ,l --- src/PHPRepl/PHPRepl.php | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/PHPRepl/PHPRepl.php b/src/PHPRepl/PHPRepl.php index 333cc20..9b991d1 100755 --- a/src/PHPRepl/PHPRepl.php +++ b/src/PHPRepl/PHPRepl.php @@ -279,8 +279,7 @@ private function cleanup($input) // if the input string contains anything but a single variable, // wrap it in single-quotes - if (!(count($tokens) == 2 && isset($tokens[1][0]) && - $tokens[1][0] = T_VARIABLE)) { + if (!(count($tokens) == 2 && isset($tokens[1][0]) && $tokens[1][0] == T_VARIABLE)) { $input = "'". str_replace("'", "\\'", $input) . "'"; } return $this->cleanup("\$this->{$sugar[$m]}($input)"); From 68548d04790207cc12fb7054eaf0c7835caa1114 Mon Sep 17 00:00:00 2001 From: peter meth Date: Tue, 4 Feb 2014 11:03:51 -0500 Subject: [PATCH 27/30] making the output functions configurable through the options array --- src/PHPRepl/PHPRepl.php | 70 ++++++++++++++++++++++++----------------- 1 file changed, 41 insertions(+), 29 deletions(-) diff --git a/src/PHPRepl/PHPRepl.php b/src/PHPRepl/PHPRepl.php index 9b991d1..b51e6e8 100755 --- a/src/PHPRepl/PHPRepl.php +++ b/src/PHPRepl/PHPRepl.php @@ -76,12 +76,23 @@ public function __construct($options = array()) * * @return array Defaults */ - private function defaultOptions() + protected function defaultOptions() { - $defaults = array('prompt' => 'php> ', - 'showtime' => false, - 'readline_hist' => getenv('HOME') . - '/.phprepl_history'); + $defaults = array( + 'prompt' => 'php> ', + 'showtime' => false, + 'readline_hist' => getenv('HOME') . '/.phprepl_history', + 'printers' => array( + 'NULL' => null, + 'double' => 'var_dump', + 'float' => 'var_dump', + 'integer' => 'var_dump', + 'boolean' => 'var_dump', + 'string' => array('var_export',"\n"), + 'array' => 'print_r', + '_default_' => 'print_r', + ), + ); if (is_readable($this->rc_file)) { $defaults = array_merge($defaults, parse_ini_file($this->rc_file)); @@ -151,7 +162,7 @@ public function run(array $scope = array()) ini_set('html_errors', 'Off'); ini_set('display_errors', 'On'); - $this->_print($_ = eval($this->cleanup($__code__))); + $this->output($_ = eval($this->cleanup($__code__))); } catch (Exception $e) { echo ($_ = $e) . "\n"; } @@ -347,31 +358,32 @@ public function ob_cleanup($output) * * @return void */ - private function _print($out) + protected function output($out) { - $type = gettype($out); - switch ($type) { - case 'NULL': - break; - - case 'double': - case 'float': - case 'integer': - case 'boolean': - var_dump($out); - break; - - case 'string': - var_export($out); - echo "\n"; - break; - case 'array': - print_r($out); - break; - - default: - print_r($out); + $printer = $this->getPrinter(gettype($out)); + $extra = ''; + + if (!$printer) { + return; + } + + if (is_array($printer)) { + $extras = $printer; + $printer = array_shift($extras); + $extra = implode('', $extras); + } + + call_user_func($printer, $out); + echo $extra; + } + + public function getPrinter($type) + { + if (isset($this->options['printers'][$type])) { + return $this->options['printers'][$type]; } + + return $this->options['printers']['_default_'];; } /** From 8b7dda5d6098be00e3c292c953167774f09bbd3b Mon Sep 17 00:00:00 2001 From: peter meth Date: Wed, 5 Feb 2014 05:44:23 -0500 Subject: [PATCH 28/30] removing auto saving of options --- src/PHPRepl/PHPRepl.php | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/PHPRepl/PHPRepl.php b/src/PHPRepl/PHPRepl.php index b51e6e8..02a8f6b 100755 --- a/src/PHPRepl/PHPRepl.php +++ b/src/PHPRepl/PHPRepl.php @@ -124,6 +124,9 @@ public function __destruct() } // Save config + /* turning off for now (maybe permanently) as support for nested + * arrays is broken + * $fp = fopen($this->rc_file, 'w'); if ($fp === false) { return; @@ -132,6 +135,7 @@ public function __destruct() fwrite($fp, "$k = \"$v\"\n"); } fclose($fp); + */ } /** From 2159b963586431935acfcf483c65956edeccc18d Mon Sep 17 00:00:00 2001 From: Peter Meth Date: Wed, 5 Feb 2014 07:58:57 -0500 Subject: [PATCH 29/30] fixing bug with setting options --- src/PHPRepl/PHPRepl.php | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/PHPRepl/PHPRepl.php b/src/PHPRepl/PHPRepl.php index 02a8f6b..199bb1c 100755 --- a/src/PHPRepl/PHPRepl.php +++ b/src/PHPRepl/PHPRepl.php @@ -58,7 +58,7 @@ public function __construct($options = array()) getenv('HOME') . '/.phpreplrc'; $defaults = $this->defaultOptions(); - $this->options = array_merge($defaults, $options); + $this->options = array_merge_recursive($defaults, $options); $this->readline_support = true; if (!function_exists('readline') || getenv('TERM') == 'dumb') { @@ -147,6 +147,10 @@ public function __destruct() */ public function run(array $scope = array()) { + ob_implicit_flush(true); + error_reporting(E_ALL | E_STRICT); + ini_set('html_errors', 'Off'); + ini_set('display_errors', 'On'); extract($scope); ob_start(); while (true) { @@ -161,10 +165,6 @@ public function run(array $scope = array()) continue; } ob_start(array($this, 'ob_cleanup')); - ob_implicit_flush(true); - error_reporting(E_ALL | E_STRICT); - ini_set('html_errors', 'Off'); - ini_set('display_errors', 'On'); $this->output($_ = eval($this->cleanup($__code__))); } catch (Exception $e) { From 2785ddbe65a854e419cec2d15a27bfe426f6b65e Mon Sep 17 00:00:00 2001 From: Peter Meth Date: Fri, 14 Feb 2014 09:04:59 -0500 Subject: [PATCH 30/30] separating printers from options. also making some sensible functions around getting and setting options and printers. readline now writes history as soon as the command is run to prevent losing your history when you encounter a fatal error --- src/PHPRepl/PHPRepl.php | 175 +++++++++++++++++++++++++--------------- 1 file changed, 109 insertions(+), 66 deletions(-) diff --git a/src/PHPRepl/PHPRepl.php b/src/PHPRepl/PHPRepl.php index 199bb1c..f2a8ea3 100755 --- a/src/PHPRepl/PHPRepl.php +++ b/src/PHPRepl/PHPRepl.php @@ -1,6 +1,7 @@ rc_file = getenv('PHPREPLRC') ? getenv('PHPREPLRC') : getenv('HOME') . '/.phpreplrc'; - $defaults = $this->defaultOptions(); + $this->printers = $this->getDefaultPrinters(); + $defaults = $this->getDefaultOptions(); $this->options = array_merge_recursive($defaults, $options); $this->readline_support = true; @@ -66,9 +70,43 @@ public function __construct($options = array()) } if ($this->readline_support && - is_readable($this->options['readline_hist'])) { - readline_read_history($this->options['readline_hist']); + is_readable($this->getOption('readline_hist'))) { + readline_read_history($this->getOption('readline_hist')); + } + } + + public function getDefaultPrinters() + { + return array( + 'NULL' => null, + 'double' => 'var_dump', + 'float' => 'var_dump', + 'integer' => 'var_dump', + 'boolean' => 'var_dump', + 'string' => array('var_export',"\n"), + 'array' => 'print_r', + 'object' => 'print_r', + '_default_' => 'print_r', + ); + } + + public function getPrinters() + { + return $this->printers; + } + + public function setPrinter($type, $printer) + { + $this->printers[$type] = $printer; + } + + public function getPrinter($type) + { + if (!isset($this->printers[$type])) { + return $this->printers['_default_']; } + + return $this->printers[$type]; } /** @@ -76,22 +114,12 @@ public function __construct($options = array()) * * @return array Defaults */ - protected function defaultOptions() + public function getDefaultOptions() { $defaults = array( 'prompt' => 'php> ', 'showtime' => false, 'readline_hist' => getenv('HOME') . '/.phprepl_history', - 'printers' => array( - 'NULL' => null, - 'double' => 'var_dump', - 'float' => 'var_dump', - 'integer' => 'var_dump', - 'boolean' => 'var_dump', - 'string' => array('var_export',"\n"), - 'array' => 'print_r', - '_default_' => 'print_r', - ), ); if (is_readable($this->rc_file)) { @@ -111,6 +139,25 @@ public function setOptions(array $options) $this->options = array_merge($this->options, $options); } + public function getOptions() + { + return $this->options; + } + + public function setOption($type, $option) + { + $this->options[$type] = $option; + } + + public function getOption($type) + { + if (!isset($this->options[$type])) { + return null; + } + + return $this->options[$type]; + } + /** * Destructor * @@ -120,7 +167,7 @@ public function __destruct() { fclose($this->input); if ($this->readline_support) { - readline_write_history($this->options['readline_hist']); + readline_write_history($this->getOption('readline_hist')); } // Save config @@ -155,8 +202,8 @@ public function run(array $scope = array()) ob_start(); while (true) { // inner loop is to escape from stacked output buffers - while ($__ob__ = ob_get_clean() ) { - echo $this->ob_cleanup($__ob__); + while ($__ob__ = ob_get_clean()) { + echo $this->obCleanup($__ob__); unset($__ob__); } @@ -164,7 +211,7 @@ public function run(array $scope = array()) if (((boolean) $__code__ = $this->read()) === false) { continue; } - ob_start(array($this, 'ob_cleanup')); + ob_start(array($this, 'obCleanup')); $this->output($_ = eval($this->cleanup($__code__))); } catch (Exception $e) { @@ -193,7 +240,7 @@ private function read() $shifted = true; } do { - $prompt = $lines > 0 ? '> ' : ($this->options['showtime'] ? date('G:i:s ') : '') . $this->options['prompt']; + $prompt = $lines > 0 ? '> ' : ($this->getOption('showtime') ? date('G:i:s ') : '') . $this->getOption('prompt'); if (count($_SERVER['argv'])) { $line = array_shift($_SERVER['argv']); } elseif ($this->readline_support) { @@ -242,7 +289,7 @@ private function read() $last_t = array_pop($tokens); if (is_array($last_t) && $last_t[0] == T_OPEN_TAG) { // if the last token was an open tag, this is nothing. - } else if ($stack[count($stack) - 1] === '{' && !in_array($last_t, array('{', '}', ';'))) { + } elseif ($stack[count($stack) - 1] === '{' && !in_array($last_t, array('{', '}', ';'))) { // allow implied semicolons inside curlies $line .= ';'; } @@ -255,6 +302,7 @@ private function read() // Add the whole block to the readline history. if ($this->readline_support) { readline_add_history($code); + readline_write_history($this->getOption('readline_hist')); } return $code; } @@ -347,7 +395,7 @@ private function cleanup($input) * * @return string Cleaned up output */ - public function ob_cleanup($output) + public function obCleanup($output) { if (strlen($output) > 0 && substr($output, -1) != "\n") { $output .= "\n"; @@ -381,15 +429,6 @@ protected function output($out) echo $extra; } - public function getPrinter($type) - { - if (isset($this->options['printers'][$type])) { - return $this->options['printers'][$type]; - } - - return $this->options['printers']['_default_'];; - } - /** * Get reflection for something * @@ -400,36 +439,39 @@ public function getPrinter($type) protected function getReflection($thing) { switch (true) { - case is_object($thing): - return new \ReflectionObject($thing); - - case class_exists($thing, false): - return new \ReflectionClass($thing); - - case function_exists($thing): - return new \ReflectionFunction($thing); - - case strstr($thing, '::'): - list($class, $what) = explode('::', $thing); - $rc = new \ReflectionClass($class); - - switch (true) { - case substr($what, -2) == '()': - $what = substr($what, 0, strlen($what) - 2); - case $rc->hasMethod($what): - return $rc->getMethod($what); - - case substr($what, 0, 1) == '$': - $what = substr($what, 1); - case $rc->hasProperty($what): - return $rc->getProperty($what); - - case $rc->hasConstant($what): - return $rc->getConstant($what); - } + case is_object($thing): + return new \ReflectionObject($thing); + + case class_exists($thing, false): + return new \ReflectionClass($thing); + + case function_exists($thing): + return new \ReflectionFunction($thing); + + case strstr($thing, '::'): + list($class, $what) = explode('::', $thing); + $rc = new \ReflectionClass($class); + + switch (true) { + case substr($what, -2) == '()': + $what = substr($what, 0, strlen($what) - 2); + // fallthrough + case $rc->hasMethod($what): + return $rc->getMethod($what); + + case substr($what, 0, 1) == '$': + $what = substr($what, 1); + // fallthrough + case $rc->hasProperty($what): + return $rc->getProperty($what); + + case $rc->hasConstant($what): + return $rc->getConstant($what); + } + // fallthrough - case is_string($thing): - return var_export($thing) . "\n"; + case is_string($thing): + return var_export($thing) . "\n"; } } @@ -476,13 +518,14 @@ protected function dir($thing) protected function doc($thing) { if ($r = $this->getReflection($thing)) { - echo preg_replace('/^\s*\*/m', ' *', - $r->getDocComment()) . "\n"; + echo preg_replace( + '/^\s*\*/m', + ' *', + $r->getDocComment() + ) . "\n"; } else { echo "(no doc)\n"; } return "---"; } } - -?>