Commit 58b297d
chasinglightning
·
2024-12-31 18:58:49 -0500 EST
parent 3f034d3
add micro text editor config
52 files changed,
+10142,
-0
| ... | ... | @@ -0,0 +1,42 @@ | |
| 1 | + | color-link default "#c6d0f5,#303446" | |
| 2 | + | color-link comment "#949cbb" | |
| 3 | + | ||
| 4 | + | color-link identifier "#8caaee" | |
| 5 | + | color-link identifier.class "#8caaee" | |
| 6 | + | color-link identifier.var "#8caaee" | |
| 7 | + | ||
| 8 | + | color-link constant "#ef9f76" | |
| 9 | + | color-link constant.number "#ef9f76" | |
| 10 | + | color-link constant.string "#a6d189" | |
| 11 | + | ||
| 12 | + | color-link symbol "#f4b8e4" | |
| 13 | + | color-link symbol.brackets "#eebebe" | |
| 14 | + | color-link symbol.tag "#8caaee" | |
| 15 | + | ||
| 16 | + | color-link type "#8caaee" | |
| 17 | + | color-link type.keyword "#e5c890" | |
| 18 | + | ||
| 19 | + | color-link special "#f4b8e4" | |
| 20 | + | color-link statement "#ca9ee6" | |
| 21 | + | color-link preproc "#f4b8e4" | |
| 22 | + | ||
| 23 | + | color-link underlined "#99d1db" | |
| 24 | + | color-link error "bold #e78284" | |
| 25 | + | color-link todo "bold #e5c890" | |
| 26 | + | ||
| 27 | + | color-link diff-added "#a6d189" | |
| 28 | + | color-link diff-modified "#e5c890" | |
| 29 | + | color-link diff-deleted "#e78284" | |
| 30 | + | ||
| 31 | + | color-link gutter-error "#e78284" | |
| 32 | + | color-link gutter-warning "#e5c890" | |
| 33 | + | ||
| 34 | + | color-link statusline "#c6d0f5,#292c3c" | |
| 35 | + | color-link tabbar "#c6d0f5,#292c3c" | |
| 36 | + | color-link indent-char "#51576d" | |
| 37 | + | color-link line-number "#51576d" | |
| 38 | + | color-link current-line-number "#babbf1" | |
| 39 | + | ||
| 40 | + | color-link cursor-line "#414559,#c6d0f5" | |
| 41 | + | color-link color-column "#414559" | |
| 42 | + | color-link type.extended "default" |
+21,
-0
| ... | ... | @@ -0,0 +1,21 @@ | |
| 1 | + | MIT License | |
| 2 | + | ||
| 3 | + | Copyright (c) 2022 Tero Karvinen https://TeroKarvinen.com | |
| 4 | + | ||
| 5 | + | Permission is hereby granted, free of charge, to any person obtaining a copy | |
| 6 | + | of this software and associated documentation files (the "Software"), to deal | |
| 7 | + | in the Software without restriction, including without limitation the rights | |
| 8 | + | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | |
| 9 | + | copies of the Software, and to permit persons to whom the Software is | |
| 10 | + | furnished to do so, subject to the following conditions: | |
| 11 | + | ||
| 12 | + | The above copyright notice and this permission notice shall be included in all | |
| 13 | + | copies or substantial portions of the Software. | |
| 14 | + | ||
| 15 | + | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |
| 16 | + | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |
| 17 | + | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | |
| 18 | + | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | |
| 19 | + | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | |
| 20 | + | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | |
| 21 | + | SOFTWARE. |
+62,
-0
| ... | ... | @@ -0,0 +1,62 @@ | |
| 1 | + | # micro-cheat - F1 cheatsheet for the language you're editing | |
| 2 | + | ||
| 3 | + | **F1** Show cheatsheet for the language you're editing: Lua, Go, Python... | |
| 4 | + | ||
| 5 | + | A plugin for Micro editor. | |
| 6 | + | ||
| 7 | + | ## Usage | |
| 8 | + | ||
| 9 | + | Edit a source code file with micro. Press **F1**. | |
| 10 | + | ||
| 11 | + | A cheatsheet for the language opens. If you're editing Python, it's a Python cheatsheet. If Go, then Go cheatsheet. | |
| 12 | + | Press Ctrl-Q to close the cheatsheet tab and return to editing. | |
| 13 | + | ||
| 14 | + | For your convenience, micro-cheat also provides a command 'cheat' that you can bind to any key or run with ctrl-E. | |
| 15 | + | ||
| 16 | + | Tested with | |
| 17 | + | ||
| 18 | + | - Python | |
| 19 | + | - Go (Golang) | |
| 20 | + | - Lua | |
| 21 | + | - Javascript | |
| 22 | + | - CSS (cascading style sheets) | |
| 23 | + | - HTML | |
| 24 | + | - HAML (HTML abstraction markup language) | |
| 25 | + | - Vagrantfile (by filename) | |
| 26 | + | - Dockerfile (by filename) | |
| 27 | + | - Makefile | |
| 28 | + | - JavaScript (ECMAScript) | |
| 29 | + | - TypeScript | |
| 30 | + | - YAML (yet another markup language) | |
| 31 | + | - org-mode (*.org) | |
| 32 | + | - bash (shell) | |
| 33 | + | ||
| 34 | + | ## Installation | |
| 35 | + | ||
| 36 | + | In the future, you will be able to install micro-cheat by | |
| 37 | + | ||
| 38 | + | $ micro --plugin install micro-cheat | |
| 39 | + | ||
| 40 | + | Currently, there is just development install | |
| 41 | + | ||
| 42 | + | $ cd $HOME/.config/micro/plug/ | |
| 43 | + | $ git clone https://github.com/terokarvinen/micro-cheat | |
| 44 | + | ||
| 45 | + | ## Tutorial | |
| 46 | + | ||
| 47 | + | [Installation & tutorial for 4 plugins: Palettero, Cheat, Run and Jump](https://terokarvinen.com/2022/command-palette-cheatsheet-run-and-make-micro/) | |
| 48 | + | ||
| 49 | + | ## Limitations | |
| 50 | + | ||
| 51 | + | All cheatsheets included in cheatsheets/ directory are not supported yet. Micro-cheat has only been tested on Linux. | |
| 52 | + | ||
| 53 | + | ## Todo | |
| 54 | + | ||
| 55 | + | Bibtex references cheatsheet. Should be MIT licensed to be included in this plugin. | |
| 56 | + | ||
| 57 | + | ## Adminstrivia | |
| 58 | + | ||
| 59 | + | Cheatsheets are from https://devhints.io project, copyright (c) 2021 Rico Sta. Cruz and contributors, received under MIT license. | |
| 60 | + | ||
| 61 | + | Micro-cheat plugin is Copyright 2022 Tero Karvinen https://TeroKarvinen.com, MIT license. | |
| 62 | + |
| ... | ... | @@ -0,0 +1,102 @@ | |
| 1 | + | --- | |
| 2 | + | title: Ansible | |
| 3 | + | category: Ansible | |
| 4 | + | --- | |
| 5 | + | ||
| 6 | + | {% raw %} | |
| 7 | + | ||
| 8 | + | ## Getting started | |
| 9 | + | ||
| 10 | + | ### Hosts | |
| 11 | + | ||
| 12 | + | $ sudo mkdir /etc/ansible | |
| 13 | + | $ sudo vim /etc/ansible/hosts | |
| 14 | + | ||
| 15 | + | [example] | |
| 16 | + | 192.0.2.101 | |
| 17 | + | 192.0.2.102 | |
| 18 | + | ||
| 19 | + | ### Running a playbook | |
| 20 | + | ||
| 21 | + | $ ansible-playbook playbook.yml | |
| 22 | + | ||
| 23 | + | ## Tasks | |
| 24 | + | ||
| 25 | + | - hosts: all | |
| 26 | + | user: root | |
| 27 | + | sudo: no | |
| 28 | + | vars: | |
| 29 | + | aaa: bbb | |
| 30 | + | tasks: | |
| 31 | + | - ... | |
| 32 | + | handlers: | |
| 33 | + | - ... | |
| 34 | + | ||
| 35 | + | ### Includes | |
| 36 | + | ||
| 37 | + | tasks: | |
| 38 | + | - include: db.yml | |
| 39 | + | handlers: | |
| 40 | + | - include: db.yml user=timmy | |
| 41 | + | ||
| 42 | + | ## Handlers | |
| 43 | + | ||
| 44 | + | handlers: | |
| 45 | + | - name: start apache2 | |
| 46 | + | action: service name=apache2 state=started | |
| 47 | + | ||
| 48 | + | tasks: | |
| 49 | + | - name: install apache | |
| 50 | + | action: apt pkg=apache2 state=latest | |
| 51 | + | notify: | |
| 52 | + | - start apache2 | |
| 53 | + | ||
| 54 | + | ## Vars | |
| 55 | + | ||
| 56 | + | - host: lol | |
| 57 | + | vars_files: | |
| 58 | + | - vars.yml | |
| 59 | + | vars: | |
| 60 | + | project_root: /etc/xyz | |
| 61 | + | tasks: | |
| 62 | + | - name: Create the SSH directory. | |
| 63 | + | file: state=directory path=${project_root}/home/.ssh/ | |
| 64 | + | only_if: "$vm == 0" | |
| 65 | + | ||
| 66 | + | ## Roles | |
| 67 | + | ||
| 68 | + | - host: xxx | |
| 69 | + | roles: | |
| 70 | + | - db | |
| 71 | + | - { role:ruby, sudo_user:$user } | |
| 72 | + | - web | |
| 73 | + | ||
| 74 | + | # Uses: | |
| 75 | + | # roles/db/tasks/*.yml | |
| 76 | + | # roles/db/handlers/*.yml | |
| 77 | + | ||
| 78 | + | ### Task: Failures | |
| 79 | + | ||
| 80 | + | - name: my task | |
| 81 | + | command: ... | |
| 82 | + | register: result | |
| 83 | + | failed_when: "'FAILED' in result.stderr" | |
| 84 | + | ||
| 85 | + | ignore_errors: yes | |
| 86 | + | ||
| 87 | + | changed_when: "result.rc != 2" | |
| 88 | + | ||
| 89 | + | ### Env vars | |
| 90 | + | ||
| 91 | + | vars: | |
| 92 | + | local_home: "{{ lookup('env','HOME') }}" | |
| 93 | + | ||
| 94 | + | ## References | |
| 95 | + | ||
| 96 | + | * [Intro](http://www.ansibleworks.com/docs/intro_configuration.html) | |
| 97 | + | * [Modules](http://www.ansibleworks.com/docs/modules.html) | |
| 98 | + | ||
| 99 | + | {% endraw %} | |
| 100 | + | ||
| 101 | + | https://devhints.io/ cheatsheets - Copyright (c) 2021 Rico Sta. Cruz and contributors - MIT license | |
| 102 | + | micro-cheat plugin Copyright 2022 Tero Karvinen https://TeroKarvinen.com/micro - MIT license |
| ... | ... | @@ -0,0 +1,112 @@ | |
| 1 | + | --- | |
| 2 | + | title: Chef | |
| 3 | + | category: Devops | |
| 4 | + | layout: 2017/sheet | |
| 5 | + | --- | |
| 6 | + | ||
| 7 | + | ### Install | |
| 8 | + | ||
| 9 | + | In your server: | |
| 10 | + | {: .-setup} | |
| 11 | + | ||
| 12 | + | ```bash | |
| 13 | + | $ sudo apt-get install curl | |
| 14 | + | ``` | |
| 15 | + | ||
| 16 | + | ```bash | |
| 17 | + | $ curl -L https://omnitruck.chef.io/install.sh | sudo bash | |
| 18 | + | Thank you for installing Chef! | |
| 19 | + | ``` | |
| 20 | + | ||
| 21 | + | ```bash | |
| 22 | + | $ chef-solo -v | |
| 23 | + | ... | |
| 24 | + | Chef: 14.5.33 | |
| 25 | + | ``` | |
| 26 | + | ||
| 27 | + | ### Start the cookbook | |
| 28 | + | ||
| 29 | + | ```bash | |
| 30 | + | wget http://github.com/chef-cookbooks/chef-repo/tarball/master -O - | tar xzf - --strip-components=1 | |
| 31 | + | ``` | |
| 32 | + | ||
| 33 | + | ### Knife | |
| 34 | + | ||
| 35 | + | ```bash | |
| 36 | + | $ knife supermarket download mysql | |
| 37 | + | ``` | |
| 38 | + | ||
| 39 | + | ### Invoking chef-solo | |
| 40 | + | ||
| 41 | + | ```bash | |
| 42 | + | $ chef-solo -c solo.rb -j web.json | |
| 43 | + | ``` | |
| 44 | + | ||
| 45 | + | ## Examples | |
| 46 | + | ||
| 47 | + | ### Simple compile-from-source | |
| 48 | + | ||
| 49 | + | ```ruby | |
| 50 | + | execute "tar --no-same-owner -zxf hi.tar.gz" do | |
| 51 | + | cwd "/usr/local/src" | |
| 52 | + | creates "/usr/local/src/node-v#{version}" | |
| 53 | + | end | |
| 54 | + | ``` | |
| 55 | + | ||
| 56 | + | ```ruby | |
| 57 | + | bash "compile" do | |
| 58 | + | cwd "/usr/local/src/node-v#{version}" | |
| 59 | + | code %[ | |
| 60 | + | PATH=/usr/local/bin:$PATH | |
| 61 | + | ./configure | |
| 62 | + | make | |
| 63 | + | ] | |
| 64 | + | creates "/usr/local/src/node-v#{version}/node" | |
| 65 | + | end | |
| 66 | + | ``` | |
| 67 | + | ||
| 68 | + | ### remote file | |
| 69 | + | ||
| 70 | + | ```ruby | |
| 71 | + | remote_file "/usr/local/src/hi.tar.gz" do | |
| 72 | + | source "http://..." | |
| 73 | + | checksum "ab83be..." | |
| 74 | + | mode 0644 | |
| 75 | + | action :create_if_missing | |
| 76 | + | end | |
| 77 | + | ``` | |
| 78 | + | ||
| 79 | + | ### ruby_block | |
| 80 | + | ||
| 81 | + | ```ruby | |
| 82 | + | ruby_block "name" do | |
| 83 | + | block { File.read ... } | |
| 84 | + | not_if { File.exists?(...) } | |
| 85 | + | end | |
| 86 | + | ``` | |
| 87 | + | ||
| 88 | + | ### Execute | |
| 89 | + | ||
| 90 | + | ```ruby | |
| 91 | + | execute "name" do | |
| 92 | + | cwd "..." | |
| 93 | + | environment({ "PATH" => "..." }) | |
| 94 | + | command "make install" | |
| 95 | + | creates "..." | |
| 96 | + | end | |
| 97 | + | ``` | |
| 98 | + | ||
| 99 | + | ### Conditions | |
| 100 | + | ||
| 101 | + | ```ruby | |
| 102 | + | creates "/usr/local/src/node-v#{version}/node" | |
| 103 | + | not_if { File.exists?('...') } | |
| 104 | + | ``` | |
| 105 | + | ||
| 106 | + | ## Also see | |
| 107 | + | ||
| 108 | + | * [Learn Chef Rally](https://learn.chef.io) _(learn.chef.io)_ | |
| 109 | + | * [install_from_source.rb recipe](https://github.com/mdxp/nodejs-cookbook/blob/master/recipes/install_from_source.rb) _(github.com)_ | |
| 110 | + | ||
| 111 | + | https://devhints.io/ cheatsheets - Copyright (c) 2021 Rico Sta. Cruz and contributors - MIT license | |
| 112 | + | micro-cheat plugin Copyright 2022 Tero Karvinen https://TeroKarvinen.com/micro - MIT license |
| ... | ... | @@ -0,0 +1,73 @@ | |
| 1 | + | --- | |
| 2 | + | title: Cron | |
| 3 | + | category: CLI | |
| 4 | + | layout: 2017/sheet | |
| 5 | + | updated: 2018-05-03 | |
| 6 | + | weight: -3 | |
| 7 | + | --- | |
| 8 | + | ||
| 9 | + | ## Format | |
| 10 | + | {: .-two-column} | |
| 11 | + | ||
| 12 | + | ### Format | |
| 13 | + | ||
| 14 | + | ``` | |
| 15 | + | Min Hour Day Mon Weekday | |
| 16 | + | ``` | |
| 17 | + | {: .-setup} | |
| 18 | + | ||
| 19 | + | ``` | |
| 20 | + | * * * * * command to be executed | |
| 21 | + | ``` | |
| 22 | + | ||
| 23 | + | ``` | |
| 24 | + | ┬ ┬ ┬ ┬ ┬ | |
| 25 | + | │ │ │ │ └─ Weekday (0=Sun .. 6=Sat) | |
| 26 | + | │ │ │ └────── Month (1..12) | |
| 27 | + | │ │ └─────────── Day (1..31) | |
| 28 | + | │ └──────────────── Hour (0..23) | |
| 29 | + | └───────────────────── Minute (0..59) | |
| 30 | + | ``` | |
| 31 | + | {: .-setup.-box-chars} | |
| 32 | + | ||
| 33 | + | ### Operators | |
| 34 | + | ||
| 35 | + | | Operator | Description | | |
| 36 | + | | --- | --- | | |
| 37 | + | | `*` | all values | | |
| 38 | + | | `,` | separate individual values | | |
| 39 | + | | `-` | a range of values | | |
| 40 | + | | `/` | divide a value into steps | | |
| 41 | + | ||
| 42 | + | ### Examples | |
| 43 | + | ||
| 44 | + | | Example | Description | | |
| 45 | + | | --- | --- | | |
| 46 | + | | `0 * * * *` | every hour | | |
| 47 | + | | `*/15 * * * *` | every 15 mins | | |
| 48 | + | | `0 */2 * * *` | every 2 hours | | |
| 49 | + | | `0 18 * * 0-6` | every week Mon-Sat at 6pm | | |
| 50 | + | | `10 2 * * 6,7` | every Sat and Sun on 2:10am | | |
| 51 | + | | `0 0 * * 0` | every Sunday midnight | | |
| 52 | + | | --- | --- | | |
| 53 | + | | `@reboot` | every reboot | | |
| 54 | + | ||
| 55 | + | ### Crontab | |
| 56 | + | ||
| 57 | + | ```bash | |
| 58 | + | # Adding tasks easily | |
| 59 | + | echo "@reboot echo hi" | crontab | |
| 60 | + | ``` | |
| 61 | + | ||
| 62 | + | ```bash | |
| 63 | + | # Open in editor | |
| 64 | + | crontab -e | |
| 65 | + | ``` | |
| 66 | + | ||
| 67 | + | ```bash | |
| 68 | + | # List tasks | |
| 69 | + | crontab -l [-u user] | |
| 70 | + | ``` | |
| 71 | + | ||
| 72 | + | https://devhints.io/ cheatsheets - Copyright (c) 2021 Rico Sta. Cruz and contributors - MIT license | |
| 73 | + | micro-cheat plugin Copyright 2022 Tero Karvinen https://TeroKarvinen.com/micro - MIT license |
| ... | ... | @@ -0,0 +1,218 @@ | |
| 1 | + | --- | |
| 2 | + | title: CSS | |
| 3 | + | category: CSS | |
| 4 | + | layout: 2017/sheet | |
| 5 | + | weight: -1 | |
| 6 | + | keywords: | |
| 7 | + | - "margin, padding, border" | |
| 8 | + | - "div, .class, #id, [attr]" | |
| 9 | + | - "font, background" | |
| 10 | + | - "display: block, inline, flex" | |
| 11 | + | - Selectors | |
| 12 | + | - Properties | |
| 13 | + | --- | |
| 14 | + | ||
| 15 | + | ## Basics | |
| 16 | + | {: .-three-column} | |
| 17 | + | ||
| 18 | + | ### Selectors | |
| 19 | + | ||
| 20 | + | ```css | |
| 21 | + | .class { | |
| 22 | + | font-weight: bold; | |
| 23 | + | } | |
| 24 | + | ``` | |
| 25 | + | {: .-setup} | |
| 26 | + | ||
| 27 | + | | Selector | Description | | |
| 28 | + | | ----------------- | ------------ | | |
| 29 | + | | `*` | All elements | | |
| 30 | + | | `div` | Element | | |
| 31 | + | | `.class` | Class | | |
| 32 | + | | `#id` | ID | | |
| 33 | + | | `[disabled]` | Attribute | | |
| 34 | + | | `[role="dialog"]` | Attribute | | |
| 35 | + | ||
| 36 | + | ### Combinators | |
| 37 | + | ||
| 38 | + | | Selector | Description | | |
| 39 | + | | ------------------- | ----------------- | | |
| 40 | + | | `.parent .child` | Descendant | | |
| 41 | + | | `.parent > .child` | Direct descendant | | |
| 42 | + | | `.child + .sibling` | Adjacent sibling | | |
| 43 | + | | `.child ~ .sibling` | Far sibling | | |
| 44 | + | | `.class1.class2` | Have both classes | | |
| 45 | + | ||
| 46 | + | ### Attribute selectors | |
| 47 | + | ||
| 48 | + | | Selector | Description | | |
| 49 | + | | ------------------ | ----------------------------------- | | |
| 50 | + | | `[role="dialog"]` | `=` Exact | | |
| 51 | + | | `[class~="box"]` | `~=` Has word | | |
| 52 | + | | `[class|="box"]` | `|=` Exact or prefix (eg, `value-`) | | |
| 53 | + | | `[href$=".doc"]` | `$=` Ends in | | |
| 54 | + | | `[href^="/index"]` | `^=` Begins with | | |
| 55 | + | | `[class*="-is-"]` | `*=` Contains | | |
| 56 | + | ||
| 57 | + | ### Pseudo-classes | |
| 58 | + | ||
| 59 | + | | Selector | Description | | |
| 60 | + | | -------------------- | ------------------------------------------ | | |
| 61 | + | | `:target` | eg, `h2#foo:target` | | |
| 62 | + | | --- | --- | | |
| 63 | + | | `:disabled` | | | |
| 64 | + | | `:focus` | | | |
| 65 | + | | `:active` | | | |
| 66 | + | | --- | --- | | |
| 67 | + | | `:nth-child(3)` | 3rd child | | |
| 68 | + | | `:nth-child(3n+2)` | 2nd child in groups of 3 | | |
| 69 | + | | `:nth-child(-n+4)` | | | |
| 70 | + | | --- | --- | | |
| 71 | + | | `:nth-last-child(2)` | | | |
| 72 | + | | `:nth-of-type(2)` | | | |
| 73 | + | | --- | --- | | |
| 74 | + | | `:checked` | Checked inputs | | |
| 75 | + | | `:disabled` | Disabled elements | | |
| 76 | + | | `:default` | Default element in a group | | |
| 77 | + | | --- | --- | | |
| 78 | + | | `:empty` | Elements without children | | |
| 79 | + | ||
| 80 | + | ### Pseudo-class variations | |
| 81 | + | ||
| 82 | + | | Selector | | |
| 83 | + | | ----------------- | | |
| 84 | + | | `:first-of-type` | | |
| 85 | + | | `:last-of-type` | | |
| 86 | + | | `:nth-of-type(2)` | | |
| 87 | + | | `:only-of-type` | | |
| 88 | + | | --- | | |
| 89 | + | | `:first-child` | | |
| 90 | + | | `:last-child` | | |
| 91 | + | | `:nth-child(2)` | | |
| 92 | + | | `:only-child` | | |
| 93 | + | {: .-left-align} | |
| 94 | + | ||
| 95 | + | ## Fonts | |
| 96 | + | {: .-left-reference} | |
| 97 | + | ||
| 98 | + | ### Properties | |
| 99 | + | ||
| 100 | + | | Property | Description | | |
| 101 | + | | ------------------ | ------------------------------------ | | |
| 102 | + | | `font-family:` | `<font>, <fontN>` | | |
| 103 | + | | `font-size:` | `<size>` | | |
| 104 | + | | `letter-spacing:` | `<size>` | | |
| 105 | + | | `line-height:` | `<number>` | | |
| 106 | + | | --- | --- | | |
| 107 | + | | `font-weight:` | `bold` `normal` | | |
| 108 | + | | `font-style:` | `italic` `normal` | | |
| 109 | + | | `text-decoration:` | `underline` `none` | | |
| 110 | + | | --- | --- | | |
| 111 | + | | `text-align:` | `left` `right` `center` `justify` | | |
| 112 | + | | `text-transform:` | `capitalize` `uppercase` `lowercase` | | |
| 113 | + | {: .-key-values} | |
| 114 | + | ||
| 115 | + | ### Shorthand | |
| 116 | + | {: .-prime} | |
| 117 | + | ||
| 118 | + | | | style | weight | size (required) | | line-height | family | | |
| 119 | + | | ------- | -------- | ------ | --------------- | --- | ----------- | ----------------- | | |
| 120 | + | | `font:` | `italic` | `400` | `14px` | `/` | `1.5` | `sans-serif` | | |
| 121 | + | | | style | weight | size (required) | | line-height | family (required) | | |
| 122 | + | {: .-css-breakdown} | |
| 123 | + | ||
| 124 | + | ### Example | |
| 125 | + | ||
| 126 | + | ```css | |
| 127 | + | font-family: Arial; | |
| 128 | + | font-size: 12pt; | |
| 129 | + | line-height: 1.5; | |
| 130 | + | letter-spacing: 0.02em; | |
| 131 | + | color: #aa3322; | |
| 132 | + | ``` | |
| 133 | + | ||
| 134 | + | ### Case | |
| 135 | + | ||
| 136 | + | ```css | |
| 137 | + | text-transform: capitalize; /* Hello */ | |
| 138 | + | text-transform: uppercase; /* HELLO */ | |
| 139 | + | text-transform: lowercase; /* hello */ | |
| 140 | + | ``` | |
| 141 | + | ||
| 142 | + | ## Background | |
| 143 | + | {: .-left-reference} | |
| 144 | + | ||
| 145 | + | ### Properties | |
| 146 | + | ||
| 147 | + | | Property | Description | | |
| 148 | + | | ------------------------ | ---------------------------------------- | | |
| 149 | + | | `background:` | _(Shorthand)_ | | |
| 150 | + | | --- | --- | | |
| 151 | + | | `background-color:` | `<color>` | | |
| 152 | + | | `background-image:` | `url(...)` | | |
| 153 | + | | `background-position:` | `left/center/right` `top/center/bottom` | | |
| 154 | + | | `background-size:` | `cover` `X Y` | | |
| 155 | + | | `background-clip:` | `border-box` `padding-box` `content-box` | | |
| 156 | + | | `background-repeat:` | `no-repeat` `repeat-x` `repeat-y` | | |
| 157 | + | | `background-attachment:` | `scroll` `fixed` `local` | | |
| 158 | + | {: .-key-values} | |
| 159 | + | ||
| 160 | + | ### Shorthand | |
| 161 | + | ||
| 162 | + | | | color | image | positionX | positionY | | size | repeat | attachment | | |
| 163 | + | | ------------- | ------ | ------------- | --------- | --------- | --- | -------------- | ----------- | ---------- | | |
| 164 | + | | `background:` | `#ff0` | `url(bg.jpg)` | `left` | `top` | `/` | `100px` `auto` | `no-repeat` | `fixed;` | | |
| 165 | + | | `background:` | `#abc` | `url(bg.png)` | `center` | `center` | `/` | `cover` | `repeat-x` | `local;` | | |
| 166 | + | | | color | image | positionX | positionY | | size | repeat | attachment | | |
| 167 | + | {: .-css-breakdown} | |
| 168 | + | ||
| 169 | + | ### Multiple backgrounds | |
| 170 | + | ||
| 171 | + | ```css | |
| 172 | + | background: linear-gradient(to bottom, rgba(0, 0, 0, 0.5), rgba(0, 0, 0, 0.5)), | |
| 173 | + | url('background.jpg') center center / cover, #333; | |
| 174 | + | ``` | |
| 175 | + | ||
| 176 | + | ## Animation | |
| 177 | + | {: .-left-reference} | |
| 178 | + | ||
| 179 | + | ### Properties | |
| 180 | + | ||
| 181 | + | | Property | Value | | |
| 182 | + | | ---------------------------- | -------------------------------------------------------- | | |
| 183 | + | | `animation:` | _(shorthand)_ | | |
| 184 | + | | `animation-name:` | `<name>` | | |
| 185 | + | | `animation-duration:` | `<time>ms` | | |
| 186 | + | | `animation-timing-function:` | `ease` `linear` `ease-in` `ease-out` `ease-in-out` | | |
| 187 | + | | `animation-delay:` | `<time>ms` | | |
| 188 | + | | `animation-iteration-count:` | `infinite` `<number>` | | |
| 189 | + | | `animation-direction:` | `normal` `reverse` `alternate` `alternate-reverse` | | |
| 190 | + | | `animation-fill-mode:` | `none` `forwards` `backwards` `both` `initial` `inherit` | | |
| 191 | + | | `animation-play-state:` | `normal` `reverse` `alternate` `alternate-reverse` | | |
| 192 | + | {: .-key-values} | |
| 193 | + | ||
| 194 | + | ### Shorthand | |
| 195 | + | ||
| 196 | + | | | name | duration | timing-function | delay | count | direction | fill-mode | play-state | | |
| 197 | + | | ------------ | -------- | -------- | --------------- | ------- | ---------- | ------------------- | --------- | ---------- | | |
| 198 | + | | `animation:` | `bounce` | `300ms` | `linear` | `100ms` | `infinite` | `alternate-reverse` | `both` | `reverse` | | |
| 199 | + | | | name | duration | timing-function | delay | count | direction | fill-mode | play-state | | |
| 200 | + | {: .-css-breakdown} | |
| 201 | + | ||
| 202 | + | ### Example | |
| 203 | + | ||
| 204 | + | ```css | |
| 205 | + | animation: bounce 300ms linear 0s infinite normal; | |
| 206 | + | animation: bounce 300ms linear infinite; | |
| 207 | + | animation: bounce 300ms linear infinite alternate-reverse; | |
| 208 | + | animation: bounce 300ms linear 2s infinite alternate-reverse forwards normal; | |
| 209 | + | ``` | |
| 210 | + | ||
| 211 | + | ### Event | |
| 212 | + | ||
| 213 | + | ```js | |
| 214 | + | .one('webkitAnimationEnd oanimationend msAnimationEnd animationend') | |
| 215 | + | ``` | |
| 216 | + | ||
| 217 | + | https://devhints.io/ cheatsheets - Copyright (c) 2021 Rico Sta. Cruz and contributors - MIT license | |
| 218 | + | micro-cheat plugin Copyright 2022 Tero Karvinen https://TeroKarvinen.com/micro - MIT license |
| ... | ... | @@ -0,0 +1,115 @@ | |
| 1 | + | --- | |
| 2 | + | title: Dockerfile | |
| 3 | + | category: Devops | |
| 4 | + | layout: 2017/sheet | |
| 5 | + | prism_languages: [docker] | |
| 6 | + | updated: 2019-10-20 | |
| 7 | + | --- | |
| 8 | + | ||
| 9 | + | ## Reference | |
| 10 | + | {: .-three-column} | |
| 11 | + | ||
| 12 | + | ### Inheritance | |
| 13 | + | ||
| 14 | + | ```docker | |
| 15 | + | FROM ruby:2.2.2 | |
| 16 | + | ``` | |
| 17 | + | ||
| 18 | + | ### Variables | |
| 19 | + | ||
| 20 | + | ```docker | |
| 21 | + | ENV APP_HOME /myapp | |
| 22 | + | RUN mkdir $APP_HOME | |
| 23 | + | ``` | |
| 24 | + | ||
| 25 | + | ```docker | |
| 26 | + | ARG APP_HOME="" | |
| 27 | + | RUN mkdir $APP_HOME | |
| 28 | + | ``` | |
| 29 | + | ||
| 30 | + | ### Initialization | |
| 31 | + | ||
| 32 | + | ```docker | |
| 33 | + | RUN bundle install | |
| 34 | + | ``` | |
| 35 | + | ||
| 36 | + | ```docker | |
| 37 | + | WORKDIR /myapp | |
| 38 | + | ``` | |
| 39 | + | ||
| 40 | + | ```docker | |
| 41 | + | VOLUME ["/data"] | |
| 42 | + | # Specification for mount point | |
| 43 | + | ``` | |
| 44 | + | ||
| 45 | + | ```docker | |
| 46 | + | ADD file.xyz /file.xyz | |
| 47 | + | COPY --chown=user:group host_file.xyz /path/container_file.xyz | |
| 48 | + | ``` | |
| 49 | + | ||
| 50 | + | ### Run commands in strict shell | |
| 51 | + | ||
| 52 | + | ```docker | |
| 53 | + | ENV my_var | |
| 54 | + | SHELL ["/bin/bash", "-euo", "pipefail", "-c"] | |
| 55 | + | ||
| 56 | + | # With strict mode: | |
| 57 | + | RUN false # fails build like using && | |
| 58 | + | RUN echo "$myvar" # will throw error due to typo | |
| 59 | + | RUN true | false # will bail out of pipe | |
| 60 | + | ``` | |
| 61 | + | ||
| 62 | + | Using `shell` will turn on strict mode for shell commands. | |
| 63 | + | ||
| 64 | + | ### Onbuild | |
| 65 | + | ||
| 66 | + | ```docker | |
| 67 | + | ONBUILD RUN bundle install | |
| 68 | + | # when used with another file | |
| 69 | + | ``` | |
| 70 | + | ||
| 71 | + | ### Commands | |
| 72 | + | ||
| 73 | + | ```docker | |
| 74 | + | EXPOSE 5900 | |
| 75 | + | CMD ["bundle", "exec", "rails", "server"] | |
| 76 | + | ``` | |
| 77 | + | ||
| 78 | + | ### Entrypoint | |
| 79 | + | ||
| 80 | + | ```docker | |
| 81 | + | ENTRYPOINT ["executable", "param1", "param2"] | |
| 82 | + | ENTRYPOINT command param1 param2 | |
| 83 | + | ``` | |
| 84 | + | ||
| 85 | + | Configures a container that will run as an executable. | |
| 86 | + | ||
| 87 | + | ```docker | |
| 88 | + | ENTRYPOINT exec top -b | |
| 89 | + | ``` | |
| 90 | + | ||
| 91 | + | This will use shell processing to substitute shell variables, and will ignore any `CMD` or `docker run` command line arguments. | |
| 92 | + | ||
| 93 | + | ### Metadata | |
| 94 | + | ||
| 95 | + | ```docker | |
| 96 | + | LABEL version="1.0" | |
| 97 | + | ``` | |
| 98 | + | ||
| 99 | + | ```docker | |
| 100 | + | LABEL "com.example.vendor"="ACME Incorporated" | |
| 101 | + | LABEL com.example.label-with-value="foo" | |
| 102 | + | ``` | |
| 103 | + | ||
| 104 | + | ```docker | |
| 105 | + | LABEL description="This text illustrates \ | |
| 106 | + | that label-values can span multiple lines." | |
| 107 | + | ``` | |
| 108 | + | ||
| 109 | + | ## See also | |
| 110 | + | {: .-one-column} | |
| 111 | + | ||
| 112 | + | - <https://docs.docker.com/engine/reference/builder/> | |
| 113 | + | ||
| 114 | + | https://devhints.io/ cheatsheets - Copyright (c) 2021 Rico Sta. Cruz and contributors - MIT license | |
| 115 | + | micro-cheat plugin Copyright 2022 Tero Karvinen https://TeroKarvinen.com/micro - MIT license |
| ... | ... | @@ -0,0 +1,78 @@ | |
| 1 | + | --- | |
| 2 | + | title: editorconfig | |
| 3 | + | layout: 2017/sheet | |
| 4 | + | prism_languages: [ini] | |
| 5 | + | weight: -1 | |
| 6 | + | updated: 2019-09-25 | |
| 7 | + | category: Apps | |
| 8 | + | --- | |
| 9 | + | ||
| 10 | + | ### Short example | |
| 11 | + | {: .-prime} | |
| 12 | + | ||
| 13 | + | ```ini | |
| 14 | + | # editorconfig.org | |
| 15 | + | root = true | |
| 16 | + | ||
| 17 | + | [*] | |
| 18 | + | indent_style = space | |
| 19 | + | indent_size = 2 | |
| 20 | + | tab_width = 2 | |
| 21 | + | end_of_line = lf | |
| 22 | + | charset = utf-8 | |
| 23 | + | trim_trailing_whitespace = true | |
| 24 | + | insert_final_newline = true | |
| 25 | + | ``` | |
| 26 | + | ||
| 27 | + | This example should be fine for most projects indented by 2 spaces. See: [animate.css editorconfig](https://github.com/daneden/animate.css/blob/master/.editorconfig) | |
| 28 | + | ||
| 29 | + | ### Properties | |
| 30 | + | ||
| 31 | + | ```ini | |
| 32 | + | indent_style = {space|tab} | |
| 33 | + | indent_size = {4|tab} | |
| 34 | + | tab_width = 2 | |
| 35 | + | end_of_line = {cr|lf|crlf} | |
| 36 | + | charset = {utf-8|utf-16be|utf-16le|latin1} | |
| 37 | + | trim_trailing_whitespace = false | |
| 38 | + | insert_final_newline = true | |
| 39 | + | max_line_length = 80 | |
| 40 | + | ``` | |
| 41 | + | ||
| 42 | + | ### Full example | |
| 43 | + | ||
| 44 | + | ```ini | |
| 45 | + | # top-most EditorConfig file | |
| 46 | + | root = true | |
| 47 | + | ||
| 48 | + | # Unix-style newlines with a newline ending every file | |
| 49 | + | [*] | |
| 50 | + | end_of_line = lf | |
| 51 | + | insert_final_newline = true | |
| 52 | + | ||
| 53 | + | # 4 space indentation | |
| 54 | + | [*.py] | |
| 55 | + | indent_style = space | |
| 56 | + | indent_size = 4 | |
| 57 | + | ||
| 58 | + | # Tab indentation (no size specified) | |
| 59 | + | [*.js] | |
| 60 | + | indent_style = tab | |
| 61 | + | ||
| 62 | + | # Indentation override for all JS under lib directory | |
| 63 | + | [lib/**.js] | |
| 64 | + | indent_style = space | |
| 65 | + | indent_size = 2 | |
| 66 | + | ||
| 67 | + | # Matches the exact files either package.json or .travis.yml | |
| 68 | + | [{package.json,.travis.yml}] | |
| 69 | + | indent_style = space | |
| 70 | + | indent_size = 2 | |
| 71 | + | ``` | |
| 72 | + | ||
| 73 | + | ### References | |
| 74 | + | ||
| 75 | + | - <https://EditorConfig.org> | |
| 76 | + | ||
| 77 | + | https://devhints.io/ cheatsheets - Copyright (c) 2021 Rico Sta. Cruz and contributors - MIT license | |
| 78 | + | micro-cheat plugin Copyright 2022 Tero Karvinen https://TeroKarvinen.com/micro - MIT license |
| ... | ... | @@ -0,0 +1,766 @@ | |
| 1 | + | --- | |
| 2 | + | title: Elixir | |
| 3 | + | category: Elixir | |
| 4 | + | layout: 2017/sheet | |
| 5 | + | tags: [New] | |
| 6 | + | updated: 2018-07-04 | |
| 7 | + | weight: -10 | |
| 8 | + | --- | |
| 9 | + | ||
| 10 | + | ## Getting started | |
| 11 | + | {: .-three-column} | |
| 12 | + | ||
| 13 | + | ### Hello world | |
| 14 | + | {: .-prime} | |
| 15 | + | ||
| 16 | + | ```elixir | |
| 17 | + | # hello.exs | |
| 18 | + | defmodule Greeter do | |
| 19 | + | def greet(name) do | |
| 20 | + | message = "Hello, " <> name <> "!" | |
| 21 | + | IO.puts message | |
| 22 | + | end | |
| 23 | + | end | |
| 24 | + | ||
| 25 | + | Greeter.greet("world") | |
| 26 | + | ``` | |
| 27 | + | ||
| 28 | + | ```bash | |
| 29 | + | elixir hello.exs | |
| 30 | + | # Hello, world! | |
| 31 | + | ``` | |
| 32 | + | {: .-setup} | |
| 33 | + | ||
| 34 | + | ### Variables | |
| 35 | + | ||
| 36 | + | ```elixir | |
| 37 | + | age = 23 | |
| 38 | + | ``` | |
| 39 | + | ||
| 40 | + | ### Maps | |
| 41 | + | ||
| 42 | + | ```elixir | |
| 43 | + | user = %{ | |
| 44 | + | name: "John", | |
| 45 | + | city: "Melbourne" | |
| 46 | + | } | |
| 47 | + | ``` | |
| 48 | + | ||
| 49 | + | ```elixir | |
| 50 | + | IO.puts "Hello, " <> user.name | |
| 51 | + | ``` | |
| 52 | + | {: .-setup} | |
| 53 | + | ||
| 54 | + | ### Lists | |
| 55 | + | ||
| 56 | + | ```elixir | |
| 57 | + | users = [ "Tom", "Dick", "Harry" ] | |
| 58 | + | ``` | |
| 59 | + | {: data-line="1"} | |
| 60 | + | ||
| 61 | + | ```elixir | |
| 62 | + | Enum.map(users, fn user -> | |
| 63 | + | IO.puts "Hello " <> user | |
| 64 | + | end) | |
| 65 | + | ``` | |
| 66 | + | ||
| 67 | + | ### Piping | |
| 68 | + | ||
| 69 | + | ```elixir | |
| 70 | + | source | |
| 71 | + | |> transform(:hello) | |
| 72 | + | |> print() | |
| 73 | + | ``` | |
| 74 | + | {: data-line="2,3"} | |
| 75 | + | ||
| 76 | + | ```elixir | |
| 77 | + | # Same as: | |
| 78 | + | print(transform(source, :hello)) | |
| 79 | + | ``` | |
| 80 | + | ||
| 81 | + | These two are equivalent. | |
| 82 | + | ||
| 83 | + | ### Pattern matching | |
| 84 | + | ||
| 85 | + | ```elixir | |
| 86 | + | user = %{name: "Tom", age: 23} | |
| 87 | + | %{name: username} = user | |
| 88 | + | ``` | |
| 89 | + | {: data-line="2"} | |
| 90 | + | ||
| 91 | + | This sets `username` to `"Tom"`. | |
| 92 | + | ||
| 93 | + | ### Pattern matching in functions | |
| 94 | + | ||
| 95 | + | ```elixir | |
| 96 | + | def greet(%{name: username}) do | |
| 97 | + | IO.puts "Hello, " <> username | |
| 98 | + | end | |
| 99 | + | ||
| 100 | + | user = %{name: "Tom", age: 23} | |
| 101 | + | ``` | |
| 102 | + | {: data-line="1"} | |
| 103 | + | ||
| 104 | + | Pattern matching works in function parameters too. | |
| 105 | + | ||
| 106 | + | Control flow | |
| 107 | + | ------------ | |
| 108 | + | {: .-three-column} | |
| 109 | + | ||
| 110 | + | ### If | |
| 111 | + | ||
| 112 | + | ```elixir | |
| 113 | + | if false do | |
| 114 | + | "This will never be seen" | |
| 115 | + | else | |
| 116 | + | "This will" | |
| 117 | + | end | |
| 118 | + | ``` | |
| 119 | + | ### Case | |
| 120 | + | ||
| 121 | + | ```elixir | |
| 122 | + | case {1, 2, 3} do | |
| 123 | + | {4, 5, 6} -> | |
| 124 | + | "This clause won't match" | |
| 125 | + | {1, x, 3} -> | |
| 126 | + | "This will match and bind x to 2" | |
| 127 | + | _ -> | |
| 128 | + | "This will match any value" | |
| 129 | + | end | |
| 130 | + | ``` | |
| 131 | + | ||
| 132 | + | ### Cond | |
| 133 | + | ||
| 134 | + | ```elixir | |
| 135 | + | cond do | |
| 136 | + | 1 + 1 == 3 -> | |
| 137 | + | "I will never be seen" | |
| 138 | + | 2 * 5 == 12 -> | |
| 139 | + | "Me neither" | |
| 140 | + | true -> | |
| 141 | + | "But I will (this is essentially an else)" | |
| 142 | + | end | |
| 143 | + | ``` | |
| 144 | + | ||
| 145 | + | ### With | |
| 146 | + | ||
| 147 | + | ```elixir | |
| 148 | + | with {:ok, {int, _asdf}} <- Integer.parse("123asdf"), | |
| 149 | + | {:ok, datetime, _utc_offset} <- DateTime.from_iso8601("2021-10-27T12:00:00Z") do | |
| 150 | + | DateTime.add(datetime, int, :second) | |
| 151 | + | # optional else clause. if not provided and an error occurs, the error is returned | |
| 152 | + | else | |
| 153 | + | :error -> "couldn't parse integer string" | |
| 154 | + | {:error, :invalid_format} -> "couldn't parse date string" | |
| 155 | + | _ -> "this will never get hit because all errors are handled" | |
| 156 | + | end | |
| 157 | + | ``` | |
| 158 | + | ||
| 159 | + | ### Errors | |
| 160 | + | ||
| 161 | + | ```elixir | |
| 162 | + | try do | |
| 163 | + | throw(:hello) | |
| 164 | + | catch | |
| 165 | + | message -> "Got #{message}." | |
| 166 | + | after | |
| 167 | + | IO.puts("I'm the after clause.") | |
| 168 | + | end | |
| 169 | + | ``` | |
| 170 | + | ||
| 171 | + | ## Types | |
| 172 | + | ||
| 173 | + | ### Primitives | |
| 174 | + | ||
| 175 | + | | Sample | Type | | |
| 176 | + | | --- | --- | | |
| 177 | + | | `nil` | Nil/null | | |
| 178 | + | | `true` _/_ `false` | Boolean | | |
| 179 | + | | --- | --- | | |
| 180 | + | | `?a` | Integer (ASCII) | | |
| 181 | + | | `23` | Integer | | |
| 182 | + | | `3.14` | Float | | |
| 183 | + | | --- | --- | | |
| 184 | + | | `'hello'` | Charlist | | |
| 185 | + | | `<<2, 3>>` | Binary | | |
| 186 | + | | `"hello"` | Binary string | | |
| 187 | + | | `:hello` | Atom | | |
| 188 | + | | --- | --- | | |
| 189 | + | | `[a, b]` | List | | |
| 190 | + | | `{a, b}` | Tuple | | |
| 191 | + | | --- | --- | | |
| 192 | + | | `%{a: "hello"}` | Map | | |
| 193 | + | | `%MyStruct{a: "hello"}` | Struct | | |
| 194 | + | | `fn -> ... end` | Function | | |
| 195 | + | ||
| 196 | + | ### Type checks | |
| 197 | + | ||
| 198 | + | ```elixir | |
| 199 | + | is_atom/1 | |
| 200 | + | is_bitstring/1 | |
| 201 | + | is_boolean/1 | |
| 202 | + | is_function/1 | |
| 203 | + | is_function/2 | |
| 204 | + | is_integer/1 | |
| 205 | + | is_float/1 | |
| 206 | + | ``` | |
| 207 | + | ||
| 208 | + | ```elixir | |
| 209 | + | is_binary/1 | |
| 210 | + | is_list/1 | |
| 211 | + | is_map/1 | |
| 212 | + | is_tuple/1 | |
| 213 | + | ``` | |
| 214 | + | ||
| 215 | + | ```elixir | |
| 216 | + | is_nil/1 | |
| 217 | + | is_number/1 | |
| 218 | + | is_pid/1 | |
| 219 | + | is_port/1 | |
| 220 | + | is_reference/1 | |
| 221 | + | ``` | |
| 222 | + | ||
| 223 | + | ### Operators | |
| 224 | + | ||
| 225 | + | ```elixir | |
| 226 | + | left != right # equal | |
| 227 | + | left !== right # match | |
| 228 | + | left ++ right # concat lists | |
| 229 | + | left <> right # concat string/binary | |
| 230 | + | left =~ right # regexp | |
| 231 | + | ``` | |
| 232 | + | ||
| 233 | + | Modules | |
| 234 | + | ------- | |
| 235 | + | ||
| 236 | + | ### Importing | |
| 237 | + | ||
| 238 | + | ```elixir | |
| 239 | + | require Redux # compiles a module | |
| 240 | + | import Redux # compiles, and you can use without the `Redux.` prefix | |
| 241 | + | ||
| 242 | + | use Redux # compiles, and runs Redux.__using__/1 | |
| 243 | + | use Redux, async: true | |
| 244 | + | ||
| 245 | + | import Redux, only: [duplicate: 2] | |
| 246 | + | import Redux, only: :functions | |
| 247 | + | import Redux, only: :macros | |
| 248 | + | ||
| 249 | + | import Foo.{Bar, Baz} | |
| 250 | + | ``` | |
| 251 | + | ||
| 252 | + | ### Aliases | |
| 253 | + | ||
| 254 | + | ```elixir | |
| 255 | + | alias Foo.Bar, as: Bar | |
| 256 | + | alias Foo.Bar # same as above | |
| 257 | + | ||
| 258 | + | alias Foo.{Bar, Baz} | |
| 259 | + | ``` | |
| 260 | + | ||
| 261 | + | ## String | |
| 262 | + | ||
| 263 | + | ### Functions | |
| 264 | + | ||
| 265 | + | ```elixir | |
| 266 | + | import String | |
| 267 | + | ``` | |
| 268 | + | {: .-setup} | |
| 269 | + | ||
| 270 | + | ```elixir | |
| 271 | + | str = "hello" | |
| 272 | + | str |> length() # → 5 | |
| 273 | + | str |> codepoints() # → ["h", "e", "l", "l", "o"] | |
| 274 | + | str |> slice(2..-1) # → "llo" | |
| 275 | + | str |> split(" ") # → ["hello"] | |
| 276 | + | str |> capitalize() # → "Hello" | |
| 277 | + | str |> match(regex) | |
| 278 | + | ``` | |
| 279 | + | ||
| 280 | + | ### Inspecting objects | |
| 281 | + | ||
| 282 | + | ```elixir | |
| 283 | + | inspect(object, opts \\ []) | |
| 284 | + | ``` | |
| 285 | + | ```elixir | |
| 286 | + | value |> IO.inspect() | |
| 287 | + | ``` | |
| 288 | + | ```elixir | |
| 289 | + | value |> IO.inspect(label: "value") | |
| 290 | + | ``` | |
| 291 | + | ||
| 292 | + | ## Numbers | |
| 293 | + | ||
| 294 | + | ### Operations | |
| 295 | + | ||
| 296 | + | ```elixir | |
| 297 | + | abs(n) | |
| 298 | + | round(n) | |
| 299 | + | rem(a, b) # remainder (modulo) | |
| 300 | + | div(a, b) # integer division | |
| 301 | + | ``` | |
| 302 | + | ||
| 303 | + | ### Float | |
| 304 | + | ||
| 305 | + | ```elixir | |
| 306 | + | import Float | |
| 307 | + | ``` | |
| 308 | + | {: .-setup} | |
| 309 | + | ||
| 310 | + | ```elixir | |
| 311 | + | n = 10.3 | |
| 312 | + | ``` | |
| 313 | + | {: .-setup} | |
| 314 | + | ||
| 315 | + | ```elixir | |
| 316 | + | n |> ceil() # → 11.0 | |
| 317 | + | n |> ceil(2) # → 11.30 | |
| 318 | + | n |> to_string() # → "1.030000+e01" | |
| 319 | + | n |> to_string([decimals: 2, compact: true]) | |
| 320 | + | ``` | |
| 321 | + | ||
| 322 | + | ```elixir | |
| 323 | + | Float.parse("34") # → { 34.0, "" } | |
| 324 | + | ``` | |
| 325 | + | ||
| 326 | + | ### Integer | |
| 327 | + | ||
| 328 | + | ```elixir | |
| 329 | + | import Integer | |
| 330 | + | ``` | |
| 331 | + | {: .-setup} | |
| 332 | + | ||
| 333 | + | ```elixir | |
| 334 | + | n = 12 | |
| 335 | + | ``` | |
| 336 | + | {: .-setup} | |
| 337 | + | ||
| 338 | + | ```elixir | |
| 339 | + | n |> digits() # → [1, 2] | |
| 340 | + | n |> to_charlist() # → '12' | |
| 341 | + | n |> to_string() # → "12" | |
| 342 | + | n |> is_even() | |
| 343 | + | n |> is_odd() | |
| 344 | + | ``` | |
| 345 | + | ||
| 346 | + | ```elixir | |
| 347 | + | # Different base: | |
| 348 | + | n |> digits(2) # → [1, 1, 0, 0] | |
| 349 | + | n |> to_charlist(2) # → '1100' | |
| 350 | + | n |> to_string(2) # → "1100" | |
| 351 | + | ``` | |
| 352 | + | ||
| 353 | + | ```elixir | |
| 354 | + | parse("12") # → {12, ""} | |
| 355 | + | undigits([1, 2]) # → 12 | |
| 356 | + | ``` | |
| 357 | + | ||
| 358 | + | ### Type casting | |
| 359 | + | ||
| 360 | + | ```elixir | |
| 361 | + | Float.parse("34.1") # → {34.1, ""} | |
| 362 | + | Integer.parse("34") # → {34, ""} | |
| 363 | + | ``` | |
| 364 | + | ||
| 365 | + | ```elixir | |
| 366 | + | Float.to_string(34.1) # → "3.4100e+01" | |
| 367 | + | Float.to_string(34.1, [decimals: 2, compact: true]) # → "34.1" | |
| 368 | + | ``` | |
| 369 | + | ||
| 370 | + | ## Map | |
| 371 | + | ||
| 372 | + | ### Defining | |
| 373 | + | ||
| 374 | + | ```elixir | |
| 375 | + | m = %{name: "hi"} # atom keys (:name) | |
| 376 | + | m = %{"name" => "hi"} # string keys ("name") | |
| 377 | + | ``` | |
| 378 | + | ||
| 379 | + | ### Updating | |
| 380 | + | ||
| 381 | + | ```elixir | |
| 382 | + | import Map | |
| 383 | + | ``` | |
| 384 | + | {: .-setup} | |
| 385 | + | ||
| 386 | + | ```elixir | |
| 387 | + | m = %{m | name: "yo"} # key must exist | |
| 388 | + | ``` | |
| 389 | + | ||
| 390 | + | ```elixir | |
| 391 | + | m |> put(:id, 2) # → %{id: 2, name: "hi"} | |
| 392 | + | m |> put_new(:id, 2) # only if `id` doesn't exist (`||=`) | |
| 393 | + | ``` | |
| 394 | + | ||
| 395 | + | ```elixir | |
| 396 | + | m |> put(:b, "Banana") | |
| 397 | + | m |> merge(%{b: "Banana"}) | |
| 398 | + | m |> update(:a, &(&1 + 1)) | |
| 399 | + | m |> update(:a, fun a -> a + 1 end) | |
| 400 | + | ``` | |
| 401 | + | ||
| 402 | + | ```elixir | |
| 403 | + | m |> get_and_update(:a, &(&1 || "default")) | |
| 404 | + | # → {old, new} | |
| 405 | + | ``` | |
| 406 | + | ||
| 407 | + | ### Deleting | |
| 408 | + | ||
| 409 | + | ```elixir | |
| 410 | + | m |> delete(:name) # → %{} | |
| 411 | + | m |> pop(:name) # → {"John", %{}} | |
| 412 | + | ``` | |
| 413 | + | ||
| 414 | + | ### Reading | |
| 415 | + | ||
| 416 | + | ```elixir | |
| 417 | + | m |> get(:id) # → 1 | |
| 418 | + | m |> keys() # → [:id, :name] | |
| 419 | + | m |> values() # → [1, "hi"] | |
| 420 | + | ``` | |
| 421 | + | ||
| 422 | + | ```elixir | |
| 423 | + | m |> to_list() # → [id: 1, name: "hi"] | |
| 424 | + | # → [{:id, 1}, {:name, "hi"}] | |
| 425 | + | ``` | |
| 426 | + | ||
| 427 | + | ### Deep | |
| 428 | + | ||
| 429 | + | ```elixir | |
| 430 | + | put_in(map, [:b, :c], "Banana") | |
| 431 | + | put_in(map[:b][:c], "Banana") # via macros | |
| 432 | + | ``` | |
| 433 | + | ||
| 434 | + | ```elixir | |
| 435 | + | get_and_update_in(users, ["john", :age], &{&1, &1 + 1}) | |
| 436 | + | ``` | |
| 437 | + | ||
| 438 | + | ### Constructing from lists | |
| 439 | + | ||
| 440 | + | ```elixir | |
| 441 | + | Map.new([{:b, 1}, {:a, 2}]) | |
| 442 | + | Map.new([a: 1, b: 2]) | |
| 443 | + | Map.new([:a, :b], fn x -> {x, x} end) # → %{a: :a, b: :b} | |
| 444 | + | ``` | |
| 445 | + | ||
| 446 | + | ### Working with structs | |
| 447 | + | ||
| 448 | + | #### Struct to map | |
| 449 | + | ||
| 450 | + | ```elixir | |
| 451 | + | Map.from_struct(%AnyStruct{a: "b"}) # → %{a: "b"} | |
| 452 | + | ``` | |
| 453 | + | ||
| 454 | + | #### Map to struct | |
| 455 | + | ||
| 456 | + | ```elixir | |
| 457 | + | struct(AnyStruct, %{a: "b"}) # → %AnyStruct{a: "b"} | |
| 458 | + | ``` | |
| 459 | + | ||
| 460 | + | ## List | |
| 461 | + | ||
| 462 | + | ```elixir | |
| 463 | + | import List | |
| 464 | + | ``` | |
| 465 | + | {: .-setup} | |
| 466 | + | ||
| 467 | + | ```elixir | |
| 468 | + | l = [ 1, 2, 3, 4 ] | |
| 469 | + | ``` | |
| 470 | + | {: .-setup} | |
| 471 | + | ||
| 472 | + | ```elixir | |
| 473 | + | l = l ++ [5] # push (append) | |
| 474 | + | l = [ 0 | list ] # unshift (prepend) | |
| 475 | + | ``` | |
| 476 | + | ||
| 477 | + | ```elixir | |
| 478 | + | l |> first() | |
| 479 | + | l |> last() | |
| 480 | + | ``` | |
| 481 | + | ||
| 482 | + | ```elixir | |
| 483 | + | l |> flatten() | |
| 484 | + | l |> flatten(tail) | |
| 485 | + | ``` | |
| 486 | + | ||
| 487 | + | Also see [Enum](#enum). | |
| 488 | + | ||
| 489 | + | ||
| 490 | + | ## Enum | |
| 491 | + | ||
| 492 | + | ### Usage | |
| 493 | + | ||
| 494 | + | ```elixir | |
| 495 | + | import Enum | |
| 496 | + | ``` | |
| 497 | + | {: .-setup} | |
| 498 | + | ||
| 499 | + | ```elixir | |
| 500 | + | list = [:a, :b, :c] | |
| 501 | + | ``` | |
| 502 | + | {: .-setup} | |
| 503 | + | ||
| 504 | + | ```elixir | |
| 505 | + | list |> at(0) # → :a | |
| 506 | + | list |> count() # → 3 | |
| 507 | + | list |> empty?() # → false | |
| 508 | + | list |> any?() # → true | |
| 509 | + | ``` | |
| 510 | + | ||
| 511 | + | ```elixir | |
| 512 | + | list |> concat([:d]) # → [:a, :b, :c, :d] | |
| 513 | + | ``` | |
| 514 | + | ||
| 515 | + | Also, consider streams instead. | |
| 516 | + | ||
| 517 | + | ### Map/reduce | |
| 518 | + | ||
| 519 | + | ```elixir | |
| 520 | + | list |> reduce(fn) | |
| 521 | + | list |> reduce(acc, fn) | |
| 522 | + | list |> map(fn) | |
| 523 | + | list |> reject(fn) | |
| 524 | + | list |> any?(fn) | |
| 525 | + | list |> empty?(fn) | |
| 526 | + | ``` | |
| 527 | + | ||
| 528 | + | ```elixir | |
| 529 | + | [1, 2, 3, 4] | |
| 530 | + | |> Enum.reduce(0, fn(x, acc) -> x + acc end) | |
| 531 | + | ``` | |
| 532 | + | ||
| 533 | + | ## Tuple | |
| 534 | + | ||
| 535 | + | ### Tuples | |
| 536 | + | ||
| 537 | + | ```elixir | |
| 538 | + | import Tuple | |
| 539 | + | ``` | |
| 540 | + | {: .-setup} | |
| 541 | + | ||
| 542 | + | ```elixir | |
| 543 | + | t = { :a, :b } | |
| 544 | + | ``` | |
| 545 | + | ||
| 546 | + | ```elixir | |
| 547 | + | t |> elem(1) # like tuple[1] | |
| 548 | + | t |> put_elem(index, value) | |
| 549 | + | t |> tuple_size() | |
| 550 | + | ``` | |
| 551 | + | ||
| 552 | + | ### Keyword lists | |
| 553 | + | ||
| 554 | + | ```elixir | |
| 555 | + | list = [{ :name, "John" }, { :age, 15 }] | |
| 556 | + | list[:name] | |
| 557 | + | ``` | |
| 558 | + | ||
| 559 | + | ```elixir | |
| 560 | + | # For string-keyed keyword lists | |
| 561 | + | list = [{"size", 2}, {"type", "shoe"}] | |
| 562 | + | List.keyfind(list, "size", 0) # → {"size", 2} | |
| 563 | + | ``` | |
| 564 | + | ||
| 565 | + | ## Functions | |
| 566 | + | ||
| 567 | + | ### Lambdas | |
| 568 | + | ||
| 569 | + | ```elixir | |
| 570 | + | square = fn n -> n*n end | |
| 571 | + | square.(20) | |
| 572 | + | ``` | |
| 573 | + | ||
| 574 | + | ### & syntax | |
| 575 | + | ||
| 576 | + | ```elixir | |
| 577 | + | square = &(&1 * &1) | |
| 578 | + | square.(20) | |
| 579 | + | ||
| 580 | + | square = &Math.square/1 | |
| 581 | + | ``` | |
| 582 | + | ||
| 583 | + | ### Running | |
| 584 | + | ||
| 585 | + | ```elixir | |
| 586 | + | fun.(args) | |
| 587 | + | apply(fun, args) | |
| 588 | + | apply(module, fun, args) | |
| 589 | + | ``` | |
| 590 | + | ||
| 591 | + | ### Function heads | |
| 592 | + | ||
| 593 | + | ```elixir | |
| 594 | + | def join(a, b \\ nil) | |
| 595 | + | def join(a, b) when is_nil(b) do: a | |
| 596 | + | def join(a, b) do: a <> b | |
| 597 | + | ``` | |
| 598 | + | ||
| 599 | + | ## Structs | |
| 600 | + | ||
| 601 | + | ### Structs | |
| 602 | + | ||
| 603 | + | ```elixir | |
| 604 | + | defmodule User do | |
| 605 | + | defstruct name: "", age: nil | |
| 606 | + | end | |
| 607 | + | ||
| 608 | + | %User{name: "John", age: 20} | |
| 609 | + | ||
| 610 | + | %User{}.struct # → User | |
| 611 | + | ``` | |
| 612 | + | ||
| 613 | + | See: [Structs](http://elixir-lang.org/getting-started/structs.html) | |
| 614 | + | ||
| 615 | + | ## Protocols | |
| 616 | + | ||
| 617 | + | ### Defining protocols | |
| 618 | + | ||
| 619 | + | ```elixir | |
| 620 | + | defprotocol Blank do | |
| 621 | + | @doc "Returns true if data is considered blank/empty" | |
| 622 | + | def blank?(data) | |
| 623 | + | end | |
| 624 | + | ``` | |
| 625 | + | ||
| 626 | + | ```elixir | |
| 627 | + | defimpl Blank, for: List do | |
| 628 | + | def blank?([]), do: true | |
| 629 | + | def blank?(_), do: false | |
| 630 | + | end | |
| 631 | + | ||
| 632 | + | Blank.blank?([]) # → true | |
| 633 | + | ``` | |
| 634 | + | ||
| 635 | + | ### Any | |
| 636 | + | ||
| 637 | + | ```elixir | |
| 638 | + | defimpl Blank, for: Any do ... end | |
| 639 | + | ||
| 640 | + | defmodule User do | |
| 641 | + | @derive Blank # Falls back to Any | |
| 642 | + | defstruct name: "" | |
| 643 | + | end | |
| 644 | + | ``` | |
| 645 | + | ||
| 646 | + | ### Examples | |
| 647 | + | ||
| 648 | + | - `Enumerable` and `Enum.map()` | |
| 649 | + | - `Inspect` and `inspect()` | |
| 650 | + | ||
| 651 | + | ## Comprehensions | |
| 652 | + | ||
| 653 | + | ### For | |
| 654 | + | ||
| 655 | + | ```elixir | |
| 656 | + | for n <- [1, 2, 3, 4], do: n * n | |
| 657 | + | for n <- 1..4, do: n * n | |
| 658 | + | ``` | |
| 659 | + | ||
| 660 | + | ```elixir | |
| 661 | + | for {key, val} <- %{a: 10, b: 20}, do: val | |
| 662 | + | # → [10, 20] | |
| 663 | + | ``` | |
| 664 | + | ||
| 665 | + | ```elixir | |
| 666 | + | for {key, val} <- %{a: 10, b: 20}, into: %{}, do: {key, val*val} | |
| 667 | + | ``` | |
| 668 | + | ||
| 669 | + | ### Conditions | |
| 670 | + | ||
| 671 | + | ```elixir | |
| 672 | + | for n <- 1..10, rem(n, 2) == 0, do: n | |
| 673 | + | # → [2, 4, 6, 8, 10] | |
| 674 | + | ``` | |
| 675 | + | ||
| 676 | + | ### Complex | |
| 677 | + | ||
| 678 | + | ```elixir | |
| 679 | + | for dir <- dirs, | |
| 680 | + | file <- File.ls!(dir), # nested comprehension | |
| 681 | + | path = Path.join(dir, file), # invoked | |
| 682 | + | File.regular?(path) do # condition | |
| 683 | + | IO.puts(file) | |
| 684 | + | end | |
| 685 | + | ``` | |
| 686 | + | ||
| 687 | + | ## Misc | |
| 688 | + | ||
| 689 | + | ### Metaprogramming | |
| 690 | + | ||
| 691 | + | ```elixir | |
| 692 | + | __MODULE__ | |
| 693 | + | __MODULE__.__info__ | |
| 694 | + | ||
| 695 | + | @after_compile __MODULE__ | |
| 696 | + | def __before_compile__(env) | |
| 697 | + | def __after_compile__(env, _bytecode) | |
| 698 | + | def __using__(opts) # invoked on `use` | |
| 699 | + | ||
| 700 | + | @on_definition {__MODULE__, :on_def} | |
| 701 | + | def on_def(_env, kind, name, args, guards, body) | |
| 702 | + | ||
| 703 | + | @on_load :load_check | |
| 704 | + | def load_check | |
| 705 | + | ``` | |
| 706 | + | ||
| 707 | + | ### Regexp | |
| 708 | + | ||
| 709 | + | ```elixir | |
| 710 | + | exp = ~r/hello/ | |
| 711 | + | exp = ~r/hello/i | |
| 712 | + | "hello world" =~ exp | |
| 713 | + | ``` | |
| 714 | + | ||
| 715 | + | ### Sigils | |
| 716 | + | ||
| 717 | + | ```elixir | |
| 718 | + | ~r/regexp/ | |
| 719 | + | ~w(list of strings) | |
| 720 | + | ~s|strings with #{interpolation} and \x20 escape codes| | |
| 721 | + | ~S|no interpolation and no escapes| | |
| 722 | + | ~c(charlist) | |
| 723 | + | ``` | |
| 724 | + | ||
| 725 | + | Allowed chars: `/` `|` `"` `'` `(` `[` `{` `<` `"""`. | |
| 726 | + | See: [Sigils](http://elixir-lang.org/getting-started/sigils.html) | |
| 727 | + | ||
| 728 | + | ### Type specs | |
| 729 | + | ||
| 730 | + | ```elixir | |
| 731 | + | @spec round(number) :: integer | |
| 732 | + | ||
| 733 | + | @type number_with_remark :: {number, String.t} | |
| 734 | + | @spec add(number, number) :: number_with_remark | |
| 735 | + | ``` | |
| 736 | + | ||
| 737 | + | Useful for [dialyzer](http://www.erlang.org/doc/man/dialyzer.html). | |
| 738 | + | See: [Typespecs](http://elixir-lang.org/getting-started/typespecs-and-behaviours.html) | |
| 739 | + | ||
| 740 | + | ### Behaviours | |
| 741 | + | ||
| 742 | + | ```elixir | |
| 743 | + | defmodule Parser do | |
| 744 | + | @callback parse(String.t) :: any | |
| 745 | + | @callback extensions() :: [String.t] | |
| 746 | + | end | |
| 747 | + | ``` | |
| 748 | + | ||
| 749 | + | ```elixir | |
| 750 | + | defmodule JSONParser do | |
| 751 | + | @behaviour Parser | |
| 752 | + | ||
| 753 | + | def parse(str), do: # ... parse JSON | |
| 754 | + | def extensions, do: ["json"] | |
| 755 | + | end | |
| 756 | + | ``` | |
| 757 | + | ||
| 758 | + | See: [Module](http://elixir-lang.org/docs/stable/elixir/Module.html) | |
| 759 | + | ||
| 760 | + | ## References | |
| 761 | + | {: .-one-column} | |
| 762 | + | ||
| 763 | + | - [Learn Elixir in Y minutes](https://learnxinyminutes.com/docs/elixir/) | |
| 764 | + | ||
| 765 | + | https://devhints.io/ cheatsheets - Copyright (c) 2021 Rico Sta. Cruz and contributors - MIT license | |
| 766 | + | micro-cheat plugin Copyright 2022 Tero Karvinen https://TeroKarvinen.com/micro - MIT license |
| ... | ... | @@ -0,0 +1,582 @@ | |
| 1 | + | --- | |
| 2 | + | title: ES2015+ | |
| 3 | + | category: JavaScript | |
| 4 | + | layout: 2017/sheet | |
| 5 | + | tags: [Featured] | |
| 6 | + | updated: 2019-11-14 | |
| 7 | + | weight: -10 | |
| 8 | + | intro: | | |
| 9 | + | A quick overview of new JavaScript features in ES2015, ES2016, ES2017, ES2018 and beyond. | |
| 10 | + | --- | |
| 11 | + | ||
| 12 | + | ### Block scoping | |
| 13 | + | ||
| 14 | + | #### Let | |
| 15 | + | ||
| 16 | + | ```js | |
| 17 | + | function fn () { | |
| 18 | + | let x = 0 | |
| 19 | + | if (true) { | |
| 20 | + | let x = 1 // only inside this `if` | |
| 21 | + | } | |
| 22 | + | } | |
| 23 | + | ``` | |
| 24 | + | {: data-line="2,4"} | |
| 25 | + | ||
| 26 | + | #### Const | |
| 27 | + | ||
| 28 | + | ```js | |
| 29 | + | const a = 1 | |
| 30 | + | ``` | |
| 31 | + | ||
| 32 | + | `let` is the new `var`. Constants work just like `let`, but can't be reassigned. | |
| 33 | + | See: [Let and const](https://babeljs.io/learn-es2015/#let--const) | |
| 34 | + | ||
| 35 | + | ### Backtick strings | |
| 36 | + | ||
| 37 | + | #### Interpolation | |
| 38 | + | ||
| 39 | + | ```js | |
| 40 | + | const message = `Hello ${name}` | |
| 41 | + | ``` | |
| 42 | + | ||
| 43 | + | #### Multiline strings | |
| 44 | + | ||
| 45 | + | ```js | |
| 46 | + | const str = ` | |
| 47 | + | hello | |
| 48 | + | world | |
| 49 | + | ` | |
| 50 | + | ``` | |
| 51 | + | ||
| 52 | + | Templates and multiline strings. | |
| 53 | + | See: [Template strings](https://babeljs.io/learn-es2015/#template-strings) | |
| 54 | + | ||
| 55 | + | ### Binary and octal literals | |
| 56 | + | ||
| 57 | + | ```js | |
| 58 | + | let bin = 0b1010010 | |
| 59 | + | let oct = 0o755 | |
| 60 | + | ``` | |
| 61 | + | ||
| 62 | + | See: [Binary and octal literals](https://babeljs.io/learn-es2015/#binary-and-octal-literals) | |
| 63 | + | ||
| 64 | + | ### New methods | |
| 65 | + | ||
| 66 | + | #### New string methods | |
| 67 | + | ||
| 68 | + | ```js | |
| 69 | + | "hello".repeat(3) | |
| 70 | + | "hello".includes("ll") | |
| 71 | + | "hello".startsWith("he") | |
| 72 | + | "hello".padStart(8) // " hello" | |
| 73 | + | "hello".padEnd(8) // "hello " | |
| 74 | + | "hello".padEnd(8, '!') // hello!!! | |
| 75 | + | "\u1E9B\u0323".normalize("NFC") | |
| 76 | + | ``` | |
| 77 | + | ||
| 78 | + | See: [New methods](https://babeljs.io/learn-es2015/#math--number--string--object-apis) | |
| 79 | + | ||
| 80 | + | ### Classes | |
| 81 | + | ||
| 82 | + | ```js | |
| 83 | + | class Circle extends Shape { | |
| 84 | + | ``` | |
| 85 | + | ||
| 86 | + | #### Constructor | |
| 87 | + | ||
| 88 | + | ```js | |
| 89 | + | constructor (radius) { | |
| 90 | + | this.radius = radius | |
| 91 | + | } | |
| 92 | + | ``` | |
| 93 | + | {: data-line="1"} | |
| 94 | + | ||
| 95 | + | #### Methods | |
| 96 | + | ||
| 97 | + | ```js | |
| 98 | + | getArea () { | |
| 99 | + | return Math.PI * 2 * this.radius | |
| 100 | + | } | |
| 101 | + | ``` | |
| 102 | + | {: data-line="1"} | |
| 103 | + | ||
| 104 | + | #### Calling superclass methods | |
| 105 | + | ||
| 106 | + | ```js | |
| 107 | + | expand (n) { | |
| 108 | + | return super.expand(n) * Math.PI | |
| 109 | + | } | |
| 110 | + | ``` | |
| 111 | + | {: data-line="2"} | |
| 112 | + | ||
| 113 | + | #### Static methods | |
| 114 | + | ||
| 115 | + | ```js | |
| 116 | + | static createFromDiameter(diameter) { | |
| 117 | + | return new Circle(diameter / 2) | |
| 118 | + | } | |
| 119 | + | } | |
| 120 | + | ``` | |
| 121 | + | {: data-line="1"} | |
| 122 | + | ||
| 123 | + | Syntactic sugar for prototypes. | |
| 124 | + | See: [Classes](https://babeljs.io/learn-es2015/#classes) | |
| 125 | + | ||
| 126 | + | ### Exponent operator | |
| 127 | + | ||
| 128 | + | ```js | |
| 129 | + | const byte = 2 ** 8 | |
| 130 | + | // Same as: Math.pow(2, 8) | |
| 131 | + | ``` | |
| 132 | + | {: data-line="1"} | |
| 133 | + | ||
| 134 | + | Promises | |
| 135 | + | -------- | |
| 136 | + | {: .-three-column} | |
| 137 | + | ||
| 138 | + | ### Making promises | |
| 139 | + | ||
| 140 | + | ```js | |
| 141 | + | new Promise((resolve, reject) => { | |
| 142 | + | if (ok) { resolve(result) } | |
| 143 | + | else { reject(error) } | |
| 144 | + | }) | |
| 145 | + | ``` | |
| 146 | + | {: data-line="1"} | |
| 147 | + | ||
| 148 | + | For asynchronous programming. | |
| 149 | + | See: [Promises](https://babeljs.io/learn-es2015/#promises) | |
| 150 | + | ||
| 151 | + | ### Using promises | |
| 152 | + | ||
| 153 | + | ```js | |
| 154 | + | promise | |
| 155 | + | .then((result) => { ··· }) | |
| 156 | + | .catch((error) => { ··· }) | |
| 157 | + | ``` | |
| 158 | + | {: data-line="2,3"} | |
| 159 | + | ||
| 160 | + | ||
| 161 | + | ### Using promises with finally | |
| 162 | + | ||
| 163 | + | ```js | |
| 164 | + | promise | |
| 165 | + | .then((result) => { ··· }) | |
| 166 | + | .catch((error) => { ··· }) | |
| 167 | + | .finally(() => { // logic independent of success/error }) | |
| 168 | + | ``` | |
| 169 | + | {: data-line="4"} | |
| 170 | + | ||
| 171 | + | The handler is called when the promise is fulfilled or rejected. | |
| 172 | + | ||
| 173 | + | ||
| 174 | + | ### Promise functions | |
| 175 | + | ||
| 176 | + | ```js | |
| 177 | + | Promise.all(···) | |
| 178 | + | Promise.race(···) | |
| 179 | + | Promise.reject(···) | |
| 180 | + | Promise.resolve(···) | |
| 181 | + | ``` | |
| 182 | + | ||
| 183 | + | ### Async-await | |
| 184 | + | ||
| 185 | + | ```js | |
| 186 | + | async function run () { | |
| 187 | + | const user = await getUser() | |
| 188 | + | const tweets = await getTweets(user) | |
| 189 | + | return [user, tweets] | |
| 190 | + | } | |
| 191 | + | ``` | |
| 192 | + | {: data-line="2,3"} | |
| 193 | + | ||
| 194 | + | `async` functions are another way of using functions. | |
| 195 | + | ||
| 196 | + | See: [async function](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/async_function) | |
| 197 | + | ||
| 198 | + | Destructuring | |
| 199 | + | ------------- | |
| 200 | + | {: .-three-column} | |
| 201 | + | ||
| 202 | + | ### Destructuring assignment | |
| 203 | + | ||
| 204 | + | #### Arrays | |
| 205 | + | ||
| 206 | + | ```js | |
| 207 | + | const [first, last] = ['Nikola', 'Tesla'] | |
| 208 | + | ``` | |
| 209 | + | {: data-line="1"} | |
| 210 | + | ||
| 211 | + | #### Objects | |
| 212 | + | ||
| 213 | + | ```js | |
| 214 | + | let {title, author} = { | |
| 215 | + | title: 'The Silkworm', | |
| 216 | + | author: 'R. Galbraith' | |
| 217 | + | } | |
| 218 | + | ``` | |
| 219 | + | {: data-line="1"} | |
| 220 | + | ||
| 221 | + | Supports for matching arrays and objects. | |
| 222 | + | See: [Destructuring](https://babeljs.io/learn-es2015/#destructuring) | |
| 223 | + | ||
| 224 | + | ### Default values | |
| 225 | + | ||
| 226 | + | ```js | |
| 227 | + | const scores = [22, 33] | |
| 228 | + | const [math = 50, sci = 50, arts = 50] = scores | |
| 229 | + | ``` | |
| 230 | + | ||
| 231 | + | ```js | |
| 232 | + | // Result: | |
| 233 | + | // math === 22, sci === 33, arts === 50 | |
| 234 | + | ``` | |
| 235 | + | ||
| 236 | + | Default values can be assigned while destructuring arrays or objects. | |
| 237 | + | ||
| 238 | + | ### Function arguments | |
| 239 | + | ||
| 240 | + | ```js | |
| 241 | + | function greet({ name, greeting }) { | |
| 242 | + | console.log(`${greeting}, ${name}!`) | |
| 243 | + | } | |
| 244 | + | ``` | |
| 245 | + | {: data-line="1"} | |
| 246 | + | ||
| 247 | + | ```js | |
| 248 | + | greet({ name: 'Larry', greeting: 'Ahoy' }) | |
| 249 | + | ``` | |
| 250 | + | ||
| 251 | + | Destructuring of objects and arrays can also be done in function arguments. | |
| 252 | + | ||
| 253 | + | ### Default values | |
| 254 | + | ||
| 255 | + | ```js | |
| 256 | + | function greet({ name = 'Rauno' } = {}) { | |
| 257 | + | console.log(`Hi ${name}!`); | |
| 258 | + | } | |
| 259 | + | ``` | |
| 260 | + | {: data-line="1"} | |
| 261 | + | ||
| 262 | + | ```js | |
| 263 | + | greet() // Hi Rauno! | |
| 264 | + | greet({ name: 'Larry' }) // Hi Larry! | |
| 265 | + | ``` | |
| 266 | + | ||
| 267 | + | ### Reassigning keys | |
| 268 | + | ||
| 269 | + | ```js | |
| 270 | + | function printCoordinates({ left: x, top: y }) { | |
| 271 | + | console.log(`x: ${x}, y: ${y}`) | |
| 272 | + | } | |
| 273 | + | ``` | |
| 274 | + | {: data-line="1"} | |
| 275 | + | ||
| 276 | + | ```js | |
| 277 | + | printCoordinates({ left: 25, top: 90 }) | |
| 278 | + | ``` | |
| 279 | + | ||
| 280 | + | This example assigns `x` to the value of the `left` key. | |
| 281 | + | ||
| 282 | + | ### Loops | |
| 283 | + | ||
| 284 | + | ```js | |
| 285 | + | for (let {title, artist} of songs) { | |
| 286 | + | ··· | |
| 287 | + | } | |
| 288 | + | ``` | |
| 289 | + | {: data-line="1"} | |
| 290 | + | ||
| 291 | + | The assignment expressions work in loops, too. | |
| 292 | + | ||
| 293 | + | ||
| 294 | + | ### Object destructuring | |
| 295 | + | ||
| 296 | + | ```js | |
| 297 | + | const { id, ...detail } = song; | |
| 298 | + | ``` | |
| 299 | + | {: data-line="1"} | |
| 300 | + | ||
| 301 | + | Extract some keys individually and remaining keys in the object using rest (...) operator | |
| 302 | + | ||
| 303 | + | ||
| 304 | + | Spread | |
| 305 | + | ------ | |
| 306 | + | ||
| 307 | + | ### Object spread | |
| 308 | + | ||
| 309 | + | #### with Object spread | |
| 310 | + | ||
| 311 | + | ```js | |
| 312 | + | const options = { | |
| 313 | + | ...defaults, | |
| 314 | + | visible: true | |
| 315 | + | } | |
| 316 | + | ``` | |
| 317 | + | {: data-line="2"} | |
| 318 | + | ||
| 319 | + | #### without Object spread | |
| 320 | + | ||
| 321 | + | ```js | |
| 322 | + | const options = Object.assign( | |
| 323 | + | {}, defaults, | |
| 324 | + | { visible: true }) | |
| 325 | + | ``` | |
| 326 | + | ||
| 327 | + | The Object spread operator lets you build new objects from other objects. | |
| 328 | + | ||
| 329 | + | See: [Object spread](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Spread_operator) | |
| 330 | + | ||
| 331 | + | ### Array spread | |
| 332 | + | ||
| 333 | + | #### with Array spread | |
| 334 | + | ||
| 335 | + | ```js | |
| 336 | + | const users = [ | |
| 337 | + | ...admins, | |
| 338 | + | ...editors, | |
| 339 | + | 'rstacruz' | |
| 340 | + | ] | |
| 341 | + | ``` | |
| 342 | + | {: data-line="2,3"} | |
| 343 | + | ||
| 344 | + | #### without Array spread | |
| 345 | + | ||
| 346 | + | ```js | |
| 347 | + | const users = admins | |
| 348 | + | .concat(editors) | |
| 349 | + | .concat([ 'rstacruz' ]) | |
| 350 | + | ``` | |
| 351 | + | ||
| 352 | + | The spread operator lets you build new arrays in the same way. | |
| 353 | + | ||
| 354 | + | See: [Spread operator](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Spread_operator) | |
| 355 | + | ||
| 356 | + | Functions | |
| 357 | + | --------- | |
| 358 | + | ||
| 359 | + | ### Function arguments | |
| 360 | + | ||
| 361 | + | #### Default arguments | |
| 362 | + | ||
| 363 | + | ```js | |
| 364 | + | function greet (name = 'Jerry') { | |
| 365 | + | return `Hello ${name}` | |
| 366 | + | } | |
| 367 | + | ``` | |
| 368 | + | {: data-line="1"} | |
| 369 | + | ||
| 370 | + | #### Rest arguments | |
| 371 | + | ||
| 372 | + | ```js | |
| 373 | + | function fn(x, ...y) { | |
| 374 | + | // y is an Array | |
| 375 | + | return x * y.length | |
| 376 | + | } | |
| 377 | + | ``` | |
| 378 | + | {: data-line="1"} | |
| 379 | + | ||
| 380 | + | #### Spread | |
| 381 | + | ||
| 382 | + | ```js | |
| 383 | + | fn(...[1, 2, 3]) | |
| 384 | + | // same as fn(1, 2, 3) | |
| 385 | + | ``` | |
| 386 | + | {: data-line="1"} | |
| 387 | + | ||
| 388 | + | Default, rest, spread. | |
| 389 | + | See: [Function arguments](https://babeljs.io/learn-es2015/#default--rest--spread) | |
| 390 | + | ||
| 391 | + | ### Fat arrows | |
| 392 | + | ||
| 393 | + | #### Fat arrows | |
| 394 | + | ||
| 395 | + | ```js | |
| 396 | + | setTimeout(() => { | |
| 397 | + | ··· | |
| 398 | + | }) | |
| 399 | + | ``` | |
| 400 | + | {: data-line="1"} | |
| 401 | + | ||
| 402 | + | #### With arguments | |
| 403 | + | ||
| 404 | + | ```js | |
| 405 | + | readFile('text.txt', (err, data) => { | |
| 406 | + | ... | |
| 407 | + | }) | |
| 408 | + | ``` | |
| 409 | + | {: data-line="1"} | |
| 410 | + | ||
| 411 | + | #### Implicit return | |
| 412 | + | ```js | |
| 413 | + | numbers.map(n => n * 2) | |
| 414 | + | // No curly braces = implicit return | |
| 415 | + | // Same as: numbers.map(function (n) { return n * 2 }) | |
| 416 | + | numbers.map(n => ({ | |
| 417 | + | result: n * 2 | |
| 418 | + | })) | |
| 419 | + | // Implicitly returning objects requires parentheses around the object | |
| 420 | + | ``` | |
| 421 | + | {: data-line="1,4,5,6"} | |
| 422 | + | ||
| 423 | + | Like functions but with `this` preserved. | |
| 424 | + | See: [Fat arrows](https://babeljs.io/learn-es2015/#arrows-and-lexical-this) | |
| 425 | + | ||
| 426 | + | Objects | |
| 427 | + | ------- | |
| 428 | + | ||
| 429 | + | ### Shorthand syntax | |
| 430 | + | ||
| 431 | + | ```js | |
| 432 | + | module.exports = { hello, bye } | |
| 433 | + | // Same as: module.exports = { hello: hello, bye: bye } | |
| 434 | + | ``` | |
| 435 | + | ||
| 436 | + | See: [Object literal enhancements](https://babeljs.io/learn-es2015/#enhanced-object-literals) | |
| 437 | + | ||
| 438 | + | ### Methods | |
| 439 | + | ||
| 440 | + | ```js | |
| 441 | + | const App = { | |
| 442 | + | start () { | |
| 443 | + | console.log('running') | |
| 444 | + | } | |
| 445 | + | } | |
| 446 | + | // Same as: App = { start: function () {···} } | |
| 447 | + | ``` | |
| 448 | + | {: data-line="2"} | |
| 449 | + | ||
| 450 | + | See: [Object literal enhancements](https://babeljs.io/learn-es2015/#enhanced-object-literals) | |
| 451 | + | ||
| 452 | + | ### Getters and setters | |
| 453 | + | ||
| 454 | + | ```js | |
| 455 | + | const App = { | |
| 456 | + | get closed () { | |
| 457 | + | return this.status === 'closed' | |
| 458 | + | }, | |
| 459 | + | set closed (value) { | |
| 460 | + | this.status = value ? 'closed' : 'open' | |
| 461 | + | } | |
| 462 | + | } | |
| 463 | + | ``` | |
| 464 | + | {: data-line="2,5"} | |
| 465 | + | ||
| 466 | + | See: [Object literal enhancements](https://babeljs.io/learn-es2015/#enhanced-object-literals) | |
| 467 | + | ||
| 468 | + | ### Computed property names | |
| 469 | + | ||
| 470 | + | ```js | |
| 471 | + | let event = 'click' | |
| 472 | + | let handlers = { | |
| 473 | + | [`on${event}`]: true | |
| 474 | + | } | |
| 475 | + | // Same as: handlers = { 'onclick': true } | |
| 476 | + | ``` | |
| 477 | + | {: data-line="3"} | |
| 478 | + | ||
| 479 | + | See: [Object literal enhancements](https://babeljs.io/learn-es2015/#enhanced-object-literals) | |
| 480 | + | ||
| 481 | + | ||
| 482 | + | ### Extract values | |
| 483 | + | ||
| 484 | + | ```js | |
| 485 | + | const fatherJS = { age: 57, name: "Brendan Eich" } | |
| 486 | + | ||
| 487 | + | Object.values(fatherJS) | |
| 488 | + | // [57, "Brendan Eich"] | |
| 489 | + | Object.entries(fatherJS) | |
| 490 | + | // [["age", 57], ["name", "Brendan Eich"]] | |
| 491 | + | ``` | |
| 492 | + | {: data-line="3,5"} | |
| 493 | + | ||
| 494 | + | ||
| 495 | + | Modules | |
| 496 | + | ------- | |
| 497 | + | ||
| 498 | + | ### Imports | |
| 499 | + | ||
| 500 | + | ```js | |
| 501 | + | import 'helpers' | |
| 502 | + | // aka: require('···') | |
| 503 | + | ``` | |
| 504 | + | ||
| 505 | + | ```js | |
| 506 | + | import Express from 'express' | |
| 507 | + | // aka: const Express = require('···').default || require('···') | |
| 508 | + | ``` | |
| 509 | + | ||
| 510 | + | ```js | |
| 511 | + | import { indent } from 'helpers' | |
| 512 | + | // aka: const indent = require('···').indent | |
| 513 | + | ``` | |
| 514 | + | ||
| 515 | + | ```js | |
| 516 | + | import * as Helpers from 'helpers' | |
| 517 | + | // aka: const Helpers = require('···') | |
| 518 | + | ``` | |
| 519 | + | ||
| 520 | + | ```js | |
| 521 | + | import { indentSpaces as indent } from 'helpers' | |
| 522 | + | // aka: const indent = require('···').indentSpaces | |
| 523 | + | ``` | |
| 524 | + | ||
| 525 | + | `import` is the new `require()`. | |
| 526 | + | See: [Module imports](https://babeljs.io/learn-es2015/#modules) | |
| 527 | + | ||
| 528 | + | ### Exports | |
| 529 | + | ||
| 530 | + | ```js | |
| 531 | + | export default function () { ··· } | |
| 532 | + | // aka: module.exports.default = ··· | |
| 533 | + | ``` | |
| 534 | + | ||
| 535 | + | ```js | |
| 536 | + | export function mymethod () { ··· } | |
| 537 | + | // aka: module.exports.mymethod = ··· | |
| 538 | + | ``` | |
| 539 | + | ||
| 540 | + | ```js | |
| 541 | + | export const pi = 3.14159 | |
| 542 | + | // aka: module.exports.pi = ··· | |
| 543 | + | ``` | |
| 544 | + | ||
| 545 | + | `export` is the new `module.exports`. | |
| 546 | + | See: [Module exports](https://babeljs.io/learn-es2015/#modules) | |
| 547 | + | ||
| 548 | + | Generators | |
| 549 | + | ---------- | |
| 550 | + | ||
| 551 | + | ### Generators | |
| 552 | + | ||
| 553 | + | ```js | |
| 554 | + | function* idMaker () { | |
| 555 | + | let id = 0 | |
| 556 | + | while (true) { yield id++ } | |
| 557 | + | } | |
| 558 | + | ``` | |
| 559 | + | ||
| 560 | + | ```js | |
| 561 | + | let gen = idMaker() | |
| 562 | + | gen.next().value // → 0 | |
| 563 | + | gen.next().value // → 1 | |
| 564 | + | gen.next().value // → 2 | |
| 565 | + | ``` | |
| 566 | + | ||
| 567 | + | It's complicated. | |
| 568 | + | See: [Generators](https://babeljs.io/learn-es2015/#generators) | |
| 569 | + | ||
| 570 | + | ### For..of iteration | |
| 571 | + | ||
| 572 | + | ```js | |
| 573 | + | for (let i of iterable) { | |
| 574 | + | ··· | |
| 575 | + | } | |
| 576 | + | ``` | |
| 577 | + | ||
| 578 | + | For iterating through generators and arrays. | |
| 579 | + | See: [For..of iteration](https://babeljs.io/learn-es2015/#iterators--forof) | |
| 580 | + | ||
| 581 | + | https://devhints.io/ cheatsheets - Copyright (c) 2021 Rico Sta. Cruz and contributors - MIT license | |
| 582 | + | micro-cheat plugin Copyright 2022 Tero Karvinen https://TeroKarvinen.com/micro - MIT license |
| ... | ... | @@ -0,0 +1,658 @@ | |
| 1 | + | --- | |
| 2 | + | title: Go | |
| 3 | + | layout: 2017/sheet | |
| 4 | + | prism_languages: [go, bash] | |
| 5 | + | weight: -3 | |
| 6 | + | tags: [Featured] | |
| 7 | + | category: C-like | |
| 8 | + | updated: 2020-06-21 | |
| 9 | + | --- | |
| 10 | + | ||
| 11 | + | ## Getting started | |
| 12 | + | {: .-three-column} | |
| 13 | + | ||
| 14 | + | ### Introduction | |
| 15 | + | {: .-intro} | |
| 16 | + | ||
| 17 | + | - [A tour of Go](https://tour.golang.org/welcome/1) _(tour.golang.org)_ | |
| 18 | + | - [Go repl](https://repl.it/languages/go) _(repl.it)_ | |
| 19 | + | - [Golang wiki](https://github.com/golang/go/wiki/) _(github.com)_ | |
| 20 | + | ||
| 21 | + | ### Hello world | |
| 22 | + | {: .-prime} | |
| 23 | + | ||
| 24 | + | #### hello.go | |
| 25 | + | {: .-file} | |
| 26 | + | ||
| 27 | + | ```go | |
| 28 | + | package main | |
| 29 | + | ||
| 30 | + | import "fmt" | |
| 31 | + | ||
| 32 | + | func main() { | |
| 33 | + | message := greetMe("world") | |
| 34 | + | fmt.Println(message) | |
| 35 | + | } | |
| 36 | + | ||
| 37 | + | func greetMe(name string) string { | |
| 38 | + | return "Hello, " + name + "!" | |
| 39 | + | } | |
| 40 | + | ``` | |
| 41 | + | ||
| 42 | + | ```bash | |
| 43 | + | $ go build | |
| 44 | + | ``` | |
| 45 | + | ||
| 46 | + | Or try it out in the [Go repl](https://repl.it/languages/go), or [A Tour of Go](https://tour.golang.org/welcome/1). | |
| 47 | + | ||
| 48 | + | ### Variables | |
| 49 | + | ||
| 50 | + | #### Variable declaration | |
| 51 | + | ||
| 52 | + | ```go | |
| 53 | + | var msg string | |
| 54 | + | msg = "Hello" | |
| 55 | + | ``` | |
| 56 | + | ||
| 57 | + | #### Shortcut of above (Infers type) | |
| 58 | + | ||
| 59 | + | ```go | |
| 60 | + | msg := "Hello" | |
| 61 | + | ``` | |
| 62 | + | ||
| 63 | + | ### Constants | |
| 64 | + | ||
| 65 | + | ```go | |
| 66 | + | const Phi = 1.618 | |
| 67 | + | ``` | |
| 68 | + | ||
| 69 | + | Constants can be character, string, boolean, or numeric values. | |
| 70 | + | ||
| 71 | + | See: [Constants](https://tour.golang.org/basics/15) | |
| 72 | + | ||
| 73 | + | ## Basic types | |
| 74 | + | {: .-three-column} | |
| 75 | + | ||
| 76 | + | ### Strings | |
| 77 | + | ||
| 78 | + | ```go | |
| 79 | + | str := "Hello" | |
| 80 | + | ``` | |
| 81 | + | ||
| 82 | + | ```go | |
| 83 | + | str := `Multiline | |
| 84 | + | string` | |
| 85 | + | ``` | |
| 86 | + | ||
| 87 | + | Strings are of type `string`. | |
| 88 | + | ||
| 89 | + | ### Numbers | |
| 90 | + | ||
| 91 | + | #### Typical types | |
| 92 | + | ||
| 93 | + | ```go | |
| 94 | + | num := 3 // int | |
| 95 | + | num := 3. // float64 | |
| 96 | + | num := 3 + 4i // complex128 | |
| 97 | + | num := byte('a') // byte (alias for uint8) | |
| 98 | + | ``` | |
| 99 | + | ||
| 100 | + | #### Other types | |
| 101 | + | ||
| 102 | + | ```go | |
| 103 | + | var u uint = 7 // uint (unsigned) | |
| 104 | + | var p float32 = 22.7 // 32-bit float | |
| 105 | + | ``` | |
| 106 | + | ||
| 107 | + | ### Arrays | |
| 108 | + | ||
| 109 | + | ```go | |
| 110 | + | // var numbers [5]int | |
| 111 | + | numbers := [...]int{0, 0, 0, 0, 0} | |
| 112 | + | ``` | |
| 113 | + | ||
| 114 | + | Arrays have a fixed size. | |
| 115 | + | ||
| 116 | + | ### Slices | |
| 117 | + | ||
| 118 | + | ```go | |
| 119 | + | slice := []int{2, 3, 4} | |
| 120 | + | ``` | |
| 121 | + | ||
| 122 | + | ```go | |
| 123 | + | slice := []byte("Hello") | |
| 124 | + | ``` | |
| 125 | + | ||
| 126 | + | Slices have a dynamic size, unlike arrays. | |
| 127 | + | ||
| 128 | + | ### Pointers | |
| 129 | + | ||
| 130 | + | ```go | |
| 131 | + | func main () { | |
| 132 | + | b := *getPointer() | |
| 133 | + | fmt.Println("Value is", b) | |
| 134 | + | } | |
| 135 | + | ``` | |
| 136 | + | {: data-line="2"} | |
| 137 | + | ||
| 138 | + | ```go | |
| 139 | + | func getPointer () (myPointer *int) { | |
| 140 | + | a := 234 | |
| 141 | + | return &a | |
| 142 | + | } | |
| 143 | + | ``` | |
| 144 | + | {: data-line="3"} | |
| 145 | + | ||
| 146 | + | ```go | |
| 147 | + | a := new(int) | |
| 148 | + | *a = 234 | |
| 149 | + | ``` | |
| 150 | + | {: data-line="2"} | |
| 151 | + | ||
| 152 | + | Pointers point to a memory location of a variable. Go is fully garbage-collected. | |
| 153 | + | ||
| 154 | + | See: [Pointers](https://tour.golang.org/moretypes/1) | |
| 155 | + | ||
| 156 | + | ### Type conversions | |
| 157 | + | ||
| 158 | + | ```go | |
| 159 | + | i := 2 | |
| 160 | + | f := float64(i) | |
| 161 | + | u := uint(i) | |
| 162 | + | ``` | |
| 163 | + | ||
| 164 | + | See: [Type conversions](https://tour.golang.org/basics/13) | |
| 165 | + | ||
| 166 | + | ## Flow control | |
| 167 | + | {: .-three-column} | |
| 168 | + | ||
| 169 | + | ### Conditional | |
| 170 | + | ||
| 171 | + | ```go | |
| 172 | + | if day == "sunday" || day == "saturday" { | |
| 173 | + | rest() | |
| 174 | + | } else if day == "monday" && isTired() { | |
| 175 | + | groan() | |
| 176 | + | } else { | |
| 177 | + | work() | |
| 178 | + | } | |
| 179 | + | ``` | |
| 180 | + | {: data-line="1,3,5"} | |
| 181 | + | ||
| 182 | + | See: [If](https://tour.golang.org/flowcontrol/5) | |
| 183 | + | ||
| 184 | + | ### Statements in if | |
| 185 | + | ||
| 186 | + | ```go | |
| 187 | + | if _, err := doThing(); err != nil { | |
| 188 | + | fmt.Println("Uh oh") | |
| 189 | + | } | |
| 190 | + | ``` | |
| 191 | + | {: data-line="1"} | |
| 192 | + | ||
| 193 | + | A condition in an `if` statement can be preceded with a statement before a `;`. Variables declared by the statement are only in scope until the end of the `if`. | |
| 194 | + | ||
| 195 | + | See: [If with a short statement](https://tour.golang.org/flowcontrol/6) | |
| 196 | + | ||
| 197 | + | ### Switch | |
| 198 | + | ||
| 199 | + | ```go | |
| 200 | + | switch day { | |
| 201 | + | case "sunday": | |
| 202 | + | // cases don't "fall through" by default! | |
| 203 | + | fallthrough | |
| 204 | + | ||
| 205 | + | case "saturday": | |
| 206 | + | rest() | |
| 207 | + | ||
| 208 | + | default: | |
| 209 | + | work() | |
| 210 | + | } | |
| 211 | + | ``` | |
| 212 | + | ||
| 213 | + | See: [Switch](https://github.com/golang/go/wiki/Switch) | |
| 214 | + | ||
| 215 | + | ### For loop | |
| 216 | + | ||
| 217 | + | ```go | |
| 218 | + | for count := 0; count <= 10; count++ { | |
| 219 | + | fmt.Println("My counter is at", count) | |
| 220 | + | } | |
| 221 | + | ``` | |
| 222 | + | ||
| 223 | + | See: [For loops](https://tour.golang.org/flowcontrol/1) | |
| 224 | + | ||
| 225 | + | ### For-Range loop | |
| 226 | + | ||
| 227 | + | ```go | |
| 228 | + | entry := []string{"Jack","John","Jones"} | |
| 229 | + | for i, val := range entry { | |
| 230 | + | fmt.Printf("At position %d, the character %s is present\n", i, val) | |
| 231 | + | } | |
| 232 | + | ``` | |
| 233 | + | ||
| 234 | + | See: [For-Range loops](https://gobyexample.com/range) | |
| 235 | + | ||
| 236 | + | ### While loop | |
| 237 | + | ||
| 238 | + | ```go | |
| 239 | + | n := 0 | |
| 240 | + | x := 42 | |
| 241 | + | for n != x { | |
| 242 | + | n := guess() | |
| 243 | + | } | |
| 244 | + | ``` | |
| 245 | + | ||
| 246 | + | See: [Go's "while"](https://tour.golang.org/flowcontrol/3) | |
| 247 | + | ||
| 248 | + | ## Functions | |
| 249 | + | {: .-three-column} | |
| 250 | + | ||
| 251 | + | ### Lambdas | |
| 252 | + | ||
| 253 | + | ```go | |
| 254 | + | myfunc := func() bool { | |
| 255 | + | return x > 10000 | |
| 256 | + | } | |
| 257 | + | ``` | |
| 258 | + | {: data-line="1"} | |
| 259 | + | ||
| 260 | + | Functions are first class objects. | |
| 261 | + | ||
| 262 | + | ### Multiple return types | |
| 263 | + | ||
| 264 | + | ```go | |
| 265 | + | a, b := getMessage() | |
| 266 | + | ``` | |
| 267 | + | ||
| 268 | + | ```go | |
| 269 | + | func getMessage() (a string, b string) { | |
| 270 | + | return "Hello", "World" | |
| 271 | + | } | |
| 272 | + | ``` | |
| 273 | + | {: data-line="2"} | |
| 274 | + | ||
| 275 | + | ||
| 276 | + | ### Named return values | |
| 277 | + | ||
| 278 | + | ```go | |
| 279 | + | func split(sum int) (x, y int) { | |
| 280 | + | x = sum * 4 / 9 | |
| 281 | + | y = sum - x | |
| 282 | + | return | |
| 283 | + | } | |
| 284 | + | ``` | |
| 285 | + | {: data-line="4"} | |
| 286 | + | ||
| 287 | + | By defining the return value names in the signature, a `return` (no args) will return variables with those names. | |
| 288 | + | ||
| 289 | + | See: [Named return values](https://tour.golang.org/basics/7) | |
| 290 | + | ||
| 291 | + | ## Packages | |
| 292 | + | {: .-three-column} | |
| 293 | + | ||
| 294 | + | ### Importing | |
| 295 | + | ||
| 296 | + | ```go | |
| 297 | + | import "fmt" | |
| 298 | + | import "math/rand" | |
| 299 | + | ``` | |
| 300 | + | ||
| 301 | + | ```go | |
| 302 | + | import ( | |
| 303 | + | "fmt" // gives fmt.Println | |
| 304 | + | "math/rand" // gives rand.Intn | |
| 305 | + | ) | |
| 306 | + | ``` | |
| 307 | + | ||
| 308 | + | Both are the same. | |
| 309 | + | ||
| 310 | + | See: [Importing](https://tour.golang.org/basics/1) | |
| 311 | + | ||
| 312 | + | ### Aliases | |
| 313 | + | ||
| 314 | + | ```go | |
| 315 | + | import r "math/rand" | |
| 316 | + | ``` | |
| 317 | + | {: data-line="1"} | |
| 318 | + | ||
| 319 | + | ```go | |
| 320 | + | r.Intn() | |
| 321 | + | ``` | |
| 322 | + | ||
| 323 | + | ### Exporting names | |
| 324 | + | ||
| 325 | + | ```go | |
| 326 | + | func Hello () { | |
| 327 | + | ··· | |
| 328 | + | } | |
| 329 | + | ``` | |
| 330 | + | ||
| 331 | + | Exported names begin with capital letters. | |
| 332 | + | ||
| 333 | + | See: [Exported names](https://tour.golang.org/basics/3) | |
| 334 | + | ||
| 335 | + | ### Packages | |
| 336 | + | ||
| 337 | + | ```go | |
| 338 | + | package hello | |
| 339 | + | ``` | |
| 340 | + | ||
| 341 | + | Every package file has to start with `package`. | |
| 342 | + | ||
| 343 | + | ## Concurrency | |
| 344 | + | {: .-three-column} | |
| 345 | + | ||
| 346 | + | ### Goroutines | |
| 347 | + | ||
| 348 | + | ```go | |
| 349 | + | func main() { | |
| 350 | + | // A "channel" | |
| 351 | + | ch := make(chan string) | |
| 352 | + | ||
| 353 | + | // Start concurrent routines | |
| 354 | + | go push("Moe", ch) | |
| 355 | + | go push("Larry", ch) | |
| 356 | + | go push("Curly", ch) | |
| 357 | + | ||
| 358 | + | // Read 3 results | |
| 359 | + | // (Since our goroutines are concurrent, | |
| 360 | + | // the order isn't guaranteed!) | |
| 361 | + | fmt.Println(<-ch, <-ch, <-ch) | |
| 362 | + | } | |
| 363 | + | ``` | |
| 364 | + | {: data-line="3,6,7,8,13"} | |
| 365 | + | ||
| 366 | + | ```go | |
| 367 | + | func push(name string, ch chan string) { | |
| 368 | + | msg := "Hey, " + name | |
| 369 | + | ch <- msg | |
| 370 | + | } | |
| 371 | + | ``` | |
| 372 | + | {: data-line="3"} | |
| 373 | + | ||
| 374 | + | Channels are concurrency-safe communication objects, used in goroutines. | |
| 375 | + | ||
| 376 | + | See: [Goroutines](https://tour.golang.org/concurrency/1), [Channels](https://tour.golang.org/concurrency/2) | |
| 377 | + | ||
| 378 | + | ### Buffered channels | |
| 379 | + | ||
| 380 | + | ```go | |
| 381 | + | ch := make(chan int, 2) | |
| 382 | + | ch <- 1 | |
| 383 | + | ch <- 2 | |
| 384 | + | ch <- 3 | |
| 385 | + | // fatal error: | |
| 386 | + | // all goroutines are asleep - deadlock! | |
| 387 | + | ``` | |
| 388 | + | {: data-line="1"} | |
| 389 | + | ||
| 390 | + | Buffered channels limit the amount of messages it can keep. | |
| 391 | + | ||
| 392 | + | See: [Buffered channels](https://tour.golang.org/concurrency/3) | |
| 393 | + | ||
| 394 | + | ### Closing channels | |
| 395 | + | ||
| 396 | + | #### Closes a channel | |
| 397 | + | ||
| 398 | + | ```go | |
| 399 | + | ch <- 1 | |
| 400 | + | ch <- 2 | |
| 401 | + | ch <- 3 | |
| 402 | + | close(ch) | |
| 403 | + | ``` | |
| 404 | + | {: data-line="4"} | |
| 405 | + | ||
| 406 | + | #### Iterates across a channel until its closed | |
| 407 | + | ||
| 408 | + | ```go | |
| 409 | + | for i := range ch { | |
| 410 | + | ··· | |
| 411 | + | } | |
| 412 | + | ``` | |
| 413 | + | {: data-line="1"} | |
| 414 | + | ||
| 415 | + | #### Closed if `ok == false` | |
| 416 | + | ||
| 417 | + | ```go | |
| 418 | + | v, ok := <- ch | |
| 419 | + | ``` | |
| 420 | + | ||
| 421 | + | See: [Range and close](https://tour.golang.org/concurrency/4) | |
| 422 | + | ||
| 423 | + | ### WaitGroup | |
| 424 | + | ||
| 425 | + | ```go | |
| 426 | + | import "sync" | |
| 427 | + | ||
| 428 | + | func main() { | |
| 429 | + | var wg sync.WaitGroup | |
| 430 | + | ||
| 431 | + | for _, item := range itemList { | |
| 432 | + | // Increment WaitGroup Counter | |
| 433 | + | wg.Add(1) | |
| 434 | + | go doOperation(&wg, item) | |
| 435 | + | } | |
| 436 | + | // Wait for goroutines to finish | |
| 437 | + | wg.Wait() | |
| 438 | + | ||
| 439 | + | } | |
| 440 | + | ``` | |
| 441 | + | {: data-line="1,4,8,12"} | |
| 442 | + | ||
| 443 | + | ```go | |
| 444 | + | func doOperation(wg *sync.WaitGroup, item string) { | |
| 445 | + | defer wg.Done() | |
| 446 | + | // do operation on item | |
| 447 | + | // ... | |
| 448 | + | } | |
| 449 | + | ``` | |
| 450 | + | {: data-line="2"} | |
| 451 | + | ||
| 452 | + | A WaitGroup waits for a collection of goroutines to finish. The main goroutine calls Add to set the number of goroutines to wait for. The goroutine calls `wg.Done()` when it finishes. | |
| 453 | + | See: [WaitGroup](https://golang.org/pkg/sync/#WaitGroup) | |
| 454 | + | ||
| 455 | + | ||
| 456 | + | ## Error control | |
| 457 | + | ||
| 458 | + | ### Defer | |
| 459 | + | ||
| 460 | + | ```go | |
| 461 | + | func main() { | |
| 462 | + | defer fmt.Println("Done") | |
| 463 | + | fmt.Println("Working...") | |
| 464 | + | } | |
| 465 | + | ``` | |
| 466 | + | {: data-line="2"} | |
| 467 | + | ||
| 468 | + | Defers running a function until the surrounding function returns. | |
| 469 | + | The arguments are evaluated immediately, but the function call is not ran until later. | |
| 470 | + | ||
| 471 | + | See: [Defer, panic and recover](https://blog.golang.org/defer-panic-and-recover) | |
| 472 | + | ||
| 473 | + | ### Deferring functions | |
| 474 | + | ||
| 475 | + | ```go | |
| 476 | + | func main() { | |
| 477 | + | defer func() { | |
| 478 | + | fmt.Println("Done") | |
| 479 | + | }() | |
| 480 | + | fmt.Println("Working...") | |
| 481 | + | } | |
| 482 | + | ``` | |
| 483 | + | {: data-line="2,3,4"} | |
| 484 | + | ||
| 485 | + | Lambdas are better suited for defer blocks. | |
| 486 | + | ||
| 487 | + | ```go | |
| 488 | + | func main() { | |
| 489 | + | var d = int64(0) | |
| 490 | + | defer func(d *int64) { | |
| 491 | + | fmt.Printf("& %v Unix Sec\n", *d) | |
| 492 | + | }(&d) | |
| 493 | + | fmt.Print("Done ") | |
| 494 | + | d = time.Now().Unix() | |
| 495 | + | } | |
| 496 | + | ``` | |
| 497 | + | {: data-line="3,4,5"} | |
| 498 | + | The defer func uses current value of d, unless we use a pointer to get final value at end of main. | |
| 499 | + | ||
| 500 | + | ## Structs | |
| 501 | + | {: .-three-column} | |
| 502 | + | ||
| 503 | + | ### Defining | |
| 504 | + | ||
| 505 | + | ```go | |
| 506 | + | type Vertex struct { | |
| 507 | + | X int | |
| 508 | + | Y int | |
| 509 | + | } | |
| 510 | + | ``` | |
| 511 | + | {: data-line="1,2,3,4"} | |
| 512 | + | ||
| 513 | + | ```go | |
| 514 | + | func main() { | |
| 515 | + | v := Vertex{1, 2} | |
| 516 | + | v.X = 4 | |
| 517 | + | fmt.Println(v.X, v.Y) | |
| 518 | + | } | |
| 519 | + | ``` | |
| 520 | + | ||
| 521 | + | See: [Structs](https://tour.golang.org/moretypes/2) | |
| 522 | + | ||
| 523 | + | ### Literals | |
| 524 | + | ||
| 525 | + | ```go | |
| 526 | + | v := Vertex{X: 1, Y: 2} | |
| 527 | + | ``` | |
| 528 | + | ||
| 529 | + | ```go | |
| 530 | + | // Field names can be omitted | |
| 531 | + | v := Vertex{1, 2} | |
| 532 | + | ``` | |
| 533 | + | ||
| 534 | + | ```go | |
| 535 | + | // Y is implicit | |
| 536 | + | v := Vertex{X: 1} | |
| 537 | + | ``` | |
| 538 | + | ||
| 539 | + | You can also put field names. | |
| 540 | + | ||
| 541 | + | ### Pointers to structs | |
| 542 | + | ||
| 543 | + | ```go | |
| 544 | + | v := &Vertex{1, 2} | |
| 545 | + | v.X = 2 | |
| 546 | + | ``` | |
| 547 | + | ||
| 548 | + | Doing `v.X` is the same as doing `(*v).X`, when `v` is a pointer. | |
| 549 | + | ||
| 550 | + | ## Methods | |
| 551 | + | ||
| 552 | + | ### Receivers | |
| 553 | + | ||
| 554 | + | ```go | |
| 555 | + | type Vertex struct { | |
| 556 | + | X, Y float64 | |
| 557 | + | } | |
| 558 | + | ``` | |
| 559 | + | ||
| 560 | + | ```go | |
| 561 | + | func (v Vertex) Abs() float64 { | |
| 562 | + | return math.Sqrt(v.X * v.X + v.Y * v.Y) | |
| 563 | + | } | |
| 564 | + | ``` | |
| 565 | + | {: data-line="1"} | |
| 566 | + | ||
| 567 | + | ```go | |
| 568 | + | v := Vertex{1, 2} | |
| 569 | + | v.Abs() | |
| 570 | + | ``` | |
| 571 | + | ||
| 572 | + | There are no classes, but you can define functions with _receivers_. | |
| 573 | + | ||
| 574 | + | See: [Methods](https://tour.golang.org/methods/1) | |
| 575 | + | ||
| 576 | + | ### Mutation | |
| 577 | + | ||
| 578 | + | ```go | |
| 579 | + | func (v *Vertex) Scale(f float64) { | |
| 580 | + | v.X = v.X * f | |
| 581 | + | v.Y = v.Y * f | |
| 582 | + | } | |
| 583 | + | ``` | |
| 584 | + | {: data-line="1"} | |
| 585 | + | ||
| 586 | + | ```go | |
| 587 | + | v := Vertex{6, 12} | |
| 588 | + | v.Scale(0.5) | |
| 589 | + | // `v` is updated | |
| 590 | + | ``` | |
| 591 | + | ||
| 592 | + | By defining your receiver as a pointer (`*Vertex`), you can do mutations. | |
| 593 | + | ||
| 594 | + | See: [Pointer receivers](https://tour.golang.org/methods/4) | |
| 595 | + | ||
| 596 | + | ## Interfaces | |
| 597 | + | ||
| 598 | + | ### A basic interface | |
| 599 | + | ||
| 600 | + | ```go | |
| 601 | + | type Shape interface { | |
| 602 | + | Area() float64 | |
| 603 | + | Perimeter() float64 | |
| 604 | + | } | |
| 605 | + | ``` | |
| 606 | + | ||
| 607 | + | ### Struct | |
| 608 | + | ||
| 609 | + | ```go | |
| 610 | + | type Rectangle struct { | |
| 611 | + | Length, Width float64 | |
| 612 | + | } | |
| 613 | + | ``` | |
| 614 | + | ||
| 615 | + | Struct `Rectangle` implicitly implements interface `Shape` by implementing all of its methods. | |
| 616 | + | ||
| 617 | + | ### Methods | |
| 618 | + | ||
| 619 | + | ```go | |
| 620 | + | func (r Rectangle) Area() float64 { | |
| 621 | + | return r.Length * r.Width | |
| 622 | + | } | |
| 623 | + | ||
| 624 | + | func (r Rectangle) Perimeter() float64 { | |
| 625 | + | return 2 * (r.Length + r.Width) | |
| 626 | + | } | |
| 627 | + | ``` | |
| 628 | + | ||
| 629 | + | The methods defined in `Shape` are implemented in `Rectangle`. | |
| 630 | + | ||
| 631 | + | ### Interface example | |
| 632 | + | ||
| 633 | + | ```go | |
| 634 | + | func main() { | |
| 635 | + | var r Shape = Rectangle{Length: 3, Width: 4} | |
| 636 | + | fmt.Printf("Type of r: %T, Area: %v, Perimeter: %v.", r, r.Area(), r.Perimeter()) | |
| 637 | + | } | |
| 638 | + | ``` | |
| 639 | + | ||
| 640 | + | ## References | |
| 641 | + | ||
| 642 | + | ### Official resources | |
| 643 | + | {: .-intro} | |
| 644 | + | ||
| 645 | + | - [A tour of Go](https://tour.golang.org/welcome/1) _(tour.golang.org)_ | |
| 646 | + | - [Golang wiki](https://github.com/golang/go/wiki/) _(github.com)_ | |
| 647 | + | - [Effective Go](https://golang.org/doc/effective_go.html) _(golang.org)_ | |
| 648 | + | ||
| 649 | + | ### Other links | |
| 650 | + | {: .-intro} | |
| 651 | + | ||
| 652 | + | - [Go by Example](https://gobyexample.com/) _(gobyexample.com)_ | |
| 653 | + | - [Awesome Go](https://awesome-go.com/) _(awesome-go.com)_ | |
| 654 | + | - [JustForFunc Youtube](https://www.youtube.com/channel/UC_BzFbxG2za3bp5NRRRXJSw) _(youtube.com)_ | |
| 655 | + | - [Style Guide](https://github.com/golang/go/wiki/CodeReviewComments) _(github.com)_ | |
| 656 | + | ||
| 657 | + | https://devhints.io/ cheatsheets - Copyright (c) 2021 Rico Sta. Cruz and contributors - MIT license | |
| 658 | + | micro-cheat plugin Copyright 2022 Tero Karvinen https://TeroKarvinen.com/micro - MIT license |
| ... | ... | @@ -0,0 +1,1277 @@ | |
| 1 | + | --- | |
| 2 | + | title: Goby | |
| 3 | + | layout: 2017/sheet | |
| 4 | + | prism_languages: [ruby] | |
| 5 | + | weight: -3 | |
| 6 | + | updated: 2018-12-06 | |
| 7 | + | category: Ruby | |
| 8 | + | intro: | | |
| 9 | + | Goby's language design is based on Ruby language's, slim and shaped up. Differences in syntax between them is very small. | |
| 10 | + | --- | |
| 11 | + | ||
| 12 | + | ||
| 13 | + | ## Getting started | |
| 14 | + | ||
| 15 | + | ### Hello world | |
| 16 | + | {: .-prime} | |
| 17 | + | ||
| 18 | + | #### hello.gb | |
| 19 | + | {: .-file} | |
| 20 | + | ||
| 21 | + | ```ruby | |
| 22 | + | class Greet | |
| 23 | + | attr_accessor :audience, :head, :tail | |
| 24 | + | ||
| 25 | + | def initialize | |
| 26 | + | @head = "Hello, " | |
| 27 | + | @tail = "!" | |
| 28 | + | end | |
| 29 | + | ||
| 30 | + | def name | |
| 31 | + | audience.name | |
| 32 | + | end | |
| 33 | + | ||
| 34 | + | def say | |
| 35 | + | puts head + name + tail | |
| 36 | + | end | |
| 37 | + | end | |
| 38 | + | ||
| 39 | + | module MyName | |
| 40 | + | attr_reader :name | |
| 41 | + | ||
| 42 | + | def initialize | |
| 43 | + | @name = self.class.to_s | |
| 44 | + | end | |
| 45 | + | end | |
| 46 | + | ||
| 47 | + | class World | |
| 48 | + | include MyName | |
| 49 | + | end | |
| 50 | + | ||
| 51 | + | greet = Greet.new | |
| 52 | + | greet.audience = World.new | |
| 53 | + | greet.say | |
| 54 | + | ``` | |
| 55 | + | ||
| 56 | + | Then run: | |
| 57 | + | ||
| 58 | + | ```bash | |
| 59 | + | $ goby hello.gb | |
| 60 | + | #=> Hello, World! | |
| 61 | + | ``` | |
| 62 | + | ||
| 63 | + | ### REPL (igb) | |
| 64 | + | ||
| 65 | + | ```bash | |
| 66 | + | $ goby -i | |
| 67 | + | ``` | |
| 68 | + | ||
| 69 | + | * `reset`: reset the VM | |
| 70 | + | * `exit`: exit REPL | |
| 71 | + | * `help`: show help | |
| 72 | + | * ctrl-c: cancel the block entered, or exit (on top level) | |
| 73 | + | ||
| 74 | + | See [igb manual & test script](https://github.com/goby-lang/goby/blob/master/igb/manual_test.md). You can use `readline` features such as command history by arrow keys. | |
| 75 | + | ||
| 76 | + | ## Variables | |
| 77 | + | {: .-three-column} | |
| 78 | + | ||
| 79 | + | ### Local variable | |
| 80 | + | ||
| 81 | + | ```ruby | |
| 82 | + | zip101 = "233-7383" | |
| 83 | + | magic_number = 42 | |
| 84 | + | ``` | |
| 85 | + | ||
| 86 | + | Should be "`[a-z][a-z0-9_]+`"(snake_case). | |
| 87 | + | ||
| 88 | + | ### Instance variable | |
| 89 | + | ||
| 90 | + | ```ruby | |
| 91 | + | module State | |
| 92 | + | def initialize(state) | |
| 93 | + | @state = state # declaring an instance variable by assignment | |
| 94 | + | end | |
| 95 | + | def show | |
| 96 | + | @state # accessible from other instance methods | |
| 97 | + | end | |
| 98 | + | end | |
| 99 | + | ||
| 100 | + | state = State.new "success" | |
| 101 | + | state.show | |
| 102 | + | #=> success | |
| 103 | + | ``` | |
| 104 | + | ||
| 105 | + | Should be "`@[a-z][a-z0-9_]+`"(snake_case). | |
| 106 | + | ||
| 107 | + | ### Multiple assignment | |
| 108 | + | ||
| 109 | + | ```ruby | |
| 110 | + | # array literal | |
| 111 | + | a, b, c = [1, 2, 3] | |
| 112 | + | ||
| 113 | + | # array with '*' | |
| 114 | + | a = [1, 2, 3] | |
| 115 | + | x, y, z = *a | |
| 116 | + | ||
| 117 | + | # array literal with '*' | |
| 118 | + | a, b, c = *[1, 2, 3] | |
| 119 | + | ||
| 120 | + | # bare assignment: unsupported | |
| 121 | + | a, b, c = 1, 2, 3 #=> unexpected 3 Line: 0 | |
| 122 | + | ``` | |
| 123 | + | ||
| 124 | + | ### Black hole variable | |
| 125 | + | ||
| 126 | + | ```ruby | |
| 127 | + | # '_' is write-only | |
| 128 | + | a, _ = [1, 2] | |
| 129 | + | ``` | |
| 130 | + | ||
| 131 | + | ### Class variable | |
| 132 | + | ||
| 133 | + | Unsupported. | |
| 134 | + | ||
| 135 | + | ### Global variable | |
| 136 | + | ||
| 137 | + | Unsupported. | |
| 138 | + | ||
| 139 | + | ## Method definition | |
| 140 | + | ||
| 141 | + | ### Method definition and calling | |
| 142 | + | ||
| 143 | + | ```ruby | |
| 144 | + | def foo_bar?(baz) | |
| 145 | + | if baz == "Hi, Goby!" | |
| 146 | + | true | |
| 147 | + | else | |
| 148 | + | false | |
| 149 | + | end | |
| 150 | + | end | |
| 151 | + | ||
| 152 | + | foo_bar? "Hi, Goby!" #=> true | |
| 153 | + | ``` | |
| 154 | + | ||
| 155 | + | Method name should be "`[a-z][a-z0-9_]+\??`" (snake_case). You can omit the trailing "`()`" only if no parameters are taken. Trailing using "`!`" is **unsupported**. | |
| 156 | + | ||
| 157 | + | ### Order of method parameter | |
| 158 | + | ||
| 159 | + | ```ruby | |
| 160 | + | def foo(normal, default="value", hash={}, ary=[], keyword:, keyword_default:"key", *sprat) | |
| 161 | + | end | |
| 162 | + | ``` | |
| 163 | + | ||
| 164 | + | If a default value is provided to a parameter, the parameter can be omitted when calling. `()` can be omitted. The order of parameters in method definition is restricted as follows: | |
| 165 | + | ||
| 166 | + | 1. **normal parameters** (like `a`) | |
| 167 | + | 2. **normal parameters with default value** (like `a=1`) | |
| 168 | + | 3. **optional parameters** (array or hash, like `ary=[]` or `hs={}`) | |
| 169 | + | 4. **keyword parameters** (like `kwd:`) | |
| 170 | + | 5. **keyword parameters with default value** (like `kwd: 1` or `ary: [1,2,3]` or `hsh: {key: "value"}`) | |
| 171 | + | 6. **splat parameters** (like `*sp`) | |
| 172 | + | ||
| 173 | + | Or you will receive an error. | |
| 174 | + | ||
| 175 | + | ### Keyword parameter (WIP) | |
| 176 | + | ||
| 177 | + | ```ruby | |
| 178 | + | def foo(process:, verb: :GET, opt:{ csp: :enabled }, ary: [1, 2, 3]) | |
| 179 | + | end | |
| 180 | + | ``` | |
| 181 | + | ||
| 182 | + | ### Returning value | |
| 183 | + | ||
| 184 | + | ```ruby | |
| 185 | + | PI = 3.14 | |
| 186 | + | def area(radius) | |
| 187 | + | radius * PI # returns the result of evaluation | |
| 188 | + | end | |
| 189 | + | ||
| 190 | + | area 6 #=> 18.84 | |
| 191 | + | ``` | |
| 192 | + | ||
| 193 | + | ### Returning multiple value | |
| 194 | + | ||
| 195 | + | ```ruby | |
| 196 | + | def my_array | |
| 197 | + | [1, 2, 3] | |
| 198 | + | end | |
| 199 | + | ||
| 200 | + | my_array #=> [1, 2, 3] | |
| 201 | + | ``` | |
| 202 | + | ||
| 203 | + | ### Instance method | |
| 204 | + | ||
| 205 | + | ```ruby | |
| 206 | + | module Foo | |
| 207 | + | def bar # defining instance method | |
| 208 | + | puts "bar" | |
| 209 | + | end | |
| 210 | + | ||
| 211 | + | def baz(count, email: "goby@example.com") | |
| 212 | + | count.times do | |
| 213 | + | puts email | |
| 214 | + | end | |
| 215 | + | end | |
| 216 | + | end | |
| 217 | + | ||
| 218 | + | foo = Foo.new | |
| 219 | + | foo.bar #=> bar | |
| 220 | + | foo.baz(3) #↓ | |
| 221 | + | goby@example.com | |
| 222 | + | goby@example.com | |
| 223 | + | goby@example.com | |
| 224 | + | ``` | |
| 225 | + | ||
| 226 | + | ### Singleton method #1 | |
| 227 | + | ||
| 228 | + | ```ruby | |
| 229 | + | str = "Goby" | |
| 230 | + | def str.foo #1 singleton method on the object | |
| 231 | + | self * 2 | |
| 232 | + | end | |
| 233 | + | ||
| 234 | + | str.foo | |
| 235 | + | #=> GobyGoby | |
| 236 | + | ``` | |
| 237 | + | ||
| 238 | + | ### Singleton method #2 | |
| 239 | + | ||
| 240 | + | ```ruby | |
| 241 | + | module Foo | |
| 242 | + | def self.bar #2 singleton method with `self.` | |
| 243 | + | 92 | |
| 244 | + | end | |
| 245 | + | end | |
| 246 | + | ``` | |
| 247 | + | ||
| 248 | + | ### Singleton method #3 | |
| 249 | + | ||
| 250 | + | ```ruby | |
| 251 | + | module Foo | |
| 252 | + | def Foo.bar #3 singleton method with a class name (unrecommended) | |
| 253 | + | 88 | |
| 254 | + | end | |
| 255 | + | end | |
| 256 | + | ``` | |
| 257 | + | ||
| 258 | + | ### Singleton method #4 | |
| 259 | + | ||
| 260 | + | ```ruby | |
| 261 | + | module Foo end | |
| 262 | + | ||
| 263 | + | def Foo.bar #4 singleton methods outside the Foo | |
| 264 | + | 9999 | |
| 265 | + | end | |
| 266 | + | ||
| 267 | + | Foo.bar #=> 9999 | |
| 268 | + | ``` | |
| 269 | + | ||
| 270 | + | ### Attribute accessor method | |
| 271 | + | ||
| 272 | + | ```ruby | |
| 273 | + | class Foo | |
| 274 | + | attr_accessor :bar, :baz | |
| 275 | + | ||
| 276 | + | def initialize | |
| 277 | + | @bar = 42 | |
| 278 | + | @baz = 99 | |
| 279 | + | end | |
| 280 | + | end | |
| 281 | + | ||
| 282 | + | foo = Foo.new | |
| 283 | + | ||
| 284 | + | foo.bar = 77 | |
| 285 | + | foo.baz = 88 | |
| 286 | + | ``` | |
| 287 | + | ||
| 288 | + | You can use the following shorthands to declare attribute accessor methods in classes/modules: | |
| 289 | + | ||
| 290 | + | * `attr_accessor` | |
| 291 | + | * `attr_reader` | |
| 292 | + | * `attr_writer` | |
| 293 | + | ||
| 294 | + | ### Private method (to be implemented) | |
| 295 | + | ||
| 296 | + | ```ruby | |
| 297 | + | class Foo | |
| 298 | + | def bar | |
| 299 | + | 42 | |
| 300 | + | end | |
| 301 | + | ||
| 302 | + | def _baz # leading '_' means private method | |
| 303 | + | 99 | |
| 304 | + | end | |
| 305 | + | end | |
| 306 | + | ``` | |
| 307 | + | ||
| 308 | + | ## Module/Class definition | |
| 309 | + | {: .-three-column} | |
| 310 | + | ||
| 311 | + | ### Module definition and `include` | |
| 312 | + | ||
| 313 | + | ```ruby | |
| 314 | + | module Foo | |
| 315 | + | def foo | |
| 316 | + | "Foo's instance method" | |
| 317 | + | end | |
| 318 | + | end | |
| 319 | + | ||
| 320 | + | class Bar | |
| 321 | + | include Foo # to include Foo | |
| 322 | + | end | |
| 323 | + | ||
| 324 | + | Bar.new.foo #=> Foo's instance method | |
| 325 | + | ``` | |
| 326 | + | ||
| 327 | + | Module names should be "`[A-Z][A-Za-z0-9_]+`" (UpperCamelCase). Modules cannot be inherited. | |
| 328 | + | ||
| 329 | + | ### Module definition and `extend` | |
| 330 | + | ||
| 331 | + | ```ruby | |
| 332 | + | module Foo | |
| 333 | + | def foo | |
| 334 | + | "Foo's instance method will be a singleton method" | |
| 335 | + | end | |
| 336 | + | end | |
| 337 | + | ||
| 338 | + | class Bar | |
| 339 | + | extend Foo # to extend Foo | |
| 340 | + | end | |
| 341 | + | ||
| 342 | + | Bar.foo #=> Foo's instance method will be a singleton method | |
| 343 | + | ``` | |
| 344 | + | ||
| 345 | + | `extend` is to use the instance methods in the specified modules as **singleton methods** in your class or module. | |
| 346 | + | ||
| 347 | + | ### Module instantiation | |
| 348 | + | ||
| 349 | + | ```ruby | |
| 350 | + | module Foo #module definition | |
| 351 | + | def foo | |
| 352 | + | 99 | |
| 353 | + | end | |
| 354 | + | end | |
| 355 | + | ||
| 356 | + | Foo.new.foo #=> 99 | |
| 357 | + | ``` | |
| 358 | + | ||
| 359 | + | Actually, Goby's module can be even **instantiated** via "`new`" like "`Foo.new`". | |
| 360 | + | ||
| 361 | + | ### Class definition and inheritance | |
| 362 | + | ||
| 363 | + | ```ruby | |
| 364 | + | class Foo # class definition | |
| 365 | + | def bar | |
| 366 | + | 99 | |
| 367 | + | end | |
| 368 | + | end | |
| 369 | + | ||
| 370 | + | class Baz < Foo # inheritance | |
| 371 | + | end | |
| 372 | + | ||
| 373 | + | Baz.new.bar #=> 99 | |
| 374 | + | ``` | |
| 375 | + | ||
| 376 | + | Class names should be "`[A-Z][A-Za-z0-9]+`" (UpperCamelCase). Inheritance with "`<`" is supported. | |
| 377 | + | ||
| 378 | + | ### Constants | |
| 379 | + | ||
| 380 | + | ```ruby | |
| 381 | + | HTTP_ERROR_404 = 404 | |
| 382 | + | HTTP_ERROR_404 = 500 # error | |
| 383 | + | ``` | |
| 384 | + | ||
| 385 | + | Constants should be "`[A-Z][A-Za-z0-9_]+`" (UPPER_SNAKECASE). Constants are **not reentrant** and the scope is **global**. | |
| 386 | + | ||
| 387 | + | ### Redefining class/modules | |
| 388 | + | ||
| 389 | + | ```ruby | |
| 390 | + | class Foo | |
| 391 | + | def bar | |
| 392 | + | 99 | |
| 393 | + | end | |
| 394 | + | end | |
| 395 | + | ||
| 396 | + | class Foo | |
| 397 | + | def bar # redefining is possible | |
| 398 | + | 77 | |
| 399 | + | end | |
| 400 | + | end | |
| 401 | + | ``` | |
| 402 | + | ||
| 403 | + | ### Namespaces | |
| 404 | + | ||
| 405 | + | ```ruby | |
| 406 | + | class Foo | |
| 407 | + | module Bar | |
| 408 | + | MAGIC = 99 | |
| 409 | + | def baz | |
| 410 | + | 99 | |
| 411 | + | end | |
| 412 | + | end | |
| 413 | + | end | |
| 414 | + | ||
| 415 | + | Foo::Bar.new.baz # Use '::' for namespacing | |
| 416 | + | Foo::Bar::MAGIC # Use '::' for namespacing | |
| 417 | + | ``` | |
| 418 | + | ||
| 419 | + | ## Load library | |
| 420 | + | ||
| 421 | + | ### `require` | |
| 422 | + | ||
| 423 | + | ```ruby | |
| 424 | + | require("uri") # to activate URL class | |
| 425 | + | ||
| 426 | + | u = URI.parse("http://example.com") | |
| 427 | + | u.scheme #=> "http" | |
| 428 | + | ``` | |
| 429 | + | ||
| 430 | + | ### `require_relative` | |
| 431 | + | ||
| 432 | + | ```ruby | |
| 433 | + | require_relative("bar") # loading the local bar.gb | |
| 434 | + | ||
| 435 | + | class Foo | |
| 436 | + | def self.bar(x) | |
| 437 | + | Bar.foo do |ten| | |
| 438 | + | x * ten | |
| 439 | + | end | |
| 440 | + | end | |
| 441 | + | ||
| 442 | + | def self.baz | |
| 443 | + | yield(100) | |
| 444 | + | end | |
| 445 | + | end | |
| 446 | + | ``` | |
| 447 | + | ||
| 448 | + | ## Literal | |
| 449 | + | {: .-three-column} | |
| 450 | + | ||
| 451 | + | ### Keyword | |
| 452 | + | ||
| 453 | + | `def`, `true`, `false`, `nil`, `if`, `elsif`, `else`, `case`, `when`, `return`, `self`, `end`, `while`, `do`, `yield`, `get_block`, `next`, `class`, `module`, `break` | |
| 454 | + | ||
| 455 | + | ### String literal | |
| 456 | + | ||
| 457 | + | ```ruby | |
| 458 | + | "double quote" | |
| 459 | + | 'single quote' | |
| 460 | + | ``` | |
| 461 | + | ||
| 462 | + | Double and single quotation can be used. | |
| 463 | + | ||
| 464 | + | ### Symbol literal | |
| 465 | + | ||
| 466 | + | ```ruby | |
| 467 | + | :symbol # equivalent to "symbol" | |
| 468 | + | { symbol: "value" } | |
| 469 | + | ``` | |
| 470 | + | ||
| 471 | + | Goby's symbol (using `:`) is always `String` class. | |
| 472 | + | ||
| 473 | + | ### Numeric literal | |
| 474 | + | ||
| 475 | + | ```ruby | |
| 476 | + | year = 2018 # Integer | |
| 477 | + | offset = -42 # Integer | |
| 478 | + | PI = 3.14 # Float | |
| 479 | + | G = -9.8 # Float | |
| 480 | + | ``` | |
| 481 | + | ||
| 482 | + | ### Array literal | |
| 483 | + | ||
| 484 | + | ```ruby | |
| 485 | + | [1, 2, 3, "hello", :goby, { key: "value"}] | |
| 486 | + | [1, 2, [3, 4], 5, 6] | |
| 487 | + | ``` | |
| 488 | + | ||
| 489 | + | ### Hash literal | |
| 490 | + | ||
| 491 | + | ```ruby | |
| 492 | + | h = { key: "value", key2: "value2" } | |
| 493 | + | h[:key2] #=> value2 | |
| 494 | + | ``` | |
| 495 | + | ||
| 496 | + | Hash literal's keys should always be **symbol literals**. | |
| 497 | + | ||
| 498 | + | ### Range literal | |
| 499 | + | ||
| 500 | + | ```ruby | |
| 501 | + | (1..10).each do |x| # '..' represents a range | |
| 502 | + | puts x*x | |
| 503 | + | end | |
| 504 | + | ``` | |
| 505 | + | ||
| 506 | + | ### Boolean and `nil` | |
| 507 | + | ||
| 508 | + | ```ruby | |
| 509 | + | true # Boolean class | |
| 510 | + | false # Boolean class | |
| 511 | + | nil # Null class | |
| 512 | + | ||
| 513 | + | !nil #=> true | |
| 514 | + | ``` | |
| 515 | + | ||
| 516 | + | Any objects except `nil` and `false` will be treated as `true` on conditionals. | |
| 517 | + | ||
| 518 | + | ## Operator | |
| 519 | + | ||
| 520 | + | ### Arithmetic/logical/assignment operators | |
| 521 | + | ||
| 522 | + | ```ruby | |
| 523 | + | + # unary | |
| 524 | + | ** # power | |
| 525 | + | - # unary | |
| 526 | + | * / % # multiplication, division, modulus | |
| 527 | + | + - # addition, subtraction | |
| 528 | + | ! # logical inversion | |
| 529 | + | > >= < <= # inequality comparison | |
| 530 | + | == != # equality comparison, negative comparison | |
| 531 | + | && # logical AND | |
| 532 | + | || # logical OR | |
| 533 | + | += -= # shorthand of addition/subtraction | |
| 534 | + | = # assignment | |
| 535 | + | ``` | |
| 536 | + | ||
| 537 | + | *Priority of operators are TBD | |
| 538 | + | ||
| 539 | + | ### Other operators | |
| 540 | + | ||
| 541 | + | ```ruby | |
| 542 | + | () # chaning priority of interpretation | |
| 543 | + | [] # array literal | |
| 544 | + | * # multiple assignment | |
| 545 | + | .. # range | |
| 546 | + | ``` | |
| 547 | + | ||
| 548 | + | *Priority of operators are TBD | |
| 549 | + | ||
| 550 | + | ### Delimiter | |
| 551 | + | ||
| 552 | + | ```ruby | |
| 553 | + | class Foo; end # ';' to delimit | |
| 554 | + | ||
| 555 | + | class Bar end # recommended | |
| 556 | + | ``` | |
| 557 | + | ||
| 558 | + | ### String interpolation (to be implemented) | |
| 559 | + | ||
| 560 | + | ```ruby | |
| 561 | + | puts "Error: #{error_message}" # double quotation is required | |
| 562 | + | ``` | |
| 563 | + | ||
| 564 | + | ### Comment | |
| 565 | + | ||
| 566 | + | ```ruby | |
| 567 | + | puts "Goby" # comments | |
| 568 | + | ``` | |
| 569 | + | ||
| 570 | + | Use the annotations to keep the comments concise. | |
| 571 | + | ||
| 572 | + | - `TODO` | |
| 573 | + | - `FIXME` | |
| 574 | + | - `OPTIMIZE` | |
| 575 | + | - `HACK` | |
| 576 | + | - `REVIEW` | |
| 577 | + | ||
| 578 | + | ### I/O | |
| 579 | + | ||
| 580 | + | * `#puts` | |
| 581 | + | ||
| 582 | + | * special constants: `ARGV`, `STDIN`, `STDOUT`, `STDERR`, `ENV` | |
| 583 | + | ||
| 584 | + | ## Flow control | |
| 585 | + | {: .-three-column} | |
| 586 | + | ||
| 587 | + | ### `if`, `else`, `elsif` | |
| 588 | + | ||
| 589 | + | ```ruby | |
| 590 | + | def foo(str) | |
| 591 | + | if str.size > 10 | |
| 592 | + | puts "too big!" | |
| 593 | + | elsif str.size < 3 | |
| 594 | + | puts "too short!" | |
| 595 | + | else | |
| 596 | + | puts "moderate" | |
| 597 | + | end | |
| 598 | + | end | |
| 599 | + | ``` | |
| 600 | + | ||
| 601 | + | `then` is **not** supported. | |
| 602 | + | ||
| 603 | + | ### Break | |
| 604 | + | ||
| 605 | + | ```ruby | |
| 606 | + | def foo(tail) | |
| 607 | + | (5..tail).each do |t| | |
| 608 | + | if t % 2 == 0 && t % 5 == 0 | |
| 609 | + | puts "ouch!" | |
| 610 | + | break # finish the block | |
| 611 | + | else | |
| 612 | + | puts t | |
| 613 | + | end | |
| 614 | + | end | |
| 615 | + | puts "out of the block" | |
| 616 | + | end | |
| 617 | + | ||
| 618 | + | foo 20 | |
| 619 | + | #=> 5 6 7 8 9 | |
| 620 | + | #=> ouch! | |
| 621 | + | #=> out of the block | |
| 622 | + | ``` | |
| 623 | + | ||
| 624 | + | ### Case | |
| 625 | + | ||
| 626 | + | ```ruby | |
| 627 | + | def foo(str) | |
| 628 | + | case str | |
| 629 | + | when "Elf" | |
| 630 | + | puts "You might be Aragorn II!" | |
| 631 | + | when "Aragorn" | |
| 632 | + | puts "Long time no see, Aragorn!" | |
| 633 | + | when "Frodo", "Sam", "Gandalf" | |
| 634 | + | puts "One of us!" | |
| 635 | + | else | |
| 636 | + | puts "You're not yourself" | |
| 637 | + | end | |
| 638 | + | end | |
| 639 | + | ``` | |
| 640 | + | ||
| 641 | + | ### While | |
| 642 | + | ||
| 643 | + | ```ruby | |
| 644 | + | decr = 10 | |
| 645 | + | while decr do | |
| 646 | + | if decr < 1 | |
| 647 | + | break | |
| 648 | + | end | |
| 649 | + | puts decr | |
| 650 | + | decr -= 1 | |
| 651 | + | end | |
| 652 | + | ``` | |
| 653 | + | ||
| 654 | + | `while`, conditional and a `do`/`end` block can be used for a loop. | |
| 655 | + | ||
| 656 | + | ### Rescue | |
| 657 | + | ||
| 658 | + | Under construction. Join [#605](https://github.com/goby-lang/goby/issues/605). | |
| 659 | + | ||
| 660 | + | ## Block | |
| 661 | + | {: .-three-column} | |
| 662 | + | ||
| 663 | + | ### Block | |
| 664 | + | ||
| 665 | + | ```ruby | |
| 666 | + | def foo(ary: [1, 2, 3]) | |
| 667 | + | ary.each do |s| # start of the block with |block variable| | |
| 668 | + | puts s | |
| 669 | + | end # end of the block | |
| 670 | + | end | |
| 671 | + | ``` | |
| 672 | + | ||
| 673 | + | `{ }` cannot be used for forming a block. | |
| 674 | + | ||
| 675 | + | ### `yield` | |
| 676 | + | ||
| 677 | + | ```ruby | |
| 678 | + | def foo | |
| 679 | + | yield(10) # executes the block given | |
| 680 | + | end | |
| 681 | + | ||
| 682 | + | foo do |ten| | |
| 683 | + | ten + 20 | |
| 684 | + | end | |
| 685 | + | ``` | |
| 686 | + | ||
| 687 | + | ### Block object and `call` | |
| 688 | + | ||
| 689 | + | ```ruby | |
| 690 | + | b = Block.new do | |
| 691 | + | 100 | |
| 692 | + | end | |
| 693 | + | ||
| 694 | + | b.call #=> 100 | |
| 695 | + | ``` | |
| 696 | + | ||
| 697 | + | `Block.new` can take a block and then `call`. | |
| 698 | + | ||
| 699 | + | ### Passing a block | |
| 700 | + | ||
| 701 | + | ```ruby | |
| 702 | + | def baz | |
| 703 | + | 1000 | |
| 704 | + | end | |
| 705 | + | ||
| 706 | + | class Foo | |
| 707 | + | def exec_block(block) | |
| 708 | + | block.call | |
| 709 | + | end | |
| 710 | + | ||
| 711 | + | def baz | |
| 712 | + | 100 | |
| 713 | + | end | |
| 714 | + | end | |
| 715 | + | ||
| 716 | + | b = Block.new do | |
| 717 | + | baz | |
| 718 | + | end | |
| 719 | + | ||
| 720 | + | f = Foo.new | |
| 721 | + | f.exec_block(b) | |
| 722 | + | ``` | |
| 723 | + | ||
| 724 | + | ### Passing a block with block arguments | |
| 725 | + | ||
| 726 | + | ```ruby | |
| 727 | + | b = Block.new do |arg, offset| | |
| 728 | + | arg + 1000 - offset | |
| 729 | + | end | |
| 730 | + | ||
| 731 | + | b.call(49, 500) #=> 549 | |
| 732 | + | ``` | |
| 733 | + | ||
| 734 | + | ### Special `get_block` keyword | |
| 735 | + | ||
| 736 | + | ```ruby | |
| 737 | + | def bar(block) | |
| 738 | + | # runs the block object and the block arg simultaneously | |
| 739 | + | block.call + get_block.call | |
| 740 | + | end | |
| 741 | + | ||
| 742 | + | def foo | |
| 743 | + | bar(get_block) do # passes two blocks to `bar` | |
| 744 | + | 20 | |
| 745 | + | end | |
| 746 | + | end | |
| 747 | + | ||
| 748 | + | foo do | |
| 749 | + | 10 | |
| 750 | + | end | |
| 751 | + | ``` | |
| 752 | + | ||
| 753 | + | `get_block` is not a method but a **keyword** to retrive a given block argument as a block object. By this, you can pass around or `call` the given block arguments as block objects. | |
| 754 | + | ||
| 755 | + | ### Closure | |
| 756 | + | ||
| 757 | + | ```ruby | |
| 758 | + | count = 0 # the declaration is used | |
| 759 | + | b = Block.new do | |
| 760 | + | count += 1 # the block looks preserving the `count` | |
| 761 | + | end | |
| 762 | + | ||
| 763 | + | class Foo | |
| 764 | + | def bar(blk) | |
| 765 | + | count = 9 # (does not affect) | |
| 766 | + | puts blk.call # local variable is resolved to the one above | |
| 767 | + | end | |
| 768 | + | end | |
| 769 | + | ||
| 770 | + | Foo.new.bar b #=> 1 | |
| 771 | + | Foo.new.bar b #=> 2 | |
| 772 | + | Foo.new.bar b #=> 3 | |
| 773 | + | ``` | |
| 774 | + | ||
| 775 | + | ## Native class (Primary) | |
| 776 | + | {: .-three-column} | |
| 777 | + | ||
| 778 | + | Goby's most "native" classes cannot instantiate with `new` in principle. | |
| 779 | + | ||
| 780 | + | ### `Object` | |
| 781 | + | ||
| 782 | + | ```ruby | |
| 783 | + | Bar.ancestors | |
| 784 | + | #» [Bar, Foo, Object] | |
| 785 | + | Bar.singleton_class.ancestors | |
| 786 | + | #» [#<Class:Bar>, #<Class:Object>, Class, Object] | |
| 787 | + | ``` | |
| 788 | + | ||
| 789 | + | `Object` is actually just for creating singleton classes. See `Class`. | |
| 790 | + | ||
| 791 | + | * **`Object.methods`**: `!`, `!=`, `==`, `block_given?`, `class`, `exit`, `instance_eval`, `instance_variable_get`, `instance_variable_set`, `is_a?`, `methods`, `nil?`, `object_id`, `puts`, `raise`, `require`, `require_relative`, `send`, `singleton_class`, `sleep`, `thread`, `to_s`, `<`, `<=`, `>`, `>=`, `ancestors`, `attr_accessor`, `attr_reader`, `attr_writer`, `extend`, `include`, `name`, `new`, `superclass` | |
| 792 | + | ||
| 793 | + | * **`Object.new.methods`**: `!`, `!=`, `==`, `block_given?`, `class`, `exit`, `instance_eval`, `instance_variable_get`, `instance_variable_set`, `is_a?`, `methods`, `nil?`, `object_id`, `puts`, `raise`, `require`, `require_relative`, `send`, `singleton_class`, `sleep`, `thread`, `to_s` | |
| 794 | + | ||
| 795 | + | ### `Class` | |
| 796 | + | ||
| 797 | + | ```ruby | |
| 798 | + | String.ancestors #=> [String, Object] | |
| 799 | + | ``` | |
| 800 | + | ||
| 801 | + | `Class` and `Object`can actually be regarded as the same and you don't need to distinguish them in almost all the cases. | |
| 802 | + | ||
| 803 | + | * **`Class.methods`**: `<`, `<=`, `>`, `>=`, `ancestors`, `attr_accessor`, `attr_reader`, `attr_writer`, `extend`, `include`, `name`, `new`, `superclass`, `!`, `!=`, `==`, `block_given?`, `class`, `exit`, `instance_eval`, `instance_variable_get`, `instance_variable_set`, `is_a?`, `methods`, `nil?`, `object_id`, `puts`, `raise`, `require`, `require_relative`, `send`, `singleton_class`, `sleep`, `thread`, `to_s` | |
| 804 | + | ||
| 805 | + | ### `String` | |
| 806 | + | ||
| 807 | + | ```ruby | |
| 808 | + | puts "Hello" + ' ' + 'world' #=> Hello world | |
| 809 | + | ``` | |
| 810 | + | ||
| 811 | + | Fixed to **UTF-8** with mb4 support. | |
| 812 | + | ||
| 813 | + | * **`String.methods`**: `fmt`, | |
| 814 | + | * the rest: `Class.methods` | |
| 815 | + | * **`"a".methods`**: `!=`, `*`, `+`, `<`, `<=>`, `==`, `=~`, `>`, `[]`, `[]=`, `capitalize`, `chop`, `concat`, `count`, `delete`, `downcase`, `each_byte`, `each_char`, `each_line`, `empty?`, `end_with?`, `eql?`, `fmt`, `include?`, `insert`, `length`, `ljust`, `match`, `new`, `replace`, `replace_once`, `reverse`, `rjust`, `size`, `slice`, `split`, `start_with`, `strip`, `to_a`, `to_bytes`, `to_d`, `to_f`, `to_i`, `to_s`, `upcase`, | |
| 816 | + | * the rest: `Object.new.methods` | |
| 817 | + | ||
| 818 | + | ### `Integer` | |
| 819 | + | ||
| 820 | + | ```ruby | |
| 821 | + | 37037 * 27 #=> 999999 | |
| 822 | + | ``` | |
| 823 | + | ||
| 824 | + | * **`Integer.methods`**: the same as `Class.methods` | |
| 825 | + | * **`1.methods`**: `!=`, `%`, `*`, `**`, `+`, `-`, `/`, `<`, `<=`, `<=>`, `==`, `>`, `>=`, `even?`, `new`, `next`, `odd?`, `pred`, `ptr`, `times`, `to_f`, `to_float32`, `to_float64`, `to_i`, `to_int`, `to_int16`, `to_int32`, `to_int64`, `to_int8`, `to_s`, `to_uint`, `to_uint16`, `to_uint32`, `to_uint64`, `to_uint8` | |
| 826 | + | * the rest: `Object.new.methods` | |
| 827 | + | ||
| 828 | + | ### `Array` | |
| 829 | + | ||
| 830 | + | ```ruby | |
| 831 | + | [1, "2", :card, [4, 5], { john: "doe" }] | |
| 832 | + | ``` | |
| 833 | + | ||
| 834 | + | * **`Array.methods`**: the same as `Class.methods` | |
| 835 | + | * **`[1].methods`**: `*`, `+`, `[]`, `[]=`, `any?`, `at`, `clear`, `concat`, `count`, `delete_at`, `dig`, `each`, `each_index`, `empty?`, `first`, `flatten`, `include?`, `join`, `last`, `lazy`, `length`, `map`, `new`, `pop`, `push`, `reduce`, `reverse`, `reverse_each`, `rotate`, `select`, `shift`, `to_enum`, `unshift`, `values_at` | |
| 836 | + | * the rest: `Object.new.methods` | |
| 837 | + | ||
| 838 | + | ### `Hash` | |
| 839 | + | ||
| 840 | + | ```ruby | |
| 841 | + | h = { key: "value" } | |
| 842 | + | h = { "key": "value" } #=> error | |
| 843 | + | ||
| 844 | + | h["key"] #=> value | |
| 845 | + | h[:key] #=> value | |
| 846 | + | ``` | |
| 847 | + | ||
| 848 | + | Keys in hash literals should be **symbol literals**, while Hash index can be either string or symbol literals. | |
| 849 | + | ||
| 850 | + | * **`Hash.methods`**: the same as `Class.methods` | |
| 851 | + | * **`{ key: "value" }.methods`**: `[]`, `[]=`, `any?`, `clear`, `default`, `default=`, `delete`, `delete_if`, `dig`, `each`, `each_key`, `each_value`, `empty?`, `eql?`, `fetch`, `fetch_values`, `has_key?`, `has_value?`, `keys`, `length`, `map_values`, `merge`, `new`, `select`, `sorted_keys`, `to_a`, `to_json`, `to_s`, `transform_values`, `values`, `values_at` | |
| 852 | + | * the rest: `Object.new.methods` | |
| 853 | + | ||
| 854 | + | ### `Range` | |
| 855 | + | ||
| 856 | + | ```ruby | |
| 857 | + | (1..10).each do |i| | |
| 858 | + | puts i ** 2 | |
| 859 | + | end | |
| 860 | + | ``` | |
| 861 | + | ||
| 862 | + | * **`Range.methods`**: the same as `Class.methods` | |
| 863 | + | * **`(1..10).methods`**: `!=`, `==`, `bsearch`, `each`, `first`, `include?`, `last`, `lazy`, `map`, `new`, `size`, `step`, `to_a`, `to_enum` | |
| 864 | + | * the rest: `Object.new.methods` | |
| 865 | + | ||
| 866 | + | ### `Block` | |
| 867 | + | ||
| 868 | + | ```ruby | |
| 869 | + | b = Block.new do | |
| 870 | + | 100 | |
| 871 | + | end | |
| 872 | + | ||
| 873 | + | b.call #=> 100 | |
| 874 | + | ``` | |
| 875 | + | ||
| 876 | + | * **`Block.methods`**: the same as `Class.methods` | |
| 877 | + | * **`(Block.new do end).methods`**: `call` | |
| 878 | + | * the rest: `Object.new.methods` | |
| 879 | + | ||
| 880 | + | ## Native class (secondary) | |
| 881 | + | {: .-three-column} | |
| 882 | + | ||
| 883 | + | ### `Float` | |
| 884 | + | ||
| 885 | + | ```ruby | |
| 886 | + | 1.1 + 1.1 # => -2.2 | |
| 887 | + | 2.1 * -2.1 # => -4.41 | |
| 888 | + | ``` | |
| 889 | + | ||
| 890 | + | Float literals like `3.14` or `-273.15`. `Float` class is based on Golang's `float64` type. | |
| 891 | + | ||
| 892 | + | * **`Float.methods`**: the same as `Class.methods` | |
| 893 | + | * **`3.14.methods`**: `!=`, `%`, `*`, `**`, `+`, `-`, `/`, `<`, `<=`, `<=>`, `==`, `>`, `>=`, `new`, `ptr`, `to_d`, `to_i` | |
| 894 | + | * the rest: `Object.new.methods` | |
| 895 | + | ||
| 896 | + | ### `Decimal` | |
| 897 | + | ||
| 898 | + | ```ruby | |
| 899 | + | "3.14".to_d # => 3.14 | |
| 900 | + | "-0.7238943".to_d # => -0.7238943 | |
| 901 | + | "355/113".to_d | |
| 902 | + | # => 3.1415929203539823008849557522123893805309734513274336283185840 | |
| 903 | + | ||
| 904 | + | a = "16.1".to_d | |
| 905 | + | b = "1.1".to_d | |
| 906 | + | e = "17.2".to_d | |
| 907 | + | a + b # => 0.1 | |
| 908 | + | a + b == e # => true | |
| 909 | + | ||
| 910 | + | ('16.1'.to_d + "1.1".to_d).to_s #=> 17.2 | |
| 911 | + | ('16.1'.to_f + "1.1".to_f).to_s #=> 17.200000000000003 | |
| 912 | + | ``` | |
| 913 | + | ||
| 914 | + | Experimental: the size is arbitrary and internally a fraction from Golang's `big.Rat` type. Decimal literal is TBD for now and you can get `Decimal` number via `to_d` method from `Integer`/`Float`/`String`. | |
| 915 | + | ||
| 916 | + | * **`Decimal.methods`**: the same as `Class.methods` | |
| 917 | + | * **`(1.1).to_d.methods`**: `!=`, `*`, `**`, `+`, `-`, `/`, `<`, `<=`, `<=>`, `==`, `>`, `>=`, `denominator`, `fraction`, `inverse` | |
| 918 | + | * the rest: `Object.new.methods` | |
| 919 | + | ||
| 920 | + | ### `Regexp` | |
| 921 | + | ||
| 922 | + | ```ruby | |
| 923 | + | a = Regexp.new("orl") | |
| 924 | + | a.match?("Hello World") #=> true | |
| 925 | + | a.match?("Hello Regexp") #=> false | |
| 926 | + | ||
| 927 | + | b = Regexp.new("😏") | |
| 928 | + | b.match?("🤡 😏 😐") #=> true | |
| 929 | + | b.match?("😝 😍 😊") #=> false | |
| 930 | + | ||
| 931 | + | c = Regexp.new("居(ら(?=れ)|さ(?=せ)|る|ろ|れ(?=[ばる])|よ|(?=な[いかくけそ]|ま[しすせ]|そう|た|て))") | |
| 932 | + | c.match?("居られればいいのに") #=> true | |
| 933 | + | c.match?("居ずまいを正す") #=> false | |
| 934 | + | ``` | |
| 935 | + | ||
| 936 | + | Using `/ /` is to be implemented. | |
| 937 | + | ||
| 938 | + | * **`Regexp.methods`**: the same as `Class.methods` | |
| 939 | + | * **`Regexp.new("^aa$").methods`**: `==`, `match?` | |
| 940 | + | * the rest: `Object.new.methods` | |
| 941 | + | ||
| 942 | + | ### `MatchData` | |
| 943 | + | ||
| 944 | + | ```ruby | |
| 945 | + | # numbered capture | |
| 946 | + | 'abcd'.match(Regexp.new('(b.)')) | |
| 947 | + | #=> #<MatchData 0:"bc" 1:"bc"> | |
| 948 | + | ||
| 949 | + | # named capture | |
| 950 | + | 'abcd'.match(Regexp.new('a(?<first>b)(?<second>c)')) | |
| 951 | + | #=> #<MatchData 0:"abc" first:"b" second:"c"> | |
| 952 | + | ||
| 953 | + | # converting to hash | |
| 954 | + | » 'abcd'.match(Regexp.new('a(?<first>b)(?<second>c)')).to_h | |
| 955 | + | #» { 0: "abc", first: "b", second: "c" } | |
| 956 | + | ``` | |
| 957 | + | ||
| 958 | + | The number keys in the captures are actually `String` class.The key `0` is the mached string. | |
| 959 | + | ||
| 960 | + | * **`MatchData.methods`**: the same as `Class.methods` | |
| 961 | + | * **`'abcd'.match(Regexp.new('(b.)')).methods`**: `captures`, `length`, `new`, `to_a`, `to_h` | |
| 962 | + | * the rest: `Object.new.methods` | |
| 963 | + | ||
| 964 | + | ### `File` | |
| 965 | + | ||
| 966 | + | ```ruby | |
| 967 | + | f = File.new("../test_fixtures/file_test/size.gb") | |
| 968 | + | f.name #=> "../test_fixtures/file_test/size.gb" | |
| 969 | + | ``` | |
| 970 | + | ||
| 971 | + | * **`File.methods`**: `basename`, `chmod`, `delete`, `exist?`, `extname`, `join` | |
| 972 | + | * the rest: `Class.methods` | |
| 973 | + | * **`File.new.methods`**: `basename`, `chmod`, `close`, `delete`, `exist?`, `extname`, `join`, `name` | |
| 974 | + | * the rest: `Object.new.methods` | |
| 975 | + | ||
| 976 | + | ## Native class (Golang-oriented) | |
| 977 | + | {: .-three-column} | |
| 978 | + | ||
| 979 | + | ### `GoMap` | |
| 980 | + | ||
| 981 | + | ```ruby | |
| 982 | + | h = { foo: "bar" } | |
| 983 | + | m = GoMap.new(h) # to pass values to Golang's code | |
| 984 | + | h2 = m.to_hash | |
| 985 | + | h2[:foo] #=> "bar" | |
| 986 | + | ``` | |
| 987 | + | ||
| 988 | + | * **`GoMap.methods`**: the same as `Class.methods` | |
| 989 | + | * **`GoMap.new.methods`**: `get`, `set`, `to_hash` | |
| 990 | + | * the rest: `Object.new.methods` | |
| 991 | + | ||
| 992 | + | ### `Channel` | |
| 993 | + | ||
| 994 | + | ```ruby | |
| 995 | + | c = Channel.new | |
| 996 | + | ||
| 997 | + | 1001.times do |i| # i start from 0 to 1000 | |
| 998 | + | thread do | |
| 999 | + | c.deliver(i) | |
| 1000 | + | end | |
| 1001 | + | end | |
| 1002 | + | ||
| 1003 | + | r = 0 | |
| 1004 | + | 1001.times do | |
| 1005 | + | r = r + c.receive | |
| 1006 | + | end | |
| 1007 | + | ||
| 1008 | + | r #=> 500500 | |
| 1009 | + | ``` | |
| 1010 | + | ||
| 1011 | + | `Channel` class is to hold channels to work with `#thread`. See `thread`. | |
| 1012 | + | ||
| 1013 | + | * **`Channel.methods`**: the same as `Class.methods` | |
| 1014 | + | * **`Channel.new.methods`**: `close`, `deliver`, `new`, `receive` | |
| 1015 | + | * the rest: `Object.new.methods` | |
| 1016 | + | ||
| 1017 | + | ## Enumerator & lazy | |
| 1018 | + | ||
| 1019 | + | Pretty new experimental library. | |
| 1020 | + | ||
| 1021 | + | ### `LazyEnumerator` | |
| 1022 | + | ||
| 1023 | + | ```ruby | |
| 1024 | + | # creating a lazy enumerator | |
| 1025 | + | enumerator = LazyEnumerator.new(ArrayEnumerator.new([1, 2, 3])) do |value| | |
| 1026 | + | 2 * value | |
| 1027 | + | end | |
| 1028 | + | result = [] | |
| 1029 | + | ||
| 1030 | + | enumerator.each do |value| | |
| 1031 | + | result.push(value) | |
| 1032 | + | end | |
| 1033 | + | ||
| 1034 | + | result #=> [2, 4, 6] | |
| 1035 | + | ``` | |
| 1036 | + | ||
| 1037 | + | A shorthand `#lazy` method is also provided in `Array` and `Range` by now. See "Tips & tricks" below. | |
| 1038 | + | ||
| 1039 | + | * **`LazyEnumerator.methods`**: the same as `Class.methods` | |
| 1040 | + | * **`[1, 2].lazy`**: `each`, `first`, `has_next?`, `initialize`, `map`, `next` | |
| 1041 | + | * the rest: `Object.new.methods` | |
| 1042 | + | ||
| 1043 | + | ### `ArrayEnumerator` | |
| 1044 | + | ||
| 1045 | + | ```ruby | |
| 1046 | + | iterated_values = [] | |
| 1047 | + | ||
| 1048 | + | enumerator = ArrayEnumerator.new([1, 2, 4]) | |
| 1049 | + | ||
| 1050 | + | while enumerator.has_next? do | |
| 1051 | + | iterated_values.push(enumerator.next) | |
| 1052 | + | end | |
| 1053 | + | ||
| 1054 | + | iterated_values #=> [1, 2, 4] | |
| 1055 | + | ``` | |
| 1056 | + | ||
| 1057 | + | * **`ArrayEnumerator.methods`**: the same as `Class.methods` | |
| 1058 | + | * **`ArrayEnumerator.new([1, 2, 3]).methods`**: `has_next?`, `initialize`, `next` | |
| 1059 | + | * the rest: `Object.new.methods` | |
| 1060 | + | ||
| 1061 | + | ### `RangeEnumerator` | |
| 1062 | + | ||
| 1063 | + | ```ruby | |
| 1064 | + | iterated_values = [] | |
| 1065 | + | ||
| 1066 | + | enumerator = RangeEnumerator.new((1..4)) | |
| 1067 | + | ||
| 1068 | + | while enumerator.has_next? do | |
| 1069 | + | iterated_values.push(enumerator.next) | |
| 1070 | + | end | |
| 1071 | + | ||
| 1072 | + | iterated_values #=> [1, 2, 3, 4] | |
| 1073 | + | ``` | |
| 1074 | + | ||
| 1075 | + | * **`RangeEnumerator.methods`**: the same as `Class.methods` | |
| 1076 | + | * **`RangeEnumerator.new(1..2).methods`**: `has_next?`, `initialize`, `next` | |
| 1077 | + | * the rest: `Object.new.methods` | |
| 1078 | + | ||
| 1079 | + | ## Special class | |
| 1080 | + | ||
| 1081 | + | ### `Boolean` | |
| 1082 | + | ||
| 1083 | + | ```ruby | |
| 1084 | + | true.class #=> Boolean | |
| 1085 | + | false.class #=> Boolean | |
| 1086 | + | ``` | |
| 1087 | + | ||
| 1088 | + | A special class that just to hold `true` and `false`. Cannot be instantiate. | |
| 1089 | + | ||
| 1090 | + | ### `Null` | |
| 1091 | + | ||
| 1092 | + | ```ruby | |
| 1093 | + | nil.class #=> Null | |
| 1094 | + | ``` | |
| 1095 | + | ||
| 1096 | + | A special class that just to hold `nil`. Cannot be instantiate. | |
| 1097 | + | ||
| 1098 | + | ### `Method` | |
| 1099 | + | ||
| 1100 | + | (A special dummy class that just holds methods defined by Goby code.) | |
| 1101 | + | ||
| 1102 | + | ### `Diggable` | |
| 1103 | + | ||
| 1104 | + | Provides `#dig` method. Currently. `Array` and `Hash` classes' instance can be `Diggable`. | |
| 1105 | + | ||
| 1106 | + | ```ruby | |
| 1107 | + | [1, 2].dig(0, 1) #=> TypeError: Expect target to be Diggable, got Integer | |
| 1108 | + | ``` | |
| 1109 | + | ||
| 1110 | + | ## Testing framework | |
| 1111 | + | ||
| 1112 | + | ### `Spec` | |
| 1113 | + | ||
| 1114 | + | ```ruby | |
| 1115 | + | require "spec" | |
| 1116 | + | ||
| 1117 | + | Spec.describe Spec do | |
| 1118 | + | it "fails and exit with code 1" do | |
| 1119 | + | expect(1).to eq(2) | |
| 1120 | + | end | |
| 1121 | + | end | |
| 1122 | + | ||
| 1123 | + | Spec.run | |
| 1124 | + | ``` | |
| 1125 | + | ||
| 1126 | + | * **`Spec.methods`**: `describe`, `describes`, `instance`, `run` | |
| 1127 | + | * the rest: `Object.methods` | |
| 1128 | + | * **`Spec.new.methods`**: `describes`, `initialize`, `run`, `session_successful`, `session_successful=` | |
| 1129 | + | * the rest: `Hash.new.methods` | |
| 1130 | + | ||
| 1131 | + | ## Tips & tricks | |
| 1132 | + | ||
| 1133 | + | ### Showing methods | |
| 1134 | + | ||
| 1135 | + | ```ruby | |
| 1136 | + | » "string".methods | |
| 1137 | + | #» ["!=", "*", "+", "<", "<=>", "==", "=~", ">", "[]", "[]=", "capitalize", "chop", "concat", "count", "delete", "downcase", "each_byte", "each_char", "each_line", "empty?", "end_with?", "eql?", "fmt", "include?", "insert", "length", "ljust", "match", "new", "replace", "replace_once", "reverse", "rjust", "size", "slice", "split", "start_with", "strip", "to_a", "to_bytes", "to_d", "to_f", "to_i", "to_s", "upcase", "!", "block_given?", "class", "exit", "instance_eval", "instance_variable_get", "instance_variable_set", "is_a?", "methods", "nil?", "object_id", "puts", "raise", "require", "require_relative", "send", "singleton_class", "sleep", "thread"] | |
| 1138 | + | ``` | |
| 1139 | + | ||
| 1140 | + | ### Showing class | |
| 1141 | + | ||
| 1142 | + | ```ruby | |
| 1143 | + | » "string".class | |
| 1144 | + | #» String | |
| 1145 | + | ``` | |
| 1146 | + | ||
| 1147 | + | ### Showing singleton class | |
| 1148 | + | ||
| 1149 | + | ```ruby | |
| 1150 | + | » "moji".singleton_class | |
| 1151 | + | #» #<Class:#<String:842352325152>> | |
| 1152 | + | ||
| 1153 | + | » "moji".class.singleton_class | |
| 1154 | + | #» #<Class:String> | |
| 1155 | + | ``` | |
| 1156 | + | ||
| 1157 | + | ### Showing ancestors | |
| 1158 | + | ||
| 1159 | + | ```ruby | |
| 1160 | + | » Integer.ancestors | |
| 1161 | + | #» [Integer, Object] | |
| 1162 | + | ||
| 1163 | + | » "moji".class.ancestors | |
| 1164 | + | #» [String, Object] | |
| 1165 | + | ``` | |
| 1166 | + | ||
| 1167 | + | ### Showing singleton classes' ancestors | |
| 1168 | + | ||
| 1169 | + | ```ruby | |
| 1170 | + | » "moji".class.singleton_class.ancestors | |
| 1171 | + | #» [#<Class:String>, #<Class:Object>, Class, Object] | |
| 1172 | + | ``` | |
| 1173 | + | ||
| 1174 | + | ### Showing object's id | |
| 1175 | + | ||
| 1176 | + | ```ruby | |
| 1177 | + | » "moji".object_id | |
| 1178 | + | #» 842352977920 | |
| 1179 | + | ``` | |
| 1180 | + | ||
| 1181 | + | ### `#to_json` | |
| 1182 | + | ||
| 1183 | + | ```ruby | |
| 1184 | + | h = { a: 1, b: [1, "2", [4, 5, nil]]} | |
| 1185 | + | h.to_json # converts hash to JSON | |
| 1186 | + | #=> {"a":1, "b":[1, "2", [4, 5, null]]} | |
| 1187 | + | ``` | |
| 1188 | + | ||
| 1189 | + | ### Customize `#to_json` | |
| 1190 | + | ||
| 1191 | + | Overwrite the `#to_json` in your class: | |
| 1192 | + | ||
| 1193 | + | ```ruby | |
| 1194 | + | class JobTitle | |
| 1195 | + | def initialize(name) | |
| 1196 | + | @name = name | |
| 1197 | + | end | |
| 1198 | + | ||
| 1199 | + | def to_json | |
| 1200 | + | { title: @name }.to_json | |
| 1201 | + | end | |
| 1202 | + | end | |
| 1203 | + | ||
| 1204 | + | class Person | |
| 1205 | + | def initialize(name, age) | |
| 1206 | + | @name = name | |
| 1207 | + | @age = age | |
| 1208 | + | @job = JobTitle.new("software engineer") | |
| 1209 | + | end | |
| 1210 | + | ||
| 1211 | + | def to_json | |
| 1212 | + | { name: @name, age: @age, job: @job }.to_json | |
| 1213 | + | end | |
| 1214 | + | end | |
| 1215 | + | ||
| 1216 | + | stan = Person.new("Stan", 23) | |
| 1217 | + | h = { person: stan } | |
| 1218 | + | h.to_json #=> {"person":{"name":"Stan","job":{"title":"software engineer"},"age":23}} | |
| 1219 | + | ``` | |
| 1220 | + | ||
| 1221 | + | ### Lazy enumeration | |
| 1222 | + | ||
| 1223 | + | To avoid N + 1 query. | |
| 1224 | + | ||
| 1225 | + | ```ruby | |
| 1226 | + | enumerator = [1, 2, 3].lazy.map do |value| | |
| 1227 | + | 2 * value | |
| 1228 | + | end | |
| 1229 | + | result = [] | |
| 1230 | + | ||
| 1231 | + | enumerator.each do |value| | |
| 1232 | + | result.push(value) | |
| 1233 | + | end | |
| 1234 | + | ||
| 1235 | + | result #=> [2, 4, 6] | |
| 1236 | + | ``` | |
| 1237 | + | ||
| 1238 | + | You can call `#lazy.map` on `Array`, `Range`, or `JSON` objects. | |
| 1239 | + | ||
| 1240 | + | ## Styling | |
| 1241 | + | ||
| 1242 | + | ### Quick style guide | |
| 1243 | + | ||
| 1244 | + | * UTF-8 should be used. | |
| 1245 | + | * Only two spaces ` ` should be used for one indentation. | |
| 1246 | + | * Tab cannot be used for indentation. | |
| 1247 | + | * For more, follow [RuboCop's style guide](https://github.com/bbatsov/ruby-style-guide) in principle. | |
| 1248 | + | ||
| 1249 | + | ### Document notation | |
| 1250 | + | ||
| 1251 | + | * `Class#instance_method` -- use `#` to represent instance methods in documents | |
| 1252 | + | * `Class.class_method` | |
| 1253 | + | * `Module.module_method` | |
| 1254 | + | ||
| 1255 | + | ### Syntax highlighting | |
| 1256 | + | ||
| 1257 | + | Ready for Vim and Sublime text. You can also use Ruby's syntax highlighting so far. | |
| 1258 | + | ||
| 1259 | + | ## References | |
| 1260 | + | ||
| 1261 | + | ### Official | |
| 1262 | + | ||
| 1263 | + | * Official site: [https://goby-lang.org/](https://goby-lang.org/) | |
| 1264 | + | * Repository: [https://github.com/goby-lang/goby/](https://github.com/goby-lang/goby/) | |
| 1265 | + | * DevHints: [https://devhints.io/goby](https://devhints.io/goby) (this page) | |
| 1266 | + | ||
| 1267 | + | ### Readings for Goby developers | |
| 1268 | + | ||
| 1269 | + | * [Write an Interpreter in Go](https://interpreterbook.com/) | |
| 1270 | + | * [Nand2Tetris II](https://www.coursera.org/learn/nand2tetris2/home/welcome) | |
| 1271 | + | * [Ruby under a microscope](http://patshaughnessy.net/ruby-under-a-microscope) | |
| 1272 | + | * [YARV's instruction table](http://www.atdot.net/yarv/insnstbl.html) | |
| 1273 | + | ||
| 1274 | + | ### JP resource | |
| 1275 | + | ||
| 1276 | + | * [Goby: Rubyライクな言語(1)Gobyを動かしてみる](https://techracho.bpsinc.jp/hachi8833/2017_11_10/47787) | |
| 1277 | + | * [Gobyの組み込みクラスにメソッドを追加する方法](https://qiita.com/hanachin_/items/efc1c976a4f5749514ef) |
| ... | ... | @@ -0,0 +1,273 @@ | |
| 1 | + | --- | |
| 2 | + | title: GraphQL | |
| 3 | + | layout: 2017/sheet | |
| 4 | + | updated: 2019-07-07 | |
| 5 | + | category: API | |
| 6 | + | --- | |
| 7 | + | ||
| 8 | + | ## Intro | |
| 9 | + | ||
| 10 | + | ## Queries | |
| 11 | + | {: .-three-column} | |
| 12 | + | ||
| 13 | + | ### Basic query | |
| 14 | + | ||
| 15 | + | ```js | |
| 16 | + | { status } | |
| 17 | + | ``` | |
| 18 | + | ||
| 19 | + | #### ↓ | |
| 20 | + | ||
| 21 | + | ```js | |
| 22 | + | { status: 'available' } | |
| 23 | + | ``` | |
| 24 | + | {: .-setup} | |
| 25 | + | ||
| 26 | + | ### Nesting | |
| 27 | + | ||
| 28 | + | ```js | |
| 29 | + | { hero { name height } } | |
| 30 | + | ``` | |
| 31 | + | ||
| 32 | + | #### ↓ | |
| 33 | + | ||
| 34 | + | ```js | |
| 35 | + | { hero: | |
| 36 | + | { name: "Luke Skywalker", | |
| 37 | + | height: 1.74 } } | |
| 38 | + | ``` | |
| 39 | + | {: .-setup} | |
| 40 | + | ||
| 41 | + | ### Lists | |
| 42 | + | ||
| 43 | + | ```js | |
| 44 | + | { friends { name } } | |
| 45 | + | ``` | |
| 46 | + | ||
| 47 | + | #### ↓ | |
| 48 | + | ||
| 49 | + | ```js | |
| 50 | + | { friends: | |
| 51 | + | [ { name: "Luke Skywalker" }, | |
| 52 | + | { name: "Han Solo" }, | |
| 53 | + | { name: "R2D2" } ] } | |
| 54 | + | ``` | |
| 55 | + | {: .-setup} | |
| 56 | + | ||
| 57 | + | GraphQL queries look the same for both single items or lists of items. | |
| 58 | + | ||
| 59 | + | ### Lookups | |
| 60 | + | ||
| 61 | + | ```js | |
| 62 | + | { | |
| 63 | + | hero(id: "1000") { id name } | |
| 64 | + | } | |
| 65 | + | ``` | |
| 66 | + | ||
| 67 | + | #### ↓ | |
| 68 | + | ||
| 69 | + | ```js | |
| 70 | + | { hero: | |
| 71 | + | { id: "1000", | |
| 72 | + | { name: "Luke Skywalker" } } | |
| 73 | + | ``` | |
| 74 | + | {: .-setup} | |
| 75 | + | ||
| 76 | + | ### Aliases | |
| 77 | + | ||
| 78 | + | ```js | |
| 79 | + | { | |
| 80 | + | luke: hero(id: "1000") { name } | |
| 81 | + | han: hero(id: "1001") { name } | |
| 82 | + | } | |
| 83 | + | ``` | |
| 84 | + | ||
| 85 | + | #### ↓ | |
| 86 | + | ||
| 87 | + | ```js | |
| 88 | + | { luke: | |
| 89 | + | { name: "Luke Skywalker" }, | |
| 90 | + | han: | |
| 91 | + | { name: "Han Solo" } } | |
| 92 | + | ``` | |
| 93 | + | {: .-setup} | |
| 94 | + | ||
| 95 | + | ### Operation names and variables | |
| 96 | + | ||
| 97 | + | #### Query | |
| 98 | + | ```js | |
| 99 | + | query FindHero($id: String!) { | |
| 100 | + | hero(id: $id) { name } | |
| 101 | + | } | |
| 102 | + | ``` | |
| 103 | + | ||
| 104 | + | Just to make things less ambiguous. Also, to use variables, you need an operation name. | |
| 105 | + | ||
| 106 | + | #### Variables | |
| 107 | + | ||
| 108 | + | ```js | |
| 109 | + | { id: '1000' } | |
| 110 | + | ``` | |
| 111 | + | ||
| 112 | + | ### Mutations | |
| 113 | + | ||
| 114 | + | #### Query | |
| 115 | + | ||
| 116 | + | ```js | |
| 117 | + | { createReview($review) { id } } | |
| 118 | + | ``` | |
| 119 | + | ||
| 120 | + | #### Variables | |
| 121 | + | ||
| 122 | + | ```js | |
| 123 | + | { review: { stars: 5 } } | |
| 124 | + | ``` | |
| 125 | + | ||
| 126 | + | #### ↓ | |
| 127 | + | ||
| 128 | + | ```js | |
| 129 | + | { createReview: { id: 5291 } } | |
| 130 | + | ``` | |
| 131 | + | ||
| 132 | + | Mutations are just fields that do something when queried. | |
| 133 | + | ||
| 134 | + | ### Multiple types | |
| 135 | + | ||
| 136 | + | ```js | |
| 137 | + | { | |
| 138 | + | search(q: "john") { | |
| 139 | + | id | |
| 140 | + | ... on User { name } | |
| 141 | + | ... on Comment { body author { name } } | |
| 142 | + | } | |
| 143 | + | } | |
| 144 | + | ``` | |
| 145 | + | ||
| 146 | + | Great for searching. | |
| 147 | + | ||
| 148 | + | ||
| 149 | + | Over HTTP | |
| 150 | + | --------- | |
| 151 | + | ||
| 152 | + | #### GET | |
| 153 | + | ||
| 154 | + | ```js | |
| 155 | + | fetch('http://myapi/graphql?query={ me { name } }') | |
| 156 | + | ``` | |
| 157 | + | ||
| 158 | + | #### POST | |
| 159 | + | ||
| 160 | + | ```js | |
| 161 | + | fetch('http://myapi/graphql', { | |
| 162 | + | body: JSON.stringify({ | |
| 163 | + | query: '...', | |
| 164 | + | operationName: '...', | |
| 165 | + | variables: { ... } | |
| 166 | + | }) | |
| 167 | + | }) | |
| 168 | + | ``` | |
| 169 | + | ||
| 170 | + | Schema | |
| 171 | + | ------ | |
| 172 | + | {: .-three-column} | |
| 173 | + | ||
| 174 | + | ### Basic schemas | |
| 175 | + | ||
| 176 | + | ```js | |
| 177 | + | type Query { | |
| 178 | + | me: User | |
| 179 | + | users(limit: Int): [User] | |
| 180 | + | } | |
| 181 | + | ||
| 182 | + | type User { | |
| 183 | + | id: ID! | |
| 184 | + | name: String | |
| 185 | + | } | |
| 186 | + | ``` | |
| 187 | + | ||
| 188 | + | See: [sogko/graphql-shorthand-notation-cheat-sheet](https://raw.githubusercontent.com/sogko/graphql-shorthand-notation-cheat-sheet/master/graphql-shorthand-notation-cheat-sheet.png) | |
| 189 | + | ||
| 190 | + | ### Built in types | |
| 191 | + | ||
| 192 | + | #### Scalar types | |
| 193 | + | ||
| 194 | + | | `Int` | Integer | | |
| 195 | + | | `Float` | Float | | |
| 196 | + | | `String` | String | | |
| 197 | + | | `Boolean` | Boolean | | |
| 198 | + | | `ID` | ID | | |
| 199 | + | ||
| 200 | + | #### Type definitions | |
| 201 | + | ||
| 202 | + | | `scalar` | Scalar type | | |
| 203 | + | | `type` | Object type | | |
| 204 | + | | `interface` | Interface type | | |
| 205 | + | | `union` | Union type | | |
| 206 | + | | `enum` | Enumerable type | | |
| 207 | + | | `input` | Input object type | | |
| 208 | + | ||
| 209 | + | #### Type modifiers | |
| 210 | + | ||
| 211 | + | | `String` | Nullable string | | |
| 212 | + | | `String!` | Required string | | |
| 213 | + | | `[String]` | List of strings | | |
| 214 | + | | `[String]!` | Required list of strings | | |
| 215 | + | | `[String!]!` | Required list of required strings | | |
| 216 | + | ||
| 217 | + | ### Mutations | |
| 218 | + | ||
| 219 | + | ```js | |
| 220 | + | type Mutation { | |
| 221 | + | users(params: ListUsersInput) [User]! | |
| 222 | + | } | |
| 223 | + | ``` | |
| 224 | + | ||
| 225 | + | ### Interfaces | |
| 226 | + | ||
| 227 | + | ```js | |
| 228 | + | interface Entity { | |
| 229 | + | id: ID! | |
| 230 | + | } | |
| 231 | + | ||
| 232 | + | type User implements Entity { | |
| 233 | + | id: ID! | |
| 234 | + | name: String | |
| 235 | + | } | |
| 236 | + | ``` | |
| 237 | + | ||
| 238 | + | ### Enums | |
| 239 | + | ||
| 240 | + | ```js | |
| 241 | + | enum DIRECTION { | |
| 242 | + | LEFT | |
| 243 | + | RIGHT | |
| 244 | + | } | |
| 245 | + | ||
| 246 | + | type Root { | |
| 247 | + | direction: DIRECTION! | |
| 248 | + | } | |
| 249 | + | ``` | |
| 250 | + | {: data-line="1,2,3,4"} | |
| 251 | + | ||
| 252 | + | ### Unions | |
| 253 | + | ||
| 254 | + | ```js | |
| 255 | + | type Artist { ··· } | |
| 256 | + | type Album { ··· } | |
| 257 | + | ||
| 258 | + | union Result = Artist | Album | |
| 259 | + | ||
| 260 | + | type Query { | |
| 261 | + | search(q: String) [Result] | |
| 262 | + | } | |
| 263 | + | ``` | |
| 264 | + | {: data-line="4"} | |
| 265 | + | ||
| 266 | + | References | |
| 267 | + | ---------- | |
| 268 | + | ||
| 269 | + | - <http://graphql.org/learn/queries/> | |
| 270 | + | - <http://graphql.org/learn/serving-over-http/> | |
| 271 | + | ||
| 272 | + | https://devhints.io/ cheatsheets - Copyright (c) 2021 Rico Sta. Cruz and contributors - MIT license | |
| 273 | + | micro-cheat plugin Copyright 2022 Tero Karvinen https://TeroKarvinen.com/micro - MIT license |
| ... | ... | @@ -0,0 +1,56 @@ | |
| 1 | + | --- | |
| 2 | + | title: Haml | |
| 3 | + | category: Markup | |
| 4 | + | layout: 2017/sheet | |
| 5 | + | prism_languages: [haml] | |
| 6 | + | --- | |
| 7 | + | ||
| 8 | + | ### Doctype | |
| 9 | + | ||
| 10 | + | ```haml | |
| 11 | + | !!! 5 | |
| 12 | + | ``` | |
| 13 | + | ||
| 14 | + | ### Tags | |
| 15 | + | ||
| 16 | + | ```haml | |
| 17 | + | %html | |
| 18 | + | %head | |
| 19 | + | %title | |
| 20 | + | %body | |
| 21 | + | %h1 Hello World | |
| 22 | + | %br/ | |
| 23 | + | ``` | |
| 24 | + | ||
| 25 | + | ### Classes and ID's | |
| 26 | + | ||
| 27 | + | ```haml | |
| 28 | + | %p.class-example | |
| 29 | + | .no-tag-defaults-to-div | |
| 30 | + | %div#butItCanBeIncluded | |
| 31 | + | ``` | |
| 32 | + | ||
| 33 | + | ### Inline Attributes | |
| 34 | + | ||
| 35 | + | Either hash syntax works | |
| 36 | + | ||
| 37 | + | ```haml | |
| 38 | + | %meta{ name: "viewport", content: "width=device-width, initial-scale=1.0" } | |
| 39 | + | %input{ :type => "text", :required => true } | |
| 40 | + | ``` | |
| 41 | + | ||
| 42 | + | ### Ruby | |
| 43 | + | ||
| 44 | + | ```haml | |
| 45 | + | -# This is a comment | |
| 46 | + | -# Anything starting with a hyphen signals to Haml that Ruby is coming | |
| 47 | + | - @arr = [1, 2, 3] | |
| 48 | + | - @str = "test" | |
| 49 | + | -# Equal signals output | |
| 50 | + | = render partial: "shared/header" | |
| 51 | + | = yield | |
| 52 | + | = link_to page_url | |
| 53 | + | ``` | |
| 54 | + | ||
| 55 | + | https://devhints.io/ cheatsheets - Copyright (c) 2021 Rico Sta. Cruz and contributors - MIT license | |
| 56 | + | micro-cheat plugin Copyright 2022 Tero Karvinen https://TeroKarvinen.com/micro - MIT license |
| ... | ... | @@ -0,0 +1,110 @@ | |
| 1 | + | --- | |
| 2 | + | title: HTML | |
| 3 | + | category: HTML | |
| 4 | + | layout: 2017/sheet | |
| 5 | + | --- | |
| 6 | + | ||
| 7 | + | ### Head stuff | |
| 8 | + | ||
| 9 | + | <link rel="shortcut icon" type="image/x-icon" href="/favicon.ico"> | |
| 10 | + | <link rel="shortcut icon" type="image/png" href="/favicon.png"> | |
| 11 | + | <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1"> | |
| 12 | + | ||
| 13 | + | ### iPhone viewport | |
| 14 | + | ||
| 15 | + | <meta name="viewport" content="initial-scale=1.0, maximum-scale=1.0"> | |
| 16 | + | <meta name="viewport" content="width=device-width"> | |
| 17 | + | <meta name="viewport" content="width=320, initial-scale=1.0, maximum-scale=1.0, user-scalable=0"/> <!-- full example --> | |
| 18 | + | ||
| 19 | + | ### Default OpenGraph meta tags | |
| 20 | + | ||
| 21 | + | <meta content="..." name="description"> | |
| 22 | + | <meta content="..." property="og:description"> | |
| 23 | + | <meta content="http://.../preview.jpg" property="og:image"> | |
| 24 | + | <meta content="Hello There" property="og:title"> | |
| 25 | + | <meta content="Hello There" property="og:site_name"> | |
| 26 | + | <meta content="hellothere" property="fb:admins"> | |
| 27 | + | <meta content="website" property="og:type"> | |
| 28 | + | ||
| 29 | + | ### Webfonts | |
| 30 | + | ||
| 31 | + | <script>WebFontConfig={ },function(a,b){var c=a.createElement(b);c.src="//ajax.googleapis.com/ajax/libs/webfont/1/webfont.js",c.async=1;var d=a.getElementsByTagName(b)[0];d.parentNode.insertBefore(c,d)}(document,"script")</script> | |
| 32 | + | ||
| 33 | + | // {typekit{id:"..."}} | |
| 34 | + | // {google:{families:['Exo:400']}} | |
| 35 | + | ||
| 36 | + | ### Google Analytics | |
| 37 | + | ||
| 38 | + | <script>location.hostname.match(/helloworld\.com/)&&(_gaq=[["_setAccount","UA-XXXXX-1"],["_trackPageview"]],function(a,b){var c=a.createElement(b),d=a.getElementsByTagName(b)[0];c.async=1,c.src=("https:"==location.protocol?"//ssl":"//www")+".google-analytics.com/ga.js",d.parentNode.insertBefore(c,d)}(document,"script"))</script> | |
| 39 | + | ||
| 40 | + | ### FB/Twitter | |
| 41 | + | ||
| 42 | + | <div id="fb-root"></div><script>fbAsyncInit=function(){FB.init({"appId":"___APPIDGOESHERE___","status":true,"cookie":true,"xfbml":true})};!function(d,s,id){var js,fjs=d.getElementsByTagName(s)[0];if(!d.getElementById(id)){js=d.createElement(s);js.id=id;js.async=1;js.src='//connect.facebook.net/en_US/all.js';fjs.parentNode.insertBefore(js,fjs);}}(document,'script','facebook-jssdk');</script> | |
| 43 | + | ||
| 44 | + | <script>!function(d,s,id){var js,fjs=d.getElementsByTagName(s)[0];if(!d.getElementById(id)){js=d.createElement(s);js.id=id;js.async=1;js.src="//platform.twitter.com/widgets.js";fjs.parentNode.insertBefore(js,fjs);}}(document,"script","twitter-wjs");</script> | |
| 45 | + | ||
| 46 | + | ### HTML5 Shiv for IE8 | |
| 47 | + | ||
| 48 | + | <!--[if lte IE 8]><script src='//cdnjs.cloudflare.com/ajax/libs/html5shiv/3.6.1/html5shiv.js'></script><![endif]--> | |
| 49 | + | ||
| 50 | + | ### H5BP HTML tag (IE8 and IE9 only) | |
| 51 | + | ||
| 52 | + | <!--[if lte IE 8]><html class="ie8"><![endif]--><!--[if IE 9]><html class="ie9"><![endif]--><!--[if gt IE 9]><!--> | |
| 53 | + | <html><!--<![endif]--> | |
| 54 | + | ||
| 55 | + | ### Touch icons | |
| 56 | + | ||
| 57 | + | * apple-touch-icon-precomposed.png | |
| 58 | + | * apple-touch-icon-57x57-precomposed.png | |
| 59 | + | * apple-touch-icon-72x72-precomposed.png | |
| 60 | + | * apple-touch-icon-114x114-precomposed.png | |
| 61 | + | * apple-touch-icon-144x144-precomposed.png | |
| 62 | + | ||
| 63 | + | ### Icons | |
| 64 | + | ||
| 65 | + | <link rel="shortcut icon" type="image/png" href="favicon.png"> | |
| 66 | + | <link href="apple-touch-icon-precomposed.png" rel="apple-touch-icon"> | |
| 67 | + | <link href="apple-touch-icon-57x57-precomposed.png" size="57x57" rel="apple-touch-icon"> | |
| 68 | + | <link href="apple-touch-icon-72x72-precomposed.png" size="72x72" rel="apple-touch-icon"> | |
| 69 | + | <link href="apple-touch-icon-114x114-precomposed.png" size="114x114" rel="apple-touch-icon"> | |
| 70 | + | <link href="apple-touch-icon-144x144-precomposed.png" size="144x144" rel="apple-touch-icon"> | |
| 71 | + | ||
| 72 | + | Only do this if you're not placing the site in the root! | |
| 73 | + | ||
| 74 | + | ### H5BP HTML tag | |
| 75 | + | ||
| 76 | + | <!--[if lt IE 7 ]> <html class="ie6"> <![endif]--> | |
| 77 | + | <!--[if IE 7 ]> <html class="ie7"> <![endif]--> | |
| 78 | + | <!--[if IE 8 ]> <html class="ie8"> <![endif]--> | |
| 79 | + | <!--[if IE 9 ]> <html class="ie9"> <![endif]--> | |
| 80 | + | <!--[if (gt IE 9)|!(IE)]><!--> <html class=""> <!--<![endif]--> | |
| 81 | + | ||
| 82 | + | ### Google jQuery | |
| 83 | + | ||
| 84 | + | <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script> | |
| 85 | + | ||
| 86 | + | ### Unsupported message | |
| 87 | + | ||
| 88 | + | <!--[if lt IE 8]> | |
| 89 | + | <div class="unsupported-browser"> | |
| 90 | + | <strong> | |
| 91 | + | You are using an outdated browser. | |
| 92 | + | </strong> | |
| 93 | + | <span> | |
| 94 | + | Please <a class="upgrade-browser" | |
| 95 | + | href="http://browsehappy.com/"> | |
| 96 | + | upgrade your browser</a> or <a class="chrome-frame" | |
| 97 | + | href="http://www.google.com/chromeframe/?redirect=true">activate Google | |
| 98 | + | Chrome Frame</a> to improve your experience. | |
| 99 | + | </span> | |
| 100 | + | </div> | |
| 101 | + | <![endif]--> | |
| 102 | + | ||
| 103 | + | ### HTML Compatibility inspector | |
| 104 | + | ||
| 105 | + | <script src="http://ie.microsoft.com/testdrive/HTML5/CompatInspector/inspector.js"></script> | |
| 106 | + | ||
| 107 | + | More info here: [microsoft.com](http://ie.microsoft.com/testdrive/HTML5/CompatInspector/) | |
| 108 | + | ||
| 109 | + | https://devhints.io/ cheatsheets - Copyright (c) 2021 Rico Sta. Cruz and contributors - MIT license | |
| 110 | + | micro-cheat plugin Copyright 2022 Tero Karvinen https://TeroKarvinen.com/micro - MIT license |
| ... | ... | @@ -0,0 +1,582 @@ | |
| 1 | + | --- | |
| 2 | + | title: ES2015+ | |
| 3 | + | category: JavaScript | |
| 4 | + | layout: 2017/sheet | |
| 5 | + | tags: [Featured] | |
| 6 | + | updated: 2019-11-14 | |
| 7 | + | weight: -10 | |
| 8 | + | intro: | | |
| 9 | + | A quick overview of new JavaScript features in ES2015, ES2016, ES2017, ES2018 and beyond. | |
| 10 | + | --- | |
| 11 | + | ||
| 12 | + | ### Block scoping | |
| 13 | + | ||
| 14 | + | #### Let | |
| 15 | + | ||
| 16 | + | ```js | |
| 17 | + | function fn () { | |
| 18 | + | let x = 0 | |
| 19 | + | if (true) { | |
| 20 | + | let x = 1 // only inside this `if` | |
| 21 | + | } | |
| 22 | + | } | |
| 23 | + | ``` | |
| 24 | + | {: data-line="2,4"} | |
| 25 | + | ||
| 26 | + | #### Const | |
| 27 | + | ||
| 28 | + | ```js | |
| 29 | + | const a = 1 | |
| 30 | + | ``` | |
| 31 | + | ||
| 32 | + | `let` is the new `var`. Constants work just like `let`, but can't be reassigned. | |
| 33 | + | See: [Let and const](https://babeljs.io/learn-es2015/#let--const) | |
| 34 | + | ||
| 35 | + | ### Backtick strings | |
| 36 | + | ||
| 37 | + | #### Interpolation | |
| 38 | + | ||
| 39 | + | ```js | |
| 40 | + | const message = `Hello ${name}` | |
| 41 | + | ``` | |
| 42 | + | ||
| 43 | + | #### Multiline strings | |
| 44 | + | ||
| 45 | + | ```js | |
| 46 | + | const str = ` | |
| 47 | + | hello | |
| 48 | + | world | |
| 49 | + | ` | |
| 50 | + | ``` | |
| 51 | + | ||
| 52 | + | Templates and multiline strings. | |
| 53 | + | See: [Template strings](https://babeljs.io/learn-es2015/#template-strings) | |
| 54 | + | ||
| 55 | + | ### Binary and octal literals | |
| 56 | + | ||
| 57 | + | ```js | |
| 58 | + | let bin = 0b1010010 | |
| 59 | + | let oct = 0o755 | |
| 60 | + | ``` | |
| 61 | + | ||
| 62 | + | See: [Binary and octal literals](https://babeljs.io/learn-es2015/#binary-and-octal-literals) | |
| 63 | + | ||
| 64 | + | ### New methods | |
| 65 | + | ||
| 66 | + | #### New string methods | |
| 67 | + | ||
| 68 | + | ```js | |
| 69 | + | "hello".repeat(3) | |
| 70 | + | "hello".includes("ll") | |
| 71 | + | "hello".startsWith("he") | |
| 72 | + | "hello".padStart(8) // " hello" | |
| 73 | + | "hello".padEnd(8) // "hello " | |
| 74 | + | "hello".padEnd(8, '!') // hello!!! | |
| 75 | + | "\u1E9B\u0323".normalize("NFC") | |
| 76 | + | ``` | |
| 77 | + | ||
| 78 | + | See: [New methods](https://babeljs.io/learn-es2015/#math--number--string--object-apis) | |
| 79 | + | ||
| 80 | + | ### Classes | |
| 81 | + | ||
| 82 | + | ```js | |
| 83 | + | class Circle extends Shape { | |
| 84 | + | ``` | |
| 85 | + | ||
| 86 | + | #### Constructor | |
| 87 | + | ||
| 88 | + | ```js | |
| 89 | + | constructor (radius) { | |
| 90 | + | this.radius = radius | |
| 91 | + | } | |
| 92 | + | ``` | |
| 93 | + | {: data-line="1"} | |
| 94 | + | ||
| 95 | + | #### Methods | |
| 96 | + | ||
| 97 | + | ```js | |
| 98 | + | getArea () { | |
| 99 | + | return Math.PI * 2 * this.radius | |
| 100 | + | } | |
| 101 | + | ``` | |
| 102 | + | {: data-line="1"} | |
| 103 | + | ||
| 104 | + | #### Calling superclass methods | |
| 105 | + | ||
| 106 | + | ```js | |
| 107 | + | expand (n) { | |
| 108 | + | return super.expand(n) * Math.PI | |
| 109 | + | } | |
| 110 | + | ``` | |
| 111 | + | {: data-line="2"} | |
| 112 | + | ||
| 113 | + | #### Static methods | |
| 114 | + | ||
| 115 | + | ```js | |
| 116 | + | static createFromDiameter(diameter) { | |
| 117 | + | return new Circle(diameter / 2) | |
| 118 | + | } | |
| 119 | + | } | |
| 120 | + | ``` | |
| 121 | + | {: data-line="1"} | |
| 122 | + | ||
| 123 | + | Syntactic sugar for prototypes. | |
| 124 | + | See: [Classes](https://babeljs.io/learn-es2015/#classes) | |
| 125 | + | ||
| 126 | + | ### Exponent operator | |
| 127 | + | ||
| 128 | + | ```js | |
| 129 | + | const byte = 2 ** 8 | |
| 130 | + | // Same as: Math.pow(2, 8) | |
| 131 | + | ``` | |
| 132 | + | {: data-line="1"} | |
| 133 | + | ||
| 134 | + | Promises | |
| 135 | + | -------- | |
| 136 | + | {: .-three-column} | |
| 137 | + | ||
| 138 | + | ### Making promises | |
| 139 | + | ||
| 140 | + | ```js | |
| 141 | + | new Promise((resolve, reject) => { | |
| 142 | + | if (ok) { resolve(result) } | |
| 143 | + | else { reject(error) } | |
| 144 | + | }) | |
| 145 | + | ``` | |
| 146 | + | {: data-line="1"} | |
| 147 | + | ||
| 148 | + | For asynchronous programming. | |
| 149 | + | See: [Promises](https://babeljs.io/learn-es2015/#promises) | |
| 150 | + | ||
| 151 | + | ### Using promises | |
| 152 | + | ||
| 153 | + | ```js | |
| 154 | + | promise | |
| 155 | + | .then((result) => { ··· }) | |
| 156 | + | .catch((error) => { ··· }) | |
| 157 | + | ``` | |
| 158 | + | {: data-line="2,3"} | |
| 159 | + | ||
| 160 | + | ||
| 161 | + | ### Using promises with finally | |
| 162 | + | ||
| 163 | + | ```js | |
| 164 | + | promise | |
| 165 | + | .then((result) => { ··· }) | |
| 166 | + | .catch((error) => { ··· }) | |
| 167 | + | .finally(() => { // logic independent of success/error }) | |
| 168 | + | ``` | |
| 169 | + | {: data-line="4"} | |
| 170 | + | ||
| 171 | + | The handler is called when the promise is fulfilled or rejected. | |
| 172 | + | ||
| 173 | + | ||
| 174 | + | ### Promise functions | |
| 175 | + | ||
| 176 | + | ```js | |
| 177 | + | Promise.all(···) | |
| 178 | + | Promise.race(···) | |
| 179 | + | Promise.reject(···) | |
| 180 | + | Promise.resolve(···) | |
| 181 | + | ``` | |
| 182 | + | ||
| 183 | + | ### Async-await | |
| 184 | + | ||
| 185 | + | ```js | |
| 186 | + | async function run () { | |
| 187 | + | const user = await getUser() | |
| 188 | + | const tweets = await getTweets(user) | |
| 189 | + | return [user, tweets] | |
| 190 | + | } | |
| 191 | + | ``` | |
| 192 | + | {: data-line="2,3"} | |
| 193 | + | ||
| 194 | + | `async` functions are another way of using functions. | |
| 195 | + | ||
| 196 | + | See: [async function](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/async_function) | |
| 197 | + | ||
| 198 | + | Destructuring | |
| 199 | + | ------------- | |
| 200 | + | {: .-three-column} | |
| 201 | + | ||
| 202 | + | ### Destructuring assignment | |
| 203 | + | ||
| 204 | + | #### Arrays | |
| 205 | + | ||
| 206 | + | ```js | |
| 207 | + | const [first, last] = ['Nikola', 'Tesla'] | |
| 208 | + | ``` | |
| 209 | + | {: data-line="1"} | |
| 210 | + | ||
| 211 | + | #### Objects | |
| 212 | + | ||
| 213 | + | ```js | |
| 214 | + | let {title, author} = { | |
| 215 | + | title: 'The Silkworm', | |
| 216 | + | author: 'R. Galbraith' | |
| 217 | + | } | |
| 218 | + | ``` | |
| 219 | + | {: data-line="1"} | |
| 220 | + | ||
| 221 | + | Supports for matching arrays and objects. | |
| 222 | + | See: [Destructuring](https://babeljs.io/learn-es2015/#destructuring) | |
| 223 | + | ||
| 224 | + | ### Default values | |
| 225 | + | ||
| 226 | + | ```js | |
| 227 | + | const scores = [22, 33] | |
| 228 | + | const [math = 50, sci = 50, arts = 50] = scores | |
| 229 | + | ``` | |
| 230 | + | ||
| 231 | + | ```js | |
| 232 | + | // Result: | |
| 233 | + | // math === 22, sci === 33, arts === 50 | |
| 234 | + | ``` | |
| 235 | + | ||
| 236 | + | Default values can be assigned while destructuring arrays or objects. | |
| 237 | + | ||
| 238 | + | ### Function arguments | |
| 239 | + | ||
| 240 | + | ```js | |
| 241 | + | function greet({ name, greeting }) { | |
| 242 | + | console.log(`${greeting}, ${name}!`) | |
| 243 | + | } | |
| 244 | + | ``` | |
| 245 | + | {: data-line="1"} | |
| 246 | + | ||
| 247 | + | ```js | |
| 248 | + | greet({ name: 'Larry', greeting: 'Ahoy' }) | |
| 249 | + | ``` | |
| 250 | + | ||
| 251 | + | Destructuring of objects and arrays can also be done in function arguments. | |
| 252 | + | ||
| 253 | + | ### Default values | |
| 254 | + | ||
| 255 | + | ```js | |
| 256 | + | function greet({ name = 'Rauno' } = {}) { | |
| 257 | + | console.log(`Hi ${name}!`); | |
| 258 | + | } | |
| 259 | + | ``` | |
| 260 | + | {: data-line="1"} | |
| 261 | + | ||
| 262 | + | ```js | |
| 263 | + | greet() // Hi Rauno! | |
| 264 | + | greet({ name: 'Larry' }) // Hi Larry! | |
| 265 | + | ``` | |
| 266 | + | ||
| 267 | + | ### Reassigning keys | |
| 268 | + | ||
| 269 | + | ```js | |
| 270 | + | function printCoordinates({ left: x, top: y }) { | |
| 271 | + | console.log(`x: ${x}, y: ${y}`) | |
| 272 | + | } | |
| 273 | + | ``` | |
| 274 | + | {: data-line="1"} | |
| 275 | + | ||
| 276 | + | ```js | |
| 277 | + | printCoordinates({ left: 25, top: 90 }) | |
| 278 | + | ``` | |
| 279 | + | ||
| 280 | + | This example assigns `x` to the value of the `left` key. | |
| 281 | + | ||
| 282 | + | ### Loops | |
| 283 | + | ||
| 284 | + | ```js | |
| 285 | + | for (let {title, artist} of songs) { | |
| 286 | + | ··· | |
| 287 | + | } | |
| 288 | + | ``` | |
| 289 | + | {: data-line="1"} | |
| 290 | + | ||
| 291 | + | The assignment expressions work in loops, too. | |
| 292 | + | ||
| 293 | + | ||
| 294 | + | ### Object destructuring | |
| 295 | + | ||
| 296 | + | ```js | |
| 297 | + | const { id, ...detail } = song; | |
| 298 | + | ``` | |
| 299 | + | {: data-line="1"} | |
| 300 | + | ||
| 301 | + | Extract some keys individually and remaining keys in the object using rest (...) operator | |
| 302 | + | ||
| 303 | + | ||
| 304 | + | Spread | |
| 305 | + | ------ | |
| 306 | + | ||
| 307 | + | ### Object spread | |
| 308 | + | ||
| 309 | + | #### with Object spread | |
| 310 | + | ||
| 311 | + | ```js | |
| 312 | + | const options = { | |
| 313 | + | ...defaults, | |
| 314 | + | visible: true | |
| 315 | + | } | |
| 316 | + | ``` | |
| 317 | + | {: data-line="2"} | |
| 318 | + | ||
| 319 | + | #### without Object spread | |
| 320 | + | ||
| 321 | + | ```js | |
| 322 | + | const options = Object.assign( | |
| 323 | + | {}, defaults, | |
| 324 | + | { visible: true }) | |
| 325 | + | ``` | |
| 326 | + | ||
| 327 | + | The Object spread operator lets you build new objects from other objects. | |
| 328 | + | ||
| 329 | + | See: [Object spread](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Spread_operator) | |
| 330 | + | ||
| 331 | + | ### Array spread | |
| 332 | + | ||
| 333 | + | #### with Array spread | |
| 334 | + | ||
| 335 | + | ```js | |
| 336 | + | const users = [ | |
| 337 | + | ...admins, | |
| 338 | + | ...editors, | |
| 339 | + | 'rstacruz' | |
| 340 | + | ] | |
| 341 | + | ``` | |
| 342 | + | {: data-line="2,3"} | |
| 343 | + | ||
| 344 | + | #### without Array spread | |
| 345 | + | ||
| 346 | + | ```js | |
| 347 | + | const users = admins | |
| 348 | + | .concat(editors) | |
| 349 | + | .concat([ 'rstacruz' ]) | |
| 350 | + | ``` | |
| 351 | + | ||
| 352 | + | The spread operator lets you build new arrays in the same way. | |
| 353 | + | ||
| 354 | + | See: [Spread operator](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Spread_operator) | |
| 355 | + | ||
| 356 | + | Functions | |
| 357 | + | --------- | |
| 358 | + | ||
| 359 | + | ### Function arguments | |
| 360 | + | ||
| 361 | + | #### Default arguments | |
| 362 | + | ||
| 363 | + | ```js | |
| 364 | + | function greet (name = 'Jerry') { | |
| 365 | + | return `Hello ${name}` | |
| 366 | + | } | |
| 367 | + | ``` | |
| 368 | + | {: data-line="1"} | |
| 369 | + | ||
| 370 | + | #### Rest arguments | |
| 371 | + | ||
| 372 | + | ```js | |
| 373 | + | function fn(x, ...y) { | |
| 374 | + | // y is an Array | |
| 375 | + | return x * y.length | |
| 376 | + | } | |
| 377 | + | ``` | |
| 378 | + | {: data-line="1"} | |
| 379 | + | ||
| 380 | + | #### Spread | |
| 381 | + | ||
| 382 | + | ```js | |
| 383 | + | fn(...[1, 2, 3]) | |
| 384 | + | // same as fn(1, 2, 3) | |
| 385 | + | ``` | |
| 386 | + | {: data-line="1"} | |
| 387 | + | ||
| 388 | + | Default, rest, spread. | |
| 389 | + | See: [Function arguments](https://babeljs.io/learn-es2015/#default--rest--spread) | |
| 390 | + | ||
| 391 | + | ### Fat arrows | |
| 392 | + | ||
| 393 | + | #### Fat arrows | |
| 394 | + | ||
| 395 | + | ```js | |
| 396 | + | setTimeout(() => { | |
| 397 | + | ··· | |
| 398 | + | }) | |
| 399 | + | ``` | |
| 400 | + | {: data-line="1"} | |
| 401 | + | ||
| 402 | + | #### With arguments | |
| 403 | + | ||
| 404 | + | ```js | |
| 405 | + | readFile('text.txt', (err, data) => { | |
| 406 | + | ... | |
| 407 | + | }) | |
| 408 | + | ``` | |
| 409 | + | {: data-line="1"} | |
| 410 | + | ||
| 411 | + | #### Implicit return | |
| 412 | + | ```js | |
| 413 | + | numbers.map(n => n * 2) | |
| 414 | + | // No curly braces = implicit return | |
| 415 | + | // Same as: numbers.map(function (n) { return n * 2 }) | |
| 416 | + | numbers.map(n => ({ | |
| 417 | + | result: n * 2 | |
| 418 | + | })) | |
| 419 | + | // Implicitly returning objects requires parentheses around the object | |
| 420 | + | ``` | |
| 421 | + | {: data-line="1,4,5,6"} | |
| 422 | + | ||
| 423 | + | Like functions but with `this` preserved. | |
| 424 | + | See: [Fat arrows](https://babeljs.io/learn-es2015/#arrows-and-lexical-this) | |
| 425 | + | ||
| 426 | + | Objects | |
| 427 | + | ------- | |
| 428 | + | ||
| 429 | + | ### Shorthand syntax | |
| 430 | + | ||
| 431 | + | ```js | |
| 432 | + | module.exports = { hello, bye } | |
| 433 | + | // Same as: module.exports = { hello: hello, bye: bye } | |
| 434 | + | ``` | |
| 435 | + | ||
| 436 | + | See: [Object literal enhancements](https://babeljs.io/learn-es2015/#enhanced-object-literals) | |
| 437 | + | ||
| 438 | + | ### Methods | |
| 439 | + | ||
| 440 | + | ```js | |
| 441 | + | const App = { | |
| 442 | + | start () { | |
| 443 | + | console.log('running') | |
| 444 | + | } | |
| 445 | + | } | |
| 446 | + | // Same as: App = { start: function () {···} } | |
| 447 | + | ``` | |
| 448 | + | {: data-line="2"} | |
| 449 | + | ||
| 450 | + | See: [Object literal enhancements](https://babeljs.io/learn-es2015/#enhanced-object-literals) | |
| 451 | + | ||
| 452 | + | ### Getters and setters | |
| 453 | + | ||
| 454 | + | ```js | |
| 455 | + | const App = { | |
| 456 | + | get closed () { | |
| 457 | + | return this.status === 'closed' | |
| 458 | + | }, | |
| 459 | + | set closed (value) { | |
| 460 | + | this.status = value ? 'closed' : 'open' | |
| 461 | + | } | |
| 462 | + | } | |
| 463 | + | ``` | |
| 464 | + | {: data-line="2,5"} | |
| 465 | + | ||
| 466 | + | See: [Object literal enhancements](https://babeljs.io/learn-es2015/#enhanced-object-literals) | |
| 467 | + | ||
| 468 | + | ### Computed property names | |
| 469 | + | ||
| 470 | + | ```js | |
| 471 | + | let event = 'click' | |
| 472 | + | let handlers = { | |
| 473 | + | [`on${event}`]: true | |
| 474 | + | } | |
| 475 | + | // Same as: handlers = { 'onclick': true } | |
| 476 | + | ``` | |
| 477 | + | {: data-line="3"} | |
| 478 | + | ||
| 479 | + | See: [Object literal enhancements](https://babeljs.io/learn-es2015/#enhanced-object-literals) | |
| 480 | + | ||
| 481 | + | ||
| 482 | + | ### Extract values | |
| 483 | + | ||
| 484 | + | ```js | |
| 485 | + | const fatherJS = { age: 57, name: "Brendan Eich" } | |
| 486 | + | ||
| 487 | + | Object.values(fatherJS) | |
| 488 | + | // [57, "Brendan Eich"] | |
| 489 | + | Object.entries(fatherJS) | |
| 490 | + | // [["age", 57], ["name", "Brendan Eich"]] | |
| 491 | + | ``` | |
| 492 | + | {: data-line="3,5"} | |
| 493 | + | ||
| 494 | + | ||
| 495 | + | Modules | |
| 496 | + | ------- | |
| 497 | + | ||
| 498 | + | ### Imports | |
| 499 | + | ||
| 500 | + | ```js | |
| 501 | + | import 'helpers' | |
| 502 | + | // aka: require('···') | |
| 503 | + | ``` | |
| 504 | + | ||
| 505 | + | ```js | |
| 506 | + | import Express from 'express' | |
| 507 | + | // aka: const Express = require('···').default || require('···') | |
| 508 | + | ``` | |
| 509 | + | ||
| 510 | + | ```js | |
| 511 | + | import { indent } from 'helpers' | |
| 512 | + | // aka: const indent = require('···').indent | |
| 513 | + | ``` | |
| 514 | + | ||
| 515 | + | ```js | |
| 516 | + | import * as Helpers from 'helpers' | |
| 517 | + | // aka: const Helpers = require('···') | |
| 518 | + | ``` | |
| 519 | + | ||
| 520 | + | ```js | |
| 521 | + | import { indentSpaces as indent } from 'helpers' | |
| 522 | + | // aka: const indent = require('···').indentSpaces | |
| 523 | + | ``` | |
| 524 | + | ||
| 525 | + | `import` is the new `require()`. | |
| 526 | + | See: [Module imports](https://babeljs.io/learn-es2015/#modules) | |
| 527 | + | ||
| 528 | + | ### Exports | |
| 529 | + | ||
| 530 | + | ```js | |
| 531 | + | export default function () { ··· } | |
| 532 | + | // aka: module.exports.default = ··· | |
| 533 | + | ``` | |
| 534 | + | ||
| 535 | + | ```js | |
| 536 | + | export function mymethod () { ··· } | |
| 537 | + | // aka: module.exports.mymethod = ··· | |
| 538 | + | ``` | |
| 539 | + | ||
| 540 | + | ```js | |
| 541 | + | export const pi = 3.14159 | |
| 542 | + | // aka: module.exports.pi = ··· | |
| 543 | + | ``` | |
| 544 | + | ||
| 545 | + | `export` is the new `module.exports`. | |
| 546 | + | See: [Module exports](https://babeljs.io/learn-es2015/#modules) | |
| 547 | + | ||
| 548 | + | Generators | |
| 549 | + | ---------- | |
| 550 | + | ||
| 551 | + | ### Generators | |
| 552 | + | ||
| 553 | + | ```js | |
| 554 | + | function* idMaker () { | |
| 555 | + | let id = 0 | |
| 556 | + | while (true) { yield id++ } | |
| 557 | + | } | |
| 558 | + | ``` | |
| 559 | + | ||
| 560 | + | ```js | |
| 561 | + | let gen = idMaker() | |
| 562 | + | gen.next().value // → 0 | |
| 563 | + | gen.next().value // → 1 | |
| 564 | + | gen.next().value // → 2 | |
| 565 | + | ``` | |
| 566 | + | ||
| 567 | + | It's complicated. | |
| 568 | + | See: [Generators](https://babeljs.io/learn-es2015/#generators) | |
| 569 | + | ||
| 570 | + | ### For..of iteration | |
| 571 | + | ||
| 572 | + | ```js | |
| 573 | + | for (let i of iterable) { | |
| 574 | + | ··· | |
| 575 | + | } | |
| 576 | + | ``` | |
| 577 | + | ||
| 578 | + | For iterating through generators and arrays. | |
| 579 | + | See: [For..of iteration](https://babeljs.io/learn-es2015/#iterators--forof) | |
| 580 | + | ||
| 581 | + | https://devhints.io/ cheatsheets - Copyright (c) 2021 Rico Sta. Cruz and contributors - MIT license | |
| 582 | + | micro-cheat plugin Copyright 2022 Tero Karvinen https://TeroKarvinen.com/micro - MIT license |
| ... | ... | @@ -0,0 +1,104 @@ | |
| 1 | + | --- | |
| 2 | + | title: Jinja | |
| 3 | + | category: Python | |
| 4 | + | layout: 2017/sheet | |
| 5 | + | --- | |
| 6 | + | ||
| 7 | + | {% raw %} | |
| 8 | + | ### Basic usage | |
| 9 | + | ||
| 10 | + | ``` | |
| 11 | + | - variable x has content: {{ x }} | |
| 12 | + | - expression: {{ x + 1 }} | |
| 13 | + | - escaped for HTML: {{ x | e }} | |
| 14 | + | ``` | |
| 15 | + | ||
| 16 | + | ### Control structures | |
| 17 | + | ||
| 18 | + | ``` | |
| 19 | + | {% for x in range(5) %} | |
| 20 | + | {% if x % 2 == 0 %} | |
| 21 | + | {{ x }} is even! | |
| 22 | + | {% else %} | |
| 23 | + | {{ x }} is odd! | |
| 24 | + | {% endif %} | |
| 25 | + | {% endfor %} | |
| 26 | + | ``` | |
| 27 | + | ||
| 28 | + | ### Whitespace trimming | |
| 29 | + | ||
| 30 | + | ``` | |
| 31 | + | these are | |
| 32 | + | {{ "three" }} | |
| 33 | + | lines. | |
| 34 | + | ||
| 35 | + | this is conc | |
| 36 | + | {{- "at" -}} | |
| 37 | + | enated. | |
| 38 | + | ``` | |
| 39 | + | ||
| 40 | + | ### Special blocks | |
| 41 | + | ||
| 42 | + | ``` | |
| 43 | + | {% filter e %}{% endraw %} | |
| 44 | + | { {%- if 0 -%}{%- endif -%} % raw %} | |
| 45 | + | {%- raw -%} | |
| 46 | + | This is a raw block where {{nothing is evaluated}} | |
| 47 | + | {% not even this %} | |
| 48 | + | and <html is escaped> too with "e" filter | |
| 49 | + | {% endraw %} | |
| 50 | + | { {%- if 0 -%}{%- endif -%} % endraw %}{% raw %} | |
| 51 | + | {% endfilter %} | |
| 52 | + | ||
| 53 | + | {% macro myfunc(x) %} | |
| 54 | + | this is a reusable macro, with arguments: {{x}} | |
| 55 | + | {% endmacro %} | |
| 56 | + | ||
| 57 | + | {{ myfunc(42) }} | |
| 58 | + | ||
| 59 | + | {# | |
| 60 | + | this is a comment | |
| 61 | + | #} | |
| 62 | + | ``` | |
| 63 | + | ||
| 64 | + | ||
| 65 | + | ### Inheritance | |
| 66 | + | ||
| 67 | + | #### shared.html | |
| 68 | + | ||
| 69 | + | ``` | |
| 70 | + | <html> | |
| 71 | + | <head> | |
| 72 | + | <title>{%block title %}{% endblock %}</title> | |
| 73 | + | </head> | |
| 74 | + | <body> | |
| 75 | + | <header><h1>{% block title %}{% endblock %}</h1></header> | |
| 76 | + | <main>{% block content %}{% endblock %}</main> | |
| 77 | + | </body> | |
| 78 | + | </html> | |
| 79 | + | ``` | |
| 80 | + | ||
| 81 | + | #### home.html | |
| 82 | + | ||
| 83 | + | ``` | |
| 84 | + | {% extends "shared.html" %} | |
| 85 | + | {% block title %}Welcome to my site{% endblock %} | |
| 86 | + | {% block content %} | |
| 87 | + | This is the body | |
| 88 | + | {% endblock %} | |
| 89 | + | ``` | |
| 90 | + | ||
| 91 | + | ## Library | |
| 92 | + | ||
| 93 | + | ### Basic usage | |
| 94 | + | ||
| 95 | + | ```python | |
| 96 | + | from jinja2 import Template | |
| 97 | + | template = Template('Hello {{ name }}!') | |
| 98 | + | template.render(name='John Doe') == u'Hello John Doe!' | |
| 99 | + | ``` | |
| 100 | + | ||
| 101 | + | {% endraw %} | |
| 102 | + | ||
| 103 | + | https://devhints.io/ cheatsheets - Copyright (c) 2021 Rico Sta. Cruz and contributors - MIT license | |
| 104 | + | micro-cheat plugin Copyright 2022 Tero Karvinen https://TeroKarvinen.com/micro - MIT license |
| ... | ... | @@ -0,0 +1,8 @@ | |
| 1 | + | --- | |
| 2 | + | title: jinja | |
| 3 | + | category: python | |
| 4 | + | redirect_to: /jinja | |
| 5 | + | --- | |
| 6 | + | ||
| 7 | + | https://devhints.io/ cheatsheets - Copyright (c) 2021 Rico Sta. Cruz and contributors - MIT license | |
| 8 | + | micro-cheat plugin Copyright 2022 Tero Karvinen https://TeroKarvinen.com/micro - MIT license |
| ... | ... | @@ -0,0 +1,407 @@ | |
| 1 | + | --- | |
| 2 | + | title: Kotlin | |
| 3 | + | layout: 2017/sheet | |
| 4 | + | updated: 2018-12-06 | |
| 5 | + | category: Java & JVM | |
| 6 | + | prism_languages: [kotlin] | |
| 7 | + | intro: | | |
| 8 | + | [Kotlin](http://kotlinlang.org/) is a statically typed programming language for modern multiplatform applications. | |
| 9 | + | --- | |
| 10 | + | ||
| 11 | + | Variables | |
| 12 | + | --------- | |
| 13 | + | {: .-three-column} | |
| 14 | + | ||
| 15 | + | ### Mutability | |
| 16 | + | ||
| 17 | + | ```kotlin | |
| 18 | + | var mutableString: String = "Adam" | |
| 19 | + | val immutableString: String = "Adam" | |
| 20 | + | val inferredString = "Adam" | |
| 21 | + | ``` | |
| 22 | + | ||
| 23 | + | ### Strings | |
| 24 | + | ||
| 25 | + | ```kotlin | |
| 26 | + | val name = "Adam" | |
| 27 | + | val greeting = "Hello, " + name | |
| 28 | + | val greetingTemplate = "Hello, $name" | |
| 29 | + | val interpolated = "Hello, ${name.toUpperCase()}" | |
| 30 | + | ``` | |
| 31 | + | ||
| 32 | + | ### Numbers | |
| 33 | + | ||
| 34 | + | ```kotlin | |
| 35 | + | val intNum = 10 | |
| 36 | + | val doubleNum = 10.0 | |
| 37 | + | val longNum = 10L | |
| 38 | + | val floatNum = 10.0F | |
| 39 | + | ``` | |
| 40 | + | ||
| 41 | + | ### Booleans | |
| 42 | + | ||
| 43 | + | ```kotlin | |
| 44 | + | val trueBoolean = true | |
| 45 | + | val falseBoolean = false | |
| 46 | + | val andCondition = trueBoolean && falseBoolean | |
| 47 | + | val orCondition = trueBoolean || falseBoolean | |
| 48 | + | ``` | |
| 49 | + | ||
| 50 | + | ### Static Fields | |
| 51 | + | ||
| 52 | + | ```kotlin | |
| 53 | + | class Person { | |
| 54 | + | companion object { | |
| 55 | + | val NAME_KEY = "name_key" | |
| 56 | + | } | |
| 57 | + | } | |
| 58 | + | ||
| 59 | + | val key = Person.NAME_KEY | |
| 60 | + | ``` | |
| 61 | + | ||
| 62 | + | Null Safety | |
| 63 | + | ----------- | |
| 64 | + | {: .-two-column} | |
| 65 | + | ||
| 66 | + | ### Nullable properties | |
| 67 | + | ||
| 68 | + | ```kotlin | |
| 69 | + | val cannotBeNull: String = null // Invalid | |
| 70 | + | val canBeNull: String? = null // Valid | |
| 71 | + | ||
| 72 | + | val cannotBeNull: Int = null // Invalid | |
| 73 | + | val canBeNull: Int? = null // Valid | |
| 74 | + | ``` | |
| 75 | + | ||
| 76 | + | ### Checking for null | |
| 77 | + | ||
| 78 | + | ```kotlin | |
| 79 | + | val name: String? = "Adam" | |
| 80 | + | ||
| 81 | + | if (name != null && name.length > 0) { | |
| 82 | + | print("String length is ${name.length}") | |
| 83 | + | } else { | |
| 84 | + | print("String is empty.") | |
| 85 | + | } | |
| 86 | + | ``` | |
| 87 | + | ||
| 88 | + | ### Safe Operator | |
| 89 | + | ||
| 90 | + | ```kotlin | |
| 91 | + | val nullableStringLength: Int? = nullableString?.length | |
| 92 | + | val nullableDepartmentHead: String? = person?.department?.head?.name | |
| 93 | + | ``` | |
| 94 | + | ||
| 95 | + | ### Elvis Operator | |
| 96 | + | ||
| 97 | + | ```kotlin | |
| 98 | + | val nonNullStringLength: Int = nullableString?.length ?: 0 | |
| 99 | + | val nonNullDepartmentHead: String = person?.department?.head?.name ?: "" | |
| 100 | + | val nonNullDepartmentHead: String = person?.department?.head?.name.orEmpty() | |
| 101 | + | ``` | |
| 102 | + | ||
| 103 | + | ### Safe Casts | |
| 104 | + | ```kotlin | |
| 105 | + | // Will not throw ClassCastException | |
| 106 | + | val nullableCar: Car? = (input as? Car) | |
| 107 | + | ``` | |
| 108 | + | ||
| 109 | + | Collections | |
| 110 | + | ----------- | |
| 111 | + | {: .-two-column} | |
| 112 | + | ||
| 113 | + | ### Creation | |
| 114 | + | ||
| 115 | + | ```kotlin | |
| 116 | + | val numArray = arrayOf(1, 2, 3) | |
| 117 | + | val numList = listOf(1, 2, 3) | |
| 118 | + | val mutableNumList = mutableListOf(1, 2, 3) | |
| 119 | + | ``` | |
| 120 | + | ||
| 121 | + | ### Accessing | |
| 122 | + | ||
| 123 | + | ```kotlin | |
| 124 | + | val firstItem = numList[0] | |
| 125 | + | val firstItem = numList.first() | |
| 126 | + | val firstItem = numList.firstOrNull() | |
| 127 | + | ``` | |
| 128 | + | ||
| 129 | + | ### Maps | |
| 130 | + | ||
| 131 | + | ```kotlin | |
| 132 | + | val faceCards = mutableMapOf("Jack" to 11, "Queen" to 12, "King" to 13) | |
| 133 | + | val jackValue = faceCards["Jack"] // 11 | |
| 134 | + | faceCards["Ace"] = 1 | |
| 135 | + | ``` | |
| 136 | + | ||
| 137 | + | ### Mutability | |
| 138 | + | ||
| 139 | + | ```kotlin | |
| 140 | + | val immutableList = listOf(1, 2, 3) | |
| 141 | + | val mutableList = immutableList.toMutableList() | |
| 142 | + | ||
| 143 | + | val immutableMap = mapOf("Jack" to 11, "Queen" to 12, "King" to 13) | |
| 144 | + | val mutableMap = immutableMap.toMutableMap() | |
| 145 | + | ``` | |
| 146 | + | ||
| 147 | + | ### Iterating | |
| 148 | + | ||
| 149 | + | ```kotlin | |
| 150 | + | for (item in myList) { | |
| 151 | + | print(item) | |
| 152 | + | } | |
| 153 | + | ||
| 154 | + | myList.forEach { | |
| 155 | + | print(it) | |
| 156 | + | } | |
| 157 | + | ||
| 158 | + | myList.forEachIndexed { index, item -> | |
| 159 | + | print("Item at $index is: $item") | |
| 160 | + | } | |
| 161 | + | ``` | |
| 162 | + | ||
| 163 | + | ### Filtering & Searching | |
| 164 | + | ||
| 165 | + | ```kotlin | |
| 166 | + | val evenNumbers = numList.filter { it % 2 == 0 } | |
| 167 | + | val containsEven = numList.any { it % 2 == 0 } | |
| 168 | + | val containsNoEvens = numList.none { it % 2 == 0 } | |
| 169 | + | val containsNoEvens = numList.all { it % 2 == 1 } | |
| 170 | + | val firstEvenNumber: Int = numList.first { it % 2 == 0 } | |
| 171 | + | val firstEvenOrNull: Int? = numList.firstOrNull { it % 2 == 0 } | |
| 172 | + | val fullMenu = objList.map { "${it.name} - $${it.detail}" } | |
| 173 | + | ``` | |
| 174 | + | ||
| 175 | + | Note: `it` is the [implicit name for a single parameter](https://kotlinlang.org/docs/reference/lambdas.html#it-implicit-name-of-a-single-parameter). | |
| 176 | + | ||
| 177 | + | Functions | |
| 178 | + | --------- | |
| 179 | + | {: .-two-column} | |
| 180 | + | ||
| 181 | + | ### Parameters & Return Types | |
| 182 | + | ||
| 183 | + | ```kotlin | |
| 184 | + | fun printName() { | |
| 185 | + | print("Adam") | |
| 186 | + | } | |
| 187 | + | ||
| 188 | + | fun printName(person: Person) { | |
| 189 | + | print(person.name) | |
| 190 | + | } | |
| 191 | + | ||
| 192 | + | fun getGreeting(person: Person): String { | |
| 193 | + | return "Hello, ${person.name}" | |
| 194 | + | } | |
| 195 | + | ||
| 196 | + | fun getGreeting(person: Person): String = "Hello, ${person.name}" | |
| 197 | + | fun getGreeting(person: Person) = "Hello, ${person.name}" | |
| 198 | + | ``` | |
| 199 | + | ||
| 200 | + | ### Higher Order Functions | |
| 201 | + | ||
| 202 | + | ```kotlin | |
| 203 | + | fun callbackIfTrue(condition: Boolean, callback: () -> Unit) { | |
| 204 | + | if (condition) { | |
| 205 | + | callback() | |
| 206 | + | } | |
| 207 | + | } | |
| 208 | + | ||
| 209 | + | callbackIfTrue(someBoolean) { | |
| 210 | + | print("Condition was true") | |
| 211 | + | } | |
| 212 | + | ``` | |
| 213 | + | ||
| 214 | + | ### Extension Functions | |
| 215 | + | ||
| 216 | + | ```kotlin | |
| 217 | + | fun Int.timesTwo(): Int { | |
| 218 | + | return this * 2 | |
| 219 | + | } | |
| 220 | + | ||
| 221 | + | val four = 2.timesTwo() | |
| 222 | + | ``` | |
| 223 | + | ||
| 224 | + | ### Default Parameters | |
| 225 | + | ||
| 226 | + | ```kotlin | |
| 227 | + | fun getGreeting(person: Person, intro: String = "Hello,") { | |
| 228 | + | return "$intro ${person.name}" | |
| 229 | + | } | |
| 230 | + | ||
| 231 | + | // Returns "Hello, Adam" | |
| 232 | + | val hello = getGreeting(Person("Adam")) | |
| 233 | + | ||
| 234 | + | // Returns "Welcome, Adam" | |
| 235 | + | val welcome = getGreeting(Person("Adam"), "Welcome,") | |
| 236 | + | ``` | |
| 237 | + | ||
| 238 | + | ### Named Parameters | |
| 239 | + | ||
| 240 | + | ```kotlin | |
| 241 | + | class Person(val name: String = "", age: Int = 0) | |
| 242 | + | ||
| 243 | + | // All valid | |
| 244 | + | val person = Person() | |
| 245 | + | val person = Person("Adam", 100) | |
| 246 | + | val person = Person(name = "Adam", age = 100) | |
| 247 | + | val person = Person(age = 100) | |
| 248 | + | val person = Person(age = 100, name = "Adam") | |
| 249 | + | ``` | |
| 250 | + | ||
| 251 | + | ### Static Functions | |
| 252 | + | ||
| 253 | + | ```kotlin | |
| 254 | + | class Fragment(val args: Bundle) { | |
| 255 | + | companion object { | |
| 256 | + | fun newInstance(args: Bundle): Fragment { | |
| 257 | + | return Fragment(args) | |
| 258 | + | } | |
| 259 | + | } | |
| 260 | + | } | |
| 261 | + | ||
| 262 | + | val fragment = Fragment.newInstance(args) | |
| 263 | + | ``` | |
| 264 | + | ||
| 265 | + | * [Companion Objects](https://kotlinlang.org/docs/reference/object-declarations.html#companion-objects) | |
| 266 | + | ||
| 267 | + | Classes | |
| 268 | + | ------- | |
| 269 | + | {: .-two-column} | |
| 270 | + | ||
| 271 | + | ### Primary Constructor | |
| 272 | + | ||
| 273 | + | ```kotlin | |
| 274 | + | class Person(val name: String, val age: Int) | |
| 275 | + | val adam = Person("Adam", 100) | |
| 276 | + | ``` | |
| 277 | + | ||
| 278 | + | ### Secondary Constructors | |
| 279 | + | ||
| 280 | + | ```kotlin | |
| 281 | + | class Person(val name: String) { | |
| 282 | + | private var age: Int? = null | |
| 283 | + | ||
| 284 | + | constructor(name: String, age: Int) : this(name) { | |
| 285 | + | this.age = age | |
| 286 | + | } | |
| 287 | + | } | |
| 288 | + | ||
| 289 | + | // Above can be replaced with default params | |
| 290 | + | class Person(val name: String, val age: Int? = null) | |
| 291 | + | ``` | |
| 292 | + | ||
| 293 | + | ### Inheritance & Implementation | |
| 294 | + | ||
| 295 | + | ```kotlin | |
| 296 | + | open class Vehicle | |
| 297 | + | class Car : Vehicle() | |
| 298 | + | ||
| 299 | + | interface Runner { | |
| 300 | + | fun run() | |
| 301 | + | } | |
| 302 | + | ||
| 303 | + | class Machine : Runner { | |
| 304 | + | override fun run() { | |
| 305 | + | // ... | |
| 306 | + | } | |
| 307 | + | } | |
| 308 | + | ``` | |
| 309 | + | ||
| 310 | + | Control Flow | |
| 311 | + | ------------ | |
| 312 | + | {: .-two-column} | |
| 313 | + | ||
| 314 | + | ### If Statements | |
| 315 | + | ||
| 316 | + | ```kotlin | |
| 317 | + | if (someBoolean) { | |
| 318 | + | doThing() | |
| 319 | + | } else { | |
| 320 | + | doOtherThing() | |
| 321 | + | } | |
| 322 | + | ``` | |
| 323 | + | ||
| 324 | + | ### For Loops | |
| 325 | + | ||
| 326 | + | ```kotlin | |
| 327 | + | for (i in 0..10) { } // 1 - 10 | |
| 328 | + | for (i in 0 until 10) // 1 - 9 | |
| 329 | + | (0..10).forEach { } | |
| 330 | + | for (i in 0 until 10 step 2) // 0, 2, 4, 6, 8 | |
| 331 | + | ``` | |
| 332 | + | ||
| 333 | + | ### When Statements | |
| 334 | + | ||
| 335 | + | ```kotlin | |
| 336 | + | when (direction) { | |
| 337 | + | NORTH -> { | |
| 338 | + | print("North") | |
| 339 | + | } | |
| 340 | + | SOUTH -> print("South") | |
| 341 | + | EAST, WEST -> print("East or West") | |
| 342 | + | "N/A" -> print("Unavailable") | |
| 343 | + | else -> print("Invalid Direction") | |
| 344 | + | } | |
| 345 | + | ``` | |
| 346 | + | ||
| 347 | + | ### While Loops | |
| 348 | + | ||
| 349 | + | ```kotlin | |
| 350 | + | while (x > 0) { | |
| 351 | + | x-- | |
| 352 | + | } | |
| 353 | + | ||
| 354 | + | do { | |
| 355 | + | x-- | |
| 356 | + | } while (x > 0) | |
| 357 | + | ``` | |
| 358 | + | ||
| 359 | + | Destructuring Declarations | |
| 360 | + | -------------------------- | |
| 361 | + | {: .-two-column} | |
| 362 | + | ||
| 363 | + | ### Objects & Lists | |
| 364 | + | ||
| 365 | + | ```kotlin | |
| 366 | + | val person = Person("Adam", 100) | |
| 367 | + | val (name, age) = person | |
| 368 | + | ||
| 369 | + | val pair = Pair(1, 2) | |
| 370 | + | val (first, second) = pair | |
| 371 | + | ||
| 372 | + | val coordinates = arrayOf(1, 2, 3) | |
| 373 | + | val (x, y, z) = coordinates | |
| 374 | + | ``` | |
| 375 | + | ||
| 376 | + | ### ComponentN Functions | |
| 377 | + | ||
| 378 | + | ```kotlin | |
| 379 | + | class Person(val name: String, val age: Int) { | |
| 380 | + | operator fun component1(): String { | |
| 381 | + | return name | |
| 382 | + | } | |
| 383 | + | ||
| 384 | + | operator fun component2(): Int { | |
| 385 | + | return age | |
| 386 | + | } | |
| 387 | + | } | |
| 388 | + | ``` | |
| 389 | + | ||
| 390 | + | References | |
| 391 | + | ---------- | |
| 392 | + | {: .-one-column} | |
| 393 | + | ||
| 394 | + | * [Defining Variables](https://kotlinlang.org/docs/reference/basic-syntax.html#defining-variables) _(kotlinlang.org)_ | |
| 395 | + | * [Strings Documentation](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/-string/index.html) _(kotlinlang.org)_ | |
| 396 | + | * [String Templates](https://kotlinlang.org/docs/reference/basic-types.html#string-templates) _(kotlinlang.org)_ | |
| 397 | + | * [Basic Types](https://kotlinlang.org/docs/reference/basic-types.html) _(kotlinlang.org)_ | |
| 398 | + | * [Companion Objects](https://kotlinlang.org/docs/reference/object-declarations.html#companion-objects) _(kotlinlang.org)_ | |
| 399 | + | * [Null Safety](https://kotlinlang.org/docs/reference/null-safety.html) _(kotlinlang.org)_ | |
| 400 | + | * [Collections Overview](https://kotlinlang.org/docs/reference/collections.html) _(kotlinlang.org)_ | |
| 401 | + | * [Collections Documentation](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/index.html) _(kotlinlang.org)_ | |
| 402 | + | * [Functions Documentation](https://kotlinlang.org/docs/reference/functions.html) _(kotlinlang.org)_ | |
| 403 | + | * [Classes Documentation](https://kotlinlang.org/docs/reference/classes.html) _(kotlinlang.org)_ | |
| 404 | + | * [Destructuring Declarations](https://kotlinlang.org/docs/reference/multi-declarations.html) _(kotlinlang.org)_ | |
| 405 | + | ||
| 406 | + | https://devhints.io/ cheatsheets - Copyright (c) 2021 Rico Sta. Cruz and contributors - MIT license | |
| 407 | + | micro-cheat plugin Copyright 2022 Tero Karvinen https://TeroKarvinen.com/micro - MIT license |
| ... | ... | @@ -0,0 +1,308 @@ | |
| 1 | + | --- | |
| 2 | + | title: Ledger CLI | |
| 3 | + | category: Ledger | |
| 4 | + | layout: 2017/sheet | |
| 5 | + | updated: 2020-05-23 | |
| 6 | + | weight: -5 | |
| 7 | + | --- | |
| 8 | + | ||
| 9 | + | ### Basic usage | |
| 10 | + | ||
| 11 | + | ```bash | |
| 12 | + | $ ledger bal | |
| 13 | + | $ ledger reg | |
| 14 | + | ``` | |
| 15 | + | ||
| 16 | + | ```bash | |
| 17 | + | $ ledger reg grocery # show entries for 'grocery' | |
| 18 | + | $ ledger bal assets # check if i'm broke | |
| 19 | + | ``` | |
| 20 | + | ||
| 21 | + | ```bash | |
| 22 | + | -b 01/01 # --begin | |
| 23 | + | -e 01/31 # --end | |
| 24 | + | -S date # --sort | |
| 25 | + | -S amount | |
| 26 | + | ``` | |
| 27 | + | ||
| 28 | + | ### Examples | |
| 29 | + | ||
| 30 | + | ```bash | |
| 31 | + | # any/all matches | |
| 32 | + | ledger bal Rent Transportation # any | |
| 33 | + | ledger bal Income and Job # all | |
| 34 | + | ledger bal Expenses and not (Drinks or Food) | |
| 35 | + | ``` | |
| 36 | + | ||
| 37 | + | ```bash | |
| 38 | + | # what did I spend on most? (--sorted) | |
| 39 | + | ledger reg Expenses -S amount | |
| 40 | + | ``` | |
| 41 | + | ||
| 42 | + | ```bash | |
| 43 | + | # how much did I have at this date? (--end) | |
| 44 | + | ledger bal -e 01/15 ^Assets ^Liabilities | |
| 45 | + | ``` | |
| 46 | + | ||
| 47 | + | ```bash | |
| 48 | + | # how much did I spend and earn this month? | |
| 49 | + | ledger bal ^Expenses ^Income --invert | |
| 50 | + | ``` | |
| 51 | + | ||
| 52 | + | ```bash | |
| 53 | + | # how much was spent over the course of 3 days? (totalled) | |
| 54 | + | ledger reg -b 01/25 -e 01/27 --subtotal | |
| 55 | + | ledger reg -b 01/25 -e 01/27 --subtotal grocery | |
| 56 | + | ``` | |
| 57 | + | ||
| 58 | + | Format | |
| 59 | + | ------ | |
| 60 | + | ||
| 61 | + | ### Basic format | |
| 62 | + | ||
| 63 | + | ``` | |
| 64 | + | 2013/01/03 * Rent for January | |
| 65 | + | Expenses:Rent $600.00 | |
| 66 | + | Assets:Savings | |
| 67 | + | ``` | |
| 68 | + | ||
| 69 | + | `*` = cleared, `!` = pending | |
| 70 | + | ||
| 71 | + | ### Secondary dates | |
| 72 | + | ||
| 73 | + | ``` | |
| 74 | + | 2008/01/01=2008/01/14 Client invoice | |
| 75 | + | ``` | |
| 76 | + | ||
| 77 | + | It can mean anything you want, eg, for the estimated date you'll be paid. | |
| 78 | + | ||
| 79 | + | ### Balance assertions | |
| 80 | + | ||
| 81 | + | ``` | |
| 82 | + | 2008/01/01 * KFC | |
| 83 | + | Expenses:Food $20 | |
| 84 | + | Assets:Cash $-20 = $500 | |
| 85 | + | ``` | |
| 86 | + | {: data-line="3"} | |
| 87 | + | ||
| 88 | + | `Cash $X = $500` ensures Cash is at $500 after the transaction. | |
| 89 | + | ||
| 90 | + | ### Balance assignment | |
| 91 | + | ||
| 92 | + | ```bash | |
| 93 | + | 2008/01/01 * Cash balance | |
| 94 | + | Assets:Cash = $500 | |
| 95 | + | Equity:Adjustments | |
| 96 | + | ||
| 97 | + | 2008/01/01 * KFC | |
| 98 | + | Expenses:Food $20 | |
| 99 | + | Assets:Cash = $500 | |
| 100 | + | ``` | |
| 101 | + | {: data-line="2,7"} | |
| 102 | + | ||
| 103 | + | `ACCOUNT = $500` figures out what's needed to make it $500. | |
| 104 | + | ||
| 105 | + | ### Payables | |
| 106 | + | ||
| 107 | + | ```bash | |
| 108 | + | 2008/04/25 * Rent | |
| 109 | + | (Assets:Checking) -$200 | |
| 110 | + | Expenses:Rent | |
| 111 | + | ``` | |
| 112 | + | {: data-line="2"} | |
| 113 | + | ||
| 114 | + | ### Commodities | |
| 115 | + | ||
| 116 | + | ```bash | |
| 117 | + | ; cost per item | |
| 118 | + | 2010/05/31 * Market | |
| 119 | + | Assets:Fridge 35 apples @ $0.42 | |
| 120 | + | Assets:Cash | |
| 121 | + | ``` | |
| 122 | + | {: data-line="3"} | |
| 123 | + | ||
| 124 | + | ```bash | |
| 125 | + | ; total cost | |
| 126 | + | 2010/05/31 * Market | |
| 127 | + | Assets:Fridge 35 apples @@ $14.70 | |
| 128 | + | Assets:Cash | |
| 129 | + | ``` | |
| 130 | + | {: data-line="3"} | |
| 131 | + | ||
| 132 | + | ```bash | |
| 133 | + | ; fixed lot prices | |
| 134 | + | 2010/05/31 * Gas | |
| 135 | + | Expenses:Gasoline 11 GAL {=$2.299} | |
| 136 | + | Assets:Cash | |
| 137 | + | ``` | |
| 138 | + | {: data-line="3"} | |
| 139 | + | ||
| 140 | + | ### Commodity definitions | |
| 141 | + | ||
| 142 | + | ``` | |
| 143 | + | commodity $ | |
| 144 | + | note American Dollars | |
| 145 | + | format $1,000.00 | |
| 146 | + | nomarket | |
| 147 | + | default | |
| 148 | + | ``` | |
| 149 | + | ||
| 150 | + | ### Budgeting | |
| 151 | + | ||
| 152 | + | ``` | |
| 153 | + | ~ Monthly | |
| 154 | + | Expenses:Rent $500 | |
| 155 | + | Expenses:Food $100 | |
| 156 | + | Expenses $40 ; everything else | |
| 157 | + | Assets | |
| 158 | + | ||
| 159 | + | ~ Yearly | |
| 160 | + | ``` | |
| 161 | + | ||
| 162 | + | ```bash | |
| 163 | + | ledger bal --budget Expenses | |
| 164 | + | ledger bal --unbudgeted Expenses | |
| 165 | + | ``` | |
| 166 | + | {: .-setup} | |
| 167 | + | ||
| 168 | + | ### Comments | |
| 169 | + | ||
| 170 | + | ; line comment | |
| 171 | + | # also line comment | |
| 172 | + | % also line comment | |
| 173 | + | | also line comment | |
| 174 | + | * also line comment | |
| 175 | + | ||
| 176 | + | Querying | |
| 177 | + | -------- | |
| 178 | + | ||
| 179 | + | ### Periods | |
| 180 | + | ||
| 181 | + | ``` | |
| 182 | + | [interval] [begin] [end] | |
| 183 | + | ``` | |
| 184 | + | ||
| 185 | + | ``` | |
| 186 | + | interval: | |
| 187 | + | every day|week|month|quarter|year | |
| 188 | + | every N days|weeks|... | |
| 189 | + | daily|weekly|... | |
| 190 | + | ``` | |
| 191 | + | ||
| 192 | + | ``` | |
| 193 | + | begin: | |
| 194 | + | from <spec> | |
| 195 | + | end: | |
| 196 | + | to <spec> | |
| 197 | + | ``` | |
| 198 | + | ||
| 199 | + | ``` | |
| 200 | + | spec: | |
| 201 | + | 2004 | |
| 202 | + | 2004/10/1 | |
| 203 | + | ``` | |
| 204 | + | ||
| 205 | + | ```bash | |
| 206 | + | $ ledger bal|reg --period "until aug" | |
| 207 | + | $ ledger bal|reg --period "last oct" | |
| 208 | + | $ ledger bal|reg --period "every week" | |
| 209 | + | ``` | |
| 210 | + | {: .-setup} | |
| 211 | + | ||
| 212 | + | ### Register | |
| 213 | + | ||
| 214 | + | ```bash | |
| 215 | + | $ ledger reg | |
| 216 | + | ``` | |
| 217 | + | {: .-setup} | |
| 218 | + | ||
| 219 | + | ```bash | |
| 220 | + | -D, --daily | |
| 221 | + | -W, --weekly | |
| 222 | + | -M, --monthly | |
| 223 | + | --quarterly | |
| 224 | + | -Y, --yearly | |
| 225 | + | -s, --subtotal | |
| 226 | + | --start-of-week monday | |
| 227 | + | ``` | |
| 228 | + | ||
| 229 | + | ```bash | |
| 230 | + | -S, --sort date | |
| 231 | + | -S, --sort amount | |
| 232 | + | ``` | |
| 233 | + | ||
| 234 | + | ### Filters | |
| 235 | + | ||
| 236 | + | ```bash | |
| 237 | + | -b, --begin DATE | |
| 238 | + | -e, --end DATE | |
| 239 | + | ||
| 240 | + | -d payee =~ /pioneer/ | |
| 241 | + | ||
| 242 | + | -C, --cleared # (with *) | |
| 243 | + | -U, --uncleared # (no *) | |
| 244 | + | --pending # (with !) | |
| 245 | + | ||
| 246 | + | -R, --real # ignore virtual postings (eg: "(Cash) $-400") | |
| 247 | + | -L, --actual # no automated postings (eg: "= /^Income/") | |
| 248 | + | ||
| 249 | + | -r, --related # show the other side | |
| 250 | + | # "reg -r savings" shows where it comes from) | |
| 251 | + | ``` | |
| 252 | + | ||
| 253 | + | ### Queries | |
| 254 | + | ||
| 255 | + | ^regex$ | |
| 256 | + | @payee | |
| 257 | + | %tag | |
| 258 | + | %tag=value | |
| 259 | + | =note | |
| 260 | + | #code | |
| 261 | + | term and term | |
| 262 | + | term or term | |
| 263 | + | not term | |
| 264 | + | \( term \) | |
| 265 | + | ||
| 266 | + | Example: | |
| 267 | + | ||
| 268 | + | ledger r ^expenses and @Denny's | |
| 269 | + | ledger r food and @Starbucks and not dining | |
| 270 | + | ||
| 271 | + | ### Display | |
| 272 | + | ||
| 273 | + | ```bash | |
| 274 | + | -n, --collapse # [register] collapse entries | |
| 275 | + | # [balance] no grand total | |
| 276 | + | -s, --subtotal # [balance] show sub-accounts | |
| 277 | + | # [other] show subtotals | |
| 278 | + | --flat | |
| 279 | + | ``` | |
| 280 | + | ||
| 281 | + | ### Effective dates | |
| 282 | + | ||
| 283 | + | ```bash | |
| 284 | + | 2008/01/01=2008/01/14 Client invoice ; estimated date you'll be paid | |
| 285 | + | Assets:Accounts Receivable $100.00 | |
| 286 | + | Income: Client name | |
| 287 | + | ``` | |
| 288 | + | {: data-line="1"} | |
| 289 | + | ||
| 290 | + | Say you're in business. If you bill a customer, you can enter something like above. | |
| 291 | + | Then, when you receive the payment, you change it to: | |
| 292 | + | ||
| 293 | + | ```bash | |
| 294 | + | 2008/01/01=2008/01/15 Client invoice ; actual date money received | |
| 295 | + | Assets:Accounts Receivable $100.00 | |
| 296 | + | Income: Client name | |
| 297 | + | ``` | |
| 298 | + | {: data-line="1"} | |
| 299 | + | ||
| 300 | + | ## References | |
| 301 | + | {: .-one-column} | |
| 302 | + | ||
| 303 | + | * <http://ledger-cli.org/3.0/doc/ledger3.html> | |
| 304 | + | * <https://gist.github.com/agaviria/3317397> | |
| 305 | + | {: .-also-see} | |
| 306 | + | ||
| 307 | + | https://devhints.io/ cheatsheets - Copyright (c) 2021 Rico Sta. Cruz and contributors - MIT license | |
| 308 | + | micro-cheat plugin Copyright 2022 Tero Karvinen https://TeroKarvinen.com/micro - MIT license |
| ... | ... | @@ -0,0 +1,45 @@ | |
| 1 | + | --- | |
| 2 | + | title: Less.js | |
| 3 | + | --- | |
| 4 | + | ||
| 5 | + | ### Functions | |
| 6 | + | ||
| 7 | + | unit(30px / 5px) #=> 6 | |
| 8 | + | unit(5, px) #=> 5px | |
| 9 | + | ||
| 10 | + | e("ms:stuff()") #=> ms:stuff() (unquote) | |
| 11 | + | ||
| 12 | + | %("count: %d", 1+2) #=> "count: 3" | |
| 13 | + | ||
| 14 | + | iscolor(@x) | |
| 15 | + | isstring(@x) | |
| 16 | + | isnumber(@x) | |
| 17 | + | iskeyword(@x) | |
| 18 | + | isurl(url(...)) | |
| 19 | + | ispixel() | |
| 20 | + | isem() | |
| 21 | + | ispercentage() | |
| 22 | + | isunit() | |
| 23 | + | ||
| 24 | + | hue(@color) | |
| 25 | + | saturation(@color) | |
| 26 | + | lightness(@color) | |
| 27 | + | luma(@color) | |
| 28 | + | luminance(@color) | |
| 29 | + | ||
| 30 | + | fade(@color, amount) | |
| 31 | + | fadein(@color, amount) | |
| 32 | + | fadeout(@color, amount) | |
| 33 | + | spin(@color, degrees) | |
| 34 | + | mix(@a, @b, amount) | |
| 35 | + | ||
| 36 | + | ### Conditionals | |
| 37 | + | ||
| 38 | + | .image when (luma(@color) > 50%) { } | |
| 39 | + | .image when (not(...)) { } | |
| 40 | + | .image when (default()) {} | |
| 41 | + | .image when (e(@shape) = 'circle') { } | |
| 42 | + | ||
| 43 | + | ||
| 44 | + | https://devhints.io/ cheatsheets - Copyright (c) 2021 Rico Sta. Cruz and contributors - MIT license | |
| 45 | + | micro-cheat plugin Copyright 2022 Tero Karvinen https://TeroKarvinen.com/micro - MIT license |
| ... | ... | @@ -0,0 +1,303 @@ | |
| 1 | + | --- | |
| 2 | + | title: Lua | |
| 3 | + | --- | |
| 4 | + | ||
| 5 | + | ## Comments | |
| 6 | + | ||
| 7 | + | -- comment | |
| 8 | + | --[[ Multiline | |
| 9 | + | comment ]] | |
| 10 | + | ||
| 11 | + | ## Invoking functions | |
| 12 | + | ||
| 13 | + | print() | |
| 14 | + | print("Hi") | |
| 15 | + | ||
| 16 | + | -- You can omit parentheses if the argument is one string or table literal | |
| 17 | + | print "Hello World" <--> print("Hello World") | |
| 18 | + | dofile 'a.lua' <--> dofile ('a.lua') | |
| 19 | + | print [[a multi-line <--> print([[a multi-line | |
| 20 | + | message]] message]]) | |
| 21 | + | f{x=10, y=20} <--> f({x=10, y=20}) | |
| 22 | + | type{} <--> type({}) | |
| 23 | + | ||
| 24 | + | ## Tables / arrays | |
| 25 | + | ||
| 26 | + | t = {} | |
| 27 | + | t = { a = 1, b = 2 } | |
| 28 | + | t.a = function() ... end | |
| 29 | + | ||
| 30 | + | t = { ["hello"] = 200 } | |
| 31 | + | t.hello | |
| 32 | + | ||
| 33 | + | -- Remember, arrays are also tables | |
| 34 | + | array = { "a", "b", "c", "d" } | |
| 35 | + | print(array[2]) -- "b" (one-indexed) | |
| 36 | + | print(#array) -- 4 (length) | |
| 37 | + | ||
| 38 | + | ## Loops | |
| 39 | + | ||
| 40 | + | while condition do | |
| 41 | + | end | |
| 42 | + | ||
| 43 | + | for i = 1,5 do | |
| 44 | + | end | |
| 45 | + | ||
| 46 | + | for i = start,finish,delta do | |
| 47 | + | end | |
| 48 | + | ||
| 49 | + | for k,v in pairs(tab) do | |
| 50 | + | end | |
| 51 | + | ||
| 52 | + | repeat | |
| 53 | + | until condition | |
| 54 | + | ||
| 55 | + | -- Breaking out: | |
| 56 | + | while x do | |
| 57 | + | if condition then break end | |
| 58 | + | end | |
| 59 | + | ||
| 60 | + | ## Conditionals | |
| 61 | + | ||
| 62 | + | if condition then | |
| 63 | + | print("yes") | |
| 64 | + | elseif condition then | |
| 65 | + | print("maybe") | |
| 66 | + | else | |
| 67 | + | print("no") | |
| 68 | + | end | |
| 69 | + | ||
| 70 | + | ## Variables | |
| 71 | + | ||
| 72 | + | local x = 2 | |
| 73 | + | two, four = 2, 4 | |
| 74 | + | ||
| 75 | + | ## Functions | |
| 76 | + | ||
| 77 | + | function myFunction() | |
| 78 | + | return 1 | |
| 79 | + | end | |
| 80 | + | ||
| 81 | + | function myFunctionWithArgs(a, b) | |
| 82 | + | -- ... | |
| 83 | + | end | |
| 84 | + | ||
| 85 | + | myFunction() | |
| 86 | + | ||
| 87 | + | anonymousFunctions(function() | |
| 88 | + | -- ... | |
| 89 | + | end) | |
| 90 | + | ||
| 91 | + | -- Not exported in the module | |
| 92 | + | local function myPrivateFunction() | |
| 93 | + | end | |
| 94 | + | ||
| 95 | + | -- Splats | |
| 96 | + | function doAction(action, ...) | |
| 97 | + | print("Doing '"..action.."' to", ...) | |
| 98 | + | --> print("Doing 'write' to", "Shirley", "Abed") | |
| 99 | + | end | |
| 100 | + | ||
| 101 | + | doAction('write', "Shirley", "Abed") | |
| 102 | + | ||
| 103 | + | ## Lookups | |
| 104 | + | ||
| 105 | + | mytable = { x = 2, y = function() .. end } | |
| 106 | + | ||
| 107 | + | -- The same: | |
| 108 | + | mytable.x | |
| 109 | + | mytable['x'] | |
| 110 | + | ||
| 111 | + | -- Syntactic sugar, these are equivalent: | |
| 112 | + | mytable.y(mytable) | |
| 113 | + | mytable:y() | |
| 114 | + | ||
| 115 | + | mytable.y(mytable, a, b) | |
| 116 | + | mytable:y(a, b) | |
| 117 | + | ||
| 118 | + | function X:y(z) .. end | |
| 119 | + | function X.y(self, z) .. end | |
| 120 | + | ||
| 121 | + | ## Metatables | |
| 122 | + | ||
| 123 | + | ||
| 124 | + | mt = {} | |
| 125 | + | ||
| 126 | + | -- A metatable is simply a table with functions in it. | |
| 127 | + | mt.__tostring = function() return "lol" end | |
| 128 | + | mt.__add = function(b) ... end -- a + b | |
| 129 | + | mt.__mul = function(b) ... end -- a * b | |
| 130 | + | mt.__index = function(k) ... end -- Lookups (a[k] or a.k) | |
| 131 | + | mt.__newindex = function(k, v) ... end -- Setters (a[k] = v) | |
| 132 | + | ||
| 133 | + | -- Metatables allow you to override behavior of another table. | |
| 134 | + | mytable = {} | |
| 135 | + | setmetatable(mytable, mt) | |
| 136 | + | ||
| 137 | + | print(myobject) | |
| 138 | + | ||
| 139 | + | ## Classes | |
| 140 | + | ||
| 141 | + | Account = {} | |
| 142 | + | ||
| 143 | + | function Account:new(balance) | |
| 144 | + | local t = setmetatable({}, { __index = Account }) | |
| 145 | + | ||
| 146 | + | -- Your constructor stuff | |
| 147 | + | t.balance = (balance or 0) | |
| 148 | + | return t | |
| 149 | + | end | |
| 150 | + | ||
| 151 | + | function Account:withdraw(amount) | |
| 152 | + | print("Withdrawing "..amount.."...") | |
| 153 | + | self.balance = self.balance - amount | |
| 154 | + | self:report() | |
| 155 | + | end | |
| 156 | + | ||
| 157 | + | function Account:report() | |
| 158 | + | print("Your current balance is: "..self.balance) | |
| 159 | + | end | |
| 160 | + | ||
| 161 | + | a = Account:new(9000) | |
| 162 | + | a:withdraw(200) -- method call | |
| 163 | + | ||
| 164 | + | ## Constants | |
| 165 | + | ||
| 166 | + | nil | |
| 167 | + | false | |
| 168 | + | true | |
| 169 | + | ||
| 170 | + | ## Operators (and their metatable names) | |
| 171 | + | ||
| 172 | + | -- Relational (binary) | |
| 173 | + | -- __eq __lt __gt __le __ge | |
| 174 | + | == < > <= >= | |
| 175 | + | ~= -- Not equal, just like != | |
| 176 | + | ||
| 177 | + | -- Arithmetic (binary) | |
| 178 | + | -- __add __sub __muv __div __mod __pow | |
| 179 | + | + - * / % ^ | |
| 180 | + | ||
| 181 | + | -- Arithmetic (unary) | |
| 182 | + | -- __unm (unary minus) | |
| 183 | + | - | |
| 184 | + | ||
| 185 | + | -- Logic (and/or) | |
| 186 | + | nil and false --> nil | |
| 187 | + | false and nil --> false | |
| 188 | + | 0 and 20 --> 20 | |
| 189 | + | 10 and 20 --> 20 | |
| 190 | + | ||
| 191 | + | ||
| 192 | + | -- Length | |
| 193 | + | -- __len(array) | |
| 194 | + | #array | |
| 195 | + | ||
| 196 | + | ||
| 197 | + | -- Indexing | |
| 198 | + | -- __index(table, key) | |
| 199 | + | t[key] | |
| 200 | + | t.key | |
| 201 | + | ||
| 202 | + | -- __newindex(table, key, value) | |
| 203 | + | t[key]=value | |
| 204 | + | ||
| 205 | + | -- String concat | |
| 206 | + | -- __concat(left, right) | |
| 207 | + | "hello, "..name | |
| 208 | + | ||
| 209 | + | -- Call | |
| 210 | + | -- __call(func, ...) | |
| 211 | + | ||
| 212 | + | ||
| 213 | + | ## API: Global functions [(ref)](http://lua.gts-stolberg.de/en/Basis.php) | |
| 214 | + | ||
| 215 | + | dofile("hello.lua") | |
| 216 | + | loadfile("hello.lua") | |
| 217 | + | ||
| 218 | + | assert(x) -- x or (raise an error) | |
| 219 | + | assert(x, "failed") | |
| 220 | + | ||
| 221 | + | type(var) -- "nil" | "number" | "string" | "boolean" | "table" | "function" | "thread" | "userdata" | |
| 222 | + | ||
| 223 | + | -- Does /not/ invoke meta methods (__index and __newindex) | |
| 224 | + | rawset(t, index, value) -- Like t[index] = value | |
| 225 | + | rawget(t, index) -- Like t[index] | |
| 226 | + | ||
| 227 | + | _G -- Global context | |
| 228 | + | setfenv(1, {}) -- 1: current function, 2: caller, and so on -- {}: the new _G | |
| 229 | + | ||
| 230 | + | pairs(t) -- iterable list of {key, value} | |
| 231 | + | ipairs(t) -- iterable list of {index, value} | |
| 232 | + | ||
| 233 | + | tonumber("34") | |
| 234 | + | tonumber("8f", 16) | |
| 235 | + | ||
| 236 | + | ## API: Strings | |
| 237 | + | ||
| 238 | + | 'string'..'concatenation' | |
| 239 | + | ||
| 240 | + | s = "Hello" | |
| 241 | + | s:upper() | |
| 242 | + | s:lower() | |
| 243 | + | s:len() -- Just like #s | |
| 244 | + | ||
| 245 | + | s:find() | |
| 246 | + | s:gfind() | |
| 247 | + | ||
| 248 | + | s:match() | |
| 249 | + | s:gmatch() | |
| 250 | + | ||
| 251 | + | s:sub() | |
| 252 | + | s:gsub() | |
| 253 | + | ||
| 254 | + | s:rep() | |
| 255 | + | s:char() | |
| 256 | + | s:dump() | |
| 257 | + | s:reverse() | |
| 258 | + | s:byte() | |
| 259 | + | s:format() | |
| 260 | + | ||
| 261 | + | ## API: Tables | |
| 262 | + | ||
| 263 | + | table.foreach(t, function(row) ... end) | |
| 264 | + | table.setn | |
| 265 | + | table.insert(t, 21) -- append (--> t[#t+1] = 21) | |
| 266 | + | table.insert(t, 4, 99) | |
| 267 | + | table.getn | |
| 268 | + | table.concat | |
| 269 | + | table.sort | |
| 270 | + | table.remove(t, 4) | |
| 271 | + | ||
| 272 | + | ## API: Math [(ref)](http://lua-users.org/wiki/MathLibraryTutorial) | |
| 273 | + | ||
| 274 | + | math.abs math.acos math.asin math.atan math.atan2 | |
| 275 | + | math.ceil math.cos math.cosh math.deg math.exp | |
| 276 | + | math.floor math.fmod math.frexp math.ldexp math.log | |
| 277 | + | math.log10 math.max math.min math.modf math.pow | |
| 278 | + | math.rad math.random math.randomseed math.sin math.sinh | |
| 279 | + | math.sqrt math.tan math.tanh | |
| 280 | + | ||
| 281 | + | math.sqrt(144) | |
| 282 | + | math | |
| 283 | + | ||
| 284 | + | ## API: Misc | |
| 285 | + | ||
| 286 | + | io.output(io.open("file.txt", "w")) | |
| 287 | + | io.write(x) | |
| 288 | + | io.close() | |
| 289 | + | ||
| 290 | + | for line in io.lines("file.txt") | |
| 291 | + | ||
| 292 | + | file = assert(io.open("file.txt", "r")) | |
| 293 | + | file:read() | |
| 294 | + | file:lines() | |
| 295 | + | file:close() | |
| 296 | + | ||
| 297 | + | ## Reference | |
| 298 | + | ||
| 299 | + | https://www.lua.org/pil/13.html | |
| 300 | + | http://lua-users.org/wiki/ObjectOrientedProgramming | |
| 301 | + | ||
| 302 | + | https://devhints.io/ cheatsheets - Copyright (c) 2021 Rico Sta. Cruz and contributors - MIT license | |
| 303 | + | micro-cheat plugin Copyright 2022 Tero Karvinen https://TeroKarvinen.com/micro - MIT license |
| ... | ... | @@ -0,0 +1,132 @@ | |
| 1 | + | --- | |
| 2 | + | title: Makefile | |
| 3 | + | prism_languages: [makefile] | |
| 4 | + | layout: 2017/sheet | |
| 5 | + | category: CLI | |
| 6 | + | --- | |
| 7 | + | ||
| 8 | + | ## Var assignment | |
| 9 | + | ||
| 10 | + | ```makefile | |
| 11 | + | foo = "bar" | |
| 12 | + | bar = $(foo) foo # dynamic (renewing) assignment | |
| 13 | + | foo := "boo" # one time assignment, $(bar) now is "boo foo" | |
| 14 | + | foo ?= /usr/local # safe assignment, $(foo) and $(bar) still the same | |
| 15 | + | bar += world # append, "boo foo world" | |
| 16 | + | foo != echo fooo # exec shell command and assign to foo | |
| 17 | + | # $(bar) now is "fooo foo world" | |
| 18 | + | ``` | |
| 19 | + | ||
| 20 | + | `=` expressions are only evaluated when they're being used. | |
| 21 | + | ||
| 22 | + | ## Magic variables | |
| 23 | + | ||
| 24 | + | ```makefile | |
| 25 | + | out.o: src.c src.h | |
| 26 | + | $@ # "out.o" (target) | |
| 27 | + | $< # "src.c" (first prerequisite) | |
| 28 | + | $^ # "src.c src.h" (all prerequisites) | |
| 29 | + | ||
| 30 | + | %.o: %.c | |
| 31 | + | $* # the 'stem' with which an implicit rule matches ("foo" in "foo.c") | |
| 32 | + | ||
| 33 | + | also: | |
| 34 | + | $+ # prerequisites (all, with duplication) | |
| 35 | + | $? # prerequisites (new ones) | |
| 36 | + | $| # prerequisites (order-only?) | |
| 37 | + | ||
| 38 | + | $(@D) # target directory | |
| 39 | + | ``` | |
| 40 | + | ||
| 41 | + | ## Command prefixes | |
| 42 | + | ||
| 43 | + | | Prefix | Description | | |
| 44 | + | | ------ | ------------------------------------------- | | |
| 45 | + | | `-` | Ignore errors | | |
| 46 | + | | `@` | Don't print command | | |
| 47 | + | | `+` | Run even if Make is in 'don't execute' mode | | |
| 48 | + | ||
| 49 | + | ```makefile | |
| 50 | + | build: | |
| 51 | + | @echo "compiling" | |
| 52 | + | -gcc $< $@ | |
| 53 | + | ||
| 54 | + | -include .depend | |
| 55 | + | ``` | |
| 56 | + | ||
| 57 | + | ## Find files | |
| 58 | + | ||
| 59 | + | ```makefile | |
| 60 | + | js_files := $(wildcard test/*.js) | |
| 61 | + | all_files := $(shell find images -name "*") | |
| 62 | + | ``` | |
| 63 | + | ||
| 64 | + | ## Substitutions | |
| 65 | + | ||
| 66 | + | ```makefile | |
| 67 | + | file = $(SOURCE:.cpp=.o) # foo.cpp => foo.o | |
| 68 | + | outputs = $(files:src/%.coffee=lib/%.js) | |
| 69 | + | ||
| 70 | + | outputs = $(patsubst %.c, %.o, $(wildcard *.c)) | |
| 71 | + | assets = $(patsubst images/%, assets/%, $(wildcard images/*)) | |
| 72 | + | ``` | |
| 73 | + | ||
| 74 | + | ## More functions | |
| 75 | + | ||
| 76 | + | ```makefile | |
| 77 | + | $(strip $(string_var)) | |
| 78 | + | ||
| 79 | + | $(filter %.less, $(files)) | |
| 80 | + | $(filter-out %.less, $(files)) | |
| 81 | + | ``` | |
| 82 | + | ||
| 83 | + | ## Building files | |
| 84 | + | ||
| 85 | + | ```makefile | |
| 86 | + | %.o: %.c | |
| 87 | + | ffmpeg -i $< > $@ # Input and output | |
| 88 | + | foo $^ | |
| 89 | + | ``` | |
| 90 | + | ||
| 91 | + | ## Includes | |
| 92 | + | ||
| 93 | + | ```makefile | |
| 94 | + | -include foo.make | |
| 95 | + | ``` | |
| 96 | + | ||
| 97 | + | ## Options | |
| 98 | + | ||
| 99 | + | ```sh | |
| 100 | + | make | |
| 101 | + | -e, --environment-overrides | |
| 102 | + | -B, --always-make | |
| 103 | + | -s, --silent | |
| 104 | + | -j, --jobs=N # parallel processing | |
| 105 | + | ``` | |
| 106 | + | ||
| 107 | + | ## Conditionals | |
| 108 | + | ||
| 109 | + | ```makefile | |
| 110 | + | foo: $(objects) | |
| 111 | + | ifeq ($(CC),gcc) | |
| 112 | + | $(CC) -o foo $(objects) $(libs_for_gcc) | |
| 113 | + | else | |
| 114 | + | $(CC) -o foo $(objects) $(normal_libs) | |
| 115 | + | endif | |
| 116 | + | ``` | |
| 117 | + | ||
| 118 | + | ## Recursive | |
| 119 | + | ||
| 120 | + | ```makefile | |
| 121 | + | deploy: | |
| 122 | + | $(MAKE) deploy2 | |
| 123 | + | ``` | |
| 124 | + | ||
| 125 | + | ## Further reading | |
| 126 | + | ||
| 127 | + | - [isaacs's Makefile](https://gist.github.com/isaacs/62a2d1825d04437c6f08) | |
| 128 | + | - [Your Makefiles are wrong](https://tech.davis-hansson.com/p/make/) | |
| 129 | + | - [Manual](https://www.gnu.org/software/make/manual/html_node/index.html) | |
| 130 | + | ||
| 131 | + | https://devhints.io/ cheatsheets - Copyright (c) 2021 Rico Sta. Cruz and contributors - MIT license | |
| 132 | + | micro-cheat plugin Copyright 2022 Tero Karvinen https://TeroKarvinen.com/micro - MIT license |
| ... | ... | @@ -0,0 +1,21 @@ | |
| 1 | + | --- | |
| 2 | + | title: Man | |
| 3 | + | category: CLI | |
| 4 | + | layout: 2017/sheet | |
| 5 | + | --- | |
| 6 | + | ||
| 7 | + | ### Man paths | |
| 8 | + | ||
| 9 | + | | `1` | General User Commands | | |
| 10 | + | | `2` | System Calls | | |
| 11 | + | | `3` | Library Routines | | |
| 12 | + | | `4` | Special Files and Sockets | | |
| 13 | + | | `5` | File formats and Conventions | | |
| 14 | + | | `6` | Games and Fun Stuff | | |
| 15 | + | | `7` | Miscellaneous Documentation | | |
| 16 | + | | `8` | System Administration | | |
| 17 | + | | `9` | Kernel and Programming Style | | |
| 18 | + | | `n` | Tcl/Tk | | |
| 19 | + | ||
| 20 | + | https://devhints.io/ cheatsheets - Copyright (c) 2021 Rico Sta. Cruz and contributors - MIT license | |
| 21 | + | micro-cheat plugin Copyright 2022 Tero Karvinen https://TeroKarvinen.com/micro - MIT license |
| ... | ... | @@ -0,0 +1,167 @@ | |
| 1 | + | --- | |
| 2 | + | title: Markdown | |
| 3 | + | category: Markup | |
| 4 | + | layout: 2017/sheet | |
| 5 | + | prism_languages: [markdown] | |
| 6 | + | updated: 2020-07-01 | |
| 7 | + | weight: -1 | |
| 8 | + | --- | |
| 9 | + | ||
| 10 | + | ## Reference | |
| 11 | + | {:.-three-column} | |
| 12 | + | ||
| 13 | + | ### Headers | |
| 14 | + | ||
| 15 | + | ```markdown | |
| 16 | + | # h1 | |
| 17 | + | ## h2 | |
| 18 | + | ### h3 | |
| 19 | + | #### h4 | |
| 20 | + | ##### h5 | |
| 21 | + | ###### h6 | |
| 22 | + | ``` | |
| 23 | + | ||
| 24 | + | ```markdown | |
| 25 | + | Header 1 | |
| 26 | + | ======== | |
| 27 | + | ``` | |
| 28 | + | ||
| 29 | + | ```markdown | |
| 30 | + | Header 2 | |
| 31 | + | -------- | |
| 32 | + | ``` | |
| 33 | + | ||
| 34 | + | ### Emphasis | |
| 35 | + | ||
| 36 | + | ```markdown | |
| 37 | + | *italic* | |
| 38 | + | _italic_ | |
| 39 | + | ``` | |
| 40 | + | ||
| 41 | + | ```markdown | |
| 42 | + | **bold** | |
| 43 | + | __bold__ | |
| 44 | + | ``` | |
| 45 | + | ||
| 46 | + | ```markdown | |
| 47 | + | ***bold italic*** | |
| 48 | + | ___bold italic___ | |
| 49 | + | ``` | |
| 50 | + | ||
| 51 | + | ```markdown | |
| 52 | + | ~~strikethrough~~ | |
| 53 | + | ``` | |
| 54 | + | ||
| 55 | + | ```markdown | |
| 56 | + | `code` | |
| 57 | + | ``` | |
| 58 | + | ||
| 59 | + | ### Lists | |
| 60 | + | ||
| 61 | + | ```markdown | |
| 62 | + | * Item 1 | |
| 63 | + | * Item 2 | |
| 64 | + | ``` | |
| 65 | + | ||
| 66 | + | ```markdown | |
| 67 | + | - Item 1 | |
| 68 | + | - Item 2 | |
| 69 | + | ``` | |
| 70 | + | ||
| 71 | + | ```markdown | |
| 72 | + | - [ ] Checkbox off | |
| 73 | + | - [x] Checkbox on | |
| 74 | + | ``` | |
| 75 | + | ||
| 76 | + | ```markdown | |
| 77 | + | 1. Item 1 | |
| 78 | + | 2. Item 2 | |
| 79 | + | ``` | |
| 80 | + | ||
| 81 | + | ### Links | |
| 82 | + | ||
| 83 | + | ```markdown | |
| 84 | + | [link](http://google.com) | |
| 85 | + | ``` | |
| 86 | + | ||
| 87 | + | ```markdown | |
| 88 | + | [link][google] | |
| 89 | + | [google]: http://google.com | |
| 90 | + | ``` | |
| 91 | + | ||
| 92 | + | ```markdown | |
| 93 | + | <http://google.com> | |
| 94 | + | ``` | |
| 95 | + | ||
| 96 | + | ### Images | |
| 97 | + | ||
| 98 | + | ```markdown | |
| 99 | + |  | |
| 100 | + |  | |
| 101 | + | ![Image alt text][img] | |
| 102 | + | ``` | |
| 103 | + | ||
| 104 | + | ```markdown | |
| 105 | + | [img]: http://foo.com/img.jpg | |
| 106 | + | ``` | |
| 107 | + | ||
| 108 | + | ### Code | |
| 109 | + | ||
| 110 | + | ```markdown | |
| 111 | + | `inline code` | |
| 112 | + | ``` | |
| 113 | + | ||
| 114 | + | ``` | |
| 115 | + | 4 space indent | |
| 116 | + | makes a code block | |
| 117 | + | ``` | |
| 118 | + | ||
| 119 | + | ~~~markdown | |
| 120 | + | ``` | |
| 121 | + | code fences | |
| 122 | + | ``` | |
| 123 | + | ~~~ | |
| 124 | + | ||
| 125 | + | ||
| 126 | + | ~~~markdown | |
| 127 | + | ```js | |
| 128 | + | codeFences.withLanguage() | |
| 129 | + | ``` | |
| 130 | + | ~~~ | |
| 131 | + | ||
| 132 | + | ### Blockquotes | |
| 133 | + | ||
| 134 | + | ```markdown | |
| 135 | + | > This is | |
| 136 | + | > a blockquote | |
| 137 | + | > | |
| 138 | + | > > Nested | |
| 139 | + | > > Blockquote | |
| 140 | + | ``` | |
| 141 | + | ||
| 142 | + | ### Horizontal line | |
| 143 | + | ||
| 144 | + | ```markdown | |
| 145 | + | ---- | |
| 146 | + | ``` | |
| 147 | + | ||
| 148 | + | ```markdown | |
| 149 | + | **** | |
| 150 | + | ``` | |
| 151 | + | ||
| 152 | + | ### Tables | |
| 153 | + | ||
| 154 | + | ```markdown | |
| 155 | + | | Column 1 Heading | Column 2 Heading | | |
| 156 | + | | ---------------- | ---------------- | | |
| 157 | + | | Some content | Other content | | |
| 158 | + | ``` | |
| 159 | + | ||
| 160 | + | ```markdown | |
| 161 | + | Column 1 Heading | Column 2 Heading | |
| 162 | + | --- | --- | |
| 163 | + | Some content | Other content | |
| 164 | + | ``` | |
| 165 | + | ||
| 166 | + | https://devhints.io/ cheatsheets - Copyright (c) 2021 Rico Sta. Cruz and contributors - MIT license | |
| 167 | + | micro-cheat plugin Copyright 2022 Tero Karvinen https://TeroKarvinen.com/micro - MIT license |
| ... | ... | @@ -0,0 +1,271 @@ | |
| 1 | + | --- | |
| 2 | + | title: MySQL | |
| 3 | + | updated: 2020-07-05 | |
| 4 | + | layout: 2017/sheet | |
| 5 | + | category: Databases | |
| 6 | + | --- | |
| 7 | + | ||
| 8 | + | ### Browsing | |
| 9 | + | ||
| 10 | + | ```sql | |
| 11 | + | SHOW DATABASES; | |
| 12 | + | SHOW TABLES; | |
| 13 | + | SHOW FIELDS FROM table / DESCRIBE table; | |
| 14 | + | SHOW CREATE TABLE table; | |
| 15 | + | SHOW PROCESSLIST; | |
| 16 | + | KILL process_number; | |
| 17 | + | ``` | |
| 18 | + | ||
| 19 | + | ### Select | |
| 20 | + | ||
| 21 | + | ```sql | |
| 22 | + | SELECT * FROM table; | |
| 23 | + | SELECT * FROM table1, table2; | |
| 24 | + | SELECT field1, field2 FROM table1, table2; | |
| 25 | + | SELECT ... FROM ... WHERE condition | |
| 26 | + | SELECT ... FROM ... WHERE condition GROUP BY field; | |
| 27 | + | SELECT ... FROM ... WHERE condition GROUP BY field HAVING condition2; | |
| 28 | + | SELECT ... FROM ... WHERE condition ORDER BY field1, field2; | |
| 29 | + | SELECT ... FROM ... WHERE condition ORDER BY field1, field2 DESC; | |
| 30 | + | SELECT ... FROM ... WHERE condition LIMIT 10; | |
| 31 | + | SELECT DISTINCT field1 FROM ... | |
| 32 | + | SELECT DISTINCT field1, field2 FROM ... | |
| 33 | + | ``` | |
| 34 | + | ||
| 35 | + | ### Select - Join | |
| 36 | + | ||
| 37 | + | ```sql | |
| 38 | + | SELECT ... FROM t1 JOIN t2 ON t1.id1 = t2.id2 WHERE condition; | |
| 39 | + | SELECT ... FROM t1 LEFT JOIN t2 ON t1.id1 = t2.id2 WHERE condition; | |
| 40 | + | SELECT ... FROM t1 JOIN (t2 JOIN t3 ON ...) ON ... | |
| 41 | + | ``` | |
| 42 | + | ||
| 43 | + | ### Conditions | |
| 44 | + | ||
| 45 | + | ```sql | |
| 46 | + | field1 = value1 | |
| 47 | + | field1 <> value1 | |
| 48 | + | field1 LIKE 'value _ %' | |
| 49 | + | field1 IS NULL | |
| 50 | + | field1 IS NOT NULL | |
| 51 | + | field1 IS IN (value1, value2) | |
| 52 | + | field1 IS NOT IN (value1, value2) | |
| 53 | + | condition1 AND condition2 | |
| 54 | + | condition1 OR condition2 | |
| 55 | + | ``` | |
| 56 | + | ||
| 57 | + | ### Create / Open / Delete Database | |
| 58 | + | ||
| 59 | + | ```sql | |
| 60 | + | CREATE DATABASE DatabaseName; | |
| 61 | + | CREATE DATABASE DatabaseName CHARACTER SET utf8; | |
| 62 | + | USE DatabaseName; | |
| 63 | + | DROP DATABASE DatabaseName; | |
| 64 | + | ALTER DATABASE DatabaseName CHARACTER SET utf8; | |
| 65 | + | ``` | |
| 66 | + | ||
| 67 | + | ### Backup Database to SQL File | |
| 68 | + | ||
| 69 | + | ```bash | |
| 70 | + | mysqldump -u Username -p dbNameYouWant > databasename_backup.sql | |
| 71 | + | ``` | |
| 72 | + | ||
| 73 | + | ### Restore from backup SQL File | |
| 74 | + | ||
| 75 | + | ```bash | |
| 76 | + | mysql -u Username -p dbNameYouWant < databasename_backup.sql; | |
| 77 | + | ``` | |
| 78 | + | ||
| 79 | + | ### Repair Tables After Unclean Shutdown | |
| 80 | + | ||
| 81 | + | ```bash | |
| 82 | + | mysqlcheck --all-databases; | |
| 83 | + | mysqlcheck --all-databases --fast; | |
| 84 | + | ``` | |
| 85 | + | ||
| 86 | + | ### Insert | |
| 87 | + | ||
| 88 | + | ```sql | |
| 89 | + | INSERT INTO table1 (field1, field2) VALUES (value1, value2); | |
| 90 | + | ``` | |
| 91 | + | ||
| 92 | + | ### Delete | |
| 93 | + | ||
| 94 | + | ```sql | |
| 95 | + | DELETE FROM table1 / TRUNCATE table1 | |
| 96 | + | DELETE FROM table1 WHERE condition | |
| 97 | + | DELETE FROM table1, table2 WHERE table1.id1 = | |
| 98 | + | table2.id2 AND condition | |
| 99 | + | ``` | |
| 100 | + | ||
| 101 | + | ### Update | |
| 102 | + | ||
| 103 | + | ```sql | |
| 104 | + | UPDATE table1 SET field1=new_value1 WHERE condition; | |
| 105 | + | UPDATE table1, table2 SET field1=new_value1, field2=new_value2, ... WHERE | |
| 106 | + | table1.id1 = table2.id2 AND condition; | |
| 107 | + | ``` | |
| 108 | + | ||
| 109 | + | ### Create / Delete / Modify Table | |
| 110 | + | ||
| 111 | + | #### Create | |
| 112 | + | ||
| 113 | + | ```sql | |
| 114 | + | CREATE TABLE table (field1 type1, field2 type2); | |
| 115 | + | CREATE TABLE table (field1 type1, field2 type2, INDEX (field)); | |
| 116 | + | CREATE TABLE table (field1 type1, field2 type2, PRIMARY KEY (field1)); | |
| 117 | + | CREATE TABLE table (field1 type1, field2 type2, PRIMARY KEY (field1,field2)); | |
| 118 | + | ``` | |
| 119 | + | ||
| 120 | + | ```sql | |
| 121 | + | CREATE TABLE table1 (fk_field1 type1, field2 type2, ..., | |
| 122 | + | FOREIGN KEY (fk_field1) REFERENCES table2 (t2_fieldA)) | |
| 123 | + | [ON UPDATE|ON DELETE] [CASCADE|SET NULL] | |
| 124 | + | ``` | |
| 125 | + | ||
| 126 | + | ```sql | |
| 127 | + | CREATE TABLE table1 (fk_field1 type1, fk_field2 type2, ..., | |
| 128 | + | FOREIGN KEY (fk_field1, fk_field2) REFERENCES table2 (t2_fieldA, t2_fieldB)) | |
| 129 | + | ``` | |
| 130 | + | ||
| 131 | + | ```sql | |
| 132 | + | CREATE TABLE table IF NOT EXISTS; | |
| 133 | + | ``` | |
| 134 | + | ||
| 135 | + | ```sql | |
| 136 | + | CREATE TEMPORARY TABLE table; | |
| 137 | + | ``` | |
| 138 | + | ||
| 139 | + | #### Drop | |
| 140 | + | ||
| 141 | + | ```sql | |
| 142 | + | DROP TABLE table; | |
| 143 | + | DROP TABLE IF EXISTS table; | |
| 144 | + | DROP TABLE table1, table2, ... | |
| 145 | + | ``` | |
| 146 | + | ||
| 147 | + | #### Alter | |
| 148 | + | ||
| 149 | + | ```sql | |
| 150 | + | ALTER TABLE table MODIFY field1 type1 | |
| 151 | + | ALTER TABLE table MODIFY field1 type1 NOT NULL ... | |
| 152 | + | ALTER TABLE table CHANGE old_name_field1 new_name_field1 type1 | |
| 153 | + | ALTER TABLE table CHANGE old_name_field1 new_name_field1 type1 NOT NULL ... | |
| 154 | + | ALTER TABLE table ALTER field1 SET DEFAULT ... | |
| 155 | + | ALTER TABLE table ALTER field1 DROP DEFAULT | |
| 156 | + | ALTER TABLE table ADD new_name_field1 type1 | |
| 157 | + | ALTER TABLE table ADD new_name_field1 type1 FIRST | |
| 158 | + | ALTER TABLE table ADD new_name_field1 type1 AFTER another_field | |
| 159 | + | ALTER TABLE table DROP field1 | |
| 160 | + | ALTER TABLE table ADD INDEX (field); | |
| 161 | + | ``` | |
| 162 | + | ||
| 163 | + | #### Change field order | |
| 164 | + | ||
| 165 | + | ```sql | |
| 166 | + | ALTER TABLE table MODIFY field1 type1 FIRST | |
| 167 | + | ALTER TABLE table MODIFY field1 type1 AFTER another_field | |
| 168 | + | ALTER TABLE table CHANGE old_name_field1 new_name_field1 type1 FIRST | |
| 169 | + | ALTER TABLE table CHANGE old_name_field1 new_name_field1 type1 AFTER | |
| 170 | + | another_field | |
| 171 | + | ``` | |
| 172 | + | ||
| 173 | + | ### Keys | |
| 174 | + | ||
| 175 | + | ```sql | |
| 176 | + | CREATE TABLE table (..., PRIMARY KEY (field1, field2)) | |
| 177 | + | CREATE TABLE table (..., FOREIGN KEY (field1, field2) REFERENCES table2 | |
| 178 | + | (t2_field1, t2_field2)) | |
| 179 | + | ``` | |
| 180 | + | ||
| 181 | + | ### Users and Privileges | |
| 182 | + | ||
| 183 | + | ```sql | |
| 184 | + | CREATE USER 'user'@'localhost'; | |
| 185 | + | GRANT ALL PRIVILEGES ON base.* TO 'user'@'localhost' IDENTIFIED BY 'password'; | |
| 186 | + | GRANT SELECT, INSERT, DELETE ON base.* TO 'user'@'localhost' IDENTIFIED BY 'password'; | |
| 187 | + | REVOKE ALL PRIVILEGES ON base.* FROM 'user'@'host'; -- one permission only | |
| 188 | + | REVOKE ALL PRIVILEGES, GRANT OPTION FROM 'user'@'host'; -- all permissions | |
| 189 | + | FLUSH PRIVILEGES; | |
| 190 | + | ``` | |
| 191 | + | ||
| 192 | + | ```sql | |
| 193 | + | SET PASSWORD = PASSWORD('new_pass'); | |
| 194 | + | SET PASSWORD FOR 'user'@'host' = PASSWORD('new_pass'); | |
| 195 | + | SET PASSWORD = OLD_PASSWORD('new_pass'); | |
| 196 | + | ``` | |
| 197 | + | ||
| 198 | + | ```sql | |
| 199 | + | DROP USER 'user'@'host'; | |
| 200 | + | ``` | |
| 201 | + | ||
| 202 | + | Host ‘%’ indicates any host. | |
| 203 | + | ||
| 204 | + | ### Main Data Types | |
| 205 | + | ||
| 206 | + | ```sql | |
| 207 | + | TINYINT (1o: -128 to +127) | |
| 208 | + | SMALLINT (2o: +-65 000) | |
| 209 | + | MEDIUMINT (3o: +-16 000 000) | |
| 210 | + | INT (4o: +- 2 000 000 000) | |
| 211 | + | BIGINT (8o: +-9.10^18) | |
| 212 | + | ``` | |
| 213 | + | ||
| 214 | + | ```sql | |
| 215 | + | Precise interval: -(2^(8*N-1)) -> (2^8*N)-1 | |
| 216 | + | ``` | |
| 217 | + | ||
| 218 | + | ⚠ INT(2) = "2 digits displayed" -- NOT "number with 2 digits max" | |
| 219 | + | ||
| 220 | + | ```sql | |
| 221 | + | FLOAT(M,D) | |
| 222 | + | DOUBLE(M,D) | |
| 223 | + | FLOAT(D=0->53) | |
| 224 | + | ``` | |
| 225 | + | ||
| 226 | + | ⚠ 8,3 -> 12345,678 -- NOT 12345678,123! | |
| 227 | + | ||
| 228 | + | ```sql | |
| 229 | + | TIME (HH:MM) | |
| 230 | + | YEAR (AAAA) | |
| 231 | + | DATE (AAAA-MM-JJ) | |
| 232 | + | DATETIME (AAAA-MM-JJ HH:MM; années 1000->9999) | |
| 233 | + | TIMESTAMP (like DATETIME, but 1970->2038, compatible with Unix) | |
| 234 | + | ``` | |
| 235 | + | ||
| 236 | + | ```sql | |
| 237 | + | VARCHAR (single-line; explicit size) | |
| 238 | + | TEXT (multi-lines; max size=65535) | |
| 239 | + | BLOB (binary; max size=65535) | |
| 240 | + | ``` | |
| 241 | + | ||
| 242 | + | Variants for TEXT&BLOB: `TINY` (max=255), `MEDIUM` (max=~16000), and `LONG` (max=4Go). Ex: `VARCHAR(32)`, `TINYTEXT`, `LONGBLOB`, `MEDIUMTEXT` | |
| 243 | + | ||
| 244 | + | ```sql | |
| 245 | + | ENUM ('value1', 'value2', ...) -- (default NULL, or '' if NOT NULL) | |
| 246 | + | ``` | |
| 247 | + | ||
| 248 | + | ### Reset Root Password | |
| 249 | + | ||
| 250 | + | ```bash | |
| 251 | + | $ /etc/init.d/mysql stop | |
| 252 | + | ``` | |
| 253 | + | ||
| 254 | + | ```bash | |
| 255 | + | $ mysqld_safe --skip-grant-tables | |
| 256 | + | ``` | |
| 257 | + | ||
| 258 | + | ```bash | |
| 259 | + | $ mysql # on another terminal | |
| 260 | + | mysql> UPDATE mysql.user SET password=PASSWORD('new_pass') WHERE user='root'; | |
| 261 | + | ``` | |
| 262 | + | ||
| 263 | + | ```bash | |
| 264 | + | ## Switch back to the mysqld_safe terminal and kill the process using Control + \ | |
| 265 | + | $ /etc/init.d/mysql start | |
| 266 | + | ``` | |
| 267 | + | ||
| 268 | + | Your commands may vary depending on your OS. | |
| 269 | + | ||
| 270 | + | https://devhints.io/ cheatsheets - Copyright (c) 2021 Rico Sta. Cruz and contributors - MIT license | |
| 271 | + | micro-cheat plugin Copyright 2022 Tero Karvinen https://TeroKarvinen.com/micro - MIT license |
| ... | ... | @@ -0,0 +1,116 @@ | |
| 1 | + | --- | |
| 2 | + | title: Org Mode | |
| 3 | + | layout: 2017/sheet | |
| 4 | + | tags: [WIP] | |
| 5 | + | category: Apps | |
| 6 | + | updated: 2018-02-19 | |
| 7 | + | intro: | | |
| 8 | + | [Org mode](https://orgmode.org/) is for keeping hierarchal notes (and more) in Emacs. | |
| 9 | + | --- | |
| 10 | + | ||
| 11 | + | ## Syntax | |
| 12 | + | {: .-three-column} | |
| 13 | + | ||
| 14 | + | ### Headings | |
| 15 | + | ||
| 16 | + | ```org | |
| 17 | + | * Welcome to Org mode | |
| 18 | + | ||
| 19 | + | Lines starting with * are headings. | |
| 20 | + | These lines without are notes. | |
| 21 | + | ||
| 22 | + | ** Sub-heading | |
| 23 | + | ||
| 24 | + | Two stars mark a 2nd-level subheading (h2). | |
| 25 | + | ``` | |
| 26 | + | ||
| 27 | + | ### Lists | |
| 28 | + | ||
| 29 | + | ```org | |
| 30 | + | * Lists | |
| 31 | + | ||
| 32 | + | To buy: | |
| 33 | + | 1. Milk | |
| 34 | + | 2. Eggs | |
| 35 | + | - Organic | |
| 36 | + | 3. Cheese | |
| 37 | + | + Parmesan | |
| 38 | + | + Mozarella | |
| 39 | + | ``` | |
| 40 | + | ||
| 41 | + | ### Inline styles | |
| 42 | + | ||
| 43 | + | ```org | |
| 44 | + | *bold* | |
| 45 | + | /italic/ | |
| 46 | + | _underline_ | |
| 47 | + | =verbatim= | |
| 48 | + | ~code~ | |
| 49 | + | +strike-through+ | |
| 50 | + | ``` | |
| 51 | + | ||
| 52 | + | ### To do | |
| 53 | + | ||
| 54 | + | ```org | |
| 55 | + | * TODO buy airplane | |
| 56 | + | ``` | |
| 57 | + | ||
| 58 | + | Cycle by using `S-LEFT` / `S-RIGHT`. List all TODO's via `C-c C-v`. | |
| 59 | + | ||
| 60 | + | ## Shortcuts | |
| 61 | + | {: .-three-column} | |
| 62 | + | ||
| 63 | + | ### Basic shortcuts | |
| 64 | + | ||
| 65 | + | | Description | Shortcut | | |
| 66 | + | | --- | --- | | |
| 67 | + | | (Un) fold | `TAB` / `S-TAB` | | |
| 68 | + | | Move up | `M-UP` / `M-DOWN` | | |
| 69 | + | | New headline | `M-RET` | | |
| 70 | + | | Cycle workflow | `S-LEFT` / `S-RIGHT` | | |
| 71 | + | | Cycle priority | `S-UP` / `S-DOWN` | | |
| 72 | + | {:.-shortcuts-right} | |
| 73 | + | ||
| 74 | + | ### Timer | |
| 75 | + | ||
| 76 | + | | Description | Shortcut | | |
| 77 | + | | --- | --- | | |
| 78 | + | | Start timer | `C-c` `C-x` `0` | | |
| 79 | + | | Stop timer | `C-c` `C-x` `_` | | |
| 80 | + | | Pause timer | `C-c` `C-x` `,` | | |
| 81 | + | | --- | --- | | |
| 82 | + | | Start countdown | `C-c` `C-x` `;` | | |
| 83 | + | {:.-shortcuts-right} | |
| 84 | + | ||
| 85 | + | You can use this for Pomodoro! | |
| 86 | + | ||
| 87 | + | ### Agenda | |
| 88 | + | ||
| 89 | + | | Description | Shortcut | | |
| 90 | + | | --- | --- | | |
| 91 | + | | Agenda menu | `C-c` `a` | | |
| 92 | + | | --- | --- | | |
| 93 | + | | Add document | `C-c` `[` | | |
| 94 | + | | Remove document | `C-c` `]` | | |
| 95 | + | | --- | --- | | |
| 96 | + | | Add date | `C-c` `.` | | |
| 97 | + | | Add time & date | `C-u` `C-c` `.` | | |
| 98 | + | {:.-shortcuts-right} | |
| 99 | + | ||
| 100 | + | Start by adding the current file to the agenda (`C-c [`), then use the agenda menu to navigate. | |
| 101 | + | ||
| 102 | + | ### Export | |
| 103 | + | ||
| 104 | + | | Description | Shortcut | | |
| 105 | + | | --- | --- | | |
| 106 | + | | Export menu | `C-c` `C-e` | | |
| 107 | + | ||
| 108 | + | Lets you export the document as Markdown, HTML, and others. | |
| 109 | + | ||
| 110 | + | ## References | |
| 111 | + | ||
| 112 | + | - [Org for beginners](https://orgmode.org/worg/org-tutorials/org4beginners.html) _(orgmode.org)_ | |
| 113 | + | - [Org mode website](https://orgmode.org/) _(orgmode.org)_ | |
| 114 | + | ||
| 115 | + | https://devhints.io/ cheatsheets - Copyright (c) 2021 Rico Sta. Cruz and contributors - MIT license | |
| 116 | + | micro-cheat plugin Copyright 2022 Tero Karvinen https://TeroKarvinen.com/micro - MIT license |
| ... | ... | @@ -0,0 +1,27 @@ | |
| 1 | + | --- | |
| 2 | + | title: PostgreSQL | |
| 3 | + | category: Databases | |
| 4 | + | --- | |
| 5 | + | ||
| 6 | + | Replace anything within `<placeholder>` accordingly | |
| 7 | + | ||
| 8 | + | ### Console | |
| 9 | + | ||
| 10 | + | $ psql #logs in to default database & default user | |
| 11 | + | $ sudo -u <rolename:postgres> psql #logs in with a particular user | |
| 12 | + | ||
| 13 | + | ### Commands | |
| 14 | + | ||
| 15 | + | * Show roles: `\du` | |
| 16 | + | * Show tables: `\dt` | |
| 17 | + | * Show databases: `\l` | |
| 18 | + | * Connect to a database: `\c <database>` | |
| 19 | + | * Show columns of a table: `\d <table>` or `\d+ <table>` | |
| 20 | + | * Quit: `\q` | |
| 21 | + | ||
| 22 | + | ### Creating database | |
| 23 | + | ||
| 24 | + | $ createdb databasename | |
| 25 | + | ||
| 26 | + | https://devhints.io/ cheatsheets - Copyright (c) 2021 Rico Sta. Cruz and contributors - MIT license | |
| 27 | + | micro-cheat plugin Copyright 2022 Tero Karvinen https://TeroKarvinen.com/micro - MIT license |
| ... | ... | @@ -0,0 +1,170 @@ | |
| 1 | + | --- | |
| 2 | + | title: Python | |
| 3 | + | category: Python | |
| 4 | + | --- | |
| 5 | + | ||
| 6 | + | ### Tuples (immutable) | |
| 7 | + | ||
| 8 | + | tuple = () | |
| 9 | + | ||
| 10 | + | ### Lists (mutable) | |
| 11 | + | ||
| 12 | + | list = [] | |
| 13 | + | list[i:j] # returns list subset | |
| 14 | + | list[-1] # returns last element | |
| 15 | + | list[:-1] # returns all but the last element | |
| 16 | + | *list # expands all elements in place | |
| 17 | + | ||
| 18 | + | list[i] = val | |
| 19 | + | list[i:j] = otherlist # replace ith to jth-1 elements with otherlist | |
| 20 | + | del list[i:j] | |
| 21 | + | ||
| 22 | + | list.append(item) | |
| 23 | + | list.extend(another_list) | |
| 24 | + | list.insert(index, item) | |
| 25 | + | list.pop() # returns and removes last element from the list | |
| 26 | + | list.pop(i) # returns and removes i-th element from the list | |
| 27 | + | list.remove(i) # removes the first item from the list whose value is i | |
| 28 | + | list1 + list2 # combine two list | |
| 29 | + | set(list) # remove duplicate elements from a list | |
| 30 | + | ||
| 31 | + | list.reverse() # reverses the elements of the list in-place | |
| 32 | + | list.count(item) | |
| 33 | + | sum(list) | |
| 34 | + | ||
| 35 | + | zip(list1, list2) # returns list of tuples with n-th element of both list1 and list2 | |
| 36 | + | list.sort() # sorts in-place, returns None | |
| 37 | + | sorted(list) # returns sorted copy of list | |
| 38 | + | ",".join(list) # returns a string with list elements seperated by comma | |
| 39 | + | ||
| 40 | + | ### Dict | |
| 41 | + | ||
| 42 | + | dict = {} | |
| 43 | + | dict.keys() | |
| 44 | + | dict.values() | |
| 45 | + | "key" in dict # let's say this returns False, then... | |
| 46 | + | dict["key"] # ...this raises KeyError | |
| 47 | + | dict.get("key") # ...this returns None | |
| 48 | + | dict.setdefault("key", 1) | |
| 49 | + | **dict # expands all k/v pairs in place | |
| 50 | + | ||
| 51 | + | ### Iteration | |
| 52 | + | ||
| 53 | + | for item in ["a", "b", "c"]: | |
| 54 | + | for i in range(4): # 0 to 3 | |
| 55 | + | for i in range(4, 8): # 4 to 7 | |
| 56 | + | for i in range(1, 9, 2): # 1, 3, 5, 7 | |
| 57 | + | for key, val in dict.items(): | |
| 58 | + | for index, item in enumerate(list): | |
| 59 | + | ||
| 60 | + | ### [String](https://docs.python.org/2/library/stdtypes.html#string-methods) | |
| 61 | + | ||
| 62 | + | str[0:4] | |
| 63 | + | len(str) | |
| 64 | + | ||
| 65 | + | string.replace("-", " ") | |
| 66 | + | ",".join(list) | |
| 67 | + | "hi {0}".format('j') | |
| 68 | + | f"hi {name}" # same as "hi {}".format('name') | |
| 69 | + | str.find(",") | |
| 70 | + | str.index(",") # same, but raises IndexError | |
| 71 | + | str.count(",") | |
| 72 | + | str.split(",") | |
| 73 | + | ||
| 74 | + | str.lower() | |
| 75 | + | str.upper() | |
| 76 | + | str.title() | |
| 77 | + | ||
| 78 | + | str.lstrip() | |
| 79 | + | str.rstrip() | |
| 80 | + | str.strip() | |
| 81 | + | ||
| 82 | + | str.islower() | |
| 83 | + | ||
| 84 | + | /* escape characters */ | |
| 85 | + | >>> 'doesn\'t' # use \' to escape the single quote... | |
| 86 | + | "doesn't" | |
| 87 | + | >>> "doesn't" # ...or use double quotes instead | |
| 88 | + | "doesn't" | |
| 89 | + | >>> '"Yes," they said.' | |
| 90 | + | '"Yes," they said.' | |
| 91 | + | >>> "\"Yes,\" they said." | |
| 92 | + | '"Yes," they said.' | |
| 93 | + | >>> '"Isn\'t," they said.' | |
| 94 | + | '"Isn\'t," they said.' | |
| 95 | + | ||
| 96 | + | ### Casting | |
| 97 | + | ||
| 98 | + | int(str) | |
| 99 | + | float(str) | |
| 100 | + | str(int) | |
| 101 | + | str(float) | |
| 102 | + | 'string'.encode() | |
| 103 | + | ||
| 104 | + | ### Comprehensions | |
| 105 | + | ||
| 106 | + | [fn(i) for i in list] # .map | |
| 107 | + | map(fn, list) # .map, returns iterator | |
| 108 | + | ||
| 109 | + | filter(fn, list) # .filter, returns iterator | |
| 110 | + | [fn(i) for i in list if i > 0] # .filter.map | |
| 111 | + | ||
| 112 | + | ### Regex | |
| 113 | + | ||
| 114 | + | import re | |
| 115 | + | ||
| 116 | + | re.match(r'^[aeiou]', str) | |
| 117 | + | re.sub(r'^[aeiou]', '?', str) | |
| 118 | + | re.sub(r'(xyz)', r'\1', str) | |
| 119 | + | ||
| 120 | + | expr = re.compile(r'^...$') | |
| 121 | + | expr.match(...) | |
| 122 | + | expr.sub(...) | |
| 123 | + | ||
| 124 | + | ## File manipulation | |
| 125 | + | ||
| 126 | + | ### Reading | |
| 127 | + | ||
| 128 | + | ```py | |
| 129 | + | file = open("hello.txt", "r") # open in read mode 'r' | |
| 130 | + | file.close() | |
| 131 | + | ``` | |
| 132 | + | ||
| 133 | + | ```py | |
| 134 | + | print(file.read()) # read the entire file and set the cursor at the end of file | |
| 135 | + | print file.readline() # Reading one line | |
| 136 | + | file.seek(0, 0) # place the cursor at the beginning of the file | |
| 137 | + | ``` | |
| 138 | + | ||
| 139 | + | ### Writing (overwrite) | |
| 140 | + | ||
| 141 | + | ```py | |
| 142 | + | file = open("hello.txt", "w") # open in write mode 'w' | |
| 143 | + | file.write("Hello World") | |
| 144 | + | ||
| 145 | + | text_lines = ["First line", "Second line", "Last line"] | |
| 146 | + | file.writelines(text_lines) | |
| 147 | + | ||
| 148 | + | file.close() | |
| 149 | + | ``` | |
| 150 | + | ||
| 151 | + | ### Writing (append) | |
| 152 | + | ||
| 153 | + | ```py | |
| 154 | + | file = open("Hello.txt", "a") # open in append mode | |
| 155 | + | file.write("Hello World again") | |
| 156 | + | file.close() | |
| 157 | + | ``` | |
| 158 | + | ||
| 159 | + | ### Context manager | |
| 160 | + | ||
| 161 | + | ```py | |
| 162 | + | with open("welcome.txt", "r") as file: | |
| 163 | + | # 'file' refers directly to "welcome.txt" | |
| 164 | + | data = file.read() | |
| 165 | + | ||
| 166 | + | # It closes the file automatically at the end of scope, no need for `file.close()`. | |
| 167 | + | ``` | |
| 168 | + | ||
| 169 | + | https://devhints.io/ cheatsheets - Copyright (c) 2021 Rico Sta. Cruz and contributors - MIT license | |
| 170 | + | micro-cheat plugin Copyright 2022 Tero Karvinen https://TeroKarvinen.com/micro - MIT license |
| ... | ... | @@ -0,0 +1,38 @@ | |
| 1 | + | --- | |
| 2 | + | title: Rake | |
| 3 | + | category: Ruby | |
| 4 | + | layout: 2017/sheet | |
| 5 | + | --- | |
| 6 | + | ||
| 7 | + | ### Basic syntax | |
| 8 | + | ||
| 9 | + | ```rb | |
| 10 | + | namespace :foo do | |
| 11 | + | desc "Description" | |
| 12 | + | task :bar do | |
| 13 | + | ... | |
| 14 | + | end | |
| 15 | + | ||
| 16 | + | task :baz => :dependency do | |
| 17 | + | end | |
| 18 | + | ||
| 19 | + | task :baz => [:dep1, :dep2, :dep3] do | |
| 20 | + | end | |
| 21 | + | end | |
| 22 | + | ||
| 23 | + | # rake foo:bar | |
| 24 | + | ``` | |
| 25 | + | ||
| 26 | + | ### Rake task with arguments | |
| 27 | + | ||
| 28 | + | ```rb | |
| 29 | + | desc "Do something" | |
| 30 | + | task :workit, [:id] => :environment do |_, args| | |
| 31 | + | id = args[:id] | |
| 32 | + | end | |
| 33 | + | ||
| 34 | + | # rake workit[234] | |
| 35 | + | ``` | |
| 36 | + | ||
| 37 | + | https://devhints.io/ cheatsheets - Copyright (c) 2021 Rico Sta. Cruz and contributors - MIT license | |
| 38 | + | micro-cheat plugin Copyright 2022 Tero Karvinen https://TeroKarvinen.com/micro - MIT license |
| ... | ... | @@ -0,0 +1,34 @@ | |
| 1 | + | --- | |
| 2 | + | title: Ruby | |
| 3 | + | category: Ruby | |
| 4 | + | tags: [WIP] | |
| 5 | + | layout: 2017/sheet | |
| 6 | + | intro: | | |
| 7 | + | Quick reference to some features of the Ruby programming language. | |
| 8 | + | --- | |
| 9 | + | ||
| 10 | + | ### Reference | |
| 11 | + | ||
| 12 | + | {:.-one-column} | |
| 13 | + | ||
| 14 | + | | Code | Description | | |
| 15 | + | | ----------------------- | --------------------------------------------------------- | | |
| 16 | + | | `$!` | latest error message | | |
| 17 | + | | `$@` | location of error | | |
| 18 | + | | `$_` | string last read by gets | | |
| 19 | + | | `$.` | line number last read by interpreter | | |
| 20 | + | | `$&` | string last matched by regexp | | |
| 21 | + | | `$~` | the last regexp match, as an array of subexpressions | | |
| 22 | + | | `$n` | the nth subexpression in the last match (same as `$~[n]`) | | |
| 23 | + | | `$=` | case-insensitivity flag | | |
| 24 | + | | `$/` | input record separator | | |
| 25 | + | | `$\` | output record separator | | |
| 26 | + | | `$0` | the name of the ruby script file | | |
| 27 | + | | `$*` (or `ARGV`) | the command line arguments | | |
| 28 | + | | `$$` | interpreter's process ID | | |
| 29 | + | | `$?` | exit status of last executed child process | | |
| 30 | + | | `$-i` `$-l` `$-p` `$-v` | Command line switches | | |
| 31 | + | | `$-v` (or `$VERBOSE`) | verbose mode | | |
| 32 | + | ||
| 33 | + | https://devhints.io/ cheatsheets - Copyright (c) 2021 Rico Sta. Cruz and contributors - MIT license | |
| 34 | + | micro-cheat plugin Copyright 2022 Tero Karvinen https://TeroKarvinen.com/micro - MIT license |
| ... | ... | @@ -0,0 +1,59 @@ | |
| 1 | + | --- | |
| 2 | + | title: sed | |
| 3 | + | category: CLI | |
| 4 | + | layout: 2017/sheet | |
| 5 | + | intro: | | |
| 6 | + | Here's some hints on using sed. | |
| 7 | + | --- | |
| 8 | + | ||
| 9 | + | ## In place replacements | |
| 10 | + | ||
| 11 | + | ### In-place replacement (GNU) | |
| 12 | + | ||
| 13 | + | ```bash | |
| 14 | + | sed -i -e 's/foo/bar/' example.md | |
| 15 | + | ``` | |
| 16 | + | ||
| 17 | + | In GNU sed: use `-i` without arg. | |
| 18 | + | ||
| 19 | + | #### In-place replacement (BSD) | |
| 20 | + | ||
| 21 | + | ```bash | |
| 22 | + | sed -i '' -e 's/foo/bar/' example.md | |
| 23 | + | ``` | |
| 24 | + | ||
| 25 | + | In OSX, `-i ''` is required. | |
| 26 | + | ||
| 27 | + | ## File regions | |
| 28 | + | {:.-three-column} | |
| 29 | + | ||
| 30 | + | ### Print until a certain line is met | |
| 31 | + | ||
| 32 | + | ```bash | |
| 33 | + | sed '/begin api/q' | |
| 34 | + | ``` | |
| 35 | + | ||
| 36 | + | ### Print until a certain line is met, but not that line | |
| 37 | + | ||
| 38 | + | ```bash | |
| 39 | + | sed '/^# begin/,$d' | |
| 40 | + | ``` | |
| 41 | + | ||
| 42 | + | ### Print everything after a given line | |
| 43 | + | ||
| 44 | + | ```bash | |
| 45 | + | sed -n '/end api/,$p' | |
| 46 | + | ``` | |
| 47 | + | ||
| 48 | + | Print after a given line is found. | |
| 49 | + | ||
| 50 | + | ### Print everything except matching | |
| 51 | + | ||
| 52 | + | ```bash | |
| 53 | + | sed -n '/regex/!p' | |
| 54 | + | ``` | |
| 55 | + | ||
| 56 | + | Print everything except lines matching regex. Useful for printing files with comments. | |
| 57 | + | ||
| 58 | + | https://devhints.io/ cheatsheets - Copyright (c) 2021 Rico Sta. Cruz and contributors - MIT license | |
| 59 | + | micro-cheat plugin Copyright 2022 Tero Karvinen https://TeroKarvinen.com/micro - MIT license |
| ... | ... | @@ -0,0 +1,843 @@ | |
| 1 | + | --- | |
| 2 | + | title: Bash scripting | |
| 3 | + | category: CLI | |
| 4 | + | layout: 2017/sheet | |
| 5 | + | tags: [Featured] | |
| 6 | + | updated: 2020-07-05 | |
| 7 | + | keywords: | |
| 8 | + | - Variables | |
| 9 | + | - Functions | |
| 10 | + | - Interpolation | |
| 11 | + | - Brace expansions | |
| 12 | + | - Loops | |
| 13 | + | - Conditional execution | |
| 14 | + | - Command substitution | |
| 15 | + | --- | |
| 16 | + | ||
| 17 | + | Getting started | |
| 18 | + | --------------- | |
| 19 | + | {: .-three-column} | |
| 20 | + | ||
| 21 | + | ### Introduction | |
| 22 | + | {: .-intro} | |
| 23 | + | ||
| 24 | + | This is a quick reference to getting started with Bash scripting. | |
| 25 | + | ||
| 26 | + | - [Learn bash in y minutes](https://learnxinyminutes.com/docs/bash/) _(learnxinyminutes.com)_ | |
| 27 | + | - [Bash Guide](http://mywiki.wooledge.org/BashGuide) _(mywiki.wooledge.org)_ | |
| 28 | + | - [Bash Hackers Wiki](https://wiki.bash-hackers.org) _(wiki.bash-hackers.org)_ | |
| 29 | + | ||
| 30 | + | ### Example | |
| 31 | + | ||
| 32 | + | ```bash | |
| 33 | + | #!/usr/bin/env bash | |
| 34 | + | ||
| 35 | + | name="John" | |
| 36 | + | echo "Hello $name!" | |
| 37 | + | ``` | |
| 38 | + | ||
| 39 | + | ### Variables | |
| 40 | + | ||
| 41 | + | ```bash | |
| 42 | + | name="John" | |
| 43 | + | echo $name # see below | |
| 44 | + | echo "$name" | |
| 45 | + | echo "${name}!" | |
| 46 | + | ``` | |
| 47 | + | Generally quote your variables unless they contain wildcards to expand or command fragments. | |
| 48 | + | ||
| 49 | + | ```bash | |
| 50 | + | wildcard="*.txt" | |
| 51 | + | option="iv" | |
| 52 | + | cp -$options $wildcard /tmp | |
| 53 | + | ``` | |
| 54 | + | ||
| 55 | + | ### String quotes | |
| 56 | + | ||
| 57 | + | ```bash | |
| 58 | + | name="John" | |
| 59 | + | echo "Hi $name" #=> Hi John | |
| 60 | + | echo 'Hi $name' #=> Hi $name | |
| 61 | + | ``` | |
| 62 | + | ||
| 63 | + | ### Shell execution | |
| 64 | + | ||
| 65 | + | ```bash | |
| 66 | + | echo "I'm in $(pwd)" | |
| 67 | + | echo "I'm in `pwd`" # obsolescent | |
| 68 | + | # Same | |
| 69 | + | ``` | |
| 70 | + | ||
| 71 | + | See [Command substitution](http://wiki.bash-hackers.org/syntax/expansion/cmdsubst) | |
| 72 | + | ||
| 73 | + | ### Conditional execution | |
| 74 | + | ||
| 75 | + | ```bash | |
| 76 | + | git commit && git push | |
| 77 | + | git commit || echo "Commit failed" | |
| 78 | + | ``` | |
| 79 | + | ||
| 80 | + | ### Functions | |
| 81 | + | {: id='functions-example'} | |
| 82 | + | ||
| 83 | + | ```bash | |
| 84 | + | get_name() { | |
| 85 | + | echo "John" | |
| 86 | + | } | |
| 87 | + | ||
| 88 | + | echo "You are $(get_name)" | |
| 89 | + | ``` | |
| 90 | + | ||
| 91 | + | See: [Functions](#functions) | |
| 92 | + | ||
| 93 | + | ### Conditionals | |
| 94 | + | {: id='conditionals-example'} | |
| 95 | + | ||
| 96 | + | ```bash | |
| 97 | + | if [[ -z "$string" ]]; then | |
| 98 | + | echo "String is empty" | |
| 99 | + | elif [[ -n "$string" ]]; then | |
| 100 | + | echo "String is not empty" | |
| 101 | + | fi | |
| 102 | + | ``` | |
| 103 | + | ||
| 104 | + | See: [Conditionals](#conditionals) | |
| 105 | + | ||
| 106 | + | ### Strict mode | |
| 107 | + | ||
| 108 | + | ```bash | |
| 109 | + | set -euo pipefail | |
| 110 | + | IFS=$'\n\t' | |
| 111 | + | ``` | |
| 112 | + | ||
| 113 | + | See: [Unofficial bash strict mode](http://redsymbol.net/articles/unofficial-bash-strict-mode/) | |
| 114 | + | ||
| 115 | + | ### Brace expansion | |
| 116 | + | ||
| 117 | + | ```bash | |
| 118 | + | echo {A,B}.js | |
| 119 | + | ``` | |
| 120 | + | ||
| 121 | + | | Expression | Description | | |
| 122 | + | | ---------- | ------------------- | | |
| 123 | + | | `{A,B}` | Same as `A B` | | |
| 124 | + | | `{A,B}.js` | Same as `A.js B.js` | | |
| 125 | + | | `{1..5}` | Same as `1 2 3 4 5` | | |
| 126 | + | ||
| 127 | + | See: [Brace expansion](http://wiki.bash-hackers.org/syntax/expansion/brace) | |
| 128 | + | ||
| 129 | + | ||
| 130 | + | Parameter expansions | |
| 131 | + | -------------------- | |
| 132 | + | {: .-three-column} | |
| 133 | + | ||
| 134 | + | ### Basics | |
| 135 | + | ||
| 136 | + | ```bash | |
| 137 | + | name="John" | |
| 138 | + | echo "${name}" | |
| 139 | + | echo "${name/J/j}" #=> "john" (substitution) | |
| 140 | + | echo "${name:0:2}" #=> "Jo" (slicing) | |
| 141 | + | echo "${name::2}" #=> "Jo" (slicing) | |
| 142 | + | echo "${name::-1}" #=> "Joh" (slicing) | |
| 143 | + | echo "${name:(-1)}" #=> "n" (slicing from right) | |
| 144 | + | echo "${name:(-2):1}" #=> "h" (slicing from right) | |
| 145 | + | echo "${food:-Cake}" #=> $food or "Cake" | |
| 146 | + | ``` | |
| 147 | + | ||
| 148 | + | ```bash | |
| 149 | + | length=2 | |
| 150 | + | echo "${name:0:length}" #=> "Jo" | |
| 151 | + | ``` | |
| 152 | + | ||
| 153 | + | See: [Parameter expansion](http://wiki.bash-hackers.org/syntax/pe) | |
| 154 | + | ||
| 155 | + | ```bash | |
| 156 | + | str="/path/to/foo.cpp" | |
| 157 | + | echo "${str%.cpp}" # /path/to/foo | |
| 158 | + | echo "${str%.cpp}.o" # /path/to/foo.o | |
| 159 | + | echo "${str%/*}" # /path/to | |
| 160 | + | ||
| 161 | + | echo "${str##*.}" # cpp (extension) | |
| 162 | + | echo "${str##*/}" # foo.cpp (basepath) | |
| 163 | + | ||
| 164 | + | echo "${str#*/}" # path/to/foo.cpp | |
| 165 | + | echo "${str##*/}" # foo.cpp | |
| 166 | + | ||
| 167 | + | echo "${str/foo/bar}" # /path/to/bar.cpp | |
| 168 | + | ``` | |
| 169 | + | ||
| 170 | + | ```bash | |
| 171 | + | str="Hello world" | |
| 172 | + | echo "${str:6:5}" # "world" | |
| 173 | + | echo "${str: -5:5}" # "world" | |
| 174 | + | ``` | |
| 175 | + | ||
| 176 | + | ```bash | |
| 177 | + | src="/path/to/foo.cpp" | |
| 178 | + | base=${src##*/} #=> "foo.cpp" (basepath) | |
| 179 | + | dir=${src%$base} #=> "/path/to/" (dirpath) | |
| 180 | + | ``` | |
| 181 | + | ||
| 182 | + | ### Substitution | |
| 183 | + | ||
| 184 | + | | Code | Description | | |
| 185 | + | | ----------------- | ------------------- | | |
| 186 | + | | `${foo%suffix}` | Remove suffix | | |
| 187 | + | | `${foo#prefix}` | Remove prefix | | |
| 188 | + | | --- | --- | | |
| 189 | + | | `${foo%%suffix}` | Remove long suffix | | |
| 190 | + | | `${foo##prefix}` | Remove long prefix | | |
| 191 | + | | --- | --- | | |
| 192 | + | | `${foo/from/to}` | Replace first match | | |
| 193 | + | | `${foo//from/to}` | Replace all | | |
| 194 | + | | --- | --- | | |
| 195 | + | | `${foo/%from/to}` | Replace suffix | | |
| 196 | + | | `${foo/#from/to}` | Replace prefix | | |
| 197 | + | ||
| 198 | + | ### Comments | |
| 199 | + | ||
| 200 | + | ```bash | |
| 201 | + | # Single line comment | |
| 202 | + | ``` | |
| 203 | + | ||
| 204 | + | ```bash | |
| 205 | + | : ' | |
| 206 | + | This is a | |
| 207 | + | multi line | |
| 208 | + | comment | |
| 209 | + | ' | |
| 210 | + | ``` | |
| 211 | + | ||
| 212 | + | ### Substrings | |
| 213 | + | ||
| 214 | + | | Expression | Description | | |
| 215 | + | | --------------- | ------------------------------ | | |
| 216 | + | | `${foo:0:3}` | Substring _(position, length)_ | | |
| 217 | + | | `${foo:(-3):3}` | Substring from the right | | |
| 218 | + | ||
| 219 | + | ### Length | |
| 220 | + | ||
| 221 | + | | Expression | Description | | |
| 222 | + | | ---------- | ---------------- | | |
| 223 | + | | `${#foo}` | Length of `$foo` | | |
| 224 | + | ||
| 225 | + | ### Manipulation | |
| 226 | + | ||
| 227 | + | ```bash | |
| 228 | + | str="HELLO WORLD!" | |
| 229 | + | echo "${str,}" #=> "hELLO WORLD!" (lowercase 1st letter) | |
| 230 | + | echo "${str,,}" #=> "hello world!" (all lowercase) | |
| 231 | + | ||
| 232 | + | str="hello world!" | |
| 233 | + | echo "${str^}" #=> "Hello world!" (uppercase 1st letter) | |
| 234 | + | echo "${str^^}" #=> "HELLO WORLD!" (all uppercase) | |
| 235 | + | ``` | |
| 236 | + | ||
| 237 | + | ### Default values | |
| 238 | + | ||
| 239 | + | | Expression | Description | | |
| 240 | + | | ----------------- | -------------------------------------------------------- | | |
| 241 | + | | `${foo:-val}` | `$foo`, or `val` if unset (or null) | | |
| 242 | + | | `${foo:=val}` | Set `$foo` to `val` if unset (or null) | | |
| 243 | + | | `${foo:+val}` | `val` if `$foo` is set (and not null) | | |
| 244 | + | | `${foo:?message}` | Show error message and exit if `$foo` is unset (or null) | | |
| 245 | + | ||
| 246 | + | Omitting the `:` removes the (non)nullity checks, e.g. `${foo-val}` expands to `val` if unset otherwise `$foo`. | |
| 247 | + | ||
| 248 | + | Loops | |
| 249 | + | ----- | |
| 250 | + | {: .-three-column} | |
| 251 | + | ||
| 252 | + | ### Basic for loop | |
| 253 | + | ||
| 254 | + | ```bash | |
| 255 | + | for i in /etc/rc.*; do | |
| 256 | + | echo "$i" | |
| 257 | + | done | |
| 258 | + | ``` | |
| 259 | + | ||
| 260 | + | ### C-like for loop | |
| 261 | + | ||
| 262 | + | ```bash | |
| 263 | + | for ((i = 0 ; i < 100 ; i++)); do | |
| 264 | + | echo "$i" | |
| 265 | + | done | |
| 266 | + | ``` | |
| 267 | + | ||
| 268 | + | ### Ranges | |
| 269 | + | ||
| 270 | + | ```bash | |
| 271 | + | for i in {1..5}; do | |
| 272 | + | echo "Welcome $i" | |
| 273 | + | done | |
| 274 | + | ``` | |
| 275 | + | ||
| 276 | + | #### With step size | |
| 277 | + | ||
| 278 | + | ```bash | |
| 279 | + | for i in {5..50..5}; do | |
| 280 | + | echo "Welcome $i" | |
| 281 | + | done | |
| 282 | + | ``` | |
| 283 | + | ||
| 284 | + | ### Reading lines | |
| 285 | + | ||
| 286 | + | ```bash | |
| 287 | + | while read -r line; do | |
| 288 | + | echo "$line" | |
| 289 | + | done <file.txt | |
| 290 | + | ``` | |
| 291 | + | ||
| 292 | + | ### Forever | |
| 293 | + | ||
| 294 | + | ```bash | |
| 295 | + | while true; do | |
| 296 | + | ··· | |
| 297 | + | done | |
| 298 | + | ``` | |
| 299 | + | ||
| 300 | + | Functions | |
| 301 | + | --------- | |
| 302 | + | {: .-three-column} | |
| 303 | + | ||
| 304 | + | ### Defining functions | |
| 305 | + | ||
| 306 | + | ```bash | |
| 307 | + | myfunc() { | |
| 308 | + | echo "hello $1" | |
| 309 | + | } | |
| 310 | + | ``` | |
| 311 | + | ||
| 312 | + | ```bash | |
| 313 | + | # Same as above (alternate syntax) | |
| 314 | + | function myfunc() { | |
| 315 | + | echo "hello $1" | |
| 316 | + | } | |
| 317 | + | ``` | |
| 318 | + | ||
| 319 | + | ```bash | |
| 320 | + | myfunc "John" | |
| 321 | + | ``` | |
| 322 | + | ||
| 323 | + | ### Returning values | |
| 324 | + | ||
| 325 | + | ```bash | |
| 326 | + | myfunc() { | |
| 327 | + | local myresult='some value' | |
| 328 | + | echo "$myresult" | |
| 329 | + | } | |
| 330 | + | ``` | |
| 331 | + | ||
| 332 | + | ```bash | |
| 333 | + | result=$(myfunc) | |
| 334 | + | ``` | |
| 335 | + | ||
| 336 | + | ### Raising errors | |
| 337 | + | ||
| 338 | + | ```bash | |
| 339 | + | myfunc() { | |
| 340 | + | return 1 | |
| 341 | + | } | |
| 342 | + | ``` | |
| 343 | + | ||
| 344 | + | ```bash | |
| 345 | + | if myfunc; then | |
| 346 | + | echo "success" | |
| 347 | + | else | |
| 348 | + | echo "failure" | |
| 349 | + | fi | |
| 350 | + | ``` | |
| 351 | + | ||
| 352 | + | ### Arguments | |
| 353 | + | ||
| 354 | + | | Expression | Description | | |
| 355 | + | | --- | --- | | |
| 356 | + | | `$#` | Number of arguments | | |
| 357 | + | | `$*` | All positional arguments (as a single word) | | |
| 358 | + | | `$@` | All positional arguments (as separate strings) | | |
| 359 | + | | `$1` | First argument | | |
| 360 | + | | `$_` | Last argument of the previous command | | |
| 361 | + | ||
| 362 | + | **Note**: `$@` and `$*` must be quoted in order to perform as described. | |
| 363 | + | Otherwise, they do exactly the same thing (arguments as separate strings). | |
| 364 | + | ||
| 365 | + | See [Special parameters](http://wiki.bash-hackers.org/syntax/shellvars#special_parameters_and_shell_variables). | |
| 366 | + | ||
| 367 | + | Conditionals | |
| 368 | + | ------------ | |
| 369 | + | {: .-three-column} | |
| 370 | + | ||
| 371 | + | ### Conditions | |
| 372 | + | ||
| 373 | + | Note that `[[` is actually a command/program that returns either `0` (true) or `1` (false). Any program that obeys the same logic (like all base utils, such as `grep(1)` or `ping(1)`) can be used as condition, see examples. | |
| 374 | + | ||
| 375 | + | | Condition | Description | | |
| 376 | + | | --- | --- | | |
| 377 | + | | `[[ -z STRING ]]` | Empty string | | |
| 378 | + | | `[[ -n STRING ]]` | Not empty string | | |
| 379 | + | | `[[ STRING == STRING ]]` | Equal | | |
| 380 | + | | `[[ STRING != STRING ]]` | Not Equal | | |
| 381 | + | | --- | --- | | |
| 382 | + | | `[[ NUM -eq NUM ]]` | Equal | | |
| 383 | + | | `[[ NUM -ne NUM ]]` | Not equal | | |
| 384 | + | | `[[ NUM -lt NUM ]]` | Less than | | |
| 385 | + | | `[[ NUM -le NUM ]]` | Less than or equal | | |
| 386 | + | | `[[ NUM -gt NUM ]]` | Greater than | | |
| 387 | + | | `[[ NUM -ge NUM ]]` | Greater than or equal | | |
| 388 | + | | --- | --- | | |
| 389 | + | | `[[ STRING =~ STRING ]]` | Regexp | | |
| 390 | + | | --- | --- | | |
| 391 | + | | `(( NUM < NUM ))` | Numeric conditions | | |
| 392 | + | ||
| 393 | + | #### More conditions | |
| 394 | + | ||
| 395 | + | | Condition | Description | | |
| 396 | + | | -------------------- | ------------------------ | | |
| 397 | + | | `[[ -o noclobber ]]` | If OPTIONNAME is enabled | | |
| 398 | + | | --- | --- | | |
| 399 | + | | `[[ ! EXPR ]]` | Not | | |
| 400 | + | | `[[ X && Y ]]` | And | | |
| 401 | + | | `[[ X || Y ]]` | Or | | |
| 402 | + | ||
| 403 | + | ### File conditions | |
| 404 | + | ||
| 405 | + | | Condition | Description | | |
| 406 | + | | --- | --- | | |
| 407 | + | | `[[ -e FILE ]]` | Exists | | |
| 408 | + | | `[[ -r FILE ]]` | Readable | | |
| 409 | + | | `[[ -h FILE ]]` | Symlink | | |
| 410 | + | | `[[ -d FILE ]]` | Directory | | |
| 411 | + | | `[[ -w FILE ]]` | Writable | | |
| 412 | + | | `[[ -s FILE ]]` | Size is > 0 bytes | | |
| 413 | + | | `[[ -f FILE ]]` | File | | |
| 414 | + | | `[[ -x FILE ]]` | Executable | | |
| 415 | + | | --- | --- | | |
| 416 | + | | `[[ FILE1 -nt FILE2 ]]` | 1 is more recent than 2 | | |
| 417 | + | | `[[ FILE1 -ot FILE2 ]]` | 2 is more recent than 1 | | |
| 418 | + | | `[[ FILE1 -ef FILE2 ]]` | Same files | | |
| 419 | + | ||
| 420 | + | ### Example | |
| 421 | + | ||
| 422 | + | ```bash | |
| 423 | + | # String | |
| 424 | + | if [[ -z "$string" ]]; then | |
| 425 | + | echo "String is empty" | |
| 426 | + | elif [[ -n "$string" ]]; then | |
| 427 | + | echo "String is not empty" | |
| 428 | + | else | |
| 429 | + | echo "This never happens" | |
| 430 | + | fi | |
| 431 | + | ``` | |
| 432 | + | ||
| 433 | + | ```bash | |
| 434 | + | # Combinations | |
| 435 | + | if [[ X && Y ]]; then | |
| 436 | + | ... | |
| 437 | + | fi | |
| 438 | + | ``` | |
| 439 | + | ||
| 440 | + | ```bash | |
| 441 | + | # Equal | |
| 442 | + | if [[ "$A" == "$B" ]] | |
| 443 | + | ``` | |
| 444 | + | ||
| 445 | + | ```bash | |
| 446 | + | # Regex | |
| 447 | + | if [[ "A" =~ . ]] | |
| 448 | + | ``` | |
| 449 | + | ||
| 450 | + | ```bash | |
| 451 | + | if (( $a < $b )); then | |
| 452 | + | echo "$a is smaller than $b" | |
| 453 | + | fi | |
| 454 | + | ``` | |
| 455 | + | ||
| 456 | + | ```bash | |
| 457 | + | if [[ -e "file.txt" ]]; then | |
| 458 | + | echo "file exists" | |
| 459 | + | fi | |
| 460 | + | ``` | |
| 461 | + | ||
| 462 | + | Arrays | |
| 463 | + | ------ | |
| 464 | + | ||
| 465 | + | ### Defining arrays | |
| 466 | + | ||
| 467 | + | ```bash | |
| 468 | + | Fruits=('Apple' 'Banana' 'Orange') | |
| 469 | + | ``` | |
| 470 | + | ||
| 471 | + | ```bash | |
| 472 | + | Fruits[0]="Apple" | |
| 473 | + | Fruits[1]="Banana" | |
| 474 | + | Fruits[2]="Orange" | |
| 475 | + | ``` | |
| 476 | + | ||
| 477 | + | ### Working with arrays | |
| 478 | + | ||
| 479 | + | ```bash | |
| 480 | + | echo "${Fruits[0]}" # Element #0 | |
| 481 | + | echo "${Fruits[-1]}" # Last element | |
| 482 | + | echo "${Fruits[@]}" # All elements, space-separated | |
| 483 | + | echo "${#Fruits[@]}" # Number of elements | |
| 484 | + | echo "${#Fruits}" # String length of the 1st element | |
| 485 | + | echo "${#Fruits[3]}" # String length of the Nth element | |
| 486 | + | echo "${Fruits[@]:3:2}" # Range (from position 3, length 2) | |
| 487 | + | echo "${!Fruits[@]}" # Keys of all elements, space-separated | |
| 488 | + | ``` | |
| 489 | + | ||
| 490 | + | ### Operations | |
| 491 | + | ||
| 492 | + | ```bash | |
| 493 | + | Fruits=("${Fruits[@]}" "Watermelon") # Push | |
| 494 | + | Fruits+=('Watermelon') # Also Push | |
| 495 | + | Fruits=( "${Fruits[@]/Ap*/}" ) # Remove by regex match | |
| 496 | + | unset Fruits[2] # Remove one item | |
| 497 | + | Fruits=("${Fruits[@]}") # Duplicate | |
| 498 | + | Fruits=("${Fruits[@]}" "${Veggies[@]}") # Concatenate | |
| 499 | + | lines=(`cat "logfile"`) # Read from file | |
| 500 | + | ``` | |
| 501 | + | ||
| 502 | + | ### Iteration | |
| 503 | + | ||
| 504 | + | ```bash | |
| 505 | + | for i in "${arrayName[@]}"; do | |
| 506 | + | echo "$i" | |
| 507 | + | done | |
| 508 | + | ``` | |
| 509 | + | ||
| 510 | + | Dictionaries | |
| 511 | + | ------------ | |
| 512 | + | {: .-three-column} | |
| 513 | + | ||
| 514 | + | ### Defining | |
| 515 | + | ||
| 516 | + | ```bash | |
| 517 | + | declare -A sounds | |
| 518 | + | ``` | |
| 519 | + | ||
| 520 | + | ```bash | |
| 521 | + | sounds[dog]="bark" | |
| 522 | + | sounds[cow]="moo" | |
| 523 | + | sounds[bird]="tweet" | |
| 524 | + | sounds[wolf]="howl" | |
| 525 | + | ``` | |
| 526 | + | ||
| 527 | + | Declares `sound` as a Dictionary object (aka associative array). | |
| 528 | + | ||
| 529 | + | ### Working with dictionaries | |
| 530 | + | ||
| 531 | + | ```bash | |
| 532 | + | echo "${sounds[dog]}" # Dog's sound | |
| 533 | + | echo "${sounds[@]}" # All values | |
| 534 | + | echo "${!sounds[@]}" # All keys | |
| 535 | + | echo "${#sounds[@]}" # Number of elements | |
| 536 | + | unset sounds[dog] # Delete dog | |
| 537 | + | ``` | |
| 538 | + | ||
| 539 | + | ### Iteration | |
| 540 | + | ||
| 541 | + | #### Iterate over values | |
| 542 | + | ||
| 543 | + | ```bash | |
| 544 | + | for val in "${sounds[@]}"; do | |
| 545 | + | echo "$val" | |
| 546 | + | done | |
| 547 | + | ``` | |
| 548 | + | ||
| 549 | + | #### Iterate over keys | |
| 550 | + | ||
| 551 | + | ```bash | |
| 552 | + | for key in "${!sounds[@]}"; do | |
| 553 | + | echo "$key" | |
| 554 | + | done | |
| 555 | + | ``` | |
| 556 | + | ||
| 557 | + | Options | |
| 558 | + | ------- | |
| 559 | + | ||
| 560 | + | ### Options | |
| 561 | + | ||
| 562 | + | ```bash | |
| 563 | + | set -o noclobber # Avoid overlay files (echo "hi" > foo) | |
| 564 | + | set -o errexit # Used to exit upon error, avoiding cascading errors | |
| 565 | + | set -o pipefail # Unveils hidden failures | |
| 566 | + | set -o nounset # Exposes unset variables | |
| 567 | + | ``` | |
| 568 | + | ||
| 569 | + | ### Glob options | |
| 570 | + | ||
| 571 | + | ```bash | |
| 572 | + | shopt -s nullglob # Non-matching globs are removed ('*.foo' => '') | |
| 573 | + | shopt -s failglob # Non-matching globs throw errors | |
| 574 | + | shopt -s nocaseglob # Case insensitive globs | |
| 575 | + | shopt -s dotglob # Wildcards match dotfiles ("*.sh" => ".foo.sh") | |
| 576 | + | shopt -s globstar # Allow ** for recursive matches ('lib/**/*.rb' => 'lib/a/b/c.rb') | |
| 577 | + | ``` | |
| 578 | + | ||
| 579 | + | Set `GLOBIGNORE` as a colon-separated list of patterns to be removed from glob | |
| 580 | + | matches. | |
| 581 | + | ||
| 582 | + | History | |
| 583 | + | ------- | |
| 584 | + | ||
| 585 | + | ### Commands | |
| 586 | + | ||
| 587 | + | | Command | Description | | |
| 588 | + | | --------------------- | ----------------------------------------- | | |
| 589 | + | | `history` | Show history | | |
| 590 | + | | `shopt -s histverify` | Don't execute expanded result immediately | | |
| 591 | + | ||
| 592 | + | ### Expansions | |
| 593 | + | ||
| 594 | + | | Expression | Description | | |
| 595 | + | | ------------ | ---------------------------------------------------- | | |
| 596 | + | | `!$` | Expand last parameter of most recent command | | |
| 597 | + | | `!*` | Expand all parameters of most recent command | | |
| 598 | + | | `!-n` | Expand `n`th most recent command | | |
| 599 | + | | `!n` | Expand `n`th command in history | | |
| 600 | + | | `!<command>` | Expand most recent invocation of command `<command>` | | |
| 601 | + | ||
| 602 | + | ### Operations | |
| 603 | + | ||
| 604 | + | | Code | Description | | |
| 605 | + | | -------------------- | --------------------------------------------------------------------- | | |
| 606 | + | | `!!` | Execute last command again | | |
| 607 | + | | `!!:s/<FROM>/<TO>/` | Replace first occurrence of `<FROM>` to `<TO>` in most recent command | | |
| 608 | + | | `!!:gs/<FROM>/<TO>/` | Replace all occurrences of `<FROM>` to `<TO>` in most recent command | | |
| 609 | + | | `!$:t` | Expand only basename from last parameter of most recent command | | |
| 610 | + | | `!$:h` | Expand only directory from last parameter of most recent command | | |
| 611 | + | ||
| 612 | + | `!!` and `!$` can be replaced with any valid expansion. | |
| 613 | + | ||
| 614 | + | ### Slices | |
| 615 | + | ||
| 616 | + | | Code | Description | | |
| 617 | + | | -------- | ---------------------------------------------------------------------------------------- | | |
| 618 | + | | `!!:n` | Expand only `n`th token from most recent command (command is `0`; first argument is `1`) | | |
| 619 | + | | `!^` | Expand first argument from most recent command | | |
| 620 | + | | `!$` | Expand last token from most recent command | | |
| 621 | + | | `!!:n-m` | Expand range of tokens from most recent command | | |
| 622 | + | | `!!:n-$` | Expand `n`th token to last from most recent command | | |
| 623 | + | ||
| 624 | + | `!!` can be replaced with any valid expansion i.e. `!cat`, `!-2`, `!42`, etc. | |
| 625 | + | ||
| 626 | + | ||
| 627 | + | Miscellaneous | |
| 628 | + | ------------- | |
| 629 | + | ||
| 630 | + | ### Numeric calculations | |
| 631 | + | ||
| 632 | + | ```bash | |
| 633 | + | $((a + 200)) # Add 200 to $a | |
| 634 | + | ``` | |
| 635 | + | ||
| 636 | + | ```bash | |
| 637 | + | $(($RANDOM%200)) # Random number 0..199 | |
| 638 | + | ``` | |
| 639 | + | ||
| 640 | + | ### Subshells | |
| 641 | + | ||
| 642 | + | ```bash | |
| 643 | + | (cd somedir; echo "I'm now in $PWD") | |
| 644 | + | pwd # still in first directory | |
| 645 | + | ``` | |
| 646 | + | ||
| 647 | + | ### Redirection | |
| 648 | + | ||
| 649 | + | ```bash | |
| 650 | + | python hello.py > output.txt # stdout to (file) | |
| 651 | + | python hello.py >> output.txt # stdout to (file), append | |
| 652 | + | python hello.py 2> error.log # stderr to (file) | |
| 653 | + | python hello.py 2>&1 # stderr to stdout | |
| 654 | + | python hello.py 2>/dev/null # stderr to (null) | |
| 655 | + | python hello.py >output.txt 2>&1 # stdout and stderr to (file), equivalent to &> | |
| 656 | + | python hello.py &>/dev/null # stdout and stderr to (null) | |
| 657 | + | echo "$0: warning: too many users" >&2 # print diagnostic message to stderr | |
| 658 | + | ``` | |
| 659 | + | ||
| 660 | + | ```bash | |
| 661 | + | python hello.py < foo.txt # feed foo.txt to stdin for python | |
| 662 | + | diff <(ls -r) <(ls) # Compare two stdout without files | |
| 663 | + | ``` | |
| 664 | + | ||
| 665 | + | ### Inspecting commands | |
| 666 | + | ||
| 667 | + | ```bash | |
| 668 | + | command -V cd | |
| 669 | + | #=> "cd is a function/alias/whatever" | |
| 670 | + | ``` | |
| 671 | + | ||
| 672 | + | ### Trap errors | |
| 673 | + | ||
| 674 | + | ```bash | |
| 675 | + | trap 'echo Error at about $LINENO' ERR | |
| 676 | + | ``` | |
| 677 | + | ||
| 678 | + | or | |
| 679 | + | ||
| 680 | + | ```bash | |
| 681 | + | traperr() { | |
| 682 | + | echo "ERROR: ${BASH_SOURCE[1]} at about ${BASH_LINENO[0]}" | |
| 683 | + | } | |
| 684 | + | ||
| 685 | + | set -o errtrace | |
| 686 | + | trap traperr ERR | |
| 687 | + | ``` | |
| 688 | + | ||
| 689 | + | ### Case/switch | |
| 690 | + | ||
| 691 | + | ```bash | |
| 692 | + | case "$1" in | |
| 693 | + | start | up) | |
| 694 | + | vagrant up | |
| 695 | + | ;; | |
| 696 | + | ||
| 697 | + | *) | |
| 698 | + | echo "Usage: $0 {start|stop|ssh}" | |
| 699 | + | ;; | |
| 700 | + | esac | |
| 701 | + | ``` | |
| 702 | + | ||
| 703 | + | ### Source relative | |
| 704 | + | ||
| 705 | + | ```bash | |
| 706 | + | source "${0%/*}/../share/foo.sh" | |
| 707 | + | ``` | |
| 708 | + | ||
| 709 | + | ### printf | |
| 710 | + | ||
| 711 | + | ```bash | |
| 712 | + | printf "Hello %s, I'm %s" Sven Olga | |
| 713 | + | #=> "Hello Sven, I'm Olga | |
| 714 | + | ||
| 715 | + | printf "1 + 1 = %d" 2 | |
| 716 | + | #=> "1 + 1 = 2" | |
| 717 | + | ||
| 718 | + | printf "This is how you print a float: %f" 2 | |
| 719 | + | #=> "This is how you print a float: 2.000000" | |
| 720 | + | ||
| 721 | + | printf '%s\n' '#!/bin/bash' 'echo hello' >file | |
| 722 | + | # format string is applied to each group of arguments | |
| 723 | + | printf '%i+%i=%i\n' 1 2 3 4 5 9 | |
| 724 | + | ``` | |
| 725 | + | ||
| 726 | + | ### Transform strings | |
| 727 | + | ||
| 728 | + | | Command option | Description | | |
| 729 | + | | ------------------ | --------------------------------------------------- | | |
| 730 | + | | `-c` | Operations apply to characters not in the given set | | |
| 731 | + | | `-d` | Delete characters | | |
| 732 | + | | `-s` | Replaces repeated characters with single occurrence | | |
| 733 | + | | `-t` | Truncates | | |
| 734 | + | | `[:upper:]` | All upper case letters | | |
| 735 | + | | `[:lower:]` | All lower case letters | | |
| 736 | + | | `[:digit:]` | All digits | | |
| 737 | + | | `[:space:]` | All whitespace | | |
| 738 | + | | `[:alpha:]` | All letters | | |
| 739 | + | | `[:alnum:]` | All letters and digits | | |
| 740 | + | ||
| 741 | + | #### Example | |
| 742 | + | ||
| 743 | + | ```bash | |
| 744 | + | echo "Welcome To Devhints" | tr '[:lower:]' '[:upper:]' | |
| 745 | + | WELCOME TO DEVHINTS | |
| 746 | + | ``` | |
| 747 | + | ||
| 748 | + | ### Directory of script | |
| 749 | + | ||
| 750 | + | ```bash | |
| 751 | + | dir=${0%/*} | |
| 752 | + | ``` | |
| 753 | + | ||
| 754 | + | ### Getting options | |
| 755 | + | ||
| 756 | + | ```bash | |
| 757 | + | while [[ "$1" =~ ^- && ! "$1" == "--" ]]; do case $1 in | |
| 758 | + | -V | --version ) | |
| 759 | + | echo "$version" | |
| 760 | + | exit | |
| 761 | + | ;; | |
| 762 | + | -s | --string ) | |
| 763 | + | shift; string=$1 | |
| 764 | + | ;; | |
| 765 | + | -f | --flag ) | |
| 766 | + | flag=1 | |
| 767 | + | ;; | |
| 768 | + | esac; shift; done | |
| 769 | + | if [[ "$1" == '--' ]]; then shift; fi | |
| 770 | + | ``` | |
| 771 | + | ||
| 772 | + | ### Heredoc | |
| 773 | + | ||
| 774 | + | ```sh | |
| 775 | + | cat <<END | |
| 776 | + | hello world | |
| 777 | + | END | |
| 778 | + | ``` | |
| 779 | + | ||
| 780 | + | ### Reading input | |
| 781 | + | ||
| 782 | + | ```bash | |
| 783 | + | echo -n "Proceed? [y/n]: " | |
| 784 | + | read -r ans | |
| 785 | + | echo "$ans" | |
| 786 | + | ``` | |
| 787 | + | ||
| 788 | + | The `-r` option disables a peculiar legacy behavior with backslashes. | |
| 789 | + | ||
| 790 | + | ```bash | |
| 791 | + | read -n 1 ans # Just one character | |
| 792 | + | ``` | |
| 793 | + | ||
| 794 | + | ### Special variables | |
| 795 | + | ||
| 796 | + | | Expression | Description | | |
| 797 | + | | ------------------ | -------------------------------------- | | |
| 798 | + | | `$?` | Exit status of last task | | |
| 799 | + | | `$!` | PID of last background task | | |
| 800 | + | | `$$` | PID of shell | | |
| 801 | + | | `$0` | Filename of the shell script | | |
| 802 | + | | `$_` | Last argument of the previous command | | |
| 803 | + | | `${PIPESTATUS[n]}` | return value of piped commands (array) | | |
| 804 | + | ||
| 805 | + | See [Special parameters](http://wiki.bash-hackers.org/syntax/shellvars#special_parameters_and_shell_variables). | |
| 806 | + | ||
| 807 | + | ### Go to previous directory | |
| 808 | + | ||
| 809 | + | ```bash | |
| 810 | + | pwd # /home/user/foo | |
| 811 | + | cd bar/ | |
| 812 | + | pwd # /home/user/foo/bar | |
| 813 | + | cd - | |
| 814 | + | pwd # /home/user/foo | |
| 815 | + | ``` | |
| 816 | + | ||
| 817 | + | ### Check for command's result | |
| 818 | + | ||
| 819 | + | ```bash | |
| 820 | + | if ping -c 1 google.com; then | |
| 821 | + | echo "It appears you have a working internet connection" | |
| 822 | + | fi | |
| 823 | + | ``` | |
| 824 | + | ||
| 825 | + | ### Grep check | |
| 826 | + | ||
| 827 | + | ```bash | |
| 828 | + | if grep -q 'foo' ~/.bash_history; then | |
| 829 | + | echo "You appear to have typed 'foo' in the past" | |
| 830 | + | fi | |
| 831 | + | ``` | |
| 832 | + | ||
| 833 | + | ## Also see | |
| 834 | + | {: .-one-column} | |
| 835 | + | ||
| 836 | + | * [Bash-hackers wiki](http://wiki.bash-hackers.org/) _(bash-hackers.org)_ | |
| 837 | + | * [Shell vars](http://wiki.bash-hackers.org/syntax/shellvars) _(bash-hackers.org)_ | |
| 838 | + | * [Learn bash in y minutes](https://learnxinyminutes.com/docs/bash/) _(learnxinyminutes.com)_ | |
| 839 | + | * [Bash Guide](http://mywiki.wooledge.org/BashGuide) _(mywiki.wooledge.org)_ | |
| 840 | + | * [ShellCheck](https://www.shellcheck.net/) _(shellcheck.net)_ | |
| 841 | + | ||
| 842 | + | https://devhints.io/ cheatsheets - Copyright (c) 2021 Rico Sta. Cruz and contributors - MIT license | |
| 843 | + | micro-cheat plugin Copyright 2022 Tero Karvinen https://TeroKarvinen.com/micro - MIT license |
| ... | ... | @@ -0,0 +1,27 @@ | |
| 1 | + | --- | |
| 2 | + | title: PostgreSQL | |
| 3 | + | category: Databases | |
| 4 | + | --- | |
| 5 | + | ||
| 6 | + | Replace anything within `<placeholder>` accordingly | |
| 7 | + | ||
| 8 | + | ### Console | |
| 9 | + | ||
| 10 | + | $ psql #logs in to default database & default user | |
| 11 | + | $ sudo -u <rolename:postgres> psql #logs in with a particular user | |
| 12 | + | ||
| 13 | + | ### Commands | |
| 14 | + | ||
| 15 | + | * Show roles: `\du` | |
| 16 | + | * Show tables: `\dt` | |
| 17 | + | * Show databases: `\l` | |
| 18 | + | * Connect to a database: `\c <database>` | |
| 19 | + | * Show columns of a table: `\d <table>` or `\d+ <table>` | |
| 20 | + | * Quit: `\q` | |
| 21 | + | ||
| 22 | + | ### Creating database | |
| 23 | + | ||
| 24 | + | $ createdb databasename | |
| 25 | + | ||
| 26 | + | https://devhints.io/ cheatsheets - Copyright (c) 2021 Rico Sta. Cruz and contributors - MIT license | |
| 27 | + | micro-cheat plugin Copyright 2022 Tero Karvinen https://TeroKarvinen.com/micro - MIT license |
| ... | ... | @@ -0,0 +1,287 @@ | |
| 1 | + | --- | |
| 2 | + | title: TypeScript | |
| 3 | + | category: JavaScript libraries | |
| 4 | + | --- | |
| 5 | + | ||
| 6 | + | TypeScript is just like ES2015 with type-checking. All ES2015 (classes, etc) should work. | |
| 7 | + | ||
| 8 | + | ## Basic types | |
| 9 | + | ||
| 10 | + | ```ts | |
| 11 | + | any | |
| 12 | + | void | |
| 13 | + | ||
| 14 | + | boolean | |
| 15 | + | number | |
| 16 | + | string | |
| 17 | + | ||
| 18 | + | null | |
| 19 | + | undefined | |
| 20 | + | ||
| 21 | + | bigint | |
| 22 | + | symbol | |
| 23 | + | ||
| 24 | + | string[] /* or Array<string> */ | |
| 25 | + | [string, number] /* tuple */ | |
| 26 | + | ||
| 27 | + | string | null | undefined /* union */ | |
| 28 | + | ||
| 29 | + | never /* unreachable */ | |
| 30 | + | unknown | |
| 31 | + | ``` | |
| 32 | + | ||
| 33 | + | ```ts | |
| 34 | + | enum Color { | |
| 35 | + | Red, | |
| 36 | + | Green, | |
| 37 | + | Blue = 4 | |
| 38 | + | }; | |
| 39 | + | ||
| 40 | + | let c: Color = Color.Green | |
| 41 | + | ``` | |
| 42 | + | ||
| 43 | + | ## Declarations | |
| 44 | + | ||
| 45 | + | ```ts | |
| 46 | + | let isDone: boolean | |
| 47 | + | let isDone: boolean = false | |
| 48 | + | ``` | |
| 49 | + | ||
| 50 | + | ```ts | |
| 51 | + | function add (a: number, b: number): number { | |
| 52 | + | return a + b | |
| 53 | + | } | |
| 54 | + | ||
| 55 | + | // Return type is optional | |
| 56 | + | function add (a: number, b: number) { ... } | |
| 57 | + | ``` | |
| 58 | + | ||
| 59 | + | ## Type assertions | |
| 60 | + | ||
| 61 | + | #### Variables | |
| 62 | + | ```ts | |
| 63 | + | let len: number = (input as string).length | |
| 64 | + | let len: number = (<string> input).length /* not allowed in JSX */ | |
| 65 | + | ``` | |
| 66 | + | ||
| 67 | + | #### Functions | |
| 68 | + | ```ts | |
| 69 | + | function object(this: {a: number, b: number}, a: number, b: number) { | |
| 70 | + | this.a = a; | |
| 71 | + | this.b = b; | |
| 72 | + | return this; | |
| 73 | + | } | |
| 74 | + | ||
| 75 | + | // this is used only for type declaration | |
| 76 | + | let a = object(1,2); | |
| 77 | + | // a has type {a: number, b: number} | |
| 78 | + | ``` | |
| 79 | + | ||
| 80 | + | ||
| 81 | + | ## Interfaces | |
| 82 | + | ||
| 83 | + | ### Inline | |
| 84 | + | ||
| 85 | + | ```ts | |
| 86 | + | function printLabel (options: { label: string }) { | |
| 87 | + | console.log(options.label) | |
| 88 | + | } | |
| 89 | + | ||
| 90 | + | // Note the semicolon | |
| 91 | + | function getUser (): { name: string; age?: number } { | |
| 92 | + | } | |
| 93 | + | ``` | |
| 94 | + | ||
| 95 | + | ### Explicit | |
| 96 | + | ||
| 97 | + | ```ts | |
| 98 | + | interface LabelOptions { | |
| 99 | + | label: string | |
| 100 | + | } | |
| 101 | + | ||
| 102 | + | function printLabel(options: LabelOptions) { ... } | |
| 103 | + | ``` | |
| 104 | + | ||
| 105 | + | ### Optional properties | |
| 106 | + | ||
| 107 | + | ```ts | |
| 108 | + | interface User { | |
| 109 | + | name: string; | |
| 110 | + | age?: number; | |
| 111 | + | } | |
| 112 | + | ``` | |
| 113 | + | ||
| 114 | + | ### Read only | |
| 115 | + | ||
| 116 | + | ```ts | |
| 117 | + | interface User { | |
| 118 | + | readonly name: string | |
| 119 | + | } | |
| 120 | + | ``` | |
| 121 | + | ||
| 122 | + | ### Dynamic keys | |
| 123 | + | ||
| 124 | + | ```ts | |
| 125 | + | { | |
| 126 | + | [key: string]: Object[] | |
| 127 | + | } | |
| 128 | + | ``` | |
| 129 | + | ||
| 130 | + | ## Type aliases | |
| 131 | + | ||
| 132 | + | ```ts | |
| 133 | + | type Name = string | string[] | |
| 134 | + | ``` | |
| 135 | + | ||
| 136 | + | ### Intersection | |
| 137 | + | ||
| 138 | + | ```ts | |
| 139 | + | interface Colorful { ... } | |
| 140 | + | ||
| 141 | + | interface Circle { ... } | |
| 142 | + | ||
| 143 | + | type ColorfulCircle = Colorful & Circle; | |
| 144 | + | ``` | |
| 145 | + | ||
| 146 | + | ## Function types | |
| 147 | + | ||
| 148 | + | ```ts | |
| 149 | + | interface User { ... } | |
| 150 | + | ||
| 151 | + | function getUser(callback: (user: User) => any) { callback({...}) } | |
| 152 | + | ||
| 153 | + | getUser(function (user: User) { ... }) | |
| 154 | + | ``` | |
| 155 | + | ||
| 156 | + | ## Classes | |
| 157 | + | ||
| 158 | + | ```ts | |
| 159 | + | class Point { | |
| 160 | + | x: number | |
| 161 | + | y: number | |
| 162 | + | static instances = 0 | |
| 163 | + | constructor(x: number, y: number) { | |
| 164 | + | this.x = x | |
| 165 | + | this.y = y | |
| 166 | + | } | |
| 167 | + | } | |
| 168 | + | ``` | |
| 169 | + | ||
| 170 | + | #### Inheritance | |
| 171 | + | ||
| 172 | + | ```ts | |
| 173 | + | class Point {...} | |
| 174 | + | ||
| 175 | + | class Point3D extends Point {...} | |
| 176 | + | ||
| 177 | + | interface Colored {...} | |
| 178 | + | ||
| 179 | + | class Pixel extends Point implements Colored {...} | |
| 180 | + | ``` | |
| 181 | + | ||
| 182 | + | #### Short fields initialisation | |
| 183 | + | ||
| 184 | + | ```ts | |
| 185 | + | class Point { | |
| 186 | + | static instances = 0; | |
| 187 | + | constructor( | |
| 188 | + | public x: number, | |
| 189 | + | public y: number, | |
| 190 | + | ){} | |
| 191 | + | } | |
| 192 | + | ``` | |
| 193 | + | ||
| 194 | + | #### Fields which do not require initialisation | |
| 195 | + | ```ts | |
| 196 | + | class Point { | |
| 197 | + | public someUselessValue!: number; | |
| 198 | + | ... | |
| 199 | + | } | |
| 200 | + | ``` | |
| 201 | + | ||
| 202 | + | ## Generics | |
| 203 | + | ||
| 204 | + | ```ts | |
| 205 | + | class Greeter<T> { | |
| 206 | + | greeting: T | |
| 207 | + | constructor(message: T) { | |
| 208 | + | this.greeting = message | |
| 209 | + | } | |
| 210 | + | } | |
| 211 | + | ||
| 212 | + | let greeter = new Greeter<string>('Hello, world') | |
| 213 | + | ``` | |
| 214 | + | ||
| 215 | + | ## Modules | |
| 216 | + | ||
| 217 | + | ```ts | |
| 218 | + | export interface User { ... } | |
| 219 | + | ``` | |
| 220 | + | ||
| 221 | + | ## Type extraction | |
| 222 | + | ||
| 223 | + | ```ts | |
| 224 | + | interface Building { | |
| 225 | + | room: { | |
| 226 | + | door: string; | |
| 227 | + | walls: string[]; | |
| 228 | + | }; | |
| 229 | + | } | |
| 230 | + | ||
| 231 | + | type Walls = Building['room']['walls']; // string[] | |
| 232 | + | ``` | |
| 233 | + | ||
| 234 | + | ## Keyof Type Operator | |
| 235 | + | ||
| 236 | + | ```ts | |
| 237 | + | type Point = { x: number; y: number }; | |
| 238 | + | ||
| 239 | + | type P = keyof Point; // x | y | |
| 240 | + | ``` | |
| 241 | + | ||
| 242 | + | ## Conditinal Types | |
| 243 | + | ||
| 244 | + | ```ts | |
| 245 | + | // SomeType extends OtherType ? TrueType : FalseType; | |
| 246 | + | ||
| 247 | + | type ToArray<T> = T extends any ? T[] : never; | |
| 248 | + | ||
| 249 | + | type StrArrOrNumArr = ToArray<string | number>; // string[] | number[] | |
| 250 | + | ``` | |
| 251 | + | ||
| 252 | + | ### Inferring | |
| 253 | + | ||
| 254 | + | ```ts | |
| 255 | + | type GetReturnType<T> = T extends (...args: unknown[]) => infer R | |
| 256 | + | ? R | |
| 257 | + | : never; | |
| 258 | + | ||
| 259 | + | type Num = GetReturnType<() => number>; // number | |
| 260 | + | ``` | |
| 261 | + | ||
| 262 | + | ```ts | |
| 263 | + | type First<T extends Array<any>> = T extends [infer F, ...infer Rest] ? F : never; | |
| 264 | + | ||
| 265 | + | type Str = First<['hello', 1, false]>; // 'hello' | |
| 266 | + | ``` | |
| 267 | + | ||
| 268 | + | ## Literal Type | |
| 269 | + | ||
| 270 | + | ```ts | |
| 271 | + | const point = { x: 4, y: 2 }; // { x: number, y: number } | |
| 272 | + | ||
| 273 | + | const literalPoint = { x: 4, y: 2 } as const; // { readonly x: 4, readonly y: 2 }; | |
| 274 | + | ``` | |
| 275 | + | ||
| 276 | + | ## Template Literal Types | |
| 277 | + | ||
| 278 | + | ```ts | |
| 279 | + | type SpaceChar = ' ' | '\n' | '\t'; | |
| 280 | + | ||
| 281 | + | type TrimLeft<S extends string> = S extends `${SpaceChar}${infer Rest}` ? TrimLeft<Rest> : S; | |
| 282 | + | ||
| 283 | + | type Str = TrimLeft<' hello'>; // 'hello' | |
| 284 | + | ``` | |
| 285 | + | ||
| 286 | + | https://devhints.io/ cheatsheets - Copyright (c) 2021 Rico Sta. Cruz and contributors - MIT license | |
| 287 | + | micro-cheat plugin Copyright 2022 Tero Karvinen https://TeroKarvinen.com/micro - MIT license |
| ... | ... | @@ -0,0 +1,130 @@ | |
| 1 | + | --- | |
| 2 | + | title: Vagrantfile | |
| 3 | + | category: Devops | |
| 4 | + | layout: 2017/sheet | |
| 5 | + | --- | |
| 6 | + | ||
| 7 | + | ## Vagrantfile | |
| 8 | + | {: .-one-column} | |
| 9 | + | ||
| 10 | + | ```rb | |
| 11 | + | Vagrant.configure("2") do |config| | |
| 12 | + | # All Vagrant configuration is done here. The most common configuration | |
| 13 | + | # options are documented and commented below. For a complete reference, | |
| 14 | + | # please see the online documentation at vagrantup.com. | |
| 15 | + | ||
| 16 | + | # Every Vagrant virtual environment requires a box to build off of. | |
| 17 | + | config.vm.box = "precise64" | |
| 18 | + | ||
| 19 | + | # The url from where the 'config.vm.box' box will be fetched if it | |
| 20 | + | # doesn't already exist on the user's system. | |
| 21 | + | # config.vm.box_url = "http://domain.com/path/to/above.box" | |
| 22 | + | ||
| 23 | + | # Create a forwarded port mapping which allows access to a specific port | |
| 24 | + | # within the machine from a port on the host machine. In the example below, | |
| 25 | + | # accessing "localhost:8080" will access port 80 on the guest machine. | |
| 26 | + | # config.vm.network :forwarded_port, guest: 80, host: 8080 | |
| 27 | + | ||
| 28 | + | # Create a private network, which allows host-only access to the machine | |
| 29 | + | # using a specific IP. | |
| 30 | + | # config.vm.network :private_network, ip: "192.168.33.10" | |
| 31 | + | ||
| 32 | + | # Create a public network, which generally matched to bridged network. | |
| 33 | + | # Bridged networks make the machine appear as another physical device on | |
| 34 | + | # your network. | |
| 35 | + | # config.vm.network :public_network | |
| 36 | + | ||
| 37 | + | # If true, then any SSH connections made will enable agent forwarding. | |
| 38 | + | # Default value: false | |
| 39 | + | # config.ssh.forward_agent = true | |
| 40 | + | ||
| 41 | + | # Share an additional folder to the guest VM. The first argument is | |
| 42 | + | # the path on the host to the actual folder. The second argument is | |
| 43 | + | # the path on the guest to mount the folder. And the optional third | |
| 44 | + | # argument is a set of non-required options. | |
| 45 | + | # config.vm.synced_folder "../data", "/vagrant_data" | |
| 46 | + | ||
| 47 | + | # Provider-specific configuration so you can fine-tune various | |
| 48 | + | # backing providers for Vagrant. These expose provider-specific options. | |
| 49 | + | # Example for VirtualBox: | |
| 50 | + | # | |
| 51 | + | # config.vm.provider :virtualbox do |vb| | |
| 52 | + | # # Don't boot with headless mode | |
| 53 | + | # vb.gui = true | |
| 54 | + | # | |
| 55 | + | # # Use VBoxManage to customize the VM. For example to change memory: | |
| 56 | + | # vb.customize ["modifyvm", :id, "--memory", "1024"] | |
| 57 | + | # end | |
| 58 | + | # | |
| 59 | + | # View the documentation for the provider you're using for more | |
| 60 | + | # information on available options. | |
| 61 | + | ||
| 62 | + | # Enable provisioning with Puppet stand alone. Puppet manifests | |
| 63 | + | # are contained in a directory path relative to this Vagrantfile. | |
| 64 | + | # You will need to create the manifests directory and a manifest in | |
| 65 | + | # the file precise64.pp in the manifests_path directory. | |
| 66 | + | # | |
| 67 | + | # An example Puppet manifest to provision the message of the day: | |
| 68 | + | # | |
| 69 | + | # # group { "puppet": | |
| 70 | + | # # ensure => "present", | |
| 71 | + | # # } | |
| 72 | + | # # | |
| 73 | + | # # File { owner => 0, group => 0, mode => 0644 } | |
| 74 | + | # # | |
| 75 | + | # # file { '/etc/motd': | |
| 76 | + | # # content => "Welcome to your Vagrant-built virtual machine! | |
| 77 | + | # # Managed by Puppet.\n" | |
| 78 | + | # # } | |
| 79 | + | # | |
| 80 | + | # config.vm.provision :puppet do |puppet| | |
| 81 | + | # puppet.manifests_path = "manifests" | |
| 82 | + | # puppet.manifest_file = "init.pp" | |
| 83 | + | # end | |
| 84 | + | ||
| 85 | + | # Enable provisioning with chef solo, specifying a cookbooks path, roles | |
| 86 | + | # path, and data_bags path (all relative to this Vagrantfile), and adding | |
| 87 | + | # some recipes and/or roles. | |
| 88 | + | # | |
| 89 | + | # config.vm.provision :chef_solo do |chef| | |
| 90 | + | # chef.cookbooks_path = "../my-recipes/cookbooks" | |
| 91 | + | # chef.roles_path = "../my-recipes/roles" | |
| 92 | + | # chef.data_bags_path = "../my-recipes/data_bags" | |
| 93 | + | # chef.add_recipe "mysql" | |
| 94 | + | # chef.add_role "web" | |
| 95 | + | # | |
| 96 | + | # # You may also specify custom JSON attributes: | |
| 97 | + | # chef.json = { :mysql_password => "foo" } | |
| 98 | + | # end | |
| 99 | + | ||
| 100 | + | # Enable provisioning with chef server, specifying the chef server URL, | |
| 101 | + | # and the path to the validation key (relative to this Vagrantfile). | |
| 102 | + | # | |
| 103 | + | # The Opscode Platform uses HTTPS. Substitute your organization for | |
| 104 | + | # ORGNAME in the URL and validation key. | |
| 105 | + | # | |
| 106 | + | # If you have your own Chef Server, use the appropriate URL, which may be | |
| 107 | + | # HTTP instead of HTTPS depending on your configuration. Also change the | |
| 108 | + | # validation key to validation.pem. | |
| 109 | + | # | |
| 110 | + | # config.vm.provision :chef_client do |chef| | |
| 111 | + | # chef.chef_server_url = "https://api.opscode.com/organizations/ORGNAME" | |
| 112 | + | # chef.validation_key_path = "ORGNAME-validator.pem" | |
| 113 | + | # end | |
| 114 | + | # | |
| 115 | + | # If you're using the Opscode platform, your validator client is | |
| 116 | + | # ORGNAME-validator, replacing ORGNAME with your organization name. | |
| 117 | + | # | |
| 118 | + | # If you have your own Chef Server, the default validation client name is | |
| 119 | + | # chef-validator, unless you changed the configuration. | |
| 120 | + | # | |
| 121 | + | # chef.validation_client_name = "ORGNAME-validator" | |
| 122 | + | end | |
| 123 | + | ``` | |
| 124 | + | ||
| 125 | + | ## Also see | |
| 126 | + | ||
| 127 | + | * [Vagrant cheatsheet](./vagrant) | |
| 128 | + | ||
| 129 | + | https://devhints.io/ cheatsheets - Copyright (c) 2021 Rico Sta. Cruz and contributors - MIT license | |
| 130 | + | micro-cheat plugin Copyright 2022 Tero Karvinen https://TeroKarvinen.com/micro - MIT license |
| ... | ... | @@ -0,0 +1,147 @@ | |
| 1 | + | --- | |
| 2 | + | title: Vainglory | |
| 3 | + | layout: 2017/sheet | |
| 4 | + | --- | |
| 5 | + | ||
| 6 | + | ## T3 items by use | |
| 7 | + | {: .-one-column} | |
| 8 | + | ||
| 9 | + | | Use | CP | WP | Util | | |
| 10 | + | | --- | --- | --- | --- | | |
| 11 | + | | __Anti-armor/shield__ | [Myth][BM] | [Bonesaw][BS], [Tension][TB] | | | |
| 12 | + | | __Stacking damage__ | [Myth][BM] | [Break][BP] | | | |
| 13 | + | | __Lifesteal__ | [Eve][Eve] | [Serpent][SM], [Shiv][PS] | | | |
| 14 | + | | __Raw power__ | [Shatterglass][SG] | [Sorrowblade][SB] | | | |
| 15 | + | | __Burst damage__ | [Aftershock][AS] | [Tension][TB] | | | |
| 16 | + | | __Attack speed__ | [AC][AC] | [Tornado][TT], [Break][BP] | | | |
| 17 | + | | __Critical__ | | [Monocle][TM] | | | |
| 18 | + | | __Auto-attack damage__ | [AC][AC], [Aftershock][AS] | _everything_ | [Stormcrown][SC] | | |
| 19 | + | | __Cooldown__ | [Clockwork][CW], [Aftershock][AS] | Spellsword | [Stormcrown][SC], [Contraption][Con], [Nullwave][Null], [Halcyon Boots][HBoot] | | |
| 20 | + | | __Slow__ | [Frostburn][FB] | | [Shiversteel][SS] | | |
| 21 | + | | __Reflex block__ | | | [Aegis][Aegis] (self/shield) <br> [Crucible][Cru] (team/HP) | | |
| 22 | + | | __Ability repeat__ | [Echo][Echo] | | | | |
| 23 | + | {: .-left-align.-headers} | |
| 24 | + | ||
| 25 | + | ## Tier 3 items | |
| 26 | + | {: .-one-column} | |
| 27 | + | ||
| 28 | + | ### Crystal power | |
| 29 | + | ||
| 30 | + | | Item | Cost | CP | Use | | |
| 31 | + | | ---- | --- | --- | --- | | |
| 32 | + | | AS: [Aftershock][AS] | 2400 | +35 cp | __Basic dmg, atk speed__ <br> *+basic dmg after ability*, +25% cooldown, +2.5 recharge | | |
| 33 | + | | EoH: [Eve of Harvest][Eve] | 2600 | +55 cp | __Lifesteal__ <br> *+10% lifesteal*, +250 energy, +5 recharge | | |
| 34 | + | | AC: [Alternating Current][AC] | 2800 | +60 cp | __Basic dmg__ <br> *+basic dmg based on CP*, +65% atk speed | | |
| 35 | + | | BM: [Broken Myth][BM] | 2150 | +70 cp | __Stack dmg__ <br> +10% shield pierce, stacking dmg | | |
| 36 | + | | FB: [Frostburn][FB] | 2600 | +100 cp | __Slow__ <br> *slow for 1.5s* at (10% + 1% per 10CP) | | |
| 37 | + | | SG: [Shatterglass][SG] | 3000 | +150 cp | __Raw power__ <br> - | | |
| 38 | + | | CW: [Clockwork][CW] | 2500 | +30% cp | __Cooldown__ <br> *+40% cooldown*, +250 energy, +7.5 recharge | | |
| 39 | + | | [Echo][Echo] | 2500? | | __Ability repeat__ <br> +250 energy, +4 recharge | | |
| 40 | + | {: .-left-align.-headers} | |
| 41 | + | ||
| 42 | + | [AS]: http://www.vaingloryfire.com/vainglory/wiki/items/aftershock | |
| 43 | + | [AC]: http://www.vaingloryfire.com/vainglory/wiki/items/alternating-current | |
| 44 | + | [Eve]: http://www.vaingloryfire.com/vainglory/wiki/items/eve-of-harvest | |
| 45 | + | [SG]: http://www.vaingloryfire.com/vainglory/wiki/items/shatterglass | |
| 46 | + | [BM]: http://www.vaingloryfire.com/vainglory/wiki/items/broken-myth | |
| 47 | + | [CW]: http://www.vaingloryfire.com/vainglory/wiki/items/clockwork | |
| 48 | + | [FB]: http://www.vaingloryfire.com/vainglory/wiki/items/frostburn | |
| 49 | + | [Echo]: http://www.vaingloryfire.com/vainglory/wiki/items/echo | |
| 50 | + | ||
| 51 | + | ### Weapon power | |
| 52 | + | ||
| 53 | + | | Item | Cost | WP | Other | | |
| 54 | + | | ---- | --- | --- | --- | | |
| 55 | + | | TT: [Tornado Trigger][TT] | 2600 | | __Atk speed__ <br> *+75% atk speed*, +20% crit change, +20% crit dmg | | |
| 56 | + | | BS: [Bonesaw][BS] | 2700 | +15 wp | __Armor shred__ <br> *stacking armor shred* | | |
| 57 | + | | TB: [Tension Bow][TB] | 2300 | +45 wp | __Bonus dmg__ <br> *bonus dmg every 6s*, +8% armor pierce | | |
| 58 | + | | TM: [Tyrant's Monocle][TM] | 2750 | +50 wp | __Crit__ <br> *+40% crit chance*, +20% crit dmg | | |
| 59 | + | | BP: [Breaking Point][BP] | 2600 | +55 wp | __Stacking dmg__ <br> *stacking weapon dmg*, +35% atk speed | | |
| 60 | + | | SM: [Serpent Mask][SM] | 2800 | +85 wp | __Lifesteal__ <br> *stacking lifesteal*, +10% lifesteal | | |
| 61 | + | | SB: [Sorrowblade][SB] | 3100 | +150 wp | __Raw power__ <br> - | | |
| 62 | + | | PS: [Poisoned Shiv][PS] | 2250 | +30 wp | __Mortal wounds__ <br> *mortal wounds for 2s*, +10% lifesteal, +30% atk speed | | |
| 63 | + | | SS: Spellsword | ? | +90 wp | __Cooldown__ <br> ? | | |
| 64 | + | {: .-left-align.-headers} | |
| 65 | + | ||
| 66 | + | [BS]: http://www.vaingloryfire.com/vainglory/wiki/items/bonesaw | |
| 67 | + | [BP]: http://www.vaingloryfire.com/vainglory/wiki/items/breaking-point | |
| 68 | + | [SM]: http://www.vaingloryfire.com/vainglory/wiki/items/serpent-mask | |
| 69 | + | [SB]: http://www.vaingloryfire.com/vainglory/wiki/items/sorrowblade | |
| 70 | + | [TB]: http://www.vaingloryfire.com/vainglory/wiki/items/tension-bow | |
| 71 | + | [TT]: http://www.vaingloryfire.com/vainglory/wiki/items/tornado-trigger | |
| 72 | + | [TM]: http://www.vaingloryfire.com/vainglory/wiki/items/tyrants-monocle | |
| 73 | + | [PS]: http://www.vaingloryfire.com/vainglory/wiki/items/poisoned-shiv | |
| 74 | + | ||
| 75 | + | ### Utilities | |
| 76 | + | ||
| 77 | + | | Item | Cost | HP | Use | | |
| 78 | + | | --- | --- | --- | --- | | |
| 79 | + | | [Halcyon Chargers][HBoot] | 2300 | +200 hp | 👟 __Boots__ <br> +15% cooldown, +250 energy, +4 recharge | | |
| 80 | + | | [Stormcrown][SC] | 2200 | +200 hp | 🔴 __Bonus dmg__ <br> +30% cooldown, +4 recharge, bonus true damage | | |
| 81 | + | | [Journey Boots][JBoot] | 1900 | +250 hp | 👟 __Boots__ <br> damaging heroes resets sprint cooldown | | |
| 82 | + | | [Nullwave Gauntlet][Null] (2.0) | 2250 | +300 hp | 😶 __Item silence__ <br> +25% cooldown | | |
| 83 | + | | [Contraption][Con] | 2100 | +350 hp | 👀 __Vision__ <br> traps/flares, +40% cooldown, +3 recharge | | |
| 84 | + | | [Shiversteel][SS] | 1450 | +500 hp | 🐌 __Slow__ <br> active: slow targets | | |
| 85 | + | | [War Treads][WBoot] | 2500 | +600 hp | 👟 __Boots__ <br> gives sprint to nearby teammates | | |
| 86 | + | {: .-left-align.-headers} | |
| 87 | + | ||
| 88 | + | ### Defense | |
| 89 | + | ||
| 90 | + | | Item | Cost | HP | Armor | Shield | Use | | |
| 91 | + | | --- | --- | --- | --- | --- | --- | | |
| 92 | + | | [Aegis][Aegis] | 2250 | | +30 ar | +125 sh | ✊__Reflex block__ (self) | | |
| 93 | + | | [Fountain of Renewal][Fountain] | 2300 | +200 hp | +30 ar | +75 sh | ❤ __Heal__ allies | | |
| 94 | + | | [Atlas Pauldron][Atlas] | 1900 | | +85 ar | +35 sh | 🐌 __Slow__ target attack speed | | |
| 95 | + | | [Metal Jacket][Metal] | 2100 | | +170 ar | +35 sh | | | |
| 96 | + | | [Crucible][Cru] | 1850 | +600 hp | | | ✊ __Reflex block__ (team) | | |
| 97 | + | | [Slumbering Husk][Husk] (2.0) | 1600 | +400 hp | | | __Fortification__ against burst damage | | |
| 98 | + | {: .-left-align.-headers} | |
| 99 | + | ||
| 100 | + | [Fountain]: http://www.vaingloryfire.com/vainglory/wiki/items/fountain-of-renewal | |
| 101 | + | [Cru]: http://www.vaingloryfire.com/vainglory/wiki/items/aegis | |
| 102 | + | [Aegis]: http://www.vaingloryfire.com/vainglory/wiki/items/aegis | |
| 103 | + | [Atlas]: http://www.vaingloryfire.com/vainglory/wiki/items/atlas-pauldron | |
| 104 | + | [Metal]: http://www.vaingloryfire.com/vainglory/wiki/items/metal-jacket | |
| 105 | + | [Husk]: http://www.vaingloryfire.com/vainglory/wiki/items/slumbering-husk | |
| 106 | + | [Null]: http://www.vaingloryfire.com/vainglory/wiki/items/nullwave-gauntlet | |
| 107 | + | ||
| 108 | + | ### Boots | |
| 109 | + | ||
| 110 | + | | Item | Movement speed | HP | Sprint | Use | | |
| 111 | + | | --- | --- | --- | --- | --- | | |
| 112 | + | | [War Treads][WBoot] | +0.4 | +600 hp | 2s (60s cooldown) <br> incl. nearby teammates | __HP, assist__ | | |
| 113 | + | | [Halcyon Chargers][HBoot] | +0.5 | | 3s (50s cooldown) | __Energy__ | | |
| 114 | + | | [Journey Boots][JBoot] | +0.6 | +250 hp | 2s (60s cooldown) <br> damaging resets cooldown | __Gap close__ | | |
| 115 | + | {: .-left-align.-headers} | |
| 116 | + | ||
| 117 | + | [Con]: http://www.vaingloryfire.com/vainglory/wiki/items/contraption | |
| 118 | + | [HBoot]: http://www.vaingloryfire.com/vainglory/wiki/items/halcyon-chargers | |
| 119 | + | [WBoot]: http://www.vaingloryfire.com/vainglory/wiki/items/war-treads | |
| 120 | + | [JBoot]: http://www.vaingloryfire.com/vainglory/wiki/items/journey-boots | |
| 121 | + | [SC]: http://www.vaingloryfire.com/vainglory/wiki/items/stormcrown | |
| 122 | + | [SS]: http://www.vaingloryfire.com/vainglory/wiki/items/shiversteel | |
| 123 | + | ||
| 124 | + | ## Skill tier names | |
| 125 | + | ||
| 126 | + | | Just Beginning | 1 | | |
| 127 | + | | Getting There | 2 | | |
| 128 | + | | Rock Solid | 3 | | |
| 129 | + | | Worthy Foe |4 | | |
| 130 | + | | Got Swagger | 5 | | |
| 131 | + | | Credible Threat | 6 | | |
| 132 | + | | The Hotness | 7 | | |
| 133 | + | | Simply Amazing | 8 | | |
| 134 | + | | Pinnacle of Awesome | 9 | | |
| 135 | + | | Vainglorious | 10 | | |
| 136 | + | ||
| 137 | + | See: [Skill tier names](http://www.vaingloryfire.com/vainglory/forum/general-discussion/bronze-silver-gold-rankings-5312) | |
| 138 | + | ||
| 139 | + | ## References | |
| 140 | + | ||
| 141 | + | - Last updated for Vainglory 1.22 with some 2.0 stuff. | |
| 142 | + | - [Vaingloryfire.com](http://www.vaingloryfire.com/) | |
| 143 | + | - [Version history](http://forums.vainglorygame.com/index.php?threads/41129/) (forums.vainglorygame.com) | |
| 144 | + | - [Skill tier points](http://brokenmyth.net/skill-tier-point-far-next-tier/#more-10043) (brokenmyth.net) | |
| 145 | + | ||
| 146 | + | https://devhints.io/ cheatsheets - Copyright (c) 2021 Rico Sta. Cruz and contributors - MIT license | |
| 147 | + | micro-cheat plugin Copyright 2022 Tero Karvinen https://TeroKarvinen.com/micro - MIT license |
| ... | ... | @@ -0,0 +1,720 @@ | |
| 1 | + | --- | |
| 2 | + | title: Vim scripting | |
| 3 | + | category: Vim | |
| 4 | + | prism_languages: [vim] | |
| 5 | + | layout: 2017/sheet | |
| 6 | + | updated: 2020-07-05 | |
| 7 | + | weight: -10 | |
| 8 | + | tags: [Featurable] | |
| 9 | + | --- | |
| 10 | + | ||
| 11 | + | ### Start hacking | |
| 12 | + | ||
| 13 | + | ```vim | |
| 14 | + | let name = "John" | |
| 15 | + | echo "Hello, " . name | |
| 16 | + | ``` | |
| 17 | + | ||
| 18 | + | You can either put this in a script (`script.vim`) and run it (`:source script.vim`), or you can type the commands individually in normal mode as `:let` and `:echo`. | |
| 19 | + | ||
| 20 | + | ### Learn by example | |
| 21 | + | ||
| 22 | + | ```vim | |
| 23 | + | function! SuperTab() | |
| 24 | + | let l:part = strpart(getline('.'),col('.')-2,1) | |
| 25 | + | if (l:part =~ '^\W\?$') | |
| 26 | + | return "\<Tab>" | |
| 27 | + | else | |
| 28 | + | return "\<C-n>" | |
| 29 | + | endif | |
| 30 | + | endfunction | |
| 31 | + | ||
| 32 | + | imap <Tab> <C-R>=SuperTab()<CR> | |
| 33 | + | ``` | |
| 34 | + | ||
| 35 | + | [Here](http://www.vimbits.com/bits/46)'s another example with [functions](#functions), [variables](#variables) and [mapping](#mapping). | |
| 36 | + | ||
| 37 | + | Variables | |
| 38 | + | --------- | |
| 39 | + | ||
| 40 | + | ### Defining | |
| 41 | + | {: .-prime} | |
| 42 | + | ||
| 43 | + | ```vim | |
| 44 | + | let var = "hello" | |
| 45 | + | ``` | |
| 46 | + | ||
| 47 | + | ### Variable prefixes | |
| 48 | + | ||
| 49 | + | ```vim | |
| 50 | + | let g:ack_options = '-s -H' " g: global | |
| 51 | + | let s:ack_program = 'ack' " s: local (to script) | |
| 52 | + | let l:foo = 'bar' " l: local (to function) | |
| 53 | + | ``` | |
| 54 | + | ||
| 55 | + | The `s:` prefix is also available in function names. See `:help local-variables` | |
| 56 | + | ||
| 57 | + | ### Other prefixes | |
| 58 | + | ||
| 59 | + | ```vim | |
| 60 | + | let w:foo = 'bar' " w: window | |
| 61 | + | let b:state = 'on' " b: buffer | |
| 62 | + | let t:state = 'off' " t: tab | |
| 63 | + | echo v:var " v: vim special | |
| 64 | + | ``` | |
| 65 | + | ||
| 66 | + | ```vim | |
| 67 | + | let @/ = '' " @ register (this clears last search pattern) | |
| 68 | + | echo $PATH " $ env | |
| 69 | + | ``` | |
| 70 | + | ||
| 71 | + | ### Vim options | |
| 72 | + | ||
| 73 | + | ```vim | |
| 74 | + | echo 'tabstop is ' . &tabstop | |
| 75 | + | if &insertmode | |
| 76 | + | echo &g:option | |
| 77 | + | echo &l:option | |
| 78 | + | ``` | |
| 79 | + | ||
| 80 | + | Prefix Vim options with `&` | |
| 81 | + | ||
| 82 | + | ### Operators | |
| 83 | + | ||
| 84 | + | ```vim | |
| 85 | + | a + b " numbers only! | |
| 86 | + | 'hello ' . name " concat | |
| 87 | + | ``` | |
| 88 | + | ||
| 89 | + | ```vim | |
| 90 | + | let var -= 2 | |
| 91 | + | let var += 5 | |
| 92 | + | let var .= 'string' " concat | |
| 93 | + | ``` | |
| 94 | + | ||
| 95 | + | ## Strings | |
| 96 | + | ||
| 97 | + | ### Strings | |
| 98 | + | ||
| 99 | + | ```vim | |
| 100 | + | let str = "String" | |
| 101 | + | let str = "String with \n newline" | |
| 102 | + | ||
| 103 | + | let literal = 'literal, no \ escaping' | |
| 104 | + | let literal = 'that''s enough' " double '' => ' | |
| 105 | + | ||
| 106 | + | echo "result = " . re " concatenation | |
| 107 | + | ``` | |
| 108 | + | ||
| 109 | + | Also see `:help literal-string` and `:help expr-quote`. | |
| 110 | + | See: [Strings](http://learnvimscriptthehardway.stevelosh.com/chapters/26.html) | |
| 111 | + | ||
| 112 | + | ### String functions | |
| 113 | + | ||
| 114 | + | ```vim | |
| 115 | + | strlen(str) " length | |
| 116 | + | len(str) " same | |
| 117 | + | strchars(str) " character length | |
| 118 | + | ||
| 119 | + | split("one two three") "=> ['one', 'two', 'three'] | |
| 120 | + | split("one.two.three", '.') "=> ['one', 'two', 'three'] | |
| 121 | + | ||
| 122 | + | join(['a', 'b'], ',') "=> 'a,b' | |
| 123 | + | ||
| 124 | + | tolower('Hello') | |
| 125 | + | toupper('Hello') | |
| 126 | + | ``` | |
| 127 | + | ||
| 128 | + | Also see `:help functions` | |
| 129 | + | See: [String functions](http://learnvimscriptthehardway.stevelosh.com/chapters/27.html) | |
| 130 | + | ||
| 131 | + | Functions | |
| 132 | + | --------- | |
| 133 | + | ||
| 134 | + | ### Functions | |
| 135 | + | {: .-prime} | |
| 136 | + | ||
| 137 | + | ```vim | |
| 138 | + | " prefix with s: for local script-only functions | |
| 139 | + | function! s:Initialize(cmd, args) | |
| 140 | + | " a: prefix for arguments | |
| 141 | + | echo "Command: " . a:cmd | |
| 142 | + | ||
| 143 | + | return 1 | |
| 144 | + | endfunction | |
| 145 | + | ``` | |
| 146 | + | ||
| 147 | + | See: [Functions](http://learnvimscriptthehardway.stevelosh.com/chapters/23.html) | |
| 148 | + | ||
| 149 | + | ### Namespacing | |
| 150 | + | ||
| 151 | + | ```vim | |
| 152 | + | function! myplugin#hello() | |
| 153 | + | ``` | |
| 154 | + | ||
| 155 | + | ### Calling functions | |
| 156 | + | ||
| 157 | + | ```vim | |
| 158 | + | call s:Initialize() | |
| 159 | + | call s:Initialize("hello") | |
| 160 | + | ``` | |
| 161 | + | ||
| 162 | + | ### Consuming return values | |
| 163 | + | ||
| 164 | + | ```vim | |
| 165 | + | echo "Result: " . s:Initialize() | |
| 166 | + | ``` | |
| 167 | + | ||
| 168 | + | ### Abortable | |
| 169 | + | ||
| 170 | + | ```vim | |
| 171 | + | function! myfunction() abort | |
| 172 | + | endfunction | |
| 173 | + | ``` | |
| 174 | + | ||
| 175 | + | Aborts when an error occurs. | |
| 176 | + | ||
| 177 | + | ### Var arguments | |
| 178 | + | ||
| 179 | + | ```vim | |
| 180 | + | function! infect(...) | |
| 181 | + | echo a:0 "=> 2 | |
| 182 | + | echo a:1 "=> jake | |
| 183 | + | echo a:2 "=> bella | |
| 184 | + | ||
| 185 | + | for s in a:000 " a list | |
| 186 | + | echon ' ' . s | |
| 187 | + | endfor | |
| 188 | + | endfunction | |
| 189 | + | ||
| 190 | + | infect('jake', 'bella') | |
| 191 | + | ``` | |
| 192 | + | ||
| 193 | + | See `:help function-argument`. See: [Var arguments](http://learnvimscriptthehardway.stevelosh.com/chapters/24.html) | |
| 194 | + | ||
| 195 | + | Loops | |
| 196 | + | ----- | |
| 197 | + | ||
| 198 | + | ```vim | |
| 199 | + | for s in list | |
| 200 | + | echo s | |
| 201 | + | continue " jump to start of loop | |
| 202 | + | break " breaks out of a loop | |
| 203 | + | endfor | |
| 204 | + | ``` | |
| 205 | + | ||
| 206 | + | ```vim | |
| 207 | + | while x < 5 | |
| 208 | + | endwhile | |
| 209 | + | ``` | |
| 210 | + | ||
| 211 | + | Custom commands | |
| 212 | + | --------------- | |
| 213 | + | ||
| 214 | + | ### Custom commands | |
| 215 | + | {: .-prime} | |
| 216 | + | ||
| 217 | + | ```vim | |
| 218 | + | command! Save :set fo=want tw=80 nowrap | |
| 219 | + | ``` | |
| 220 | + | ||
| 221 | + | Custom commands start with uppercase letters. The `!` redefines a command if it already exists. | |
| 222 | + | ||
| 223 | + | ### Commands calling functions | |
| 224 | + | ||
| 225 | + | ```vim | |
| 226 | + | command! Save call <SID>foo() | |
| 227 | + | ``` | |
| 228 | + | {: .-setup} | |
| 229 | + | ||
| 230 | + | ```vim | |
| 231 | + | function! s:foo() | |
| 232 | + | ... | |
| 233 | + | endfunction | |
| 234 | + | ``` | |
| 235 | + | ||
| 236 | + | ### Commands with arguments | |
| 237 | + | ||
| 238 | + | ```vim | |
| 239 | + | command! -nargs=? Save call script#foo(<args>) | |
| 240 | + | ``` | |
| 241 | + | {: .-setup} | |
| 242 | + | ||
| 243 | + | | What | What | | |
| 244 | + | | ---- | ---- | | |
| 245 | + | | `-nargs=0` | 0 arguments, default | | |
| 246 | + | | `-nargs=1` | 1 argument, includes spaces | | |
| 247 | + | | `-nargs=?` | 0 or 1 argument | | |
| 248 | + | | `-nargs=*` | 0+ arguments, space separated | | |
| 249 | + | | `-nargs=+` | 1+ arguments, space reparated | | |
| 250 | + | ||
| 251 | + | Flow | |
| 252 | + | ---- | |
| 253 | + | ||
| 254 | + | ### Conditionals | |
| 255 | + | ||
| 256 | + | ```vim | |
| 257 | + | let char = getchar() | |
| 258 | + | if char == "\<LeftMouse>" | |
| 259 | + | " ... | |
| 260 | + | elseif char == "\<RightMouse>" | |
| 261 | + | " ... | |
| 262 | + | else | |
| 263 | + | " ... | |
| 264 | + | endif | |
| 265 | + | ``` | |
| 266 | + | ||
| 267 | + | ### Truthiness | |
| 268 | + | ||
| 269 | + | ```vim | |
| 270 | + | if 1 | echo "true" | endif | |
| 271 | + | if 0 | echo "false" | endif | |
| 272 | + | ``` | |
| 273 | + | ||
| 274 | + | ```vim | |
| 275 | + | if 1 "=> 1 (true) | |
| 276 | + | if 0 "=> 0 (false) | |
| 277 | + | if "1" "=> 1 (true) | |
| 278 | + | if "456" "=> 1 (true) | |
| 279 | + | if "xfz" "=> 0 (false) | |
| 280 | + | ``` | |
| 281 | + | ||
| 282 | + | No booleans. `0` is false, `1` is true. | |
| 283 | + | See: [Truthiness](http://learnvimscriptthehardway.stevelosh.com/chapters/21.html) | |
| 284 | + | ||
| 285 | + | ### Operators | |
| 286 | + | ||
| 287 | + | ```vim | |
| 288 | + | if 3 > 2 | |
| 289 | + | if a && b | |
| 290 | + | if (a && b) || (c && d) | |
| 291 | + | if !c | |
| 292 | + | ``` | |
| 293 | + | ||
| 294 | + | See `:help expression-syntax`. | |
| 295 | + | See: [Operators](http://learnvimscriptthehardway.stevelosh.com/chapters/22.html) | |
| 296 | + | ||
| 297 | + | ### Strings | |
| 298 | + | ||
| 299 | + | ```vim | |
| 300 | + | if name ==# 'John' " case-sensitive | |
| 301 | + | if name ==? 'John' " case-insensitive | |
| 302 | + | if name == 'John' " depends on :set ignorecase | |
| 303 | + | ||
| 304 | + | " also: is#, is?, >=#, >=?, and so on | |
| 305 | + | ``` | |
| 306 | + | ||
| 307 | + | ### Identity operators | |
| 308 | + | ||
| 309 | + | ```vim | |
| 310 | + | a is b | |
| 311 | + | a isnot b | |
| 312 | + | ``` | |
| 313 | + | ||
| 314 | + | Checks if it's the same instance object. | |
| 315 | + | ||
| 316 | + | ### Regexp matches | |
| 317 | + | ||
| 318 | + | ```vim | |
| 319 | + | "hello" =~ 'xx*' | |
| 320 | + | "hello" !~ 'xx*' | |
| 321 | + | "hello" =~ '\v<\d+>' | |
| 322 | + | ``` | |
| 323 | + | ||
| 324 | + | `\v` enables "extended" regex mode which allows word boundary (`<>`), `+`, and more. | |
| 325 | + | ||
| 326 | + | ### Single line | |
| 327 | + | ||
| 328 | + | ```vim | |
| 329 | + | if empty(a:path) | return [] | endif | |
| 330 | + | a ? b : c | |
| 331 | + | ``` | |
| 332 | + | ||
| 333 | + | Use `|` to join lines together. | |
| 334 | + | ||
| 335 | + | ### Boolean logic | |
| 336 | + | ||
| 337 | + | ```vim | |
| 338 | + | if g:use_dispatch && s:has_dispatch | |
| 339 | + | ··· | |
| 340 | + | endif | |
| 341 | + | ``` | |
| 342 | + | ||
| 343 | + | Lists | |
| 344 | + | ----- | |
| 345 | + | ||
| 346 | + | ### Lists | |
| 347 | + | ||
| 348 | + | ```vim | |
| 349 | + | let mylist = [1, two, 3, "four"] | |
| 350 | + | ||
| 351 | + | let first = mylist[0] | |
| 352 | + | let last = mylist[-1] | |
| 353 | + | ||
| 354 | + | " Suppresses errors | |
| 355 | + | let second = get(mylist, 1) | |
| 356 | + | let second = get(mylist, 1, "NONE") | |
| 357 | + | ``` | |
| 358 | + | ||
| 359 | + | ### Functions | |
| 360 | + | ||
| 361 | + | ```vim | |
| 362 | + | len(mylist) | |
| 363 | + | empty(mylist) | |
| 364 | + | ||
| 365 | + | sort(list) | |
| 366 | + | let sortedlist = sort(copy(list)) | |
| 367 | + | ||
| 368 | + | split('hello there world', ' ') | |
| 369 | + | ``` | |
| 370 | + | ||
| 371 | + | ### Concatenation | |
| 372 | + | ||
| 373 | + | ```vim | |
| 374 | + | let longlist = mylist + [5, 6] | |
| 375 | + | let mylist += [7, 8] | |
| 376 | + | ``` | |
| 377 | + | ||
| 378 | + | ### Sublists | |
| 379 | + | ||
| 380 | + | ```vim | |
| 381 | + | let shortlist = mylist[2:-1] | |
| 382 | + | let shortlist = mylist[2:] " same | |
| 383 | + | ||
| 384 | + | let shortlist = mylist[2:2] " one item | |
| 385 | + | ``` | |
| 386 | + | ||
| 387 | + | ### Push | |
| 388 | + | ||
| 389 | + | ```vim | |
| 390 | + | let alist = [1, 2, 3] | |
| 391 | + | let alist = add(alist, 4) | |
| 392 | + | ``` | |
| 393 | + | ||
| 394 | + | ### Map | |
| 395 | + | ||
| 396 | + | ```vim | |
| 397 | + | call map(files, "bufname(v:val)") " use v:val for value | |
| 398 | + | call filter(files, 'v:val != ""') | |
| 399 | + | ``` | |
| 400 | + | ||
| 401 | + | Dictionaries | |
| 402 | + | ------------ | |
| 403 | + | ||
| 404 | + | ### Dictionaries | |
| 405 | + | ||
| 406 | + | ```vim | |
| 407 | + | let colors = { | |
| 408 | + | \ "apple": "red", | |
| 409 | + | \ "banana": "yellow" | |
| 410 | + | } | |
| 411 | + | ||
| 412 | + | echo colors["a"] | |
| 413 | + | echo get(colors, "apple") " suppress error | |
| 414 | + | ``` | |
| 415 | + | ||
| 416 | + | See `:help dict` | |
| 417 | + | ||
| 418 | + | ### Using dictionaries | |
| 419 | + | ||
| 420 | + | ```vim | |
| 421 | + | remove(colors, "apple") | |
| 422 | + | ``` | |
| 423 | + | ||
| 424 | + | ```vim | |
| 425 | + | " :help E715 | |
| 426 | + | if has_key(dict, 'foo') | |
| 427 | + | if empty(dict) | |
| 428 | + | keys(dict) | |
| 429 | + | len(dict) | |
| 430 | + | ``` | |
| 431 | + | ||
| 432 | + | ```vim | |
| 433 | + | max(dict) | |
| 434 | + | min(dict) | |
| 435 | + | ``` | |
| 436 | + | ||
| 437 | + | ```vim | |
| 438 | + | count(dict, 'x') | |
| 439 | + | string(dict) | |
| 440 | + | ``` | |
| 441 | + | ||
| 442 | + | ```vim | |
| 443 | + | map(dict, '<>> " . v:val') | |
| 444 | + | ``` | |
| 445 | + | ||
| 446 | + | ### Iteration | |
| 447 | + | ||
| 448 | + | ```vim | |
| 449 | + | for key in keys(mydict) | |
| 450 | + | echo key . ': ' . mydict(key) | |
| 451 | + | endfor | |
| 452 | + | ``` | |
| 453 | + | ||
| 454 | + | ### Prefixes | |
| 455 | + | ||
| 456 | + | ```vim | |
| 457 | + | keys(s:) | |
| 458 | + | ``` | |
| 459 | + | ||
| 460 | + | Prefixes (`s:`, `g:`, `l:`, etc) are actually dictionaries. | |
| 461 | + | ||
| 462 | + | ### Extending | |
| 463 | + | ||
| 464 | + | ```vim | |
| 465 | + | " Extending with more | |
| 466 | + | let extend(s:fruits, { ... }) | |
| 467 | + | ``` | |
| 468 | + | ||
| 469 | + | Casting | |
| 470 | + | ------- | |
| 471 | + | ||
| 472 | + | ```vim | |
| 473 | + | str2float("2.3") | |
| 474 | + | str2nr("3") | |
| 475 | + | float2nr("3.14") | |
| 476 | + | ``` | |
| 477 | + | ||
| 478 | + | Numbers | |
| 479 | + | ------- | |
| 480 | + | ||
| 481 | + | ### Numbers | |
| 482 | + | {: .-prime} | |
| 483 | + | ||
| 484 | + | ```vim | |
| 485 | + | let int = 1000 | |
| 486 | + | let int = 0xff | |
| 487 | + | let int = 0755 " octal | |
| 488 | + | ``` | |
| 489 | + | ||
| 490 | + | See `:help Number`. | |
| 491 | + | See: [Numbers](http://learnvimscriptthehardway.stevelosh.com/chapters/25.html) | |
| 492 | + | ||
| 493 | + | ### Floats | |
| 494 | + | ||
| 495 | + | ```vim | |
| 496 | + | let fl = 100.1 | |
| 497 | + | let fl = 5.4e4 | |
| 498 | + | ``` | |
| 499 | + | ||
| 500 | + | See `:help Float` | |
| 501 | + | ||
| 502 | + | ### Arithmetic | |
| 503 | + | ||
| 504 | + | ```vim | |
| 505 | + | 3 / 2 "=> 1, integer division | |
| 506 | + | 3 / 2.0 "=> 1.5 | |
| 507 | + | 3 * 2.0 "=> 6.0 | |
| 508 | + | ``` | |
| 509 | + | ||
| 510 | + | ### Math functions | |
| 511 | + | ||
| 512 | + | ```vim | |
| 513 | + | sqrt(100) | |
| 514 | + | floor(3.5) | |
| 515 | + | ceil(3.3) | |
| 516 | + | abs(-3.4) | |
| 517 | + | ||
| 518 | + | sin() cos() tan() | |
| 519 | + | sinh() cosh() tanh() | |
| 520 | + | asin() acos() atan() | |
| 521 | + | ``` | |
| 522 | + | ||
| 523 | + | Vim-isms | |
| 524 | + | -------- | |
| 525 | + | ||
| 526 | + | ### Execute a command | |
| 527 | + | ||
| 528 | + | ```vim | |
| 529 | + | execute "vsplit" | |
| 530 | + | execute "e " . fnameescape(filename) | |
| 531 | + | ``` | |
| 532 | + | ||
| 533 | + | Runs an ex command you typically run with `:`. Also see `:help execute`. | |
| 534 | + | See: [Execute a command](http://learnvimscriptthehardway.stevelosh.com/chapters/28.html) | |
| 535 | + | ||
| 536 | + | ### Running keystrokes | |
| 537 | + | ||
| 538 | + | ```vim | |
| 539 | + | normal G | |
| 540 | + | normal! G " skips key mappings | |
| 541 | + | ||
| 542 | + | execute "normal! gg/foo\<cr>dd" | |
| 543 | + | ``` | |
| 544 | + | ||
| 545 | + | Use `:normal` to execute keystrokes as if you're typing them in normal mode. Combine with `:execute` for special keystrokes. | |
| 546 | + | See: [Running keystrokes](http://learnvimscriptthehardway.stevelosh.com/chapters/29.html) | |
| 547 | + | ||
| 548 | + | ### Getting filenames | |
| 549 | + | ||
| 550 | + | ```vim | |
| 551 | + | echo expand("%") " path/file.txt | |
| 552 | + | echo expand("%:t") " file.txt | |
| 553 | + | echo expand("%:p:h") " /home/you/path/file.txt | |
| 554 | + | echo expand("%:r") " path/file | |
| 555 | + | echo expand("%:e") " txt | |
| 556 | + | ``` | |
| 557 | + | ||
| 558 | + | See `:help expand` | |
| 559 | + | ||
| 560 | + | ### Silencing | |
| 561 | + | ||
| 562 | + | ```vim | |
| 563 | + | silent g/Aap/p | |
| 564 | + | ``` | |
| 565 | + | ||
| 566 | + | Suppresses output. See `:help silent` | |
| 567 | + | ||
| 568 | + | ### Echo | |
| 569 | + | ||
| 570 | + | ```vim | |
| 571 | + | echoerr 'oh it failed' | |
| 572 | + | echomsg 'hello there' | |
| 573 | + | echo 'hello' | |
| 574 | + | ||
| 575 | + | echohl WarningMsg | echomsg "=> " . a:msg | echohl None | |
| 576 | + | ``` | |
| 577 | + | ||
| 578 | + | ||
| 579 | + | ### Settings | |
| 580 | + | ||
| 581 | + | ```vim | |
| 582 | + | set number | |
| 583 | + | set nonumber | |
| 584 | + | set number! " toggle | |
| 585 | + | set numberwidth=5 | |
| 586 | + | set guioptions+=e | |
| 587 | + | ``` | |
| 588 | + | ||
| 589 | + | ### Prompts | |
| 590 | + | ||
| 591 | + | ```vim | |
| 592 | + | let result = confirm("Sure?") | |
| 593 | + | execute "confirm q" | |
| 594 | + | ``` | |
| 595 | + | ||
| 596 | + | ### Built-ins | |
| 597 | + | ||
| 598 | + | ```vim | |
| 599 | + | has("feature") " :h feature-list | |
| 600 | + | executable("python") | |
| 601 | + | globpath(&rtp, "syntax/c.vim") | |
| 602 | + | ||
| 603 | + | exists("$ENV") | |
| 604 | + | exists(":command") | |
| 605 | + | exists("variable") | |
| 606 | + | exists("+option") | |
| 607 | + | exists("g:...") | |
| 608 | + | ``` | |
| 609 | + | ||
| 610 | + | Mapping | |
| 611 | + | ------- | |
| 612 | + | {: .-three-column} | |
| 613 | + | ||
| 614 | + | ### Mapping commands | |
| 615 | + | ||
| 616 | + | ```vim | |
| 617 | + | nmap | |
| 618 | + | vmap | |
| 619 | + | imap | |
| 620 | + | xmap | |
| 621 | + | nnoremap | |
| 622 | + | vnoremap | |
| 623 | + | inoremap | |
| 624 | + | xnoremap | |
| 625 | + | ... | |
| 626 | + | ``` | |
| 627 | + | ||
| 628 | + | ### Explanation | |
| 629 | + | ||
| 630 | + | ```vim | |
| 631 | + | [nvixso](nore)map | |
| 632 | + | ``` | |
| 633 | + | ||
| 634 | + | ``` | |
| 635 | + | │ └ don't recurse | |
| 636 | + | │ | |
| 637 | + | └ normal, visual, insert, | |
| 638 | + | eX mode, select, operator-pending | |
| 639 | + | ``` | |
| 640 | + | {: .-setup} | |
| 641 | + | ||
| 642 | + | ### Arguments | |
| 643 | + | ||
| 644 | + | | `<buffer>` | only in current buffer | | |
| 645 | + | | `<silent>` | no echo | | |
| 646 | + | | `<nowait>` | | | |
| 647 | + | ||
| 648 | + | Syntax | |
| 649 | + | ------ | |
| 650 | + | ||
| 651 | + | ### Highlights | |
| 652 | + | ||
| 653 | + | ```vim | |
| 654 | + | hi Comment | |
| 655 | + | term=bold,underline | |
| 656 | + | gui=bold | |
| 657 | + | ctermfg=4 | |
| 658 | + | guifg=#80a0ff | |
| 659 | + | ``` | |
| 660 | + | ||
| 661 | + | ### Filetype detection | |
| 662 | + | ||
| 663 | + | ```vim | |
| 664 | + | augroup filetypedetect | |
| 665 | + | au! BufNewFile,BufRead *.json setf javascript | |
| 666 | + | augroup END | |
| 667 | + | ||
| 668 | + | au Filetype markdown setlocal spell | |
| 669 | + | ``` | |
| 670 | + | ||
| 671 | + | ### Conceal | |
| 672 | + | ||
| 673 | + | ```vim | |
| 674 | + | set conceallevel=2 | |
| 675 | + | syn match newLine "<br>" conceal cchar=} | |
| 676 | + | hi newLine guifg=green | |
| 677 | + | ``` | |
| 678 | + | ||
| 679 | + | ### Region conceal | |
| 680 | + | ||
| 681 | + | ```vim | |
| 682 | + | syn region inBold concealends matchgroup=bTag start="<b>" end="</b>" | |
| 683 | + | hi inBold gui=bold | |
| 684 | + | hi bTag guifg=blue | |
| 685 | + | ``` | |
| 686 | + | ||
| 687 | + | ### Syntax | |
| 688 | + | ||
| 689 | + | ```vim | |
| 690 | + | syn match :name ":regex" :flags | |
| 691 | + | ||
| 692 | + | syn region Comment start="/\*" end="\*/" | |
| 693 | + | syn region String start=+"+ end=+"+ skip=+\\"+ | |
| 694 | + | ||
| 695 | + | syn cluster :name contains=:n1,:n2,:n3... | |
| 696 | + | ||
| 697 | + | flags: | |
| 698 | + | keepend | |
| 699 | + | oneline | |
| 700 | + | nextgroup= | |
| 701 | + | contains= | |
| 702 | + | contained | |
| 703 | + | ||
| 704 | + | hi def link markdownH1 htmlH1 | |
| 705 | + | ``` | |
| 706 | + | ||
| 707 | + | ### Include guards | |
| 708 | + | ||
| 709 | + | ```vim | |
| 710 | + | if exists('g:loaded_myplugin') | |
| 711 | + | finish | |
| 712 | + | endif | |
| 713 | + | ||
| 714 | + | " ... | |
| 715 | + | ||
| 716 | + | let g:loaded_myplugin = 1 | |
| 717 | + | ``` | |
| 718 | + | ||
| 719 | + | https://devhints.io/ cheatsheets - Copyright (c) 2021 Rico Sta. Cruz and contributors - MIT license | |
| 720 | + | micro-cheat plugin Copyright 2022 Tero Karvinen https://TeroKarvinen.com/micro - MIT license |
| ... | ... | @@ -0,0 +1,365 @@ | |
| 1 | + | --- | |
| 2 | + | title: Vue.js | |
| 3 | + | category: JavaScript | |
| 4 | + | layout: 2017/sheet | |
| 5 | + | updated: 2019-12-26 | |
| 6 | + | weight: -10 | |
| 7 | + | intro: | | |
| 8 | + | [Vue.js](https://vuejs.org/) is an open-source Model–view–viewmodel JavaScript framework for building user interfaces and single-page applications. | |
| 9 | + | --- | |
| 10 | + | ||
| 11 | + | {%raw%} | |
| 12 | + | ||
| 13 | + | Expressions | |
| 14 | + | ---------- | |
| 15 | + | {: .-three-column} | |
| 16 | + | ||
| 17 | + | ### Expressions | |
| 18 | + | ||
| 19 | + | ```html | |
| 20 | + | <div id="app"> | |
| 21 | + | <p>I have a {{ product }}</p> | |
| 22 | + | <p>{{ product + 's' }}</p> | |
| 23 | + | <p>{{ isWorking ? 'YES' : 'NO' }}</p> | |
| 24 | + | <p>{{ product.getSalePrice() }}</p> | |
| 25 | + | </div> | |
| 26 | + | ``` | |
| 27 | + | ||
| 28 | + | See: [Delimiters](https://vuejs.org/v2/api/#delimiters) | |
| 29 | + | ||
| 30 | + | ### Binding | |
| 31 | + | ||
| 32 | + | ```html | |
| 33 | + | <a v-bind:href="url">...</a> | |
| 34 | + | ``` | |
| 35 | + | ||
| 36 | + | #### Shorthand syntax | |
| 37 | + | ```html | |
| 38 | + | <a :href="url">...</a> | |
| 39 | + | ``` | |
| 40 | + | {: data-line="1"} | |
| 41 | + | ||
| 42 | + | #### True or false will add or remove attribute | |
| 43 | + | ```html | |
| 44 | + | <button :disabled="isButtonDisabled">... | |
| 45 | + | ``` | |
| 46 | + | ||
| 47 | + | #### If isActive is truthy, the class ‘active’ will appear | |
| 48 | + | ```html | |
| 49 | + | <div :class="{ active: isActive }">... | |
| 50 | + | ``` | |
| 51 | + | ||
| 52 | + | #### Style color set to value of activeColor | |
| 53 | + | ```html | |
| 54 | + | <div :style="{ color: activeColor }"> | |
| 55 | + | ``` | |
| 56 | + | ||
| 57 | + | See: [v-bind](https://vuejs.org/v2/api/#v-bind) | |
| 58 | + | ||
| 59 | + | ### Directives | |
| 60 | + | ||
| 61 | + | #### Element inserted/removed based on truthiness | |
| 62 | + | ```html | |
| 63 | + | <p v-if="inStock">{{ product }}</p> | |
| 64 | + | ``` | |
| 65 | + | ```html | |
| 66 | + | <p v-else-if="onSale">...</p> | |
| 67 | + | <p v-else>...</p> | |
| 68 | + | ``` | |
| 69 | + | ||
| 70 | + | #### Toggles the display: none CSS property | |
| 71 | + | ```html | |
| 72 | + | <p v-show="showProductDetails">...</p> | |
| 73 | + | ``` | |
| 74 | + | ||
| 75 | + | #### Two-way data binding | |
| 76 | + | ```html | |
| 77 | + | <input v-model="firstName" > | |
| 78 | + | ``` | |
| 79 | + | ||
| 80 | + | | Method | Description | | |
| 81 | + | | --- | --- | | |
| 82 | + | | `v-model.lazy="..."` | Syncs input after change event | | |
| 83 | + | | `v-model.number="..."` | Always returns a number | | |
| 84 | + | | `v-model.trim="..."` | Strips whitespace | | |
| 85 | + | ||
| 86 | + | See: [Directives](https://vuejs.org/v2/api/#Directives) | |
| 87 | + | ||
| 88 | + | ### Actions/Events | |
| 89 | + | ||
| 90 | + | #### Calls addToCart method on component | |
| 91 | + | ```html | |
| 92 | + | <button v-on:click="addToCart">... | |
| 93 | + | ``` | |
| 94 | + | ||
| 95 | + | #### Shorthand syntax | |
| 96 | + | ```html | |
| 97 | + | <button @click="addToCart">... | |
| 98 | + | ``` | |
| 99 | + | {: data-line="1"} | |
| 100 | + | ||
| 101 | + | #### Arguments can be passed | |
| 102 | + | ```html | |
| 103 | + | <button @click="addToCart(product)">... | |
| 104 | + | ``` | |
| 105 | + | ||
| 106 | + | #### To prevent default behavior (e.g. page reload) | |
| 107 | + | ```html | |
| 108 | + | <form @submit.prevent="addProduct">... | |
| 109 | + | ``` | |
| 110 | + | ||
| 111 | + | #### Only trigger once | |
| 112 | + | ```html | |
| 113 | + | <img @mouseover.once="showImage">... | |
| 114 | + | ``` | |
| 115 | + | ||
| 116 | + | | Method | Description | | |
| 117 | + | | --- | --- | | |
| 118 | + | | `.stop` | Stop all event propagation | | |
| 119 | + | | `.self ` | Only trigger if event.target is element itself | | |
| 120 | + | ||
| 121 | + | #### Keyboard entry example | |
| 122 | + | ```html | |
| 123 | + | <input @keyup.enter="submit"> | |
| 124 | + | ``` | |
| 125 | + | ||
| 126 | + | #### Call onCopy when control-c is pressed | |
| 127 | + | ```html | |
| 128 | + | <input @keyup.ctrl.c="onCopy"> | |
| 129 | + | ``` | |
| 130 | + | ||
| 131 | + | See: [Events](https://vuejs.org/v2/guide/events.html) | |
| 132 | + | ||
| 133 | + | ### List rendering | |
| 134 | + | ||
| 135 | + | #### The `:key` is always recommended | |
| 136 | + | ```html | |
| 137 | + | <li v-for="item in items" | |
| 138 | + | :key="item.id"> | |
| 139 | + | {{ item }} | |
| 140 | + | </li> | |
| 141 | + | ``` | |
| 142 | + | {: data-line="2"} | |
| 143 | + | ||
| 144 | + | #### To access the position in the array | |
| 145 | + | ```html | |
| 146 | + | <li v-for="(item, index) in items">... | |
| 147 | + | ``` | |
| 148 | + | ||
| 149 | + | #### To iterate through objects | |
| 150 | + | ```html | |
| 151 | + | <li v-for="(value, key) in object">... | |
| 152 | + | ``` | |
| 153 | + | ||
| 154 | + | #### Using `v-for` with a component | |
| 155 | + | ```html | |
| 156 | + | <cart-product v-for="item in products" | |
| 157 | + | :product="item" | |
| 158 | + | :key="item.id"> | |
| 159 | + | ``` | |
| 160 | + | ||
| 161 | + | See: [List Rendering](https://vuejs.org/v2/guide/list.html) | |
| 162 | + | ||
| 163 | + | ||
| 164 | + | Component | |
| 165 | + | -------- | |
| 166 | + | ||
| 167 | + | ### Component anatomy | |
| 168 | + | ||
| 169 | + | ```js | |
| 170 | + | Vue.component('my-component', { | |
| 171 | + | components: { | |
| 172 | + | // Components that can be used in the template | |
| 173 | + | ProductComponent, | |
| 174 | + | ReviewComponent | |
| 175 | + | }, | |
| 176 | + | props: { | |
| 177 | + | // The parameters the component accepts | |
| 178 | + | message: String, | |
| 179 | + | product: Object, | |
| 180 | + | email: { | |
| 181 | + | type: String, | |
| 182 | + | required: true, | |
| 183 | + | default: "none" | |
| 184 | + | validator: function (value) { | |
| 185 | + | // Should return true if value is valid | |
| 186 | + | } | |
| 187 | + | } | |
| 188 | + | }, | |
| 189 | + | data: function() { | |
| 190 | + | // `data` must be a function | |
| 191 | + | return { | |
| 192 | + | firstName: 'Vue', | |
| 193 | + | lastName: 'Mastery' | |
| 194 | + | } | |
| 195 | + | }, | |
| 196 | + | computed: { | |
| 197 | + | // Return cached values until dependencies change | |
| 198 | + | fullName: function () { | |
| 199 | + | return this.firstName + ' ' + this.lastName | |
| 200 | + | } | |
| 201 | + | }, | |
| 202 | + | watch: { | |
| 203 | + | // Called when firstName changes value | |
| 204 | + | firstName: function (value, oldValue) { ... } | |
| 205 | + | }, | |
| 206 | + | methods: { ... }, | |
| 207 | + | template: '<span>{{ message }}</span>', | |
| 208 | + | // Can also use backticks in `template` for multi-line | |
| 209 | + | }) | |
| 210 | + | ``` | |
| 211 | + | {: data-line="3, 8, 16, 21, 28, 34, 39"} | |
| 212 | + | ||
| 213 | + | See: [Components Basics](https://vuejs.org/v2/guide/components.html) | |
| 214 | + | ||
| 215 | + | ### Lifecycle hooks | |
| 216 | + | ||
| 217 | + | | Method | Description | | |
| 218 | + | | --- | --- | | |
| 219 | + | | `beforeCreate` | After the instance has been initialized [#](https://vuejs.org/v2/api/#beforeCreate) | | |
| 220 | + | | `created` | After the instance is created [#](https://vuejs.org/v2/api/#created) | | |
| 221 | + | | `beforeMount` | Before the first render [#](https://vuejs.org/v2/api/#beforeMount) | | |
| 222 | + | | `mounted` | After the instance has been mounted [#](https://vuejs.org/v2/api/#mounted) | | |
| 223 | + | | `beforeUpdate` | When data changes, before the DOM is patched [#](https://vuejs.org/v2/api/#beforeUpdate) | | |
| 224 | + | | `updated` | After a data change [#](https://vuejs.org/v2/api/#updated) | | |
| 225 | + | | `beforeDestroy` | Before the instance is destroyed [#](https://vuejs.org/v2/api/#beforeDestroy) | | |
| 226 | + | | `destroyed` | After a Vue instance has been destroyed [#](https://vuejs.org/v2/api/#destroyed) | | |
| 227 | + | ||
| 228 | + | See: [Lifecycle Hooks](https://vuejs.org/v2/api/#Options-Lifecycle-Hooks) | |
| 229 | + | ||
| 230 | + | ### Custom events | |
| 231 | + | ||
| 232 | + | #### Set listener on component, within its parent | |
| 233 | + | ```html | |
| 234 | + | <button-counter v-on:incrementBy="incWithVal"> | |
| 235 | + | ``` | |
| 236 | + | ||
| 237 | + | #### Inside parent component | |
| 238 | + | ```js | |
| 239 | + | methods: { | |
| 240 | + | incWithVal: function (toAdd) { ... } | |
| 241 | + | } | |
| 242 | + | ``` | |
| 243 | + | ||
| 244 | + | #### Inside button-counter template | |
| 245 | + | ```js | |
| 246 | + | this.$emit( | |
| 247 | + | 'incrementBy', // Custom event name | |
| 248 | + | 5 // Data sent up to parent | |
| 249 | + | ) | |
| 250 | + | ``` | |
| 251 | + | ||
| 252 | + | Use props to pass data into child components, | |
| 253 | + | custom events to pass data to parent elements. | |
| 254 | + | ||
| 255 | + | See: [Custom Events](https://vuejs.org/v2/guide/components-custom-events.html) | |
| 256 | + | ||
| 257 | + | Single file components | |
| 258 | + | -------- | |
| 259 | + | ||
| 260 | + | ### Single file | |
| 261 | + | ```html | |
| 262 | + | <template> | |
| 263 | + | <p>{{ greeting }} World!</p> | |
| 264 | + | </template> | |
| 265 | + | ||
| 266 | + | <script> | |
| 267 | + | module.exports = { | |
| 268 | + | data: function () { | |
| 269 | + | return { | |
| 270 | + | greeting: 'Hello' | |
| 271 | + | } | |
| 272 | + | } | |
| 273 | + | } | |
| 274 | + | </script> | |
| 275 | + | ||
| 276 | + | <style scoped> | |
| 277 | + | p { | |
| 278 | + | font-size: 2em; | |
| 279 | + | text-align: center; | |
| 280 | + | } | |
| 281 | + | </style> | |
| 282 | + | ``` | |
| 283 | + | ||
| 284 | + | See: [Single File Components](https://vuejs.org/v2/guide/single-file-components.html) | |
| 285 | + | ||
| 286 | + | ### Separation | |
| 287 | + | ```html | |
| 288 | + | <template> | |
| 289 | + | <div>This will be pre-compiled</div> | |
| 290 | + | </template> | |
| 291 | + | <script src="./my-component.js"></script> | |
| 292 | + | <style src="./my-component.css"></style> | |
| 293 | + | ``` | |
| 294 | + | ||
| 295 | + | See: [What About Separation of Concerns?](https://vuejs.org/v2/guide/single-file-components.html#What-About-Separation-of-Concerns) | |
| 296 | + | ||
| 297 | + | Slots | |
| 298 | + | -------- | |
| 299 | + | ||
| 300 | + | ### Using a single slot | |
| 301 | + | ||
| 302 | + | #### Component template | |
| 303 | + | ```html | |
| 304 | + | <div> | |
| 305 | + | <h2>I'm a title</h2> | |
| 306 | + | <slot> | |
| 307 | + | Only displayed if no slot content | |
| 308 | + | </slot> | |
| 309 | + | </div> | |
| 310 | + | ``` | |
| 311 | + | {: data-line="3,4,5"} | |
| 312 | + | ||
| 313 | + | #### Use of component with data for slot | |
| 314 | + | ```html | |
| 315 | + | <my-component> | |
| 316 | + | <p>This will go in the slot</p> | |
| 317 | + | </my-component> | |
| 318 | + | ``` | |
| 319 | + | {: data-line="2"} | |
| 320 | + | ||
| 321 | + | See: [Slots](https://vuejs.org/v2/guide/components-slots.html) | |
| 322 | + | ||
| 323 | + | ### Multiple slots | |
| 324 | + | ||
| 325 | + | #### Component template | |
| 326 | + | ```html | |
| 327 | + | <div class="container"> | |
| 328 | + | <header> | |
| 329 | + | <slot name="header"></slot> | |
| 330 | + | </header> | |
| 331 | + | <main> | |
| 332 | + | <slot>Default content</slot> | |
| 333 | + | </main> | |
| 334 | + | <footer> | |
| 335 | + | <slot name="footer"></slot> | |
| 336 | + | </footer> | |
| 337 | + | </div> | |
| 338 | + | ``` | |
| 339 | + | {: data-line="3,6,9"} | |
| 340 | + | ||
| 341 | + | #### Use of component with data for slots | |
| 342 | + | ```html | |
| 343 | + | <app-layout> | |
| 344 | + | <h1 slot="header">Page title</h1> | |
| 345 | + | <p>the main content.</p> | |
| 346 | + | <p slot="footer">Contact info</p> | |
| 347 | + | </app-layout> | |
| 348 | + | ``` | |
| 349 | + | {: data-line="2,3,4"} | |
| 350 | + | ||
| 351 | + | See: [Slots](https://vuejs.org/v2/guide/components-slots.html) | |
| 352 | + | ||
| 353 | + | Also see | |
| 354 | + | -------- | |
| 355 | + | ||
| 356 | + | * [Vue CLI](https://cli.vuejs.org/) _(cli.vuejs.org)_ | |
| 357 | + | * [Vue Router](https://router.vuejs.org/) _(router.vuejs.org)_ | |
| 358 | + | * [Vue DevTools](https://chrome.google.com/webstore/detail/vuejs-devtools/nhdogjmejiglipccpnnnanhbledajbpd?hl=en) _(chrome.google.com)_ | |
| 359 | + | * [Nuxt.js](https://nuxtjs.org/) _(nuxtjs.org)_ | |
| 360 | + | * [Vue.js v1.0.28 cheatsheet](vue@1.0.28/) _Legacy version_ | |
| 361 | + | ||
| 362 | + | {%endraw%} | |
| 363 | + | ||
| 364 | + | https://devhints.io/ cheatsheets - Copyright (c) 2021 Rico Sta. Cruz and contributors - MIT license | |
| 365 | + | micro-cheat plugin Copyright 2022 Tero Karvinen https://TeroKarvinen.com/micro - MIT license |
| ... | ... | @@ -0,0 +1,40 @@ | |
| 1 | + | --- | |
| 2 | + | title: Yaml | |
| 3 | + | category: Markup | |
| 4 | + | layout: 2017/sheet | |
| 5 | + | prism_languages: [yaml] | |
| 6 | + | --- | |
| 7 | + | ||
| 8 | + | ### Multiline strings | |
| 9 | + | ||
| 10 | + | ```yaml | |
| 11 | + | Multiline: | | |
| 12 | + | hello | |
| 13 | + | world | |
| 14 | + | ``` | |
| 15 | + | ||
| 16 | + | ### Inheritance | |
| 17 | + | ||
| 18 | + | ```yaml | |
| 19 | + | parent: &defaults | |
| 20 | + | a: 2 | |
| 21 | + | b: 3 | |
| 22 | + | ||
| 23 | + | child: | |
| 24 | + | <<: *defaults | |
| 25 | + | b: 4 | |
| 26 | + | ``` | |
| 27 | + | ||
| 28 | + | ### Reference content | |
| 29 | + | ||
| 30 | + | ```yaml | |
| 31 | + | values: &ref | |
| 32 | + | - These values | |
| 33 | + | - will be reused below | |
| 34 | + | ||
| 35 | + | other_values: | |
| 36 | + | <<: *ref | |
| 37 | + | ``` | |
| 38 | + | ||
| 39 | + | https://devhints.io/ cheatsheets - Copyright (c) 2021 Rico Sta. Cruz and contributors - MIT license | |
| 40 | + | micro-cheat plugin Copyright 2022 Tero Karvinen https://TeroKarvinen.com/micro - MIT license |
| ... | ... | @@ -0,0 +1,45 @@ | |
| 1 | + | --- | |
| 2 | + | title: zsh | |
| 3 | + | category: CLI | |
| 4 | + | layout: 2017/sheet | |
| 5 | + | --- | |
| 6 | + | ||
| 7 | + | ### Expressions | |
| 8 | + | ||
| 9 | + | | Expression | Example | Description | |
| 10 | + | | --- | --- | --- | |
| 11 | + | | `!!` | `sudo !!` | Last command (`sudo !!`) | |
| 12 | + | | --- | --- | --- | |
| 13 | + | | `!*` | `vim !*` | Last command's parameters (`vim !*`) | |
| 14 | + | | `!^` | | Last command's first parameter | |
| 15 | + | | `!$` | | Last command's last parameter | |
| 16 | + | | --- | --- | --- | |
| 17 | + | | `!?ls` `<tab>` | `sudo !?mv` `<tab>` | Command and params of last `ls` command | |
| 18 | + | | `!?ls?:*` `<tab>` | | Params of last `ls` command | |
| 19 | + | | --- | --- | --- | |
| 20 | + | | `*(m0)` | `rm *(m0)` | Last modified today | |
| 21 | + | | `*(m-4)` | | Last modified <4 days ago | |
| 22 | + | {: .-headers} | |
| 23 | + | ||
| 24 | + | ### Change default shell | |
| 25 | + | ||
| 26 | + | ```bash | |
| 27 | + | chsh -s `which zsh` | |
| 28 | + | ``` | |
| 29 | + | ||
| 30 | + | ### Process Substitution | |
| 31 | + | ||
| 32 | + | | Expression | Example | Description | |
| 33 | + | | --- | --- | --- | |
| 34 | + | | `<(COMMAND)` | `grep "needle" <(curl "https://haystack.io")` | Replace argument with _named pipe/FIFO_ (read-only) with command output | |
| 35 | + | | `=(COMMAND)` | `vim =(curl "https://haystack.io")` | Replace argument with _file_ (writable) containing command output | |
| 36 | + | {: .-headers} | |
| 37 | + | ||
| 38 | + | ### Also see | |
| 39 | + | ||
| 40 | + | - [Bash cheatsheet](./bash) | |
| 41 | + | ||
| 42 | + | Zsh is mostly compatible with Bash, so most everything in Bash's cheatsheet also applies. | |
| 43 | + | ||
| 44 | + | https://devhints.io/ cheatsheets - Copyright (c) 2021 Rico Sta. Cruz and contributors - MIT license | |
| 45 | + | micro-cheat plugin Copyright 2022 Tero Karvinen https://TeroKarvinen.com/micro - MIT license |
| ... | ... | @@ -0,0 +1 @@ | |
| 1 | + | 2024/12/29 01:44:02 Micro started |
+40,
-0
| ... | ... | @@ -0,0 +1,40 @@ | |
| 1 | + | -- micro-cheat copyright 2022 Tero Karvinen https://TeroKarvinen.com | |
| 2 | + | ||
| 3 | + | -- Cheatsheets are copyrighted by their original authors | |
| 4 | + | ||
| 5 | + | -- Cheatsheets from Devhints.io are copyright 2021 | |
| 6 | + | -- Rico Sta. Cruz and contributors, received under the MIT license | |
| 7 | + | ||
| 8 | + | local micro = import("micro") | |
| 9 | + | local config = import("micro/config") | |
| 10 | + | ||
| 11 | + | local cheatdir = config.ConfigDir.."/plug/cheat/cheatsheets/" | |
| 12 | + | ||
| 13 | + | function init() | |
| 14 | + | -- runs once when micro starts | |
| 15 | + | config.MakeCommand("cheat", cheatCommand, config.NoComplete) | |
| 16 | + | config.TryBindKey("F1", "command:cheat", false) | |
| 17 | + | end | |
| 18 | + | ||
| 19 | + | function cheatCommand(bp) | |
| 20 | + | local filename = bp.Buf:GetName() | |
| 21 | + | local filetype = bp.Buf:FileType() | |
| 22 | + | ||
| 23 | + | if "Vagrantfile" == filename or "Dockerfile" == filename then | |
| 24 | + | filetype = filename:lower() | |
| 25 | + | micro.InfoBar():Message("Cheatsheet by file name: "..filename) | |
| 26 | + | elseif string.find(filename, "\.org$") then -- not detected by micro | |
| 27 | + | filetype = "org" | |
| 28 | + | micro.InfoBar():Message("Cheatsheet by file suffix: "..filename) | |
| 29 | + | elseif "unknown" ~= filetype then | |
| 30 | + | -- micro hopefully detected the filetype, the typical case | |
| 31 | + | micro.InfoBar():Message("Cheatsheet by file type: "..filetype) | |
| 32 | + | else | |
| 33 | + | micro.InfoBar():Message("Cheatsheet not found for type '"..filetype.."', filename '"..filename.."'") | |
| 34 | + | return | |
| 35 | + | end | |
| 36 | + | ||
| 37 | + | local cmd = "tab " .. cheatdir .. filetype .. ".md" | |
| 38 | + | bp:HandleCommand(cmd) | |
| 39 | + | ||
| 40 | + | end |
+35,
-0
| ... | ... | @@ -0,0 +1,35 @@ | |
| 1 | + | [{ | |
| 2 | + | "Name": "cheat", | |
| 3 | + | "Description": "F1 for cheatsheet related to the type of file you're editing: Lua, Go, Python...", | |
| 4 | + | "Website": "https://terokarvinen.com/micro", | |
| 5 | + | "Tags": ["cheatsheet", "help", "docs", "Lua", "Go", "Python", "reference"], | |
| 6 | + | "Versions": [ | |
| 7 | + | { | |
| 8 | + | "Version": "0.0.4", | |
| 9 | + | "Url": "https://github.com/terokarvinen/micro-cheat/archive/v0.0.4.zip", | |
| 10 | + | "Require": { | |
| 11 | + | "micro": ">=2.0.0" | |
| 12 | + | } | |
| 13 | + | }, | |
| 14 | + | { | |
| 15 | + | "Version": "0.0.3", | |
| 16 | + | "Url": "https://github.com/terokarvinen/micro-cheat/archive/v0.0.3.zip", | |
| 17 | + | "Require": { | |
| 18 | + | "micro": ">=2.0.0" | |
| 19 | + | } | |
| 20 | + | }, | |
| 21 | + | { | |
| 22 | + | "Version": "0.0.2", | |
| 23 | + | "Url": "https://github.com/terokarvinen/micro-cheat/archive/v0.0.2.zip", | |
| 24 | + | "Require": { | |
| 25 | + | "micro": ">=2.0.0" | |
| 26 | + | } | |
| 27 | + | }, | |
| 28 | + | { | |
| 29 | + | "Version": "0.0.1", | |
| 30 | + | "Require": { | |
| 31 | + | "micro": ">=2.0.0" | |
| 32 | + | } | |
| 33 | + | } | |
| 34 | + | ] | |
| 35 | + | }] |
| ... | ... | @@ -0,0 +1,6 @@ | |
| 1 | + | Version 1.2.1 | |
| 2 | + | * Fixed utf8 character count | |
| 3 | + | ||
| 4 | + | Version 1.2.0 | |
| 5 | + | + Now counts lines | |
| 6 | + | + Added Support for counting lines, words and characters in selection |
+21,
-0
| ... | ... | @@ -0,0 +1,21 @@ | |
| 1 | + | MIT License | |
| 2 | + | ||
| 3 | + | Copyright (c) 2020 bananaapple | |
| 4 | + | ||
| 5 | + | Permission is hereby granted, free of charge, to any person obtaining a copy | |
| 6 | + | of this software and associated documentation files (the "Software"), to deal | |
| 7 | + | in the Software without restriction, including without limitation the rights | |
| 8 | + | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | |
| 9 | + | copies of the Software, and to permit persons to whom the Software is | |
| 10 | + | furnished to do so, subject to the following conditions: | |
| 11 | + | ||
| 12 | + | The above copyright notice and this permission notice shall be included in all | |
| 13 | + | copies or substantial portions of the Software. | |
| 14 | + | ||
| 15 | + | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |
| 16 | + | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |
| 17 | + | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | |
| 18 | + | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | |
| 19 | + | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | |
| 20 | + | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | |
| 21 | + | SOFTWARE. |
+4,
-0
| ... | ... | @@ -0,0 +1,4 @@ | |
| 1 | + | # Micro Word Count Plugin | |
| 2 | + | ||
| 3 | + | Word, character and line counter for micro editor. | |
| 4 | + | (forked from https://github.com/adamnpeace/micro-wc-plugin) |
+25,
-0
| ... | ... | @@ -0,0 +1,25 @@ | |
| 1 | + | # WordCount (wc) Plugin # | |
| 2 | + | ||
| 3 | + | The wc plugin provides the user with the ability to count either | |
| 4 | + | characters or strings in any text being edited with micro. | |
| 5 | + | ||
| 6 | + | A word is defined as a string of characters delimited by white | |
| 7 | + | space characters. White space characters are the set of characters | |
| 8 | + | for which the iswspace(3) function returns true. | |
| 9 | + | ||
| 10 | + | A line is defined as a string of characters delimited by \n | |
| 11 | + | characters, or by the beginning or end of the file. \r\n line | |
| 12 | + | endings will be counted correctly as well, since there is only | |
| 13 | + | one \n per \r\n. | |
| 14 | + | ||
| 15 | + | Character count includes white space and newline characters. | |
| 16 | + | ||
| 17 | + | To initiate the function, you can either: | |
| 18 | + | ||
| 19 | + | Press "F5" | |
| 20 | + | ||
| 21 | + | Or run: | |
| 22 | + | ||
| 23 | + | ``` | |
| 24 | + | > wc | |
| 25 | + | ``` |
+10,
-0
| ... | ... | @@ -0,0 +1,10 @@ | |
| 1 | + | { | |
| 2 | + | "name": "wc", | |
| 3 | + | "description": "Word count plugin", | |
| 4 | + | "website": "", | |
| 5 | + | "install": "", | |
| 6 | + | "version": "1.2.1", | |
| 7 | + | "require": [ | |
| 8 | + | "micro >= 2.0.0" | |
| 9 | + | ] | |
| 10 | + | } |
+22,
-0
| ... | ... | @@ -0,0 +1,22 @@ | |
| 1 | + | [{ | |
| 2 | + | "Name": "wc", | |
| 3 | + | "Description": "Plugin to count words/characters in micro", | |
| 4 | + | "Tags": ["wc", "word", "character", "count"], | |
| 5 | + | "Website": "https://github.com/adamnpeace/micro-wc-plugin", | |
| 6 | + | "Versions": [ | |
| 7 | + | { | |
| 8 | + | "Version": "1.1.0", | |
| 9 | + | "Url": "https://github.com/adamnpeace/micro-wc-plugin/archive/v1.1.0.zip", | |
| 10 | + | "Require": { | |
| 11 | + | "micro": ">=2.0.0-1" | |
| 12 | + | } | |
| 13 | + | }, | |
| 14 | + | { | |
| 15 | + | "Version": "1.0.1", | |
| 16 | + | "Url": "https://github.com/adamnpeace/micro-wc-plugin/archive/v1.0.1.zip", | |
| 17 | + | "Require": { | |
| 18 | + | "micro": ">=1.1.0" | |
| 19 | + | } | |
| 20 | + | } | |
| 21 | + | ] | |
| 22 | + | }] |
+37,
-0
| ... | ... | @@ -0,0 +1,37 @@ | |
| 1 | + | VERSION = "1.2.1" | |
| 2 | + | ||
| 3 | + | local micro = import("micro") | |
| 4 | + | local config = import("micro/config") | |
| 5 | + | local util = import("micro/util") | |
| 6 | + | local utf8 = import("unicode/utf8") | |
| 7 | + | ||
| 8 | + | function init() | |
| 9 | + | config.MakeCommand("wc", wordCount, config.NoComplete) | |
| 10 | + | config.AddRuntimeFile("wc", config.RTHelp, "help/wc.md") | |
| 11 | + | config.TryBindKey("F5", "lua:wc.wordCount", false) | |
| 12 | + | end | |
| 13 | + | ||
| 14 | + | function wordCount(bp) | |
| 15 | + | -- Buffer of selection/whole document | |
| 16 | + | local buffer | |
| 17 | + | --Get active cursor (to get selection) | |
| 18 | + | local cursor = bp.Buf:GetActiveCursor() | |
| 19 | + | --If cursor exists and there is selection, convert selection byte[] to string | |
| 20 | + | if cursor and cursor:HasSelection() then | |
| 21 | + | buffer = util.String(cursor:GetSelection()) | |
| 22 | + | else | |
| 23 | + | --no selection, convert whole buffer byte[] to string | |
| 24 | + | buffer = util.String(bp.Buf:Bytes()) | |
| 25 | + | end | |
| 26 | + | --length of the buffer/selection (string), utf8 friendly | |
| 27 | + | charCount = utf8.RuneCountInString(buffer) | |
| 28 | + | --Get word/line count using gsub's number of substitutions | |
| 29 | + | -- number of substitutions, pattern: %S+ (more than one non-whitespace characters) | |
| 30 | + | local _ , wordCount = buffer:gsub("%S+","") | |
| 31 | + | -- number of substitutions, pattern: \n (number of newline characters) | |
| 32 | + | local _, lineCount = buffer:gsub("\n", "") | |
| 33 | + | --add one to line count (since we're counting separators not lines above) | |
| 34 | + | lineCount = lineCount + 1 | |
| 35 | + | --display the message | |
| 36 | + | micro.InfoBar():Message("Lines:" .. lineCount .. " Words:"..wordCount.." Characters:"..charCount) | |
| 37 | + | end |