Zsh Development Guide (Part 20 code style)

Time:2021-10-22

Reading guide

Because the shell script syntax is relatively flexible, and the programming languages familiar to the developers who write shell scripts are also quite different, it is easy for everyone to write code with different styles. It’s ok if you only use it by yourself. If you cooperate to develop the same project, different code styles will cause no small trouble. Therefore, it is necessary to agree on a code style.

The code style conventions in this article are just my personal suggestions, which can be adjusted according to your needs or likes. The code style conventions in this article are also applicable to bash to a certain extent.

Note that people with rich shell programming experience are required to formulate and maintain code style conventions, otherwise it is easy to be unable to execute or become a mere formality and can not solve practical problems. The code style agreement not only needs to agree on how to write the code, but also explain why to write it, otherwise it is easy to be difficult to convince the public and cannot be popularized.

indent

  • Use 4 spaces to indent uniformly.

reason:

  1. Use spaces instead of tabs. Because on the terminalcat less diffSome commands are not configurable (even if configurable, it is troublesome to synchronize the configuration of all machines). If you configure the tab to 4 or 2 spaces in the editor, it will be associated withcat lessThe display methods of such commands are inconsistent, which will lead to a lot of trouble.
  2. If the 8 spaces are too long, indenting several times will lead to too long lines, and each line of shell script should not be too long.
  3. 2 spaces, if indented more frequently, it seems more laborious. In addition, if you write code carelessly with more or less than one space, in some scenarios, if you don’t look at the logic, you can’t determine whether it is more or less, which is more likely to lead to wrong modifications by others, or the more the code is changed, the more chaotic it is.
  4. For the problem that four spaces may also lead to too long lines when the number of indented layers is too many, it can be solved by modifying the logic to reduce the number of indented layers or line folding, rather than reducing the number of indented spaces.

Maximum characters per line of code

  • For non special scenarios, each line of code shall not exceed 100 characters.

reason:

  1. The code is too long. It’s inconvenient to read. It’s easy to usediffIt is also inconvenient for tools such as to analyze and process the code, so it is necessary to agree on the maximum number of characters.
  2. The classic 80 character agreement is a standard limited by the output equipment at that time, but now the screens are basically widescreen, and the terminal simulators are adjustable (rather than fixed 80×24). There is no need to cut their feet to suit their shoes, cater to the old standards, and waste screen space. Moreover, if the 80 character convention is used, it is easy to encounter the need for line folding, which will lead to the decline of readability.
  3. If a line exceeds 100 characters, it usually indicates that there is too much logic and it needs to be broken or folded.
  4. For some special scenarios, such as displaying a picture composed of ASCII characters, there will be a requirement that a line exceed 100 characters, so the convention that each line must not exceed 100 characters cannot be strictly implemented. If the branch or break line will inevitably lead to the decrease of code readability, readability is preferred.

Fold line

  • Add a space and at the end of the previous line\Line break, indent one layer after line break (4 spaces).
  • If you indent a block of text, you can use aligned indent or a fixed indent of 4 spaces.
  • If it’s inaa && bb || cc[[ ]]perhaps(( ))Middle folding line,&& ||At the beginning of the next line.

reason:

  1. Both folding indentation and ordinary indentation are to reflect the progressive relationship of code, and there is no need to treat them differently (for example, folding indentation two layers).
  2. If you want to look beautiful, use aligned indents instead of fixed indents. Then, because everyone’s aesthetic is different, it is easy to produce different indentation methods, resulting in unnecessary trouble. However, it is special for text blocks because alignment and indentation are usually not controversial.
  3. &&and||Logically, it belongs to the second half of the sentence, and it is also true in natural language, such asTomorrow I'll go to the park or go shopping, if it needs to be split into two clauses, it will beTomorrow I'll go to the park or go shopping, notTomorrow I'll go to the park or go shopping。 The same is true for code. And put&&or||It’s easier to align at the beginning of the line and look more comfortable.

