[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[nongnu] elpa/typescript-mode e25c7ddb8a 062/222: Fix indentation of fun
From: |
ELPA Syncer |
Subject: |
[nongnu] elpa/typescript-mode e25c7ddb8a 062/222: Fix indentation of funcs with return annotations. |
Date: |
Sun, 6 Feb 2022 16:59:16 -0500 (EST) |
branch: elpa/typescript-mode
commit e25c7ddb8a6418c7cf9d596d8cb4ab51d1b2b2ef
Author: Louis-Dominique Dubeau <ldd@lddubeau.com>
Commit: Louis-Dominique Dubeau <ldd@lddubeau.com>
Fix indentation of funcs with return annotations.
---
test-files/indentation-reference-document.ts | 207 +++++++++++++++++++++++++++
typescript-mode.el | 147 ++++++++++++++++++-
2 files changed, 352 insertions(+), 2 deletions(-)
diff --git a/test-files/indentation-reference-document.ts
b/test-files/indentation-reference-document.ts
index da1dd7d80c..7a6ee48680 100644
--- a/test-files/indentation-reference-document.ts
+++ b/test-files/indentation-reference-document.ts
@@ -50,6 +50,8 @@ namespace ts.server {
pid: number;
}
+ export type SomeType = string | number;
+
class Logger implements ts.server.Logger {
private firstInGroup = true;
@@ -237,3 +239,208 @@ namespace ts.server {
/def/);
}
}
+
+// Tests for return value annotations.
+
+// Unannotated.
+function moo(x: any,
+ f: string) {
+ return null;
+}
+
+// Parens around return type.
+function foo(x: any,
+ f: string): ((a: number) => void) {
+ return null;
+}
+
+class Moo {}
+
+// Type guard.
+function foo2(x: any,
+ f: string): x is Moo {
+ return x.something === 1;
+}
+
+// Usage of generic in return type.
+function foo3(a: number,
+ b: number): Array<Array<(a: number) => void>> {
+ return [];
+}
+
+// Curly brackets in return type.
+function bar(a: number,
+ b: number): { z(): string } {
+ return {
+ z() { return "a"; }
+ };
+}
+
+// The sequence ): in the return type.
+function bif(a: number,
+ b: number): "abc):d" {
+ return "abc):d";
+}
+
+// Comment where the return type would appear.
+function gogo(a: number,
+ b: number) /* foo */ {
+}
+
+// Function call in the list of arguments.
+function foo5(x: any,
+ f: string = bif(1, 2)): ((a: number) => void) {
+ return null;
+}
+
+// Dotted name in return type.
+function foo6(x: any,
+ f: number): ts.server.SomeType {
+ return "string";
+}
+
+// First parameter has function signature.
+function foo7(x: (a: string, b: string) => Array<number>,
+ b: number): void {
+}
+
+// Second parameter has function signature.
+function foo7b(a: string,
+ x: (a: number, b: number) => Array<number>): void {
+}
+
+function foo8(): void {
+ // Arrow function in first parameter.
+ foo7((a: string): Array<number> => {
+ return [1];
+ },
+ 1);
+
+ // Arrow function in first parameter, line break in parameters.
+ foo7((a: string,
+ b: string): Array<number> => {
+ return [1];
+ },
+ 1);
+
+ // Arrow function in second parameter.
+ foo7b("1",
+ (a: number, b: number): Array<number> => {
+ return [1];
+ });
+
+ // Arrow function in second parameter, line break in parameters.
+ foo7b("1",
+ (a: number,
+ b: number): Array<number> => {
+ return [1];
+ });
+}
+
+// Arrow function assignment, line break in parameters.
+const foo9 = (a: string,
+ b: string): Array<number> => {
+ return [1];
+}
+
+// Arrow function assignment.
+const foo10 = (a: string, b: string): Array<number> => {
+ return [1];
+}
+
+// Arrow function assignment, parenthesized.
+const foo11 = ((a: string, b: string): Array<number> => {
+ return [1];
+ });
+
+function foo12(): void {
+ // Function in first parameter.
+ foo7(function (a: string): Array<number> {
+ return [1];
+ },
+ 1);
+
+ // Function in first parameter, line break in parameters.
+ foo7(function (a: string,
+ b: string): Array<number> {
+ return [1];
+ },
+ 1);
+
+ // Arrow function in second parameter.
+ foo7b("1",
+ function (a: number, b: number): Array<number> {
+ return [1];
+ });
+
+ // Arrow function in second parameter, line break in parameters.
+ foo7b("1",
+ function (a: number,
+ b: number): Array<number> {
+ return [1];
+ });
+
+ // Same cases as above but named.
+
+ // Function in first parameter.
+ foo7(function _mip(a: string): Array<number> {
+ return [1];
+ },
+ 1);
+
+ // Function in first parameter, line break in parameters.
+ foo7(function _mip(a: string,
+ b: string): Array<number> {
+ return [1];
+ },
+ 1);
+
+ // Arrow function in second parameter.
+ foo7b("1",
+ function _mip(a: number, b: number): Array<number> {
+ return [1];
+ });
+
+ // Arrow function in second parameter, line break in parameters.
+ foo7b("1",
+ function _mip(a: number,
+ b: number): Array<number> {
+ return [1];
+ });
+
+ // Same cases as above but generators.
+
+ // Function in first parameter.
+ foo7(function *(a: string): Array<number> {
+ return [1];
+ },
+ 1);
+
+ // Function in first parameter, line break in parameters.
+ foo7(function *(a: string,
+ b: string): Array<number> {
+ return [1];
+ },
+ 1);
+
+ // Arrow function in second parameter.
+ foo7b("1",
+ function *(a: number, b: number): Array<number> {
+ return [1];
+ });
+
+ // Arrow function in second parameter, line break in parameters.
+ foo7b("1",
+ function *(a: number,
+ b: number): Array<number> {
+ return [1];
+ });
+
+ // Check that JavaScript objects are still handled right. Whether
+ // in the 1st or subsequent position of a call.
+ function smurf(a: {}, b: {}) {}
+ smurf({
+ },
+ {
+ });
+}
diff --git a/typescript-mode.el b/typescript-mode.el
index 8baad489d3..e69a3db45b 100644
--- a/typescript-mode.el
+++ b/typescript-mode.el
@@ -1759,6 +1759,140 @@ nil."
(list (cons 'c typescript-comment-lineup-func))))
(c-get-syntactic-indentation (list (cons symbol anchor)))))
+(defun typescript--backward-over-generic-parameter-list ()
+ "Search backward for the start of a generic's parameter list and move to it.
+
+This is a utility function for
+`typescript--backward-to-parameter-list'.
+
+This function must be called with the point placed on the final >
+of the generic's parameter list. It will scan backwards to find
+the start. If successful, it will move the point to the start of
+the list. If not, it does not move the point.
+
+Returns nil on failure, or the position to which the point was
+moved on success."
+ (when (eq (char-after) ?>)
+ (let ((depth 1))
+ (loop named search-loop
+ while (> depth 0)
+ do (progn
+ (unless (re-search-backward "[<>]" nil t)
+ (cl-return-from search-loop nil))
+ (cond
+ ((looking-at ">")
+ (unless (eq (char-before) ?=)
+ (setq depth (1+ depth))))
+ ((looking-at "<") (setq depth (1- depth)))))
+ finally return (point)))))
+
+(defun typescript--backward-to-parameter-list ()
+ "Search backward for the end of a parameter list and move to it.
+
+This is a utility function for `typescript--proper-indentation'.
+
+This function must be called with the point placed before an
+opening curly brace. It will try to skip over the type
+annotation that would mark the return value of a function and
+move to the end of the parameter list. If it is unsuccessful, it
+does not move the point. \"Unsuccessful\" here also means that
+the position at which we started did not in fact mark the
+beginning of a function. The curly brace belonged to some other
+syntactic construct than a function.
+
+Returns nil on failure, or the position to which the point was
+moved on success."
+ (let ((location
+ (or
+ ;; This handles the case of a function with return type annotation.
+ (save-excursion
+ (loop named search-loop
+ do (progn
+ (if (eq (char-before) ?>)
+ (if (looking-back "=>" (- (point) 2))
+ ;; Move back over the arrow of an arrow
function.
+ (backward-char 2)
+ ;; Otherwise, we are looking at the end of the
parameters
+ ;; list of a generic. We need to move back over
the list.
+ (backward-char)
+
(typescript--backward-over-generic-parameter-list))
+ ;; General case: we just move back over the current
sexp.
+ (condition-case nil
+ (backward-sexp)
+ (scan-error nil)))
+ (typescript--backward-syntactic-ws)
+ (let ((before (char-before)))
+ ;; Check whether we are at "):".
+ (when (and (eq before ?\:)
+ (progn
+ (backward-char)
+ (skip-syntax-backward " ")
+ (eq (char-before) ?\))))
+ ;; Success! This the end of the parameter list.
+ (cl-return-from search-loop (point)))
+ ;; All the following cases are constructs that are
allowed to
+ ;; appear between the opening brace of a function and
the
+ ;; end of a parameter list.
+ (unless
+ (or
+ ;; End of a generic.
+ (eq before ?>)
+ ;; Union of types
+ (eq before ?|)
+ ;; Dotted names
+ (eq before ?.)
+ ;; Typeguard (eg. foo is SomeClass)
+ (looking-back "is" (- (point) 2))
+ ;; This is also dealing with dotted names. This
may come
+ ;; into play if a jump back moves over an entire
dotted
+ ;; name at once.
+ ;;
+ ;; The earlier test for dotted names comes into
play if the
+ ;; logic moves over one part of a dotted name at
a time (which
+ ;; is what `backward-sexp` normally does).
+ (looking-back typescript--dotted-name-re nil)
+ )
+ ;; We did not encounter a valid construct, so
+ ;; the search is unsuccessful.
+ (cl-return-from search-loop nil))))))
+ ;; This handles the case of a function without return type
annotation.
+ (progn
+ (typescript--backward-syntactic-ws)
+ (when (eq (char-before) ?\))
+ (point))))))
+ (when location
+ (goto-char location))))
+
+(defun typescript--backward-to-function-start ()
+ "Search backward for the start of a function and move to it.
+
+This function moves the point to the start of the function and
+returns the point.
+
+The point must already be at the start of the parameter list.
+See `typescript--backward-to-parameter-list' for a function that
+does this. If the point is not at the start of the parameter
+list, this function may return an incorrect result."
+ (goto-char
+ (or (condition-case nil
+ (save-excursion
+ (skip-syntax-backward " ")
+ (backward-sexp)
+ ;; First, check for an anonymous function.
+ (or (when (looking-at "function")
+ (point))
+ ;; Otherwise check if we have a named function.
+ (progn
+ (skip-syntax-backward " ")
+ (backward-sexp)
+ (when (looking-at "function")
+ (point)))))
+ ;; backward-sexp may cause a scan-error if the sexp is
+ ;; incomplete.
+ (scan-error nil))
+ ;; If we get here, what we are looking at is an arrow function.
+ (point))))
+
(defun typescript--proper-indentation (parse-status)
"Return the proper indentation for the current line."
(save-excursion
@@ -1777,8 +1911,17 @@ nil."
(if (looking-at "[({[]\\s-*\\(/[/*]\\|$\\)")
(progn
(skip-syntax-backward " ")
- (when (eq (char-before) ?\)) (backward-list))
- (back-to-indentation)
+ (when (or (typescript--backward-to-parameter-list)
+ (eq (char-before) ?\)))
+ (backward-list))
+ ;; If the parameter list is preceded by (, take the
+ ;; start of the parameter list as our reference.
+ ;; This allows handling functions in parameter
+ ;; lists. Otherwise, we want to go back to the
+ ;; start of function declaration.
+ (when (not (and (typescript--backward-to-function-start)
+ (eq (char-before) ?\()))
+ (back-to-indentation))
(cond (same-indent-p
(current-column))
(continued-expr-p
- [nongnu] elpa/typescript-mode d81cc72782 013/222: Merge pull request #7 from paulkoerbitz/patch-1, (continued)
- [nongnu] elpa/typescript-mode d81cc72782 013/222: Merge pull request #7 from paulkoerbitz/patch-1, ELPA Syncer, 2022/02/06
- [nongnu] elpa/typescript-mode a532ef57cf 046/222: Merge pull request #29 from lddubeau/fix/method-generator, ELPA Syncer, 2022/02/06
- [nongnu] elpa/typescript-mode c1a7d40dd8 005/222: highlight template string, ELPA Syncer, 2022/02/06
- [nongnu] elpa/typescript-mode 8fe879a96d 028/222: Support 'of' keyword., ELPA Syncer, 2022/02/06
- [nongnu] elpa/typescript-mode ca510ab853 048/222: Merge pull request #30 from lddubeau/fix/keyword-members, ELPA Syncer, 2022/02/06
- [nongnu] elpa/typescript-mode a2c2ff03e7 024/222: Add support for compilation-mode., ELPA Syncer, 2022/02/06
- [nongnu] elpa/typescript-mode 7526f138a0 032/222: Avoid capturing things we dont need for compilation-mode., ELPA Syncer, 2022/02/06
- [nongnu] elpa/typescript-mode 666052f09f 033/222: Update readme., ELPA Syncer, 2022/02/06
- [nongnu] elpa/typescript-mode 4235b47a38 060/222: Fix indent for lines which starts with tabs., ELPA Syncer, 2022/02/06
- [nongnu] elpa/typescript-mode 52c08d0628 091/222: Add more fontification tests for regular expressions., ELPA Syncer, 2022/02/06
- [nongnu] elpa/typescript-mode e25c7ddb8a 062/222: Fix indentation of funcs with return annotations.,
ELPA Syncer <=
- [nongnu] elpa/typescript-mode 536e4da380 087/222: Fix bug with hanling array shorthand in return value types., ELPA Syncer, 2022/02/06
- [nongnu] elpa/typescript-mode 70acbf9c3d 078/222: Change font-lock-test to also accept a list of locations, ELPA Syncer, 2022/02/06
- [nongnu] elpa/typescript-mode a2167a133d 056/222: Fix errors with indentation when line has wide unicode chars., ELPA Syncer, 2022/02/06
- [nongnu] elpa/typescript-mode 09bdb97c32 065/222: Fix an indentation bug., ELPA Syncer, 2022/02/06
- [nongnu] elpa/typescript-mode 8b2815514d 088/222: Simplify typescript--backward-to-parameter-list, ELPA Syncer, 2022/02/06
- [nongnu] elpa/typescript-mode f9cd0dd539 112/222: Try parse new error-format introduced in tsc 2.7+, ELPA Syncer, 2022/02/06
- [nongnu] elpa/typescript-mode a1cdb7a1ec 121/222: Remove redundant regexp groups for jsdoc tags, ELPA Syncer, 2022/02/06
- [nongnu] elpa/typescript-mode fd1c9daa4d 094/222: Add failing cases., ELPA Syncer, 2022/02/06
- [nongnu] elpa/typescript-mode bd046e0fae 120/222: Add tags in usejsdoc.org, ELPA Syncer, 2022/02/06
- [nongnu] elpa/typescript-mode 3c79132066 136/222: fix warnings from package-lint, ELPA Syncer, 2022/02/06