branch: externals/phps-mode commit be810f9922edb1b6d33073de40f137b674a32717 Author: Christian Johansson <christ...@cvj.se> Commit: Christian Johansson <christ...@cvj.se>
Improved token-blind indentation around multi-line assignments --- phps-mode-lex-analyzer.el | 173 ++++++++++++++------------- phps-mode.el | 4 +- test/phps-mode-test-lex-analyzer.el | 228 +++++++----------------------------- 3 files changed, 135 insertions(+), 270 deletions(-) diff --git a/phps-mode-lex-analyzer.el b/phps-mode-lex-analyzer.el index add8cf0..6248b4a 100644 --- a/phps-mode-lex-analyzer.el +++ b/phps-mode-lex-analyzer.el @@ -2000,88 +2000,97 @@ SQUARE-BRACKET-LEVEL and ROUND-BRACKET-LEVEL." (line-beginning-position) (line-end-position)) ) - (when (> line-number 1) - (while (and - (> line-number 0) - line-is-empty) - (forward-line -1) - (setq line-number (1- line-number)) - (beginning-of-line) - (setq line-beginning-position (line-beginning-position)) - (setq line-end-position (line-end-position)) - (setq - line-string - (buffer-substring-no-properties line-beginning-position line-end-position)) - (setq line-is-empty (string-match-p "^[ \t\f\r\n]*$" line-string)) - (setq move-length (1+ move-length))) - - (unless line-is-empty - (let* ((old-indentation (current-indentation)) - (current-line-starts-with-closing-bracket (phps-mode-lex-analyzer--string-starts-with-closing-bracket-p current-line-string)) - (line-starts-with-closing-bracket (phps-mode-lex-analyzer--string-starts-with-closing-bracket-p line-string)) - (line-starts-with-opening-doc-comment (phps-mode-lex-analyzer--string-starts-with-opening-doc-comment-p line-string)) - (line-ends-with-assignment (phps-mode-lex-analyzer--string-ends-with-assignment-p line-string)) - (line-ends-with-opening-bracket (phps-mode-lex-analyzer--string-ends-with-opening-bracket-p line-string)) - (line-ends-with-terminus (phps-mode-lex-analyzer--string-ends-with-terminus-p line-string)) - (bracket-level (phps-mode-lex-analyzer--get-string-brackets-count line-string))) - (setq new-indentation old-indentation) - (goto-char point) - - (when (> bracket-level 0) - (if (< bracket-level tab-width) - (setq new-indentation (+ new-indentation 1)) - (setq new-indentation (+ new-indentation tab-width)))) - - (when (= bracket-level -1) - (setq new-indentation (1- new-indentation))) - - (when (and (= bracket-level 0) - line-starts-with-closing-bracket) - (setq new-indentation (+ new-indentation tab-width))) - - (when current-line-starts-with-closing-bracket - (setq new-indentation (- new-indentation tab-width))) - - (when line-starts-with-opening-doc-comment - (setq new-indentation (+ new-indentation 1))) - - (when line-ends-with-assignment - (setq new-indentation (+ new-indentation tab-width))) - - (when (and line-ends-with-opening-bracket - (< bracket-level 0)) - (setq new-indentation (+ new-indentation tab-width))) - - (when line-ends-with-terminus - ;; Back-trace buffer from previous line - ;; Determine if semi-colon ended an assignment or not - (forward-line (* -1 move-length)) - (end-of-line) - (forward-char -1) - (let ((not-found t) - (is-assignment nil)) - (while (and - not-found - (search-backward-regexp "\\(;\\|,\\|:\\|)\\|=\\)" nil t)) - (let ((match (buffer-substring-no-properties (match-beginning 0) (match-end 0)))) - (setq is-assignment (string= match "=")) - (setq not-found nil))) - ;; If it ended an assignment on a previous line, decrease indentation - (when (and is-assignment - (> bracket-level -1) - (not - (= line-number (line-number-at-pos)))) - ;; NOTE stuff like $var = array(\n 4\n);\n - ;; will end assignment but also decrease bracket-level - (setq new-indentation (- new-indentation tab-width)))) - - (goto-char point)) - - ;; Decrease indentation if current line decreases in bracket level - (when (< new-indentation 0) - (setq new-indentation 0)) - - (indent-line-to new-indentation)))))) + (if (> line-number 1) + (progn + (while (and + (> line-number 0) + line-is-empty) + (forward-line -1) + (setq line-number (1- line-number)) + (beginning-of-line) + (setq line-beginning-position (line-beginning-position)) + (setq line-end-position (line-end-position)) + (setq + line-string + (buffer-substring-no-properties line-beginning-position line-end-position)) + (setq line-is-empty (string-match-p "^[ \t\f\r\n]*$" line-string)) + (setq move-length (1+ move-length))) + + (unless line-is-empty + (let* ((old-indentation (current-indentation)) + (current-line-starts-with-closing-bracket (phps-mode-lex-analyzer--string-starts-with-closing-bracket-p current-line-string)) + (line-starts-with-closing-bracket (phps-mode-lex-analyzer--string-starts-with-closing-bracket-p line-string)) + (line-starts-with-opening-doc-comment (phps-mode-lex-analyzer--string-starts-with-opening-doc-comment-p line-string)) + (line-ends-with-assignment (phps-mode-lex-analyzer--string-ends-with-assignment-p line-string)) + (line-ends-with-opening-bracket (phps-mode-lex-analyzer--string-ends-with-opening-bracket-p line-string)) + (line-ends-with-terminus (phps-mode-lex-analyzer--string-ends-with-terminus-p line-string)) + (bracket-level (phps-mode-lex-analyzer--get-string-brackets-count line-string))) + (setq new-indentation old-indentation) + (goto-char point) + + (when (> bracket-level 0) + (if (< bracket-level tab-width) + (setq new-indentation (+ new-indentation 1)) + (setq new-indentation (+ new-indentation tab-width)))) + + (when (= bracket-level -1) + (setq new-indentation (1- new-indentation))) + + (when (and (= bracket-level 0) + line-starts-with-closing-bracket) + (setq new-indentation (+ new-indentation tab-width))) + + (when current-line-starts-with-closing-bracket + (setq new-indentation (- new-indentation tab-width))) + + (when line-starts-with-opening-doc-comment + (setq new-indentation (+ new-indentation 1))) + + (when line-ends-with-assignment + (setq new-indentation (+ new-indentation tab-width))) + + (when (and line-ends-with-opening-bracket + (< bracket-level 0)) + (setq new-indentation (+ new-indentation tab-width))) + + (when line-ends-with-terminus + ;; Back-trace buffer from previous line + ;; Determine if semi-colon ended an assignment or not + (forward-line (* -1 move-length)) + (end-of-line) + (forward-char -1) + (let ((not-found t) + (is-assignment nil) + (parenthesis-level 0)) + (while (and + not-found + (search-backward-regexp "\\(;\\|{\\|(\\|)\\|=\\)" nil t)) + (let ((match (buffer-substring-no-properties (match-beginning 0) (match-end 0)))) + (when (string= match ")") + (setq parenthesis-level (1- parenthesis-level))) + (when (= parenthesis-level 0) + (setq is-assignment (string= match "=")) + (setq not-found nil)) + + (when (string= match "(") + (setq parenthesis-level (1+ parenthesis-level))))) + ;; If it ended an assignment on a previous line, decrease indentation + (when (and is-assignment + (> bracket-level -1) + (not + (= line-number (line-number-at-pos)))) + ;; NOTE stuff like $var = array(\n 4\n);\n + ;; will end assignment but also decrease bracket-level + (setq new-indentation (- new-indentation tab-width)))) + + (goto-char point)) + + ;; Decrease indentation if current line decreases in bracket level + (when (< new-indentation 0) + (setq new-indentation 0)) + + (indent-line-to new-indentation)))) + (indent-line-to 0)))) ;; Only move to end of line if point is the current point and is at end of line (when (equal point (point)) (if point-at-end-of-line diff --git a/phps-mode.el b/phps-mode.el index 736ee8b..6350c69 100644 --- a/phps-mode.el +++ b/phps-mode.el @@ -5,8 +5,8 @@ ;; Author: Christian Johansson <christ...@cvj.se> ;; Maintainer: Christian Johansson <christ...@cvj.se> ;; Created: 3 Mar 2018 -;; Modified: 4 May 2020 -;; Version: 0.3.45 +;; Modified: 8 May 2020 +;; Version: 0.3.46 ;; Keywords: tools, convenience ;; URL: https://github.com/cjohansson/emacs-phps-mode diff --git a/test/phps-mode-test-lex-analyzer.el b/test/phps-mode-test-lex-analyzer.el index 7c9539f..f466219 100644 --- a/test/phps-mode-test-lex-analyzer.el +++ b/test/phps-mode-test-lex-analyzer.el @@ -72,18 +72,6 @@ (phps-mode-test--with-buffer "<?php\nif ($myCondition) {\necho 'I was here';\n}" "Alternative indentation inside if block" - (goto-char 32) - (should (equal - (phps-mode-lex-analyzer--alternative-indentation) - 4)) - (goto-char 15) - (should (equal - (phps-mode-lex-analyzer--alternative-indentation) - 0)) - (goto-char (point-max)) - (should (equal - (phps-mode-lex-analyzer--alternative-indentation) - 0)) (phps-mode-test-lex-analyzer--alternative-indentation-whole-buffer) (let ((buffer-contents (buffer-substring-no-properties (point-min) (point-max)))) (should (equal @@ -93,18 +81,6 @@ (phps-mode-test--with-buffer "<?php\nif ($myCondition) {\necho 'I was here';\necho 'I was here again';\n}" "Alternative indentation on closing if block" - (goto-char 30) - (should (equal - (phps-mode-lex-analyzer--alternative-indentation) - 4)) - (goto-char 57) - (should (equal - (phps-mode-lex-analyzer--alternative-indentation) - 4)) - (goto-char (point-max)) - (should (equal - (phps-mode-lex-analyzer--alternative-indentation) - 0)) (phps-mode-test-lex-analyzer--alternative-indentation-whole-buffer) (let ((buffer-contents (buffer-substring-no-properties (point-min) (point-max)))) (should (equal @@ -112,16 +88,8 @@ "<?php\nif ($myCondition) {\n echo 'I was here';\n echo 'I was here again';\n}")))) (phps-mode-test--with-buffer - "<?php\nif ($test) {\n if ($test2) {\n\n}\n}" + "<?php\nif ($test) {\nif ($test2) {\n\n}\n}" "Alternative indentation on nested if block with empty contents" - (goto-char 40) - (should (equal - (phps-mode-lex-analyzer--alternative-indentation) - 4)) - (goto-char (point-max)) - (should (equal - (phps-mode-lex-analyzer--alternative-indentation) - 0)) (phps-mode-test-lex-analyzer--alternative-indentation-whole-buffer) (let ((buffer-contents (buffer-substring-no-properties (point-min) (point-max)))) (should (equal @@ -129,12 +97,8 @@ "<?php\nif ($test) {\n if ($test2) {\n \n }\n}")))) (phps-mode-test--with-buffer - "<?php\nif ($test) {\n if ($test2) {\n \n }\n\n}" + "<?php\nif ($test) {\nif ($test2) {\n\n}\n\n}" "Alternative indentation on multiple closing brackets" - (goto-char 53) - (should (equal - (phps-mode-lex-analyzer--alternative-indentation) - 4)) (phps-mode-test-lex-analyzer--alternative-indentation-whole-buffer) (let ((buffer-contents (buffer-substring-no-properties (point-min) (point-max)))) (should (equal @@ -142,12 +106,8 @@ "<?php\nif ($test) {\n if ($test2) {\n \n }\n \n}")))) (phps-mode-test--with-buffer - "<?php\nif ($test) {\n \n} else if ($test) {\n \n}\n" + "<?php\nif ($test) {\n\n} else if ($test) {\n\n}\n" "Alternative indentation on elseif block" - (goto-char 25) - (should (equal - (phps-mode-lex-analyzer--alternative-indentation) - 0)) (phps-mode-test-lex-analyzer--alternative-indentation-whole-buffer) (let ((buffer-contents (buffer-substring-no-properties (point-min) (point-max)))) (should (equal @@ -155,12 +115,8 @@ "<?php\nif ($test) {\n \n} else if ($test) {\n \n}\n")))) (phps-mode-test--with-buffer - "if ($true) {\n if ($true) {\n }\n}" + "if ($true) {\nif ($true) {\n}\n}" "Alternative indentation on closing bracket inside parent bracket" - (goto-char 36) - (should (equal - (phps-mode-lex-analyzer--alternative-indentation) - 4)) (phps-mode-test-lex-analyzer--alternative-indentation-whole-buffer) (let ((buffer-contents (buffer-substring-no-properties (point-min) (point-max)))) (should (equal @@ -168,12 +124,8 @@ "if ($true) {\n if ($true) {\n }\n}")))) (phps-mode-test--with-buffer - "/**\n *\n */" + "/**\n*\n*/" "Alternative indentation on last line of doc comment block" - (goto-char 11) - (should (equal - (phps-mode-lex-analyzer--alternative-indentation) - 1)) (phps-mode-test-lex-analyzer--alternative-indentation-whole-buffer) (let ((buffer-contents (buffer-substring-no-properties (point-min) (point-max)))) (should (equal @@ -181,38 +133,8 @@ "/**\n *\n */")))) (phps-mode-test--with-buffer - "/**\n *\n */\n" - "Alternative indentation on line after closing of doc comment block" - (goto-char 12) - (should (equal - (phps-mode-lex-analyzer--alternative-indentation) - 0)) - (phps-mode-test-lex-analyzer--alternative-indentation-whole-buffer) - (let ((buffer-contents (buffer-substring-no-properties (point-min) (point-max)))) - (should (equal - buffer-contents - "/**\n *\n */\n")))) - - (phps-mode-test--with-buffer - "/**\n *\n **/\n" - "Alternative indentation on line after closing of doc comment block variant 2" - (goto-char 13) - (should (equal - (phps-mode-lex-analyzer--alternative-indentation) - 0)) - (phps-mode-test-lex-analyzer--alternative-indentation-whole-buffer) - (let ((buffer-contents (buffer-substring-no-properties (point-min) (point-max)))) - (should (equal - buffer-contents - "/**\n *\n **/\n")))) - - (phps-mode-test--with-buffer - "$var = 'abc';\n// Comment" + " $var = 'abc';\n // Comment" "Alternative indentation on single-line assignment" - (goto-char 1) - (should (equal - (phps-mode-lex-analyzer--alternative-indentation) - 0)) (phps-mode-test-lex-analyzer--alternative-indentation-whole-buffer) (let ((buffer-contents (buffer-substring-no-properties (point-min) (point-max)))) (should (equal @@ -220,25 +142,8 @@ "$var = 'abc';\n// Comment")))) (phps-mode-test--with-buffer - "$var = 'abc';\n// Comment" - "Alternative indentation on line after single-line assignment" - (goto-char 15) - (should (equal - (phps-mode-lex-analyzer--alternative-indentation) - 0)) - (phps-mode-test-lex-analyzer--alternative-indentation-whole-buffer) - (let ((buffer-contents (buffer-substring-no-properties (point-min) (point-max)))) - (should (equal - buffer-contents - "$var = 'abc';\n// Comment")))) - - (phps-mode-test--with-buffer - "$var =\n 'abc';\n$var =\n 'abc'\n . 'def';\n// Comment\n" - "Alternative indentation on first line of multi-line assignment" - (goto-char 1) - (should (equal - (phps-mode-lex-analyzer--alternative-indentation) - 0)) + "$var =\n'abc';\n$var =\n'abc'\n. 'def';\n// Comment\n" + "Alternative indentation on multi-line assignment" (phps-mode-test-lex-analyzer--alternative-indentation-whole-buffer) (let ((buffer-contents (buffer-substring-no-properties (point-min) (point-max)))) (should (equal @@ -246,151 +151,102 @@ "$var =\n 'abc';\n$var =\n 'abc'\n . 'def';\n// Comment\n")))) (phps-mode-test--with-buffer - "$var =\n 'abc';\n$var =\n 'abc'\n . 'def';\n// Comment\n" - "Alternative indentation on second line of multi-line assignment" - (goto-char 30) - (should (equal - (phps-mode-lex-analyzer--alternative-indentation) - 4)) + "<?php\nif ($here) {\nif ($wasHere)\n{\n\n}\n}\n\n" + "Alternative indentation on line after condition" (phps-mode-test-lex-analyzer--alternative-indentation-whole-buffer) (let ((buffer-contents (buffer-substring-no-properties (point-min) (point-max)))) (should (equal buffer-contents - "$var =\n 'abc';\n$var =\n 'abc'\n . 'def';\n// Comment\n")))) + "<?php\nif ($here) {\n if ($wasHere)\n {\n \n }\n}\n\n")))) (phps-mode-test--with-buffer - "$var =\n 'abc';\n$var =\n 'abc'\n . 'def';\n// Comment\n" - "Alternative indentation on last line of multi-line assignment" - (goto-char 12) - (should (equal - (phps-mode-lex-analyzer--alternative-indentation) - 4)) - (goto-char 40) - (should (equal - (phps-mode-lex-analyzer--alternative-indentation) - 4)) + "<?php\nif ($myCondition)\n{\n$var = array(\n'was here'\n);\n// Was here\n}\n" + "Alternative indentation on line after array declaration" (phps-mode-test-lex-analyzer--alternative-indentation-whole-buffer) (let ((buffer-contents (buffer-substring-no-properties (point-min) (point-max)))) (should (equal buffer-contents - "$var =\n 'abc';\n$var =\n 'abc'\n . 'def';\n// Comment\n")))) + "<?php\nif ($myCondition)\n{\n $var = array(\n 'was here'\n );\n // Was here\n}\n" + )))) (phps-mode-test--with-buffer - "$var =\n 'abc';\n$var =\n 'abc'\n . 'def';\n// Comment\n" - "Alternative indentation on line after multi-line assignment" - (goto-char 53) - (should (equal - (phps-mode-lex-analyzer--alternative-indentation) - 0)) + "<?php\nif ($myCondition == 2) {\necho 'store_vars: <pre>' . print_r($store_vars, true) . '</pre>';\necho 'search_ids: <pre>' . print_r($search_ids, true) . '</pre>';\n}" + "Alternative indentation on line echo" (phps-mode-test-lex-analyzer--alternative-indentation-whole-buffer) (let ((buffer-contents (buffer-substring-no-properties (point-min) (point-max)))) (should (equal buffer-contents - "$var =\n 'abc';\n$var =\n 'abc'\n . 'def';\n// Comment\n")))) + "<?php\nif ($myCondition == 2) {\n echo 'store_vars: <pre>' . print_r($store_vars, true) . '</pre>';\n echo 'search_ids: <pre>' . print_r($search_ids, true) . '</pre>';\n}" + )))) (phps-mode-test--with-buffer - "<?php\nif ($here) {\n if ($wasHere)\n{\n \n }\n}\n\n" - "Alternative indentation on line after condition" - (goto-char 38) - (should (equal - (phps-mode-lex-analyzer--alternative-indentation) - 4)) + "<?php\nif (is_array(\n$array\n)) {\necho 'was here';\n}" + "Alternative indentation after trailing opening bracket while closing two earlier on line" (phps-mode-test-lex-analyzer--alternative-indentation-whole-buffer) (let ((buffer-contents (buffer-substring-no-properties (point-min) (point-max)))) (should (equal buffer-contents - "<?php\nif ($here) {\n if ($wasHere)\n {\n \n }\n}\n\n")))) + "<?php\nif (is_array(\n $array\n)) {\n echo 'was here';\n}" + )))) (phps-mode-test--with-buffer - "<?php\nif ($myCondition)\n{\n $var = array(\n 'was here'\n );\n// Was here\n}\n" - "Alternative indentation on line after array declaration" - (goto-char 71) - (should (equal - (phps-mode-lex-analyzer--alternative-indentation) - 4)) + "<?php\n\n$var = array(\n'123' =>\n'def',\n);" + "Alternative indentation on lines after lines ending with T_DOUBLE_ARROW" (phps-mode-test-lex-analyzer--alternative-indentation-whole-buffer) (let ((buffer-contents (buffer-substring-no-properties (point-min) (point-max)))) (should (equal buffer-contents - "<?php\nif ($myCondition)\n{\n $var = array(\n 'was here'\n );\n // Was here\n}\n" + "<?php\n\n$var = array(\n '123' =>\n 'def',\n);" )))) (phps-mode-test--with-buffer - "<?php\nif ($myCondition == 2) {\n echo 'store_vars: <pre>' . print_r($store_vars, true) . '</pre>';\n echo 'search_ids: <pre>' . print_r($search_ids, true) . '</pre>';\n}" - "Alternative indentation on line echo" - (goto-char 36) - (should (equal - (phps-mode-lex-analyzer--alternative-indentation) - 4)) - (goto-char 106) - (should (equal - (phps-mode-lex-analyzer--alternative-indentation) - 4)) + "<?php\n$var = array(\n'123' => true,\n\n);" + "Alternative indentation after comma ended double arrow assignment" (phps-mode-test-lex-analyzer--alternative-indentation-whole-buffer) (let ((buffer-contents (buffer-substring-no-properties (point-min) (point-max)))) (should (equal buffer-contents - "<?php\nif ($myCondition == 2) {\n echo 'store_vars: <pre>' . print_r($store_vars, true) . '</pre>';\n echo 'search_ids: <pre>' . print_r($search_ids, true) . '</pre>';\n}" + "<?php\n$var = array(\n '123' => true,\n \n);" )))) (phps-mode-test--with-buffer - "<?php\nif (is_array(\n $array\n)) {\n echo 'was here';\n}" - "Alternative indentation after trailing opening bracket while closing two earlier on line" - (goto-char 41) - (should (equal - (phps-mode-lex-analyzer--alternative-indentation) - 4)) + "<?php\nfunction myFunction(\n$arg = true,\n$arg2 = false\n) {\n\n}" + "Line after function argument with default value" (phps-mode-test-lex-analyzer--alternative-indentation-whole-buffer) (let ((buffer-contents (buffer-substring-no-properties (point-min) (point-max)))) (should (equal buffer-contents - "<?php\nif (is_array(\n $array\n)) {\n echo 'was here';\n}" + "<?php\nfunction myFunction(\n $arg = true,\n $arg2 = false\n) {\n \n}" )))) - (phps-mode-test--with-buffer - "<?php\n\n$var = array(\n '123' =>\n 'def',\n);" - "Token-blind indentation on lines after lines ending with T_DOUBLE_ARROW" - (goto-char 43) - (should (equal - (phps-mode-lex-analyzer--alternative-indentation) - 8)) - (goto-char 50) - (should (equal - (phps-mode-lex-analyzer--alternative-indentation) - 0)) +(phps-mode-test--with-buffer + "$random = get_post_meta(\n $postId,\n '_random', // TODO Here\n true // TODO Here\n );" + "Line in multi-line function call" (phps-mode-test-lex-analyzer--alternative-indentation-whole-buffer) (let ((buffer-contents (buffer-substring-no-properties (point-min) (point-max)))) (should (equal buffer-contents - "<?php\n\n$var = array(\n '123' =>\n 'def',\n);" + "$random = get_post_meta(\n $postId,\n '_random', // TODO Here\n true // TODO Here\n);" )))) (phps-mode-test--with-buffer - "<?php\n$var = array(\n '123' => true,\n \n);" - "Line after comma ended double arrow assignment" - (goto-char 44) - (should (equal - (phps-mode-lex-analyzer--alternative-indentation) - 4)) + "$cartPrice = round(\n $cartPrice,\n2 // TODO Here\n);" + "Assignment with multi-line function call" (phps-mode-test-lex-analyzer--alternative-indentation-whole-buffer) (let ((buffer-contents (buffer-substring-no-properties (point-min) (point-max)))) (should (equal buffer-contents - "<?php\n$var = array(\n '123' => true,\n \n);" + "$cartPrice = round(\n $cartPrice,\n 2 // TODO Here\n);" )))) (phps-mode-test--with-buffer - "<?php\nfunction myFunction(\n $arg = true,\n $arg2 = false\n) {\n \n}" - "Line after function argument with default value" - (goto-char 49) - (should (equal - (phps-mode-lex-analyzer--alternative-indentation) - 4)) + "$applications =\n $transaction->getResponseBodyDecoded();\n // TODO Here\n" + "Line after multi-line assignment with object-operator" (phps-mode-test-lex-analyzer--alternative-indentation-whole-buffer) (let ((buffer-contents (buffer-substring-no-properties (point-min) (point-max)))) (should (equal buffer-contents - "<?php\nfunction myFunction(\n $arg = true,\n $arg2 = false\n) {\n \n}" + "$applications =\n $transaction->getResponseBodyDecoded();\n// TODO Here\n" )))) )