Skip to content

Add custom var for allowing additional indent in function parameter lists #42

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 4 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
243 changes: 243 additions & 0 deletions test-files/custom-indentation-reference-document.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,243 @@
/// <reference types="node" />
/// <reference path="shared.ts" />
/// <reference path="session.ts" />
// used in fs.writeSync
/* tslint:disable:no-null-keyword */

/*
* this file is a butchered copy of TypeScript's tsserver.ts file
* made to contain the most important syntactical elements
* of TypeScript to verify indentation-code.
* It is indented with
* typescript-indent-level 2
* typescript-expr-indent-offset 2
* typescript-fn-parameter-indent-offset 2
*
* It will not build, and that's NOT a problem!
*/

// namespaces indent.
namespace ts.server {

const net: {
connect(options: { port: number }, onConnect?: () => void): NodeSocket
} = require("net");

// functions indent.
function getGlobalTypingsCacheLocation() {
// We know switch/case is indented incorrectly.
// TODO: FIX!

// switch (process.platform) {
// case "win32": {
// const basePath = process.env.LOCALAPPDATA ||
// process.env.APPDATA;
// return combinePaths(normalizeSlashes(basePath), "Microsoft/TypeScript");
// }
// case "darwin":
// case "linux":
// case "android": {
// const cacheLocation = getNonWindowsCacheLocation(process.platform === "darwin");
// return combinePaths(cacheLocation, "typescript");
// }
// default:
// Debug.fail(`unsupported platform '${process.platform}'`);
// return;
// }
}

// interfaces and classes indent.
interface NodeChildProcess {
send(message: any, sendHandle?: any): void;
on(message: "message" | "exit", f: (m: any) => void): void;
kill(): void;
pid: number;
}

class Logger implements ts.server.Logger {
private firstInGroup = true;

// parameter-lists are currently not indented like tsserver wants it to...
// constructor(private readonly logFilename: string,
// private readonly traceToConsole: boolean,
// private readonly level: LogLevel) {
// }

// function-typed class-members indent.
constructor(private readonly logFilename: string) {
console.log("yes");
}

static padStringRight(str: string, padding: string) {
return (str + padding).slice(0, padding.length);
}

close() {
if (this.fd >= 0) {
fs.close(this.fd);
}
}
}

// object initialization/parameter-lists indent.
const ioSession = new IOSession(
sys,
cancellationToken,
eventPort,
/*canUseEvents*/ eventPort === undefined,
useSingleInferredProject,
disableAutomaticTypingAcquisition,
getGlobalTypingsCacheLocation(),
telemetryEnabled,
logger);
process.on("uncaughtException", function (err: Error) {
ioSession.logError(err, "unknown");
});

// Generators as methods.
class WithAGeneratorFirst {
*blah() {
}
}

class WithAGeneratorAfterAProperty {
public foo: string = "1";

*blah() {
}
}

class WithAGeneratorAfterAnotherMethod {
foo() {
}

*blah() {
}
}

class WithSpaceAfterAsterisk {
bar() {
}

* oops() {
}
}


class WithSpaceAfterParens {
bar() {
}

*oops () {
}
}

class WithArguments {
bar() {
}

*oops(foo: number, bar: string) {
}
}

// Some continued expressions
{
const a = 1 *
2 /
3 +
4 -
5 %
6;

const b = 1 >
2;

const c = 1 <
2;

const d = 1 &
2 |
3;

const e = b ?
2 :
3;

const f = window
.document;

const g = f
instanceof Object;

const h = "q"
in [1, 2];

}

{
// Object with fields that are keyword names.
const a = {
in: 1,
IN: 1,
instanceof: 1,
instanceOf: 1,
};

// Objects with methods that are keyword names. At the top of
// the object declaration, and after a function declaration.
class One {
instanceOf(): void {
}

in(): void {}
}

// After a field declaration.
class Two {
foo: boolean = true;

instanceOf(): void {
}
}
}

// Spread syntax
{
const a = { a: 1, b: 2 };
const b = {
...a,
a: 3,
};
const c = [1, 2];
const d = [
"a",
...c
];

function foo(a: string,
b: number,
...rest: any[]) {
}
}

{
// Regular expressions in lists.

// List objects...
const a = [
/abc/,
/def/
];

const z =
/abcd/;

// Argument lists...
function foo(a: RegExp, b: RegExp): void {
}

foo(
/abc/,
/def/);
}
}
13 changes: 11 additions & 2 deletions typescript-mode-tests.el
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@
(indent-region (point-min) (point-max) nil)
(untabify (point-min) (point-max)))

(ert-deftest indentation-reference-document-is-reflowed-correctly ()
(let* ((buffer (find-file "test-files/indentation-reference-document.ts")))
(defun typescript-test-reference-document-is-reflowed-correctly (filename)
(let* ((buffer (find-file filename)))
;; double ensure mode is active
(typescript-mode)

Expand All @@ -29,6 +29,15 @@

(kill-buffer buffer)))

(ert-deftest indentation-reference-document-is-reflowed-correctly ()
(typescript-test-reference-document-is-reflowed-correctly "test-files/indentation-reference-document.ts"))

(ert-deftest indentation-custom-reference-document-is-reflowed-correctly ()
(let ((typescript-indent-level 2)
(typescript-expr-indent-offset 2)
(typescript-fn-parameter-indent-offset 2))
(typescript-test-reference-document-is-reflowed-correctly "test-files/custom-indentation-reference-document.ts")))

(defun get-all-matched-strings (to-match)
(let (result)
(dotimes (x (/ (length (match-data)) 2))
Expand Down
23 changes: 19 additions & 4 deletions typescript-mode.el
Original file line number Diff line number Diff line change
Expand Up @@ -432,6 +432,13 @@ The value must be no less than minus `typescript-indent-level'."
:type 'integer
:group 'typescript)

(defcustom typescript-fn-parameter-indent-offset 0
"Number of additional spaces used for indentation of continued lines in
function parameter lists (including both calls and declarations).
The value must be no less than minus `typescript-indent-level'."
:type 'integer
:group 'typescript)

(defcustom typescript-auto-indent-flag t
"Whether to automatically indent when typing punctuation characters.
If non-nil, the characters {}();,: also indent the current line
Expand Down Expand Up @@ -1774,22 +1781,30 @@ nil."
"[]})]\\|\\_<case\\_>\\|\\_<default\\_>"))
(continued-expr-p (typescript--continued-expression-p)))
(goto-char (nth 1 parse-status))
(if (looking-at "[({[]\\s-*\\(/[/*]\\|$\\)")
(progn
(skip-syntax-backward " ")
(let* ((looking-at-list-opener-p
(looking-at "[({[]\\s-*\\(/[/*]\\|$\\)"))
(looking-at-fn-param-list-opener-p
(and looking-at-list-opener-p (looking-at "("))))
(if looking-at-list-opener-p
(progn
(skip-syntax-backward " ")
(when (eq (char-before) ?\)) (backward-list))
(back-to-indentation)
(cond (same-indent-p
(current-column))
(continued-expr-p
(+ (current-column) (* 2 typescript-indent-level)
typescript-expr-indent-offset))
(looking-at-fn-param-list-opener-p
(+ (current-column)
typescript-indent-level
typescript-fn-parameter-indent-offset))
(t
(+ (current-column) typescript-indent-level))))
(unless same-indent-p
(forward-char)
(skip-chars-forward " \t"))
(current-column))))
(current-column)))))

((typescript--continued-expression-p)
(+ typescript-indent-level typescript-expr-indent-offset))
Expand Down