|
| 1 | +# Best practices |
| 2 | + |
| 3 | +This page is a working document collecting syntax guidelines and best practices we have discovered so far. |
| 4 | +The goal of this document is to eventually land on a canonical Nushell code style, but as for now it is still work in |
| 5 | +progress and subject to change. We welcome discussion and contributions. |
| 6 | + |
| 7 | +Keep in mind that these guidelines are not required to be used in external repositories (not ours), you can change them in the |
| 8 | +way you want, but please be consistent and follow your rules. |
| 9 | + |
| 10 | +All escape sequences should not be interpreted literally, unless directed to do so. In other words, |
| 11 | +treat something like `\n` like the new line character and not a literal slash followed by `n`. |
| 12 | + |
| 13 | +## Formatting |
| 14 | + |
| 15 | +### Defaults |
| 16 | + |
| 17 | +**It's recommended to** assume that by default no spaces or tabs allowed, but the following rules define where they are allowed. |
| 18 | + |
| 19 | +### Basic |
| 20 | + |
| 21 | +- **It's recommended to** put one space before and after pipe `|` symbol, commands, subcommands, their options and arguments. |
| 22 | +- **It's recommended to** never put several consecutive spaces unless they are part of string. |
| 23 | +- **It's recommended to** omit commas between list items. |
| 24 | + |
| 25 | +Correct: |
| 26 | + |
| 27 | +```nushell |
| 28 | +'Hello, Nushell! This is a gradient.' | ansi gradient --fgstart '0x40c9ff' --fgend '0xe81cff' |
| 29 | +``` |
| 30 | + |
| 31 | +Incorrect: |
| 32 | + |
| 33 | +```nushell |
| 34 | +# - too many spaces after "|": 2 instead of 1 |
| 35 | +'Hello, Nushell! This is a gradient.' | ansi gradient --fgstart '0x40c9ff' --fgend '0xe81cff' |
| 36 | +``` |
| 37 | + |
| 38 | +#### One-line format |
| 39 | + |
| 40 | +One-line format is a format for writing all commands in one line. |
| 41 | + |
| 42 | +**It's recommended to** default to this format: |
| 43 | + |
| 44 | +1. unless you are writing scripts |
| 45 | +2. in scripts for lists and records unless they either: |
| 46 | + 1. more than 80 characters long |
| 47 | + 2. contain nested lists or records |
| 48 | +3. for pipelines less than 80 characters long not containing items should be formatted with |
| 49 | + a long format |
| 50 | + |
| 51 | +Rules: |
| 52 | + |
| 53 | +1. parameters: |
| 54 | + 1. **It's recommended to** put one space after comma `,` after block or closure parameter. |
| 55 | + 2. **It's recommended to** put one space after pipe `|` symbol denoting block or closure parameter list end. |
| 56 | +2. block and closure bodies: |
| 57 | + 1. **It's recommended to** put one space after opening block or closure curly brace `{` if no explicit parameters defined. |
| 58 | + 2. **It's recommended to** put one space before closing block or closure curly brace `}`. |
| 59 | +3. records: |
| 60 | + 1. **It's recommended to** put one space after `:` after record key. |
| 61 | + 2. **It's recommended to** put one space after comma `,` after key value. |
| 62 | +4. lists: |
| 63 | + 1. **It's recommended to** put one space after comma `,` after list value. |
| 64 | +5. surrounding constructs: |
| 65 | + 1. **It's recommended to** put one space before opening square `[`, curly brace `{`, or parenthesis `(` if preceding symbol is not the same. |
| 66 | + 2. **It's recommended to** put one space after closing square `]`, curly brace `}`, or parenthesis `)` if following symbol is not the same. |
| 67 | + |
| 68 | +Correct: |
| 69 | + |
| 70 | +```nushell |
| 71 | +[[status]; [UP] [UP]] | all {|el| $el.status == UP } |
| 72 | +[1 2 3 4] | reduce {|it, acc| $it + $acc } |
| 73 | +[1 2 3 4] | reduce {|it acc| $it + $acc } |
| 74 | +{x: 1, y: 2} |
| 75 | +{x: 1 y: 2} |
| 76 | +[1 2] | zip [3 4] |
| 77 | +[] |
| 78 | +(1 + 2) * 3 |
| 79 | +``` |
| 80 | + |
| 81 | +Incorrect: |
| 82 | + |
| 83 | +```nushell |
| 84 | +# too many spaces before "|el|": no space is allowed |
| 85 | +[[status]; [UP] [UP]] | all { |el| $el.status == UP } |
| 86 | +
|
| 87 | +# too many spaces before ",": no space is allowed |
| 88 | +[1 2 3 4] | reduce {|it , acc| $it + $acc } |
| 89 | +
|
| 90 | +# too many spaces before "x": no space is allowed |
| 91 | +{ x: 1, y: 2} |
| 92 | +
|
| 93 | +# too many spaces before "[3": one space is required |
| 94 | +[1 2] | zip [3 4] |
| 95 | +
|
| 96 | +# too many spaces before "]": no space is allowed |
| 97 | +[ ] |
| 98 | +
|
| 99 | +# too many spaces before ")": no space is allowed |
| 100 | +(1 + 2 ) * 3 |
| 101 | +``` |
| 102 | + |
| 103 | +#### Multi-line format |
| 104 | + |
| 105 | +Multi-line format is a format for writing all commands in several lines. It inherits all rules from one-line format |
| 106 | +and modifies them slightly. |
| 107 | + |
| 108 | +**It's recommended to** default to this format: |
| 109 | + |
| 110 | +1. while you are writing scripts |
| 111 | +2. in scripts for lists and records while they either: |
| 112 | + 1. more than 80 characters long |
| 113 | + 2. contain nested lists or records |
| 114 | +3. for pipelines more 80 characters long |
| 115 | + |
| 116 | +Rules: |
| 117 | + |
| 118 | +1. general: |
| 119 | + 1. **It's required to omit** trailing spaces. |
| 120 | +2. block and closure bodies: |
| 121 | + 1. **It's recommended to** put each body pipeline on a separate line. |
| 122 | +3. records: |
| 123 | + 1. **It's recommended to** put each record key-value pair on separate line. |
| 124 | +4. lists: |
| 125 | + 1. **It's recommended to** put each list item on separate line. |
| 126 | +5. surrounding constructs: |
| 127 | + 1. **It's recommended to** put one `\n` before opening square `[`, curly brace `{`, or parenthesis `(` if preceding symbol is not the and applying this rule produce line with a singular parenthesis. |
| 128 | + 2. **It's recommended to** put one `\n` after closing square `]`, curly brace `}`, or parenthesis `)` if following symbol is not the same and applying this rule produce line with a singular parenthesis. |
| 129 | + |
| 130 | +Correct: |
| 131 | + |
| 132 | +```nushell |
| 133 | +[[status]; [UP] [UP]] | all {|el| |
| 134 | + $el.status == UP |
| 135 | +} |
| 136 | +
|
| 137 | +[1 2 3 4] | reduce {|it, acc| |
| 138 | + $it + $acc |
| 139 | +} |
| 140 | +
|
| 141 | +{x: 1, y: 2} |
| 142 | +
|
| 143 | +[ |
| 144 | + {name: "Teresa", age: 24}, |
| 145 | + {name: "Thomas", age: 26} |
| 146 | +] |
| 147 | +
|
| 148 | +let selectedProfile = (for it in ($credentials | transpose name credentials) { |
| 149 | + echo $it.name |
| 150 | +}) |
| 151 | +``` |
| 152 | + |
| 153 | +Incorrect: |
| 154 | + |
| 155 | +```nushell |
| 156 | +# too many spaces before "|el|": no space is allowed (like in one-line format) |
| 157 | +[[status]; [UP] [UP]] | all { |el| |
| 158 | + # too few "\n" before "}": one "\n" is required |
| 159 | + $el.status == UP} |
| 160 | +
|
| 161 | +# too many spaces before "2": one space is required (like in one-line format) |
| 162 | +[1 2 3 4] | reduce {|it, acc| |
| 163 | + $it + $acc |
| 164 | +} |
| 165 | +
|
| 166 | +{ |
| 167 | + # too many "\n" before "x": one-line format required as no nested lists or record exist |
| 168 | + x: 1, |
| 169 | + y: 2 |
| 170 | +} |
| 171 | +
|
| 172 | +# too few "\n" before "{": multi-line format required as there are two nested records |
| 173 | +[{name: "Teresa", age: 24}, |
| 174 | + {name: "Thomas", age: 26}] |
| 175 | +
|
| 176 | +let selectedProfile = ( |
| 177 | + # too many "\n" before "foo": no "\n" is allowed |
| 178 | + for it in ($credentials | transpose name credentials) { |
| 179 | + echo $it.name |
| 180 | +}) |
| 181 | +``` |
| 182 | + |
| 183 | +## Options and parameters of custom commands |
| 184 | + |
| 185 | +- **It's recommended to** keep count of all positional parameters less than or equal to 2, for remaining inputs use options. Assume that command can expect source and destination parameter, like `mv`: source and target file or directory. |
| 186 | +- **It's recommended to** use positional parameters unless they can't be used due to rules listed here or technical restrictions. |
| 187 | + For instance, when there are several kinds of optional parameters (but at least one parameter should be provided) |
| 188 | + use options. Great example of this is `ansi gradient` command where at least foreground or background must be passed. |
| 189 | +- **It's recommended to** provide both long and short options. |
| 190 | + |
| 191 | +## Documentation |
| 192 | + |
| 193 | +- **It's recommended to** provide documentation for all exported entities (like custom commands) and their |
| 194 | + inputs (like custom command parameters and options). |
0 commit comments