diff --git a/README.md b/README.md index 4cc6ba8..7e3d6e5 100644 --- a/README.md +++ b/README.md @@ -27,7 +27,9 @@ This extension contributes the following settings: * `php-docblocker.returnVoid`: set to `false` to turn off the automatic void return type when it can't be determined * `php-docblocker.extra`: an array of extra tags to add to each DocBlock (These can include tabstops and snippet variables) * `php-docblocker.useShortNames`: Whether we should use short type names. e.g. bool or boolean -* `php-docblocker.qualifyClassNames`: When adding type hints for class names search namespace use statements and qualify the class +* `php-docblocker.qualifyClassNames`: When adding type hints for class names search namespace use statements and qualify the class +* `php-docblocker.alignParams`: set to `true` to align params vertically and add appropriate spaces after param names +* `php-docblocker.alignReturn`: set to `true` to align return vertically with above params statements, this setting requires align params to also be active * `php-docblocker.author`: An object containing your default author tag settings * `php-docblocker.functionTemplate`: See below for how to set up docblock templates * `php-docblocker.propertyTemplate`: See below for how to set up docblock templates @@ -74,7 +76,7 @@ config option per key to add additional control. #### Configured function template example -In the example below we have added some gap configuration and removed the return tag for our template as well as +In the example below we have added some gap configuration and removed the return tag for our template as well as changing the default order. This means we'll never have a @return tag and extra comes before the params. It's also worth pointing out that the gapAfter in the message is the same as setting the gap config option in the main config to true. @@ -93,8 +95,8 @@ to true. #### Configured function with extra content and placeholders -The example below won't have a return tag and will add in an author tag with correct placeholders depending on -how many options you have. You can put in placeholders by using `###` in place of the tab stop number and it +The example below won't have a return tag and will add in an author tag with correct placeholders depending on +how many options you have. You can put in placeholders by using `###` in place of the tab stop number and it will be calculated at generation time. ```json diff --git a/package-lock.json b/package-lock.json index 81ff3ef..6e08e79 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "php-docblocker", - "version": "2.0.1", + "version": "2.1.0", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/package.json b/package.json index 1a0ba3b..c4a4193 100644 --- a/package.json +++ b/package.json @@ -71,6 +71,16 @@ "default": false, "description": "Fully qualifies any data types used in param and returns by reading the namespaces." }, + "php-docblocker.alignParams": { + "type": "boolean", + "default": false, + "description": "Vertically aligns param types and names with additional spaces." + }, + "php-docblocker.alignReturn": { + "type": "boolean", + "default": false, + "description": "Vertically aligns return with above param statements." + }, "php-docblocker.functionTemplate": { "type": "object", "default": null, diff --git a/src/doc.ts b/src/doc.ts index 3f90087..62dba17 100644 --- a/src/doc.ts +++ b/src/doc.ts @@ -89,6 +89,9 @@ export class Doc let extra = Config.instance.get('extra'); let gap = Config.instance.get('gap'); let returnGap = Config.instance.get('returnGap'); + let alignParams = Config.instance.get('alignParams'); + // Align return is false if align params is not active. + let alignReturn = alignParams ? Config.instance.get('alignReturn') : false; let returnString = ""; let varString = ""; @@ -103,13 +106,54 @@ export class Doc messageString = "\${###" + (this.message != "" ? ':' : '') + this.message + "}"; + // Loop through params and find max length of type and name. + let maxParamTypeLength = 0; + let maxParamNameLength = 0; + if (this.params.length && alignParams) { + this.params.forEach(param => { + let paramType = param.type; + if (paramType.length > maxParamTypeLength) { + maxParamTypeLength = paramType.length; + } + let paramName = param.name.replace('$', '\\$') + if (paramName.length > maxParamNameLength) { + maxParamNameLength = paramName.length; + } + }); + } + // If align return is active, check if it has a longer type. + if (this.return && (this.return != 'void' || Config.instance.get('returnVoid')) && alignReturn) { + let returnType = this.return; + if (returnType.length > maxParamTypeLength) { + maxParamTypeLength = returnType.length; + } + } + if (this.params.length) { paramString = ""; this.params.forEach(param => { if (paramString != "") { paramString += "\n"; } - paramString += "@param \${###:"+param.type+"} " + param.name.replace('$', '\\$'); + + let paramType = param.type; + let paramName = param.name.replace('$', '\\$'); + + let prependSpace = ''; + let appendSpace = ''; + if (alignParams) { + // Append additional spaces on param type and param name. + prependSpace = Array(maxParamTypeLength - paramType.length).fill(' ').join(''); + // Add 1 to array size, so there is already a space appended for typing comments. + appendSpace = Array(1 + maxParamNameLength - paramName.length).fill(' ').join(''); + } + + paramString += + "@param " + + // Add extra space to align '@param' and '@return'. + (alignReturn ? ' ' : '') + + "\${###:"+paramType+"} " + + prependSpace + paramName + appendSpace; }); } @@ -118,7 +162,11 @@ export class Doc } if (this.return && (this.return != 'void' || Config.instance.get('returnVoid'))) { - returnString = "@return \${###:" +this.return + "}"; + let appendSpace = ''; + if (alignReturn) { + appendSpace = Array(1 + maxParamNameLength).fill(' ').join(''); + } + returnString = "@return \${###:" +this.return + "}" + appendSpace; } if (Array.isArray(extra) && extra.length > 0) { diff --git a/test/fixtures/doc.json b/test/fixtures/doc.json index a7b45e5..a91a836 100644 --- a/test/fixtures/doc.json +++ b/test/fixtures/doc.json @@ -325,5 +325,96 @@ " * @param ${4:int} \\$name", " */" ] + }, + { + "name": "Align params", + "config": { + "gap": true, + "alignParams": true + }, + "input": { + "message": "Undocumented function", + "params": [ + { + "name": "$nameLong", + "type": "int" + }, + { + "name": "$name", + "type": "string" + } + ], + "return": "LongClassName" + }, + "expected": [ + "/**", + " * ${1:Undocumented function}", + " *", + " * @param ${2:int} \\$nameLong ", + " * @param ${3:string} \\$name ", + " * @return ${4:LongClassName}", + " */" + ] + }, + { + "name": "Align params without return statement", + "config": { + "gap": true, + "alignParams": true, + "returnVoid": false + }, + "input": { + "message": "Undocumented function", + "params": [ + { + "name": "$nameLong", + "type": "int" + }, + { + "name": "$name", + "type": "string" + } + ], + "return": "void" + }, + "expected": [ + "/**", + " * ${1:Undocumented function}", + " *", + " * @param ${2:int} \\$nameLong ", + " * @param ${3:string} \\$name ", + " */" + ] + }, + { + "name": "Align params and return statement", + "config": { + "gap": true, + "alignParams": true, + "alignReturn": true + }, + "input": { + "message": "Undocumented function", + "params": [ + { + "name": "$nameLong", + "type": "int" + }, + { + "name": "$name", + "type": "string" + } + ], + "return": "LongClassName" + }, + "expected": [ + "/**", + " * ${1:Undocumented function}", + " *", + " * @param ${2:int} \\$nameLong ", + " * @param ${3:string} \\$name ", + " * @return ${4:LongClassName} ", + " */" + ] } ]