Space

  • Logically unnecessary consecutive spaces are not allowed in indents and scenes outside them.
  • + && |A space should be added around the binary operator.
  • ! ~There is no space between the equal unary operator and the action object.
  • ( )and(( )) { }No space inside,[[ ]]Because of the syntax, add a space inside.
  • ;No space before and one space after.
  • When defining a function (and(( ))When calling a function, the function name and(No spaces between.
  • if whileAdd a space between the keyword and the following content.
  • if [[ ]] {And so on,{Add a space between and the previous content.
  • Variables and[ ]No space between, use[ ]When fetching array or hash table values,[ ]No space inside.
  • > <There is no space between the redirection symbol and the file or file descriptor.

reason:

  1. Adding an appropriate amount of space can make the code clearer and easier to read.
  2. These conventions basically belong to the custom of conventions in many programming language code styles, which is in line with the aesthetics of most people.

Blank line

  • For non special scenarios, more than two consecutive blank lines are not allowed.
  • #!/bin/zshAdd a blank line after.
  • if whileAdd a blank line after the statement block.
  • Add a blank line after defining the function.
  • Between two lines (or two blocks) of code with weak logical relationship, one or two empty lines shall be added according to the strength of logical relationship (self judgment).

reason:

  1. Adding an appropriate amount of spaces can make the code logic separated by blank lines and improve readability.
  2. Because the method of adding blank lines involves many factors, it is difficult to make a detailed agreement, which mainly depends on the developer’s own judgment.

brackets

  • In the scenario of judging conditions, it is not used[ ], use[[ ]]Replace.
  • In the scene of numerical calculation, use$(( ))instead of$[ ]

reason:

  1. In the scenario of judging conditions,[ ]There is no function of[[ ]]Rich, and there are differences in their usage, so mixed use is easy to cause problems.
  2. In the scenario of numerical comparison or calculation,$[ ]There is no function of$(( ))Rich, mixed use is easy to cause problems.
  3. [ ]The functions are inconsistent in various places, and unnecessary scenes shall be avoided as far as possible.

constant

  • If there is no special symbol in the string constant, both ends can be without quotation marks or with quotation marks.
  • When using numeric values, do not use quotation marks at both ends.

reason:

  1. If any string constant is quoted at both ends, it is easy to fill the code with quotation marks and affect readability. And if you accidentally delete quotation marks, it is easy to cause difficult positioning errors.
  2. Shell script is different from many other programming languages. The logic of processing string accounts for a large part. If you put quotation marks around each string constant, it will increase a lot of extra work.

variable

  • use$varWhen taking the value of a variable, do not put double quotes around it, unless you need to convert a non string variable to a string.
  • In non essential scenarios, you do not need to add${var}Braces in.
  • Where local variables can be used, use local variables (withlocalDefinition).
  • Words in variable names can be separated by underscores or hump style. All lowercase letters can also be used without affecting readability, but they should be consistent in the same file.

reason:

  1. Unlike bash, Zsh uses$varWhen reading the contents of a variable, there is no need to generate various logic errors because the variable does not exist, the value is empty, and contains special symbols, so there is no need to add double quotes at both ends.
  2. use$varReading variables is a common usage in many programming languages${var}It is almost a unique usage in the shell, and input is more troublesome. There is no need to promote this usage. Moreover, errors caused by variable name adhesion due to not enlarging parentheses can be recognized when writing code, which has nothing to do with external input. There is no need to enter many additional braces to avoid non-existent problems.
  3. If global variables are used where local variables can be used, it is more likely that global variables have the same name and affect each other, resulting in errors. This kind of error is difficult to check (because there will be no syntax error, it is easy to suspect that it is a problem of code logic without checking whether there are global variable names), which often wastes a lot of time for developers or testers.
  4. Developers of different programming languages have different style preferences for variable names, so it is not suitable to specify a unified style.

Quotation marks

  • Double quotation marks or single quotation marks can be added at both ends of string constants, but the style should be consistent in the same file.

reason:

  1. The functions of double quotation marks and single quotation marks are different, and mixed use is inevitable.
  2. In the scenario where both double quotation marks and single quotation marks are applicable, the unified use of one quotation mark can make the code cleaner and easier to read.
  3. Developers with different programming language backgrounds have different preferences for single and double quotation marks, so it is not appropriate to impose the default quotation marks.

function

  • have access toname()perhapsfunction name()Define functions, but the style in the same file should be consistent.

reason:

  1. If it is agreed to be used uniformlyname()Defining functions does not take care of the habits of developers of programming languages such as JavaScript, andfunctionKeywords are helpful for code search.
  2. If it is agreed to be used uniformlyfunction name()To define a function, you need to input 9 additional characters, but the meaning is limited, and the input is larger than the output.

Number of script lines

  • For non special scenarios, a single script file shall not exceed 1000 lines.

reason:

  1. Because of the characteristics of shell script, a single script file is too long, which can easily lead to various problems (such as the interaction of global variables). 1000 lines of code are enough for most scenarios.
  2. If you write scripts that need to be distributed such as installation scripts, it is much easier to distribute a single file than multiple files (additional work such as packaging and unpacking). This scenario may require writing long scripts. Therefore, it is not appropriate to force the maximum number of lines in a single script file.

summary

This article introduces my proposed Zsh code style, which can be used as an appropriate reference. The content needs to be improved.

This article will not be updated. The full series of articles will be updated and maintained here:github.com/goreliu/zshguide

Pay to solve problems related to windows, Linux, shell, C, C + +, AHK, python, JavaScript, Lua and other fields, flexible pricing, welcome to consult, wechat ly50247.

Recommended Today

Swift advanced (XV) extension

The extension in swift is somewhat similar to the category in OC Extension can beenumeration、structural morphology、class、agreementAdd new features□ you can add methods, calculation attributes, subscripts, (convenient) initializers, nested types, protocols, etc What extensions can’t do:□ original functions cannot be overwritten□ you cannot add storage attributes or add attribute observers to existing attributes□ cannot add parent […]