sistema_progs

Programas para customizar o meu entorno de traballo nos meus equipos persoais
Log | Files | Refs

CONTRIBUTING.md (20605B)


      1 # Contribution Guide
      2 
      3 ## How to contribute
      4 
      5 ### Issues
      6 
      7 You can freely create an issue using the following links:
      8 
      9 - Report and fixes for bugs and performance issues [[Here]](https://github.com/akinomyoga/ble.sh/issues/new?template=bug_report.md)
     10 - Questions on usage [[Here]](https://github.com/akinomyoga/ble.sh/issues/new?template=feature_request.md)
     11 - Feature request [[Here]](https://github.com/akinomyoga/ble.sh/issues/new?template=help.md)
     12 - Others (suggestions, projects, discussion, complaints, news, information or anything) [[Here]](https://github.com/akinomyoga/ble.sh/issues/new?template=free_style.md)
     13 
     14 ### Pull requests
     15 
     16 We always welcome following types of pull requests. Any changes will be considered to be provided under the BSD 3-Clause License.
     17 If you do not know whether your changes would be appropriate for merge, please feel free to create a pull request and let us talk with each other!
     18 
     19 - Better translation to English, typo fixes
     20 - Fixes, optimization, test cases
     21 - New features
     22 - New color themes ... We accept new themes in [`contrib`](https://github.com/akinomyoga/blesh-contrib/pulls) repository.
     23 - Others
     24 
     25 ### Wiki
     26 
     27 You can freely edit [wiki pages](https://github.com/akinomyoga/ble.sh/wiki).
     28 
     29 - Translations
     30 - Typo fixes
     31 - Create new pages
     32 
     33 ## For package maintainers
     34 
     35 If you are a package maintainer for a repository of Linux distribution, etc.
     36 you may provide a package-specific setting by preparing
     37 a file `/path/to/blesh/lib/_package.sh` (e.g. `/usr/share/blesh/lib/_package.sh`)
     38 which will be sourced after the load of `ble.sh` just before sourcing user's configuration (`~/.blerc`).
     39 
     40 - In the file, the shell variable `_ble_base_package_type=TYPE` should be
     41    set up to have a repository-specific name (such as `AUR`). 
     42 
     43 - The function named `ble/base/package:TYPE/update` (where `TYPE`
     44   matches with a value assigned to `_ble_base_package_type`) may be
     45   provided to define a custom updating procedure.  The exit status of the function can be
     46   - `0` ... when the update successed
     47   - `6` ... when the update was skipped because the package was up to date.
     48   - `125` ... when it wants to fallback to the built-in updating procedure of `ble.sh`.
     49   - Other ... when the update failed
     50 
     51 An example `lib/_package.sh` might be
     52 
     53 ```bash
     54 _ble_base_package_type=apt
     55 
     56 function ble/base/package:apt/update {
     57   sudo apt upgrade blesh
     58 }
     59 ```
     60 
     61 You can also find a real example for AUR (Arch User Repository) [here](https://aur.archlinux.org/cgit/aur.git/tree/blesh-update.sh?h=blesh-git).
     62 
     63 ## Summary of codebase
     64 
     65 The core script file `ble.sh` is generated by combining the following files:
     66 
     67 - `ble.pp` ... Basic initialiation
     68 - `src/def.sh` ... Prototype definitions
     69 - `src/util.sh` ... Basic utility functions
     70 - `src/decode.sh` ... User-input decoder and keybindings
     71 - `src/color.sh` ... Terminal graphic attributes
     72 - `src/canvas.sh` ... Terminal layout engine
     73   - `src/canvas.emoji.sh` ... Emoji database
     74 - `src/history.sh` ... Command history management
     75 - `src/edit.sh` ... Line editor
     76 - `src/benchmark.sh` ... Measure processing time
     77 - `lib/core-completion.sh` ... Prototype definition for completions
     78 - `lib/core-syntax.sh` ... Prototype definitions for syntax analyzer
     79 
     80 Useful features are implemented in separate modules:
     81 
     82 - `lib/keymap.vi.sh` ... Vim mode
     83   - `lib/vim-arpeggio.sh` ... `vim-arpeggio`-like plugin
     84   - `lib/vim-surround.sh` ... `vim-surround`-like plugin
     85 - `lib/keymap.emacs.sh` ... Emacs mode
     86 - `lib/core-syntax.sh` ... Shell parser and syntax highlighting
     87   - `lib/core-syntax-ctx.def` ... Definition of parser states
     88 - `lib/core-complete.sh` ... Completions including `menu-complete`, `auto-complete`, `menu-filter`, `dabbrev`, `sabbrev`, etc.
     89 
     90 The following files are initialization scripts:
     91 
     92 - `lib/init-term.sh` ... Initialize terminal escape sequences (host-to-terminal, i.e. control sequences)
     93 - `lib/init-cmap.sh` ... Initialize terminal escape sequences (terminal-to-host, i.e. key sequences)
     94 - `lib/init-bind.sh` ... Initialize readline attacher
     95 - `lib/init-msys1.sh` ... Workaround for MSYS1 with broken pipes
     96   - `lib/init-msys1-helper.c` ... Helper C program for the workaround of broken pipes
     97 
     98 The contrib repository contains configurations built on top of the `ble.sh` framework
     99 
    100 - `contrib/config/*.bash` are specific configurations whose details may depend on the user's preferences. These are expected to work just by `ble-import` but at the same time serve as examples for the user's personal versions.
    101 - `contrib/sample/*.bash` are examples to explain interfaces for configurations.  These are just explanation of the interface so would not actually function.
    102 - `contrib/airline/*.bash` are the themes for `vim-airline`.
    103 - `contrib/integration/*.bash` are codes needed for the adjustments with other framework.
    104 - `contrib/*.bash` are other miscellaneous configurations. Usually one needs additional configuration after `ble-import`. These files may be moved to another directory in the future.
    105 
    106 ## Tests
    107 
    108 Tests can be run by one of the following commands:
    109 
    110 ```bash
    111 $ make check
    112 $ make check-all
    113 $ bash out/ble.sh --test
    114 
    115 ```
    116 
    117 Currently test coverage is very small
    118 partly because the testing for interactive behavior and terminal rendering results is hard.
    119 Nevertheless, the tests are defined in the following files:
    120 
    121 - `lib/core-test.sh` ... Library for tests
    122 - `lib/test-bash.sh`
    123 - `lib/test-main.sh`
    124 - `lib/test-util.sh`
    125 - `lib/test-canvas.sh`
    126 - `lib/test-edit.sh`
    127 - `lib/test-complete.sh`
    128 - `lib/test-syntax.sh`
    129 
    130 ## Coding styles
    131 
    132 These styles are not required for the initial PR as these are too complicated.
    133 The maintainer(s) will apply the styles before merging.
    134 Nevertheless, it would be useful to follow the styles when you are going to submit PRs many times.
    135 
    136 ### Naming convention for functions
    137 
    138 The function names roughly has the following structure, but the rule is ambiguous to some extent, and there are also many exceptions in the codebase.
    139 
    140 ```ebnf
    141 function_name = (namespace '/')* function_basename ;
    142 
    143 namespace = function_basename ;
    144 
    145 function_basename = name ext?                        (* namespace function              *)
    146                   | class '.' name ext?              (* class method                    *)
    147                   | class '#' name ext?              (* instance method                 *)
    148                   | class '#' class '::' name ext?   (* instance method (override)      *)
    149                   | type ':' name ext? ;             (* customization point             *)
    150 
    151 name = hyphenated_name extension                     (* public                          *)
    152      | '.' hyphenated_name ;                         (* private                         *)
    153 
    154 ext = '.hook'                                        (* hook functions for blehook      *)
    155     | '.draw'                                        (* function operating on DRAW_BUFF *)
    156     | '.fib'                                         (* worker for ble/util/fiberchain  *)
    157     | '.proc'                                        (* callback functions              *)
    158     | '.impl' ;                                      (* internal implementation         *)
    159                                                      (* ... (and more extensions)       *)
    160 
    161 class = name ;
    162 
    163 type = hyphenated_name ;
    164 
    165 hyphenated_name = (word '-')* word ;
    166 
    167 word = /[_a-zA-Z0-9]+/ ;
    168 ```
    169 
    170 The function names are basically hyphenated words (such as `foo-bar-baz` instead of `foo_bar_baz`, `fooBarBaz`, or `FooBarBaz`).
    171 
    172 **Namespace**--The function names can be prefixed by namespaces of the form `<namespace>/`.
    173 Except for the functions intended to be called from the command line or the user configuration, all the function should be defined in a namespace.
    174 The interface of the functions defined in a namespace is subject to change in the future.
    175 A function name can also be used as the namespace name for the helper functions to implement the function.
    176 For the functions defined in external modules, the following namespace should be used to avoid conflicts:
    177 
    178 | Types                                               | Namespace                              |
    179 |:----------------------------------------------------|----------------------------------------|
    180 | `contrib/*.bash`                                    | `ble/contrib/<modulename>`             |
    181 | `contrib/config/*.bash`                             | `ble/contrib/config:<modulename>`      |
    182 | `contrib/integration/*.bash`                        | `ble/contrib/integration:<modulename>` |
    183 | User's public config                                | e.g. `<user>`                          |
    184 | User's private config                               | e.g. `<user>` or `my`                  |
    185 | User's private config in Bash initialization file   | e.g. `<user>`, `my` or `bashrc`        |
    186 | User's private config in ble.sh initialization file | e.g. `<user>`, `my` or `blerc`         |
    187 
    188 **Private**--The function basename started with `.` is considered private within the namespace. All the other functions are public.
    189 
    190 **Method**--The function basename of the form `<class>#<name>` is considered an instance method.
    191 The function basename of the form `<class>.<name>` is considered a class method.
    192 The difference between the two is the latter assumes a single global state while the former assumes that an instance is specified by the first argument or by other means.
    193 The way to specify the instance depends on the class.
    194 For example, `ble/array#*` receives the variable name as the first argument while `ble/string#*` directly receives the string value as the first argument.
    195 For `ble/textarea#*`, the target instance is selected by the shell variable `_ble_textarea_panel`.
    196 The function basename of the form `<class1>#<class2>::<name>` is used to define a virtual function called by the base class `<class2>` at the side of the derived class `<class1>`.
    197 
    198 **Customization point**--The function basename of the form `<type>:<name>` is used to provide the customization point for dynamic values.
    199 This function is typically called as `<type>:"$var"` with `var` contains a value that depends on the context including the currently selected class, user configuration, etc.
    200 
    201 **Extension**--The extension `<ext>` can be used to mark the specific types of functions.
    202 
    203 ### Naming convention for variables
    204 
    205 The variable names roughly have the following structure.
    206 
    207 ```ebnf
    208 local_variable_name = varname
    209                     | '__ble_' varname
    210                     | '_ble_local_' varname ;
    211 
    212 global_variable_name = ('_' namespace)* '_' varname ;
    213 
    214 namespace = word ;
    215 varname = (word '_')* word ;
    216 word = /[a-zA-Z0-9]+/ ;
    217 ```
    218 
    219 The variable names are basically lowercase underscored words such as `foo_bar_baz` (instead of `fooBarBaz` or `FooBarBaz`).
    220 Some global constants and the exported variables have all-uppercase names, but the lowercase should be basically used.
    221 
    222 **Local variables**--The local variables that are only used in the declared function should be basically unprefixed by an underscore.
    223 When the function reads/returns a value through an arbitrary name of <i>in</i>/<i>out</i> variables,
    224 the local variable declared within the function should be prefixed by `__ble_` or `_ble_local_` to avoid the name conflicts between the local and in/out variables.
    225 
    226 **Global variables**--All the global variables, except for the variables that are intended to be directly modified from the command line, should be prefixed by `_`.
    227 Currently, there are no variables intended to be directly modified from the command line<sup><b>[Note 1]</b></sup>.
    228 The variables defined in external modules should be namespaced by the module name.
    229 The variables in modules in the `contrib` repository should have the prefix `_ble_contrib_<module_name>_`
    230 
    231 - <sup><b>[Note 1]</b></sup> In the initial implementation of ble.sh, the ble.sh options are provided as shell variables `bleopt_*`.
    232 As remnant or for the backward compatibility, the values of ble.sh options are still stored in the variables of the name `bleopt_*`,
    233 but these variables for the ble.sh options will be renamed in the future.
    234 
    235 ### Function interface
    236 
    237 The success/failure states should be returned by the exit status.
    238 
    239 **`ret`**--All the other values should be basically returned through shell variables.
    240 This is because, if a function returned its result through the standard output,
    241 the caller would need to capture the results by a command substitution which involves a fork of a subshell and thus is slow.
    242 Here, the efficiency is the primary interest, so there are exceptions where the standard output can be more efficient:
    243 For examples, when the output needs to be saved to a file for later use or to pass it to a different process,
    244 or when the output needs to be processed by the external commands that reads the standard input.
    245 The variable name to return a value should be basically `ret` unless the purpose of function is to store values.
    246 When the function basename has the form `get-<name>`, one should consider retruning the result through the shell variable named `<name>`.
    247 When a function returning multiple values is called from many places, the function may receive an array name as the first argument and stores the result in the specified array.
    248 When the <i>out</i> variable names are specified in the arguments, they should come first in the list of the arguments.
    249 
    250 **`opts`**--The argument position should be basically fixed (e.g., never shifted by optional arguments like `-f` or `-o name`).
    251 The optional arguments can be specified by a colon-separated fields (like `SHELLOPTS` or `BASHOPTS`)
    252 instead of the unix-style flags and options like `-f` and `-o optarg`.
    253 This is because usually the parsing of the unix-style arguments (with or without `getopts`) is slow.
    254 The local variable that receives the colon-separated option typically has the name `opts` or `*opts` (e.g. `local opts=$2`).
    255 A single option has the form `name` or `name=value`,
    256 where `name` should be a hyphenated words like `foo-bar-baz`.
    257 The former form without the value is called a flag option.
    258 One can test a flag option by `[[ :$opts: == *:flag-name:* ]]`.
    259 An option of the form `name=value` can be matched by `ble/opts#extract-first-optarg`, `ble/opts#extract-last-optarg`, or `ble/opts#extract-all-optargs`.
    260 The function `ble/opts#has` can be used to test if either of `name` or `name=value` is contained
    261 
    262 **`$*`**--The functions that receive a string should not allow a variable number of arguments that are joined inside the function.
    263 A variable number of arguments should be only used when each argument is really processed separatedly.
    264 If necessary, the joining should be performed at the caller side.
    265 This is because `IFS` in the caller context affects the joining `$*`, so the handling of `IFS` should be properly done at the caller side.
    266 Another reason is for the future extension, e.g., to add another optional argument.
    267 
    268 ### Variable declarations
    269 
    270 Local variables should be declared by `local` (instead of `declare` or `typeset`).
    271 Variables should be always initialized before referencing their values. This is because uninitialized variables can have random values when `shopt -s localvar_inherit` is turned on.
    272 
    273 The declaration and the initialization of an array variable should be separated as far as the initializer values contain any expansions or any spaces.
    274 There is a bug in Bash 3.0 that the values are separated by whitespaces even when the values are quoted.
    275 When the declaration and the initialization of an array variable are made in a single command, the option `-a` needs to be specified.
    276 Without `-a`, the entire list `(...)` including the surrounding parens will be treated as a scalar string in Bash 3.0.
    277 
    278 ```bash
    279 local v; v=("$var")
    280 local -a v=()
    281 
    282 # The following may not work as expected
    283 # local v=()         # Bash 3.0 will initialize a scalar with the value v='()'  #D0184
    284 # local -a v=("a b") # Bash 3.0 will split it into the two elements "a" and "b" #D0525
    285 ```
    286 
    287 Defining local readonly variables should be avoided
    288 because they will hide global variables from the utilities `ble/variable#is-global`, `ble/util/print-global-definitions`, etc.
    289 Global readonly variables should never be defined.
    290 The background is described in the Limitation section of README.
    291 
    292 ### Conditional commands `[[ ... ]]`
    293 
    294 Do not use `[ ... ]` or `test` unless it is intended to be a POSIX script. Always use `[[ ... ]]`.
    295 
    296 Use `[[ word ]]` and `[[ ! word ]]` instead of `[[ -n word ]]` and `[[ -z word ]]`.
    297 
    298 Use `==` instead of the operator `=` inside conditional commands.
    299 
    300 **Quoting**--The right-hand sides of `==` and `!=` inside conditional commands `[[ ... ]]` should be properly quoted.
    301 The right-hand sides of `=~` inside the conditional commands `[[ ... ]]` should be specified by a single parameter expansion
    302 as `[[ word =~ $rex ]]`, or one can use `ble/string#match 'word' "$rex"` instead.
    303 In other contexts, the arguments of the conditional command should not be quoted
    304 unless raw special characters ``[[:space:]|&;<>\`"$]`` are contained in the argument.
    305 
    306 **No `-eq` etc**--Basically use arithmetic commands `((expr))`
    307 instead of the operators `-eq`, `-ne`, `-gt`, `-ge`, `-lt`, and `-le` of the conditional command.
    308 They might be used when the test is used as a part of complicated conditions in the conditional commands.
    309 For example, `[[ -f $file || $word && word -eq 0 ]]` can be used instead of `[[ -f $file ]] || { [[ $word ]] && ((word == 0)); }` becausing sticking with the arithmetic command would unnecessarily complicate the code in this case.
    310 
    311 ### Other styles
    312 
    313 **Function definition**--There are two forms of function definitions, the POSIX style `func()` and the ksh style `functino func`, as well as the mixed form.
    314 We always use the ksh style of the function definition.
    315 The reasons are that it is easier to search by the keyword `function ` and that it is protected by the aliases of the same name as the function (unless the user defines an alias with the same name as the keyword `function`).
    316 The function body is always the compound command `{ ... }` (instead of any other compound commands such as `( ... )`, `for`, `if`, etc.), and the opening brace `{` is placed on the first line.
    317 
    318 ```bash
    319 function function-name {
    320   : do_something
    321 }
    322 ```
    323 
    324 **`ble/util/print`**--Use `ble/util/print` instead of `echo`. Use `ble/util/put` instead of `echo -n`.
    325 The control characters should be directly specified by the escape string literal `$'...'` instead of relying on the conversion by `echo -e`.
    326 This is because the builtin `echo` can change its behavior depending on the shell option `shopt -s xpg_echo`, where the backslashes in the arguments might have special meaning.
    327 `ble.sh` is intended to work under any possible user options.
    328 
    329 **Quote/unquote**--The arguments where the word splitting and pathname expansions can take place need to be always quoted.
    330 When the subject word of `case` statement and the right-hand sides of variable assignments
    331 (including those specified to assignment builtins `declare`, `typeset`, `local`, `export`, and `readonly`)
    332 contains `$*`, `${arr[*]}`, or raw special characters ``[[:space:]|&;<>\`"$]``, they need to be quoted.
    333 In other contexts, the subject word of `case` and the right-hand sides of variable assignments should not be quoted.
    334 In these contexts, the word splitting and pathname expansions will never happen, so the quoting is unnecessary.
    335 
    336 
    337 Array subscripts are arithmetic context, so the arithmetic expansions `$((expr))` inside the array subscripts are redundant. One should simply write it as `arr[expr]` instead of `arr[$((expr))]`.
    338 
    339 **`ble/util/assign`**--Use `ble/util/assign`, `ble/util/assign-array`, and `ble/util/assign-words` instead of `var=$(cmd)`, `mapfile -t var <<< "$(cmd)"`, and `var=($(cmd))`, respectively.
    340 The command substitutions `$(...)` are slow because they involve the forks of subshells.
    341 
    342 **External commands**--Implement it using built-in Bash features as much as possible.
    343 If the same result can be obtained by built-in Bash features efficiently, do not use the external commands.
    344 When the external command is used, first freeeze the path by calling `ble/bin#freeze-utility-path '<cmd>'` and call the commands through `ble/bin/<cmd>`.
    345 Or save the path of the external command in a variable, and call the command through the variable as `"$_saved_cmd" args...`.
    346 The POSIX commands should be basically used. If non-POSIX commands are used, a POSIX fallback should be always prepared.
    347 Please combine multiple calls of external commands into a single call of the command as much as possible.
    348 Usually, a single call of `sed` and `awk` are preferred over the chain of simple commands.